summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/SConscript2
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aaline.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_aapoint.c14
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_clip.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_cull.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_flatshade.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_offset.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_stipple.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_twoside.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_unfilled.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_validate.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_vbuf.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_line.c1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_point.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt.h1
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch.c10
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_emit.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos_machine.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c6
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.cpp2
-rw-r--r--src/gallium/auxiliary/indices/u_unfilled_gen.c160
-rw-r--r--src/gallium/auxiliary/indices/u_unfilled_gen.py1
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c19
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c102
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c2
-rw-r--r--src/gallium/auxiliary/rbug/Makefile14
-rw-r--r--src/gallium/auxiliary/rbug/README21
-rw-r--r--src/gallium/auxiliary/rbug/SConscript14
-rw-r--r--src/gallium/auxiliary/rbug/rbug.h33
-rw-r--r--src/gallium/auxiliary/rbug/rbug_connection.c167
-rw-r--r--src/gallium/auxiliary/rbug/rbug_connection.h45
-rw-r--r--src/gallium/auxiliary/rbug/rbug_context.c759
-rw-r--r--src/gallium/auxiliary/rbug/rbug_context.h212
-rw-r--r--src/gallium/auxiliary/rbug/rbug_core.c359
-rw-r--r--src/gallium/auxiliary/rbug/rbug_core.h105
-rw-r--r--src/gallium/auxiliary/rbug/rbug_demarshal.c93
-rw-r--r--src/gallium/auxiliary/rbug/rbug_internal.h100
-rw-r--r--src/gallium/auxiliary/rbug/rbug_proto.h94
-rw-r--r--src/gallium/auxiliary/rbug/rbug_shader.c468
-rw-r--r--src/gallium/auxiliary/rbug/rbug_shader.h142
-rw-r--r--src/gallium/auxiliary/rbug/rbug_texture.c631
-rw-r--r--src/gallium/auxiliary/rbug/rbug_texture.h206
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_cpu.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c62
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c133
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_transform.c27
-rw-r--r--src/gallium/auxiliary/trace/trace_drm.h165
-rw-r--r--src/gallium/auxiliary/util/Makefile2
-rw-r--r--src/gallium/auxiliary/util/SConscript2
-rw-r--r--src/gallium/auxiliary/util/u_blit.c5
-rw-r--r--src/gallium/auxiliary/util/u_debug.c58
-rw-r--r--src/gallium/auxiliary/util/u_debug.h21
-rw-r--r--src/gallium/auxiliary/util/u_debug_stack.c11
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c100
-rw-r--r--src/gallium/auxiliary/util/u_linear.c31
-rw-r--r--src/gallium/auxiliary/util/u_linear.h31
-rw-r--r--src/gallium/auxiliary/util/u_network.c188
-rw-r--r--src/gallium/auxiliary/util/u_network.h24
-rw-r--r--src/gallium/auxiliary/util/u_surface.c113
-rw-r--r--src/gallium/auxiliary/util/u_surface.h (renamed from src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.h)45
-rw-r--r--src/gallium/auxiliary/util/u_tile.c17
-rw-r--r--src/gallium/auxiliary/util/u_time.c5
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c30
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c25
-rw-r--r--src/gallium/drivers/cell/spu/spu_render.c79
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c133
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.h2
-rw-r--r--src/gallium/drivers/failover/fo_context.c23
-rw-r--r--src/gallium/drivers/i915simple/Makefile1
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c26
-rw-r--r--src/gallium/drivers/i965simple/brw_context.c25
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c2
-rw-r--r--src/gallium/drivers/nouveau/Makefile8
-rw-r--r--src/gallium/drivers/nouveau/nouveau_push.h39
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c240
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h25
-rw-r--r--src/gallium/drivers/nouveau/nouveau_stateobj.h44
-rw-r--r--src/gallium/drivers/nouveau/nouveau_winsys.h51
-rw-r--r--src/gallium/drivers/nv04/nv04_context.c27
-rw-r--r--src/gallium/drivers/nv04/nv04_miptree.c3
-rw-r--r--src/gallium/drivers/nv04/nv04_screen.c88
-rw-r--r--src/gallium/drivers/nv04/nv04_screen.h4
-rw-r--r--src/gallium/drivers/nv04/nv04_state.c7
-rw-r--r--src/gallium/drivers/nv04/nv04_state.h2
-rw-r--r--src/gallium/drivers/nv04/nv04_surface_2d.c28
-rw-r--r--src/gallium/drivers/nv04/nv04_surface_2d.h3
-rw-r--r--src/gallium/drivers/nv04/nv04_transfer.c1
-rw-r--r--src/gallium/drivers/nv04/nv04_vbo.c16
-rw-r--r--src/gallium/drivers/nv10/nv10_context.c36
-rw-r--r--src/gallium/drivers/nv10/nv10_prim_vbuf.c14
-rw-r--r--src/gallium/drivers/nv10/nv10_screen.c92
-rw-r--r--src/gallium/drivers/nv10/nv10_screen.h4
-rw-r--r--src/gallium/drivers/nv10/nv10_state.c7
-rw-r--r--src/gallium/drivers/nv10/nv10_transfer.c1
-rw-r--r--src/gallium/drivers/nv10/nv10_vbo.c15
-rw-r--r--src/gallium/drivers/nv20/nv20_context.c41
-rw-r--r--src/gallium/drivers/nv20/nv20_prim_vbuf.c12
-rw-r--r--src/gallium/drivers/nv20/nv20_screen.c84
-rw-r--r--src/gallium/drivers/nv20/nv20_screen.h4
-rw-r--r--src/gallium/drivers/nv20/nv20_state.c7
-rw-r--r--src/gallium/drivers/nv20/nv20_transfer.c1
-rw-r--r--src/gallium/drivers/nv20/nv20_vbo.c16
-rw-r--r--src/gallium/drivers/nv20/nv20_vertprog.c12
-rw-r--r--src/gallium/drivers/nv30/nv30_context.c26
-rw-r--r--src/gallium/drivers/nv30/nv30_fragprog.c24
-rw-r--r--src/gallium/drivers/nv30/nv30_fragtex.c7
-rw-r--r--src/gallium/drivers/nv30/nv30_query.c25
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c133
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.h5
-rw-r--r--src/gallium/drivers/nv30/nv30_state_emit.c11
-rw-r--r--src/gallium/drivers/nv30/nv30_state_fb.c53
-rw-r--r--src/gallium/drivers/nv30/nv30_transfer.c1
-rw-r--r--src/gallium/drivers/nv30/nv30_vbo.c44
-rw-r--r--src/gallium/drivers/nv30/nv30_vertprog.c32
-rw-r--r--src/gallium/drivers/nv40/nv40_context.c26
-rw-r--r--src/gallium/drivers/nv40/nv40_draw.c21
-rw-r--r--src/gallium/drivers/nv40/nv40_fragprog.c24
-rw-r--r--src/gallium/drivers/nv40/nv40_fragtex.c7
-rw-r--r--src/gallium/drivers/nv40/nv40_query.c25
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c135
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.h4
-rw-r--r--src/gallium/drivers/nv40/nv40_state_emit.c11
-rw-r--r--src/gallium/drivers/nv40/nv40_state_fb.c96
-rw-r--r--src/gallium/drivers/nv40/nv40_surface.c5
-rw-r--r--src/gallium/drivers/nv40/nv40_transfer.c1
-rw-r--r--src/gallium/drivers/nv40/nv40_vbo.c42
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c28
-rw-r--r--src/gallium/drivers/nv50/nv50_clear.c76
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c28
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h18
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c1223
-rw-r--r--src/gallium/drivers/nv50/nv50_program.h11
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c29
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c200
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.h15
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c15
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c74
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c16
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c36
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c82
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c23
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c5
-rw-r--r--src/gallium/drivers/r300/r300_chipset.h2
-rw-r--r--src/gallium/drivers/r300/r300_context.c38
-rw-r--r--src/gallium/drivers/r300/r300_context.h86
-rw-r--r--src/gallium/drivers/r300/r300_cs.h42
-rw-r--r--src/gallium/drivers/r300/r300_debug.c118
-rw-r--r--src/gallium/drivers/r300/r300_debug.h176
-rw-r--r--src/gallium/drivers/r300/r300_emit.c203
-rw-r--r--src/gallium/drivers/r300/r300_emit.h5
-rw-r--r--src/gallium/drivers/r300/r300_flush.c2
-rw-r--r--src/gallium/drivers/r300/r300_reg.h3
-rw-r--r--src/gallium/drivers/r300/r300_render.c77
-rw-r--r--src/gallium/drivers/r300/r300_screen.c41
-rw-r--r--src/gallium/drivers/r300/r300_state.c82
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c357
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h19
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c34
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.c153
-rw-r--r--src/gallium/drivers/r300/r300_state_shader.h24
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.c171
-rw-r--r--src/gallium/drivers/r300/r300_state_tcl.h24
-rw-r--r--src/gallium/drivers/r300/r300_surface.c150
-rw-r--r--src/gallium/drivers/r300/r300_surface.h4
-rw-r--r--src/gallium/drivers/r300/r300_texture.c2
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h56
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c23
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c30
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_pipe.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_query.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c11
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c20
-rw-r--r--src/gallium/drivers/softpipe/sp_winsys.h22
-rw-r--r--src/gallium/drivers/trace/Makefile2
-rw-r--r--src/gallium/drivers/trace/README18
-rw-r--r--src/gallium/drivers/trace/SConscript2
-rw-r--r--src/gallium/drivers/trace/tr_buffer.c9
-rw-r--r--src/gallium/drivers/trace/tr_buffer.h8
-rw-r--r--src/gallium/drivers/trace/tr_context.c225
-rw-r--r--src/gallium/drivers/trace/tr_context.h40
-rw-r--r--src/gallium/drivers/trace/tr_dump.c177
-rw-r--r--src/gallium/drivers/trace/tr_dump.h38
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.c490
-rw-r--r--src/gallium/drivers/trace/tr_dump_state.h78
-rw-r--r--src/gallium/drivers/trace/tr_rbug.c864
-rw-r--r--src/gallium/drivers/trace/tr_screen.c78
-rw-r--r--src/gallium/drivers/trace/tr_screen.h61
-rw-r--r--src/gallium/drivers/trace/tr_state.c515
-rw-r--r--src/gallium/drivers/trace/tr_state.h108
-rw-r--r--src/gallium/drivers/trace/tr_texture.c21
-rw-r--r--src/gallium/drivers/trace/tr_texture.h6
-rw-r--r--src/gallium/include/pipe/p_atomic.h81
-rw-r--r--src/gallium/include/pipe/p_context.h40
-rw-r--r--src/gallium/include/pipe/p_defines.h23
-rw-r--r--src/gallium/include/pipe/p_format.h24
-rw-r--r--src/gallium/include/pipe/p_screen.h14
-rw-r--r--src/gallium/include/pipe/p_state.h1
-rw-r--r--src/gallium/include/pipe/p_thread.h2
-rw-r--r--src/gallium/include/state_tracker/dri1_api.h82
-rw-r--r--src/gallium/include/state_tracker/drm_api.h19
-rw-r--r--src/gallium/state_trackers/dri/Makefile (renamed from src/gallium/state_trackers/dri2/Makefile)2
-rw-r--r--src/gallium/state_trackers/dri/SConscript23
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c (renamed from src/gallium/state_trackers/dri2/dri_context.c)121
-rw-r--r--src/gallium/state_trackers/dri/dri_context.h (renamed from src/gallium/state_trackers/dri2/dri_context.h)59
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c605
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h (renamed from src/gallium/state_trackers/dri2/dri_drawable.h)46
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c (renamed from src/gallium/state_trackers/dri2/dri_extensions.c)18
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c (renamed from src/gallium/state_trackers/dri2/dri_screen.c)224
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h (renamed from src/gallium/state_trackers/dri2/dri_screen.h)20
-rw-r--r--src/gallium/state_trackers/dri2/dri_drawable.c325
-rw-r--r--src/gallium/state_trackers/egl/Makefile36
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.c2
-rw-r--r--src/gallium/state_trackers/glx/xlib/fakeglx.c13
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c21
-rw-r--r--src/gallium/state_trackers/python/p_texture.i2
-rwxr-xr-xsrc/gallium/state_trackers/python/retrace/interpreter.py48
-rwxr-xr-xsrc/gallium/state_trackers/python/retrace/parse.py392
-rwxr-xr-xsrc/gallium/state_trackers/python/retrace/parser.py360
-rw-r--r--src/gallium/state_trackers/python/st_softpipe_winsys.c2
-rwxr-xr-xsrc/gallium/state_trackers/python/tests/texture_sample.py223
-rw-r--r--src/gallium/state_trackers/wgl/SConscript3
-rw-r--r--src/gallium/state_trackers/wgl/icd/stw_icd.c741
-rw-r--r--src/gallium/state_trackers/wgl/icd/stw_icd.h6
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c186
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h61
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_context.c305
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_context.h3
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_device.c26
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_device.h17
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c (renamed from src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.c)26
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_framebuffer.c487
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_framebuffer.h52
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c30
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_pixelformat.c421
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_pixelformat.h62
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_public.h5
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_quirks.c116
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_tls.c37
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_tls.h6
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_winsys.h8
-rw-r--r--src/gallium/state_trackers/wgl/wgl/stw_wgl.c12
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c16
-rw-r--r--src/gallium/winsys/drm/Makefile.template2
-rw-r--r--src/gallium/winsys/drm/intel/SConscript7
-rw-r--r--src/gallium/winsys/drm/intel/dri/Makefile (renamed from src/gallium/winsys/drm/intel/dri2/Makefile)8
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript16
-rw-r--r--src/gallium/winsys/drm/intel/gem/SConscript17
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.c6
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.h3
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c14
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c47
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h2
-rw-r--r--src/gallium/winsys/drm/intel/xorg/Makefile5
-rw-r--r--src/gallium/winsys/drm/intel/xorg/intel_xorg.c9
-rw-r--r--src/gallium/winsys/drm/nouveau/Makefile2
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/Makefile19
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context.c118
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context.h53
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c73
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c330
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h16
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c115
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h11
-rw-r--r--src/gallium/winsys/drm/nouveau/dri2/Makefile26
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/Makefile4
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h (renamed from src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h)0
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c169
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h29
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c94
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c204
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h52
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c39
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h24
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c13
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h3
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c200
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.h13
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c33
-rw-r--r--src/gallium/winsys/drm/radeon/dri/Makefile (renamed from src/gallium/winsys/drm/radeon/dri2/Makefile)3
-rw-r--r--src/gallium/winsys/drm/radeon/dri/SConscript (renamed from src/gallium/winsys/drm/radeon/dri2/SConscript)0
-rw-r--r--src/gallium/winsys/drm/radeon/egl/Makefile1
-rw-r--r--src/gallium/winsys/drm/radeon/xorg/Makefile2
-rw-r--r--src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c9
-rw-r--r--src/gallium/winsys/egl_xlib/Makefile4
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c7
-rw-r--r--src/gallium/winsys/g3dvl/xsp_winsys.c2
-rw-r--r--src/gallium/winsys/gdi/SConscript1
-rw-r--r--src/gallium/winsys/gdi/gdi_softpipe_winsys.c14
-rw-r--r--src/gallium/winsys/xlib/Makefile4
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c2
-rw-r--r--src/gallium/winsys/xlib/xlib_trace.c16
301 files changed, 14554 insertions, 6300 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index 0c632ac2b8..32b7c2980a 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -22,6 +22,7 @@ SConscript([
'auxiliary/draw/SConscript',
'auxiliary/pipebuffer/SConscript',
'auxiliary/indices/SConscript',
+ 'auxiliary/rbug/SConscript',
])
for driver in env['drivers']:
@@ -29,6 +30,7 @@ for driver in env['drivers']:
SConscript('state_trackers/python/SConscript')
SConscript('state_trackers/glx/xlib/SConscript')
+SConscript('state_trackers/dri/SConscript')
if platform == 'windows':
SConscript('state_trackers/wgl/SConscript')
diff --git a/src/gallium/auxiliary/draw/draw_pipe.h b/src/gallium/auxiliary/draw/draw_pipe.h
index dbad8f98ac..479250729f 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.h
+++ b/src/gallium/auxiliary/draw/draw_pipe.h
@@ -57,6 +57,7 @@ struct draw_stage
struct draw_context *draw; /**< parent context */
struct draw_stage *next; /**< next stage in pipeline */
+ const char *name; /**< for debugging */
struct vertex_header **tmp; /**< temp vert storage, such as for clipping */
unsigned nr_tmps;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
index ca69f0b95e..9f956715a2 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
@@ -60,8 +60,6 @@ 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 */
};
@@ -373,10 +371,15 @@ 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;
+ goto fail;
aaline->fs->generic_attrib = transform.maxGeneric + 1;
+ FREE((void *)aaline_fs.tokens);
return TRUE;
+
+fail:
+ FREE((void *)aaline_fs.tokens);
+ return FALSE;
}
@@ -746,6 +749,7 @@ draw_aaline_stage(struct draw_context *draw)
goto fail;
aaline->stage.draw = draw;
+ aaline->stage.name = "aaline";
aaline->stage.next = NULL;
aaline->stage.point = draw_pipe_passthrough_point;
aaline->stage.line = aaline_first_line;
@@ -815,6 +819,10 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
/* pass-through */
aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
+
+ if (aafs->aaline_fs)
+ aaline->driver_delete_fs_state(aaline->pipe, aafs->aaline_fs);
+
FREE(aafs);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
index 3133abe5dc..ae1712fe12 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
@@ -523,11 +523,15 @@ 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;
+ goto fail;
aapoint->fs->generic_attrib = transform.maxGeneric + 1;
-
+ FREE((void *)aapoint_fs.tokens);
return TRUE;
+
+fail:
+ FREE((void *)aapoint_fs.tokens);
+ return FALSE;
}
@@ -757,6 +761,7 @@ draw_aapoint_stage(struct draw_context *draw)
goto fail;
aapoint->stage.draw = draw;
+ aapoint->stage.name = "aapoint";
aapoint->stage.next = NULL;
aapoint->stage.point = aapoint_first_point;
aapoint->stage.line = draw_pipe_passthrough_line;
@@ -824,8 +829,13 @@ 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);
+
+ if (aafs->aapoint_fs)
+ aapoint->driver_delete_fs_state(aapoint->pipe, aafs->aapoint_fs);
+
FREE(aafs);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index 3265dcd154..0670268a19 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -496,6 +496,7 @@ struct draw_stage *draw_clip_stage( struct draw_context *draw )
goto fail;
clipper->stage.draw = draw;
+ clipper->stage.name = "clipper";
clipper->stage.point = clip_point;
clipper->stage.line = clip_first_line;
clipper->stage.tri = clip_first_tri;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c
index 053be5f050..0a70483858 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_cull.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_cull.c
@@ -129,6 +129,7 @@ struct draw_stage *draw_cull_stage( struct draw_context *draw )
goto fail;
cull->stage.draw = draw;
+ cull->stage.name = "cull";
cull->stage.next = NULL;
cull->stage.point = draw_pipe_passthrough_point;
cull->stage.line = draw_pipe_passthrough_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
index 43d1fecc4d..34afb1a0b6 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
@@ -261,6 +261,7 @@ struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
goto fail;
flatshade->stage.draw = draw;
+ flatshade->stage.name = "flatshade";
flatshade->stage.next = NULL;
flatshade->stage.point = draw_pipe_passthrough_point;
flatshade->stage.line = flatshade_first_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c
index 62c31532d0..40798a5d6e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_offset.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_offset.c
@@ -166,6 +166,7 @@ struct draw_stage *draw_offset_stage( struct draw_context *draw )
draw_alloc_temp_verts( &offset->stage, 3 );
offset->stage.draw = draw;
+ offset->stage.name = "offset";
offset->stage.next = NULL;
offset->stage.point = draw_pipe_passthrough_point;
offset->stage.line = draw_pipe_passthrough_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 04e59152c5..30a6d2919d 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -358,6 +358,7 @@ generate_pstip_fs(struct pstip_stage *pstip)
pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
+ FREE((void *)pstip_fs.tokens);
return TRUE;
}
@@ -586,6 +587,7 @@ draw_pstip_stage(struct draw_context *draw)
draw_alloc_temp_verts( &pstip->stage, 8 );
pstip->stage.draw = draw;
+ pstip->stage.name = "pstip";
pstip->stage.next = NULL;
pstip->stage.point = draw_pipe_passthrough_point;
pstip->stage.line = draw_pipe_passthrough_line;
@@ -648,6 +650,10 @@ pstip_delete_fs_state(struct pipe_context *pipe, void *fs)
struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
/* pass-through */
pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs);
+
+ if (aafs->pstip_fs)
+ pstip->driver_delete_fs_state(pstip->pipe, aafs->pstip_fs);
+
FREE(aafs);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
index b65e2aa102..6e921bac27 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_stipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
@@ -238,6 +238,7 @@ struct draw_stage *draw_stipple_stage( struct draw_context *draw )
draw_alloc_temp_verts( &stipple->stage, 2 );
stipple->stage.draw = draw;
+ stipple->stage.name = "stipple";
stipple->stage.next = NULL;
stipple->stage.point = stipple_reset_point;
stipple->stage.line = stipple_first_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
index c329d92339..eef0238b15 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
@@ -181,6 +181,7 @@ struct draw_stage *draw_twoside_stage( struct draw_context *draw )
goto fail;
twoside->stage.draw = draw;
+ twoside->stage.name = "twoside";
twoside->stage.next = NULL;
twoside->stage.point = draw_pipe_passthrough_point;
twoside->stage.line = draw_pipe_passthrough_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
index 68835fd1a5..03bb842e20 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
@@ -184,6 +184,7 @@ struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
goto fail;
unfilled->stage.draw = draw;
+ unfilled->stage.name = "unfilled";
unfilled->stage.next = NULL;
unfilled->stage.tmp = NULL;
unfilled->stage.point = draw_pipe_passthrough_point;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c
index 03e842ce08..bea90e50d3 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_validate.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_validate.c
@@ -262,7 +262,15 @@ static struct draw_stage *validate_pipeline( struct draw_stage *stage )
draw->pipeline.first = next;
- return next;
+
+ if (0) {
+ debug_printf("draw pipeline:\n");
+ for (next = draw->pipeline.first; next ; next = next->next )
+ debug_printf(" %s\n", next->name);
+ debug_printf("\n");
+ }
+
+ return draw->pipeline.first;
}
static void validate_tri( struct draw_stage *stage,
@@ -318,6 +326,7 @@ struct draw_stage *draw_validate_stage( struct draw_context *draw )
return NULL;
stage->draw = draw;
+ stage->name = "validate";
stage->next = NULL;
stage->point = validate_point;
stage->line = validate_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
index 12325d30d6..a5d840b96e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
@@ -446,6 +446,7 @@ struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
goto fail;
vbuf->stage.draw = draw;
+ vbuf->stage.name = "vbuf";
vbuf->stage.point = vbuf_first_point;
vbuf->stage.line = vbuf_first_line;
vbuf->stage.tri = vbuf_first_tri;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
index 184e363594..f32cbef983 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
@@ -168,6 +168,7 @@ struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
draw_alloc_temp_verts( &wide->stage, 4 );
wide->stage.draw = draw;
+ wide->stage.name = "wide-line";
wide->stage.next = NULL;
wide->stage.point = draw_pipe_passthrough_point;
wide->stage.line = wideline_line;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index e1af9e56a2..d84bab9eaa 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -253,6 +253,7 @@ static void widepoint_flush( struct draw_stage *stage, unsigned flags )
{
stage->point = widepoint_first_point;
stage->next->flush( stage->next, flags );
+ stage->draw->extra_vp_outputs.slot = 0;
}
@@ -279,6 +280,7 @@ struct draw_stage *draw_wide_point_stage( struct draw_context *draw )
goto fail;
wide->stage.draw = draw;
+ wide->stage.name = "wide-point";
wide->stage.next = NULL;
wide->stage.point = widepoint_first_point;
wide->stage.line = draw_pipe_passthrough_line;
diff --git a/src/gallium/auxiliary/draw/draw_pt.h b/src/gallium/auxiliary/draw/draw_pt.h
index 6f3e1e0289..8ef0ea8011 100644
--- a/src/gallium/auxiliary/draw/draw_pt.h
+++ b/src/gallium/auxiliary/draw/draw_pt.h
@@ -187,6 +187,7 @@ struct pt_emit *draw_pt_emit_create( struct draw_context *draw );
struct pt_fetch;
void draw_pt_fetch_prepare( struct pt_fetch *fetch,
+ unsigned vertex_input_count,
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 058caf7dcc..65c3a34c34 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch.c
@@ -26,6 +26,7 @@
**************************************************************************/
#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"
@@ -56,9 +57,11 @@ struct pt_fetch {
*
*/
void draw_pt_fetch_prepare( struct pt_fetch *fetch,
+ unsigned vs_input_count,
unsigned vertex_size )
{
struct draw_context *draw = fetch->draw;
+ unsigned nr_inputs;
unsigned i, nr = 0;
unsigned dst_offset = 0;
struct translate_key key;
@@ -89,8 +92,11 @@ void draw_pt_fetch_prepare( struct pt_fetch *fetch,
dst_offset += 4 * sizeof(float);
}
+ assert( draw->pt.nr_vertex_elements >= vs_input_count );
- for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
+ nr_inputs = MIN2( vs_input_count, draw->pt.nr_vertex_elements );
+
+ for (i = 0; i < nr_inputs; 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;
@@ -114,7 +120,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, 0, 0xffff };
+ static struct vertex_header vh = { 0, 1, 0, UNDEFINED_VERTEX_ID, { .0f, .0f, .0f, .0f } };
fetch->translate->set_buffer(fetch->translate,
draw->pt.nr_vertex_buffers,
&vh,
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
index 6b7d02a19b..e7fe6b3b76 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_emit.c
@@ -130,6 +130,10 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
unsigned output_format;
switch (vinfo->attrib[i].emit) {
+ case EMIT_4UB:
+ output_format = PIPE_FORMAT_R8G8B8A8_UNORM;
+ emit_sz = 4 * sizeof(unsigned char);
+ break;
case EMIT_4F:
output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
emit_sz = 4 * sizeof(float);
@@ -153,6 +157,8 @@ static void fetch_emit_prepare( struct draw_pt_middle_end *middle,
output_format = PIPE_FORMAT_R32_FLOAT;
emit_sz = 1 * sizeof(float);
break;
+ case EMIT_OMIT:
+ continue;
default:
assert(0);
output_format = PIPE_FORMAT_NONE;
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 11ac90fc56..df6c265b7e 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline.c
@@ -77,8 +77,8 @@ static void fetch_pipeline_prepare( struct draw_pt_middle_end *middle,
draw_pt_fetch_prepare( fpme->fetch,
+ vs->info.num_inputs,
fpme->vertex_size );
-
/* XXX: it's not really gl rasterization rules we care about here,
* but gl vs dx9 clip spaces.
*/
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 55a8e6521d..010c7a18a7 100644
--- a/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
+++ b/src/gallium/auxiliary/draw/draw_pt_varray_tmp_linear.h
@@ -9,7 +9,7 @@ static void FUNC(struct draw_pt_front_end *frontend,
unsigned count)
{
struct varray_frontend *varray = (struct varray_frontend *)frontend;
- unsigned start = (unsigned)elts;
+ unsigned start = (unsigned) ((char *) elts - (char *) NULL);
unsigned j;
unsigned first, incr;
diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
index b358bd2df4..3240e3745d 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos_machine.c
@@ -74,7 +74,7 @@ void PIPE_CDECL aos_do_lit( struct aos_machine *machine,
{
result[0] = 1.0F;
result[1] = in[0];
- result[2] = 1.0;
+ result[2] = 0.0F;
result[3] = 1.0F;
}
else
@@ -108,7 +108,7 @@ static void PIPE_CDECL do_lit_lut( struct aos_machine *machine,
{
result[0] = 1.0F;
result[1] = in[0];
- result[2] = 1.0;
+ result[2] = 0.0F;
result[3] = 1.0F;
return;
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index dbbc33fffa..f2368dde5c 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -114,6 +114,12 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
#endif
for (slot = 0; slot < shader->info.num_inputs; slot++) {
+#if 0
+ assert(!util_is_inf_or_nan(input[slot][0]));
+ assert(!util_is_inf_or_nan(input[slot][1]));
+ assert(!util_is_inf_or_nan(input[slot][2]));
+ assert(!util_is_inf_or_nan(input[slot][3]));
+#endif
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];
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
index 925e948763..2d2af3085e 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
@@ -24,6 +24,8 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
+
+#include <cstdio>
#include "instructionssoa.h"
#include "storagesoa.h"
diff --git a/src/gallium/auxiliary/indices/u_unfilled_gen.c b/src/gallium/auxiliary/indices/u_unfilled_gen.c
index fd082ebbb3..93897c98de 100644
--- a/src/gallium/auxiliary/indices/u_unfilled_gen.c
+++ b/src/gallium/auxiliary/indices/u_unfilled_gen.c
@@ -71,13 +71,10 @@ static void generate_tris_ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (ushort)(i);
(out+j)[1] = (ushort)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)(i+1);
(out+j+2)[1] = (ushort)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (ushort)(i+2);
(out+j+4)[1] = (ushort)(i);
}
@@ -90,13 +87,10 @@ static void generate_tristrip_ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (ushort)(i);
(out+j)[1] = (ushort)(i+1/*+(i&1)*/);
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (ushort)(i+1/*+(i&1)*/);
(out+j+2)[1] = (ushort)(i+2/*-(i&1)*/);
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (ushort)(i+2/*-(i&1)*/);
(out+j+4)[1] = (ushort)(i);
}
@@ -109,13 +103,10 @@ static void generate_trifan_ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)(0);
(out+j)[1] = (ushort)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)(i+1);
(out+j+2)[1] = (ushort)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)(i+2);
(out+j+4)[1] = (ushort)(0);
}
@@ -128,16 +119,12 @@ static void generate_quads_ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (ushort)(i+0);
(out+j)[1] = (ushort)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)(i+1);
(out+j+2)[1] = (ushort)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (ushort)(i+2);
(out+j+4)[1] = (ushort)(i+3);
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (ushort)(i+3);
(out+j+6)[1] = (ushort)(i+0);
}
@@ -150,16 +137,12 @@ static void generate_quadstrip_ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (ushort)(i+2);
(out+j)[1] = (ushort)(i+0);
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (ushort)(i+0);
(out+j+2)[1] = (ushort)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (ushort)(i+1);
(out+j+4)[1] = (ushort)(i+3);
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (ushort)(i+3);
(out+j+6)[1] = (ushort)(i+2);
}
@@ -172,13 +155,10 @@ static void generate_polygon_ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)(0);
(out+j)[1] = (ushort)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)(i+1);
(out+j+2)[1] = (ushort)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)(i+2);
(out+j+4)[1] = (ushort)(0);
}
@@ -191,13 +171,10 @@ static void generate_tris_uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (uint)(i);
(out+j)[1] = (uint)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)(i+1);
(out+j+2)[1] = (uint)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (uint)(i+2);
(out+j+4)[1] = (uint)(i);
}
@@ -210,13 +187,10 @@ static void generate_tristrip_uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (uint)(i);
(out+j)[1] = (uint)(i+1/*+(i&1)*/);
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (uint)(i+1/*+(i&1)*/);
(out+j+2)[1] = (uint)(i+2/*-(i&1)*/);
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (uint)(i+2/*-(i&1)*/);
(out+j+4)[1] = (uint)(i);
}
@@ -229,13 +203,10 @@ static void generate_trifan_uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)(0);
(out+j)[1] = (uint)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)(i+1);
(out+j+2)[1] = (uint)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)(i+2);
(out+j+4)[1] = (uint)(0);
}
@@ -248,16 +219,12 @@ static void generate_quads_uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (uint)(i+0);
(out+j)[1] = (uint)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)(i+1);
(out+j+2)[1] = (uint)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (uint)(i+2);
(out+j+4)[1] = (uint)(i+3);
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (uint)(i+3);
(out+j+6)[1] = (uint)(i+0);
}
@@ -270,16 +237,12 @@ static void generate_quadstrip_uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (uint)(i+2);
(out+j)[1] = (uint)(i+0);
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (uint)(i+0);
(out+j+2)[1] = (uint)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (uint)(i+1);
(out+j+4)[1] = (uint)(i+3);
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (uint)(i+3);
(out+j+6)[1] = (uint)(i+2);
}
@@ -292,13 +255,10 @@ static void generate_polygon_uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)(0);
(out+j)[1] = (uint)(i+1);
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)(i+1);
(out+j+2)[1] = (uint)(i+2);
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)(i+2);
(out+j+4)[1] = (uint)(0);
}
@@ -313,13 +273,10 @@ static void translate_tris_ubyte2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (ushort)in[i];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[i];
}
@@ -334,13 +291,10 @@ static void translate_tristrip_ubyte2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (ushort)in[i];
(out+j)[1] = (ushort)in[i+1/*+(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (ushort)in[i+1/*+(i&1)*/];
(out+j+2)[1] = (ushort)in[i+2/*-(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (ushort)in[i+2/*-(i&1)*/];
(out+j+4)[1] = (ushort)in[i];
}
@@ -355,13 +309,10 @@ static void translate_trifan_ubyte2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)in[0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[0];
}
@@ -376,16 +327,12 @@ static void translate_quads_ubyte2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (ushort)in[i+0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (ushort)in[i+3];
(out+j+6)[1] = (ushort)in[i+0];
}
@@ -400,16 +347,12 @@ static void translate_quadstrip_ubyte2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (ushort)in[i+2];
(out+j)[1] = (ushort)in[i+0];
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (ushort)in[i+0];
(out+j+2)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (ushort)in[i+1];
(out+j+4)[1] = (ushort)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (ushort)in[i+3];
(out+j+6)[1] = (ushort)in[i+2];
}
@@ -424,13 +367,10 @@ static void translate_polygon_ubyte2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)in[0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[0];
}
@@ -445,13 +385,10 @@ static void translate_tris_ubyte2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (uint)in[i];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[i];
}
@@ -466,13 +403,10 @@ static void translate_tristrip_ubyte2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (uint)in[i];
(out+j)[1] = (uint)in[i+1/*+(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (uint)in[i+1/*+(i&1)*/];
(out+j+2)[1] = (uint)in[i+2/*-(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (uint)in[i+2/*-(i&1)*/];
(out+j+4)[1] = (uint)in[i];
}
@@ -487,13 +421,10 @@ static void translate_trifan_ubyte2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)in[0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[0];
}
@@ -508,16 +439,12 @@ static void translate_quads_ubyte2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (uint)in[i+0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (uint)in[i+3];
(out+j+6)[1] = (uint)in[i+0];
}
@@ -532,16 +459,12 @@ static void translate_quadstrip_ubyte2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (uint)in[i+2];
(out+j)[1] = (uint)in[i+0];
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (uint)in[i+0];
(out+j+2)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (uint)in[i+1];
(out+j+4)[1] = (uint)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (uint)in[i+3];
(out+j+6)[1] = (uint)in[i+2];
}
@@ -556,13 +479,10 @@ static void translate_polygon_ubyte2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)in[0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[0];
}
@@ -577,13 +497,10 @@ static void translate_tris_ushort2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (ushort)in[i];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[i];
}
@@ -598,13 +515,10 @@ static void translate_tristrip_ushort2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (ushort)in[i];
(out+j)[1] = (ushort)in[i+1/*+(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (ushort)in[i+1/*+(i&1)*/];
(out+j+2)[1] = (ushort)in[i+2/*-(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (ushort)in[i+2/*-(i&1)*/];
(out+j+4)[1] = (ushort)in[i];
}
@@ -619,13 +533,10 @@ static void translate_trifan_ushort2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)in[0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[0];
}
@@ -640,16 +551,12 @@ static void translate_quads_ushort2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (ushort)in[i+0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (ushort)in[i+3];
(out+j+6)[1] = (ushort)in[i+0];
}
@@ -664,16 +571,12 @@ static void translate_quadstrip_ushort2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (ushort)in[i+2];
(out+j)[1] = (ushort)in[i+0];
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (ushort)in[i+0];
(out+j+2)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (ushort)in[i+1];
(out+j+4)[1] = (ushort)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (ushort)in[i+3];
(out+j+6)[1] = (ushort)in[i+2];
}
@@ -688,13 +591,10 @@ static void translate_polygon_ushort2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)in[0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[0];
}
@@ -709,13 +609,10 @@ static void translate_tris_ushort2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (uint)in[i];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[i];
}
@@ -730,13 +627,10 @@ static void translate_tristrip_ushort2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (uint)in[i];
(out+j)[1] = (uint)in[i+1/*+(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (uint)in[i+1/*+(i&1)*/];
(out+j+2)[1] = (uint)in[i+2/*-(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (uint)in[i+2/*-(i&1)*/];
(out+j+4)[1] = (uint)in[i];
}
@@ -751,13 +645,10 @@ static void translate_trifan_ushort2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)in[0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[0];
}
@@ -772,16 +663,12 @@ static void translate_quads_ushort2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (uint)in[i+0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (uint)in[i+3];
(out+j+6)[1] = (uint)in[i+0];
}
@@ -796,16 +683,12 @@ static void translate_quadstrip_ushort2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (uint)in[i+2];
(out+j)[1] = (uint)in[i+0];
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (uint)in[i+0];
(out+j+2)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (uint)in[i+1];
(out+j+4)[1] = (uint)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (uint)in[i+3];
(out+j+6)[1] = (uint)in[i+2];
}
@@ -820,13 +703,10 @@ static void translate_polygon_ushort2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)in[0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[0];
}
@@ -841,13 +721,10 @@ static void translate_tris_uint2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (ushort)in[i];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[i];
}
@@ -862,13 +739,10 @@ static void translate_tristrip_uint2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (ushort)in[i];
(out+j)[1] = (ushort)in[i+1/*+(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (ushort)in[i+1/*+(i&1)*/];
(out+j+2)[1] = (ushort)in[i+2/*-(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (ushort)in[i+2/*-(i&1)*/];
(out+j+4)[1] = (ushort)in[i];
}
@@ -883,13 +757,10 @@ static void translate_trifan_uint2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)in[0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[0];
}
@@ -904,16 +775,12 @@ static void translate_quads_uint2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (ushort)in[i+0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (ushort)in[i+3];
(out+j+6)[1] = (ushort)in[i+0];
}
@@ -928,16 +795,12 @@ static void translate_quadstrip_uint2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (ushort)in[i+2];
(out+j)[1] = (ushort)in[i+0];
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (ushort)in[i+0];
(out+j+2)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (ushort)in[i+1];
(out+j+4)[1] = (ushort)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (ushort)in[i+3];
(out+j+6)[1] = (ushort)in[i+2];
}
@@ -952,13 +815,10 @@ static void translate_polygon_uint2ushort(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (ushort)in[0];
(out+j)[1] = (ushort)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (ushort)in[i+1];
(out+j+2)[1] = (ushort)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (ushort)in[i+2];
(out+j+4)[1] = (ushort)in[0];
}
@@ -973,13 +833,10 @@ static void translate_tris_uint2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i+=3) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1);
(out+j)[0] = (uint)in[i];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[i];
}
@@ -994,13 +851,10 @@ static void translate_tristrip_uint2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)i, (int)i+1/*+(i&1)*/);
(out+j)[0] = (uint)in[i];
(out+j)[1] = (uint)in[i+1/*+(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+1/*+(i&1)*/, (int)i+2/*-(i&1)*/);
(out+j+2)[0] = (uint)in[i+1/*+(i&1)*/];
(out+j+2)[1] = (uint)in[i+2/*-(i&1)*/];
- debug_printf(" line %d %d\n", (int)i+2/*-(i&1)*/, (int)i);
(out+j+4)[0] = (uint)in[i+2/*-(i&1)*/];
(out+j+4)[1] = (uint)in[i];
}
@@ -1015,13 +869,10 @@ static void translate_trifan_uint2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)in[0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[0];
}
@@ -1036,16 +887,12 @@ static void translate_quads_uint2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=4) {
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j)[0] = (uint)in[i+0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)i+3);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+0);
(out+j+6)[0] = (uint)in[i+3];
(out+j+6)[1] = (uint)in[i+0];
}
@@ -1060,16 +907,12 @@ static void translate_quadstrip_uint2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=8, i+=2) {
- debug_printf(" line %d %d\n", (int)i+2, (int)i+0);
(out+j)[0] = (uint)in[i+2];
(out+j)[1] = (uint)in[i+0];
- debug_printf(" line %d %d\n", (int)i+0, (int)i+1);
(out+j+2)[0] = (uint)in[i+0];
(out+j+2)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+3);
(out+j+4)[0] = (uint)in[i+1];
(out+j+4)[1] = (uint)in[i+3];
- debug_printf(" line %d %d\n", (int)i+3, (int)i+2);
(out+j+6)[0] = (uint)in[i+3];
(out+j+6)[1] = (uint)in[i+2];
}
@@ -1084,13 +927,10 @@ static void translate_polygon_uint2uint(
unsigned i, j;
(void)j;
for (j = i = 0; j < nr; j+=6, i++) {
- debug_printf(" line %d %d\n", (int)0, (int)i+1);
(out+j)[0] = (uint)in[0];
(out+j)[1] = (uint)in[i+1];
- debug_printf(" line %d %d\n", (int)i+1, (int)i+2);
(out+j+2)[0] = (uint)in[i+1];
(out+j+2)[1] = (uint)in[i+2];
- debug_printf(" line %d %d\n", (int)i+2, (int)0);
(out+j+4)[0] = (uint)in[i+2];
(out+j+4)[1] = (uint)in[0];
}
diff --git a/src/gallium/auxiliary/indices/u_unfilled_gen.py b/src/gallium/auxiliary/indices/u_unfilled_gen.py
index d0344fe313..36896ce605 100644
--- a/src/gallium/auxiliary/indices/u_unfilled_gen.py
+++ b/src/gallium/auxiliary/indices/u_unfilled_gen.py
@@ -99,7 +99,6 @@ def vert( intype, outtype, v0 ):
return '(' + outtype + ')in[' + v0 + ']'
def line( intype, outtype, ptr, v0, v1 ):
- print ' debug_printf(" line %d %d\\n", (int)' + v0 + ', (int)' + v1 + ');'
print ' (' + ptr + ')[0] = ' + vert( intype, outtype, v0 ) + ';'
print ' (' + ptr + ')[1] = ' + vert( intype, outtype, v1 ) + ';'
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 2cd0b8a8cd..4698efa69c 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -365,21 +365,22 @@ fenced_buffer_validate(struct pb_buffer *buf,
if(fenced_buf->vl && fenced_buf->vl != vl)
return PIPE_ERROR_RETRY;
+#if 0
/* Do not validate if buffer is still mapped */
if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
/* TODO: wait for the thread that mapped the buffer to unmap it */
return PIPE_ERROR_RETRY;
}
+ /* Final sanity checking */
+ assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
+ assert(!fenced_buf->mapcount);
+#endif
if(fenced_buf->vl == vl &&
(fenced_buf->validation_flags & flags) == flags) {
/* Nothing to do -- buffer already validated */
return PIPE_OK;
}
-
- /* Final sanity checking */
- assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE));
- assert(!fenced_buf->mapcount);
ret = pb_validate(fenced_buf->buffer, vl, flags);
if (ret != PIPE_OK)
@@ -530,16 +531,17 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
pipe_mutex_lock(fenced_list->mutex);
- debug_printf("%10s %7s %10s %s\n",
- "buffer", "reference.count", "fence", "signalled");
+ debug_printf("%10s %7s %7s %10s %s\n",
+ "buffer", "size", "refcount", "fence", "signalled");
curr = fenced_list->unfenced.next;
next = curr->next;
while(curr != &fenced_list->unfenced) {
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
assert(!fenced_buf->fence);
- debug_printf("%10p %7u\n",
+ debug_printf("%10p %7u %7u\n",
fenced_buf,
+ fenced_buf->base.base.size,
fenced_buf->base.base.reference.count);
curr = next;
next = curr->next;
@@ -551,8 +553,9 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
int signaled;
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head);
signaled = ops->fence_signalled(ops, fenced_buf->fence, 0);
- debug_printf("%10p %7u %10p %s\n",
+ debug_printf("%10p %7u %7u %10p %s\n",
fenced_buf,
+ fenced_buf->base.base.size,
fenced_buf->base.base.reference.count,
fenced_buf->fence,
signaled == 0 ? "y" : "n");
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
index f1a05be46e..cedf745bda 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
@@ -40,6 +40,7 @@
#include "util/u_memory.h"
#include "util/u_double_list.h"
#include "util/u_time.h"
+#include "util/u_debug_stack.h"
#include "pb_buffer.h"
#include "pb_bufmgr.h"
@@ -48,6 +49,10 @@
#ifdef DEBUG
+#define PB_DEBUG_CREATE_BACKTRACE 8
+#define PB_DEBUG_MAP_BACKTRACE 8
+
+
/**
* Convenience macro (type safe).
*/
@@ -69,6 +74,14 @@ struct pb_debug_buffer
size_t underflow_size;
size_t overflow_size;
+
+ struct debug_stack_frame create_backtrace[PB_DEBUG_CREATE_BACKTRACE];
+
+ pipe_mutex mutex;
+ unsigned map_count;
+ struct debug_stack_frame map_backtrace[PB_DEBUG_MAP_BACKTRACE];
+
+ struct list_head head;
};
@@ -80,6 +93,9 @@ struct pb_debug_manager
size_t underflow_size;
size_t overflow_size;
+
+ pipe_mutex mutex;
+ struct list_head list;
};
@@ -189,6 +205,9 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf)
max_ofs == buf->overflow_size - 1 ? "+" : "");
}
+ if(underflow || overflow)
+ debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
+
debug_assert(!underflow && !overflow);
/* re-fill if not aborted */
@@ -207,11 +226,18 @@ static void
pb_debug_buffer_destroy(struct pb_buffer *_buf)
{
struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
+ struct pb_debug_manager *mgr = buf->mgr;
assert(!pipe_is_referenced(&buf->base.base.reference));
pb_debug_buffer_check(buf);
+ pipe_mutex_lock(mgr->mutex);
+ LIST_DEL(&buf->head);
+ pipe_mutex_unlock(mgr->mutex);
+
+ pipe_mutex_destroy(buf->mutex);
+
pb_reference(&buf->buffer, NULL);
FREE(buf);
}
@@ -230,6 +256,13 @@ pb_debug_buffer_map(struct pb_buffer *_buf,
if(!map)
return NULL;
+ if(map) {
+ pipe_mutex_lock(buf->mutex);
+ ++buf->map_count;
+ debug_backtrace_capture(buf->map_backtrace, 1, PB_DEBUG_MAP_BACKTRACE);
+ pipe_mutex_unlock(buf->mutex);
+ }
+
return (uint8_t *)map + buf->underflow_size;
}
@@ -238,6 +271,13 @@ static void
pb_debug_buffer_unmap(struct pb_buffer *_buf)
{
struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
+
+ pipe_mutex_lock(buf->mutex);
+ assert(buf->map_count);
+ if(buf->map_count)
+ --buf->map_count;
+ pipe_mutex_unlock(buf->mutex);
+
pb_unmap(buf->buffer);
pb_debug_buffer_check(buf);
@@ -262,6 +302,14 @@ pb_debug_buffer_validate(struct pb_buffer *_buf,
{
struct pb_debug_buffer *buf = pb_debug_buffer(_buf);
+ pipe_mutex_lock(buf->mutex);
+ if(buf->map_count) {
+ debug_printf("%s: attempting to validate a mapped buffer\n", __FUNCTION__);
+ debug_printf("last map backtrace is\n");
+ debug_backtrace_dump(buf->map_backtrace, PB_DEBUG_MAP_BACKTRACE);
+ }
+ pipe_mutex_unlock(buf->mutex);
+
pb_debug_buffer_check(buf);
return pb_validate(buf->buffer, vl, flags);
@@ -288,6 +336,31 @@ pb_debug_buffer_vtbl = {
};
+static void
+pb_debug_manager_dump(struct pb_debug_manager *mgr)
+{
+ struct list_head *curr, *next;
+ struct pb_debug_buffer *buf;
+
+ pipe_mutex_lock(mgr->mutex);
+
+ curr = mgr->list.next;
+ next = curr->next;
+ while(curr != &mgr->list) {
+ buf = LIST_ENTRY(struct pb_debug_buffer, curr, head);
+
+ debug_printf("buffer = %p\n", buf);
+ debug_printf(" .size = %p\n", buf->base.base.size);
+ debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
+
+ curr = next;
+ next = curr->next;
+ }
+
+ pipe_mutex_unlock(mgr->mutex);
+}
+
+
static struct pb_buffer *
pb_debug_manager_create_buffer(struct pb_manager *_mgr,
size_t size,
@@ -312,6 +385,13 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr,
&real_desc);
if(!buf->buffer) {
FREE(buf);
+#if 0
+ pipe_mutex_lock(mgr->mutex);
+ debug_printf("%s: failed to create buffer\n", __FUNCTION__);
+ if(!LIST_IS_EMPTY(&mgr->list))
+ pb_debug_manager_dump(mgr);
+ pipe_mutex_unlock(mgr->mutex);
+#endif
return NULL;
}
@@ -331,8 +411,16 @@ pb_debug_manager_create_buffer(struct pb_manager *_mgr,
buf->underflow_size = mgr->underflow_size;
buf->overflow_size = buf->buffer->base.size - buf->underflow_size - size;
+ debug_backtrace_capture(buf->create_backtrace, 1, PB_DEBUG_CREATE_BACKTRACE);
+
pb_debug_buffer_fill(buf);
+ pipe_mutex_init(buf->mutex);
+
+ pipe_mutex_lock(mgr->mutex);
+ LIST_ADDTAIL(&buf->head, &mgr->list);
+ pipe_mutex_unlock(mgr->mutex);
+
return &buf->base;
}
@@ -351,6 +439,15 @@ static void
pb_debug_manager_destroy(struct pb_manager *_mgr)
{
struct pb_debug_manager *mgr = pb_debug_manager(_mgr);
+
+ pipe_mutex_lock(mgr->mutex);
+ if(!LIST_IS_EMPTY(&mgr->list)) {
+ debug_printf("%s: unfreed buffers\n", __FUNCTION__);
+ pb_debug_manager_dump(mgr);
+ }
+ pipe_mutex_unlock(mgr->mutex);
+
+ pipe_mutex_destroy(mgr->mutex);
mgr->provider->destroy(mgr->provider);
FREE(mgr);
}
@@ -375,7 +472,10 @@ pb_debug_manager_create(struct pb_manager *provider,
mgr->provider = provider;
mgr->underflow_size = underflow_size;
mgr->overflow_size = overflow_size;
-
+
+ pipe_mutex_init(mgr->mutex);
+ LIST_INITHEAD(&mgr->list);
+
return &mgr->base;
}
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c
index 5a342fbf3b..d8decba49d 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c
@@ -200,8 +200,8 @@ mm_bufmgr_create_buffer(struct pb_manager *mgr,
mm_buf->block = u_mmAllocMem(mm->heap, size, mm->align2, 0);
if(!mm_buf->block) {
- debug_printf("warning: heap full\n");
#if 0
+ debug_printf("warning: heap full\n");
mmDumpMemInfo(mm->heap);
#endif
FREE(mm_buf);
diff --git a/src/gallium/auxiliary/rbug/Makefile b/src/gallium/auxiliary/rbug/Makefile
new file mode 100644
index 0000000000..cd12e8468f
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/Makefile
@@ -0,0 +1,14 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = rbug
+
+C_SOURCES = \
+ rbug_connection.c \
+ rbug_core.c \
+ rbug_texture.c \
+ rbug_context.c \
+ rbug_shader.c \
+ rbug_demarshal.c
+
+include ../../Makefile.template
diff --git a/src/gallium/auxiliary/rbug/README b/src/gallium/auxiliary/rbug/README
new file mode 100644
index 0000000000..33d76371de
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/README
@@ -0,0 +1,21 @@
+ GALLIUM REMOTE DEBUGGING COMMON CODE
+
+= About =
+
+This directory contains the common code for the Gallium 3D remote debugging
+driver and clients. The code is two parts the connection managment code and
+the (de)marsheller.
+
+The code currently uses tcp and ip4v for connections.
+
+Information about driver integration can be found in:
+
+src/gallium/drivers/trace/README
+
+for information about applications look in:
+
+progs/rbug/README
+
+
+--
+Jakob Bornecrantz <jakob@vmware.com>
diff --git a/src/gallium/auxiliary/rbug/SConscript b/src/gallium/auxiliary/rbug/SConscript
new file mode 100644
index 0000000000..4a9afb45d3
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/SConscript
@@ -0,0 +1,14 @@
+Import('*')
+
+rbug = env.ConvenienceLibrary(
+ target = 'rbug',
+ source = [
+ 'rbug_core.c',
+ 'rbug_shader.c',
+ 'rbug_context.c',
+ 'rbug_texture.c',
+ 'rbug_demarshal.c',
+ 'rbug_connection.c',
+ ])
+
+auxiliaries.insert(0, rbug)
diff --git a/src/gallium/auxiliary/rbug/rbug.h b/src/gallium/auxiliary/rbug/rbug.h
new file mode 100644
index 0000000000..259bfc6c79
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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 all for users the remote debugger protocol code.
+ */
+
+#include "rbug/rbug_core.h"
+#include "rbug/rbug_shader.h"
+#include "rbug/rbug_context.h"
+#include "rbug/rbug_texture.h"
+#include "rbug/rbug_connection.h"
diff --git a/src/gallium/auxiliary/rbug/rbug_connection.c b/src/gallium/auxiliary/rbug/rbug_connection.c
new file mode 100644
index 0000000000..52acb700af
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_connection.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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 "rbug/rbug.h"
+#include "rbug/rbug_internal.h"
+
+#include "util/u_network.h"
+
+struct rbug_connection
+{
+ int socket;
+ uint32_t send_serial;
+ uint32_t recv_serial;
+ enum rbug_opcode opcode;
+};
+
+/**
+ * Create a rbug connection from a socket created with u_socket.
+ *
+ * Result:
+ * A new allocated connection using socket as communication path
+ */
+struct rbug_connection *
+rbug_from_socket(int socket)
+{
+ struct rbug_connection *c = CALLOC_STRUCT(rbug_connection);
+ c->socket = socket;
+ return c;
+}
+
+/**
+ * Free a connection, also closes socket.
+ */
+void
+rbug_disconnect(struct rbug_connection *c)
+{
+ u_socket_close(c->socket);
+ FREE(c);
+}
+
+/**
+ * Waits for a message to be fully received.
+ * Also returns the serial for the message, serial is not touched for replys.
+ *
+ * Result:
+ * demarshaled message on success, NULL on connection error
+ */
+struct rbug_header *
+rbug_get_message(struct rbug_connection *c, uint32_t *serial)
+{
+ struct rbug_proto_header header;
+ struct rbug_header *out;
+ struct rbug_proto_header *data;
+ size_t length = 0;
+ size_t read = 0;
+ int ret;
+
+
+ ret = u_socket_peek(c->socket, &header, sizeof(header));
+ if (ret <= 0) {
+ return NULL;
+ }
+
+ length = (size_t)header.length * 4;
+ data = MALLOC(length);
+ if (!data) {
+ return NULL;
+ }
+
+ do {
+ uint8_t *ptr = ((uint8_t*)data) + read;
+ ret = u_socket_recv(c->socket, ptr, length - read);
+
+ if (ret <= 0) {
+ FREE(data);
+ return NULL;
+ }
+
+ read += ret;
+ } while(read < length);
+
+ out = rbug_demarshal(data);
+ if (!out)
+ FREE(data);
+ else if (serial)
+ *serial = c->recv_serial++;
+ else
+ c->recv_serial++;
+
+ return out;
+}
+
+/**
+ * Frees a message and associated data.
+ */
+void
+rbug_free_header(struct rbug_header *header)
+{
+ if (!header)
+ return;
+
+ FREE(header->__message);
+ FREE(header);
+}
+
+/**
+ * Internal function used by rbug_send_* functions.
+ *
+ * Start sending a message.
+ */
+int
+rbug_connection_send_start(struct rbug_connection *c, enum rbug_opcode opcode, uint32_t length)
+{
+ c->opcode = opcode;
+ return 0;
+}
+
+/**
+ * Internal function used by rbug_send_* functions.
+ *
+ * Write data to the socket.
+ */
+int
+rbug_connection_write(struct rbug_connection *c, void *to, uint32_t size)
+{
+ int ret = u_socket_send(c->socket, to, size);
+ return ret;
+}
+
+/**
+ * Internal function used by rbug_send_* functions.
+ *
+ * Finish writeing data to the socket.
+ * Ups the send_serial and sets the serial argument if supplied.
+ */
+int rbug_connection_send_finish(struct rbug_connection *c, uint32_t *serial)
+{
+ if (c->opcode < 0)
+ return 0;
+ else if (serial)
+ *serial = c->send_serial++;
+ else
+ c->send_serial++;
+
+ return 0;
+}
diff --git a/src/gallium/auxiliary/rbug/rbug_connection.h b/src/gallium/auxiliary/rbug/rbug_connection.h
new file mode 100644
index 0000000000..1f2c9ff347
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_connection.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file contains the function defentions for connection see c file for
+ * more comments covering function use.
+ */
+
+#ifndef _RBUG_CONNECTION_H_
+#define _RBUG_CONNECTION_H_
+
+#include "rbug/rbug_proto.h"
+
+struct rbug_connection * rbug_from_socket(int socket);
+
+void rbug_disconnect(struct rbug_connection *c);
+
+struct rbug_header * rbug_get_message(struct rbug_connection *c, uint32_t *serial);
+
+void rbug_free_header(struct rbug_header *header);
+
+struct rbug_header * rbug_demarshal(struct rbug_proto_header *header);
+
+#endif
diff --git a/src/gallium/auxiliary/rbug/rbug_context.c b/src/gallium/auxiliary/rbug/rbug_context.c
new file mode 100644
index 0000000000..1832425658
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_context.c
@@ -0,0 +1,759 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds the function implementation for one of the rbug extensions.
+ * Prototypes and declerations of functions and structs is in the same folder
+ * in the header file matching this file's name.
+ *
+ * The functions starting rbug_send_* encodes a call to the write format and
+ * sends that to the supplied connection, while functions starting with
+ * rbug_demarshal_* demarshal data in the wire protocol.
+ *
+ * Functions ending with _reply are replies to requests.
+ */
+
+#include "rbug_internal.h"
+#include "rbug/rbug_context.h"
+
+int rbug_send_context_list(struct rbug_connection *__con,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_LIST));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_LIST, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_info(struct rbug_connection *__con,
+ rbug_context_t context,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_INFO));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_INFO, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_draw_block(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t block,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(4); /* block */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_DRAW_BLOCK));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(4, rbug_block_t, block); /* block */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_DRAW_BLOCK, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_draw_step(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t step,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(4); /* step */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_DRAW_STEP));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(4, rbug_block_t, step); /* step */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_DRAW_STEP, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_draw_unblock(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t unblock,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(4); /* unblock */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_DRAW_UNBLOCK));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(4, rbug_block_t, unblock); /* unblock */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_DRAW_UNBLOCK, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_draw_rule(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t vertex,
+ rbug_shader_t fragment,
+ rbug_texture_t texture,
+ rbug_texture_t surface,
+ rbug_block_t block,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(8); /* vertex */
+ LEN(8); /* fragment */
+ LEN(8); /* texture */
+ LEN(8); /* surface */
+ LEN(4); /* block */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_DRAW_RULE));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(8, rbug_shader_t, vertex); /* vertex */
+ WRITE(8, rbug_shader_t, fragment); /* fragment */
+ WRITE(8, rbug_texture_t, texture); /* texture */
+ WRITE(8, rbug_texture_t, surface); /* surface */
+ WRITE(4, rbug_block_t, block); /* block */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_DRAW_RULE, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_flush(struct rbug_connection *__con,
+ rbug_context_t context,
+ int32_t flags,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(4); /* flags */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_FLUSH));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(4, int32_t, flags); /* flags */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_FLUSH, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_list_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_context_t *contexts,
+ uint32_t contexts_len,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN_ARRAY(8, contexts); /* contexts */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_LIST_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE_ARRAY(8, rbug_context_t, contexts); /* contexts */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_LIST_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_info_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_shader_t vertex,
+ rbug_shader_t fragment,
+ rbug_texture_t *texs,
+ uint32_t texs_len,
+ rbug_texture_t *cbufs,
+ uint32_t cbufs_len,
+ rbug_texture_t zsbuf,
+ rbug_block_t blocker,
+ rbug_block_t blocked,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN(8); /* vertex */
+ LEN(8); /* fragment */
+ LEN_ARRAY(8, texs); /* texs */
+ LEN_ARRAY(8, cbufs); /* cbufs */
+ LEN(8); /* zsbuf */
+ LEN(4); /* blocker */
+ LEN(4); /* blocked */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_INFO_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE(8, rbug_shader_t, vertex); /* vertex */
+ WRITE(8, rbug_shader_t, fragment); /* fragment */
+ WRITE_ARRAY(8, rbug_texture_t, texs); /* texs */
+ WRITE_ARRAY(8, rbug_texture_t, cbufs); /* cbufs */
+ WRITE(8, rbug_texture_t, zsbuf); /* zsbuf */
+ WRITE(4, rbug_block_t, blocker); /* blocker */
+ WRITE(4, rbug_block_t, blocked); /* blocked */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_INFO_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_context_draw_blocked(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t block,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(4); /* block */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_DRAW_BLOCKED));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(4, rbug_block_t, block); /* block */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_CONTEXT_DRAW_BLOCKED, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_list *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_LIST)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+
+ return ret;
+}
+
+struct rbug_proto_context_info * rbug_demarshal_context_info(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_info *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_INFO)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+
+ return ret;
+}
+
+struct rbug_proto_context_draw_block * rbug_demarshal_context_draw_block(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_draw_block *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_DRAW_BLOCK)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(4, rbug_block_t, block); /* block */
+
+ return ret;
+}
+
+struct rbug_proto_context_draw_step * rbug_demarshal_context_draw_step(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_draw_step *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_DRAW_STEP)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(4, rbug_block_t, step); /* step */
+
+ return ret;
+}
+
+struct rbug_proto_context_draw_unblock * rbug_demarshal_context_draw_unblock(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_draw_unblock *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_DRAW_UNBLOCK)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(4, rbug_block_t, unblock); /* unblock */
+
+ return ret;
+}
+
+struct rbug_proto_context_draw_rule * rbug_demarshal_context_draw_rule(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_draw_rule *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_DRAW_RULE)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(8, rbug_shader_t, vertex); /* vertex */
+ READ(8, rbug_shader_t, fragment); /* fragment */
+ READ(8, rbug_texture_t, texture); /* texture */
+ READ(8, rbug_texture_t, surface); /* surface */
+ READ(4, rbug_block_t, block); /* block */
+
+ return ret;
+}
+
+struct rbug_proto_context_flush * rbug_demarshal_context_flush(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_flush *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_FLUSH)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(4, int32_t, flags); /* flags */
+
+ return ret;
+}
+
+struct rbug_proto_context_list_reply * rbug_demarshal_context_list_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_list_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_LIST_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ_ARRAY(8, rbug_context_t, contexts); /* contexts */
+
+ return ret;
+}
+
+struct rbug_proto_context_info_reply * rbug_demarshal_context_info_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_info_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_INFO_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ(8, rbug_shader_t, vertex); /* vertex */
+ READ(8, rbug_shader_t, fragment); /* fragment */
+ READ_ARRAY(8, rbug_texture_t, texs); /* texs */
+ READ_ARRAY(8, rbug_texture_t, cbufs); /* cbufs */
+ READ(8, rbug_texture_t, zsbuf); /* zsbuf */
+ READ(4, rbug_block_t, blocker); /* blocker */
+ READ(4, rbug_block_t, blocked); /* blocked */
+
+ return ret;
+}
+
+struct rbug_proto_context_draw_blocked * rbug_demarshal_context_draw_blocked(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_context_draw_blocked *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_CONTEXT_DRAW_BLOCKED)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(4, rbug_block_t, block); /* block */
+
+ return ret;
+}
diff --git a/src/gallium/auxiliary/rbug/rbug_context.h b/src/gallium/auxiliary/rbug/rbug_context.h
new file mode 100644
index 0000000000..da61c2365b
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_context.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds structs decelerations and function prototypes for one of
+ * the rbug extensions. Implementation of the functions is in the same folder
+ * in the c file matching this file's name.
+ *
+ * The structs what is returned from the demarshal functions. The functions
+ * starting rbug_send_* encodes a call to the write format and sends that to
+ * the supplied connection, while functions starting with rbug_demarshal_*
+ * demarshal data from the wire protocol.
+ *
+ * Structs and functions ending with _reply are replies to requests.
+ */
+
+#ifndef _RBUG_PROTO_CONTEXT_H_
+#define _RBUG_PROTO_CONTEXT_H_
+
+#include "rbug/rbug_proto.h"
+#include "rbug/rbug_core.h"
+
+typedef enum
+{
+ RBUG_BLOCK_BEFORE = 1,
+ RBUG_BLOCK_AFTER = 2,
+ RBUG_BLOCK_RULE = 4,
+ RBUG_BLOCK_MASK = 7,
+} rbug_block_t;
+
+struct rbug_proto_context_list
+{
+ struct rbug_header header;
+};
+
+struct rbug_proto_context_info
+{
+ struct rbug_header header;
+ rbug_context_t context;
+};
+
+struct rbug_proto_context_draw_block
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_block_t block;
+};
+
+struct rbug_proto_context_draw_step
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_block_t step;
+};
+
+struct rbug_proto_context_draw_unblock
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_block_t unblock;
+};
+
+struct rbug_proto_context_draw_rule
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_shader_t vertex;
+ rbug_shader_t fragment;
+ rbug_texture_t texture;
+ rbug_texture_t surface;
+ rbug_block_t block;
+};
+
+struct rbug_proto_context_flush
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ int32_t flags;
+};
+
+struct rbug_proto_context_list_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ rbug_context_t *contexts;
+ uint32_t contexts_len;
+};
+
+struct rbug_proto_context_info_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ rbug_shader_t vertex;
+ rbug_shader_t fragment;
+ rbug_texture_t *texs;
+ uint32_t texs_len;
+ rbug_texture_t *cbufs;
+ uint32_t cbufs_len;
+ rbug_texture_t zsbuf;
+ rbug_block_t blocker;
+ rbug_block_t blocked;
+};
+
+struct rbug_proto_context_draw_blocked
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_block_t block;
+};
+
+int rbug_send_context_list(struct rbug_connection *__con,
+ uint32_t *__serial);
+
+int rbug_send_context_info(struct rbug_connection *__con,
+ rbug_context_t context,
+ uint32_t *__serial);
+
+int rbug_send_context_draw_block(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t block,
+ uint32_t *__serial);
+
+int rbug_send_context_draw_step(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t step,
+ uint32_t *__serial);
+
+int rbug_send_context_draw_unblock(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t unblock,
+ uint32_t *__serial);
+
+int rbug_send_context_draw_rule(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t vertex,
+ rbug_shader_t fragment,
+ rbug_texture_t texture,
+ rbug_texture_t surface,
+ rbug_block_t block,
+ uint32_t *__serial);
+
+int rbug_send_context_flush(struct rbug_connection *__con,
+ rbug_context_t context,
+ int32_t flags,
+ uint32_t *__serial);
+
+int rbug_send_context_list_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_context_t *contexts,
+ uint32_t contexts_len,
+ uint32_t *__serial);
+
+int rbug_send_context_info_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_shader_t vertex,
+ rbug_shader_t fragment,
+ rbug_texture_t *texs,
+ uint32_t texs_len,
+ rbug_texture_t *cbufs,
+ uint32_t cbufs_len,
+ rbug_texture_t zsbuf,
+ rbug_block_t blocker,
+ rbug_block_t blocked,
+ uint32_t *__serial);
+
+int rbug_send_context_draw_blocked(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_block_t block,
+ uint32_t *__serial);
+
+struct rbug_proto_context_list * rbug_demarshal_context_list(struct rbug_proto_header *header);
+
+struct rbug_proto_context_info * rbug_demarshal_context_info(struct rbug_proto_header *header);
+
+struct rbug_proto_context_draw_block * rbug_demarshal_context_draw_block(struct rbug_proto_header *header);
+
+struct rbug_proto_context_draw_step * rbug_demarshal_context_draw_step(struct rbug_proto_header *header);
+
+struct rbug_proto_context_draw_unblock * rbug_demarshal_context_draw_unblock(struct rbug_proto_header *header);
+
+struct rbug_proto_context_draw_rule * rbug_demarshal_context_draw_rule(struct rbug_proto_header *header);
+
+struct rbug_proto_context_flush * rbug_demarshal_context_flush(struct rbug_proto_header *header);
+
+struct rbug_proto_context_list_reply * rbug_demarshal_context_list_reply(struct rbug_proto_header *header);
+
+struct rbug_proto_context_info_reply * rbug_demarshal_context_info_reply(struct rbug_proto_header *header);
+
+struct rbug_proto_context_draw_blocked * rbug_demarshal_context_draw_blocked(struct rbug_proto_header *header);
+
+#endif
diff --git a/src/gallium/auxiliary/rbug/rbug_core.c b/src/gallium/auxiliary/rbug/rbug_core.c
new file mode 100644
index 0000000000..876ae5a0ce
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_core.c
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds the function implementation for one of the rbug extensions.
+ * Prototypes and declerations of functions and structs is in the same folder
+ * in the header file matching this file's name.
+ *
+ * The functions starting rbug_send_* encodes a call to the write format and
+ * sends that to the supplied connection, while functions starting with
+ * rbug_demarshal_* demarshal data in the wire protocol.
+ *
+ * Functions ending with _reply are replies to requests.
+ */
+
+#include "rbug_internal.h"
+#include "rbug/rbug_core.h"
+
+int rbug_send_noop(struct rbug_connection *__con,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_NOOP));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_NOOP, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_ping(struct rbug_connection *__con,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_PING));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_PING, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_error(struct rbug_connection *__con,
+ uint32_t error,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* error */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_ERROR));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, error); /* error */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_ERROR, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_ping_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_PING_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_PING_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_error_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t error,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN(4); /* error */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_ERROR_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE(4, uint32_t, error); /* error */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_ERROR_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_noop *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_NOOP)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+
+ return ret;
+}
+
+struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_ping *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_PING)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+
+ return ret;
+}
+
+struct rbug_proto_error * rbug_demarshal_error(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_error *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_ERROR)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, error); /* error */
+
+ return ret;
+}
+
+struct rbug_proto_ping_reply * rbug_demarshal_ping_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_ping_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_PING_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+
+ return ret;
+}
+
+struct rbug_proto_error_reply * rbug_demarshal_error_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_error_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_ERROR_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ(4, uint32_t, error); /* error */
+
+ return ret;
+}
diff --git a/src/gallium/auxiliary/rbug/rbug_core.h b/src/gallium/auxiliary/rbug/rbug_core.h
new file mode 100644
index 0000000000..99a36a0163
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_core.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds structs decelerations and function prototypes for one of
+ * the rbug extensions. Implementation of the functions is in the same folder
+ * in the c file matching this file's name.
+ *
+ * The structs what is returned from the demarshal functions. The functions
+ * starting rbug_send_* encodes a call to the write format and sends that to
+ * the supplied connection, while functions starting with rbug_demarshal_*
+ * demarshal data from the wire protocol.
+ *
+ * Structs and functions ending with _reply are replies to requests.
+ */
+
+#ifndef _RBUG_PROTO_CORE_H_
+#define _RBUG_PROTO_CORE_H_
+
+#include "rbug/rbug_proto.h"
+
+typedef uint64_t rbug_shader_t;
+typedef uint64_t rbug_context_t;
+typedef uint64_t rbug_texture_t;
+
+struct rbug_proto_noop
+{
+ struct rbug_header header;
+};
+
+struct rbug_proto_ping
+{
+ struct rbug_header header;
+};
+
+struct rbug_proto_error
+{
+ struct rbug_header header;
+ uint32_t error;
+};
+
+struct rbug_proto_ping_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+};
+
+struct rbug_proto_error_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ uint32_t error;
+};
+
+int rbug_send_noop(struct rbug_connection *__con,
+ uint32_t *__serial);
+
+int rbug_send_ping(struct rbug_connection *__con,
+ uint32_t *__serial);
+
+int rbug_send_error(struct rbug_connection *__con,
+ uint32_t error,
+ uint32_t *__serial);
+
+int rbug_send_ping_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t *__serial);
+
+int rbug_send_error_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t error,
+ uint32_t *__serial);
+
+struct rbug_proto_noop * rbug_demarshal_noop(struct rbug_proto_header *header);
+
+struct rbug_proto_ping * rbug_demarshal_ping(struct rbug_proto_header *header);
+
+struct rbug_proto_error * rbug_demarshal_error(struct rbug_proto_header *header);
+
+struct rbug_proto_ping_reply * rbug_demarshal_ping_reply(struct rbug_proto_header *header);
+
+struct rbug_proto_error_reply * rbug_demarshal_error_reply(struct rbug_proto_header *header);
+
+#endif
diff --git a/src/gallium/auxiliary/rbug/rbug_demarshal.c b/src/gallium/auxiliary/rbug/rbug_demarshal.c
new file mode 100644
index 0000000000..47390fbcee
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_demarshal.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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 "rbug.h"
+
+/**
+ * Small function that looks at the proto_header and selects the correct
+ * demarshal functions and return the result.
+ */
+struct rbug_header * rbug_demarshal(struct rbug_proto_header *header)
+{
+ switch(header->opcode) {
+ case RBUG_OP_NOOP:
+ return (struct rbug_header *)rbug_demarshal_noop(header);
+ case RBUG_OP_PING:
+ return (struct rbug_header *)rbug_demarshal_ping(header);
+ case RBUG_OP_ERROR:
+ return (struct rbug_header *)rbug_demarshal_error(header);
+ case RBUG_OP_PING_REPLY:
+ return (struct rbug_header *)rbug_demarshal_ping_reply(header);
+ case RBUG_OP_ERROR_REPLY:
+ return (struct rbug_header *)rbug_demarshal_error_reply(header);
+ case RBUG_OP_TEXTURE_LIST:
+ return (struct rbug_header *)rbug_demarshal_texture_list(header);
+ case RBUG_OP_TEXTURE_INFO:
+ return (struct rbug_header *)rbug_demarshal_texture_info(header);
+ case RBUG_OP_TEXTURE_WRITE:
+ return (struct rbug_header *)rbug_demarshal_texture_write(header);
+ case RBUG_OP_TEXTURE_READ:
+ return (struct rbug_header *)rbug_demarshal_texture_read(header);
+ case RBUG_OP_TEXTURE_LIST_REPLY:
+ return (struct rbug_header *)rbug_demarshal_texture_list_reply(header);
+ case RBUG_OP_TEXTURE_INFO_REPLY:
+ return (struct rbug_header *)rbug_demarshal_texture_info_reply(header);
+ case RBUG_OP_TEXTURE_READ_REPLY:
+ return (struct rbug_header *)rbug_demarshal_texture_read_reply(header);
+ case RBUG_OP_CONTEXT_LIST:
+ return (struct rbug_header *)rbug_demarshal_context_list(header);
+ case RBUG_OP_CONTEXT_INFO:
+ return (struct rbug_header *)rbug_demarshal_context_info(header);
+ case RBUG_OP_CONTEXT_DRAW_BLOCK:
+ return (struct rbug_header *)rbug_demarshal_context_draw_block(header);
+ case RBUG_OP_CONTEXT_DRAW_STEP:
+ return (struct rbug_header *)rbug_demarshal_context_draw_step(header);
+ case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
+ return (struct rbug_header *)rbug_demarshal_context_draw_unblock(header);
+ case RBUG_OP_CONTEXT_DRAW_RULE:
+ return (struct rbug_header *)rbug_demarshal_context_draw_rule(header);
+ case RBUG_OP_CONTEXT_FLUSH:
+ return (struct rbug_header *)rbug_demarshal_context_flush(header);
+ case RBUG_OP_CONTEXT_LIST_REPLY:
+ return (struct rbug_header *)rbug_demarshal_context_list_reply(header);
+ case RBUG_OP_CONTEXT_INFO_REPLY:
+ return (struct rbug_header *)rbug_demarshal_context_info_reply(header);
+ case RBUG_OP_CONTEXT_DRAW_BLOCKED:
+ return (struct rbug_header *)rbug_demarshal_context_draw_blocked(header);
+ case RBUG_OP_SHADER_LIST:
+ return (struct rbug_header *)rbug_demarshal_shader_list(header);
+ case RBUG_OP_SHADER_INFO:
+ return (struct rbug_header *)rbug_demarshal_shader_info(header);
+ case RBUG_OP_SHADER_DISABLE:
+ return (struct rbug_header *)rbug_demarshal_shader_disable(header);
+ case RBUG_OP_SHADER_REPLACE:
+ return (struct rbug_header *)rbug_demarshal_shader_replace(header);
+ case RBUG_OP_SHADER_LIST_REPLY:
+ return (struct rbug_header *)rbug_demarshal_shader_list_reply(header);
+ case RBUG_OP_SHADER_INFO_REPLY:
+ return (struct rbug_header *)rbug_demarshal_shader_info_reply(header);
+ default:
+ return NULL;
+ }
+}
diff --git a/src/gallium/auxiliary/rbug/rbug_internal.h b/src/gallium/auxiliary/rbug/rbug_internal.h
new file mode 100644
index 0000000000..4aba1a810f
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_internal.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file is internal to the rbug protocol code, and contains asorted
+ * features needed by the code.
+ */
+
+#ifndef _RBUG_INTERNAL_H_
+#define _RBUG_INTERNAL_H_
+
+#include "rbug/rbug_proto.h"
+
+#include "util/u_memory.h"
+#include "util/u_debug.h"
+#include <errno.h>
+
+int rbug_connection_send_start(struct rbug_connection *con, enum rbug_opcode opcode, uint32_t length);
+int rbug_connection_write(struct rbug_connection *con, void *data, uint32_t size);
+int rbug_connection_send_finish(struct rbug_connection *con, uint32_t *c);
+
+/**
+ * Only works with multiples of 2
+ */
+#define PAD(from, to) \
+do { \
+ from = (from + to - 1) & ~(to - 1); \
+} while(0)
+
+#define LEN(size) \
+do { \
+ PAD(__len, size); \
+ __len += size; \
+} while(0)
+
+#define LEN_ARRAY(size, name) \
+do { \
+ LEN(4); \
+ PAD(__len, size); \
+ __len += size * name##_len; \
+} while(0)
+
+#define WRITE(size, type, name) \
+do { \
+ PAD(__pos, size); \
+ *((type *)(&__data[__pos])) = name; \
+ __pos += size; \
+} while(0)
+
+#define WRITE_ARRAY(size, type, name) \
+do { \
+ WRITE(4, uint32_t, name##_len); \
+ PAD(__pos, size); \
+ memcpy(&__data[__pos], name, size * name##_len); \
+ __pos += size * name##_len; \
+} while(0)
+
+#define READ(size, type, name) \
+do { \
+ PAD(pos, size); \
+ pos += size; \
+ if (pos > len) \
+ break; \
+ ret->name = *((type *)(&data[pos - size])); \
+} while(0)
+
+#define READ_ARRAY(size, type, name) \
+do { \
+ READ(4, uint32_t, name##_len); \
+ if (pos > len) \
+ break; \
+ PAD(pos, size); \
+ pos += size * ret->name##_len; \
+ if (pos > len) \
+ break; \
+ ret->name = (type *)&data[pos - size * ret->name##_len]; \
+} while(0)
+
+#endif
diff --git a/src/gallium/auxiliary/rbug/rbug_proto.h b/src/gallium/auxiliary/rbug/rbug_proto.h
new file mode 100644
index 0000000000..d273be0166
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_proto.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds common definitions of the gallium remote debugging protocol.
+ */
+
+#ifndef _RBUG_PROTO_H_
+#define _RBUG_PROTO_H_
+
+#include "pipe/p_compiler.h"
+
+/**
+ * Uniqe indentifier for each command.
+ *
+ * Replys are designated by negative.
+ */
+enum rbug_opcode
+{
+ RBUG_OP_NOOP = 0,
+ RBUG_OP_PING = 1,
+ RBUG_OP_ERROR = 2,
+ RBUG_OP_PING_REPLY = -1,
+ RBUG_OP_ERROR_REPLY = -2,
+ RBUG_OP_TEXTURE_LIST = 256,
+ RBUG_OP_TEXTURE_INFO = 257,
+ RBUG_OP_TEXTURE_WRITE = 258,
+ RBUG_OP_TEXTURE_READ = 259,
+ RBUG_OP_TEXTURE_LIST_REPLY = -256,
+ RBUG_OP_TEXTURE_INFO_REPLY = -257,
+ RBUG_OP_TEXTURE_READ_REPLY = -259,
+ RBUG_OP_CONTEXT_LIST = 512,
+ RBUG_OP_CONTEXT_INFO = 513,
+ RBUG_OP_CONTEXT_DRAW_BLOCK = 514,
+ RBUG_OP_CONTEXT_DRAW_STEP = 515,
+ RBUG_OP_CONTEXT_DRAW_UNBLOCK = 516,
+ RBUG_OP_CONTEXT_DRAW_RULE = 518,
+ RBUG_OP_CONTEXT_FLUSH = 519,
+ RBUG_OP_CONTEXT_LIST_REPLY = -512,
+ RBUG_OP_CONTEXT_INFO_REPLY = -513,
+ RBUG_OP_CONTEXT_DRAW_BLOCKED = 517,
+ RBUG_OP_SHADER_LIST = 768,
+ RBUG_OP_SHADER_INFO = 769,
+ RBUG_OP_SHADER_DISABLE = 770,
+ RBUG_OP_SHADER_REPLACE = 771,
+ RBUG_OP_SHADER_LIST_REPLY = -768,
+ RBUG_OP_SHADER_INFO_REPLY = -769,
+};
+
+/**
+ * Header for demarshaled message.
+ */
+struct rbug_header
+{
+ enum rbug_opcode opcode;
+ void *__message;
+};
+
+/**
+ * Header for a message in wire format.
+ */
+struct rbug_proto_header
+{
+ int32_t opcode;
+ uint32_t length;
+};
+
+/**
+ * Forward declare connection here, as this file is included by all users.
+ */
+struct rbug_connection;
+
+#endif
diff --git a/src/gallium/auxiliary/rbug/rbug_shader.c b/src/gallium/auxiliary/rbug/rbug_shader.c
new file mode 100644
index 0000000000..fccd2f55ef
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_shader.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds the function implementation for one of the rbug extensions.
+ * Prototypes and declerations of functions and structs is in the same folder
+ * in the header file matching this file's name.
+ *
+ * The functions starting rbug_send_* encodes a call to the write format and
+ * sends that to the supplied connection, while functions starting with
+ * rbug_demarshal_* demarshal data in the wire protocol.
+ *
+ * Functions ending with _reply are replies to requests.
+ */
+
+#include "rbug_internal.h"
+#include "rbug/rbug_shader.h"
+
+int rbug_send_shader_list(struct rbug_connection *__con,
+ rbug_context_t context,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_LIST));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_SHADER_LIST, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_shader_info(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t shader,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(8); /* shader */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_INFO));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(8, rbug_shader_t, shader); /* shader */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_SHADER_INFO, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_shader_disable(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t shader,
+ uint8_t disable,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(8); /* shader */
+ LEN(1); /* disable */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_DISABLE));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(8, rbug_shader_t, shader); /* shader */
+ WRITE(1, uint8_t, disable); /* disable */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_SHADER_DISABLE, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_shader_replace(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t shader,
+ uint32_t *tokens,
+ uint32_t tokens_len,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* context */
+ LEN(8); /* shader */
+ LEN_ARRAY(4, tokens); /* tokens */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_REPLACE));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_context_t, context); /* context */
+ WRITE(8, rbug_shader_t, shader); /* shader */
+ WRITE_ARRAY(4, uint32_t, tokens); /* tokens */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_SHADER_REPLACE, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_shader_list_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_shader_t *shaders,
+ uint32_t shaders_len,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN_ARRAY(8, shaders); /* shaders */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_LIST_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE_ARRAY(8, rbug_shader_t, shaders); /* shaders */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_SHADER_LIST_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_shader_info_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t *original,
+ uint32_t original_len,
+ uint32_t *replaced,
+ uint32_t replaced_len,
+ uint8_t disabled,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN_ARRAY(4, original); /* original */
+ LEN_ARRAY(4, replaced); /* replaced */
+ LEN(1); /* disabled */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_SHADER_INFO_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE_ARRAY(4, uint32_t, original); /* original */
+ WRITE_ARRAY(4, uint32_t, replaced); /* replaced */
+ WRITE(1, uint8_t, disabled); /* disabled */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_SHADER_INFO_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+struct rbug_proto_shader_list * rbug_demarshal_shader_list(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_shader_list *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_SHADER_LIST)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+
+ return ret;
+}
+
+struct rbug_proto_shader_info * rbug_demarshal_shader_info(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_shader_info *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_SHADER_INFO)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(8, rbug_shader_t, shader); /* shader */
+
+ return ret;
+}
+
+struct rbug_proto_shader_disable * rbug_demarshal_shader_disable(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_shader_disable *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_SHADER_DISABLE)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(8, rbug_shader_t, shader); /* shader */
+ READ(1, uint8_t, disable); /* disable */
+
+ return ret;
+}
+
+struct rbug_proto_shader_replace * rbug_demarshal_shader_replace(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_shader_replace *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_SHADER_REPLACE)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_context_t, context); /* context */
+ READ(8, rbug_shader_t, shader); /* shader */
+ READ_ARRAY(4, uint32_t, tokens); /* tokens */
+
+ return ret;
+}
+
+struct rbug_proto_shader_list_reply * rbug_demarshal_shader_list_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_shader_list_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_SHADER_LIST_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ_ARRAY(8, rbug_shader_t, shaders); /* shaders */
+
+ return ret;
+}
+
+struct rbug_proto_shader_info_reply * rbug_demarshal_shader_info_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_shader_info_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_SHADER_INFO_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ_ARRAY(4, uint32_t, original); /* original */
+ READ_ARRAY(4, uint32_t, replaced); /* replaced */
+ READ(1, uint8_t, disabled); /* disabled */
+
+ return ret;
+}
diff --git a/src/gallium/auxiliary/rbug/rbug_shader.h b/src/gallium/auxiliary/rbug/rbug_shader.h
new file mode 100644
index 0000000000..b5d886781d
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_shader.h
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds structs decelerations and function prototypes for one of
+ * the rbug extensions. Implementation of the functions is in the same folder
+ * in the c file matching this file's name.
+ *
+ * The structs what is returned from the demarshal functions. The functions
+ * starting rbug_send_* encodes a call to the write format and sends that to
+ * the supplied connection, while functions starting with rbug_demarshal_*
+ * demarshal data from the wire protocol.
+ *
+ * Structs and functions ending with _reply are replies to requests.
+ */
+
+#ifndef _RBUG_PROTO_SHADER_H_
+#define _RBUG_PROTO_SHADER_H_
+
+#include "rbug/rbug_proto.h"
+#include "rbug/rbug_core.h"
+
+struct rbug_proto_shader_list
+{
+ struct rbug_header header;
+ rbug_context_t context;
+};
+
+struct rbug_proto_shader_info
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_shader_t shader;
+};
+
+struct rbug_proto_shader_disable
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_shader_t shader;
+ uint8_t disable;
+};
+
+struct rbug_proto_shader_replace
+{
+ struct rbug_header header;
+ rbug_context_t context;
+ rbug_shader_t shader;
+ uint32_t *tokens;
+ uint32_t tokens_len;
+};
+
+struct rbug_proto_shader_list_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ rbug_shader_t *shaders;
+ uint32_t shaders_len;
+};
+
+struct rbug_proto_shader_info_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ uint32_t *original;
+ uint32_t original_len;
+ uint32_t *replaced;
+ uint32_t replaced_len;
+ uint8_t disabled;
+};
+
+int rbug_send_shader_list(struct rbug_connection *__con,
+ rbug_context_t context,
+ uint32_t *__serial);
+
+int rbug_send_shader_info(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t shader,
+ uint32_t *__serial);
+
+int rbug_send_shader_disable(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t shader,
+ uint8_t disable,
+ uint32_t *__serial);
+
+int rbug_send_shader_replace(struct rbug_connection *__con,
+ rbug_context_t context,
+ rbug_shader_t shader,
+ uint32_t *tokens,
+ uint32_t tokens_len,
+ uint32_t *__serial);
+
+int rbug_send_shader_list_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_shader_t *shaders,
+ uint32_t shaders_len,
+ uint32_t *__serial);
+
+int rbug_send_shader_info_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t *original,
+ uint32_t original_len,
+ uint32_t *replaced,
+ uint32_t replaced_len,
+ uint8_t disabled,
+ uint32_t *__serial);
+
+struct rbug_proto_shader_list * rbug_demarshal_shader_list(struct rbug_proto_header *header);
+
+struct rbug_proto_shader_info * rbug_demarshal_shader_info(struct rbug_proto_header *header);
+
+struct rbug_proto_shader_disable * rbug_demarshal_shader_disable(struct rbug_proto_header *header);
+
+struct rbug_proto_shader_replace * rbug_demarshal_shader_replace(struct rbug_proto_header *header);
+
+struct rbug_proto_shader_list_reply * rbug_demarshal_shader_list_reply(struct rbug_proto_header *header);
+
+struct rbug_proto_shader_info_reply * rbug_demarshal_shader_info_reply(struct rbug_proto_header *header);
+
+#endif
diff --git a/src/gallium/auxiliary/rbug/rbug_texture.c b/src/gallium/auxiliary/rbug/rbug_texture.c
new file mode 100644
index 0000000000..5a918fe6bc
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_texture.c
@@ -0,0 +1,631 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds the function implementation for one of the rbug extensions.
+ * Prototypes and declerations of functions and structs is in the same folder
+ * in the header file matching this file's name.
+ *
+ * The functions starting rbug_send_* encodes a call to the write format and
+ * sends that to the supplied connection, while functions starting with
+ * rbug_demarshal_* demarshal data in the wire protocol.
+ *
+ * Functions ending with _reply are replies to requests.
+ */
+
+#include "rbug_internal.h"
+#include "rbug/rbug_texture.h"
+
+int rbug_send_texture_list(struct rbug_connection *__con,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_LIST));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_LIST, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_texture_info(struct rbug_connection *__con,
+ rbug_texture_t texture,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* texture */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_INFO));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_texture_t, texture); /* texture */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_INFO, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_texture_write(struct rbug_connection *__con,
+ rbug_texture_t texture,
+ uint32_t face,
+ uint32_t level,
+ uint32_t zslice,
+ uint32_t x,
+ uint32_t y,
+ uint32_t w,
+ uint32_t h,
+ uint8_t *data,
+ uint32_t data_len,
+ uint32_t stride,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* texture */
+ LEN(4); /* face */
+ LEN(4); /* level */
+ LEN(4); /* zslice */
+ LEN(4); /* x */
+ LEN(4); /* y */
+ LEN(4); /* w */
+ LEN(4); /* h */
+ LEN_ARRAY(1, data); /* data */
+ LEN(4); /* stride */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_WRITE));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_texture_t, texture); /* texture */
+ WRITE(4, uint32_t, face); /* face */
+ WRITE(4, uint32_t, level); /* level */
+ WRITE(4, uint32_t, zslice); /* zslice */
+ WRITE(4, uint32_t, x); /* x */
+ WRITE(4, uint32_t, y); /* y */
+ WRITE(4, uint32_t, w); /* w */
+ WRITE(4, uint32_t, h); /* h */
+ WRITE_ARRAY(1, uint8_t, data); /* data */
+ WRITE(4, uint32_t, stride); /* stride */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_WRITE, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_texture_read(struct rbug_connection *__con,
+ rbug_texture_t texture,
+ uint32_t face,
+ uint32_t level,
+ uint32_t zslice,
+ uint32_t x,
+ uint32_t y,
+ uint32_t w,
+ uint32_t h,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(8); /* texture */
+ LEN(4); /* face */
+ LEN(4); /* level */
+ LEN(4); /* zslice */
+ LEN(4); /* x */
+ LEN(4); /* y */
+ LEN(4); /* w */
+ LEN(4); /* h */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_READ));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(8, rbug_texture_t, texture); /* texture */
+ WRITE(4, uint32_t, face); /* face */
+ WRITE(4, uint32_t, level); /* level */
+ WRITE(4, uint32_t, zslice); /* zslice */
+ WRITE(4, uint32_t, x); /* x */
+ WRITE(4, uint32_t, y); /* y */
+ WRITE(4, uint32_t, w); /* w */
+ WRITE(4, uint32_t, h); /* h */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_READ, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_texture_list_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_texture_t *textures,
+ uint32_t textures_len,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN_ARRAY(8, textures); /* textures */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_LIST_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE_ARRAY(8, rbug_texture_t, textures); /* textures */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_LIST_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_texture_info_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t target,
+ uint32_t format,
+ uint32_t *width,
+ uint32_t width_len,
+ uint32_t *height,
+ uint32_t height_len,
+ uint32_t *depth,
+ uint32_t depth_len,
+ uint32_t blockw,
+ uint32_t blockh,
+ uint32_t blocksize,
+ uint32_t last_level,
+ uint32_t nr_samples,
+ uint32_t tex_usage,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN(4); /* target */
+ LEN(4); /* format */
+ LEN_ARRAY(4, width); /* width */
+ LEN_ARRAY(4, height); /* height */
+ LEN_ARRAY(4, depth); /* depth */
+ LEN(4); /* blockw */
+ LEN(4); /* blockh */
+ LEN(4); /* blocksize */
+ LEN(4); /* last_level */
+ LEN(4); /* nr_samples */
+ LEN(4); /* tex_usage */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_INFO_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE(4, uint32_t, target); /* target */
+ WRITE(4, uint32_t, format); /* format */
+ WRITE_ARRAY(4, uint32_t, width); /* width */
+ WRITE_ARRAY(4, uint32_t, height); /* height */
+ WRITE_ARRAY(4, uint32_t, depth); /* depth */
+ WRITE(4, uint32_t, blockw); /* blockw */
+ WRITE(4, uint32_t, blockh); /* blockh */
+ WRITE(4, uint32_t, blocksize); /* blocksize */
+ WRITE(4, uint32_t, last_level); /* last_level */
+ WRITE(4, uint32_t, nr_samples); /* nr_samples */
+ WRITE(4, uint32_t, tex_usage); /* tex_usage */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_INFO_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+int rbug_send_texture_read_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t format,
+ uint32_t blockw,
+ uint32_t blockh,
+ uint32_t blocksize,
+ uint8_t *data,
+ uint32_t data_len,
+ uint32_t stride,
+ uint32_t *__serial)
+{
+ uint32_t __len = 0;
+ uint32_t __pos = 0;
+ uint8_t *__data = NULL;
+ int __ret = 0;
+
+ LEN(8); /* header */
+ LEN(4); /* serial */
+ LEN(4); /* format */
+ LEN(4); /* blockw */
+ LEN(4); /* blockh */
+ LEN(4); /* blocksize */
+ LEN_ARRAY(1, data); /* data */
+ LEN(4); /* stride */
+
+ /* align */
+ PAD(__len, 8);
+
+ __data = (uint8_t*)MALLOC(__len);
+ if (!__data)
+ return -ENOMEM;
+
+ WRITE(4, int32_t, ((int32_t)RBUG_OP_TEXTURE_READ_REPLY));
+ WRITE(4, uint32_t, ((uint32_t)(__len / 4)));
+ WRITE(4, uint32_t, serial); /* serial */
+ WRITE(4, uint32_t, format); /* format */
+ WRITE(4, uint32_t, blockw); /* blockw */
+ WRITE(4, uint32_t, blockh); /* blockh */
+ WRITE(4, uint32_t, blocksize); /* blocksize */
+ WRITE_ARRAY(1, uint8_t, data); /* data */
+ WRITE(4, uint32_t, stride); /* stride */
+
+ /* final pad */
+ PAD(__pos, 8);
+
+ if (__pos != __len) {
+ __ret = -EINVAL;
+ } else {
+ rbug_connection_send_start(__con, RBUG_OP_TEXTURE_READ_REPLY, __len);
+ rbug_connection_write(__con, __data, __len);
+ __ret = rbug_connection_send_finish(__con, __serial);
+ }
+
+ FREE(__data);
+ return __ret;
+}
+
+struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_list *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_LIST)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+
+ return ret;
+}
+
+struct rbug_proto_texture_info * rbug_demarshal_texture_info(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_info *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_INFO)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_texture_t, texture); /* texture */
+
+ return ret;
+}
+
+struct rbug_proto_texture_write * rbug_demarshal_texture_write(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_write *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_WRITE)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_texture_t, texture); /* texture */
+ READ(4, uint32_t, face); /* face */
+ READ(4, uint32_t, level); /* level */
+ READ(4, uint32_t, zslice); /* zslice */
+ READ(4, uint32_t, x); /* x */
+ READ(4, uint32_t, y); /* y */
+ READ(4, uint32_t, w); /* w */
+ READ(4, uint32_t, h); /* h */
+ READ_ARRAY(1, uint8_t, data); /* data */
+ READ(4, uint32_t, stride); /* stride */
+
+ return ret;
+}
+
+struct rbug_proto_texture_read * rbug_demarshal_texture_read(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_read *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_READ)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(8, rbug_texture_t, texture); /* texture */
+ READ(4, uint32_t, face); /* face */
+ READ(4, uint32_t, level); /* level */
+ READ(4, uint32_t, zslice); /* zslice */
+ READ(4, uint32_t, x); /* x */
+ READ(4, uint32_t, y); /* y */
+ READ(4, uint32_t, w); /* w */
+ READ(4, uint32_t, h); /* h */
+
+ return ret;
+}
+
+struct rbug_proto_texture_list_reply * rbug_demarshal_texture_list_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_list_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_LIST_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ_ARRAY(8, rbug_texture_t, textures); /* textures */
+
+ return ret;
+}
+
+struct rbug_proto_texture_info_reply * rbug_demarshal_texture_info_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_info_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_INFO_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ(4, uint32_t, target); /* target */
+ READ(4, uint32_t, format); /* format */
+ READ_ARRAY(4, uint32_t, width); /* width */
+ READ_ARRAY(4, uint32_t, height); /* height */
+ READ_ARRAY(4, uint32_t, depth); /* depth */
+ READ(4, uint32_t, blockw); /* blockw */
+ READ(4, uint32_t, blockh); /* blockh */
+ READ(4, uint32_t, blocksize); /* blocksize */
+ READ(4, uint32_t, last_level); /* last_level */
+ READ(4, uint32_t, nr_samples); /* nr_samples */
+ READ(4, uint32_t, tex_usage); /* tex_usage */
+
+ return ret;
+}
+
+struct rbug_proto_texture_read_reply * rbug_demarshal_texture_read_reply(struct rbug_proto_header *header)
+{
+ uint32_t len = 0;
+ uint32_t pos = 0;
+ uint8_t *data = NULL;
+ struct rbug_proto_texture_read_reply *ret;
+
+ if (!header)
+ return NULL;
+ if (header->opcode != (int16_t)RBUG_OP_TEXTURE_READ_REPLY)
+ return NULL;
+
+ pos = 0;
+ len = header->length * 4;
+ data = (uint8_t*)&header[1];
+ ret = MALLOC(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->header.__message = header;
+ ret->header.opcode = header->opcode;
+
+ READ(4, uint32_t, serial); /* serial */
+ READ(4, uint32_t, format); /* format */
+ READ(4, uint32_t, blockw); /* blockw */
+ READ(4, uint32_t, blockh); /* blockh */
+ READ(4, uint32_t, blocksize); /* blocksize */
+ READ_ARRAY(1, uint8_t, data); /* data */
+ READ(4, uint32_t, stride); /* stride */
+
+ return ret;
+}
diff --git a/src/gallium/auxiliary/rbug/rbug_texture.h b/src/gallium/auxiliary/rbug/rbug_texture.h
new file mode 100644
index 0000000000..fbb247e1d4
--- /dev/null
+++ b/src/gallium/auxiliary/rbug/rbug_texture.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2009 VMware, 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
+ * VMWARE 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.
+ */
+
+/*
+ * This file holds structs decelerations and function prototypes for one of
+ * the rbug extensions. Implementation of the functions is in the same folder
+ * in the c file matching this file's name.
+ *
+ * The structs what is returned from the demarshal functions. The functions
+ * starting rbug_send_* encodes a call to the write format and sends that to
+ * the supplied connection, while functions starting with rbug_demarshal_*
+ * demarshal data from the wire protocol.
+ *
+ * Structs and functions ending with _reply are replies to requests.
+ */
+
+#ifndef _RBUG_PROTO_TEXTURE_H_
+#define _RBUG_PROTO_TEXTURE_H_
+
+#include "rbug/rbug_proto.h"
+#include "rbug/rbug_core.h"
+
+struct rbug_proto_texture_list
+{
+ struct rbug_header header;
+};
+
+struct rbug_proto_texture_info
+{
+ struct rbug_header header;
+ rbug_texture_t texture;
+};
+
+struct rbug_proto_texture_write
+{
+ struct rbug_header header;
+ rbug_texture_t texture;
+ uint32_t face;
+ uint32_t level;
+ uint32_t zslice;
+ uint32_t x;
+ uint32_t y;
+ uint32_t w;
+ uint32_t h;
+ uint8_t *data;
+ uint32_t data_len;
+ uint32_t stride;
+};
+
+struct rbug_proto_texture_read
+{
+ struct rbug_header header;
+ rbug_texture_t texture;
+ uint32_t face;
+ uint32_t level;
+ uint32_t zslice;
+ uint32_t x;
+ uint32_t y;
+ uint32_t w;
+ uint32_t h;
+};
+
+struct rbug_proto_texture_list_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ rbug_texture_t *textures;
+ uint32_t textures_len;
+};
+
+struct rbug_proto_texture_info_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ uint32_t target;
+ uint32_t format;
+ uint32_t *width;
+ uint32_t width_len;
+ uint32_t *height;
+ uint32_t height_len;
+ uint32_t *depth;
+ uint32_t depth_len;
+ uint32_t blockw;
+ uint32_t blockh;
+ uint32_t blocksize;
+ uint32_t last_level;
+ uint32_t nr_samples;
+ uint32_t tex_usage;
+};
+
+struct rbug_proto_texture_read_reply
+{
+ struct rbug_header header;
+ uint32_t serial;
+ uint32_t format;
+ uint32_t blockw;
+ uint32_t blockh;
+ uint32_t blocksize;
+ uint8_t *data;
+ uint32_t data_len;
+ uint32_t stride;
+};
+
+int rbug_send_texture_list(struct rbug_connection *__con,
+ uint32_t *__serial);
+
+int rbug_send_texture_info(struct rbug_connection *__con,
+ rbug_texture_t texture,
+ uint32_t *__serial);
+
+int rbug_send_texture_write(struct rbug_connection *__con,
+ rbug_texture_t texture,
+ uint32_t face,
+ uint32_t level,
+ uint32_t zslice,
+ uint32_t x,
+ uint32_t y,
+ uint32_t w,
+ uint32_t h,
+ uint8_t *data,
+ uint32_t data_len,
+ uint32_t stride,
+ uint32_t *__serial);
+
+int rbug_send_texture_read(struct rbug_connection *__con,
+ rbug_texture_t texture,
+ uint32_t face,
+ uint32_t level,
+ uint32_t zslice,
+ uint32_t x,
+ uint32_t y,
+ uint32_t w,
+ uint32_t h,
+ uint32_t *__serial);
+
+int rbug_send_texture_list_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ rbug_texture_t *textures,
+ uint32_t textures_len,
+ uint32_t *__serial);
+
+int rbug_send_texture_info_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t target,
+ uint32_t format,
+ uint32_t *width,
+ uint32_t width_len,
+ uint32_t *height,
+ uint32_t height_len,
+ uint32_t *depth,
+ uint32_t depth_len,
+ uint32_t blockw,
+ uint32_t blockh,
+ uint32_t blocksize,
+ uint32_t last_level,
+ uint32_t nr_samples,
+ uint32_t tex_usage,
+ uint32_t *__serial);
+
+int rbug_send_texture_read_reply(struct rbug_connection *__con,
+ uint32_t serial,
+ uint32_t format,
+ uint32_t blockw,
+ uint32_t blockh,
+ uint32_t blocksize,
+ uint8_t *data,
+ uint32_t data_len,
+ uint32_t stride,
+ uint32_t *__serial);
+
+struct rbug_proto_texture_list * rbug_demarshal_texture_list(struct rbug_proto_header *header);
+
+struct rbug_proto_texture_info * rbug_demarshal_texture_info(struct rbug_proto_header *header);
+
+struct rbug_proto_texture_write * rbug_demarshal_texture_write(struct rbug_proto_header *header);
+
+struct rbug_proto_texture_read * rbug_demarshal_texture_read(struct rbug_proto_header *header);
+
+struct rbug_proto_texture_list_reply * rbug_demarshal_texture_list_reply(struct rbug_proto_header *header);
+
+struct rbug_proto_texture_info_reply * rbug_demarshal_texture_info_reply(struct rbug_proto_header *header);
+
+struct rbug_proto_texture_read_reply * rbug_demarshal_texture_read_reply(struct rbug_proto_header *header);
+
+#endif
diff --git a/src/gallium/auxiliary/rtasm/rtasm_cpu.c b/src/gallium/auxiliary/rtasm/rtasm_cpu.c
index 03bdd47238..2e15751e50 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_cpu.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_cpu.c
@@ -30,6 +30,7 @@
#include "rtasm_cpu.h"
+#if defined(PIPE_ARCH_X86)
static boolean rtasm_sse_enabled(void)
{
static boolean firsttime = 1;
@@ -43,6 +44,7 @@ static boolean rtasm_sse_enabled(void)
}
return enabled;
}
+#endif
int rtasm_cpu_has_sse(void)
{
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index e8bd7cda3b..aba7a3f937 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -53,6 +53,7 @@
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
+#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi_exec.h"
@@ -169,6 +170,56 @@ print_temp(const struct tgsi_exec_machine *mach, uint index)
#endif
+/**
+ * Check if there's a potential src/dst register data dependency when
+ * using SOA execution.
+ * Example:
+ * MOV T, T.yxwz;
+ * This would expand into:
+ * MOV t0, t1;
+ * MOV t1, t0;
+ * MOV t2, t3;
+ * MOV t3, t2;
+ * The second instruction will have the wrong value for t0 if executed as-is.
+ */
+static boolean
+tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst)
+{
+ uint i, chan;
+
+ uint writemask = inst->FullDstRegisters[0].DstRegister.WriteMask;
+ if (writemask == TGSI_WRITEMASK_X ||
+ writemask == TGSI_WRITEMASK_Y ||
+ writemask == TGSI_WRITEMASK_Z ||
+ writemask == TGSI_WRITEMASK_W ||
+ writemask == TGSI_WRITEMASK_NONE) {
+ /* no chance of data dependency */
+ return FALSE;
+ }
+
+ /* loop over src regs */
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ if ((inst->FullSrcRegisters[i].SrcRegister.File ==
+ inst->FullDstRegisters[0].DstRegister.File) &&
+ (inst->FullSrcRegisters[i].SrcRegister.Index ==
+ inst->FullDstRegisters[0].DstRegister.Index)) {
+ /* loop over dest channels */
+ uint channelsWritten = 0x0;
+ FOR_EACH_ENABLED_CHANNEL(*inst, chan) {
+ /* check if we're reading a channel that's been written */
+ uint swizzle = tgsi_util_get_full_src_register_extswizzle(&inst->FullSrcRegisters[i], chan);
+ if (swizzle <= TGSI_SWIZZLE_W &&
+ (channelsWritten & (1 << swizzle))) {
+ return TRUE;
+ }
+
+ channelsWritten |= (1 << chan);
+ }
+ }
+ }
+ return FALSE;
+}
+
/**
* Initialize machine state by expanding tokens to full instructions,
@@ -280,6 +331,17 @@ tgsi_exec_machine_bind_shader(
memcpy(instructions + numInstructions,
&parse.FullToken.FullInstruction,
sizeof(instructions[0]));
+
+#if 0
+ if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) {
+ debug_printf("SOA dependency in instruction:\n");
+ tgsi_dump_instruction(&parse.FullToken.FullInstruction,
+ numInstructions);
+ }
+#else
+ (void) tgsi_check_soa_dependencies;
+#endif
+
numInstructions++;
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 0b4b2a6fb6..da22baad3e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -34,7 +34,7 @@
extern "C" {
#endif
-#define MAX_LABELS 1024
+#define MAX_LABELS (4 * 1024) /**< basically, max instructions */
#define NUM_CHANNELS 4 /* R,G,B,A */
#define QUAD_SIZE 4 /* 4 pixel/quad */
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index d70bcd03c5..ba2bfdef06 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -1466,6 +1466,31 @@ emit_cmp(
}
}
+
+/**
+ * Check if inst src/dest regs use indirect addressing into temporary
+ * register file.
+ */
+static boolean
+indirect_temp_reference(const struct tgsi_full_instruction *inst)
+{
+ uint i;
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[i];
+ if (reg->SrcRegister.File == TGSI_FILE_TEMPORARY &&
+ reg->SrcRegister.Indirect)
+ return TRUE;
+ }
+ for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+ const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[i];
+ if (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
+ reg->DstRegister.Indirect)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
static int
emit_instruction(
struct x86_function *func,
@@ -1473,10 +1498,15 @@ emit_instruction(
{
unsigned chan_index;
+ /* we can't handle indirect addressing into temp register file yet */
+ if (indirect_temp_reference(inst))
+ return FALSE;
+
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
+ emit_flr(func, 0, 0);
emit_f2it( func, 0 );
STORE( func, *inst, 0, 0, chan_index );
}
@@ -1553,7 +1583,7 @@ emit_instruction(
func,
make_xmm( 2 ),
make_xmm( 0 ),
- cc_LessThanEqual );
+ cc_LessThan );
sse_andps(
func,
make_xmm( 2 ),
@@ -2177,32 +2207,83 @@ emit_instruction(
/* 3 or 4-component normalization */
{
uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
- /* note: cannot use xmm regs 2/3 here (see emit_rsqrt() above) */
- FETCH( func, *inst, 4, 0, CHAN_X ); /* xmm4 = src[0].x */
- FETCH( func, *inst, 5, 0, CHAN_Y ); /* xmm5 = src[0].y */
- FETCH( func, *inst, 6, 0, CHAN_Z ); /* xmm6 = src[0].z */
- if (dims == 4) {
- FETCH( func, *inst, 7, 0, CHAN_W ); /* xmm7 = src[0].w */
- }
- emit_MOV( func, 0, 4 ); /* xmm0 = xmm3 */
- emit_mul( func, 0, 4 ); /* xmm0 *= xmm3 */
- emit_MOV( func, 1, 5 ); /* xmm1 = xmm4 */
- emit_mul( func, 1, 5 ); /* xmm1 *= xmm4 */
- emit_add( func, 0, 1 ); /* xmm0 += xmm1 */
- emit_MOV( func, 1, 6 ); /* xmm1 = xmm5 */
- emit_mul( func, 1, 6 ); /* xmm1 *= xmm5 */
- emit_add( func, 0, 1 ); /* xmm0 += xmm1 */
- if (dims == 4) {
- emit_MOV( func, 1, 7 ); /* xmm1 = xmm7 */
- emit_mul( func, 1, 7 ); /* xmm1 *= xmm7 */
- emit_add( func, 0, 0 ); /* xmm0 += xmm1 */
- }
- emit_rsqrt( func, 1, 0 ); /* xmm1 = 1/sqrt(xmm0) */
- FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
- if (chan_index < dims) {
- emit_mul( func, 4+chan_index, 1); /* xmm[4+ch] *= xmm1 */
- STORE( func, *inst, 4+chan_index, 0, chan_index );
+
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X) ||
+ IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y) ||
+ IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z) ||
+ (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W) && dims == 4)) {
+
+ /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
+
+ /* xmm4 = src.x */
+ /* xmm0 = src.x * src.x */
+ FETCH(func, *inst, 0, 0, CHAN_X);
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X)) {
+ emit_MOV(func, 4, 0);
+ }
+ emit_mul(func, 0, 0);
+
+ /* xmm5 = src.y */
+ /* xmm0 = xmm0 + src.y * src.y */
+ FETCH(func, *inst, 1, 0, CHAN_Y);
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y)) {
+ emit_MOV(func, 5, 1);
+ }
+ emit_mul(func, 1, 1);
+ emit_add(func, 0, 1);
+
+ /* xmm6 = src.z */
+ /* xmm0 = xmm0 + src.z * src.z */
+ FETCH(func, *inst, 1, 0, CHAN_Z);
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z)) {
+ emit_MOV(func, 6, 1);
+ }
+ emit_mul(func, 1, 1);
+ emit_add(func, 0, 1);
+
+ if (dims == 4) {
+ /* xmm7 = src.w */
+ /* xmm0 = xmm0 + src.w * src.w */
+ FETCH(func, *inst, 1, 0, CHAN_W);
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W)) {
+ emit_MOV(func, 7, 1);
+ }
+ emit_mul(func, 1, 1);
+ emit_add(func, 0, 1);
}
+
+ /* xmm1 = 1 / sqrt(xmm0) */
+ emit_rsqrt(func, 1, 0);
+
+ /* dst.x = xmm1 * src.x */
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X)) {
+ emit_mul(func, 4, 1);
+ STORE(func, *inst, 4, 0, CHAN_X);
+ }
+
+ /* dst.y = xmm1 * src.y */
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y)) {
+ emit_mul(func, 5, 1);
+ STORE(func, *inst, 5, 0, CHAN_Y);
+ }
+
+ /* dst.z = xmm1 * src.z */
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z)) {
+ emit_mul(func, 6, 1);
+ STORE(func, *inst, 6, 0, CHAN_Z);
+ }
+
+ /* dst.w = xmm1 * src.w */
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X) && dims == 4) {
+ emit_mul(func, 7, 1);
+ STORE(func, *inst, 7, 0, CHAN_W);
+ }
+ }
+
+ /* dst0.w = 1.0 */
+ if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W) && dims == 3) {
+ emit_tempf(func, 0, TEMP_ONE_I, TEMP_ONE_C);
+ STORE(func, *inst, 0, 0, CHAN_W);
}
}
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_transform.c b/src/gallium/auxiliary/tgsi/tgsi_transform.c
index 062c1be938..bc9c18fd4a 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_transform.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_transform.c
@@ -198,3 +198,30 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
return ctx->ti;
}
+
+
+#include "tgsi_text.h"
+
+extern int tgsi_transform_foo( struct tgsi_token *tokens_out,
+ uint max_tokens_out );
+
+/* This function exists only so that tgsi_text_translate() doesn't get
+ * magic-ed out of the libtgsi.a archive by the build system. Don't
+ * remove unless you know this has been fixed - check on mingw/scons
+ * builds as well.
+ */
+int
+tgsi_transform_foo( struct tgsi_token *tokens_out,
+ uint max_tokens_out )
+{
+ const char *text =
+ "FRAG1.1\n"
+ "DCL IN[0], COLOR, CONSTANT\n"
+ "DCL OUT[0], COLOR\n"
+ " 0: MOV OUT[0], IN[0]\n"
+ " 1: END";
+
+ return tgsi_text_translate( text,
+ tokens_out,
+ max_tokens_out );
+}
diff --git a/src/gallium/auxiliary/trace/trace_drm.h b/src/gallium/auxiliary/trace/trace_drm.h
new file mode 100644
index 0000000000..892bd9860c
--- /dev/null
+++ b/src/gallium/auxiliary/trace/trace_drm.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2009 Jakob Bornecrantz <jakob@vmware.com>
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to 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
+ * THE AUTHOR(S) 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 TRACE_DRM_H
+#define TRACE_DRM_H
+
+#include "state_tracker/drm_api.h"
+
+#include "trace/tr_buffer.h"
+#include "trace/tr_context.h"
+#include "trace/tr_screen.h"
+#include "trace/tr_texture.h"
+
+struct drm_api hooks;
+
+static struct pipe_screen *
+trace_drm_create_screen(int fd, struct drm_create_screen_arg *arg)
+{
+ struct pipe_screen *screen;
+
+ if (arg && arg->mode != DRM_CREATE_NORMAL)
+ return NULL;
+
+ screen = hooks.create_screen(fd, arg);
+
+ return trace_screen_create(screen);
+};
+
+static struct pipe_context *
+trace_drm_create_context(struct pipe_screen *_screen)
+{
+ struct pipe_screen *screen;
+ struct pipe_context *pipe;
+
+ if (trace_enabled())
+ screen = trace_screen(_screen)->screen;
+ else
+ screen = _screen;
+
+ pipe = hooks.create_context(screen);
+
+ if (trace_enabled())
+ pipe = trace_context_create(_screen, pipe);
+
+ return pipe;
+};
+
+static boolean
+trace_drm_buffer_from_texture(struct pipe_texture *_texture,
+ struct pipe_buffer **_buffer,
+ unsigned *stride)
+{
+ struct pipe_texture *texture;
+ struct pipe_buffer *buffer = NULL;
+ boolean result;
+
+ if (trace_enabled())
+ texture = trace_texture(_texture)->texture;
+ else
+ texture = _texture;
+
+ result = hooks.buffer_from_texture(texture, &buffer, stride);
+
+ if (result && _buffer)
+ buffer = trace_buffer_create(trace_screen(texture->screen), buffer);
+
+ if (_buffer)
+ *_buffer = buffer;
+ else
+ pipe_buffer_reference(&buffer, NULL);
+
+ return result;
+}
+
+static struct pipe_buffer *
+trace_drm_buffer_from_handle(struct pipe_screen *_screen,
+ const char *name,
+ unsigned handle)
+{
+ struct pipe_screen *screen;
+ struct pipe_buffer *result;
+
+ if (trace_enabled())
+ screen = trace_screen(_screen)->screen;
+ else
+ screen = _screen;
+
+ result = hooks.buffer_from_handle(screen, name, handle);
+
+ if (trace_enabled())
+ result = trace_buffer_create(trace_screen(_screen), result);
+
+ return result;
+}
+
+static boolean
+trace_drm_handle_from_buffer(struct pipe_screen *_screen,
+ struct pipe_buffer *_buffer,
+ unsigned *handle)
+{
+ struct pipe_screen *screen;
+ struct pipe_buffer *buffer;
+
+ if (trace_enabled()) {
+ screen = trace_screen(_screen)->screen;
+ buffer = trace_buffer(_buffer)->buffer;
+ } else {
+ screen = _screen;
+ buffer = _buffer;
+ }
+
+ return hooks.handle_from_buffer(screen, buffer, handle);
+}
+
+static boolean
+trace_drm_global_handle_from_buffer(struct pipe_screen *_screen,
+ struct pipe_buffer *_buffer,
+ unsigned *handle)
+{
+ struct pipe_screen *screen;
+ struct pipe_buffer *buffer;
+
+ if (trace_enabled()) {
+ screen = trace_screen(_screen)->screen;
+ buffer = trace_buffer(_buffer)->buffer;
+ } else {
+ screen = _screen;
+ buffer = _buffer;
+ }
+
+ return hooks.global_handle_from_buffer(screen, buffer, handle);
+}
+
+struct drm_api drm_api_hooks =
+{
+ .create_screen = trace_drm_create_screen,
+ .create_context = trace_drm_create_context,
+
+ .buffer_from_texture = trace_drm_buffer_from_texture,
+ .buffer_from_handle = trace_drm_buffer_from_handle,
+ .handle_from_buffer = trace_drm_handle_from_buffer,
+ .global_handle_from_buffer = trace_drm_global_handle_from_buffer,
+};
+
+#endif /* TRACE_DRM_H */
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
index 5035e9cc13..6a8eb73e84 100644
--- a/src/gallium/auxiliary/util/Makefile
+++ b/src/gallium/auxiliary/util/Makefile
@@ -16,6 +16,7 @@ C_SOURCES = \
u_hash.c \
u_keymap.c \
u_linear.c \
+ u_network.c \
u_math.c \
u_mm.c \
u_rect.c \
@@ -23,6 +24,7 @@ C_SOURCES = \
u_snprintf.c \
u_stream_stdc.c \
u_stream_wd.c \
+ u_surface.c \
u_tile.c \
u_time.c \
u_timed_winsys.c \
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
index 8317263bb8..fb142eebca 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -17,6 +17,7 @@ util = env.ConvenienceLibrary(
'u_hash.c',
'u_hash_table.c',
'u_keymap.c',
+ 'u_network.c',
'u_math.c',
'u_mm.c',
'u_rect.c',
@@ -24,6 +25,7 @@ util = env.ConvenienceLibrary(
'u_snprintf.c',
'u_stream_stdc.c',
'u_stream_wd.c',
+ 'u_surface.c',
'u_tile.c',
'u_time.c',
'u_timed_winsys.c',
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index deb68c43a6..414cf91025 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -89,10 +89,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* 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;
/* no-op depth/stencil/alpha */
@@ -337,7 +333,6 @@ util_blit_pixels(struct blit_state *ctx,
texTemp.width[0] = srcW;
texTemp.height[0] = srcH;
texTemp.depth[0] = 1;
- texTemp.compressed = 0;
pf_get_block(src->format, &texTemp.block);
tex = screen->texture_create(screen, &texTemp);
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 96a2222f9b..18597ef839 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -109,6 +109,7 @@ void _debug_vprintf(const char *format, va_list ap)
}
if(GetConsoleWindow() && !IsDebuggerPresent()) {
+ fflush(stdout);
vfprintf(stderr, format, ap);
fflush(stderr);
}
@@ -145,6 +146,7 @@ void _debug_vprintf(const char *format, va_list ap)
/* TODO */
#else /* !PIPE_SUBSYSTEM_WINDOWS */
#ifdef DEBUG
+ fflush(stdout);
vfprintf(stderr, format, ap);
#endif
#endif
@@ -719,6 +721,7 @@ void
debug_dump_surface_bmp(const char *filename,
struct pipe_surface *surface)
{
+#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
struct pipe_transfer *transfer;
struct pipe_texture *texture = surface->texture;
struct pipe_screen *screen = texture->screen;
@@ -731,6 +734,7 @@ debug_dump_surface_bmp(const char *filename,
debug_dump_transfer_bmp(filename, transfer);
screen->tex_transfer_destroy(transfer);
+#endif
}
void
@@ -738,11 +742,7 @@ debug_dump_transfer_bmp(const char *filename,
struct pipe_transfer *transfer)
{
#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
- struct util_stream *stream;
- struct bmp_file_header bmfh;
- struct bmp_info_header bmih;
float *rgba;
- unsigned x, y;
if (!transfer)
goto error1;
@@ -751,19 +751,47 @@ debug_dump_transfer_bmp(const char *filename,
if(!rgba)
goto error1;
+ pipe_get_tile_rgba(transfer, 0, 0,
+ transfer->width, transfer->height,
+ rgba);
+
+ debug_dump_float_rgba_bmp(filename,
+ transfer->width, transfer->height,
+ rgba, transfer->width);
+
+ FREE(rgba);
+error1:
+ ;
+#endif
+}
+
+void
+debug_dump_float_rgba_bmp(const char *filename,
+ unsigned width, unsigned height,
+ float *rgba, unsigned stride)
+{
+#ifndef PIPE_SUBSYSTEM_WINDOWS_MINIPORT
+ struct util_stream *stream;
+ struct bmp_file_header bmfh;
+ struct bmp_info_header bmih;
+ unsigned x, y;
+
+ if(!rgba)
+ goto error1;
+
bmfh.bfType = 0x4d42;
- bmfh.bfSize = 14 + 40 + transfer->height*transfer->width*4;
+ bmfh.bfSize = 14 + 40 + height*width*4;
bmfh.bfReserved1 = 0;
bmfh.bfReserved2 = 0;
bmfh.bfOffBits = 14 + 40;
bmih.biSize = 40;
- bmih.biWidth = transfer->width;
- bmih.biHeight = transfer->height;
+ bmih.biWidth = width;
+ bmih.biHeight = height;
bmih.biPlanes = 1;
bmih.biBitCount = 32;
bmih.biCompression = 0;
- bmih.biSizeImage = transfer->height*transfer->width*4;
+ bmih.biSizeImage = height*width*4;
bmih.biXPelsPerMeter = 0;
bmih.biYPelsPerMeter = 0;
bmih.biClrUsed = 0;
@@ -771,19 +799,15 @@ debug_dump_transfer_bmp(const char *filename,
stream = util_stream_create(filename, bmfh.bfSize);
if(!stream)
- goto error2;
+ goto error1;
util_stream_write(stream, &bmfh, 14);
util_stream_write(stream, &bmih, 40);
- pipe_get_tile_rgba(transfer, 0, 0,
- transfer->width, transfer->height,
- rgba);
-
- y = transfer->height;
+ y = height;
while(y--) {
- float *ptr = rgba + (transfer->width * y * 4);
- for(x = 0; x < transfer->width; ++x)
+ float *ptr = rgba + (stride * y * 4);
+ for(x = 0; x < width; ++x)
{
struct bmp_rgb_quad pixel;
pixel.rgbRed = float_to_ubyte(ptr[x*4 + 0]);
@@ -795,8 +819,6 @@ debug_dump_transfer_bmp(const char *filename,
}
util_stream_close(stream);
-error2:
- FREE(rgba);
error1:
;
#endif
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index 8d703e47fc..d42b65ce28 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -102,6 +102,22 @@ debug_printf(const char *format, ...)
}
+/*
+ * ... isn't portable so we need to pass arguments in parentheses.
+ *
+ * usage:
+ * debug_printf_once(("awnser: %i\n", 42));
+ */
+#define debug_printf_once(args) \
+ do { \
+ static boolean once = TRUE; \
+ if (once) { \
+ once = FALSE; \
+ debug_printf args; \
+ } \
+ } while (0)
+
+
#ifdef DEBUG
#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap)
#else
@@ -347,10 +363,15 @@ void debug_dump_surface_bmp(const char *filename,
struct pipe_surface *surface);
void debug_dump_transfer_bmp(const char *filename,
struct pipe_transfer *transfer);
+void debug_dump_float_rgba_bmp(const char *filename,
+ unsigned width, unsigned height,
+ float *rgba, unsigned stride);
#else
#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0)
#define debug_dump_surface(prefix, surface) ((void)0)
#define debug_dump_surface_bmp(filename, surface) ((void)0)
+#define debug_dump_transfer_bmp(filename, transfer) ((void)0)
+#define debug_dump_rgba_float_bmp(filename, width, height, rgba, stride) ((void)0)
#endif
diff --git a/src/gallium/auxiliary/util/u_debug_stack.c b/src/gallium/auxiliary/util/u_debug_stack.c
index e9891fde8a..528a1c394b 100644
--- a/src/gallium/auxiliary/util/u_debug_stack.c
+++ b/src/gallium/auxiliary/util/u_debug_stack.c
@@ -62,6 +62,8 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
#ifdef PIPE_ARCH_X86
while(nr_frames) {
+ const void **next_frame_pointer;
+
if(!frame_pointer)
break;
@@ -72,7 +74,14 @@ debug_backtrace_capture(struct debug_stack_frame *backtrace,
--nr_frames;
}
- frame_pointer = (const void **)frame_pointer[0];
+ next_frame_pointer = (const void **)frame_pointer[0];
+
+ /* Limit the stack walk to avoid referencing undefined memory */
+ if((uintptr_t)next_frame_pointer <= (uintptr_t)frame_pointer ||
+ (uintptr_t)next_frame_pointer > (uintptr_t)frame_pointer + 64*1024)
+ break;
+
+ frame_pointer = next_frame_pointer;
}
#endif
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index b32ad1cbe9..ca797486a0 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1278,10 +1278,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
/* 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;
/* no-op depth/stencil/alpha */
@@ -1320,7 +1316,6 @@ util_create_gen_mipmap(struct pipe_context *pipe,
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 */
}
@@ -1354,29 +1349,104 @@ get_next_slot(struct gen_mipmap_state *ctx)
static unsigned
-set_vertex_data(struct gen_mipmap_state *ctx, float width, float height)
+set_vertex_data(struct gen_mipmap_state *ctx,
+ enum pipe_texture_target tex_target,
+ uint face, float width, float height)
{
unsigned offset;
+ /* vert[0].position */
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*/
+ /* vert[1].position */
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;
+ /* vert[2].position */
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;
+ /* vert[3].position */
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;
+
+ /* Setup vertex texcoords. This is a little tricky for cube maps. */
+ if (tex_target == PIPE_TEXTURE_CUBE) {
+ static const float st[4][2] = {
+ {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
+ };
+ float rx, ry, rz;
+ uint i;
+
+ /* loop over quad verts */
+ for (i = 0; i < 4; i++) {
+ /* Compute sc = +/-scale and tc = +/-scale.
+ * Not +/-1 to avoid cube face selection ambiguity near the edges,
+ * though that can still sometimes happen with this scale factor...
+ */
+ const float scale = 0.9999f;
+ const float sc = (2.0f * st[i][0] - 1.0f) * scale;
+ const float tc = (2.0f * st[i][1] - 1.0f) * scale;
+
+ switch (face) {
+ case PIPE_TEX_FACE_POS_X:
+ rx = 1.0f;
+ ry = -tc;
+ rz = -sc;
+ break;
+ case PIPE_TEX_FACE_NEG_X:
+ rx = -1.0f;
+ ry = -tc;
+ rz = sc;
+ break;
+ case PIPE_TEX_FACE_POS_Y:
+ rx = sc;
+ ry = 1.0f;
+ rz = tc;
+ break;
+ case PIPE_TEX_FACE_NEG_Y:
+ rx = sc;
+ ry = -1.0f;
+ rz = -tc;
+ break;
+ case PIPE_TEX_FACE_POS_Z:
+ rx = sc;
+ ry = -tc;
+ rz = 1.0f;
+ break;
+ case PIPE_TEX_FACE_NEG_Z:
+ rx = -sc;
+ ry = -tc;
+ rz = -1.0f;
+ break;
+ default:
+ assert(0);
+ }
+
+ ctx->vertices[i][1][0] = rx; /*s*/
+ ctx->vertices[i][1][1] = ry; /*t*/
+ ctx->vertices[i][1][2] = rz; /*r*/
+ }
+ }
+ else {
+ /* 1D/2D */
+ ctx->vertices[0][1][0] = 0.0f; /*s*/
+ ctx->vertices[0][1][1] = 0.0f; /*t*/
+ ctx->vertices[0][1][2] = 0.0f; /*r*/
+
+ ctx->vertices[1][1][0] = 1.0f;
+ ctx->vertices[1][1][1] = 0.0f;
+ ctx->vertices[1][1][2] = 0.0f;
+
+ ctx->vertices[2][1][0] = 1.0f;
+ ctx->vertices[2][1][1] = 1.0f;
+ ctx->vertices[2][1][2] = 0.0f;
+
+ ctx->vertices[3][1][0] = 0.0f;
+ ctx->vertices[3][1][1] = 1.0f;
+ ctx->vertices[3][1][2] = 0.0f;
+ }
offset = get_next_slot( ctx );
@@ -1507,6 +1577,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
/* quad coords in window coords (bypassing vs, clip and viewport) */
offset = set_vertex_data(ctx,
+ pt->target,
+ face,
(float) pt->width[dstLevel],
(float) pt->height[dstLevel]);
diff --git a/src/gallium/auxiliary/util/u_linear.c b/src/gallium/auxiliary/util/u_linear.c
index 6be365e53b..a1dce3f5cf 100644
--- a/src/gallium/auxiliary/util/u_linear.c
+++ b/src/gallium/auxiliary/util/u_linear.c
@@ -1,3 +1,34 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 converting tiled data to linear and vice versa.
+ */
+
#include "util/u_debug.h"
#include "u_linear.h"
diff --git a/src/gallium/auxiliary/util/u_linear.h b/src/gallium/auxiliary/util/u_linear.h
index 1589f029bc..b74308ffa3 100644
--- a/src/gallium/auxiliary/util/u_linear.h
+++ b/src/gallium/auxiliary/util/u_linear.h
@@ -1,3 +1,34 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 converting tiled data to linear and vice versa.
+ */
+
#ifndef U_LINEAR_H
#define U_LINEAR_H
diff --git a/src/gallium/auxiliary/util/u_network.c b/src/gallium/auxiliary/util/u_network.c
new file mode 100644
index 0000000000..07d804ecdb
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_network.c
@@ -0,0 +1,188 @@
+
+#include "pipe/p_compiler.h"
+#include "util/u_network.h"
+#include "util/u_debug.h"
+
+#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+# include <winsock2.h>
+# include <windows.h>
+#elif defined(PIPE_OS_LINUX)
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <netdb.h>
+#else
+# warning "No socket implementation"
+#endif
+
+boolean
+u_socket_init()
+{
+#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
+
+ /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
+ wVersionRequested = MAKEWORD(1, 1);
+
+ err = WSAStartup(wVersionRequested, &wsaData);
+ if (err != 0) {
+ debug_printf("WSAStartup failed with error: %d\n", err);
+ return FALSE;
+ }
+ return TRUE;
+#elif defined(PIPE_HAVE_SOCKETS)
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+void
+u_socket_stop()
+{
+#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+ WSACleanup();
+#endif
+}
+
+void
+u_socket_close(int s)
+{
+ if (s < 0)
+ return;
+
+#if defined(PIPE_OS_LINUX)
+ shutdown(s, SHUT_RDWR);
+ close(s);
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+ shutdown(s, SD_BOTH);
+ closesocket(s);
+#else
+ assert(0);
+#endif
+}
+
+int u_socket_accept(int s)
+{
+#if defined(PIPE_HAVE_SOCKETS)
+ return accept(s, NULL, NULL);
+#else
+ return -1;
+#endif
+}
+
+int
+u_socket_send(int s, void *data, size_t size)
+{
+#if defined(PIPE_HAVE_SOCKETS)
+ return send(s, data, size, 0);
+#else
+ return -1;
+#endif
+}
+
+int
+u_socket_peek(int s, void *data, size_t size)
+{
+#if defined(PIPE_HAVE_SOCKETS)
+ return recv(s, data, size, MSG_PEEK);
+#else
+ return -1;
+#endif
+}
+
+int
+u_socket_recv(int s, void *data, size_t size)
+{
+#if defined(PIPE_HAVE_SOCKETS)
+ return recv(s, data, size, 0);
+#else
+ return -1;
+#endif
+}
+
+int
+u_socket_connect(const char *hostname, uint16_t port)
+{
+#if defined(PIPE_HAVE_SOCKETS)
+ int s;
+ struct sockaddr_in sa;
+ struct hostent *host = NULL;
+
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+ host = gethostbyname(hostname);
+ if (!host)
+ return -1;
+
+ memcpy((char *)&sa.sin_addr,host->h_addr,host->h_length);
+ sa.sin_family= host->h_addrtype;
+ sa.sin_port = htons(port);
+
+ s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP);
+ if (s < 0)
+ return -1;
+
+ if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) {
+ u_socket_close(s);
+ return -1;
+ }
+
+ return s;
+#else
+ assert(0);
+ return -1;
+#endif
+}
+
+int
+u_socket_listen_on_port(uint16_t portnum)
+{
+#if defined(PIPE_HAVE_SOCKETS)
+ int s;
+ struct sockaddr_in sa;
+ memset(&sa, 0, sizeof(struct sockaddr_in));
+
+ sa.sin_family = AF_INET;
+ sa.sin_port = htons(portnum);
+
+ s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (s < 0)
+ return -1;
+
+ if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) {
+ u_socket_close(s);
+ return -1;
+ }
+
+ listen(s, 0);
+
+ return s;
+#else
+ assert(0);
+ return -1;
+#endif
+}
+
+void
+u_socket_block(int s, boolean block)
+{
+#if defined(PIPE_OS_LINUX)
+ int old = fcntl(s, F_GETFL, 0);
+ if (old == -1)
+ return;
+
+ /* TODO obey block */
+ if (block)
+ fcntl(s, F_SETFL, old & ~O_NONBLOCK);
+ else
+ fcntl(s, F_SETFL, old | O_NONBLOCK);
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+ u_long iMode = block ? 0 : 1;
+ ioctlsocket(s, FIONBIO, &iMode);
+#else
+ assert(0);
+#endif
+}
diff --git a/src/gallium/auxiliary/util/u_network.h b/src/gallium/auxiliary/util/u_network.h
new file mode 100644
index 0000000000..14d3884427
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_network.h
@@ -0,0 +1,24 @@
+
+#ifndef _U_NETWORK_H_
+#define _U_NETWORK_H_
+
+#include "pipe/p_compiler.h"
+
+#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+# define PIPE_HAVE_SOCKETS
+#elif defined(PIPE_OS_LINUX)
+# define PIPE_HAVE_SOCKETS
+#endif
+
+boolean u_socket_init(void);
+void u_socket_stop(void);
+void u_socket_close(int s);
+int u_socket_listen_on_port(uint16_t portnum);
+int u_socket_accept(int s);
+int u_socket_connect(const char *host, uint16_t port);
+int u_socket_send(int s, void *data, size_t size);
+int u_socket_peek(int s, void *data, size_t size);
+int u_socket_recv(int s, void *data, size_t size);
+void u_socket_block(int s, boolean block);
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c
new file mode 100644
index 0000000000..85e443204e
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -0,0 +1,113 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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
+ * Surface utility functions.
+ *
+ * @author Brian Paul
+ */
+
+
+#include "pipe/p_screen.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+
+#include "util/u_surface.h"
+
+
+/**
+ * Helper to quickly create an RGBA rendering surface of a certain size.
+ * \param textureOut returns the new texture
+ * \param surfaceOut returns the new surface
+ * \return TRUE for success, FALSE if failure
+ */
+boolean
+util_create_rgba_surface(struct pipe_screen *screen,
+ uint width, uint height,
+ struct pipe_texture **textureOut,
+ struct pipe_surface **surfaceOut)
+{
+ static const enum pipe_format rgbaFormats[] = {
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_R8G8B8A8_UNORM,
+ PIPE_FORMAT_NONE
+ };
+ const uint target = PIPE_TEXTURE_2D;
+ const uint usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ enum pipe_format format = PIPE_FORMAT_NONE;
+ struct pipe_texture templ;
+ uint i;
+
+ /* Choose surface format */
+ for (i = 0; rgbaFormats[i]; i++) {
+ if (screen->is_format_supported(screen, rgbaFormats[i],
+ target, usage, 0)) {
+ format = rgbaFormats[i];
+ break;
+ }
+ }
+ if (format == PIPE_FORMAT_NONE)
+ return FALSE; /* unable to get an rgba format!?! */
+
+ /* create texture */
+ memset(&templ, 0, sizeof(templ));
+ templ.target = target;
+ templ.format = format;
+ templ.last_level = 0;
+ templ.width[0] = width;
+ templ.height[0] = height;
+ templ.depth[0] = 1;
+ pf_get_block(format, &templ.block);
+ templ.tex_usage = usage;
+
+ *textureOut = screen->texture_create(screen, &templ);
+ if (!*textureOut)
+ return FALSE;
+
+ /* create surface / view into texture */
+ *surfaceOut = screen->get_tex_surface(screen, *textureOut, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
+ if (!*surfaceOut) {
+ pipe_texture_reference(textureOut, NULL);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/**
+ * Release the surface and texture from util_create_rgba_surface().
+ */
+void
+util_destroy_rgba_surface(struct pipe_texture *texture,
+ struct pipe_surface *surface)
+{
+ pipe_surface_reference(&surface, NULL);
+ pipe_texture_reference(&texture, NULL);
+}
+
diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.h b/src/gallium/auxiliary/util/u_surface.h
index a0e4c5d98e..a5b73cfc20 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -1,8 +1,7 @@
/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
+ *
+ * Copyright 2009 VMware, 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
@@ -10,26 +9,44 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 WGL_ARBEXTENSIONSSTRING_H
-#define WGL_ARBEXTENSIONSSTRING_H
-WINGDIAPI const char * APIENTRY
-wglGetExtensionsStringARB(
- HDC hdc );
+#ifndef U_SURFACE_H
+#define U_SURFACE_H
-#endif /* WGL_ARBEXTENSIONSSTRING_H */
+
+#include "pipe/p_compiler.h"
+
+
+struct pipe_screen;
+struct pipe_texture;
+struct pipe_surface;
+
+
+extern boolean
+util_create_rgba_surface(struct pipe_screen *screen,
+ uint width, uint height,
+ struct pipe_texture **textureOut,
+ struct pipe_surface **surfaceOut);
+
+
+extern void
+util_destroy_rgba_surface(struct pipe_texture *texture,
+ struct pipe_surface *surface);
+
+
+#endif /* U_SURFACE_H */
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index f0a5a339eb..9747a55cbf 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -1126,7 +1126,22 @@ pipe_get_tile_z(struct pipe_transfer *pt,
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 24-bit Z to 32-bit Z */
- pDest[j] = (ptrc[j] << 8) | (ptrc[j] & 0xff);
+ pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff);
+ }
+ pDest += dstStride;
+ ptrc += pt->stride/4;
+ }
+ }
+ break;
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ {
+ const uint *ptrc
+ = (const uint *)(map + y * pt->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] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff);
}
pDest += dstStride;
ptrc += pt->stride/4;
diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c
index 8afe4fccf7..5268cbf79c 100644
--- a/src/gallium/auxiliary/util/u_time.c
+++ b/src/gallium/auxiliary/util/u_time.c
@@ -217,4 +217,9 @@ void util_time_sleep(unsigned usecs)
} while(start <= curr && curr < end ||
end < start && (curr < end || start <= curr));
}
+#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+void util_time_sleep(unsigned usecs)
+{
+ Sleep((usecs + 999)/ 1000);
+}
#endif
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index d9c0d7afa8..2eb98068c8 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -70,7 +70,7 @@ struct u_upload_mgr *u_upload_create( struct pipe_screen *screen,
}
-static INLINE void
+static INLINE enum pipe_error
my_buffer_write(struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned offset, unsigned size, unsigned dirty_size,
@@ -84,12 +84,14 @@ my_buffer_write(struct pipe_screen *screen,
assert(size);
map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_WRITE);
- assert(map);
- if(map) {
- memcpy(map + offset, data, size);
- pipe_buffer_flush_mapped_range(screen, buf, offset, dirty_size);
- pipe_buffer_unmap(screen, buf);
- }
+ if (map == NULL)
+ return PIPE_ERROR_OUT_OF_MEMORY;
+
+ memcpy(map + offset, data, size);
+ pipe_buffer_flush_mapped_range(screen, buf, offset, dirty_size);
+ pipe_buffer_unmap(screen, buf);
+
+ return PIPE_OK;
}
/* Release old buffer.
@@ -162,12 +164,14 @@ enum pipe_error u_upload_data( struct u_upload_mgr *upload,
/* Copy the data, using map_range if available:
*/
- my_buffer_write( upload->screen,
- upload->buffer,
- upload->offset,
- size,
- alloc_size,
- data );
+ ret = my_buffer_write( upload->screen,
+ upload->buffer,
+ upload->offset,
+ size,
+ alloc_size,
+ data );
+ if (ret)
+ return ret;
/* Emit the return values:
*/
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 808be589bd..ebb7a7acc4 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -99,6 +99,28 @@ static const struct debug_named_value cell_debug_flags[] = {
{NULL, 0}
};
+static unsigned int
+cell_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+cell_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
struct pipe_context *
cell_create_context(struct pipe_screen *screen,
@@ -122,6 +144,9 @@ cell_create_context(struct pipe_screen *screen,
cell->pipe.clear = cell_clear;
cell->pipe.flush = cell_flush;
+ cell->pipe.is_texture_referenced = cell_is_texture_referenced;
+ cell->pipe.is_buffer_referenced = cell_is_buffer_referenced;
+
#if 0
cell->pipe.begin_query = cell_begin_query;
cell->pipe.end_query = cell_end_query;
diff --git a/src/gallium/drivers/cell/spu/spu_render.c b/src/gallium/drivers/cell/spu/spu_render.c
index 7c225e2f27..5ffb7073ab 100644
--- a/src/gallium/drivers/cell/spu/spu_render.c
+++ b/src/gallium/drivers/cell/spu/spu_render.c
@@ -32,6 +32,7 @@
#include "spu_main.h"
#include "spu_render.h"
+#include "spu_shuffle.h"
#include "spu_tri.h"
#include "spu_tile.h"
#include "cell/common.h"
@@ -267,15 +268,75 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
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);
+ const qword vertex_sizes = (qword)spu_splats(vertex_size);
+ const qword verticess = (qword)spu_splats((uint)vertices);
+
+ ASSERT_ALIGN16(&indexes[0]);
+
+ const uint num_indexes = render->num_indexes;
+
+ /* loop over tris
+ * &indexes[0] will be 16 byte aligned. This loop is heavily unrolled
+ * avoiding variable rotates when extracting vertex indices.
+ */
+ for (j = 0; j < num_indexes; j += 24) {
+ /* Load three vectors, containing 24 ushort indices */
+ const qword* lower_qword = (qword*)&indexes[j];
+ const qword indices0 = lower_qword[0];
+ const qword indices1 = lower_qword[1];
+ const qword indices2 = lower_qword[2];
+
+ /* stores three indices for each tri n in slots 0, 1 and 2 of vsn */
+ /* Straightforward rotates for these */
+ qword vs0 = indices0;
+ qword vs1 = si_shlqbyi(indices0, 6);
+ qword vs3 = si_shlqbyi(indices1, 2);
+ qword vs4 = si_shlqbyi(indices1, 8);
+ qword vs6 = si_shlqbyi(indices2, 4);
+ qword vs7 = si_shlqbyi(indices2, 10);
+
+ /* For tri 2 and 5, the three indices are split across two machine
+ * words - rotate and combine */
+ const qword tmp2a = si_shlqbyi(indices0, 12);
+ const qword tmp2b = si_rotqmbyi(indices1, 12|16);
+ qword vs2 = si_selb(tmp2a, tmp2b, si_fsmh(si_from_uint(0x20)));
+
+ const qword tmp5a = si_shlqbyi(indices1, 14);
+ const qword tmp5b = si_rotqmbyi(indices2, 14|16);
+ qword vs5 = si_selb(tmp5a, tmp5b, si_fsmh(si_from_uint(0x60)));
+
+ /* unpack indices from halfword slots to word slots */
+ vs0 = si_shufb(vs0, vs0, SHUFB8(0,A,0,B,0,C,0,0));
+ vs1 = si_shufb(vs1, vs1, SHUFB8(0,A,0,B,0,C,0,0));
+ vs2 = si_shufb(vs2, vs2, SHUFB8(0,A,0,B,0,C,0,0));
+ vs3 = si_shufb(vs3, vs3, SHUFB8(0,A,0,B,0,C,0,0));
+ vs4 = si_shufb(vs4, vs4, SHUFB8(0,A,0,B,0,C,0,0));
+ vs5 = si_shufb(vs5, vs5, SHUFB8(0,A,0,B,0,C,0,0));
+ vs6 = si_shufb(vs6, vs6, SHUFB8(0,A,0,B,0,C,0,0));
+ vs7 = si_shufb(vs7, vs7, SHUFB8(0,A,0,B,0,C,0,0));
+
+ /* Calculate address of vertex in vertices[] */
+ vs0 = si_mpya(vs0, vertex_sizes, verticess);
+ vs1 = si_mpya(vs1, vertex_sizes, verticess);
+ vs2 = si_mpya(vs2, vertex_sizes, verticess);
+ vs3 = si_mpya(vs3, vertex_sizes, verticess);
+ vs4 = si_mpya(vs4, vertex_sizes, verticess);
+ vs5 = si_mpya(vs5, vertex_sizes, verticess);
+ vs6 = si_mpya(vs6, vertex_sizes, verticess);
+ vs7 = si_mpya(vs7, vertex_sizes, verticess);
+
+ /* Select the appropriate call based on the number of vertices
+ * remaining */
+ switch(num_indexes - j) {
+ default: drawn += tri_draw(vs7, tx, ty);
+ case 21: drawn += tri_draw(vs6, tx, ty);
+ case 18: drawn += tri_draw(vs5, tx, ty);
+ case 15: drawn += tri_draw(vs4, tx, ty);
+ case 12: drawn += tri_draw(vs3, tx, ty);
+ case 9: drawn += tri_draw(vs2, tx, ty);
+ case 6: drawn += tri_draw(vs1, tx, ty);
+ case 3: drawn += tri_draw(vs0, tx, ty);
+ }
}
//printf("SPU %u: drew %u of %u\n", spu.init.id, drawn, render->num_indexes/3);
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index d727268475..58be001be4 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -133,7 +133,15 @@ struct setup_stage {
uint tx, ty; /**< position of current tile (x, y) */
- int cliprect_minx, cliprect_maxx, cliprect_miny, cliprect_maxy;
+ union {
+ struct {
+ int cliprect_minx;
+ int cliprect_miny;
+ int cliprect_maxx;
+ int cliprect_maxy;
+ };
+ qword cliprect;
+ };
struct interp_coef coef[PIPE_MAX_SHADER_INPUTS];
@@ -432,6 +440,41 @@ print_vertex(const struct vertex_header *v)
}
#endif
+/* Returns the minimum of each slot of two vec_float4s as qwords.
+ * i.e. return[n] = min(q0[n],q1[n]);
+ */
+static qword
+minfq(qword q0, qword q1)
+{
+ const qword q0q1m = si_fcgt(q0, q1);
+ return si_selb(q0, q1, q0q1m);
+}
+
+/* Returns the minimum of each slot of three vec_float4s as qwords.
+ * i.e. return[n] = min(q0[n],q1[n],q2[n]);
+ */
+static qword
+min3fq(qword q0, qword q1, qword q2)
+{
+ return minfq(minfq(q0, q1), q2);
+}
+
+/* Returns the maximum of each slot of two vec_float4s as qwords.
+ * i.e. return[n] = min(q0[n],q1[n],q2[n]);
+ */
+static qword
+maxfq(qword q0, qword q1) {
+ const qword q0q1m = si_fcgt(q0, q1);
+ return si_selb(q1, q0, q0q1m);
+}
+
+/* Returns the maximum of each slot of three vec_float4s as qwords.
+ * i.e. return[n] = min(q0[n],q1[n],q2[n]);
+ */
+static qword
+max3fq(qword q0, qword q1, qword q2) {
+ return maxfq(maxfq(q0, q1), q2);
+}
/**
* Sort vertices from top to bottom.
@@ -440,9 +483,7 @@ print_vertex(const struct vertex_header *v)
* \return FALSE if tri is totally outside tile, TRUE otherwise
*/
static boolean
-setup_sort_vertices(const struct vertex_header *v0,
- const struct vertex_header *v1,
- const struct vertex_header *v2)
+setup_sort_vertices(const qword vs)
{
float area, sign;
@@ -455,57 +496,57 @@ setup_sort_vertices(const struct vertex_header *v0,
}
#endif
- /* determine bottom to top order of vertices */
{
+ /* Load the float values for various processing... */
+ const qword f0 = (qword)(((const struct vertex_header*)si_to_ptr(vs))->data[0]);
+ const qword f1 = (qword)(((const struct vertex_header*)si_to_ptr(si_rotqbyi(vs, 4)))->data[0]);
+ const qword f2 = (qword)(((const struct vertex_header*)si_to_ptr(si_rotqbyi(vs, 8)))->data[0]);
+
+ /* Check if triangle is completely outside the tile bounds
+ * Find the min and max x and y positions of the three poits */
+ const qword minf = min3fq(f0, f1, f2);
+ const qword maxf = max3fq(f0, f1, f2);
+
+ /* Compare min and max against cliprect vals */
+ const qword maxsmins = si_shufb(maxf, minf, SHUFB4(A,B,a,b));
+ const qword outside = si_fcgt(maxsmins, si_csflt(setup.cliprect, 0));
+
+ /* Use a little magic to work out of the tri is visible or not */
+ if(si_to_uint(si_xori(si_gb(outside), 0xc))) return FALSE;
+
+ /* determine bottom to top order of vertices */
/* A table of shuffle patterns for putting vertex_header pointers into
correct order. Quite magical. */
- const vec_uchar16 sort_order_patterns[] = {
- SHUFFLE4(A,B,C,C),
- SHUFFLE4(C,A,B,C),
- SHUFFLE4(A,C,B,C),
- SHUFFLE4(B,C,A,C),
- SHUFFLE4(B,A,C,C),
- SHUFFLE4(C,B,A,C) };
-
- /* The vertex_header pointers, packed for easy shuffling later */
- const vec_uint4 vs = {(unsigned)v0, (unsigned)v1, (unsigned)v2};
+ const qword sort_order_patterns[] = {
+ SHUFB4(A,B,C,C),
+ SHUFB4(C,A,B,C),
+ SHUFB4(A,C,B,C),
+ SHUFB4(B,C,A,C),
+ SHUFB4(B,A,C,C),
+ SHUFB4(C,B,A,C) };
/* Collate y values into two vectors for comparison.
Using only one shuffle constant! ;) */
- const vec_float4 y_02_ = spu_shuffle(v0->data[0], v2->data[0], SHUFFLE4(0,B,b,C));
- const vec_float4 y_10_ = spu_shuffle(v1->data[0], v0->data[0], SHUFFLE4(0,B,b,C));
- const vec_float4 y_012 = spu_shuffle(y_02_, v1->data[0], SHUFFLE4(0,B,b,C));
- const vec_float4 y_120 = spu_shuffle(y_10_, v2->data[0], SHUFFLE4(0,B,b,C));
+ const qword y_02_ = si_shufb(f0, f2, SHUFB4(0,B,b,C));
+ const qword y_10_ = si_shufb(f1, f0, SHUFB4(0,B,b,C));
+ const qword y_012 = si_shufb(y_02_, f1, SHUFB4(0,B,b,C));
+ const qword y_120 = si_shufb(y_10_, f2, SHUFB4(0,B,b,C));
/* Perform comparison: {y0,y1,y2} > {y1,y2,y0} */
- const vec_uint4 compare = spu_cmpgt(y_012, y_120);
+ const qword compare = si_fcgt(y_012, y_120);
/* Compress the result of the comparison into 4 bits */
- const vec_uint4 gather = spu_gather(compare);
+ const qword gather = si_gb(compare);
/* Subtract one to attain the index into the LUT. Magical. */
- const unsigned int index = spu_extract(gather, 0) - 1;
+ const unsigned int index = si_to_uint(gather) - 1;
/* Load the appropriate pattern and construct the desired vector. */
- setup.vertex_headers = (qword)spu_shuffle(vs, vs, sort_order_patterns[index]);
+ setup.vertex_headers = si_shufb(vs, vs, sort_order_patterns[index]);
/* Using the result of the comparison, set sign.
Very magical. */
- sign = ((si_to_uint(si_cntb((qword)gather)) == 2) ? 1.0f : -1.0f);
+ sign = ((si_to_uint(si_cntb(gather)) == 2) ? 1.0f : -1.0f);
}
- /* 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.ds = spu_sub(setup.vmid->data[0], setup.vmin->data[0]);
setup.emaj.ds = spu_sub(setup.vmax->data[0], setup.vmin->data[0]);
setup.etop.ds = spu_sub(setup.vmax->data[0], setup.vmid->data[0]);
@@ -761,21 +802,19 @@ subtriangle(struct edge *eleft, struct edge *eright, unsigned lines)
* The tile data should have already been fetched.
*/
boolean
-tri_draw(const float *v0, const float *v1, const float *v2,
+tri_draw(const qword vs,
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)) {
+ const qword clipbase = (qword)((vec_uint4){tx, ty});
+ const qword clipmin = si_mpyui(clipbase, TILE_SIZE);
+ const qword clipmax = si_ai(clipmin, TILE_SIZE);
+ setup.cliprect = si_shufb(clipmin, clipmax, SHUFB4(A,B,a,b));
+
+ if(!setup_sort_vertices(vs)) {
return FALSE; /* totally clipped */
}
diff --git a/src/gallium/drivers/cell/spu/spu_tri.h b/src/gallium/drivers/cell/spu/spu_tri.h
index aa694dd7c9..82e3b19ad7 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.h
+++ b/src/gallium/drivers/cell/spu/spu_tri.h
@@ -31,7 +31,7 @@
extern boolean
-tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty);
+tri_draw(const qword vs, uint tx, uint ty);
#endif /* SPU_TRI_H */
diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c
index fcad717cf8..37184eac7b 100644
--- a/src/gallium/drivers/failover/fo_context.c
+++ b/src/gallium/drivers/failover/fo_context.c
@@ -105,7 +105,28 @@ static boolean failover_draw_arrays( struct pipe_context *pipe,
return failover_draw_elements(pipe, NULL, 0, prim, start, count);
}
+static unsigned int
+failover_is_texture_referenced( struct pipe_context *_pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ struct failover_context *failover = failover_context( _pipe );
+ struct pipe_context *pipe = (failover->mode == FO_HW) ?
+ failover->hw : failover->sw;
+
+ return pipe->is_texture_referenced(pipe, texture, face, level);
+}
+static unsigned int
+failover_is_buffer_referenced( struct pipe_context *_pipe,
+ struct pipe_buffer *buf)
+{
+ struct failover_context *failover = failover_context( _pipe );
+ struct pipe_context *pipe = (failover->mode == FO_HW) ?
+ failover->hw : failover->sw;
+
+ return pipe->is_buffer_referenced(pipe, buf);
+}
struct pipe_context *failover_create( struct pipe_context *hw,
struct pipe_context *sw )
@@ -151,6 +172,8 @@ struct pipe_context *failover_create( struct pipe_context *hw,
#endif
failover->pipe.flush = hw->flush;
+ failover->pipe.is_texture_referenced = failover_is_texture_referenced;
+ failover->pipe.is_buffer_referenced = failover_is_buffer_referenced;
failover->dirty = 0;
diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile
index 12821c5a76..8870b39866 100644
--- a/src/gallium/drivers/i915simple/Makefile
+++ b/src/gallium/drivers/i915simple/Makefile
@@ -8,7 +8,6 @@ C_SOURCES = \
i915_clear.c \
i915_flush.c \
i915_context.c \
- i915_context.c \
i915_debug.c \
i915_debug_fp.c \
i915_state.c \
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index 3e3a596884..ccf9bb31fb 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -136,6 +136,29 @@ static boolean i915_draw_arrays( struct pipe_context *pipe,
}
+static unsigned int
+i915_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+i915_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *i915_create_context( struct pipe_screen *screen,
struct pipe_winsys *pipe_winsys,
@@ -160,6 +183,9 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
i915->pipe.draw_elements = i915_draw_elements;
i915->pipe.draw_range_elements = i915_draw_range_elements;
+ i915->pipe.is_texture_referenced = i915_is_texture_referenced;
+ i915->pipe.is_buffer_referenced = i915_is_buffer_referenced;
+
/*
* Create drawing context and plug our rendering stage into it.
*/
diff --git a/src/gallium/drivers/i965simple/brw_context.c b/src/gallium/drivers/i965simple/brw_context.c
index c74cbf8d73..9b33285bc7 100644
--- a/src/gallium/drivers/i965simple/brw_context.c
+++ b/src/gallium/drivers/i965simple/brw_context.c
@@ -73,6 +73,28 @@ static void brw_clear(struct pipe_context *pipe, struct pipe_surface *ps,
pipe->surface_fill(pipe, ps, x, y, w, h, clearValue);
}
+static unsigned int
+brw_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+brw_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
struct pipe_context *brw_create(struct pipe_screen *screen,
struct brw_winsys *brw_winsys,
@@ -94,6 +116,9 @@ struct pipe_context *brw_create(struct pipe_screen *screen,
brw->pipe.destroy = brw_destroy;
brw->pipe.clear = brw_clear;
+ brw->pipe.is_texture_referenced = brw_is_texture_referenced;
+ brw->pipe.is_buffer_referenced = brw_is_buffer_referenced;
+
brw_init_surface_functions(brw);
brw_init_texture_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 f44bd17451..8aea8c0558 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -240,7 +240,7 @@ static boolean brw_miptree_layout(struct brw_texture *tex)
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
- if (pt->compressed) {
+ if (pf_is_compressed(pt->format)) {
pack_y_pitch = (height + 3) / 4;
if (pack_x_pitch > align(width, align_w)) {
diff --git a/src/gallium/drivers/nouveau/Makefile b/src/gallium/drivers/nouveau/Makefile
new file mode 100644
index 0000000000..dbe8a6e7bf
--- /dev/null
+++ b/src/gallium/drivers/nouveau/Makefile
@@ -0,0 +1,8 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = nouveau
+
+C_SOURCES = nouveau_screen.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/nouveau/nouveau_push.h b/src/gallium/drivers/nouveau/nouveau_push.h
index 54ef1c1291..9c235080a5 100644
--- a/src/gallium/drivers/nouveau/nouveau_push.h
+++ b/src/gallium/drivers/nouveau/nouveau_push.h
@@ -9,13 +9,13 @@
#define OUT_RING(data) do { \
NOUVEAU_PUSH_CONTEXT(pc); \
- (*pc->nvws->channel->pushbuf->cur++) = (data); \
+ (*pc->base.channel->pushbuf->cur++) = (data); \
} while(0)
#define OUT_RINGp(src,size) do { \
NOUVEAU_PUSH_CONTEXT(pc); \
- memcpy(pc->nvws->channel->pushbuf->cur, (src), (size) * 4); \
- pc->nvws->channel->pushbuf->cur += (size); \
+ memcpy(pc->base.channel->pushbuf->cur, (src), (size) * 4); \
+ pc->base.channel->pushbuf->cur += (size); \
} while(0)
#define OUT_RINGf(data) do { \
@@ -26,25 +26,35 @@
#define BEGIN_RING(obj,mthd,size) do { \
NOUVEAU_PUSH_CONTEXT(pc); \
- if (pc->nvws->channel->pushbuf->remaining < ((size) + 1)) \
- pc->nvws->push_flush(pc->nvws, ((size) + 1), NULL); \
+ struct nouveau_channel *chan = pc->base.channel; \
+ if (chan->pushbuf->remaining < ((size) + 1)) \
+ nouveau_pushbuf_flush(chan, ((size) + 1)); \
OUT_RING((pc->obj->subc << 13) | ((size) << 18) | (mthd)); \
- pc->nvws->channel->pushbuf->remaining -= ((size) + 1); \
+ chan->pushbuf->remaining -= ((size) + 1); \
} while(0)
#define BEGIN_RING_NI(obj,mthd,size) do { \
BEGIN_RING(obj, (mthd) | 0x40000000, (size)); \
} while(0)
+static inline void
+DO_FIRE_RING(struct nouveau_channel *chan, struct pipe_fence_handle **fence)
+{
+ nouveau_pushbuf_flush(chan, 0);
+ if (fence)
+ *fence = NULL;
+}
+
#define FIRE_RING(fence) do { \
NOUVEAU_PUSH_CONTEXT(pc); \
- pc->nvws->push_flush(pc->nvws, 0, fence); \
+ DO_FIRE_RING(pc->base.channel, fence); \
} while(0)
#define OUT_RELOC(bo,data,flags,vor,tor) do { \
NOUVEAU_PUSH_CONTEXT(pc); \
- pc->nvws->push_reloc(pc->nvws, pc->nvws->channel->pushbuf->cur++, \
- (bo), (data), (flags), (vor), (tor)); \
+ struct nouveau_channel *chan = pc->base.channel; \
+ nouveau_pushbuf_emit_reloc(chan, chan->pushbuf->cur++, nouveau_bo(bo), \
+ (data), 0, (flags), (vor), (tor)); \
} while(0)
/* Raw data + flags depending on FB/TT buffer */
@@ -55,8 +65,8 @@
/* FB/TT object handle */
#define OUT_RELOCo(bo,flags) do { \
OUT_RELOC((bo), 0, (flags) | NOUVEAU_BO_OR, \
- pc->nvws->channel->vram->handle, \
- pc->nvws->channel->gart->handle); \
+ pc->base.channel->vram->handle, \
+ pc->base.channel->gart->handle); \
} while(0)
/* Low 32-bits of offset */
@@ -72,11 +82,12 @@
/* A reloc which'll recombine into a NV_DMA_METHOD packet header */
#define OUT_RELOCm(bo, flags, obj, mthd, size) do { \
NOUVEAU_PUSH_CONTEXT(pc); \
- if (pc->nvws->channel->pushbuf->remaining < ((size) + 1)) \
- pc->nvws->push_flush(pc->nvws->channel, ((size) + 1), NULL); \
+ struct nouveau_channel *chan = pc->base.channel; \
+ if (chan->pushbuf->remaining < ((size) + 1)) \
+ nouveau_pushbuf_flush(chan, ((size) + 1)); \
OUT_RELOCd((bo), (pc->obj->subc << 13) | ((size) << 18) | (mthd), \
(flags), 0, 0); \
- pc->nvws->channel->pushbuf->remaining -= ((size) + 1); \
+ chan->pushbuf->remaining -= ((size) + 1); \
} while(0)
#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
new file mode 100644
index 0000000000..832366e646
--- /dev/null
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -0,0 +1,240 @@
+#include <pipe/p_defines.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_state.h>
+
+#include <util/u_memory.h>
+
+#include "nouveau/nouveau_bo.h"
+#include "nouveau_winsys.h"
+#include "nouveau_screen.h"
+
+static const char *
+nouveau_screen_get_name(struct pipe_screen *pscreen)
+{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ static char buffer[128];
+
+ snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
+ return buffer;
+}
+
+static const char *
+nouveau_screen_get_vendor(struct pipe_screen *pscreen)
+{
+ return "nouveau";
+}
+
+static struct pipe_buffer *
+nouveau_screen_bo_skel(struct pipe_screen *pscreen, struct nouveau_bo *bo,
+ unsigned alignment, unsigned usage, unsigned size)
+{
+ struct pipe_buffer *pb;
+
+ pb = CALLOC(1, sizeof(struct pipe_buffer)+sizeof(struct nouveau_bo *));
+ if (!pb) {
+ nouveau_bo_ref(NULL, &bo);
+ return NULL;
+ }
+
+ pipe_reference_init(&pb->reference, 1);
+ pb->screen = pscreen;
+ pb->alignment = alignment;
+ pb->usage = usage;
+ pb->size = size;
+ *(struct nouveau_bo **)(pb + 1) = bo;
+ return pb;
+}
+
+static struct pipe_buffer *
+nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment,
+ unsigned usage, unsigned size)
+{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ struct nouveau_bo *bo = NULL;
+ uint32_t flags = NOUVEAU_BO_MAP;
+ int ret;
+
+ if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER)
+ flags |= NOUVEAU_BO_GART;
+ else
+ if (usage & PIPE_BUFFER_USAGE_VERTEX) {
+ if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
+ flags |= NOUVEAU_BO_GART;
+ } else
+ if (usage & PIPE_BUFFER_USAGE_INDEX) {
+ if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
+ flags |= NOUVEAU_BO_GART;
+ }
+
+ if (usage & PIPE_BUFFER_USAGE_PIXEL) {
+ if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
+ flags |= NOUVEAU_BO_GART;
+ if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
+ flags |= NOUVEAU_BO_VRAM;
+
+ if (dev->chipset == 0x50 || dev->chipset >= 0x80) {
+ flags |= NOUVEAU_BO_TILED;
+ if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
+ flags |= NOUVEAU_BO_ZTILE;
+ }
+ }
+
+ ret = nouveau_bo_new(dev, flags, alignment, size, &bo);
+ if (ret)
+ return NULL;
+
+ return nouveau_screen_bo_skel(pscreen, bo, alignment, usage, size);
+}
+
+static struct pipe_buffer *
+nouveau_screen_bo_user(struct pipe_screen *pscreen, void *ptr, unsigned bytes)
+{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ struct nouveau_bo *bo = NULL;
+ int ret;
+
+ ret = nouveau_bo_user(dev, ptr, bytes, &bo);
+ if (ret)
+ return NULL;
+
+ return nouveau_screen_bo_skel(pscreen, bo, 0, 0, bytes);
+}
+
+static inline uint32_t
+nouveau_screen_map_flags(unsigned pipe)
+{
+ uint32_t flags = 0;
+
+ if (pipe & PIPE_BUFFER_USAGE_CPU_READ)
+ flags |= NOUVEAU_BO_RD;
+ if (pipe & PIPE_BUFFER_USAGE_CPU_WRITE)
+ flags |= NOUVEAU_BO_WR;
+ if (pipe & PIPE_BUFFER_USAGE_DISCARD)
+ flags |= NOUVEAU_BO_INVAL;
+ if (pipe & PIPE_BUFFER_USAGE_DONTBLOCK)
+ flags |= NOUVEAU_BO_NOWAIT;
+ else
+ if (pipe & 0 /*PIPE_BUFFER_USAGE_UNSYNCHRONIZED*/)
+ flags |= NOUVEAU_BO_NOSYNC;
+
+ return flags;
+}
+
+static void *
+nouveau_screen_bo_map(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+ unsigned usage)
+{
+ struct nouveau_bo *bo = nouveau_bo(pb);
+ int ret;
+
+ ret = nouveau_bo_map(bo, nouveau_screen_map_flags(usage));
+ if (ret) {
+ debug_printf("map failed: %d\n", ret);
+ return NULL;
+ }
+
+ return bo->map;
+}
+
+static void *
+nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+ unsigned offset, unsigned length, unsigned usage)
+{
+ struct nouveau_bo *bo = nouveau_bo(pb);
+ int ret;
+
+ ret = nouveau_bo_map_range(bo, offset, length,
+ nouveau_screen_map_flags(usage));
+ if (ret) {
+ debug_printf("map_range failed: %d\n", ret);
+ return NULL;
+ }
+
+ return (char *)bo->map - offset; /* why gallium? why? */
+}
+
+static void
+nouveau_screen_bo_map_flush(struct pipe_screen *pscreen, struct pipe_buffer *pb,
+ unsigned offset, unsigned length)
+{
+ struct nouveau_bo *bo = nouveau_bo(pb);
+
+ nouveau_bo_map_flush(bo, offset, length);
+}
+
+static void
+nouveau_screen_bo_unmap(struct pipe_screen *pscreen, struct pipe_buffer *pb)
+{
+ struct nouveau_bo *bo = nouveau_bo(pb);
+
+ nouveau_bo_unmap(bo);
+}
+
+static void
+nouveau_screen_bo_del(struct pipe_buffer *pb)
+{
+ struct nouveau_bo *bo = nouveau_bo(pb);
+
+ nouveau_bo_ref(NULL, &bo);
+ FREE(pb);
+}
+
+static void
+nouveau_screen_fence_ref(struct pipe_screen *pscreen,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *pfence)
+{
+ *ptr = pfence;
+}
+
+static int
+nouveau_screen_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *pfence,
+ unsigned flags)
+{
+ return 0;
+}
+
+static int
+nouveau_screen_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *pfence,
+ unsigned flags)
+{
+ return 0;
+}
+
+int
+nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
+{
+ struct pipe_screen *pscreen = &screen->base;
+ int ret;
+
+ ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
+ &screen->channel);
+ if (ret)
+ return ret;
+ screen->device = dev;
+
+ pscreen->get_name = nouveau_screen_get_name;
+ pscreen->get_vendor = nouveau_screen_get_vendor;
+
+ pscreen->buffer_create = nouveau_screen_bo_new;
+ pscreen->user_buffer_create = nouveau_screen_bo_user;
+ pscreen->buffer_map = nouveau_screen_bo_map;
+ pscreen->buffer_map_range = nouveau_screen_bo_map_range;
+ pscreen->buffer_flush_mapped_range = nouveau_screen_bo_map_flush;
+ pscreen->buffer_unmap = nouveau_screen_bo_unmap;
+ pscreen->buffer_destroy = nouveau_screen_bo_del;
+
+ pscreen->fence_reference = nouveau_screen_fence_ref;
+ pscreen->fence_signalled = nouveau_screen_fence_signalled;
+ pscreen->fence_finish = nouveau_screen_fence_finish;
+
+ return 0;
+}
+
+void
+nouveau_screen_fini(struct nouveau_screen *screen)
+{
+}
+
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
new file mode 100644
index 0000000000..9968b07896
--- /dev/null
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -0,0 +1,25 @@
+#ifndef __NOUVEAU_SCREEN_H__
+#define __NOUVEAU_SCREEN_H__
+
+struct nouveau_screen {
+ struct pipe_screen base;
+ struct nouveau_device *device;
+ struct nouveau_channel *channel;
+};
+
+static inline struct nouveau_screen *
+nouveau_screen(struct pipe_screen *pscreen)
+{
+ return (struct nouveau_screen *)pscreen;
+}
+
+static inline struct nouveau_bo *
+nouveau_bo(struct pipe_buffer *pb)
+{
+ return pb ? *(struct nouveau_bo **)(pb + 1) : NULL;
+}
+
+int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
+void nouveau_screen_fini(struct nouveau_screen *);
+
+#endif
diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h
index a54820e851..b595405357 100644
--- a/src/gallium/drivers/nouveau/nouveau_stateobj.h
+++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h
@@ -4,7 +4,7 @@
#include "util/u_debug.h"
struct nouveau_stateobj_reloc {
- struct pipe_buffer *bo;
+ struct nouveau_bo *bo;
unsigned offset;
unsigned packet;
@@ -51,7 +51,7 @@ so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso)
if (pipe_reference((struct pipe_reference**)pso, &ref->reference)) {
free(so->push);
for (i = 0; i < so->cur_reloc; i++)
- pipe_buffer_reference(&so->reloc[i].bo, NULL);
+ nouveau_bo_ref(NULL, &so->reloc[i].bo);
free(so->reloc);
free(so);
}
@@ -81,13 +81,13 @@ so_method(struct nouveau_stateobj *so, struct nouveau_grobj *gr,
}
static INLINE void
-so_reloc(struct nouveau_stateobj *so, struct pipe_buffer *bo,
+so_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo,
unsigned data, unsigned flags, unsigned vor, unsigned tor)
{
struct nouveau_stateobj_reloc *r = &so->reloc[so->cur_reloc++];
r->bo = NULL;
- pipe_buffer_reference(&r->bo, bo);
+ nouveau_bo_ref(bo, &r->bo);
r->offset = so->cur - so->push;
r->packet = so->cur_packet;
r->data = data;
@@ -107,50 +107,52 @@ so_dump(struct nouveau_stateobj *so)
}
static INLINE void
-so_emit(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
+so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so)
{
- struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
+ struct nouveau_pushbuf *pb = chan->pushbuf;
unsigned nr, i;
nr = so->cur - so->push;
if (pb->remaining < nr)
- nvws->push_flush(nvws, nr, NULL);
+ nouveau_pushbuf_flush(chan, nr);
pb->remaining -= nr;
memcpy(pb->cur, so->push, nr * 4);
for (i = 0; i < so->cur_reloc; i++) {
struct nouveau_stateobj_reloc *r = &so->reloc[i];
- nvws->push_reloc(nvws, pb->cur + r->offset, r->bo,
- r->data, r->flags, r->vor, r->tor);
+ nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset,
+ r->bo, r->data, 0, r->flags,
+ r->vor, r->tor);
}
pb->cur += nr;
}
static INLINE void
-so_emit_reloc_markers(struct nouveau_winsys *nvws, struct nouveau_stateobj *so)
+so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so)
{
- struct nouveau_pushbuf *pb = nvws->channel->pushbuf;
+ struct nouveau_pushbuf *pb = chan->pushbuf;
unsigned i;
if (!so)
return;
i = so->cur_reloc << 1;
- if (nvws->channel->pushbuf->remaining < i)
- nvws->push_flush(nvws, i, NULL);
- nvws->channel->pushbuf->remaining -= i;
+ if (pb->remaining < i)
+ nouveau_pushbuf_flush(chan, i);
+ pb->remaining -= i;
for (i = 0; i < so->cur_reloc; i++) {
struct nouveau_stateobj_reloc *r = &so->reloc[i];
- nvws->push_reloc(nvws, pb->cur++, r->bo, r->packet,
- (r->flags & (NOUVEAU_BO_VRAM |
- NOUVEAU_BO_GART |
- NOUVEAU_BO_RDWR)) |
- NOUVEAU_BO_DUMMY, 0, 0);
- nvws->push_reloc(nvws, pb->cur++, r->bo, r->data,
- r->flags | NOUVEAU_BO_DUMMY, r->vor, r->tor);
+ nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0,
+ (r->flags & (NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_GART |
+ NOUVEAU_BO_RDWR)) |
+ NOUVEAU_BO_DUMMY, 0, 0);
+ nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0,
+ r->flags | NOUVEAU_BO_DUMMY,
+ r->vor, r->tor);
}
}
diff --git a/src/gallium/drivers/nouveau/nouveau_winsys.h b/src/gallium/drivers/nouveau/nouveau_winsys.h
index ff7dd1c51c..42c77e5e77 100644
--- a/src/gallium/drivers/nouveau/nouveau_winsys.h
+++ b/src/gallium/drivers/nouveau/nouveau_winsys.h
@@ -23,77 +23,38 @@
#define NOUVEAU_BUFFER_USAGE_ZETA (1 << 17)
#define NOUVEAU_BUFFER_USAGE_TRANSFER (1 << 18)
-struct nouveau_winsys {
- struct pipe_winsys *ws;
-
- struct nouveau_channel *channel;
-
- int (*res_init)(struct nouveau_resource **heap, unsigned start,
- unsigned size);
- int (*res_alloc)(struct nouveau_resource *heap, int size, void *priv,
- struct nouveau_resource **);
- void (*res_free)(struct nouveau_resource **);
-
- int (*push_reloc)(struct nouveau_winsys *, void *ptr,
- struct pipe_buffer *, uint32_t data,
- uint32_t flags, uint32_t vor, uint32_t tor);
- int (*push_flush)(struct nouveau_winsys *, unsigned size,
- struct pipe_fence_handle **fence);
-
- int (*grobj_alloc)(struct nouveau_winsys *, int grclass,
- struct nouveau_grobj **);
- void (*grobj_free)(struct nouveau_grobj **);
-
- int (*notifier_alloc)(struct nouveau_winsys *, int count,
- struct nouveau_notifier **);
- void (*notifier_free)(struct nouveau_notifier **);
- void (*notifier_reset)(struct nouveau_notifier *, int id);
- uint32_t (*notifier_status)(struct nouveau_notifier *, int id);
- uint32_t (*notifier_retval)(struct nouveau_notifier *, int id);
- int (*notifier_wait)(struct nouveau_notifier *, int id,
- int status, double timeout);
-
- int (*surface_copy)(struct nouveau_winsys *, struct pipe_surface *,
- unsigned, unsigned, struct pipe_surface *,
- unsigned, unsigned, unsigned, unsigned);
- int (*surface_fill)(struct nouveau_winsys *, struct pipe_surface *,
- unsigned, unsigned, unsigned, unsigned, unsigned);
-
- struct nouveau_bo *(*get_bo)(struct pipe_buffer *);
-};
-
extern struct pipe_screen *
-nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
+nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_context *
nv04_create(struct pipe_screen *, unsigned pctx_id);
extern struct pipe_screen *
-nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
+nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_context *
nv10_create(struct pipe_screen *, unsigned pctx_id);
extern struct pipe_screen *
-nv20_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
+nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_context *
nv20_create(struct pipe_screen *, unsigned pctx_id);
extern struct pipe_screen *
-nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
+nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_context *
nv30_create(struct pipe_screen *, unsigned pctx_id);
extern struct pipe_screen *
-nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
+nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_context *
nv40_create(struct pipe_screen *, unsigned pctx_id);
extern struct pipe_screen *
-nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *);
+nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *);
extern struct pipe_context *
nv50_create(struct pipe_screen *, unsigned pctx_id);
diff --git a/src/gallium/drivers/nv04/nv04_context.c b/src/gallium/drivers/nv04/nv04_context.c
index d6710cd892..17166c9f51 100644
--- a/src/gallium/drivers/nv04/nv04_context.c
+++ b/src/gallium/drivers/nv04/nv04_context.c
@@ -64,6 +64,30 @@ nv04_init_hwctx(struct nv04_context *nv04)
return TRUE;
}
+static unsigned int
+nv04_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv04_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+
struct pipe_context *
nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -89,6 +113,9 @@ nv04_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv04->pipe.clear = nv04_clear;
nv04->pipe.flush = nv04_flush;
+ nv04->pipe.is_texture_referenced = nv04_is_texture_referenced;
+ nv04->pipe.is_buffer_referenced = nv04_is_buffer_referenced;
+
nv04_init_surface_functions(nv04);
nv04_init_state_functions(nv04);
diff --git a/src/gallium/drivers/nv04/nv04_miptree.c b/src/gallium/drivers/nv04/nv04_miptree.c
index 4da833c25e..93f752faec 100644
--- a/src/gallium/drivers/nv04/nv04_miptree.c
+++ b/src/gallium/drivers/nv04/nv04_miptree.c
@@ -31,7 +31,8 @@ nv04_miptree_layout(struct nv04_miptree *nv04mt)
for (l = 0; l <= pt->last_level; l++) {
- nv04mt->level[l].image_offset = offset;
+ nv04mt->level[l].image_offset =
+ CALLOC(nr_faces, sizeof(unsigned));
offset += nv04mt->level[l].pitch * pt->height[l];
}
diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c
index f9f6d97426..4bbedfb4d6 100644
--- a/src/gallium/drivers/nv04/nv04_screen.c
+++ b/src/gallium/drivers/nv04/nv04_screen.c
@@ -1,27 +1,9 @@
#include "pipe/p_screen.h"
#include "pipe/p_inlines.h"
-#include "util/u_simple_screen.h"
#include "nv04_context.h"
#include "nv04_screen.h"
-static const char *
-nv04_screen_get_name(struct pipe_screen *screen)
-{
- struct nv04_screen *nv04screen = nv04_screen(screen);
- struct nouveau_device *dev = nv04screen->nvws->channel->device;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
- return buffer;
-}
-
-static const char *
-nv04_screen_get_vendor(struct pipe_screen *screen)
-{
- return "nouveau";
-}
-
static int
nv04_screen_get_param(struct pipe_screen *screen, int param)
{
@@ -123,10 +105,9 @@ static void
nv04_screen_destroy(struct pipe_screen *pscreen)
{
struct nv04_screen *screen = nv04_screen(pscreen);
- struct nouveau_winsys *nvws = screen->nvws;
- nvws->notifier_free(&screen->sync);
- nvws->grobj_free(&screen->fahrenheit);
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->fahrenheit);
nv04_surface_2d_takedown(&screen->eng2d);
FREE(pscreen);
@@ -141,21 +122,38 @@ nv04_surface_buffer(struct pipe_surface *surf)
}
struct pipe_screen *
-nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv04_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv04_screen *screen = CALLOC_STRUCT(nv04_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
unsigned fahrenheit_class = 0, sub3d_class = 0;
- unsigned chipset = nvws->channel->device->chipset;
int ret;
if (!screen)
return NULL;
- screen->nvws = nvws;
+ pscreen = &screen->base.base;
+
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nv04_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nv04_screen_destroy;
+ pscreen->get_param = nv04_screen_get_param;
+ pscreen->get_paramf = nv04_screen_get_paramf;
+ pscreen->is_format_supported = nv04_screen_is_format_supported;
- if (chipset>=0x20) {
+ nv04_screen_init_miptree_functions(pscreen);
+ nv04_screen_init_transfer_functions(pscreen);
+
+ if (dev->chipset >= 0x20) {
fahrenheit_class = 0;
sub3d_class = 0;
- } else if (chipset>=0x10) {
+ } else if (dev->chipset >= 0x10) {
fahrenheit_class = NV10_DX5_TEXTURED_TRIANGLE;
sub3d_class = NV10_CONTEXT_SURFACES_3D;
} else {
@@ -164,50 +162,40 @@ nv04_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
}
if (!fahrenheit_class) {
- NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", chipset);
+ NOUVEAU_ERR("Unknown nv04 chipset: nv%02x\n", dev->chipset);
return NULL;
}
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(nvws);
- screen->eng2d->buf = nv04_surface_buffer;
-
/* 3D object */
- ret = nvws->grobj_alloc(nvws, fahrenheit_class, &screen->fahrenheit);
+ ret = nouveau_grobj_alloc(chan, 0xbeef0001, fahrenheit_class,
+ &screen->fahrenheit);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
return NULL;
}
+ BIND_RING(chan, screen->fahrenheit, 7);
/* 3D surface object */
- ret = nvws->grobj_alloc(nvws, sub3d_class, &screen->context_surfaces_3d);
+ ret = nouveau_grobj_alloc(chan, 0xbeef0002, sub3d_class,
+ &screen->context_surfaces_3d);
if (ret) {
NOUVEAU_ERR("Error creating 3D surface object: %d\n", ret);
return NULL;
}
+ BIND_RING(chan, screen->context_surfaces_3d, 6);
+
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(&screen->base);
+ screen->eng2d->buf = nv04_surface_buffer;
/* Notifier for sync purposes */
- ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv04_screen_destroy(&screen->pipe);
+ nv04_screen_destroy(pscreen);
return NULL;
}
- screen->pipe.winsys = ws;
- screen->pipe.destroy = nv04_screen_destroy;
-
- screen->pipe.get_name = nv04_screen_get_name;
- screen->pipe.get_vendor = nv04_screen_get_vendor;
- screen->pipe.get_param = nv04_screen_get_param;
- screen->pipe.get_paramf = nv04_screen_get_paramf;
-
- screen->pipe.is_format_supported = nv04_screen_is_format_supported;
-
- nv04_screen_init_miptree_functions(&screen->pipe);
- nv04_screen_init_transfer_functions(&screen->pipe);
- u_simple_screen_init(&screen->pipe);
-
- return &screen->pipe;
+ return pscreen;
}
diff --git a/src/gallium/drivers/nv04/nv04_screen.h b/src/gallium/drivers/nv04/nv04_screen.h
index ee6fb6db44..11466b9442 100644
--- a/src/gallium/drivers/nv04/nv04_screen.h
+++ b/src/gallium/drivers/nv04/nv04_screen.h
@@ -1,11 +1,11 @@
#ifndef __NV04_SCREEN_H__
#define __NV04_SCREEN_H__
-#include "pipe/p_screen.h"
+#include "nouveau/nouveau_screen.h"
#include "nv04_surface_2d.h"
struct nv04_screen {
- struct pipe_screen pipe;
+ struct nouveau_screen base;
struct nouveau_winsys *nvws;
unsigned chipset;
diff --git a/src/gallium/drivers/nv04/nv04_state.c b/src/gallium/drivers/nv04/nv04_state.c
index 87c635f962..d356ebd8b3 100644
--- a/src/gallium/drivers/nv04/nv04_state.c
+++ b/src/gallium/drivers/nv04/nv04_state.c
@@ -2,6 +2,7 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
+#include "pipe/p_inlines.h"
#include "tgsi/tgsi_parse.h"
@@ -334,7 +335,7 @@ nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const struct pipe_constant_buffer *buf )
{
struct nv04_context *nv04 = nv04_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *pscreen = pipe->screen;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
@@ -342,12 +343,12 @@ nv04_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
if (buf) {
void *mapped;
if (buf->buffer && buf->buffer->size &&
- (mapped = ws->buffer_map(ws, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
+ (mapped = pipe_buffer_map(pscreen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
{
memcpy(nv04->constbuf[shader], mapped, buf->buffer->size);
nv04->constbuf_nr[shader] =
buf->buffer->size / (4 * sizeof(float));
- ws->buffer_unmap(ws, buf->buffer);
+ pipe_buffer_unmap(pscreen, buf->buffer);
}
}
}
diff --git a/src/gallium/drivers/nv04/nv04_state.h b/src/gallium/drivers/nv04/nv04_state.h
index 0d51439e3f..399f750dbe 100644
--- a/src/gallium/drivers/nv04/nv04_state.h
+++ b/src/gallium/drivers/nv04/nv04_state.h
@@ -37,7 +37,7 @@ struct nv04_miptree {
struct {
uint pitch;
- uint image_offset;
+ uint *image_offset;
} level[PIPE_MAX_TEXTURE_LEVELS];
};
diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c
index f3a8d7efee..5afd028ddd 100644
--- a/src/gallium/drivers/nv04/nv04_surface_2d.c
+++ b/src/gallium/drivers/nv04/nv04_surface_2d.c
@@ -4,6 +4,7 @@
#include "nouveau/nouveau_winsys.h"
#include "nouveau/nouveau_util.h"
+#include "nouveau/nouveau_screen.h"
#include "nv04_surface_2d.h"
static INLINE int
@@ -96,11 +97,11 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
struct pipe_surface *src, int sx, int sy,
int w, int h)
{
- struct nouveau_channel *chan = ctx->nvws->channel;
+ struct nouveau_channel *chan = ctx->swzsurf->channel;
struct nouveau_grobj *swzsurf = ctx->swzsurf;
struct nouveau_grobj *sifm = ctx->sifm;
- struct nouveau_bo *src_bo = ctx->nvws->get_bo(ctx->buf(src));
- struct nouveau_bo *dst_bo = ctx->nvws->get_bo(ctx->buf(dst));
+ struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
+ struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
const unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
const unsigned max_w = 1024;
const unsigned max_h = 1024;
@@ -167,10 +168,10 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
struct pipe_surface *dst, int dx, int dy,
struct pipe_surface *src, int sx, int sy, int w, int h)
{
- struct nouveau_channel *chan = ctx->nvws->channel;
+ struct nouveau_channel *chan = ctx->m2mf->channel;
struct nouveau_grobj *m2mf = ctx->m2mf;
- struct nouveau_bo *src_bo = ctx->nvws->get_bo(ctx->buf(src));
- struct nouveau_bo *dst_bo = ctx->nvws->get_bo(ctx->buf(dst));
+ struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
+ struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
unsigned dst_offset = dst->offset + dy * dst_pitch +
@@ -213,11 +214,11 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
int dx, int dy, struct pipe_surface *src, int sx, int sy,
int w, int h)
{
- struct nouveau_channel *chan = ctx->nvws->channel;
+ struct nouveau_channel *chan = ctx->surf2d->channel;
struct nouveau_grobj *surf2d = ctx->surf2d;
struct nouveau_grobj *blit = ctx->blit;
- struct nouveau_bo *src_bo = ctx->nvws->get_bo(ctx->buf(src));
- struct nouveau_bo *dst_bo = ctx->nvws->get_bo(ctx->buf(dst));
+ struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
+ struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
int format;
@@ -279,10 +280,10 @@ static void
nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
int dx, int dy, int w, int h, unsigned value)
{
- struct nouveau_channel *chan = ctx->nvws->channel;
+ struct nouveau_channel *chan = ctx->surf2d->channel;
struct nouveau_grobj *surf2d = ctx->surf2d;
struct nouveau_grobj *rect = ctx->rect;
- struct nouveau_bo *dst_bo = ctx->nvws->get_bo(ctx->buf(dst));
+ struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
int cs2d_format, gdirect_format;
@@ -334,10 +335,10 @@ nv04_surface_2d_takedown(struct nv04_surface_2d **pctx)
}
struct nv04_surface_2d *
-nv04_surface_2d_init(struct nouveau_winsys *nvws)
+nv04_surface_2d_init(struct nouveau_screen *screen)
{
struct nv04_surface_2d *ctx = CALLOC_STRUCT(nv04_surface_2d);
- struct nouveau_channel *chan = nvws->channel;
+ struct nouveau_channel *chan = screen->channel;
unsigned handle = 0x88000000, class;
int ret;
@@ -460,7 +461,6 @@ nv04_surface_2d_init(struct nouveau_winsys *nvws)
return NULL;
}
- ctx->nvws = nvws;
ctx->copy = nv04_surface_copy;
ctx->fill = nv04_surface_fill;
return ctx;
diff --git a/src/gallium/drivers/nv04/nv04_surface_2d.h b/src/gallium/drivers/nv04/nv04_surface_2d.h
index 82ce7189c8..02b3f56ba8 100644
--- a/src/gallium/drivers/nv04/nv04_surface_2d.h
+++ b/src/gallium/drivers/nv04/nv04_surface_2d.h
@@ -7,7 +7,6 @@ struct nv04_surface {
};
struct nv04_surface_2d {
- struct nouveau_winsys *nvws;
struct nouveau_notifier *ntfy;
struct nouveau_grobj *surf2d;
struct nouveau_grobj *swzsurf;
@@ -26,7 +25,7 @@ struct nv04_surface_2d {
};
struct nv04_surface_2d *
-nv04_surface_2d_init(struct nouveau_winsys *nvws);
+nv04_surface_2d_init(struct nouveau_screen *screen);
void
nv04_surface_2d_takedown(struct nv04_surface_2d **);
diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c
index e925a44e29..854b855d64 100644
--- a/src/gallium/drivers/nv04/nv04_transfer.c
+++ b/src/gallium/drivers/nv04/nv04_transfer.c
@@ -43,7 +43,6 @@ nv04_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv04/nv04_vbo.c b/src/gallium/drivers/nv04/nv04_vbo.c
index d21a0e34f7..e3167814f2 100644
--- a/src/gallium/drivers/nv04/nv04_vbo.c
+++ b/src/gallium/drivers/nv04/nv04_vbo.c
@@ -1,6 +1,7 @@
#include "draw/draw_context.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "nv04_context.h"
#include "nv04_state.h"
@@ -13,6 +14,7 @@ boolean nv04_draw_elements( struct pipe_context *pipe,
unsigned indexSize,
unsigned prim, unsigned start, unsigned count)
{
+ struct pipe_screen *pscreen = pipe->screen;
struct nv04_context *nv04 = nv04_context( pipe );
struct draw_context *draw = nv04->draw;
unsigned i;
@@ -25,17 +27,17 @@ boolean nv04_draw_elements( struct pipe_context *pipe,
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (nv04->vtxbuf[i].buffer) {
void *buf
- = pipe->winsys->buffer_map(pipe->winsys,
- nv04->vtxbuf[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ = pipe_buffer_map(pscreen,
+ nv04->vtxbuf[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);
+ = pipe_buffer_map(pscreen, indexBuffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -55,12 +57,12 @@ boolean nv04_draw_elements( struct pipe_context *pipe,
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (nv04->vtxbuf[i].buffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, nv04->vtxbuf[i].buffer);
+ pipe_buffer_unmap(pscreen, nv04->vtxbuf[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
if (indexBuffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
+ pipe_buffer_unmap(pscreen, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
}
diff --git a/src/gallium/drivers/nv10/nv10_context.c b/src/gallium/drivers/nv10/nv10_context.c
index ef2c0c5d9f..a127b134ec 100644
--- a/src/gallium/drivers/nv10/nv10_context.c
+++ b/src/gallium/drivers/nv10/nv10_context.c
@@ -30,18 +30,18 @@ nv10_destroy(struct pipe_context *pipe)
static void nv10_init_hwctx(struct nv10_context *nv10)
{
struct nv10_screen *screen = nv10->screen;
- struct nouveau_winsys *nvws = screen->nvws;
+ struct nouveau_channel *chan = screen->base.channel;
int i;
float projectionmatrix[16];
BEGIN_RING(celsius, NV10TCL_DMA_NOTIFY, 1);
OUT_RING (screen->sync->handle);
BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY0, 2);
- OUT_RING (nvws->channel->vram->handle);
- OUT_RING (nvws->channel->gart->handle);
+ OUT_RING (chan->vram->handle);
+ OUT_RING (chan->gart->handle);
BEGIN_RING(celsius, NV10TCL_DMA_IN_MEMORY2, 2);
- OUT_RING (nvws->channel->vram->handle);
- OUT_RING (nvws->channel->vram->handle);
+ OUT_RING (chan->vram->handle);
+ OUT_RING (chan->vram->handle);
BEGIN_RING(celsius, NV10TCL_NOP, 1);
OUT_RING (0);
@@ -257,6 +257,29 @@ nv10_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
{
}
+static unsigned int
+nv10_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv10_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -282,6 +305,9 @@ nv10_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv10->pipe.clear = nv10_clear;
nv10->pipe.flush = nv10_flush;
+ nv10->pipe.is_texture_referenced = nv10_is_texture_referenced;
+ nv10->pipe.is_buffer_referenced = nv10_is_buffer_referenced;
+
nv10_init_surface_functions(nv10);
nv10_init_state_functions(nv10);
diff --git a/src/gallium/drivers/nv10/nv10_prim_vbuf.c b/src/gallium/drivers/nv10/nv10_prim_vbuf.c
index 089c236302..1806d5f8cc 100644
--- a/src/gallium/drivers/nv10/nv10_prim_vbuf.c
+++ b/src/gallium/drivers/nv10/nv10_prim_vbuf.c
@@ -40,7 +40,6 @@
#include "util/u_debug.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "nv10_context.h"
#include "nv10_state.h"
@@ -124,11 +123,10 @@ nv10_vbuf_render_map_vertices( struct vbuf_render *render )
{
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
struct nv10_context *nv10 = nv10_render->nv10;
- struct pipe_winsys *winsys = nv10->pipe.winsys;
+ struct pipe_screen *pscreen = nv10->pipe.screen;
- return winsys->buffer_map(winsys,
- nv10_render->buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ return pipe_buffer_map(pscreen, nv10_render->buffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
}
static void
@@ -138,10 +136,10 @@ nv10_vbuf_render_unmap_vertices( struct vbuf_render *render,
{
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
struct nv10_context *nv10 = nv10_render->nv10;
- struct pipe_winsys *winsys = nv10->pipe.winsys;
+ struct pipe_screen *pscreen = nv10->pipe.screen;
assert(!nv10_render->buffer);
- winsys->buffer_unmap(winsys, nv10_render->buffer);
+ pipe_buffer_unmap(pscreen, nv10_render->buffer);
}
static boolean
@@ -202,8 +200,6 @@ static void
nv10_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv10_vbuf_render *nv10_render = nv10_vbuf_render(render);
- struct nv10_context *nv10 = nv10_render->nv10;
- struct pipe_screen *pscreen = &nv10->screen->pipe;
assert(nv10_render->buffer);
pipe_buffer_reference(&nv10_render->buffer, NULL);
diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c
index 6532a93c7b..b03c291f9d 100644
--- a/src/gallium/drivers/nv10/nv10_screen.c
+++ b/src/gallium/drivers/nv10/nv10_screen.c
@@ -1,26 +1,8 @@
#include "pipe/p_screen.h"
-#include "util/u_simple_screen.h"
#include "nv10_context.h"
#include "nv10_screen.h"
-static const char *
-nv10_screen_get_name(struct pipe_screen *screen)
-{
- struct nv10_screen *nv10screen = nv10_screen(screen);
- struct nouveau_device *dev = nv10screen->nvws->channel->device;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
- return buffer;
-}
-
-static const char *
-nv10_screen_get_vendor(struct pipe_screen *screen)
-{
- return "nouveau";
-}
-
static int
nv10_screen_get_param(struct pipe_screen *screen, int param)
{
@@ -120,10 +102,9 @@ static void
nv10_screen_destroy(struct pipe_screen *pscreen)
{
struct nv10_screen *screen = nv10_screen(pscreen);
- struct nouveau_winsys *nvws = screen->nvws;
- nvws->notifier_free(&screen->sync);
- nvws->grobj_free(&screen->celsius);
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->celsius);
FREE(pscreen);
}
@@ -137,64 +118,69 @@ nv10_surface_buffer(struct pipe_surface *surf)
}
struct pipe_screen *
-nv10_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv10_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv10_screen *screen = CALLOC_STRUCT(nv10_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
unsigned celsius_class;
- unsigned chipset = nvws->channel->device->chipset;
int ret;
if (!screen)
return NULL;
- screen->nvws = nvws;
+ pscreen = &screen->base.base;
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(nvws);
- screen->eng2d->buf = nv10_surface_buffer;
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nv10_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nv10_screen_destroy;
+ pscreen->get_param = nv10_screen_get_param;
+ pscreen->get_paramf = nv10_screen_get_paramf;
+ pscreen->is_format_supported = nv10_screen_is_format_supported;
+
+ nv10_screen_init_miptree_functions(pscreen);
+ nv10_screen_init_transfer_functions(pscreen);
/* 3D object */
- if (chipset>=0x20)
- celsius_class=NV11TCL;
- else if (chipset>=0x17)
- celsius_class=NV17TCL;
- else if (chipset>=0x11)
- celsius_class=NV11TCL;
+ if (dev->chipset >= 0x20)
+ celsius_class = NV11TCL;
+ else if (dev->chipset >= 0x17)
+ celsius_class = NV17TCL;
+ else if (dev->chipset >= 0x11)
+ celsius_class = NV11TCL;
else
- celsius_class=NV10TCL;
+ celsius_class = NV10TCL;
if (!celsius_class) {
- NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", chipset);
+ NOUVEAU_ERR("Unknown nv1x chipset: nv%02x\n", dev->chipset);
return NULL;
}
- ret = nvws->grobj_alloc(nvws, celsius_class, &screen->celsius);
+ ret = nouveau_grobj_alloc(chan, 0xbeef0001, celsius_class,
+ &screen->celsius);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
return FALSE;
}
+ BIND_RING(chan, screen->celsius, 7);
+
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(&screen->base);
+ screen->eng2d->buf = nv10_surface_buffer;
/* Notifier for sync purposes */
- ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv10_screen_destroy(&screen->pipe);
+ nv10_screen_destroy(pscreen);
return NULL;
}
- screen->pipe.winsys = ws;
- screen->pipe.destroy = nv10_screen_destroy;
-
- screen->pipe.get_name = nv10_screen_get_name;
- screen->pipe.get_vendor = nv10_screen_get_vendor;
- screen->pipe.get_param = nv10_screen_get_param;
- screen->pipe.get_paramf = nv10_screen_get_paramf;
-
- screen->pipe.is_format_supported = nv10_screen_is_format_supported;
-
- nv10_screen_init_miptree_functions(&screen->pipe);
- nv10_screen_init_transfer_functions(&screen->pipe);
- u_simple_screen_init(&screen->pipe);
-
- return &screen->pipe;
+ return pscreen;
}
diff --git a/src/gallium/drivers/nv10/nv10_screen.h b/src/gallium/drivers/nv10/nv10_screen.h
index ad829ee3fd..86b6d8def5 100644
--- a/src/gallium/drivers/nv10/nv10_screen.h
+++ b/src/gallium/drivers/nv10/nv10_screen.h
@@ -1,11 +1,11 @@
#ifndef __NV10_SCREEN_H__
#define __NV10_SCREEN_H__
-#include "pipe/p_screen.h"
+#include "nouveau/nouveau_screen.h"
#include "nv04/nv04_surface_2d.h"
struct nv10_screen {
- struct pipe_screen pipe;
+ struct nouveau_screen base;
struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nv10/nv10_state.c b/src/gallium/drivers/nv10/nv10_state.c
index 119af66dfd..9b38219b99 100644
--- a/src/gallium/drivers/nv10/nv10_state.c
+++ b/src/gallium/drivers/nv10/nv10_state.c
@@ -2,6 +2,7 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
+#include "pipe/p_inlines.h"
#include "tgsi/tgsi_parse.h"
@@ -460,7 +461,7 @@ nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const struct pipe_constant_buffer *buf )
{
struct nv10_context *nv10 = nv10_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *pscreen = pipe->screen;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
@@ -468,12 +469,12 @@ nv10_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
if (buf) {
void *mapped;
if (buf->buffer && buf->buffer->size &&
- (mapped = ws->buffer_map(ws, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
+ (mapped = pipe_buffer_map(pscreen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
{
memcpy(nv10->constbuf[shader], mapped, buf->buffer->size);
nv10->constbuf_nr[shader] =
buf->buffer->size / (4 * sizeof(float));
- ws->buffer_unmap(ws, buf->buffer);
+ pipe_buffer_unmap(pscreen, buf->buffer);
}
}
}
diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c
index 5a99225409..c06b8d34c7 100644
--- a/src/gallium/drivers/nv10/nv10_transfer.c
+++ b/src/gallium/drivers/nv10/nv10_transfer.c
@@ -43,7 +43,6 @@ nv10_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv10/nv10_vbo.c b/src/gallium/drivers/nv10/nv10_vbo.c
index d0e788ac03..441a4f75f3 100644
--- a/src/gallium/drivers/nv10/nv10_vbo.c
+++ b/src/gallium/drivers/nv10/nv10_vbo.c
@@ -1,6 +1,7 @@
#include "draw/draw_context.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "nv10_context.h"
#include "nv10_state.h"
@@ -15,6 +16,7 @@ boolean nv10_draw_elements( struct pipe_context *pipe,
{
struct nv10_context *nv10 = nv10_context( pipe );
struct draw_context *draw = nv10->draw;
+ struct pipe_screen *pscreen = pipe->screen;
unsigned i;
nv10_emit_hw_state(nv10);
@@ -24,9 +26,8 @@ boolean nv10_draw_elements( struct pipe_context *pipe,
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (nv10->vtxbuf[i].buffer) {
- void *buf
- = pipe->winsys->buffer_map(pipe->winsys,
- nv10->vtxbuf[i].buffer,
+ void *buf =
+ pipe_buffer_map(pscreen, nv10->vtxbuf[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
@@ -34,8 +35,8 @@ boolean nv10_draw_elements( struct pipe_context *pipe,
/* Map index buffer, if present */
if (indexBuffer) {
void *mapped_indexes
- = pipe->winsys->buffer_map(pipe->winsys, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ = pipe_buffer_map(pscreen, indexBuffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -55,12 +56,12 @@ boolean nv10_draw_elements( struct pipe_context *pipe,
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (nv10->vtxbuf[i].buffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, nv10->vtxbuf[i].buffer);
+ pipe_buffer_unmap(pscreen, nv10->vtxbuf[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
if (indexBuffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
+ pipe_buffer_unmap(pscreen, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
}
diff --git a/src/gallium/drivers/nv20/nv20_context.c b/src/gallium/drivers/nv20/nv20_context.c
index 1659aec8fa..b32d0d83ba 100644
--- a/src/gallium/drivers/nv20/nv20_context.c
+++ b/src/gallium/drivers/nv20/nv20_context.c
@@ -30,7 +30,7 @@ nv20_destroy(struct pipe_context *pipe)
static void nv20_init_hwctx(struct nv20_context *nv20)
{
struct nv20_screen *screen = nv20->screen;
- struct nouveau_winsys *nvws = screen->nvws;
+ struct nouveau_channel *chan = screen->base.channel;
int i;
float projectionmatrix[16];
const boolean is_nv25tcl = (nv20->screen->kelvin->grclass == NV25TCL);
@@ -38,11 +38,11 @@ static void nv20_init_hwctx(struct nv20_context *nv20)
BEGIN_RING(kelvin, NV20TCL_DMA_NOTIFY, 1);
OUT_RING (screen->sync->handle);
BEGIN_RING(kelvin, NV20TCL_DMA_TEXTURE0, 2);
- OUT_RING (nvws->channel->vram->handle);
- OUT_RING (nvws->channel->gart->handle); /* TEXTURE1 */
+ OUT_RING (chan->vram->handle);
+ OUT_RING (chan->gart->handle); /* TEXTURE1 */
BEGIN_RING(kelvin, NV20TCL_DMA_COLOR, 2);
- OUT_RING (nvws->channel->vram->handle);
- OUT_RING (nvws->channel->vram->handle); /* ZETA */
+ OUT_RING (chan->vram->handle);
+ OUT_RING (chan->vram->handle); /* ZETA */
BEGIN_RING(kelvin, NV20TCL_DMA_QUERY, 1);
OUT_RING (0); /* renouveau: beef0351, unique */
@@ -99,9 +99,9 @@ static void nv20_init_hwctx(struct nv20_context *nv20)
OUT_RING (3);
BEGIN_RING(kelvin, NV25TCL_DMA_IN_MEMORY9, 1);
- OUT_RING (nvws->channel->vram->handle);
+ OUT_RING (chan->vram->handle);
BEGIN_RING(kelvin, NV25TCL_DMA_IN_MEMORY8, 1);
- OUT_RING (nvws->channel->vram->handle);
+ OUT_RING (chan->vram->handle);
}
BEGIN_RING(kelvin, NV20TCL_DMA_FENCE, 1);
OUT_RING (0); /* renouveau: beef1e10 */
@@ -380,6 +380,30 @@ nv20_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
{
}
+
+static unsigned int
+nv20_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv20_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -405,6 +429,9 @@ nv20_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv20->pipe.clear = nv20_clear;
nv20->pipe.flush = nv20_flush;
+ nv20->pipe.is_texture_referenced = nv20_is_texture_referenced;
+ nv20->pipe.is_buffer_referenced = nv20_is_buffer_referenced;
+
nv20_init_surface_functions(nv20);
nv20_init_state_functions(nv20);
diff --git a/src/gallium/drivers/nv20/nv20_prim_vbuf.c b/src/gallium/drivers/nv20/nv20_prim_vbuf.c
index 8aa342cd2d..ddfcdb8057 100644
--- a/src/gallium/drivers/nv20/nv20_prim_vbuf.c
+++ b/src/gallium/drivers/nv20/nv20_prim_vbuf.c
@@ -152,12 +152,11 @@ static void *
nv20_vbuf_render_map_vertices( struct vbuf_render *render )
{
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
- struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
+ struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen;
if (nv20_render->pbuffer) {
- return winsys->buffer_map(winsys,
- nv20_render->pbuffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ return pipe_buffer_map(pscreen, nv20_render->pbuffer,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
} else if (nv20_render->mbuffer) {
return nv20_render->mbuffer;
} else
@@ -173,10 +172,10 @@ nv20_vbuf_render_unmap_vertices( struct vbuf_render *render,
ushort max_index )
{
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
- struct pipe_winsys *winsys = nv20_render->nv20->pipe.winsys;
+ struct pipe_screen *pscreen = nv20_render->nv20->pipe.screen;
if (nv20_render->pbuffer)
- winsys->buffer_unmap(winsys, nv20_render->pbuffer);
+ pipe_buffer_unmap(pscreen, nv20_render->pbuffer);
}
static boolean
@@ -358,7 +357,6 @@ nv20_vbuf_render_release_vertices( struct vbuf_render *render )
{
struct nv20_vbuf_render *nv20_render = nv20_vbuf_render(render);
struct nv20_context *nv20 = nv20_render->nv20;
- struct pipe_screen *pscreen = &nv20->screen->pipe;
if (nv20_render->pbuffer) {
pipe_buffer_reference(&nv20_render->pbuffer, NULL);
diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c
index 7760ae27c0..024356ca74 100644
--- a/src/gallium/drivers/nv20/nv20_screen.c
+++ b/src/gallium/drivers/nv20/nv20_screen.c
@@ -1,26 +1,8 @@
#include "pipe/p_screen.h"
-#include "util/u_simple_screen.h"
#include "nv20_context.h"
#include "nv20_screen.h"
-static const char *
-nv20_screen_get_name(struct pipe_screen *screen)
-{
- struct nv20_screen *nv20screen = nv20_screen(screen);
- struct nouveau_device *dev = nv20screen->nvws->channel->device;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
- return buffer;
-}
-
-static const char *
-nv20_screen_get_vendor(struct pipe_screen *screen)
-{
- return "nouveau";
-}
-
static int
nv20_screen_get_param(struct pipe_screen *screen, int param)
{
@@ -120,10 +102,9 @@ static void
nv20_screen_destroy(struct pipe_screen *pscreen)
{
struct nv20_screen *screen = nv20_screen(pscreen);
- struct nouveau_winsys *nvws = screen->nvws;
- nvws->notifier_free(&screen->sync);
- nvws->grobj_free(&screen->kelvin);
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->kelvin);
FREE(pscreen);
}
@@ -137,60 +118,65 @@ nv20_surface_buffer(struct pipe_surface *surf)
}
struct pipe_screen *
-nv20_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv20_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv20_screen *screen = CALLOC_STRUCT(nv20_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
unsigned kelvin_class = 0;
- unsigned chipset = nvws->channel->device->chipset;
int ret;
if (!screen)
return NULL;
- screen->nvws = nvws;
+ pscreen = &screen->base.base;
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(nvws);
- screen->eng2d->buf = nv20_surface_buffer;
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nv20_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nv20_screen_destroy;
+ pscreen->get_param = nv20_screen_get_param;
+ pscreen->get_paramf = nv20_screen_get_paramf;
+ pscreen->is_format_supported = nv20_screen_is_format_supported;
+
+ nv20_screen_init_miptree_functions(pscreen);
+ nv20_screen_init_transfer_functions(pscreen);
/* 3D object */
- if (chipset >= 0x25)
+ if (dev->chipset >= 0x25)
kelvin_class = NV25TCL;
- else if (chipset >= 0x20)
+ else if (dev->chipset >= 0x20)
kelvin_class = NV20TCL;
- if (!kelvin_class || chipset >= 0x30) {
- NOUVEAU_ERR("Unknown nv2x chipset: nv%02x\n", chipset);
+ if (!kelvin_class || dev->chipset >= 0x30) {
+ NOUVEAU_ERR("Unknown nv2x chipset: nv%02x\n", dev->chipset);
return NULL;
}
- ret = nvws->grobj_alloc(nvws, kelvin_class, &screen->kelvin);
+ ret = nouveau_grobj_alloc(chan, 0xbeef0097, kelvin_class,
+ &screen->kelvin);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
return FALSE;
}
+ BIND_RING(chan, screen->kelvin, 7);
+
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(&screen->base);
+ screen->eng2d->buf = nv20_surface_buffer;
/* Notifier for sync purposes */
- ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv20_screen_destroy(&screen->pipe);
+ nv20_screen_destroy(pscreen);
return NULL;
}
- screen->pipe.winsys = ws;
- screen->pipe.destroy = nv20_screen_destroy;
-
- screen->pipe.get_name = nv20_screen_get_name;
- screen->pipe.get_vendor = nv20_screen_get_vendor;
- screen->pipe.get_param = nv20_screen_get_param;
- screen->pipe.get_paramf = nv20_screen_get_paramf;
-
- screen->pipe.is_format_supported = nv20_screen_is_format_supported;
-
- nv20_screen_init_miptree_functions(&screen->pipe);
- nv20_screen_init_transfer_functions(&screen->pipe);
- u_simple_screen_init(&screen->pipe);
-
- return &screen->pipe;
+ return pscreen;
}
diff --git a/src/gallium/drivers/nv20/nv20_screen.h b/src/gallium/drivers/nv20/nv20_screen.h
index d9fce2bced..fc7bb05033 100644
--- a/src/gallium/drivers/nv20/nv20_screen.h
+++ b/src/gallium/drivers/nv20/nv20_screen.h
@@ -1,11 +1,11 @@
#ifndef __NV20_SCREEN_H__
#define __NV20_SCREEN_H__
-#include "pipe/p_screen.h"
+#include "nouveau/nouveau_screen.h"
#include "nv04/nv04_surface_2d.h"
struct nv20_screen {
- struct pipe_screen pipe;
+ struct nouveau_screen base;
struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nv20/nv20_state.c b/src/gallium/drivers/nv20/nv20_state.c
index ecec4f49a0..ed4084980f 100644
--- a/src/gallium/drivers/nv20/nv20_state.c
+++ b/src/gallium/drivers/nv20/nv20_state.c
@@ -2,6 +2,7 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "pipe/p_shader_tokens.h"
+#include "pipe/p_inlines.h"
#include "tgsi/tgsi_parse.h"
@@ -453,7 +454,7 @@ nv20_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
const struct pipe_constant_buffer *buf )
{
struct nv20_context *nv20 = nv20_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *pscreen = pipe->screen;
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
@@ -461,12 +462,12 @@ nv20_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
if (buf) {
void *mapped;
if (buf->buffer && buf->buffer->size &&
- (mapped = ws->buffer_map(ws, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
+ (mapped = pipe_buffer_map(pscreen, buf->buffer, PIPE_BUFFER_USAGE_CPU_READ)))
{
memcpy(nv20->constbuf[shader], mapped, buf->buffer->size);
nv20->constbuf_nr[shader] =
buf->buffer->size / (4 * sizeof(float));
- ws->buffer_unmap(ws, buf->buffer);
+ pipe_buffer_unmap(pscreen, buf->buffer);
}
}
}
diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c
index e5255296aa..5018995596 100644
--- a/src/gallium/drivers/nv20/nv20_transfer.c
+++ b/src/gallium/drivers/nv20/nv20_transfer.c
@@ -43,7 +43,6 @@ nv20_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv20/nv20_vbo.c b/src/gallium/drivers/nv20/nv20_vbo.c
index 24d8f4bef0..84d7db6c5e 100644
--- a/src/gallium/drivers/nv20/nv20_vbo.c
+++ b/src/gallium/drivers/nv20/nv20_vbo.c
@@ -1,6 +1,7 @@
#include "draw/draw_context.h"
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "nv20_context.h"
#include "nv20_state.h"
@@ -13,6 +14,7 @@ boolean nv20_draw_elements( struct pipe_context *pipe,
unsigned indexSize,
unsigned prim, unsigned start, unsigned count)
{
+ struct pipe_screen *pscreen = pipe->screen;
struct nv20_context *nv20 = nv20_context( pipe );
struct draw_context *draw = nv20->draw;
unsigned i;
@@ -25,17 +27,17 @@ boolean nv20_draw_elements( struct pipe_context *pipe,
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (nv20->vtxbuf[i].buffer) {
void *buf
- = pipe->winsys->buffer_map(pipe->winsys,
- nv20->vtxbuf[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ = pipe_buffer_map(pscreen,
+ nv20->vtxbuf[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);
+ = pipe_buffer_map(pscreen, indexBuffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(draw, indexSize, mapped_indexes);
}
else {
@@ -55,12 +57,12 @@ boolean nv20_draw_elements( struct pipe_context *pipe,
*/
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
if (nv20->vtxbuf[i].buffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, nv20->vtxbuf[i].buffer);
+ pipe_buffer_unmap(pscreen, nv20->vtxbuf[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
}
if (indexBuffer) {
- pipe->winsys->buffer_unmap(pipe->winsys, indexBuffer);
+ pipe_buffer_unmap(pscreen, indexBuffer);
draw_set_mapped_element_buffer(draw, 0, NULL);
}
diff --git a/src/gallium/drivers/nv20/nv20_vertprog.c b/src/gallium/drivers/nv20/nv20_vertprog.c
index 5db0e807ff..c1e588902b 100644
--- a/src/gallium/drivers/nv20/nv20_vertprog.c
+++ b/src/gallium/drivers/nv20/nv20_vertprog.c
@@ -1,6 +1,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
@@ -645,8 +646,8 @@ out_err:
static boolean
nv20_vertprog_validate(struct nv20_context *nv20)
{
+ struct pipe_screen *pscreen = nv20->pipe.screen;
struct nouveau_winsys *nvws = nv20->nvws;
- struct pipe_winsys *ws = nv20->pipe.winsys;
struct nouveau_grobj *rankine = nv20->screen->rankine;
struct nv20_vertex_program *vp;
struct pipe_buffer *constbuf;
@@ -749,8 +750,8 @@ nv20_vertprog_validate(struct nv20_context *nv20)
float *map = NULL;
if (constbuf) {
- map = ws->buffer_map(ws, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, constbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
}
for (i = 0; i < vp->nr_consts; i++) {
@@ -770,9 +771,8 @@ nv20_vertprog_validate(struct nv20_context *nv20)
OUT_RINGp ((uint32_t *)vpd->value, 4);
}
- if (constbuf) {
- ws->buffer_unmap(ws, constbuf);
- }
+ if (constbuf)
+ pipe_buffer_unmap(pscreen, constbuf);
}
/* Upload vtxprog */
diff --git a/src/gallium/drivers/nv30/nv30_context.c b/src/gallium/drivers/nv30/nv30_context.c
index 61654f8756..f827bdc78b 100644
--- a/src/gallium/drivers/nv30/nv30_context.c
+++ b/src/gallium/drivers/nv30/nv30_context.c
@@ -31,6 +31,29 @@ nv30_destroy(struct pipe_context *pipe)
FREE(nv30);
}
+static unsigned int
+nv30_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv30_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv30_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -55,6 +78,9 @@ nv30_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv30->pipe.clear = nv30_clear;
nv30->pipe.flush = nv30_flush;
+ nv30->pipe.is_texture_referenced = nv30_is_texture_referenced;
+ nv30->pipe.is_buffer_referenced = nv30_is_buffer_referenced;
+
nv30_init_query_functions(nv30);
nv30_init_surface_functions(nv30);
nv30_init_state_functions(nv30);
diff --git a/src/gallium/drivers/nv30/nv30_fragprog.c b/src/gallium/drivers/nv30/nv30_fragprog.c
index bdfe1425d2..1d1c556fb1 100644
--- a/src/gallium/drivers/nv30/nv30_fragprog.c
+++ b/src/gallium/drivers/nv30/nv30_fragprog.c
@@ -1,6 +1,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
@@ -798,12 +799,12 @@ static void
nv30_fragprog_upload(struct nv30_context *nv30,
struct nv30_fragment_program *fp)
{
- struct pipe_winsys *ws = nv30->pipe.winsys;
+ struct pipe_screen *pscreen = nv30->pipe.screen;
const uint32_t le = 1;
uint32_t *map;
int i;
- map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
#if 0
for (i = 0; i < fp->insn_len; i++) {
@@ -825,7 +826,7 @@ nv30_fragprog_upload(struct nv30_context *nv30,
}
}
- ws->buffer_unmap(ws, fp->buffer);
+ pipe_buffer_unmap(pscreen, fp->buffer);
}
static boolean
@@ -834,8 +835,7 @@ nv30_fragprog_validate(struct nv30_context *nv30)
struct nv30_fragment_program *fp = nv30->fragprog;
struct pipe_buffer *constbuf =
nv30->constbuf[PIPE_SHADER_FRAGMENT];
- struct pipe_screen *screen = nv30->pipe.screen;
- struct pipe_winsys *ws = nv30->pipe.winsys;
+ struct pipe_screen *pscreen = nv30->pipe.screen;
struct nouveau_stateobj *so;
boolean new_consts = FALSE;
int i;
@@ -850,14 +850,15 @@ nv30_fragprog_validate(struct nv30_context *nv30)
return FALSE;
}
- fp->buffer = screen->buffer_create(screen, 0x100, 0, fp->insn_len * 4);
+ fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
nv30_fragprog_upload(nv30, fp);
so = so_new(8, 1);
so_method(so, nv30->screen->rankine, NV34TCL_FP_ACTIVE_PROGRAM, 1);
- so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- NV34TCL_FP_ACTIVE_PROGRAM_DMA0, NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
+ so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_OR, NV34TCL_FP_ACTIVE_PROGRAM_DMA0,
+ NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
so_method(so, nv30->screen->rankine, NV34TCL_FP_CONTROL, 1);
so_data (so, fp->fp_control);
so_method(so, nv30->screen->rankine, NV34TCL_FP_REG_CONTROL, 1);
@@ -871,7 +872,8 @@ update_constants:
if (fp->nr_consts) {
float *map;
- map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, constbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
for (i = 0; i < fp->nr_consts; i++) {
struct nv30_fragment_program_data *fpd = &fp->consts[i];
uint32_t *p = &fp->insn[fpd->offset];
@@ -882,7 +884,7 @@ update_constants:
memcpy(p, cb, 4 * sizeof(float));
new_consts = TRUE;
}
- ws->buffer_unmap(ws, constbuf);
+ pipe_buffer_unmap(pscreen, constbuf);
if (new_consts)
nv30_fragprog_upload(nv30, fp);
diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c
index 8b6ab992d1..822e1d8def 100644
--- a/src/gallium/drivers/nv30/nv30_fragtex.c
+++ b/src/gallium/drivers/nv30/nv30_fragtex.c
@@ -61,6 +61,7 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
struct nv30_sampler_state *ps = nv30->tex_sampler[unit];
struct nv30_miptree *nv30mt = nv30->tex_miptree[unit];
struct pipe_texture *pt = &nv30mt->base;
+ struct nouveau_bo *bo = nouveau_bo(nv30mt->buffer);
struct nv30_texture_format *tf;
struct nouveau_stateobj *so;
uint32_t txf, txs , txp;
@@ -106,9 +107,9 @@ nv30_fragtex_build(struct nv30_context *nv30, int unit)
so = so_new(16, 2);
so_method(so, nv30->screen->rankine, NV34TCL_TX_OFFSET(unit), 8);
- so_reloc (so, nv30mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
- so_reloc (so, nv30mt->buffer, txf, tex_flags | NOUVEAU_BO_OR,
- NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
+ so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
+ NV34TCL_TX_FORMAT_DMA0, NV34TCL_TX_FORMAT_DMA1);
so_data (so, ps->wrap);
so_data (so, NV34TCL_TX_ENABLE_ENABLE | ps->en);
so_data (so, txs);
diff --git a/src/gallium/drivers/nv30/nv30_query.c b/src/gallium/drivers/nv30/nv30_query.c
index 2f974cf5c4..1d1c8a484e 100644
--- a/src/gallium/drivers/nv30/nv30_query.c
+++ b/src/gallium/drivers/nv30/nv30_query.c
@@ -29,11 +29,10 @@ nv30_query_create(struct pipe_context *pipe, unsigned query_type)
static void
nv30_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
{
- struct nv30_context *nv30 = nv30_context(pipe);
struct nv30_query *q = nv30_query(pq);
if (q->object)
- nv30->nvws->res_free(&q->object);
+ nouveau_resource_free(&q->object);
FREE(q);
}
@@ -54,9 +53,9 @@ nv30_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
pipe->get_query_result(pipe, pq, 1, &tmp);
}
- if (nv30->nvws->res_alloc(nv30->screen->query_heap, 1, NULL, &q->object))
+ if (nouveau_resource_alloc(nv30->screen->query_heap, 1, NULL, &q->object))
assert(0);
- nv30->nvws->notifier_reset(nv30->screen->query, q->object->start);
+ nouveau_notifier_reset(nv30->screen->query, q->object->start);
BEGIN_RING(rankine, NV34TCL_QUERY_RESET, 1);
OUT_RING (1);
@@ -84,27 +83,27 @@ nv30_query_result(struct pipe_context *pipe, struct pipe_query *pq,
{
struct nv30_context *nv30 = nv30_context(pipe);
struct nv30_query *q = nv30_query(pq);
- struct nouveau_winsys *nvws = nv30->nvws;
assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
if (!q->ready) {
unsigned status;
- status = nvws->notifier_status(nv30->screen->query,
- q->object->start);
+ status = nouveau_notifier_status(nv30->screen->query,
+ q->object->start);
if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
if (wait == FALSE)
return FALSE;
- nvws->notifier_wait(nv30->screen->query, q->object->start,
- NV_NOTIFY_STATE_STATUS_COMPLETED,
- 0);
+
+ nouveau_notifier_wait_status(nv30->screen->query,
+ q->object->start,
+ NV_NOTIFY_STATE_STATUS_COMPLETED, 0);
}
- q->result = nvws->notifier_retval(nv30->screen->query,
- q->object->start);
+ q->result = nouveau_notifier_return_val(nv30->screen->query,
+ q->object->start);
q->ready = TRUE;
- nvws->res_free(&q->object);
+ nouveau_resource_free(&q->object);
}
*result = q->result;
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index d395c5e1b7..31bc1f3173 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -1,5 +1,7 @@
#include "pipe/p_screen.h"
-#include "util/u_simple_screen.h"
+#include "pipe/p_state.h"
+
+#include "nouveau/nouveau_screen.h"
#include "nv30_context.h"
#include "nv30_screen.h"
@@ -8,23 +10,6 @@
#define NV34TCL_CHIPSET_3X_MASK 0x00000010
#define NV35TCL_CHIPSET_3X_MASK 0x000001e0
-static const char *
-nv30_screen_get_name(struct pipe_screen *pscreen)
-{
- struct nv30_screen *screen = nv30_screen(pscreen);
- struct nouveau_device *dev = screen->nvws->channel->device;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
- return buffer;
-}
-
-static const char *
-nv30_screen_get_vendor(struct pipe_screen *pscreen)
-{
- return "nouveau";
-}
-
static int
nv30_screen_get_param(struct pipe_screen *pscreen, int param)
{
@@ -139,45 +124,57 @@ static void
nv30_screen_destroy(struct pipe_screen *pscreen)
{
struct nv30_screen *screen = nv30_screen(pscreen);
- struct nouveau_winsys *nvws = screen->nvws;
- nvws->res_free(&screen->vp_exec_heap);
- nvws->res_free(&screen->vp_data_heap);
- nvws->res_free(&screen->query_heap);
- nvws->notifier_free(&screen->query);
- nvws->notifier_free(&screen->sync);
- nvws->grobj_free(&screen->rankine);
+ nouveau_resource_free(&screen->vp_exec_heap);
+ nouveau_resource_free(&screen->vp_data_heap);
+ nouveau_resource_free(&screen->query_heap);
+ nouveau_notifier_free(&screen->query);
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->rankine);
FREE(pscreen);
}
struct pipe_screen *
-nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv30_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv30_screen *screen = CALLOC_STRUCT(nv30_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
struct nouveau_stateobj *so;
unsigned rankine_class = 0;
- unsigned chipset = nvws->channel->device->chipset;
int ret, i;
if (!screen)
return NULL;
- screen->nvws = nvws;
+ pscreen = &screen->base.base;
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(nvws);
- screen->eng2d->buf = nv30_surface_buffer;
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nv30_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nv30_screen_destroy;
+ pscreen->get_param = nv30_screen_get_param;
+ pscreen->get_paramf = nv30_screen_get_paramf;
+ pscreen->is_format_supported = nv30_screen_surface_format_supported;
+
+ nv30_screen_init_miptree_functions(pscreen);
+ nv30_screen_init_transfer_functions(pscreen);
/* 3D object */
- switch (chipset & 0xf0) {
+ switch (dev->chipset & 0xf0) {
case 0x30:
- if (NV30TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
+ if (NV30TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
rankine_class = 0x0397;
else
- if (NV34TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
+ if (NV34TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
rankine_class = 0x0697;
else
- if (NV35TCL_CHIPSET_3X_MASK & (1 << (chipset & 0x0f)))
+ if (NV35TCL_CHIPSET_3X_MASK & (1 << (dev->chipset & 0x0f)))
rankine_class = 0x0497;
break;
default:
@@ -185,43 +182,49 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
}
if (!rankine_class) {
- NOUVEAU_ERR("Unknown nv3x chipset: nv%02x\n", chipset);
+ NOUVEAU_ERR("Unknown nv3x chipset: nv%02x\n", dev->chipset);
return NULL;
}
- ret = nvws->grobj_alloc(nvws, rankine_class, &screen->rankine);
+ ret = nouveau_grobj_alloc(chan, 0xbeef3097, rankine_class,
+ &screen->rankine);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
return FALSE;
}
+ BIND_RING(chan, screen->rankine, 7);
+
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(&screen->base);
+ screen->eng2d->buf = nv30_surface_buffer;
/* Notifier for sync purposes */
- ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv30_screen_destroy(&screen->pipe);
+ nv30_screen_destroy(pscreen);
return NULL;
}
/* Query objects */
- ret = nvws->notifier_alloc(nvws, 32, &screen->query);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
if (ret) {
NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
- nv30_screen_destroy(&screen->pipe);
+ nv30_screen_destroy(pscreen);
return NULL;
}
- ret = nvws->res_init(&screen->query_heap, 0, 32);
+ ret = nouveau_resource_init(&screen->query_heap, 0, 32);
if (ret) {
NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
- nv30_screen_destroy(&screen->pipe);
+ nv30_screen_destroy(pscreen);
return NULL;
}
/* Vtxprog resources */
- if (nvws->res_init(&screen->vp_exec_heap, 0, 256) ||
- nvws->res_init(&screen->vp_data_heap, 0, 256)) {
- nv30_screen_destroy(&screen->pipe);
+ if (nouveau_resource_init(&screen->vp_exec_heap, 0, 256) ||
+ nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {
+ nv30_screen_destroy(pscreen);
return NULL;
}
@@ -230,23 +233,23 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->rankine, NV34TCL_DMA_NOTIFY, 1);
so_data (so, screen->sync->handle);
so_method(so, screen->rankine, NV34TCL_DMA_TEXTURE0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->gart->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->gart->handle);
so_method(so, screen->rankine, NV34TCL_DMA_COLOR1, 1);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->rankine, NV34TCL_DMA_COLOR0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->rankine, NV34TCL_DMA_VTXBUF0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->gart->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->gart->handle);
/* so_method(so, screen->rankine, NV34TCL_DMA_FENCE, 2);
so_data (so, 0);
so_data (so, screen->query->handle);*/
so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY7, 1);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->rankine, NV34TCL_DMA_IN_MEMORY8, 1);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
for (i=1; i<8; i++) {
so_method(so, screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(i), 1);
@@ -301,23 +304,9 @@ nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->rankine, 0x1e94, 1);
so_data (so, 0x13);
- so_emit(nvws, so);
+ so_emit(chan, so);
so_ref(NULL, &so);
- nvws->push_flush(nvws, 0, NULL);
-
- screen->pipe.winsys = ws;
- screen->pipe.destroy = nv30_screen_destroy;
-
- screen->pipe.get_name = nv30_screen_get_name;
- screen->pipe.get_vendor = nv30_screen_get_vendor;
- screen->pipe.get_param = nv30_screen_get_param;
- screen->pipe.get_paramf = nv30_screen_get_paramf;
-
- screen->pipe.is_format_supported = nv30_screen_surface_format_supported;
-
- nv30_screen_init_miptree_functions(&screen->pipe);
- nv30_screen_init_transfer_functions(&screen->pipe);
- u_simple_screen_init(&screen->pipe);
+ nouveau_pushbuf_flush(chan, 0);
- return &screen->pipe;
+ return pscreen;
}
diff --git a/src/gallium/drivers/nv30/nv30_screen.h b/src/gallium/drivers/nv30/nv30_screen.h
index 8e36883975..5fbd998b53 100644
--- a/src/gallium/drivers/nv30/nv30_screen.h
+++ b/src/gallium/drivers/nv30/nv30_screen.h
@@ -1,11 +1,12 @@
#ifndef __NV30_SCREEN_H__
#define __NV30_SCREEN_H__
-#include "pipe/p_screen.h"
+#include "nouveau/nouveau_screen.h"
+
#include "nv04/nv04_surface_2d.h"
struct nv30_screen {
- struct pipe_screen pipe;
+ struct nouveau_screen base;
struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c
index c18be20a32..621b8846c8 100644
--- a/src/gallium/drivers/nv30/nv30_state_emit.c
+++ b/src/gallium/drivers/nv30/nv30_state_emit.c
@@ -38,6 +38,7 @@ nv30_state_do_validate(struct nv30_context *nv30,
void
nv30_state_emit(struct nv30_context *nv30)
{
+ struct nouveau_channel *chan = nv30->screen->base.channel;
struct nv30_state *state = &nv30->state;
struct nv30_screen *screen = nv30->screen;
unsigned i, samplers;
@@ -57,23 +58,23 @@ nv30_state_emit(struct nv30_context *nv30)
continue;
so_ref (state->hw[i], &nv30->screen->state[i]);
if (state->hw[i])
- so_emit(nv30->nvws, nv30->screen->state[i]);
+ so_emit(chan, nv30->screen->state[i]);
states &= ~(1ULL << i);
}
state->dirty = 0;
- so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
+ so_emit_reloc_markers(chan, state->hw[NV30_STATE_FB]);
for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
if (!(samplers & (1 << i)))
continue;
- so_emit_reloc_markers(nv30->nvws,
+ so_emit_reloc_markers(chan,
state->hw[NV30_STATE_FRAGTEX0+i]);
samplers &= ~(1ULL << i);
}
- so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FRAGPROG]);
+ so_emit_reloc_markers(chan, state->hw[NV30_STATE_FRAGPROG]);
if (state->hw[NV30_STATE_VTXBUF] /*&& nv30->render_mode == HW*/)
- so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_VTXBUF]);
+ so_emit_reloc_markers(chan, state->hw[NV30_STATE_VTXBUF]);
}
boolean
diff --git a/src/gallium/drivers/nv30/nv30_state_fb.c b/src/gallium/drivers/nv30/nv30_state_fb.c
index fdc1cade90..cb1a260eaa 100644
--- a/src/gallium/drivers/nv30/nv30_state_fb.c
+++ b/src/gallium/drivers/nv30/nv30_state_fb.c
@@ -5,6 +5,8 @@ static boolean
nv30_state_framebuffer_validate(struct nv30_context *nv30)
{
struct pipe_framebuffer_state *fb = &nv30->framebuffer;
+ struct nouveau_channel *chan = nv30->screen->base.channel;
+ struct nouveau_grobj *rankine = nv30->screen->rankine;
struct nv04_surface *rt[2], *zeta = NULL;
uint32_t rt_enable, rt_format;
int i, colour_format = 0, zeta_format = 0;
@@ -79,56 +81,53 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
}
nv30mt = (struct nv30_miptree *)rt[0]->base.texture;
- so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR0, 1);
- so_reloc (so, nv30mt->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv30->nvws->channel->vram->handle,
- nv30->nvws->channel->gart->handle);
- so_method(so, nv30->screen->rankine, NV34TCL_COLOR0_PITCH, 2);
+ so_method(so, rankine, NV34TCL_DMA_COLOR0, 1);
+ so_reloc (so, nouveau_bo(nv30mt->buffer), 0, rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, rankine, NV34TCL_COLOR0_PITCH, 2);
so_data (so, pitch);
- so_reloc (so, nv30mt->buffer, rt[0]->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, nouveau_bo(nv30mt->buffer), rt[0]->base.offset,
+ rt_flags | NOUVEAU_BO_LOW, 0, 0);
}
if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
nv30mt = (struct nv30_miptree *)rt[1]->base.texture;
- so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR1, 1);
- so_reloc (so, nv30mt->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv30->nvws->channel->vram->handle,
- nv30->nvws->channel->gart->handle);
- so_method(so, nv30->screen->rankine, NV34TCL_COLOR1_OFFSET, 2);
- so_reloc (so, nv30mt->buffer, rt[1]->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, rankine, NV34TCL_DMA_COLOR1, 1);
+ so_reloc (so, nouveau_bo(nv30mt->buffer), 0, rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, rankine, NV34TCL_COLOR1_OFFSET, 2);
+ so_reloc (so, nouveau_bo(nv30mt->buffer), rt[1]->base.offset,
+ rt_flags | NOUVEAU_BO_LOW, 0, 0);
so_data (so, rt[1]->pitch);
}
if (zeta_format) {
nv30mt = (struct nv30_miptree *)zeta->base.texture;
- so_method(so, nv30->screen->rankine, NV34TCL_DMA_ZETA, 1);
- so_reloc (so, nv30mt->buffer, 0, rt_flags | NOUVEAU_BO_OR,
- nv30->nvws->channel->vram->handle,
- nv30->nvws->channel->gart->handle);
- so_method(so, nv30->screen->rankine, NV34TCL_ZETA_OFFSET, 1);
- so_reloc (so, nv30mt->buffer, zeta->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, rankine, NV34TCL_DMA_ZETA, 1);
+ so_reloc (so, nouveau_bo(nv30mt->buffer), 0, rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, rankine, NV34TCL_ZETA_OFFSET, 1);
+ so_reloc (so, nouveau_bo(nv30mt->buffer), zeta->base.offset,
+ rt_flags | NOUVEAU_BO_LOW, 0, 0);
/* TODO: allocate LMA depth buffer */
}
- so_method(so, nv30->screen->rankine, NV34TCL_RT_ENABLE, 1);
+ so_method(so, rankine, NV34TCL_RT_ENABLE, 1);
so_data (so, rt_enable);
- so_method(so, nv30->screen->rankine, NV34TCL_RT_HORIZ, 3);
+ so_method(so, rankine, NV34TCL_RT_HORIZ, 3);
so_data (so, (w << 16) | 0);
so_data (so, (h << 16) | 0);
so_data (so, rt_format);
- so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_HORIZ, 2);
+ so_method(so, rankine, NV34TCL_VIEWPORT_HORIZ, 2);
so_data (so, (w << 16) | 0);
so_data (so, (h << 16) | 0);
- so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
+ so_method(so, rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
so_data (so, ((w - 1) << 16) | 0);
so_data (so, ((h - 1) << 16) | 0);
- so_method(so, nv30->screen->rankine, 0x1d88, 1);
+ so_method(so, rankine, 0x1d88, 1);
so_data (so, (1 << 12) | h);
/* Wonder why this is needed, context should all be set to zero on init */
- so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
+ so_method(so, rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
so_data (so, 0);
so_ref(so, &nv30->state.hw[NV30_STATE_FB]);
diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c
index 8b915b35bd..2367571878 100644
--- a/src/gallium/drivers/nv30/nv30_transfer.c
+++ b/src/gallium/drivers/nv30/nv30_transfer.c
@@ -43,7 +43,6 @@ nv30_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c
index 990a876382..189656ec81 100644
--- a/src/gallium/drivers/nv30/nv30_vbo.c
+++ b/src/gallium/drivers/nv30/nv30_vbo.c
@@ -1,5 +1,6 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "nv30_context.h"
#include "nv30_state.h"
@@ -70,7 +71,7 @@ static boolean
nv30_vbo_set_idxbuf(struct nv30_context *nv30, struct pipe_buffer *ib,
unsigned ib_size)
{
- struct pipe_screen *pscreen = &nv30->screen->pipe;
+ struct pipe_screen *pscreen = &nv30->screen->base.base;
unsigned type;
if (!ib) {
@@ -108,7 +109,7 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so,
int attrib, struct pipe_vertex_element *ve,
struct pipe_vertex_buffer *vb)
{
- struct pipe_winsys *ws = nv30->pipe.winsys;
+ struct pipe_screen *pscreen = nv30->pipe.screen;
struct nouveau_grobj *rankine = nv30->screen->rankine;
unsigned type, ncomp;
void *map;
@@ -116,7 +117,7 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so,
if (nv30_vbo_format_to_hw(ve->src_format, &type, &ncomp))
return FALSE;
- map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
map += vb->buffer_offset + ve->src_offset;
switch (type) {
@@ -148,18 +149,17 @@ nv30_vbo_static_attrib(struct nv30_context *nv30, struct nouveau_stateobj *so,
so_data (so, fui(v[0]));
break;
default:
- ws->buffer_unmap(ws, vb->buffer);
+ pipe_buffer_unmap(pscreen, vb->buffer);
return FALSE;
}
}
break;
default:
- ws->buffer_unmap(ws, vb->buffer);
+ pipe_buffer_unmap(pscreen, vb->buffer);
return FALSE;
}
- ws->buffer_unmap(ws, vb->buffer);
-
+ pipe_buffer_unmap(pscreen, vb->buffer);
return TRUE;
}
@@ -168,7 +168,7 @@ nv30_draw_arrays(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv30_context *nv30 = nv30_context(pipe);
- struct nouveau_channel *chan = nv30->nvws->channel;
+ struct nouveau_channel *chan = nv30->screen->base.channel;
unsigned restart = 0;
nv30_vbo_set_idxbuf(nv30, NULL, 0);
@@ -228,7 +228,7 @@ static INLINE void
nv30_draw_elements_u08(struct nv30_context *nv30, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv30->nvws->channel;
+ struct nouveau_channel *chan = nv30->screen->base.channel;
while (count) {
uint8_t *elts = (uint8_t *)ib + start;
@@ -277,7 +277,7 @@ static INLINE void
nv30_draw_elements_u16(struct nv30_context *nv30, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv30->nvws->channel;
+ struct nouveau_channel *chan = nv30->screen->base.channel;
while (count) {
uint16_t *elts = (uint16_t *)ib + start;
@@ -326,7 +326,7 @@ static INLINE void
nv30_draw_elements_u32(struct nv30_context *nv30, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv30->nvws->channel;
+ struct nouveau_channel *chan = nv30->screen->base.channel;
while (count) {
uint32_t *elts = (uint32_t *)ib + start;
@@ -368,10 +368,10 @@ nv30_draw_elements_inline(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv30_context *nv30 = nv30_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *pscreen = pipe->screen;
void *map;
- map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
if (!ib) {
NOUVEAU_ERR("failed mapping ib\n");
return FALSE;
@@ -392,7 +392,7 @@ nv30_draw_elements_inline(struct pipe_context *pipe,
break;
}
- ws->buffer_unmap(ws, ib);
+ pipe_buffer_unmap(pscreen, ib);
return TRUE;
}
@@ -401,7 +401,7 @@ nv30_draw_elements_vbo(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv30_context *nv30 = nv30_context(pipe);
- struct nouveau_channel *chan = nv30->nvws->channel;
+ struct nouveau_channel *chan = nv30->screen->base.channel;
unsigned restart = 0;
while (count) {
@@ -521,18 +521,20 @@ nv30_vbo_validate(struct nv30_context *nv30)
return FALSE;
}
- so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset,
- vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- 0, NV34TCL_VTXBUF_ADDRESS_DMA1);
+ so_reloc(vtxbuf, nouveau_bo(vb->buffer), vb->buffer_offset +
+ ve->src_offset, vb_flags | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_OR, 0, NV34TCL_VTXBUF_ADDRESS_DMA1);
so_data (vtxfmt, ((vb->stride << NV34TCL_VTXFMT_STRIDE_SHIFT) |
(ncomp << NV34TCL_VTXFMT_SIZE_SHIFT) | type));
}
if (ib) {
+ struct nouveau_bo *bo = nouveau_bo(ib);
+
so_method(vtxbuf, rankine, NV34TCL_IDXBUF_ADDRESS, 2);
- so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
- so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR,
- 0, NV34TCL_IDXBUF_FORMAT_DMA1);
+ so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
+ 0, NV34TCL_IDXBUF_FORMAT_DMA1);
}
so_method(vtxbuf, rankine, 0x1710, 1);
diff --git a/src/gallium/drivers/nv30/nv30_vertprog.c b/src/gallium/drivers/nv30/nv30_vertprog.c
index eaf543b8f7..c7514efcfe 100644
--- a/src/gallium/drivers/nv30/nv30_vertprog.c
+++ b/src/gallium/drivers/nv30/nv30_vertprog.c
@@ -1,6 +1,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
@@ -645,8 +646,7 @@ out_err:
static boolean
nv30_vertprog_validate(struct nv30_context *nv30)
{
- struct nouveau_winsys *nvws = nv30->nvws;
- struct pipe_winsys *ws = nv30->pipe.winsys;
+ struct pipe_screen *pscreen = nv30->pipe.screen;
struct nouveau_grobj *rankine = nv30->screen->rankine;
struct nv30_vertex_program *vp;
struct pipe_buffer *constbuf;
@@ -669,15 +669,15 @@ nv30_vertprog_validate(struct nv30_context *nv30)
struct nouveau_stateobj *so;
uint vplen = vp->nr_insns;
- if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) {
+ if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec)) {
while (heap->next && heap->size < vplen) {
struct nv30_vertex_program *evict;
evict = heap->next->priv;
- nvws->res_free(&evict->exec);
+ nouveau_resource_free(&evict->exec);
}
- if (nvws->res_alloc(heap, vplen, vp, &vp->exec))
+ if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec))
assert(0);
}
@@ -694,15 +694,16 @@ nv30_vertprog_validate(struct nv30_context *nv30)
if (vp->nr_consts && !vp->data) {
struct nouveau_resource *heap = nv30->screen->vp_data_heap;
- if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) {
+ if (nouveau_resource_alloc(heap, vp->nr_consts, vp, &vp->data)) {
while (heap->next && heap->size < vp->nr_consts) {
struct nv30_vertex_program *evict;
evict = heap->next->priv;
- nvws->res_free(&evict->data);
+ nouveau_resource_free(&evict->data);
}
- if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data))
+ if (nouveau_resource_alloc(heap, vp->nr_consts, vp,
+ &vp->data))
assert(0);
}
@@ -750,8 +751,8 @@ nv30_vertprog_validate(struct nv30_context *nv30)
float *map = NULL;
if (constbuf) {
- map = ws->buffer_map(ws, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, constbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
}
for (i = 0; i < vp->nr_consts; i++) {
@@ -771,9 +772,8 @@ nv30_vertprog_validate(struct nv30_context *nv30)
OUT_RINGp ((uint32_t *)vpd->value, 4);
}
- if (constbuf) {
- ws->buffer_unmap(ws, constbuf);
- }
+ if (constbuf)
+ pipe_buffer_unmap(pscreen, constbuf);
}
/* Upload vtxprog */
@@ -804,8 +804,6 @@ nv30_vertprog_validate(struct nv30_context *nv30)
void
nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp)
{
- struct nouveau_winsys *nvws = nv30->screen->nvws;
-
vp->translated = FALSE;
if (vp->nr_insns) {
@@ -820,9 +818,9 @@ nv30_vertprog_destroy(struct nv30_context *nv30, struct nv30_vertex_program *vp)
vp->nr_consts = 0;
}
- nvws->res_free(&vp->exec);
+ nouveau_resource_free(&vp->exec);
vp->exec_start = 0;
- nvws->res_free(&vp->data);
+ nouveau_resource_free(&vp->data);
vp->data_start = 0;
vp->data_start_min = 0;
diff --git a/src/gallium/drivers/nv40/nv40_context.c b/src/gallium/drivers/nv40/nv40_context.c
index 5d325f5067..8eba6a43ef 100644
--- a/src/gallium/drivers/nv40/nv40_context.c
+++ b/src/gallium/drivers/nv40/nv40_context.c
@@ -31,6 +31,29 @@ nv40_destroy(struct pipe_context *pipe)
FREE(nv40);
}
+static unsigned int
+nv40_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv40_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -55,6 +78,9 @@ nv40_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv40->pipe.clear = nv40_clear;
nv40->pipe.flush = nv40_flush;
+ nv40->pipe.is_texture_referenced = nv40_is_texture_referenced;
+ nv40->pipe.is_buffer_referenced = nv40_is_buffer_referenced;
+
nv40_init_query_functions(nv40);
nv40_init_surface_functions(nv40);
nv40_init_state_functions(nv40);
diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c
index c83ff91d7e..b2f19ecb69 100644
--- a/src/gallium/drivers/nv40/nv40_draw.c
+++ b/src/gallium/drivers/nv40/nv40_draw.c
@@ -1,4 +1,5 @@
#include "pipe/p_shader_tokens.h"
+#include "pipe/p_inlines.h"
#include "util/u_pack_color.h"
@@ -81,7 +82,7 @@ nv40_render_prim(struct draw_stage *stage, struct prim_header *prim,
{
struct nv40_render_stage *rs = nv40_render_stage(stage);
struct nv40_context *nv40 = rs->nv40;
- struct nouveau_pushbuf *pb = nv40->nvws->channel->pushbuf;
+ struct nouveau_pushbuf *pb = nv40->screen->base.channel->pushbuf;
unsigned i;
/* Ensure there's room for 4xfloat32 + potentially 3 begin/end */
@@ -231,7 +232,7 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *pscreen = pipe->screen;
unsigned i;
void *map;
@@ -241,13 +242,14 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe,
nv40_state_emit(nv40);
for (i = 0; i < nv40->vtxbuf_nr; i++) {
- map = ws->buffer_map(ws, nv40->vtxbuf[i].buffer,
+ map = pipe_buffer_map(pscreen, nv40->vtxbuf[i].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(nv40->draw, i, map);
}
if (idxbuf) {
- map = ws->buffer_map(ws, idxbuf, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, idxbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer(nv40->draw, idxbuf_size, map);
} else {
draw_set_mapped_element_buffer(nv40->draw, 0, NULL);
@@ -256,21 +258,22 @@ nv40_draw_elements_swtnl(struct pipe_context *pipe,
if (nv40->constbuf[PIPE_SHADER_VERTEX]) {
const unsigned nr = nv40->constbuf_nr[PIPE_SHADER_VERTEX];
- map = ws->buffer_map(ws, nv40->constbuf[PIPE_SHADER_VERTEX],
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen,
+ nv40->constbuf[PIPE_SHADER_VERTEX],
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_constant_buffer(nv40->draw, map, nr);
}
draw_arrays(nv40->draw, mode, start, count);
for (i = 0; i < nv40->vtxbuf_nr; i++)
- ws->buffer_unmap(ws, nv40->vtxbuf[i].buffer);
+ pipe_buffer_unmap(pscreen, nv40->vtxbuf[i].buffer);
if (idxbuf)
- ws->buffer_unmap(ws, idxbuf);
+ pipe_buffer_unmap(pscreen, idxbuf);
if (nv40->constbuf[PIPE_SHADER_VERTEX])
- ws->buffer_unmap(ws, nv40->constbuf[PIPE_SHADER_VERTEX]);
+ pipe_buffer_unmap(pscreen, nv40->constbuf[PIPE_SHADER_VERTEX]);
draw_flush(nv40->draw);
pipe->flush(pipe, 0, NULL);
diff --git a/src/gallium/drivers/nv40/nv40_fragprog.c b/src/gallium/drivers/nv40/nv40_fragprog.c
index 16e40889ec..680976da56 100644
--- a/src/gallium/drivers/nv40/nv40_fragprog.c
+++ b/src/gallium/drivers/nv40/nv40_fragprog.c
@@ -1,6 +1,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
@@ -881,12 +882,12 @@ static void
nv40_fragprog_upload(struct nv40_context *nv40,
struct nv40_fragment_program *fp)
{
- struct pipe_winsys *ws = nv40->pipe.winsys;
+ struct pipe_screen *pscreen = nv40->pipe.screen;
const uint32_t le = 1;
uint32_t *map;
int i;
- map = ws->buffer_map(ws, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = pipe_buffer_map(pscreen, fp->buffer, PIPE_BUFFER_USAGE_CPU_WRITE);
#if 0
for (i = 0; i < fp->insn_len; i++) {
@@ -908,7 +909,7 @@ nv40_fragprog_upload(struct nv40_context *nv40,
}
}
- ws->buffer_unmap(ws, fp->buffer);
+ pipe_buffer_unmap(pscreen, fp->buffer);
}
static boolean
@@ -917,8 +918,7 @@ nv40_fragprog_validate(struct nv40_context *nv40)
struct nv40_fragment_program *fp = nv40->fragprog;
struct pipe_buffer *constbuf =
nv40->constbuf[PIPE_SHADER_FRAGMENT];
- struct pipe_screen *screen = nv40->pipe.screen;
- struct pipe_winsys *ws = nv40->pipe.winsys;
+ struct pipe_screen *pscreen = nv40->pipe.screen;
struct nouveau_stateobj *so;
boolean new_consts = FALSE;
int i;
@@ -933,14 +933,15 @@ nv40_fragprog_validate(struct nv40_context *nv40)
return FALSE;
}
- fp->buffer = screen->buffer_create(screen, 0x100, 0, fp->insn_len * 4);
+ fp->buffer = pscreen->buffer_create(pscreen, 0x100, 0, fp->insn_len * 4);
nv40_fragprog_upload(nv40, fp);
so = so_new(4, 1);
so_method(so, nv40->screen->curie, NV40TCL_FP_ADDRESS, 1);
- so_reloc (so, fp->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
- NOUVEAU_BO_RD | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- NV40TCL_FP_ADDRESS_DMA0, NV40TCL_FP_ADDRESS_DMA1);
+ so_reloc (so, nouveau_bo(fp->buffer), 0, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_GART | NOUVEAU_BO_RD | NOUVEAU_BO_LOW |
+ NOUVEAU_BO_OR, NV40TCL_FP_ADDRESS_DMA0,
+ NV40TCL_FP_ADDRESS_DMA1);
so_method(so, nv40->screen->curie, NV40TCL_FP_CONTROL, 1);
so_data (so, fp->fp_control);
so_ref(so, &fp->so);
@@ -950,7 +951,8 @@ update_constants:
if (fp->nr_consts) {
float *map;
- map = ws->buffer_map(ws, constbuf, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, constbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
for (i = 0; i < fp->nr_consts; i++) {
struct nv40_fragment_program_data *fpd = &fp->consts[i];
uint32_t *p = &fp->insn[fpd->offset];
@@ -961,7 +963,7 @@ update_constants:
memcpy(p, cb, 4 * sizeof(float));
new_consts = TRUE;
}
- ws->buffer_unmap(ws, constbuf);
+ pipe_buffer_unmap(pscreen, constbuf);
if (new_consts)
nv40_fragprog_upload(nv40, fp);
diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c
index eb3002dc05..f6cdf31dfe 100644
--- a/src/gallium/drivers/nv40/nv40_fragtex.c
+++ b/src/gallium/drivers/nv40/nv40_fragtex.c
@@ -62,6 +62,7 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
{
struct nv40_sampler_state *ps = nv40->tex_sampler[unit];
struct nv40_miptree *nv40mt = nv40->tex_miptree[unit];
+ struct nouveau_bo *bo = nouveau_bo(nv40mt->buffer);
struct pipe_texture *pt = &nv40mt->base;
struct nv40_texture_format *tf;
struct nouveau_stateobj *so;
@@ -108,9 +109,9 @@ nv40_fragtex_build(struct nv40_context *nv40, int unit)
so = so_new(16, 2);
so_method(so, nv40->screen->curie, NV40TCL_TEX_OFFSET(unit), 8);
- so_reloc (so, nv40mt->buffer, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
- so_reloc (so, nv40mt->buffer, txf, tex_flags | NOUVEAU_BO_OR,
- NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1);
+ so_reloc (so, bo, 0, tex_flags | NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, bo, txf, tex_flags | NOUVEAU_BO_OR,
+ NV40TCL_TEX_FORMAT_DMA0, NV40TCL_TEX_FORMAT_DMA1);
so_data (so, ps->wrap);
so_data (so, NV40TCL_TEX_ENABLE_ENABLE | ps->en);
so_data (so, txs);
diff --git a/src/gallium/drivers/nv40/nv40_query.c b/src/gallium/drivers/nv40/nv40_query.c
index 9b9a43f49d..7874aedd42 100644
--- a/src/gallium/drivers/nv40/nv40_query.c
+++ b/src/gallium/drivers/nv40/nv40_query.c
@@ -29,11 +29,10 @@ nv40_query_create(struct pipe_context *pipe, unsigned query_type)
static void
nv40_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
{
- struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_query *q = nv40_query(pq);
if (q->object)
- nv40->nvws->res_free(&q->object);
+ nouveau_resource_free(&q->object);
FREE(q);
}
@@ -54,9 +53,9 @@ nv40_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
pipe->get_query_result(pipe, pq, 1, &tmp);
}
- if (nv40->nvws->res_alloc(nv40->screen->query_heap, 1, NULL, &q->object))
+ if (nouveau_resource_alloc(nv40->screen->query_heap, 1, NULL, &q->object))
assert(0);
- nv40->nvws->notifier_reset(nv40->screen->query, q->object->start);
+ nouveau_notifier_reset(nv40->screen->query, q->object->start);
BEGIN_RING(curie, NV40TCL_QUERY_RESET, 1);
OUT_RING (1);
@@ -84,27 +83,27 @@ nv40_query_result(struct pipe_context *pipe, struct pipe_query *pq,
{
struct nv40_context *nv40 = nv40_context(pipe);
struct nv40_query *q = nv40_query(pq);
- struct nouveau_winsys *nvws = nv40->nvws;
assert(q->object && q->type == PIPE_QUERY_OCCLUSION_COUNTER);
if (!q->ready) {
unsigned status;
- status = nvws->notifier_status(nv40->screen->query,
- q->object->start);
+ status = nouveau_notifier_status(nv40->screen->query,
+ q->object->start);
if (status != NV_NOTIFY_STATE_STATUS_COMPLETED) {
if (wait == FALSE)
return FALSE;
- nvws->notifier_wait(nv40->screen->query, q->object->start,
- NV_NOTIFY_STATE_STATUS_COMPLETED,
- 0);
+ nouveau_notifier_wait_status(nv40->screen->query,
+ q->object->start,
+ NV_NOTIFY_STATE_STATUS_COMPLETED,
+ 0);
}
- q->result = nvws->notifier_retval(nv40->screen->query,
- q->object->start);
+ q->result = nouveau_notifier_return_val(nv40->screen->query,
+ q->object->start);
q->ready = TRUE;
- nvws->res_free(&q->object);
+ nouveau_resource_free(&q->object);
}
*result = q->result;
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index 0d4baefaea..b8b2af482a 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -1,5 +1,4 @@
#include "pipe/p_screen.h"
-#include "util/u_simple_screen.h"
#include "nv40_context.h"
#include "nv40_screen.h"
@@ -8,23 +7,6 @@
#define NV4X_GRCLASS4497_CHIPSETS 0x00005450
#define NV6X_GRCLASS4497_CHIPSETS 0x00000088
-static const char *
-nv40_screen_get_name(struct pipe_screen *pscreen)
-{
- struct nv40_screen *screen = nv40_screen(pscreen);
- struct nouveau_device *dev = screen->nvws->channel->device;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
- return buffer;
-}
-
-static const char *
-nv40_screen_get_vendor(struct pipe_screen *pscreen)
-{
- return "nouveau";
-}
-
static int
nv40_screen_get_param(struct pipe_screen *pscreen, int param)
{
@@ -148,88 +130,107 @@ static void
nv40_screen_destroy(struct pipe_screen *pscreen)
{
struct nv40_screen *screen = nv40_screen(pscreen);
- struct nouveau_winsys *nvws = screen->nvws;
- nvws->res_free(&screen->vp_exec_heap);
- nvws->res_free(&screen->vp_data_heap);
- nvws->res_free(&screen->query_heap);
- nvws->notifier_free(&screen->query);
- nvws->notifier_free(&screen->sync);
- nvws->grobj_free(&screen->curie);
+ nouveau_resource_free(&screen->vp_exec_heap);
+ nouveau_resource_free(&screen->vp_data_heap);
+ nouveau_resource_free(&screen->query_heap);
+ nouveau_notifier_free(&screen->query);
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->curie);
+
+ nouveau_screen_fini(&screen->base);
FREE(pscreen);
}
struct pipe_screen *
-nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv40_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv40_screen *screen = CALLOC_STRUCT(nv40_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
struct nouveau_stateobj *so;
unsigned curie_class = 0;
- unsigned chipset = nvws->channel->device->chipset;
int ret;
if (!screen)
return NULL;
- screen->nvws = nvws;
+ pscreen = &screen->base.base;
- /* 2D engine setup */
- screen->eng2d = nv04_surface_2d_init(nvws);
- screen->eng2d->buf = nv40_surface_buffer;
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nv40_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nv40_screen_destroy;
+ pscreen->get_param = nv40_screen_get_param;
+ pscreen->get_paramf = nv40_screen_get_paramf;
+ pscreen->is_format_supported = nv40_screen_surface_format_supported;
+
+ nv40_screen_init_miptree_functions(pscreen);
+ nv40_screen_init_transfer_functions(pscreen);
/* 3D object */
- switch (chipset & 0xf0) {
+ switch (dev->chipset & 0xf0) {
case 0x40:
- if (NV4X_GRCLASS4097_CHIPSETS & (1 << (chipset & 0x0f)))
+ if (NV4X_GRCLASS4097_CHIPSETS & (1 << (dev->chipset & 0x0f)))
curie_class = NV40TCL;
else
- if (NV4X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f)))
+ if (NV4X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
curie_class = NV44TCL;
break;
case 0x60:
- if (NV6X_GRCLASS4497_CHIPSETS & (1 << (chipset & 0x0f)))
+ if (NV6X_GRCLASS4497_CHIPSETS & (1 << (dev->chipset & 0x0f)))
curie_class = NV44TCL;
break;
}
if (!curie_class) {
- NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", chipset);
+ NOUVEAU_ERR("Unknown nv4x chipset: nv%02x\n", dev->chipset);
return NULL;
}
- ret = nvws->grobj_alloc(nvws, curie_class, &screen->curie);
+ ret = nouveau_grobj_alloc(chan, 0xbeef3097, curie_class, &screen->curie);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
return FALSE;
}
+ BIND_RING(chan, screen->curie, 7);
+
+ /* 2D engine setup */
+ screen->eng2d = nv04_surface_2d_init(&screen->base);
+ screen->eng2d->buf = nv40_surface_buffer;
/* Notifier for sync purposes */
- ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv40_screen_destroy(&screen->pipe);
+ nv40_screen_destroy(pscreen);
return NULL;
}
/* Query objects */
- ret = nvws->notifier_alloc(nvws, 32, &screen->query);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0302, 32, &screen->query);
if (ret) {
NOUVEAU_ERR("Error initialising query objects: %d\n", ret);
- nv40_screen_destroy(&screen->pipe);
+ nv40_screen_destroy(pscreen);
return NULL;
}
- ret = nvws->res_init(&screen->query_heap, 0, 32);
+ nouveau_resource_init(&screen->query_heap, 0, 32);
if (ret) {
NOUVEAU_ERR("Error initialising query object heap: %d\n", ret);
- nv40_screen_destroy(&screen->pipe);
+ nv40_screen_destroy(pscreen);
return NULL;
}
/* Vtxprog resources */
- if (nvws->res_init(&screen->vp_exec_heap, 0, 512) ||
- nvws->res_init(&screen->vp_data_heap, 0, 256)) {
- nv40_screen_destroy(&screen->pipe);
+ if (nouveau_resource_init(&screen->vp_exec_heap, 0, 512) ||
+ nouveau_resource_init(&screen->vp_data_heap, 0, 256)) {
+ nv40_screen_destroy(pscreen);
return NULL;
}
@@ -238,25 +239,25 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->curie, NV40TCL_DMA_NOTIFY, 1);
so_data (so, screen->sync->handle);
so_method(so, screen->curie, NV40TCL_DMA_TEXTURE0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->gart->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->gart->handle);
so_method(so, screen->curie, NV40TCL_DMA_COLOR1, 1);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->curie, NV40TCL_DMA_COLOR0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->curie, NV40TCL_DMA_VTXBUF0, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->gart->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->gart->handle);
so_method(so, screen->curie, NV40TCL_DMA_FENCE, 2);
so_data (so, 0);
so_data (so, screen->query->handle);
so_method(so, screen->curie, NV40TCL_DMA_UNK01AC, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->curie, NV40TCL_DMA_COLOR2, 2);
- so_data (so, nvws->channel->vram->handle);
- so_data (so, nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->curie, 0x1ea4, 3);
so_data (so, 0x00000010);
@@ -281,24 +282,10 @@ nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->curie, 0x1e94, 1);
so_data (so, 0x00000001);
- so_emit(nvws, so);
+ so_emit(chan, so);
so_ref(NULL, &so);
- nvws->push_flush(nvws, 0, NULL);
-
- screen->pipe.winsys = ws;
- screen->pipe.destroy = nv40_screen_destroy;
-
- screen->pipe.get_name = nv40_screen_get_name;
- screen->pipe.get_vendor = nv40_screen_get_vendor;
- screen->pipe.get_param = nv40_screen_get_param;
- screen->pipe.get_paramf = nv40_screen_get_paramf;
-
- screen->pipe.is_format_supported = nv40_screen_surface_format_supported;
-
- nv40_screen_init_miptree_functions(&screen->pipe);
- nv40_screen_init_transfer_functions(&screen->pipe);
- u_simple_screen_init(&screen->pipe);
+ nouveau_pushbuf_flush(chan, 0);
- return &screen->pipe;
+ return pscreen;
}
diff --git a/src/gallium/drivers/nv40/nv40_screen.h b/src/gallium/drivers/nv40/nv40_screen.h
index 7b503bd207..57b4c8fc46 100644
--- a/src/gallium/drivers/nv40/nv40_screen.h
+++ b/src/gallium/drivers/nv40/nv40_screen.h
@@ -1,11 +1,11 @@
#ifndef __NV40_SCREEN_H__
#define __NV40_SCREEN_H__
-#include "pipe/p_screen.h"
+#include "nouveau/nouveau_screen.h"
#include "nv04/nv04_surface_2d.h"
struct nv40_screen {
- struct pipe_screen pipe;
+ struct nouveau_screen base;
struct nouveau_winsys *nvws;
diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c
index 10aae29832..198692965d 100644
--- a/src/gallium/drivers/nv40/nv40_state_emit.c
+++ b/src/gallium/drivers/nv40/nv40_state_emit.c
@@ -54,6 +54,7 @@ nv40_state_do_validate(struct nv40_context *nv40,
void
nv40_state_emit(struct nv40_context *nv40)
{
+ struct nouveau_channel *chan = nv40->screen->base.channel;
struct nv40_state *state = &nv40->state;
struct nv40_screen *screen = nv40->screen;
unsigned i, samplers;
@@ -73,7 +74,7 @@ nv40_state_emit(struct nv40_context *nv40)
continue;
so_ref (state->hw[i], &nv40->screen->state[i]);
if (state->hw[i])
- so_emit(nv40->nvws, nv40->screen->state[i]);
+ so_emit(chan, nv40->screen->state[i]);
states &= ~(1ULL << i);
}
@@ -87,17 +88,17 @@ nv40_state_emit(struct nv40_context *nv40)
state->dirty = 0;
- so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FB]);
+ so_emit_reloc_markers(chan, state->hw[NV40_STATE_FB]);
for (i = 0, samplers = state->fp_samplers; i < 16 && samplers; i++) {
if (!(samplers & (1 << i)))
continue;
- so_emit_reloc_markers(nv40->nvws,
+ so_emit_reloc_markers(chan,
state->hw[NV40_STATE_FRAGTEX0+i]);
samplers &= ~(1ULL << i);
}
- so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_FRAGPROG]);
+ so_emit_reloc_markers(chan, state->hw[NV40_STATE_FRAGPROG]);
if (state->hw[NV40_STATE_VTXBUF] && nv40->render_mode == HW)
- so_emit_reloc_markers(nv40->nvws, state->hw[NV40_STATE_VTXBUF]);
+ so_emit_reloc_markers(chan, state->hw[NV40_STATE_VTXBUF]);
}
boolean
diff --git a/src/gallium/drivers/nv40/nv40_state_fb.c b/src/gallium/drivers/nv40/nv40_state_fb.c
index be618a306b..273142f9e0 100644
--- a/src/gallium/drivers/nv40/nv40_state_fb.c
+++ b/src/gallium/drivers/nv40/nv40_state_fb.c
@@ -2,15 +2,19 @@
#include "nouveau/nouveau_util.h"
static struct pipe_buffer *
-nv40_surface_buffer(struct pipe_surface *surface)
+nv40_do_surface_buffer(struct pipe_surface *surface)
{
struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture;
return mt->buffer;
}
+#define nv40_surface_buffer(ps) nouveau_bo(nv40_do_surface_buffer(ps))
+
static boolean
nv40_state_framebuffer_validate(struct nv40_context *nv40)
{
+ struct nouveau_channel *chan = nv40->screen->base.channel;
+ struct nouveau_grobj *curie = nv40->screen->curie;
struct pipe_framebuffer_state *fb = &nv40->framebuffer;
struct nv04_surface *rt[4], *zeta;
uint32_t rt_enable, rt_format;
@@ -77,76 +81,80 @@ nv40_state_framebuffer_validate(struct nv40_context *nv40)
}
if (rt_enable & NV40TCL_RT_ENABLE_COLOR0) {
- so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR0, 1);
- so_reloc (so, nv40_surface_buffer(&rt[0]->base), 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->screen->curie, NV40TCL_COLOR0_PITCH, 2);
+ so_method(so, curie, NV40TCL_DMA_COLOR0, 1);
+ so_reloc (so, nv40_surface_buffer(&rt[0]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, curie, NV40TCL_COLOR0_PITCH, 2);
so_data (so, rt[0]->pitch);
- so_reloc (so, nv40_surface_buffer(&rt[0]->base), rt[0]->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, nv40_surface_buffer(&rt[0]->base),
+ rt[0]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
}
if (rt_enable & NV40TCL_RT_ENABLE_COLOR1) {
- so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR1, 1);
- so_reloc (so, nv40_surface_buffer(&rt[1]->base), 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->screen->curie, NV40TCL_COLOR1_OFFSET, 2);
- so_reloc (so, nv40_surface_buffer(&rt[1]->base), rt[1]->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, curie, NV40TCL_DMA_COLOR1, 1);
+ so_reloc (so, nv40_surface_buffer(&rt[1]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, curie, NV40TCL_COLOR1_OFFSET, 2);
+ so_reloc (so, nv40_surface_buffer(&rt[1]->base),
+ rt[1]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
so_data (so, rt[1]->pitch);
}
if (rt_enable & NV40TCL_RT_ENABLE_COLOR2) {
- so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR2, 1);
- so_reloc (so, nv40_surface_buffer(&rt[2]->base), 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->screen->curie, NV40TCL_COLOR2_OFFSET, 1);
- so_reloc (so, nv40_surface_buffer(&rt[2]->base), rt[2]->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_method(so, nv40->screen->curie, NV40TCL_COLOR2_PITCH, 1);
+ so_method(so, curie, NV40TCL_DMA_COLOR2, 1);
+ so_reloc (so, nv40_surface_buffer(&rt[2]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, curie, NV40TCL_COLOR2_OFFSET, 1);
+ so_reloc (so, nv40_surface_buffer(&rt[2]->base),
+ rt[2]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
+ so_method(so, curie, NV40TCL_COLOR2_PITCH, 1);
so_data (so, rt[2]->pitch);
}
if (rt_enable & NV40TCL_RT_ENABLE_COLOR3) {
- so_method(so, nv40->screen->curie, NV40TCL_DMA_COLOR3, 1);
- so_reloc (so, nv40_surface_buffer(&rt[3]->base), 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->screen->curie, NV40TCL_COLOR3_OFFSET, 1);
- so_reloc (so, nv40_surface_buffer(&rt[3]->base), rt[3]->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_method(so, nv40->screen->curie, NV40TCL_COLOR3_PITCH, 1);
+ so_method(so, curie, NV40TCL_DMA_COLOR3, 1);
+ so_reloc (so, nv40_surface_buffer(&rt[3]->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, curie, NV40TCL_COLOR3_OFFSET, 1);
+ so_reloc (so, nv40_surface_buffer(&rt[3]->base),
+ rt[3]->base.offset, rt_flags | NOUVEAU_BO_LOW,
+ 0, 0);
+ so_method(so, curie, NV40TCL_COLOR3_PITCH, 1);
so_data (so, rt[3]->pitch);
}
if (zeta_format) {
- so_method(so, nv40->screen->curie, NV40TCL_DMA_ZETA, 1);
- so_reloc (so, nv40_surface_buffer(&zeta->base), 0, rt_flags | NOUVEAU_BO_OR,
- nv40->nvws->channel->vram->handle,
- nv40->nvws->channel->gart->handle);
- so_method(so, nv40->screen->curie, NV40TCL_ZETA_OFFSET, 1);
- so_reloc (so, nv40_surface_buffer(&zeta->base), zeta->base.offset, rt_flags |
- NOUVEAU_BO_LOW, 0, 0);
- so_method(so, nv40->screen->curie, NV40TCL_ZETA_PITCH, 1);
+ so_method(so, curie, NV40TCL_DMA_ZETA, 1);
+ so_reloc (so, nv40_surface_buffer(&zeta->base), 0,
+ rt_flags | NOUVEAU_BO_OR,
+ chan->vram->handle, chan->gart->handle);
+ so_method(so, curie, NV40TCL_ZETA_OFFSET, 1);
+ so_reloc (so, nv40_surface_buffer(&zeta->base),
+ zeta->base.offset, rt_flags | NOUVEAU_BO_LOW, 0, 0);
+ so_method(so, curie, NV40TCL_ZETA_PITCH, 1);
so_data (so, zeta->pitch);
}
- so_method(so, nv40->screen->curie, NV40TCL_RT_ENABLE, 1);
+ so_method(so, curie, NV40TCL_RT_ENABLE, 1);
so_data (so, rt_enable);
- so_method(so, nv40->screen->curie, NV40TCL_RT_HORIZ, 3);
+ so_method(so, curie, NV40TCL_RT_HORIZ, 3);
so_data (so, (w << 16) | 0);
so_data (so, (h << 16) | 0);
so_data (so, rt_format);
- so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_HORIZ, 2);
+ so_method(so, curie, NV40TCL_VIEWPORT_HORIZ, 2);
so_data (so, (w << 16) | 0);
so_data (so, (h << 16) | 0);
- so_method(so, nv40->screen->curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
+ so_method(so, curie, NV40TCL_VIEWPORT_CLIP_HORIZ(0), 2);
so_data (so, ((w - 1) << 16) | 0);
so_data (so, ((h - 1) << 16) | 0);
- so_method(so, nv40->screen->curie, 0x1d88, 1);
+ so_method(so, curie, 0x1d88, 1);
so_data (so, (1 << 12) | h);
so_ref(so, &nv40->state.hw[NV40_STATE_FB]);
diff --git a/src/gallium/drivers/nv40/nv40_surface.c b/src/gallium/drivers/nv40/nv40_surface.c
index 1a849da32d..a596547974 100644
--- a/src/gallium/drivers/nv40/nv40_surface.c
+++ b/src/gallium/drivers/nv40/nv40_surface.c
@@ -26,12 +26,13 @@
*
**************************************************************************/
-#include "nv40_context.h"
#include "pipe/p_defines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_inlines.h"
+
#include "util/u_tile.h"
+#include "nv40_context.h"
+
static void
nv40_surface_copy(struct pipe_context *pipe,
struct pipe_surface *dest, unsigned destx, unsigned desty,
diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c
index 728e8b5674..ce45055fe8 100644
--- a/src/gallium/drivers/nv40/nv40_transfer.c
+++ b/src/gallium/drivers/nv40/nv40_transfer.c
@@ -43,7 +43,6 @@ nv40_compatible_transfer_tex(struct pipe_texture *pt, unsigned level,
template->nblocksx[0] = pt->nblocksx[level];
template->nblocksy[0] = pt->nblocksx[level];
template->last_level = 0;
- template->compressed = pt->compressed;
template->nr_samples = pt->nr_samples;
template->tex_usage = PIPE_TEXTURE_USAGE_DYNAMIC |
diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c
index f3518b2e4f..b2753b8e2e 100644
--- a/src/gallium/drivers/nv40/nv40_vbo.c
+++ b/src/gallium/drivers/nv40/nv40_vbo.c
@@ -1,5 +1,6 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "nv40_context.h"
#include "nv40_state.h"
@@ -70,7 +71,7 @@ static boolean
nv40_vbo_set_idxbuf(struct nv40_context *nv40, struct pipe_buffer *ib,
unsigned ib_size)
{
- struct pipe_screen *pscreen = &nv40->screen->pipe;
+ struct pipe_screen *pscreen = &nv40->screen->base.base;
unsigned type;
if (!ib) {
@@ -108,7 +109,7 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so,
int attrib, struct pipe_vertex_element *ve,
struct pipe_vertex_buffer *vb)
{
- struct pipe_winsys *ws = nv40->pipe.winsys;
+ struct pipe_screen *pscreen = nv40->pipe.screen;
struct nouveau_grobj *curie = nv40->screen->curie;
unsigned type, ncomp;
void *map;
@@ -116,7 +117,7 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so,
if (nv40_vbo_format_to_hw(ve->src_format, &type, &ncomp))
return FALSE;
- map = ws->buffer_map(ws, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, vb->buffer, PIPE_BUFFER_USAGE_CPU_READ);
map += vb->buffer_offset + ve->src_offset;
switch (type) {
@@ -148,17 +149,17 @@ nv40_vbo_static_attrib(struct nv40_context *nv40, struct nouveau_stateobj *so,
so_data (so, fui(v[0]));
break;
default:
- ws->buffer_unmap(ws, vb->buffer);
+ pipe_buffer_unmap(pscreen, vb->buffer);
return FALSE;
}
}
break;
default:
- ws->buffer_unmap(ws, vb->buffer);
+ pipe_buffer_unmap(pscreen, vb->buffer);
return FALSE;
}
- ws->buffer_unmap(ws, vb->buffer);
+ pipe_buffer_unmap(pscreen, vb->buffer);
return TRUE;
}
@@ -168,7 +169,7 @@ nv40_draw_arrays(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_channel *chan = nv40->nvws->channel;
+ struct nouveau_channel *chan = nv40->screen->base.channel;
unsigned restart;
nv40_vbo_set_idxbuf(nv40, NULL, 0);
@@ -227,7 +228,7 @@ static INLINE void
nv40_draw_elements_u08(struct nv40_context *nv40, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv40->nvws->channel;
+ struct nouveau_channel *chan = nv40->screen->base.channel;
while (count) {
uint8_t *elts = (uint8_t *)ib + start;
@@ -276,7 +277,7 @@ static INLINE void
nv40_draw_elements_u16(struct nv40_context *nv40, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv40->nvws->channel;
+ struct nouveau_channel *chan = nv40->screen->base.channel;
while (count) {
uint16_t *elts = (uint16_t *)ib + start;
@@ -325,7 +326,7 @@ static INLINE void
nv40_draw_elements_u32(struct nv40_context *nv40, void *ib,
unsigned mode, unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv40->nvws->channel;
+ struct nouveau_channel *chan = nv40->screen->base.channel;
while (count) {
uint32_t *elts = (uint32_t *)ib + start;
@@ -367,10 +368,10 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *pscreen = pipe->screen;
void *map;
- map = ws->buffer_map(ws, ib, PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, ib, PIPE_BUFFER_USAGE_CPU_READ);
if (!ib) {
NOUVEAU_ERR("failed mapping ib\n");
return FALSE;
@@ -391,7 +392,7 @@ nv40_draw_elements_inline(struct pipe_context *pipe,
break;
}
- ws->buffer_unmap(ws, ib);
+ pipe_buffer_unmap(pscreen, ib);
return TRUE;
}
@@ -400,7 +401,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv40_context *nv40 = nv40_context(pipe);
- struct nouveau_channel *chan = nv40->nvws->channel;
+ struct nouveau_channel *chan = nv40->screen->base.channel;
unsigned restart;
while (count) {
@@ -519,17 +520,20 @@ nv40_vbo_validate(struct nv40_context *nv40)
return FALSE;
}
- so_reloc(vtxbuf, vb->buffer, vb->buffer_offset + ve->src_offset,
- vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
- 0, NV40TCL_VTXBUF_ADDRESS_DMA1);
+ so_reloc(vtxbuf, nouveau_bo(vb->buffer),
+ vb->buffer_offset + ve->src_offset,
+ vb_flags | NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
+ 0, NV40TCL_VTXBUF_ADDRESS_DMA1);
so_data (vtxfmt, ((vb->stride << NV40TCL_VTXFMT_STRIDE_SHIFT) |
(ncomp << NV40TCL_VTXFMT_SIZE_SHIFT) | type));
}
if (ib) {
+ struct nouveau_bo *bo = nouveau_bo(ib);
+
so_method(vtxbuf, curie, NV40TCL_IDXBUF_ADDRESS, 2);
- so_reloc (vtxbuf, ib, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
- so_reloc (vtxbuf, ib, ib_format, vb_flags | NOUVEAU_BO_OR,
+ so_reloc (vtxbuf, bo, 0, vb_flags | NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (vtxbuf, bo, ib_format, vb_flags | NOUVEAU_BO_OR,
0, NV40TCL_IDXBUF_FORMAT_DMA1);
}
diff --git a/src/gallium/drivers/nv40/nv40_vertprog.c b/src/gallium/drivers/nv40/nv40_vertprog.c
index 7df9a4d326..e75e8d3f42 100644
--- a/src/gallium/drivers/nv40/nv40_vertprog.c
+++ b/src/gallium/drivers/nv40/nv40_vertprog.c
@@ -1,6 +1,7 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/tgsi_parse.h"
@@ -855,8 +856,7 @@ out_err:
static boolean
nv40_vertprog_validate(struct nv40_context *nv40)
{
- struct nouveau_winsys *nvws = nv40->nvws;
- struct pipe_winsys *ws = nv40->pipe.winsys;
+ struct pipe_screen *pscreen = nv40->pipe.screen;
struct nouveau_grobj *curie = nv40->screen->curie;
struct nv40_vertex_program *vp;
struct pipe_buffer *constbuf;
@@ -895,15 +895,15 @@ check_gpu_resources:
struct nouveau_stateobj *so;
uint vplen = vp->nr_insns;
- if (nvws->res_alloc(heap, vplen, vp, &vp->exec)) {
+ if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec)) {
while (heap->next && heap->size < vplen) {
struct nv40_vertex_program *evict;
evict = heap->next->priv;
- nvws->res_free(&evict->exec);
+ nouveau_resource_free(&evict->exec);
}
- if (nvws->res_alloc(heap, vplen, vp, &vp->exec))
+ if (nouveau_resource_alloc(heap, vplen, vp, &vp->exec))
assert(0);
}
@@ -925,15 +925,15 @@ check_gpu_resources:
if (vp->nr_consts && !vp->data) {
struct nouveau_resource *heap = nv40->screen->vp_data_heap;
- if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data)) {
+ if (nouveau_resource_alloc(heap, vp->nr_consts, vp, &vp->data)) {
while (heap->next && heap->size < vp->nr_consts) {
struct nv40_vertex_program *evict;
evict = heap->next->priv;
- nvws->res_free(&evict->data);
+ nouveau_resource_free(&evict->data);
}
- if (nvws->res_alloc(heap, vp->nr_consts, vp, &vp->data))
+ if (nouveau_resource_alloc(heap, vp->nr_consts, vp, &vp->data))
assert(0);
}
@@ -981,8 +981,8 @@ check_gpu_resources:
float *map = NULL;
if (constbuf) {
- map = ws->buffer_map(ws, constbuf,
- PIPE_BUFFER_USAGE_CPU_READ);
+ map = pipe_buffer_map(pscreen, constbuf,
+ PIPE_BUFFER_USAGE_CPU_READ);
}
for (i = 0; i < vp->nr_consts; i++) {
@@ -1003,7 +1003,7 @@ check_gpu_resources:
}
if (constbuf)
- ws->buffer_unmap(ws, constbuf);
+ pscreen->buffer_unmap(pscreen, constbuf);
}
/* Upload vtxprog */
@@ -1035,8 +1035,6 @@ check_gpu_resources:
void
nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp)
{
- struct nouveau_winsys *nvws = nv40->screen->nvws;
-
vp->translated = FALSE;
if (vp->nr_insns) {
@@ -1051,9 +1049,9 @@ nv40_vertprog_destroy(struct nv40_context *nv40, struct nv40_vertex_program *vp)
vp->nr_consts = 0;
}
- nvws->res_free(&vp->exec);
+ nouveau_resource_free(&vp->exec);
vp->exec_start = 0;
- nvws->res_free(&vp->data);
+ nouveau_resource_free(&vp->data);
vp->data_start = 0;
vp->data_start_min = 0;
diff --git a/src/gallium/drivers/nv50/nv50_clear.c b/src/gallium/drivers/nv50/nv50_clear.c
index db44a9da0e..e0b2d2880b 100644
--- a/src/gallium/drivers/nv50/nv50_clear.c
+++ b/src/gallium/drivers/nv50/nv50_clear.c
@@ -27,64 +27,42 @@
#include "nv50_context.h"
void
-nv50_clear(struct pipe_context *pipe, struct pipe_surface *ps,
- unsigned clearValue)
+nv50_clear(struct pipe_context *pipe, unsigned buffers,
+ const float *rgba, double depth, unsigned stencil)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->base.channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_framebuffer_state fb, s_fb = nv50->framebuffer;
- struct pipe_scissor_state sc, s_sc = nv50->scissor;
- unsigned dirty = nv50->dirty;
+ struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+ unsigned mode = 0, i;
- nv50->dirty = 0;
+ if (!nv50_state_validate(nv50))
+ return;
- if (ps->format == PIPE_FORMAT_Z24S8_UNORM ||
- ps->format == PIPE_FORMAT_Z16_UNORM) {
- fb.nr_cbufs = 0;
- fb.zsbuf = ps;
- } else {
- fb.nr_cbufs = 1;
- fb.cbufs[0] = ps;
- fb.zsbuf = NULL;
+ if (buffers & PIPE_CLEAR_COLOR && fb->nr_cbufs) {
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_COLOR(0), 4);
+ OUT_RING (chan, fui(rgba[0]));
+ OUT_RING (chan, fui(rgba[1]));
+ OUT_RING (chan, fui(rgba[2]));
+ OUT_RING (chan, fui(rgba[3]));
+ mode |= 0x3c;
}
- fb.width = ps->width;
- fb.height = ps->height;
- pipe->set_framebuffer_state(pipe, &fb);
- sc.minx = sc.miny = 0;
- sc.maxx = fb.width;
- sc.maxy = fb.height;
- pipe->set_scissor_state(pipe, &sc);
+ if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_DEPTH, 1);
+ OUT_RING (chan, fui(depth));
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_STENCIL, 1);
+ OUT_RING (chan, stencil & 0xff);
- nv50_state_validate(nv50);
-
- switch (ps->format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- BEGIN_RING(chan, tesla, 0x0d80, 4);
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 16) & 0xff));
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 8) & 0xff));
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 0) & 0xff));
- OUT_RINGf (chan, ubyte_to_float((clearValue >> 24) & 0xff));
- BEGIN_RING(chan, tesla, 0x19d0, 1);
- OUT_RING (chan, 0x3c);
- break;
- case PIPE_FORMAT_Z24S8_UNORM:
- BEGIN_RING(chan, tesla, 0x0d90, 1);
- OUT_RINGf (chan, (float)(clearValue >> 8) * (1.0 / 16777215.0));
- BEGIN_RING(chan, tesla, 0x0da0, 1);
- OUT_RING (chan, clearValue & 0xff);
- BEGIN_RING(chan, tesla, 0x19d0, 1);
- OUT_RING (chan, 0x03);
- break;
- default:
- pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height,
- clearValue);
- break;
+ mode |= 0x03;
}
- pipe->set_framebuffer_state(pipe, &s_fb);
- pipe->set_scissor_state(pipe, &s_sc);
- nv50->dirty |= dirty;
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
+ OUT_RING (chan, mode);
+
+ for (i = 1; i < fb->nr_cbufs; i++) {
+ BEGIN_RING(chan, tesla, NV50TCL_CLEAR_BUFFERS, 1);
+ OUT_RING (chan, (i << 6) | 0x3c);
+ }
}
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 565a5da668..e02afc4be9 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -33,7 +33,7 @@ nv50_flush(struct pipe_context *pipe, unsigned flags,
{
struct nv50_context *nv50 = (struct nv50_context *)pipe;
- FIRE_RING(nv50->screen->nvws->channel);
+ FIRE_RING(nv50->screen->base.channel);
}
static void
@@ -51,6 +51,29 @@ nv50_set_edgeflags(struct pipe_context *pipe, const unsigned *bitfield)
{
}
+static unsigned int
+nv50_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+nv50_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context *
nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
{
@@ -76,6 +99,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv50->pipe.flush = nv50_flush;
+ nv50->pipe.is_texture_referenced = nv50_is_texture_referenced;
+ nv50->pipe.is_buffer_referenced = nv50_is_buffer_referenced;
+
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
nv50_init_query_functions(nv50);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 7b67a75439..9b8cc4d37d 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -63,6 +63,11 @@ struct nv50_rasterizer_stateobj {
struct nouveau_stateobj *so;
};
+struct nv50_sampler_stateobj {
+ bool normalized;
+ unsigned tsc[8];
+};
+
struct nv50_miptree_level {
int *image_offset;
unsigned pitch;
@@ -70,7 +75,8 @@ struct nv50_miptree_level {
struct nv50_miptree {
struct pipe_texture base;
- struct pipe_buffer *buffer;
+
+ struct nouveau_bo *bo;
struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
int image_nr;
@@ -93,13 +99,6 @@ nv50_surface(struct pipe_surface *pt)
return (struct nv50_surface *)pt;
}
-static INLINE struct pipe_buffer *
-nv50_surface_buffer(struct pipe_surface *surface)
-{
- struct nv50_miptree *mt = (struct nv50_miptree *)surface->texture;
- return mt->buffer;
-}
-
struct nv50_state {
unsigned dirty;
@@ -115,6 +114,7 @@ struct nv50_state {
unsigned viewport_bypass;
struct nouveau_stateobj *tsc_upload;
struct nouveau_stateobj *tic_upload;
+ unsigned miptree_nr;
struct nouveau_stateobj *vertprog;
struct nouveau_stateobj *fragprog;
struct nouveau_stateobj *vtxfmt;
@@ -147,7 +147,7 @@ struct nv50_context {
unsigned vtxbuf_nr;
struct pipe_vertex_element vtxelt[PIPE_MAX_ATTRIBS];
unsigned vtxelt_nr;
- unsigned *sampler[PIPE_MAX_SAMPLERS];
+ struct nv50_sampler_stateobj *sampler[PIPE_MAX_SAMPLERS];
unsigned sampler_nr;
struct nv50_miptree *miptree[PIPE_MAX_SAMPLERS];
unsigned miptree_nr;
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index f79a7ca86c..6b605ba416 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -29,26 +29,35 @@
static struct pipe_texture *
nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
struct pipe_texture *pt = &mt->base;
- unsigned usage, width = tmp->width[0], height = tmp->height[0];
+ unsigned width = tmp->width[0], height = tmp->height[0];
unsigned depth = tmp->depth[0];
- int i, l;
+ uint32_t tile_mode, tile_flags, tile_h;
+ int ret, i, l;
mt->base = *tmp;
pipe_reference_init(&mt->base.reference, 1);
mt->base.screen = pscreen;
- usage = PIPE_BUFFER_USAGE_PIXEL;
switch (pt->format) {
case PIPE_FORMAT_Z24S8_UNORM:
case PIPE_FORMAT_Z16_UNORM:
- usage |= NOUVEAU_BUFFER_USAGE_ZETA;
+ tile_flags = 0x2800;
break;
default:
+ tile_flags = 0x7000;
break;
}
+ if (pt->height[0] > 32) tile_mode = 4;
+ else if (pt->height[0] > 16) tile_mode = 3;
+ else if (pt->height[0] > 8) tile_mode = 2;
+ else if (pt->height[0] > 4) tile_mode = 1;
+ else tile_mode = 0;
+ tile_h = 1 << (tile_mode + 2);
+
switch (pt->target) {
case PIPE_TEXTURE_3D:
mt->image_nr = pt->depth[0];
@@ -85,7 +94,7 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
size = align(pt->width[l], 8) * pt->block.size;
size = align(size, 64);
- size *= align(pt->height[l], 8) * pt->block.size;
+ size *= align(pt->height[l], tile_h) * pt->block.size;
lvl->image_offset[i] = mt->total_size;
@@ -93,12 +102,13 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
}
}
- mt->buffer = pscreen->buffer_create(pscreen, 256, usage, mt->total_size);
- if (!mt->buffer) {
+ ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size,
+ tile_mode, tile_flags, &mt->bo);
+ if (ret) {
FREE(mt);
return NULL;
}
-
+
return &mt->base;
}
@@ -106,6 +116,7 @@ static struct pipe_texture *
nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
const unsigned *stride, struct pipe_buffer *pb)
{
+ struct nouveau_bo *bo = nouveau_bo(pb);
struct nv50_miptree *mt;
/* Only supports 2D, non-mipmapped textures for the moment */
@@ -124,7 +135,7 @@ nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
mt->level[0].pitch = *stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
- pipe_buffer_reference(&mt->buffer, pb);
+ nouveau_bo_ref(bo, &mt->bo);
return &mt->base;
}
@@ -133,7 +144,7 @@ nv50_miptree_destroy(struct pipe_texture *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
- pipe_buffer_reference(&mt->buffer, NULL);
+ nouveau_bo_ref(NULL, &mt->bo);
FREE(mt);
}
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 2d15868ae8..5f7d06dbec 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -85,6 +85,9 @@ struct nv50_reg {
int hw;
int neg;
+
+ int rhw; /* result hw for FP outputs, or interpolant index */
+ int acc; /* instruction where this reg is last read (first insn == 1) */
};
struct nv50_pc {
@@ -108,12 +111,23 @@ struct nv50_pc {
struct nv50_reg *temp_temp[16];
unsigned temp_temp_nr;
+
+ unsigned interp_mode[32];
+ /* perspective interpolation registers */
+ struct nv50_reg *iv_p;
+ struct nv50_reg *iv_c;
+
+ /* current instruction and total number of insns */
+ unsigned insn_cur;
+ unsigned insn_nr;
+
+ boolean allow32;
};
static void
alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg)
{
- int i;
+ int i = 0;
if (reg->type == P_RESULT) {
if (pc->p->cfg.high_result < (reg->hw + 1))
@@ -131,7 +145,22 @@ alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg)
return;
}
- for (i = 0; i < NV50_SU_MAX_TEMP; i++) {
+ if (reg->rhw != -1) {
+ /* try to allocate temporary with index rhw first */
+ if (!(pc->r_temp[reg->rhw])) {
+ pc->r_temp[reg->rhw] = reg;
+ reg->hw = reg->rhw;
+ if (pc->p->cfg.high_temp < (reg->rhw + 1))
+ pc->p->cfg.high_temp = reg->rhw + 1;
+ return;
+ }
+ /* make sure we don't get things like $r0 needs to go
+ * in $r1 and $r1 in $r0
+ */
+ i = pc->result_nr * 4;
+ }
+
+ for (; i < NV50_SU_MAX_TEMP; i++) {
if (!(pc->r_temp[i])) {
pc->r_temp[i] = reg;
reg->hw = i;
@@ -159,6 +188,7 @@ alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
r->type = P_TEMP;
r->index = -1;
r->hw = i;
+ r->rhw = -1;
pc->r_temp[i] = r;
return r;
}
@@ -168,6 +198,38 @@ alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
return NULL;
}
+/* Assign the hw of the discarded temporary register src
+ * to the tgsi register dst and free src.
+ */
+static void
+assimilate_temp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
+{
+ assert(src->index == -1 && src->hw != -1);
+
+ if (dst->hw != -1)
+ pc->r_temp[dst->hw] = NULL;
+ pc->r_temp[src->hw] = dst;
+ dst->hw = src->hw;
+
+ FREE(src);
+}
+
+/* release the hardware resource held by r */
+static void
+release_hw(struct nv50_pc *pc, struct nv50_reg *r)
+{
+ assert(r->type == P_TEMP);
+ if (r->hw == -1)
+ return;
+
+ assert(pc->r_temp[r->hw] == r);
+ pc->r_temp[r->hw] = NULL;
+
+ r->acc = 0;
+ if (r->index == -1)
+ FREE(r);
+}
+
static void
free_temp(struct nv50_pc *pc, struct nv50_reg *r)
{
@@ -250,7 +312,13 @@ alloc_immd(struct nv50_pc *pc, float f)
struct nv50_reg *r = CALLOC_STRUCT(nv50_reg);
unsigned hw;
- hw = ctor_immd(pc, f, 0, 0, 0) * 4;
+ for (hw = 0; hw < pc->immd_nr * 4; hw++)
+ if (pc->immd_buf[hw] == f)
+ break;
+
+ if (hw == pc->immd_nr * 4)
+ hw = ctor_immd(pc, f, -f, 0.5 * f, 0) * 4;
+
r->type = P_IMMD;
r->hw = hw;
r->index = -1;
@@ -341,7 +409,8 @@ set_dst(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_program_exec *e)
static INLINE void
set_immd(struct nv50_pc *pc, struct nv50_reg *imm, struct nv50_program_exec *e)
{
- unsigned val = fui(pc->immd_buf[imm->hw]); /* XXX */
+ float f = pc->immd_buf[imm->hw];
+ unsigned val = fui(imm->neg ? -f : f);
set_long(pc, e);
/*XXX: can't be predicated - bits overlap.. catch cases where both
@@ -354,20 +423,35 @@ set_immd(struct nv50_pc *pc, struct nv50_reg *imm, struct nv50_program_exec *e)
e->inst[1] |= (val >> 6) << 2;
}
+
+#define INTERP_LINEAR 0
+#define INTERP_FLAT 1
+#define INTERP_PERSPECTIVE 2
+#define INTERP_CENTROID 4
+
+/* interpolant index has been stored in dst->rhw */
static void
-emit_interp(struct nv50_pc *pc, struct nv50_reg *dst,
- struct nv50_reg *src, struct nv50_reg *iv)
+emit_interp(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *iv,
+ unsigned mode)
{
+ assert(dst->rhw != -1);
struct nv50_program_exec *e = exec(pc);
e->inst[0] |= 0x80000000;
set_dst(pc, dst, e);
- alloc_reg(pc, src);
- e->inst[0] |= (src->hw << 16);
- if (iv) {
- e->inst[0] |= (1 << 25);
- alloc_reg(pc, iv);
- e->inst[0] |= (iv->hw << 9);
+ e->inst[0] |= (dst->rhw << 16);
+
+ if (mode & INTERP_FLAT) {
+ e->inst[0] |= (1 << 8);
+ } else {
+ if (mode & INTERP_PERSPECTIVE) {
+ e->inst[0] |= (1 << 25);
+ alloc_reg(pc, iv);
+ e->inst[0] |= (iv->hw << 9);
+ }
+
+ if (mode & INTERP_CENTROID)
+ e->inst[0] |= (1 << 24);
}
emit(pc, e);
@@ -378,22 +462,12 @@ set_data(struct nv50_pc *pc, struct nv50_reg *src, unsigned m, unsigned s,
struct nv50_program_exec *e)
{
set_long(pc, e);
-#if 1
- e->inst[1] |= (1 << 22);
-#else
- if (src->type == P_IMMD) {
- e->inst[1] |= (NV50_CB_PMISC << 22);
- } else {
- if (pc->p->type == PIPE_SHADER_VERTEX)
- e->inst[1] |= (NV50_CB_PVP << 22);
- else
- e->inst[1] |= (NV50_CB_PFP << 22);
- }
-#endif
e->param.index = src->hw;
e->param.shift = s;
e->param.mask = m << (s % 32);
+
+ e->inst[1] |= (((src->type == P_IMMD) ? 0 : 1) << 22);
}
static void
@@ -405,12 +479,11 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
set_dst(pc, dst, e);
- if (0 && dst->type != P_RESULT && src->type == P_IMMD) {
+ if (pc->allow32 && dst->type != P_RESULT && src->type == P_IMMD) {
set_immd(pc, src, e);
/*XXX: 32-bit, but steals part of "half" reg space - need to
* catch and handle this case if/when we do half-regs
*/
- e->inst[0] |= 0x00008000;
} else
if (src->type == P_IMMD || src->type == P_CONST) {
set_long(pc, e);
@@ -426,18 +499,25 @@ emit_mov(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
e->inst[0] |= (src->hw << 9);
}
- /* We really should support "half" instructions here at some point,
- * but I don't feel confident enough about them yet.
- */
- set_long(pc, e);
if (is_long(e) && !is_immd(e)) {
e->inst[1] |= 0x04000000; /* 32-bit */
- e->inst[1] |= 0x0003c000; /* "subsubop" 0xf == mov */
- }
+ e->inst[1] |= 0x0000c000; /* "subsubop" 0x3 */
+ if (!(e->inst[1] & 0x20000000))
+ e->inst[1] |= 0x00030000; /* "subsubop" 0xf */
+ } else
+ e->inst[0] |= 0x00008000;
emit(pc, e);
}
+static INLINE void
+emit_mov_immdval(struct nv50_pc *pc, struct nv50_reg *dst, float f)
+{
+ struct nv50_reg *imm = alloc_immd(pc, f);
+ emit_mov(pc, dst, imm);
+ FREE(imm);
+}
+
static boolean
check_swap_src_0_1(struct nv50_pc *pc,
struct nv50_reg **s0, struct nv50_reg **s1)
@@ -541,12 +621,26 @@ emit_mul(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
struct nv50_program_exec *e = exec(pc);
e->inst[0] |= 0xc0000000;
- set_long(pc, e);
+
+ if (!pc->allow32)
+ set_long(pc, e);
check_swap_src_0_1(pc, &src0, &src1);
set_dst(pc, dst, e);
set_src_0(pc, src0, e);
- set_src_1(pc, src1, e);
+ if (src1->type == P_IMMD && !is_long(e)) {
+ if (src0->neg)
+ e->inst[0] |= 0x00008000;
+ set_immd(pc, src1, e);
+ } else {
+ set_src_1(pc, src1, e);
+ if (src0->neg ^ src1->neg) {
+ if (is_long(e))
+ e->inst[1] |= 0x08000000;
+ else
+ e->inst[0] |= 0x00008000;
+ }
+ }
emit(pc, e);
}
@@ -560,11 +654,20 @@ emit_add(struct nv50_pc *pc, struct nv50_reg *dst,
e->inst[0] |= 0xb0000000;
check_swap_src_0_1(pc, &src0, &src1);
+
+ if (!pc->allow32 || src0->neg || src1->neg) {
+ set_long(pc, e);
+ e->inst[1] |= (src0->neg << 26) | (src1->neg << 27);
+ }
+
set_dst(pc, dst, e);
set_src_0(pc, src0, e);
- if (is_long(e))
+ if (src1->type == P_CONST || src1->type == P_ATTR || is_long(e))
set_src_2(pc, src1, e);
else
+ if (src1->type == P_IMMD)
+ set_immd(pc, src1, e);
+ else
set_src_1(pc, src1, e);
emit(pc, e);
@@ -588,25 +691,13 @@ emit_minmax(struct nv50_pc *pc, unsigned sub, struct nv50_reg *dst,
emit(pc, e);
}
-static void
+static INLINE void
emit_sub(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
struct nv50_reg *src1)
{
- struct nv50_program_exec *e = exec(pc);
-
- e->inst[0] |= 0xb0000000;
-
- set_long(pc, e);
- if (check_swap_src_0_1(pc, &src0, &src1))
- e->inst[1] |= 0x04000000;
- else
- e->inst[1] |= 0x08000000;
-
- set_dst(pc, dst, e);
- set_src_0(pc, src0, e);
- set_src_2(pc, src1, e);
-
- emit(pc, e);
+ src1->neg ^= 1;
+ emit_add(pc, dst, src0, src1);
+ src1->neg ^= 1;
}
static void
@@ -623,26 +714,21 @@ emit_mad(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
set_src_1(pc, src1, e);
set_src_2(pc, src2, e);
+ if (src0->neg ^ src1->neg)
+ e->inst[1] |= 0x04000000;
+ if (src2->neg)
+ e->inst[1] |= 0x08000000;
+
emit(pc, e);
}
-static void
+static INLINE void
emit_msb(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src0,
struct nv50_reg *src1, struct nv50_reg *src2)
{
- struct nv50_program_exec *e = exec(pc);
-
- e->inst[0] |= 0xe0000000;
- set_long(pc, e);
- e->inst[1] |= 0x08000000; /* src0 * src1 - src2 */
-
- check_swap_src_0_1(pc, &src0, &src1);
- set_dst(pc, dst, e);
- set_src_0(pc, src0, e);
- set_src_1(pc, src1, e);
- set_src_2(pc, src2, e);
-
- emit(pc, e);
+ src2->neg ^= 1;
+ emit_mad(pc, dst, src0, src1, src2);
+ src2->neg ^= 1;
}
static void
@@ -693,6 +779,48 @@ emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
emit(pc, e);
}
+#define CVTOP_RN 0x01
+#define CVTOP_FLOOR 0x03
+#define CVTOP_CEIL 0x05
+#define CVTOP_TRUNC 0x07
+#define CVTOP_SAT 0x08
+#define CVTOP_ABS 0x10
+
+#define CVT_F32_F32 0xc4
+#define CVT_F32_S32 0x44
+#define CVT_F32_U32 0x64
+#define CVT_S32_F32 0x8c
+#define CVT_S32_S32 0x0c
+#define CVT_F32_F32_ROP 0xcc
+
+static void
+emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src,
+ int wp, unsigned cop, unsigned fmt)
+{
+ struct nv50_program_exec *e;
+
+ e = exec(pc);
+ set_long(pc, e);
+
+ e->inst[0] |= 0xa0000000;
+ e->inst[1] |= 0x00004000;
+ e->inst[1] |= (cop << 16);
+ e->inst[1] |= (fmt << 24);
+ set_src_0(pc, src, e);
+
+ if (wp >= 0)
+ set_pred_wr(pc, 1, wp, e);
+
+ if (dst)
+ set_dst(pc, dst, e);
+ else {
+ e->inst[0] |= 0x000001fc;
+ e->inst[1] |= 0x00000008;
+ }
+
+ emit(pc, e);
+}
+
static void
emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst,
struct nv50_reg *src0, struct nv50_reg *src1)
@@ -736,22 +864,10 @@ emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst,
free_temp(pc, dst);
}
-static void
+static INLINE void
emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
{
- struct nv50_program_exec *e = exec(pc);
-
- e->inst[0] = 0xa0000000; /* cvt */
- set_long(pc, e);
- e->inst[1] |= (6 << 29); /* cvt */
- e->inst[1] |= 0x08000000; /* integer mode */
- e->inst[1] |= 0x04000000; /* 32 bit */
- e->inst[1] |= ((0x1 << 3)) << 14; /* .rn */
- e->inst[1] |= (1 << 14); /* src .f32 */
- set_dst(pc, dst, e);
- set_src_0(pc, src, e);
-
- emit(pc, e);
+ emit_cvt(pc, dst, src, -1, CVTOP_FLOOR, CVT_F32_F32_ROP);
}
static void
@@ -768,21 +884,10 @@ emit_pow(struct nv50_pc *pc, struct nv50_reg *dst,
free_temp(pc, temp);
}
-static void
+static INLINE void
emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
{
- struct nv50_program_exec *e = exec(pc);
-
- e->inst[0] = 0xa0000000; /* cvt */
- set_long(pc, e);
- e->inst[1] |= (6 << 29); /* cvt */
- e->inst[1] |= 0x04000000; /* 32 bit */
- e->inst[1] |= (1 << 14); /* src .f32 */
- e->inst[1] |= ((1 << 6) << 14); /* .abs */
- set_dst(pc, dst, e);
- set_src_0(pc, src, e);
-
- emit(pc, e);
+ emit_cvt(pc, dst, src, -1, CVTOP_ABS, CVT_F32_F32);
}
static void
@@ -794,18 +899,12 @@ emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
struct nv50_reg *neg128 = alloc_immd(pc, -127.999999);
struct nv50_reg *pos128 = alloc_immd(pc, 127.999999);
struct nv50_reg *tmp[4];
+ boolean allow32 = pc->allow32;
- if (mask & (1 << 0))
- emit_mov(pc, dst[0], one);
-
- if (mask & (1 << 3))
- emit_mov(pc, dst[3], one);
+ pc->allow32 = FALSE;
if (mask & (3 << 1)) {
- if (mask & (1 << 1))
- tmp[0] = dst[1];
- else
- tmp[0] = temp_temp(pc);
+ tmp[0] = alloc_temp(pc, NULL);
emit_minmax(pc, 4, tmp[0], src[0], zero);
}
@@ -823,6 +922,26 @@ emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
emit_mov(pc, dst[2], zero);
set_pred(pc, 3, 0, pc->p->exec_tail);
}
+
+ if (mask & (1 << 1))
+ assimilate_temp(pc, dst[1], tmp[0]);
+ else
+ if (mask & (1 << 2))
+ free_temp(pc, tmp[0]);
+
+ pc->allow32 = allow32;
+
+ /* do this last, in case src[i,j] == dst[0,3] */
+ if (mask & (1 << 0))
+ emit_mov(pc, dst[0], one);
+
+ if (mask & (1 << 3))
+ emit_mov(pc, dst[3], one);
+
+ FREE(pos128);
+ FREE(neg128);
+ FREE(zero);
+ FREE(one);
}
static void
@@ -853,6 +972,8 @@ emit_kil(struct nv50_pc *pc, struct nv50_reg *src)
e->inst[1] = 0xc4014788;
set_src_0(pc, src, e);
set_pred_wr(pc, 1, r_pred, e);
+ if (src->neg)
+ e->inst[1] |= 0x20000000;
emit(pc, e);
/* This is probably KILP */
@@ -863,6 +984,180 @@ emit_kil(struct nv50_pc *pc, struct nv50_reg *src)
emit(pc, e);
}
+static void
+emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
+ struct nv50_reg **src, unsigned unit, unsigned type, boolean proj)
+{
+ struct nv50_reg *temp, *t[4];
+ struct nv50_program_exec *e;
+
+ unsigned c, mode, dim;
+
+ switch (type) {
+ case TGSI_TEXTURE_1D:
+ dim = 1;
+ break;
+ case TGSI_TEXTURE_UNKNOWN:
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_SHADOW1D: /* XXX: x, z */
+ case TGSI_TEXTURE_RECT:
+ dim = 2;
+ break;
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT: /* XXX */
+ dim = 3;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ alloc_temp4(pc, t, 0);
+
+ if (proj) {
+ if (src[0]->type == P_TEMP && src[0]->rhw != -1) {
+ mode = pc->interp_mode[src[0]->index];
+
+ t[3]->rhw = src[3]->rhw;
+ emit_interp(pc, t[3], NULL, (mode & INTERP_CENTROID));
+ emit_flop(pc, 0, t[3], t[3]);
+
+ for (c = 0; c < dim; c++) {
+ t[c]->rhw = src[c]->rhw;
+ emit_interp(pc, t[c], t[3],
+ (mode | INTERP_PERSPECTIVE));
+ }
+ } else {
+ emit_flop(pc, 0, t[3], src[3]);
+ for (c = 0; c < dim; c++)
+ emit_mul(pc, t[c], src[c], t[3]);
+
+ /* XXX: for some reason the blob sometimes uses MAD:
+ * emit_mad(pc, t[c], src[0][c], t[3], t[3])
+ * pc->p->exec_tail->inst[1] |= 0x080fc000;
+ */
+ }
+ } else {
+ if (type == TGSI_TEXTURE_CUBE) {
+ temp = temp_temp(pc);
+ emit_minmax(pc, 4, temp, src[0], src[1]);
+ emit_minmax(pc, 4, temp, temp, src[2]);
+ emit_flop(pc, 0, temp, temp);
+ for (c = 0; c < 3; c++)
+ emit_mul(pc, t[c], src[c], temp);
+ } else {
+ for (c = 0; c < dim; c++)
+ emit_mov(pc, t[c], src[c]);
+ }
+ }
+
+ e = exec(pc);
+ set_long(pc, e);
+ e->inst[0] |= 0xf0000000;
+ e->inst[1] |= 0x00000004;
+ set_dst(pc, t[0], e);
+ e->inst[0] |= (unit << 9);
+
+ if (dim == 2)
+ e->inst[0] |= 0x00400000;
+ else
+ if (dim == 3)
+ e->inst[0] |= 0x00800000;
+
+ e->inst[0] |= (mask & 0x3) << 25;
+ e->inst[1] |= (mask & 0xc) << 12;
+
+ emit(pc, e);
+
+#if 1
+ if (mask & 1) emit_mov(pc, dst[0], t[0]);
+ if (mask & 2) emit_mov(pc, dst[1], t[1]);
+ if (mask & 4) emit_mov(pc, dst[2], t[2]);
+ if (mask & 8) emit_mov(pc, dst[3], t[3]);
+
+ free_temp4(pc, t);
+#else
+ /* XXX: if p.e. MUL is used directly after TEX, it would still use
+ * the texture coordinates, not the fetched values: latency ? */
+
+ for (c = 0; c < 4; c++) {
+ if (mask & (1 << c))
+ assimilate_temp(pc, dst[c], t[c]);
+ else
+ free_temp(pc, t[c]);
+ }
+#endif
+}
+
+static void
+convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e)
+{
+ unsigned q = 0, m = ~0;
+
+ assert(!is_long(e));
+
+ switch (e->inst[0] >> 28) {
+ case 0x1:
+ /* MOV */
+ q = 0x0403c000;
+ m = 0xffff7fff;
+ break;
+ case 0x8:
+ /* INTERP */
+ m = ~0x02000000;
+ if (e->inst[0] & 0x02000000)
+ q = 0x00020000;
+ break;
+ case 0x9:
+ /* RCP */
+ break;
+ case 0xB:
+ /* ADD */
+ m = ~(127 << 16);
+ q = ((e->inst[0] & (~m)) >> 2);
+ break;
+ case 0xC:
+ /* MUL */
+ m = ~0x00008000;
+ q = ((e->inst[0] & (~m)) << 12);
+ break;
+ case 0xE:
+ /* MAD (if src2 == dst) */
+ q = ((e->inst[0] & 0x1fc) << 12);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ set_long(pc, e);
+ pc->p->exec_size++;
+
+ e->inst[0] &= m;
+ e->inst[1] |= q;
+}
+
+static boolean
+negate_supported(const struct tgsi_full_instruction *insn, int i)
+{
+ switch (insn->Instruction.Opcode) {
+ case TGSI_OPCODE_DP3:
+ case TGSI_OPCODE_DP4:
+ case TGSI_OPCODE_MUL:
+ case TGSI_OPCODE_KIL:
+ case TGSI_OPCODE_ADD:
+ case TGSI_OPCODE_SUB:
+ case TGSI_OPCODE_MAD:
+ return TRUE;
+ case TGSI_OPCODE_POW:
+ return (i == 1) ? TRUE : FALSE;
+ default:
+ return FALSE;
+ }
+}
+
static struct nv50_reg *
tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
{
@@ -881,11 +1176,14 @@ tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
}
static struct nv50_reg *
-tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src)
+tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
+ boolean neg)
{
struct nv50_reg *r = NULL;
struct nv50_reg *temp;
- unsigned c;
+ unsigned sgn, c;
+
+ sgn = tgsi_util_get_full_src_register_sign_mode(src, chan);
c = tgsi_util_get_full_src_register_extswizzle(src, chan);
switch (c) {
@@ -915,16 +1213,17 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src)
break;
case TGSI_EXTSWIZZLE_ZERO:
r = alloc_immd(pc, 0.0);
- break;
+ return r;
case TGSI_EXTSWIZZLE_ONE:
- r = alloc_immd(pc, 1.0);
- break;
+ if (sgn == TGSI_UTIL_SIGN_TOGGLE || sgn == TGSI_UTIL_SIGN_SET)
+ return alloc_immd(pc, -1.0);
+ return alloc_immd(pc, 1.0);
default:
assert(0);
break;
}
- switch (tgsi_util_get_full_src_register_sign_mode(src, chan)) {
+ switch (sgn) {
case TGSI_UTIL_SIGN_KEEP:
break;
case TGSI_UTIL_SIGN_CLEAR:
@@ -933,14 +1232,21 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src)
r = temp;
break;
case TGSI_UTIL_SIGN_TOGGLE:
- temp = temp_temp(pc);
- emit_neg(pc, temp, r);
- r = temp;
+ if (neg)
+ r->neg = 1;
+ else {
+ temp = temp_temp(pc);
+ emit_neg(pc, temp, r);
+ r = temp;
+ }
break;
case TGSI_UTIL_SIGN_SET:
temp = temp_temp(pc);
emit_abs(pc, temp, r);
- emit_neg(pc, temp, r);
+ if (neg)
+ temp->neg = 1;
+ else
+ emit_neg(pc, temp, temp);
r = temp;
break;
default:
@@ -951,12 +1257,40 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src)
return r;
}
+/* returns TRUE if instruction can overwrite sources before they're read */
+static boolean
+direct2dest_op(const struct tgsi_full_instruction *insn)
+{
+ if (insn->Instruction.Saturate)
+ return FALSE;
+
+ switch (insn->Instruction.Opcode) {
+ case TGSI_OPCODE_COS:
+ case TGSI_OPCODE_DP3:
+ case TGSI_OPCODE_DP4:
+ case TGSI_OPCODE_DPH:
+ case TGSI_OPCODE_KIL:
+ case TGSI_OPCODE_LIT:
+ case TGSI_OPCODE_POW:
+ case TGSI_OPCODE_RCP:
+ case TGSI_OPCODE_RSQ:
+ case TGSI_OPCODE_SCS:
+ case TGSI_OPCODE_SIN:
+ case TGSI_OPCODE_TEX:
+ case TGSI_OPCODE_TXP:
+ return FALSE;
+ default:
+ return TRUE;
+ }
+}
+
static boolean
nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
{
const struct tgsi_full_instruction *inst = &tok->FullInstruction;
struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp;
unsigned mask, sat, unit;
+ boolean assimilate = FALSE;
int i, c;
mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
@@ -967,6 +1301,10 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]);
else
dst[c] = NULL;
+ rdst[c] = NULL;
+ src[0][c] = NULL;
+ src[1][c] = NULL;
+ src[2][c] = NULL;
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
@@ -976,7 +1314,8 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
unit = fs->SrcRegister.Index;
for (c = 0; c < 4; c++)
- src[i][c] = tgsi_src(pc, c, fs);
+ src[i][c] = tgsi_src(pc, c, fs,
+ negate_supported(inst, i));
}
if (sat) {
@@ -984,6 +1323,25 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
rdst[c] = dst[c];
dst[c] = temp_temp(pc);
}
+ } else
+ if (direct2dest_op(inst)) {
+ for (c = 0; c < 4; c++) {
+ if (!dst[c] || dst[c]->type != P_TEMP)
+ continue;
+
+ for (i = c + 1; i < 4; i++) {
+ if (dst[c] == src[0][i] ||
+ dst[c] == src[1][i] ||
+ dst[c] == src[2][i])
+ break;
+ }
+ if (i == 4)
+ continue;
+
+ assimilate = TRUE;
+ rdst[c] = dst[c];
+ dst[c] = alloc_temp(pc, NULL);
+ }
}
switch (inst->Instruction.Opcode) {
@@ -1002,7 +1360,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_COS:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_precossin(pc, temp, src[0][0]);
emit_flop(pc, 5, temp, temp);
for (c = 0; c < 4; c++) {
@@ -1012,7 +1370,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_DP3:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_mul(pc, temp, src[0][0], src[1][0]);
emit_mad(pc, temp, src[0][1], src[1][1], temp);
emit_mad(pc, temp, src[0][2], src[1][2], temp);
@@ -1021,10 +1379,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
continue;
emit_mov(pc, dst[c], temp);
}
- free_temp(pc, temp);
break;
case TGSI_OPCODE_DP4:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_mul(pc, temp, src[0][0], src[1][0]);
emit_mad(pc, temp, src[0][1], src[1][1], temp);
emit_mad(pc, temp, src[0][2], src[1][2], temp);
@@ -1034,10 +1391,9 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
continue;
emit_mov(pc, dst[c], temp);
}
- free_temp(pc, temp);
break;
case TGSI_OPCODE_DPH:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_mul(pc, temp, src[0][0], src[1][0]);
emit_mad(pc, temp, src[0][1], src[1][1], temp);
emit_mad(pc, temp, src[0][2], src[1][2], temp);
@@ -1047,7 +1403,6 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
continue;
emit_mov(pc, dst[c], temp);
}
- free_temp(pc, temp);
break;
case TGSI_OPCODE_DST:
{
@@ -1064,7 +1419,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_EX2:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_preex2(pc, temp, src[0][0]);
emit_flop(pc, 6, temp, temp);
for (c = 0; c < 4; c++) {
@@ -1072,7 +1427,6 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
continue;
emit_mov(pc, dst[c], temp);
}
- free_temp(pc, temp);
break;
case TGSI_OPCODE_FLR:
for (c = 0; c < 4; c++) {
@@ -1082,26 +1436,26 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_FRC:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
emit_flr(pc, temp, src[0][c]);
emit_sub(pc, dst[c], src[0][c], temp);
}
- free_temp(pc, temp);
break;
case TGSI_OPCODE_KIL:
emit_kil(pc, src[0][0]);
emit_kil(pc, src[0][1]);
emit_kil(pc, src[0][2]);
emit_kil(pc, src[0][3]);
+ pc->p->cfg.fp.regs[2] |= 0x00100000;
break;
case TGSI_OPCODE_LIT:
emit_lit(pc, &dst[0], mask, &src[0][0]);
break;
case TGSI_OPCODE_LG2:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_flop(pc, 3, temp, src[0][0]);
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
@@ -1110,15 +1464,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_LRP:
+ temp = temp_temp(pc);
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
- /*XXX: we can do better than this */
- temp = alloc_temp(pc, NULL);
- emit_neg(pc, temp, src[0][c]);
- emit_mad(pc, temp, temp, src[2][c], src[2][c]);
- emit_mad(pc, dst[c], src[0][c], src[1][c], temp);
- free_temp(pc, temp);
+ emit_sub(pc, temp, src[1][c], src[2][c]);
+ emit_mad(pc, dst[c], temp, src[0][c], src[2][c]);
}
break;
case TGSI_OPCODE_MAD:
@@ -1157,36 +1508,39 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_POW:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_pow(pc, temp, src[0][0], src[1][0]);
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
emit_mov(pc, dst[c], temp);
}
- free_temp(pc, temp);
break;
case TGSI_OPCODE_RCP:
- for (c = 0; c < 4; c++) {
+ for (c = 3; c >= 0; c--) {
if (!(mask & (1 << c)))
continue;
emit_flop(pc, 0, dst[c], src[0][0]);
}
break;
case TGSI_OPCODE_RSQ:
- for (c = 0; c < 4; c++) {
+ for (c = 3; c >= 0; c--) {
if (!(mask & (1 << c)))
continue;
emit_flop(pc, 2, dst[c], src[0][0]);
}
break;
case TGSI_OPCODE_SCS:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_precossin(pc, temp, src[0][0]);
if (mask & (1 << 0))
emit_flop(pc, 5, dst[0], temp);
if (mask & (1 << 1))
emit_flop(pc, 4, dst[1], temp);
+ if (mask & (1 << 2))
+ emit_mov_immdval(pc, dst[2], 0.0);
+ if (mask & (1 << 3))
+ emit_mov_immdval(pc, dst[3], 1.0);
break;
case TGSI_OPCODE_SGE:
for (c = 0; c < 4; c++) {
@@ -1196,7 +1550,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_SIN:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
emit_precossin(pc, temp, src[0][0]);
emit_flop(pc, 4, temp, temp);
for (c = 0; c < 4; c++) {
@@ -1220,33 +1574,15 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_TEX:
+ emit_tex(pc, dst, mask, src[0], unit,
+ inst->InstructionExtTexture.Texture, FALSE);
+ break;
case TGSI_OPCODE_TXP:
- {
- struct nv50_reg *t[4];
- struct nv50_program_exec *e;
-
- alloc_temp4(pc, t, 0);
- emit_mov(pc, t[0], src[0][0]);
- emit_mov(pc, t[1], src[0][1]);
-
- e = exec(pc);
- e->inst[0] = 0xf6400000;
- e->inst[0] |= (unit << 9);
- set_long(pc, e);
- e->inst[1] |= 0x0000c004;
- set_dst(pc, t[0], e);
- emit(pc, e);
-
- if (mask & (1 << 0)) emit_mov(pc, dst[0], t[0]);
- if (mask & (1 << 1)) emit_mov(pc, dst[1], t[1]);
- if (mask & (1 << 2)) emit_mov(pc, dst[2], t[2]);
- if (mask & (1 << 3)) emit_mov(pc, dst[3], t[3]);
-
- free_temp4(pc, t);
- }
+ emit_tex(pc, dst, mask, src[0], unit,
+ inst->InstructionExtTexture.Texture, TRUE);
break;
case TGSI_OPCODE_XPD:
- temp = alloc_temp(pc, NULL);
+ temp = temp_temp(pc);
if (mask & (1 << 0)) {
emit_mul(pc, temp, src[0][2], src[1][1]);
emit_msb(pc, dst[0], src[0][1], src[1][2], temp);
@@ -1259,7 +1595,8 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
emit_mul(pc, temp, src[0][1], src[1][0]);
emit_msb(pc, dst[2], src[0][0], src[1][1], temp);
}
- free_temp(pc, temp);
+ if (mask & (1 << 3))
+ emit_mov_immdval(pc, dst[3], 1.0);
break;
case TGSI_OPCODE_END:
break;
@@ -1270,21 +1607,26 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
if (sat) {
for (c = 0; c < 4; c++) {
- struct nv50_program_exec *e;
-
if (!(mask & (1 << c)))
continue;
- e = exec(pc);
+ emit_cvt(pc, rdst[c], dst[c], -1, CVTOP_SAT,
+ CVT_F32_F32);
+ }
+ } else if (assimilate) {
+ for (c = 0; c < 4; c++)
+ if (rdst[c])
+ assimilate_temp(pc, rdst[c], dst[c]);
+ }
- e->inst[0] = 0xa0000000; /* cvt */
- set_long(pc, e);
- e->inst[1] |= (6 << 29); /* cvt */
- e->inst[1] |= 0x04000000; /* 32 bit */
- e->inst[1] |= (1 << 14); /* src .f32 */
- e->inst[1] |= ((1 << 5) << 14); /* .sat */
- set_dst(pc, rdst[c], e);
- set_src_0(pc, dst[c], e);
- emit(pc, e);
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ for (c = 0; c < 4; c++) {
+ if (!src[i][c])
+ continue;
+ if (src[i][c]->index == -1 && src[i][c]->type == P_IMMD)
+ FREE(src[i][c]);
+ else
+ if (src[i][c]->acc == pc->insn_cur)
+ release_hw(pc, src[i][c]);
}
}
@@ -1292,12 +1634,169 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
return TRUE;
}
+/* Adjust a bitmask that indicates what components of a source are used,
+ * we use this in tx_prep so we only load interpolants that are needed.
+ */
+static void
+insn_adjust_mask(const struct tgsi_full_instruction *insn, unsigned *mask)
+{
+ const struct tgsi_instruction_ext_texture *tex;
+
+ switch (insn->Instruction.Opcode) {
+ case TGSI_OPCODE_DP3:
+ *mask = 0x7;
+ break;
+ case TGSI_OPCODE_DP4:
+ case TGSI_OPCODE_DPH:
+ *mask = 0xF;
+ break;
+ case TGSI_OPCODE_LIT:
+ *mask = 0xB;
+ break;
+ case TGSI_OPCODE_RCP:
+ case TGSI_OPCODE_RSQ:
+ *mask = 0x1;
+ break;
+ case TGSI_OPCODE_TEX:
+ case TGSI_OPCODE_TXP:
+ assert(insn->Instruction.Extended);
+ tex = &insn->InstructionExtTexture;
+
+ *mask = 0x7;
+ if (tex->Texture == TGSI_TEXTURE_1D)
+ *mask = 0x1;
+ else
+ if (tex->Texture == TGSI_TEXTURE_2D)
+ *mask = 0x3;
+
+ if (insn->Instruction.Opcode == TGSI_OPCODE_TXP)
+ *mask |= 0x8;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+prep_inspect_insn(struct nv50_pc *pc, const union tgsi_full_token *tok,
+ unsigned *r_usage[2])
+{
+ const struct tgsi_full_instruction *insn;
+ const struct tgsi_full_src_register *src;
+ const struct tgsi_dst_register *dst;
+
+ unsigned i, c, k, n, mask, *acc_p;
+
+ insn = &tok->FullInstruction;
+ dst = &insn->FullDstRegisters[0].DstRegister;
+ mask = dst->WriteMask;
+
+ if (!r_usage[0])
+ r_usage[0] = CALLOC(pc->temp_nr * 4, sizeof(unsigned));
+ if (!r_usage[1])
+ r_usage[1] = CALLOC(pc->attr_nr * 4, sizeof(unsigned));
+
+ if (dst->File == TGSI_FILE_TEMPORARY) {
+ for (c = 0; c < 4; c++) {
+ if (!(mask & (1 << c)))
+ continue;
+ r_usage[0][dst->Index * 4 + c] = pc->insn_nr;
+ }
+ }
+
+ for (i = 0; i < insn->Instruction.NumSrcRegs; i++) {
+ src = &insn->FullSrcRegisters[i];
+
+ switch (src->SrcRegister.File) {
+ case TGSI_FILE_TEMPORARY:
+ acc_p = r_usage[0];
+ break;
+ case TGSI_FILE_INPUT:
+ acc_p = r_usage[1];
+ break;
+ default:
+ continue;
+ }
+
+ insn_adjust_mask(insn, &mask);
+
+ for (c = 0; c < 4; c++) {
+ if (!(mask & (1 << c)))
+ continue;
+
+ k = tgsi_util_get_full_src_register_extswizzle(src, c);
+ switch (k) {
+ case TGSI_EXTSWIZZLE_X:
+ case TGSI_EXTSWIZZLE_Y:
+ case TGSI_EXTSWIZZLE_Z:
+ case TGSI_EXTSWIZZLE_W:
+ n = src->SrcRegister.Index * 4 + k;
+ acc_p[n] = pc->insn_nr;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static unsigned
+load_fp_attrib(struct nv50_pc *pc, int i, unsigned *acc, int *mid,
+ int *aid, int *p_oid)
+{
+ struct nv50_reg *iv;
+ int oid, c, n;
+ unsigned mask = 0;
+
+ iv = (pc->interp_mode[i] & INTERP_CENTROID) ? pc->iv_c : pc->iv_p;
+
+ for (c = 0, n = i * 4; c < 4; c++, n++) {
+ oid = (*p_oid)++;
+ pc->attr[n].type = P_TEMP;
+ pc->attr[n].index = i;
+
+ if (pc->attr[n].acc == acc[n])
+ continue;
+ mask |= (1 << c);
+
+ pc->attr[n].acc = acc[n];
+ pc->attr[n].rhw = pc->attr[n].hw = -1;
+ alloc_reg(pc, &pc->attr[n]);
+
+ pc->attr[n].rhw = (*aid)++;
+ emit_interp(pc, &pc->attr[n], iv, pc->interp_mode[i]);
+
+ pc->p->cfg.fp.map[(*mid) / 4] |= oid << (8 * ((*mid) % 4));
+ (*mid)++;
+ pc->p->cfg.fp.regs[1] += 0x00010001;
+ }
+
+ return mask;
+}
+
static boolean
nv50_program_tx_prep(struct nv50_pc *pc)
{
struct tgsi_parse_context p;
boolean ret = FALSE;
unsigned i, c;
+ unsigned fcol, bcol, fcrd, depr;
+
+ /* count (centroid) perspective interpolations */
+ unsigned centroid_loads = 0;
+ unsigned perspect_loads = 0;
+
+ /* track register access for temps and attrs */
+ unsigned *r_usage[2];
+ r_usage[0] = NULL;
+ r_usage[1] = NULL;
+
+ depr = fcol = bcol = fcrd = 0xffff;
+
+ if (pc->p->type == PIPE_SHADER_FRAGMENT) {
+ pc->p->cfg.fp.regs[0] = 0x01000404;
+ pc->p->cfg.fp.regs[1] = 0x00000400;
+ }
tgsi_parse_init(&p, pc->p->pipe.tokens);
while (!tgsi_parse_end_of_tokens(&p)) {
@@ -1319,9 +1818,10 @@ nv50_program_tx_prep(struct nv50_pc *pc)
case TGSI_TOKEN_TYPE_DECLARATION:
{
const struct tgsi_full_declaration *d;
- unsigned last;
+ unsigned last, first, mode;
d = &p.FullToken.FullDeclaration;
+ first = d->DeclarationRange.First;
last = d->DeclarationRange.Last;
switch (d->Declaration.File) {
@@ -1332,10 +1832,69 @@ nv50_program_tx_prep(struct nv50_pc *pc)
case TGSI_FILE_OUTPUT:
if (pc->result_nr < (last + 1))
pc->result_nr = last + 1;
+
+ if (!d->Declaration.Semantic)
+ break;
+
+ switch (d->Semantic.SemanticName) {
+ case TGSI_SEMANTIC_POSITION:
+ depr = first;
+ pc->p->cfg.fp.regs[2] |= 0x00000100;
+ pc->p->cfg.fp.regs[3] |= 0x00000011;
+ break;
+ default:
+ break;
+ }
+
break;
case TGSI_FILE_INPUT:
+ {
if (pc->attr_nr < (last + 1))
pc->attr_nr = last + 1;
+
+ if (pc->p->type != PIPE_SHADER_FRAGMENT)
+ break;
+
+ switch (d->Declaration.Interpolate) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ mode = INTERP_FLAT;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ mode = INTERP_PERSPECTIVE;
+ break;
+ default:
+ mode = INTERP_LINEAR;
+ break;
+ }
+
+ if (d->Declaration.Semantic) {
+ switch (d->Semantic.SemanticName) {
+ case TGSI_SEMANTIC_POSITION:
+ fcrd = first;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ fcol = first;
+ mode = INTERP_PERSPECTIVE;
+ break;
+ case TGSI_SEMANTIC_BCOLOR:
+ bcol = first;
+ mode = INTERP_PERSPECTIVE;
+ break;
+ }
+ }
+
+ if (d->Declaration.Centroid) {
+ mode |= INTERP_CENTROID;
+ if (mode & INTERP_PERSPECTIVE)
+ centroid_loads++;
+ } else
+ if (mode & INTERP_PERSPECTIVE)
+ perspect_loads++;
+
+ assert(last < 32);
+ for (i = first; i <= last; i++)
+ pc->interp_mode[i] = mode;
+ }
break;
case TGSI_FILE_CONSTANT:
if (pc->param_nr < (last + 1))
@@ -1351,6 +1910,8 @@ nv50_program_tx_prep(struct nv50_pc *pc)
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
+ pc->insn_nr++;
+ prep_inspect_insn(pc, tok, r_usage);
break;
default:
break;
@@ -1366,56 +1927,95 @@ nv50_program_tx_prep(struct nv50_pc *pc)
for (c = 0; c < 4; c++) {
pc->temp[i*4+c].type = P_TEMP;
pc->temp[i*4+c].hw = -1;
+ pc->temp[i*4+c].rhw = -1;
pc->temp[i*4+c].index = i;
+ pc->temp[i*4+c].acc = r_usage[0][i*4+c];
}
}
}
if (pc->attr_nr) {
- struct nv50_reg *iv = NULL;
- int aid = 0;
+ int oid = 4, mid = 4, aid = 0;
+ /* oid = VP output id
+ * aid = FP attribute/interpolant id
+ * mid = VP output mapping field ID
+ */
pc->attr = CALLOC(pc->attr_nr * 4, sizeof(struct nv50_reg));
if (!pc->attr)
goto out_err;
if (pc->p->type == PIPE_SHADER_FRAGMENT) {
- iv = alloc_temp(pc, NULL);
- emit_interp(pc, iv, iv, NULL);
- emit_flop(pc, 0, iv, iv);
- aid++;
- }
+ /* position should be loaded first */
+ if (fcrd != 0xffff) {
+ unsigned mask;
+ mid = 0;
+ mask = load_fp_attrib(pc, fcrd, r_usage[1],
+ &mid, &aid, &oid);
+ oid = 0;
+ pc->p->cfg.fp.regs[1] |= (mask << 24);
+ pc->p->cfg.fp.map[0] = 0x04040404 * fcrd;
+ }
+ pc->p->cfg.fp.map[0] += 0x03020100;
- for (i = 0; i < pc->attr_nr; i++) {
- struct nv50_reg *a = &pc->attr[i*4];
+ /* should do MAD fcrd.xy, fcrd, SOME_CONST, fcrd */
- for (c = 0; c < 4; c++) {
- if (pc->p->type == PIPE_SHADER_FRAGMENT) {
- struct nv50_reg *at =
- alloc_temp(pc, NULL);
- pc->attr[i*4+c].type = at->type;
- pc->attr[i*4+c].hw = at->hw;
- pc->attr[i*4+c].index = at->index;
+ if (perspect_loads) {
+ pc->iv_p = alloc_temp(pc, NULL);
+
+ if (!(pc->p->cfg.fp.regs[1] & 0x08000000)) {
+ pc->p->cfg.fp.regs[1] |= 0x08000000;
+ pc->iv_p->rhw = aid++;
+ emit_interp(pc, pc->iv_p, NULL,
+ INTERP_LINEAR);
+ emit_flop(pc, 0, pc->iv_p, pc->iv_p);
} else {
- pc->p->cfg.vp.attr[aid/32] |=
- (1 << (aid % 32));
- pc->attr[i*4+c].type = P_ATTR;
- pc->attr[i*4+c].hw = aid++;
- pc->attr[i*4+c].index = i;
+ pc->iv_p->rhw = aid - 1;
+ emit_flop(pc, 0, pc->iv_p,
+ &pc->attr[fcrd * 4 + 3]);
}
}
- if (pc->p->type != PIPE_SHADER_FRAGMENT)
- continue;
+ if (centroid_loads) {
+ pc->iv_c = alloc_temp(pc, NULL);
+ pc->iv_c->rhw = pc->iv_p ? aid - 1 : aid++;
+ emit_interp(pc, pc->iv_c, NULL,
+ INTERP_CENTROID);
+ emit_flop(pc, 0, pc->iv_c, pc->iv_c);
+ pc->p->cfg.fp.regs[1] |= 0x08000000;
+ }
- emit_interp(pc, &a[0], &a[0], iv);
- emit_interp(pc, &a[1], &a[1], iv);
- emit_interp(pc, &a[2], &a[2], iv);
- emit_interp(pc, &a[3], &a[3], iv);
- }
+ for (c = 0; c < 4; c++) {
+ /* I don't know what these values do, but
+ * let's set them like the blob does:
+ */
+ if (fcol != 0xffff && r_usage[1][fcol * 4 + c])
+ pc->p->cfg.fp.regs[0] += 0x00010000;
+ if (bcol != 0xffff && r_usage[1][bcol * 4 + c])
+ pc->p->cfg.fp.regs[0] += 0x00010000;
+ }
- if (iv)
- free_temp(pc, iv);
+ for (i = 0; i < pc->attr_nr; i++)
+ load_fp_attrib(pc, i, r_usage[1],
+ &mid, &aid, &oid);
+
+ if (pc->iv_p)
+ free_temp(pc, pc->iv_p);
+ if (pc->iv_c)
+ free_temp(pc, pc->iv_c);
+
+ pc->p->cfg.fp.high_map = (mid / 4);
+ pc->p->cfg.fp.high_map += ((mid % 4) ? 1 : 0);
+ } else {
+ /* vertex program */
+ for (i = 0; i < pc->attr_nr * 4; i++) {
+ pc->p->cfg.vp.attr[aid / 32] |=
+ (1 << (aid % 32));
+ pc->attr[i].type = P_ATTR;
+ pc->attr[i].hw = aid++;
+ pc->attr[i].index = i / 4;
+ }
+ }
}
if (pc->result_nr) {
@@ -1430,12 +2030,20 @@ nv50_program_tx_prep(struct nv50_pc *pc)
if (pc->p->type == PIPE_SHADER_FRAGMENT) {
pc->result[i*4+c].type = P_TEMP;
pc->result[i*4+c].hw = -1;
+ pc->result[i*4+c].rhw = (i == depr) ?
+ -1 : rid++;
} else {
pc->result[i*4+c].type = P_RESULT;
pc->result[i*4+c].hw = rid++;
}
pc->result[i*4+c].index = i;
}
+
+ if (pc->p->type == PIPE_SHADER_FRAGMENT &&
+ depr != 0xffff) {
+ pc->result[depr * 4 + 2].rhw =
+ (pc->result_nr - 1) * 4;
+ }
}
}
@@ -1456,7 +2064,7 @@ nv50_program_tx_prep(struct nv50_pc *pc)
}
if (pc->immd_nr) {
- int rid = pc->param_nr * 4;
+ int rid = 0;
pc->immd = CALLOC(pc->immd_nr * 4, sizeof(struct nv50_reg));
if (!pc->immd)
@@ -1473,15 +2081,38 @@ nv50_program_tx_prep(struct nv50_pc *pc)
ret = TRUE;
out_err:
+ if (r_usage[0])
+ FREE(r_usage[0]);
+ if (r_usage[1])
+ FREE(r_usage[1]);
+
tgsi_parse_free(&p);
return ret;
}
+static void
+free_nv50_pc(struct nv50_pc *pc)
+{
+ if (pc->immd)
+ FREE(pc->immd);
+ if (pc->param)
+ FREE(pc->param);
+ if (pc->result)
+ FREE(pc->result);
+ if (pc->attr)
+ FREE(pc->attr);
+ if (pc->temp)
+ FREE(pc->temp);
+
+ FREE(pc);
+}
+
static boolean
nv50_program_tx(struct nv50_program *p)
{
struct tgsi_parse_context parse;
struct nv50_pc *pc;
+ unsigned k;
boolean ret;
pc = CALLOC_STRUCT(nv50_pc);
@@ -1498,10 +2129,16 @@ nv50_program_tx(struct nv50_program *p)
while (!tgsi_parse_end_of_tokens(&parse)) {
const union tgsi_full_token *tok = &parse.FullToken;
+ /* don't allow half insn/immd on first and last instruction */
+ pc->allow32 = TRUE;
+ if (pc->insn_cur == 0 || pc->insn_cur + 2 == pc->insn_nr)
+ pc->allow32 = FALSE;
+
tgsi_parse_token(&parse);
switch (tok->Token.Type) {
case TGSI_TOKEN_TYPE_INSTRUCTION:
+ ++pc->insn_cur;
ret = nv50_program_tx_insn(pc, tok);
if (ret == FALSE)
goto out_err;
@@ -1515,8 +2152,40 @@ nv50_program_tx(struct nv50_program *p)
struct nv50_reg out;
out.type = P_TEMP;
- for (out.hw = 0; out.hw < pc->result_nr * 4; out.hw++)
- emit_mov(pc, &out, &pc->result[out.hw]);
+ for (k = 0; k < pc->result_nr * 4; k++) {
+ if (pc->result[k].rhw == -1)
+ continue;
+ if (pc->result[k].hw != pc->result[k].rhw) {
+ out.hw = pc->result[k].rhw;
+ emit_mov(pc, &out, &pc->result[k]);
+ }
+ if (pc->p->cfg.high_result < (pc->result[k].rhw + 1))
+ pc->p->cfg.high_result = pc->result[k].rhw + 1;
+ }
+ }
+
+ /* look for single half instructions and make them long */
+ struct nv50_program_exec *e, *e_prev;
+
+ for (k = 0, e = pc->p->exec_head, e_prev = NULL; e; e = e->next) {
+ if (!is_long(e))
+ k++;
+
+ if (!e->next || is_long(e->next)) {
+ if (k & 1)
+ convert_to_long(pc, e);
+ k = 0;
+ }
+
+ if (e->next)
+ e_prev = e;
+ }
+
+ if (!is_long(pc->p->exec_tail)) {
+ /* this may occur if moving FP results */
+ assert(e_prev && !is_long(e_prev));
+ convert_to_long(pc, e_prev);
+ convert_to_long(pc, pc->p->exec_tail);
}
assert(is_long(pc->p->exec_tail) && !is_immd(pc->p->exec_head));
@@ -1530,6 +2199,7 @@ out_err:
tgsi_parse_free(&parse);
out_cleanup:
+ free_nv50_pc(pc);
return ret;
}
@@ -1543,16 +2213,16 @@ nv50_program_validate(struct nv50_context *nv50, struct nv50_program *p)
static void
nv50_program_upload_data(struct nv50_context *nv50, float *map,
- unsigned start, unsigned count)
+ unsigned start, unsigned count, unsigned cbuf)
{
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->base.channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
while (count) {
unsigned nr = count > 2047 ? 2047 : count;
BEGIN_RING(chan, tesla, 0x00000f00, 1);
- OUT_RING (chan, (NV50_CB_PMISC << 0) | (start << 8));
+ OUT_RING (chan, (cbuf << 0) | (start << 8));
BEGIN_RING(chan, tesla, 0x40000f04, nr);
OUT_RINGp (chan, map, nr);
@@ -1565,70 +2235,93 @@ nv50_program_upload_data(struct nv50_context *nv50, float *map,
static void
nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
{
- struct nouveau_winsys *nvws = nv50->screen->nvws;
- struct pipe_winsys *ws = nv50->pipe.winsys;
- unsigned nr = p->param_nr + p->immd_nr;
+ struct pipe_screen *pscreen = nv50->pipe.screen;
- if (!p->data && nr) {
- struct nouveau_resource *heap = nv50->screen->vp_data_heap;
+ if (!p->data[0] && p->immd_nr) {
+ struct nouveau_resource *heap = nv50->screen->immd_heap[0];
- if (nvws->res_alloc(heap, nr, p, &p->data)) {
- while (heap->next && heap->size < nr) {
+ if (nouveau_resource_alloc(heap, p->immd_nr, p, &p->data[0])) {
+ while (heap->next && heap->size < p->immd_nr) {
struct nv50_program *evict = heap->next->priv;
- nvws->res_free(&evict->data);
+ nouveau_resource_free(&evict->data[0]);
}
- if (nvws->res_alloc(heap, nr, p, &p->data))
+ if (nouveau_resource_alloc(heap, p->immd_nr, p,
+ &p->data[0]))
assert(0);
}
+
+ /* immediates only need to be uploaded again when freed */
+ nv50_program_upload_data(nv50, p->immd, p->data[0]->start,
+ p->immd_nr, NV50_CB_PMISC);
}
- if (p->param_nr) {
- float *map = ws->buffer_map(ws, nv50->constbuf[p->type],
- PIPE_BUFFER_USAGE_CPU_READ);
- nv50_program_upload_data(nv50, map, p->data->start,
- p->param_nr);
- ws->buffer_unmap(ws, nv50->constbuf[p->type]);
+ if (!p->data[1] && p->param_nr) {
+ struct nouveau_resource *heap =
+ nv50->screen->parm_heap[p->type];
+
+ if (nouveau_resource_alloc(heap, p->param_nr, p, &p->data[1])) {
+ while (heap->next && heap->size < p->param_nr) {
+ struct nv50_program *evict = heap->next->priv;
+ nouveau_resource_free(&evict->data[1]);
+ }
+
+ if (nouveau_resource_alloc(heap, p->param_nr, p,
+ &p->data[1]))
+ assert(0);
+ }
}
- if (p->immd_nr) {
- nv50_program_upload_data(nv50, p->immd,
- p->data->start + p->param_nr,
- p->immd_nr);
+ if (p->param_nr) {
+ unsigned cbuf = NV50_CB_PVP;
+ float *map = pipe_buffer_map(pscreen, nv50->constbuf[p->type],
+ PIPE_BUFFER_USAGE_CPU_READ);
+ if (p->type == PIPE_SHADER_FRAGMENT)
+ cbuf = NV50_CB_PFP;
+ nv50_program_upload_data(nv50, map, p->data[1]->start,
+ p->param_nr, cbuf);
+ pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]);
}
}
static void
nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
{
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->base.channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_screen *screen = nv50->pipe.screen;
struct nv50_program_exec *e;
struct nouveau_stateobj *so;
const unsigned flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_WR;
unsigned start, count, *up, *ptr;
boolean upload = FALSE;
- if (!p->buffer) {
- p->buffer = screen->buffer_create(screen, 0x100, 0, p->exec_size * 4);
+ if (!p->bo) {
+ nouveau_bo_new(chan->device, NOUVEAU_BO_VRAM, 0x100,
+ p->exec_size * 4, &p->bo);
upload = TRUE;
}
- if (p->data && p->data->start != p->data_start) {
+ if ((p->data[0] && p->data[0]->start != p->data_start[0]) ||
+ (p->data[1] && p->data[1]->start != p->data_start[1])) {
for (e = p->exec_head; e; e = e->next) {
- unsigned ei, ci;
+ unsigned ei, ci, bs;
if (e->param.index < 0)
continue;
+ bs = (e->inst[1] >> 22) & 0x07;
+ assert(bs < 2);
ei = e->param.shift >> 5;
- ci = e->param.index + p->data->start;
+ ci = e->param.index + p->data[bs]->start;
e->inst[ei] &= ~e->param.mask;
e->inst[ei] |= (ci << e->param.shift);
}
- p->data_start = p->data->start;
+ if (p->data[0])
+ p->data_start[0] = p->data[0]->start;
+ if (p->data[1])
+ p->data_start[1] = p->data[1]->start;
+
upload = TRUE;
}
@@ -1637,13 +2330,11 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
#ifdef NV50_PROGRAM_DUMP
NOUVEAU_ERR("-------\n");
- up = ptr = MALLOC(p->exec_size * 4);
for (e = p->exec_head; e; e = e->next) {
NOUVEAU_ERR("0x%08x\n", e->inst[0]);
if (is_long(e))
NOUVEAU_ERR("0x%08x\n", e->inst[1]);
}
-
#endif
up = ptr = MALLOC(p->exec_size * 4);
@@ -1655,20 +2346,20 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
so = so_new(4,2);
so_method(so, nv50->screen->tesla, 0x1280, 3);
- so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, p->buffer, 0, flags | NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_HIGH, 0, 0);
+ so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4));
start = 0; count = p->exec_size;
while (count) {
- struct nouveau_winsys *nvws = nv50->screen->nvws;
+ struct nouveau_channel *chan = nv50->screen->base.channel;
unsigned nr;
- so_emit(nvws, so);
+ so_emit(chan, so);
nr = MIN2(count, 2047);
- nr = MIN2(nvws->channel->pushbuf->remaining, nr);
- if (nvws->channel->pushbuf->remaining < (nr + 3)) {
+ nr = MIN2(chan->pushbuf->remaining, nr);
+ if (chan->pushbuf->remaining < (nr + 3)) {
FIRE_RING(chan);
continue;
}
@@ -1704,10 +2395,10 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so = so_new(13, 2);
so_method(so, tesla, NV50TCL_VP_ADDRESS_HIGH, 2);
- so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
- NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
- NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
+ NOUVEAU_BO_HIGH, 0, 0);
+ so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
+ NOUVEAU_BO_LOW, 0, 0);
so_method(so, tesla, 0x1650, 2);
so_data (so, p->cfg.vp.attr[0]);
so_data (so, p->cfg.vp.attr[1]);
@@ -1728,6 +2419,7 @@ nv50_fragprog_validate(struct nv50_context *nv50)
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nv50_program *p = nv50->fragprog;
struct nouveau_stateobj *so;
+ unsigned i;
if (!p->translated) {
nv50_program_validate(nv50, p);
@@ -1740,22 +2432,27 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so = so_new(64, 2);
so_method(so, tesla, NV50TCL_FP_ADDRESS_HIGH, 2);
- so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
- NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
- NOUVEAU_BO_LOW, 0, 0);
+ so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
+ NOUVEAU_BO_HIGH, 0, 0);
+ so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
+ NOUVEAU_BO_LOW, 0, 0);
so_method(so, tesla, 0x1904, 4);
- so_data (so, 0x00040404); /* p: 0x01000404 */
+ so_data (so, p->cfg.fp.regs[0]); /* 0x01000404 / 0x00040404 */
so_data (so, 0x00000004);
so_data (so, 0x00000000);
so_data (so, 0x00000000);
- so_method(so, tesla, 0x16bc, 3); /*XXX: fixme */
- so_data (so, 0x03020100);
- so_data (so, 0x07060504);
- so_data (so, 0x0b0a0908);
+ so_method(so, tesla, 0x16bc, p->cfg.fp.high_map);
+ for (i = 0; i < p->cfg.fp.high_map; i++)
+ so_data(so, p->cfg.fp.map[i]);
so_method(so, tesla, 0x1988, 2);
- so_data (so, 0x08080408); //0x08040404); /* p: 0x0f000401 */
+ so_data (so, p->cfg.fp.regs[1]); /* 0x08040404 / 0x0f000401 */
so_data (so, p->cfg.high_temp);
+ so_method(so, tesla, 0x1298, 1);
+ so_data (so, p->cfg.high_result);
+ so_method(so, tesla, 0x19a8, 1);
+ so_data (so, p->cfg.fp.regs[2]);
+ so_method(so, tesla, 0x196c, 1);
+ so_data (so, p->cfg.fp.regs[3]);
so_method(so, tesla, 0x1414, 1);
so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.fragprog);
@@ -1765,8 +2462,6 @@ nv50_fragprog_validate(struct nv50_context *nv50)
void
nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
{
- struct pipe_screen *pscreen = nv50->pipe.screen;
-
while (p->exec_head) {
struct nv50_program_exec *e = p->exec_head;
@@ -1776,10 +2471,10 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
p->exec_tail = NULL;
p->exec_size = 0;
- if (p->buffer)
- pipe_buffer_reference(&p->buffer, NULL);
+ nouveau_bo_ref(NULL, &p->bo);
- nv50->screen->nvws->res_free(&p->data);
+ nouveau_resource_free(&p->data[0]);
+ nouveau_resource_free(&p->data[1]);
p->translated = 0;
}
diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h
index 78deed6a38..096e0476aa 100644
--- a/src/gallium/drivers/nv50/nv50_program.h
+++ b/src/gallium/drivers/nv50/nv50_program.h
@@ -24,10 +24,10 @@ struct nv50_program {
struct nv50_program_exec *exec_head;
struct nv50_program_exec *exec_tail;
unsigned exec_size;
- struct nouveau_resource *data;
- unsigned data_start;
+ struct nouveau_resource *data[2];
+ unsigned data_start[2];
- struct pipe_buffer *buffer;
+ struct nouveau_bo *bo;
float *immd;
unsigned immd_nr;
@@ -39,6 +39,11 @@ struct nv50_program {
struct {
unsigned attr[2];
} vp;
+ struct {
+ unsigned regs[4];
+ unsigned map[5];
+ unsigned high_map;
+ } fp;
} cfg;
};
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 35cebdbdc3..940e04365f 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -26,7 +26,7 @@
#include "nv50_context.h"
struct nv50_query {
- struct pipe_buffer *buffer;
+ struct nouveau_bo *bo;
unsigned type;
boolean ready;
uint64_t result;
@@ -41,14 +41,16 @@ nv50_query(struct pipe_query *pipe)
static struct pipe_query *
nv50_query_create(struct pipe_context *pipe, unsigned type)
{
- struct pipe_screen *screen = pipe->screen;
+ struct nouveau_device *dev = nouveau_screen(pipe->screen)->device;
struct nv50_query *q = CALLOC_STRUCT(nv50_query);
+ int ret;
assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER);
q->type = type;
- q->buffer = screen->buffer_create(screen, 256, 0, 16);
- if (!q->buffer) {
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 256,
+ 16, &q->bo);
+ if (ret) {
FREE(q);
return NULL;
}
@@ -62,7 +64,7 @@ nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
struct nv50_query *q = nv50_query(pq);
if (q) {
- pipe_buffer_reference(&q->buffer, NULL);
+ nouveau_bo_ref(NULL, &q->bo);
FREE(q);
}
}
@@ -71,7 +73,7 @@ static void
nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->base.channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nv50_query *q = nv50_query(pq);
@@ -87,15 +89,14 @@ static void
nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->base.channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nv50_query *q = nv50_query(pq);
- struct nouveau_bo *bo = nv50->screen->nvws->get_bo(q->buffer);
WAIT_RING (chan, 5);
BEGIN_RING(chan, tesla, 0x1b00, 4);
- OUT_RELOCh(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RING (chan, 0x00000000);
OUT_RING (chan, 0x0100f002);
FIRE_RING (chan);
@@ -105,7 +106,6 @@ static boolean
nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, uint64_t *result)
{
- struct pipe_winsys *ws = pipe->winsys;
struct nv50_query *q = nv50_query(pq);
/*XXX: Want to be able to return FALSE here instead of blocking
@@ -113,11 +113,10 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
*/
if (!q->ready) {
- uint32_t *map = ws->buffer_map(ws, q->buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
- q->result = map[1];
+ nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
+ q->result = ((uint32_t *)q->bo->map)[1];
q->ready = TRUE;
- ws->buffer_unmap(ws, q->buffer);
+ nouveau_bo_unmap(q->bo);
}
*result = q->result;
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 2980564594..fd39fa738b 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -22,8 +22,6 @@
#include "pipe/p_screen.h"
-#include "util/u_simple_screen.h"
-
#include "nv50_context.h"
#include "nv50_screen.h"
@@ -68,23 +66,6 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
return FALSE;
}
-static const char *
-nv50_screen_get_name(struct pipe_screen *pscreen)
-{
- struct nv50_screen *screen = nv50_screen(pscreen);
- struct nouveau_device *dev = screen->nvws->channel->device;
- static char buffer[128];
-
- snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
- return buffer;
-}
-
-static const char *
-nv50_screen_get_vendor(struct pipe_screen *pscreen)
-{
- return "nouveau";
-}
-
static int
nv50_screen_get_param(struct pipe_screen *pscreen, int param)
{
@@ -153,37 +134,64 @@ nv50_screen_get_paramf(struct pipe_screen *pscreen, int param)
static void
nv50_screen_destroy(struct pipe_screen *pscreen)
{
- FREE(pscreen);
+ struct nv50_screen *screen = nv50_screen(pscreen);
+
+ nouveau_notifier_free(&screen->sync);
+ nouveau_grobj_free(&screen->tesla);
+ nouveau_grobj_free(&screen->eng2d);
+ nouveau_grobj_free(&screen->m2mf);
+ nouveau_screen_fini(&screen->base);
+ FREE(screen);
}
struct pipe_screen *
-nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
+nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
{
struct nv50_screen *screen = CALLOC_STRUCT(nv50_screen);
+ struct nouveau_channel *chan;
+ struct pipe_screen *pscreen;
struct nouveau_stateobj *so;
- unsigned tesla_class = 0, ret;
- unsigned chipset = nvws->channel->device->chipset;
- int i;
+ unsigned chipset = dev->chipset;
+ unsigned tesla_class = 0;
+ int ret, i;
if (!screen)
return NULL;
- screen->nvws = nvws;
+ pscreen = &screen->base.base;
+
+ ret = nouveau_screen_init(&screen->base, dev);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+ chan = screen->base.channel;
+
+ pscreen->winsys = ws;
+ pscreen->destroy = nv50_screen_destroy;
+ pscreen->get_param = nv50_screen_get_param;
+ pscreen->get_paramf = nv50_screen_get_paramf;
+ pscreen->is_format_supported = nv50_screen_is_format_supported;
+
+ nv50_screen_init_miptree_functions(pscreen);
+ nv50_transfer_init_screen_functions(pscreen);
/* DMA engine object */
- ret = nvws->grobj_alloc(nvws, 0x5039, &screen->m2mf);
+ ret = nouveau_grobj_alloc(chan, 0xbeef5039, 0x5039, &screen->m2mf);
if (ret) {
NOUVEAU_ERR("Error creating M2MF object: %d\n", ret);
- nv50_screen_destroy(&screen->pipe);
+ nv50_screen_destroy(pscreen);
return NULL;
}
+ BIND_RING(chan, screen->m2mf, 1);
/* 2D object */
- ret = nvws->grobj_alloc(nvws, NV50_2D, &screen->eng2d);
+ ret = nouveau_grobj_alloc(chan, 0xbeef502d, 0x502d, &screen->eng2d);
if (ret) {
NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
- nv50_screen_destroy(&screen->pipe);
+ nv50_screen_destroy(pscreen);
return NULL;
}
+ BIND_RING(chan, screen->eng2d, 2);
/* 3D object */
switch (chipset & 0xf0) {
@@ -199,70 +207,55 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
break;
default:
NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset);
- nv50_screen_destroy(&screen->pipe);
+ nv50_screen_destroy(pscreen);
return NULL;
}
if (tesla_class == 0) {
NOUVEAU_ERR("Unknown G8x chipset: NV%02x\n", chipset);
- nv50_screen_destroy(&screen->pipe);
+ nv50_screen_destroy(pscreen);
return NULL;
}
- ret = nvws->grobj_alloc(nvws, tesla_class, &screen->tesla);
+ ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
- nv50_screen_destroy(&screen->pipe);
+ nv50_screen_destroy(pscreen);
return NULL;
}
+ BIND_RING(chan, screen->tesla, 3);
/* Sync notifier */
- ret = nvws->notifier_alloc(nvws, 1, &screen->sync);
+ ret = nouveau_notifier_alloc(chan, 0xbeef0301, 1, &screen->sync);
if (ret) {
NOUVEAU_ERR("Error creating notifier object: %d\n", ret);
- nv50_screen_destroy(&screen->pipe);
+ nv50_screen_destroy(pscreen);
return NULL;
}
- /* Setup the pipe */
- screen->pipe.winsys = ws;
-
- screen->pipe.destroy = nv50_screen_destroy;
-
- screen->pipe.get_name = nv50_screen_get_name;
- screen->pipe.get_vendor = nv50_screen_get_vendor;
- screen->pipe.get_param = nv50_screen_get_param;
- screen->pipe.get_paramf = nv50_screen_get_paramf;
-
- screen->pipe.is_format_supported = nv50_screen_is_format_supported;
-
- nv50_screen_init_miptree_functions(&screen->pipe);
- nv50_transfer_init_screen_functions(&screen->pipe);
- u_simple_screen_init(&screen->pipe);
-
/* Static M2MF init */
so = so_new(32, 0);
so_method(so, screen->m2mf, 0x0180, 3);
so_data (so, screen->sync->handle);
- so_data (so, screen->nvws->channel->vram->handle);
- so_data (so, screen->nvws->channel->vram->handle);
- so_emit(nvws, so);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_emit(chan, so);
so_ref (NULL, &so);
/* Static 2D init */
so = so_new(64, 0);
so_method(so, screen->eng2d, NV50_2D_DMA_NOTIFY, 4);
so_data (so, screen->sync->handle);
- so_data (so, screen->nvws->channel->vram->handle);
- so_data (so, screen->nvws->channel->vram->handle);
- so_data (so, screen->nvws->channel->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
+ so_data (so, chan->vram->handle);
so_method(so, screen->eng2d, NV50_2D_OPERATION, 1);
so_data (so, NV50_2D_OPERATION_SRCCOPY);
so_method(so, screen->eng2d, 0x0290, 1);
so_data (so, 0);
so_method(so, screen->eng2d, 0x0888, 1);
so_data (so, 1);
- so_emit(nvws, so);
+ so_emit(chan, so);
so_ref(NULL, &so);
/* Static tesla init */
@@ -275,11 +268,11 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->tesla, NV50TCL_DMA_UNK0(0),
NV50TCL_DMA_UNK0__SIZE);
for (i = 0; i < NV50TCL_DMA_UNK0__SIZE; i++)
- so_data(so, nvws->channel->vram->handle);
+ so_data(so, chan->vram->handle);
so_method(so, screen->tesla, NV50TCL_DMA_UNK1(0),
NV50TCL_DMA_UNK1__SIZE);
for (i = 0; i < NV50TCL_DMA_UNK1__SIZE; i++)
- so_data(so, nvws->channel->vram->handle);
+ so_data(so, chan->vram->handle);
so_method(so, screen->tesla, 0x121c, 1);
so_data (so, 1);
@@ -290,27 +283,81 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->tesla, 0x16b8, 1);
so_data (so, 8);
- /* Shared constant buffer */
- screen->constbuf = screen->pipe.buffer_create(&screen->pipe, 0, 0, 128 * 4 * 4);
- if (nvws->res_init(&screen->vp_data_heap, 0, 128)) {
- NOUVEAU_ERR("Error initialising constant buffer\n");
- nv50_screen_destroy(&screen->pipe);
+ /* constant buffers for immediates and VP/FP parameters */
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 128*4*4,
+ &screen->constbuf_misc[0]);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
return NULL;
}
+ for (i = 0; i < 2; i++) {
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 128*4*4,
+ &screen->constbuf_parm[i]);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+ }
+
+ if (nouveau_resource_init(&screen->immd_heap[0], 0, 128) ||
+ nouveau_resource_init(&screen->parm_heap[0], 0, 128) ||
+ nouveau_resource_init(&screen->parm_heap[1], 0, 128))
+ {
+ NOUVEAU_ERR("Error initialising constant buffers.\n");
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+
+ /*
+ // map constant buffers:
+ // B = buffer ID (maybe more than 1 byte)
+ // N = CB index used in shader instruction
+ // P = program type (0 = VP, 2 = GP, 3 = FP)
+ so_method(so, screen->tesla, 0x1694, 1);
+ so_data (so, 0x000BBNP1);
+ */
+
so_method(so, screen->tesla, 0x1280, 3);
- so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM |
+ so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (so, screen->constbuf, 0, NOUVEAU_BO_VRAM |
+ so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
- so_data (so, (NV50_CB_PMISC << 16) | 0x00001000);
+ so_data (so, (NV50_CB_PMISC << 16) | 0x00000800);
+ so_method(so, screen->tesla, 0x1694, 1);
+ so_data (so, 0x00000001 | (NV50_CB_PMISC << 12));
+ so_method(so, screen->tesla, 0x1694, 1);
+ so_data (so, 0x00000031 | (NV50_CB_PMISC << 12));
+
+ so_method(so, screen->tesla, 0x1280, 3);
+ so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
+ so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+ so_data (so, (NV50_CB_PVP << 16) | 0x00000800);
+ so_method(so, screen->tesla, 0x1694, 1);
+ so_data (so, 0x00000101 | (NV50_CB_PVP << 12));
+
+ so_method(so, screen->tesla, 0x1280, 3);
+ so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
+ so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+ so_data (so, (NV50_CB_PFP << 16) | 0x00000800);
+ so_method(so, screen->tesla, 0x1694, 1);
+ so_data (so, 0x00000131 | (NV50_CB_PFP << 12));
/* Texture sampler/image unit setup - we abuse the constant buffer
* upload mechanism for the moment to upload data to the tex config
* blocks. At some point we *may* want to go the NVIDIA way of doing
* things?
*/
- screen->tic = screen->pipe.buffer_create(&screen->pipe, 0, 0, 32 * 8 * 4);
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 32*8*4, &screen->tic);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+
so_method(so, screen->tesla, 0x1280, 3);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
@@ -324,7 +371,12 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, 0x00000800);
- screen->tsc = screen->pipe.buffer_create(&screen->pipe, 0, 0, 32 * 8 * 4);
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 0, 32*8*4, &screen->tsc);
+ if (ret) {
+ nv50_screen_destroy(pscreen);
+ return NULL;
+ }
+
so_method(so, screen->tesla, 0x1280, 3);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
@@ -352,14 +404,12 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws)
so_method(so, screen->tesla, 0x1234, 1);
so_data (so, 1);
- so_method(so, screen->tesla, 0x1458, 1);
- so_data (so, 1);
- so_emit(nvws, so);
+ so_emit(chan, so);
so_ref (so, &screen->static_init);
so_ref (NULL, &so);
- nvws->push_flush(nvws, 0, NULL);
+ nouveau_pushbuf_flush(chan, 0);
- return &screen->pipe;
+ return pscreen;
}
diff --git a/src/gallium/drivers/nv50/nv50_screen.h b/src/gallium/drivers/nv50/nv50_screen.h
index db567aaac8..61e24a5b57 100644
--- a/src/gallium/drivers/nv50/nv50_screen.h
+++ b/src/gallium/drivers/nv50/nv50_screen.h
@@ -1,10 +1,10 @@
#ifndef __NV50_SCREEN_H__
#define __NV50_SCREEN_H__
-#include "pipe/p_screen.h"
+#include "nouveau/nouveau_screen.h"
struct nv50_screen {
- struct pipe_screen pipe;
+ struct nouveau_screen base;
struct nouveau_winsys *nvws;
@@ -15,11 +15,14 @@ struct nv50_screen {
struct nouveau_grobj *m2mf;
struct nouveau_notifier *sync;
- struct pipe_buffer *constbuf;
- struct nouveau_resource *vp_data_heap;
+ struct nouveau_bo *constbuf_misc[1];
+ struct nouveau_bo *constbuf_parm[2];
- struct pipe_buffer *tic;
- struct pipe_buffer *tsc;
+ struct nouveau_resource *immd_heap[1];
+ struct nouveau_resource *parm_heap[2];
+
+ struct nouveau_bo *tic;
+ struct nouveau_bo *tsc;
struct nouveau_stateobj *static_init;
};
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index ba852194cd..116866a8e7 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -136,9 +136,11 @@ static void *
nv50_sampler_state_create(struct pipe_context *pipe,
const struct pipe_sampler_state *cso)
{
- unsigned *tsc = CALLOC(8, sizeof(unsigned));
+ struct nv50_sampler_stateobj *sso = CALLOC(1, sizeof(*sso));
+ unsigned *tsc = sso->tsc;
+ float limit;
- tsc[0] = (0x00024000 |
+ tsc[0] = (0x00026000 |
(wrap_mode(cso->wrap_s) << 0) |
(wrap_mode(cso->wrap_t) << 3) |
(wrap_mode(cso->wrap_r) << 6));
@@ -202,7 +204,14 @@ nv50_sampler_state_create(struct pipe_context *pipe,
tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7);
}
- return (void *)tsc;
+ limit = CLAMP(cso->lod_bias, -16.0, 15.0);
+ tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 11;
+
+ tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) |
+ ((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8);
+
+ sso->normalized = cso->normalized_coords;
+ return (void *)sso;
}
static void
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index c13d3de1cb..0caf4b4e91 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -32,6 +32,9 @@ nv50_state_validate_fb(struct nv50_context *nv50)
unsigned i, w, h, gw = 0;
for (i = 0; i < fb->nr_cbufs; i++) {
+ struct pipe_texture *pt = fb->cbufs[i]->texture;
+ struct nouveau_bo *bo = nv50_miptree(pt)->bo;
+
if (!gw) {
w = fb->cbufs[i]->width;
h = fb->cbufs[i]->height;
@@ -46,12 +49,10 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data (so, fb->cbufs[i]->height);
so_method(so, tesla, NV50TCL_RT_ADDRESS_HIGH(i), 5);
- so_reloc (so, nv50_surface_buffer(fb->cbufs[i]), fb->cbufs[i]->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH |
- NOUVEAU_BO_RDWR, 0, 0);
- so_reloc (so, nv50_surface_buffer(fb->cbufs[i]), fb->cbufs[i]->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
- NOUVEAU_BO_RDWR, 0, 0);
+ so_reloc (so, bo, fb->cbufs[i]->offset, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0);
+ so_reloc (so, bo, fb->cbufs[i]->offset, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
switch (fb->cbufs[i]->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
so_data(so, 0xcf);
@@ -65,7 +66,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data(so, 0xe6);
break;
}
- so_data(so, 0x00000000);
+ so_data(so, bo->tile_mode << 4);
so_data(so, 0x00000000);
so_method(so, tesla, 0x1224, 1);
@@ -73,6 +74,9 @@ nv50_state_validate_fb(struct nv50_context *nv50)
}
if (fb->zsbuf) {
+ struct pipe_texture *pt = fb->zsbuf->texture;
+ struct nouveau_bo *bo = nv50_miptree(pt)->bo;
+
if (!gw) {
w = fb->zsbuf->width;
h = fb->zsbuf->height;
@@ -83,12 +87,10 @@ nv50_state_validate_fb(struct nv50_context *nv50)
}
so_method(so, tesla, NV50TCL_ZETA_ADDRESS_HIGH, 5);
- so_reloc (so, nv50_surface_buffer(fb->zsbuf), fb->zsbuf->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH |
- NOUVEAU_BO_RDWR, 0, 0);
- so_reloc (so, nv50_surface_buffer(fb->zsbuf), fb->zsbuf->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
- NOUVEAU_BO_RDWR, 0, 0);
+ so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_HIGH | NOUVEAU_BO_RDWR, 0, 0);
+ so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
switch (fb->zsbuf->format) {
case PIPE_FORMAT_Z24S8_UNORM:
so_data(so, 0x16);
@@ -102,7 +104,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_data(so, 0x16);
break;
}
- so_data(so, 0x00000000);
+ so_data(so, bo->tile_mode << 4);
so_data(so, 0x00000000);
so_method(so, tesla, 0x1538, 1);
@@ -131,7 +133,7 @@ static void
nv50_state_emit(struct nv50_context *nv50)
{
struct nv50_screen *screen = nv50->screen;
- struct nouveau_winsys *nvws = screen->nvws;
+ struct nouveau_channel *chan = screen->base.channel;
if (nv50->pctx_id != screen->cur_pctx) {
nv50->state.dirty |= 0xffffffff;
@@ -139,40 +141,40 @@ nv50_state_emit(struct nv50_context *nv50)
}
if (nv50->state.dirty & NV50_NEW_FRAMEBUFFER)
- so_emit(nvws, nv50->state.fb);
+ so_emit(chan, nv50->state.fb);
if (nv50->state.dirty & NV50_NEW_BLEND)
- so_emit(nvws, nv50->state.blend);
+ so_emit(chan, nv50->state.blend);
if (nv50->state.dirty & NV50_NEW_ZSA)
- so_emit(nvws, nv50->state.zsa);
+ so_emit(chan, nv50->state.zsa);
if (nv50->state.dirty & NV50_NEW_VERTPROG)
- so_emit(nvws, nv50->state.vertprog);
+ so_emit(chan, nv50->state.vertprog);
if (nv50->state.dirty & NV50_NEW_FRAGPROG)
- so_emit(nvws, nv50->state.fragprog);
+ so_emit(chan, nv50->state.fragprog);
if (nv50->state.dirty & NV50_NEW_RASTERIZER)
- so_emit(nvws, nv50->state.rast);
+ so_emit(chan, nv50->state.rast);
if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
- so_emit(nvws, nv50->state.blend_colour);
+ so_emit(chan, nv50->state.blend_colour);
if (nv50->state.dirty & NV50_NEW_STIPPLE)
- so_emit(nvws, nv50->state.stipple);
+ so_emit(chan, nv50->state.stipple);
if (nv50->state.dirty & NV50_NEW_SCISSOR)
- so_emit(nvws, nv50->state.scissor);
+ so_emit(chan, nv50->state.scissor);
if (nv50->state.dirty & NV50_NEW_VIEWPORT)
- so_emit(nvws, nv50->state.viewport);
+ so_emit(chan, nv50->state.viewport);
if (nv50->state.dirty & NV50_NEW_SAMPLER)
- so_emit(nvws, nv50->state.tsc_upload);
+ so_emit(chan, nv50->state.tsc_upload);
if (nv50->state.dirty & NV50_NEW_TEXTURE)
- so_emit(nvws, nv50->state.tic_upload);
+ so_emit(chan, nv50->state.tic_upload);
if (nv50->state.dirty & NV50_NEW_ARRAYS) {
- so_emit(nvws, nv50->state.vtxfmt);
- so_emit(nvws, nv50->state.vtxbuf);
+ so_emit(chan, nv50->state.vtxfmt);
+ so_emit(chan, nv50->state.vtxbuf);
}
nv50->state.dirty = 0;
- so_emit_reloc_markers(nvws, nv50->state.fb);
- so_emit_reloc_markers(nvws, nv50->state.vertprog);
- so_emit_reloc_markers(nvws, nv50->state.fragprog);
- so_emit_reloc_markers(nvws, nv50->state.vtxbuf);
- so_emit_reloc_markers(nvws, nv50->screen->static_init);
+ so_emit_reloc_markers(chan, nv50->state.fb);
+ so_emit_reloc_markers(chan, nv50->state.vertprog);
+ so_emit_reloc_markers(chan, nv50->state.fragprog);
+ so_emit_reloc_markers(chan, nv50->state.vtxbuf);
+ so_emit_reloc_markers(chan, nv50->screen->static_init);
}
boolean
@@ -293,12 +295,12 @@ viewport_uptodate:
so_data (so, NV50_CB_TSC);
so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8);
for (i = 0; i < nv50->sampler_nr; i++)
- so_datap (so, nv50->sampler[i], 8);
+ so_datap (so, nv50->sampler[i]->tsc, 8);
so_ref(so, &nv50->state.tsc_upload);
so_ref(NULL, &so);
}
- if (nv50->dirty & NV50_NEW_TEXTURE)
+ if (nv50->dirty & (NV50_NEW_TEXTURE | NV50_NEW_SAMPLER))
nv50_tex_validate(nv50);
if (nv50->dirty & NV50_NEW_ARRAYS)
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 0cc5168144..8db3b6d344 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -52,21 +52,17 @@ static int
nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
{
struct nv50_miptree *mt = nv50_miptree(ps->texture);
- struct nouveau_channel *chan = screen->nvws->channel;
+ struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
- struct nouveau_bo *bo;
+ struct nouveau_bo *bo = nv50_miptree(ps->texture)->bo;
int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
-
- bo = screen->nvws->get_bo(nv50_miptree(ps->texture)->buffer);
- if (!bo)
- return 1;
format = nv50_format(ps->format);
if (format < 0)
return 1;
- if (!bo->tiled) {
+ if (!bo->tile_flags) {
BEGIN_RING(chan, eng2d, mthd, 2);
OUT_RING (chan, format);
OUT_RING (chan, 1);
@@ -80,7 +76,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
BEGIN_RING(chan, eng2d, mthd, 5);
OUT_RING (chan, format);
OUT_RING (chan, 0);
- OUT_RING (chan, 0);
+ OUT_RING (chan, bo->tile_mode << 4);
OUT_RING (chan, 1);
OUT_RING (chan, 0);
BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
@@ -108,7 +104,7 @@ nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst,
int dx, int dy, struct pipe_surface *src, int sx, int sy,
int w, int h)
{
- struct nouveau_channel *chan = screen->nvws->channel;
+ struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
int ret;
@@ -165,7 +161,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
{
struct nv50_context *nv50 = (struct nv50_context *)pipe;
struct nv50_screen *screen = nv50->screen;
- struct nouveau_channel *chan = screen->nvws->channel;
+ struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
int format, ret;
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index 223c8a3a45..ff40c2ad81 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -26,7 +26,8 @@
#include "nouveau/nouveau_stateobj.h"
static int
-nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt)
+nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
+ struct nv50_miptree *mt, int unit)
{
switch (mt->base.format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
@@ -117,15 +118,18 @@ nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt)
return 1;
}
- so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ so_reloc(so, mt->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
- so_data (so, 0xd0005000);
+ if (nv50->sampler[unit]->normalized)
+ so_data (so, 0xd0005000 | mt->bo->tile_mode << 22);
+ else
+ so_data (so, 0x5001d000 | mt->bo->tile_mode << 22);
so_data (so, 0x00300000);
so_data (so, mt->base.width[0]);
- so_data (so, (mt->base.depth[0] << 16) | mt->base.height[0]);
+ so_data (so, (mt->base.last_level << 28) |
+ (mt->base.depth[0] << 16) | mt->base.height[0]);
so_data (so, 0x03000000);
- so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH |
- NOUVEAU_BO_RD, 0, 0);
+ so_data (so, mt->base.last_level << 4);
return 0;
}
@@ -135,23 +139,35 @@ nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so;
- int unit;
+ int unit, push;
+
+ push = nv50->miptree_nr * 9 + 2;
+ push += MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2;
- so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2);
+ so = so_new(push, nv50->miptree_nr * 2);
so_method(so, tesla, 0x0f00, 1);
so_data (so, NV50_CB_TIC);
- so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8);
for (unit = 0; unit < nv50->miptree_nr; unit++) {
struct nv50_miptree *mt = nv50->miptree[unit];
- if (nv50_tex_construct(so, mt)) {
+ so_method(so, tesla, 0x40000f04, 8);
+ if (nv50_tex_construct(nv50, so, mt, unit)) {
NOUVEAU_ERR("failed tex validate\n");
so_ref(NULL, &so);
return;
}
+
+ so_method(so, tesla, 0x1458, 1);
+ so_data (so, (unit << 9) | (unit << 1) | 1);
+ }
+
+ for (; unit < nv50->state.miptree_nr; unit++) {
+ so_method(so, tesla, 0x1458, 1);
+ so_data (so, (unit << 1) | 0);
}
so_ref(so, &nv50->state.tic_upload);
so_ref(NULL, &so);
+ nv50->state.miptree_nr = nv50->miptree_nr;
}
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index 747195b4f6..d0b7f0bef4 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -6,8 +6,8 @@
struct nv50_transfer {
struct pipe_transfer base;
- struct pipe_buffer *buffer;
- struct nv50_miptree_level *level;
+ struct nouveau_bo *bo;
+ unsigned level_offset;
int level_pitch;
int level_width;
int level_height;
@@ -16,51 +16,48 @@ struct nv50_transfer {
};
static void
-nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src,
- int src_pitch, int sx, int sy, int sw, int sh,
- struct pipe_buffer *dst, int dst_pitch, int dx, int dy,
+nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
+ unsigned src_offset, int src_pitch, int sx, int sy,
+ int sw, int sh, struct nouveau_bo *dst_bo,
+ unsigned dst_offset, int dst_pitch, int dx, int dy,
int dw, int dh, int cpp, int width, int height,
unsigned src_reloc, unsigned dst_reloc)
{
struct nv50_screen *screen = nv50_screen(pscreen);
- struct nouveau_winsys *nvws = screen->nvws;
- struct nouveau_channel *chan = nvws->channel;
+ struct nouveau_channel *chan = screen->m2mf->channel;
struct nouveau_grobj *m2mf = screen->m2mf;
- struct nouveau_bo *src_bo = nvws->get_bo(src);
- struct nouveau_bo *dst_bo = nvws->get_bo(dst);
- unsigned src_offset = 0, dst_offset = 0;
src_reloc |= NOUVEAU_BO_RD;
dst_reloc |= NOUVEAU_BO_WR;
WAIT_RING (chan, 14);
- if (!src_bo->tiled) {
+ if (!src_bo->tile_flags) {
BEGIN_RING(chan, m2mf, 0x0200, 1);
OUT_RING (chan, 1);
BEGIN_RING(chan, m2mf, 0x0314, 1);
OUT_RING (chan, src_pitch);
- src_offset = (sy * src_pitch) + (sx * cpp);
+ src_offset += (sy * src_pitch) + (sx * cpp);
} else {
BEGIN_RING(chan, m2mf, 0x0200, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, 0);
+ OUT_RING (chan, src_bo->tile_mode << 4);
OUT_RING (chan, sw * cpp);
OUT_RING (chan, sh);
OUT_RING (chan, 1);
OUT_RING (chan, 0);
}
- if (!dst_bo->tiled) {
+ if (!dst_bo->tile_flags) {
BEGIN_RING(chan, m2mf, 0x021c, 1);
OUT_RING (chan, 1);
BEGIN_RING(chan, m2mf, 0x0318, 1);
OUT_RING (chan, dst_pitch);
- dst_offset = (dy * dst_pitch) + (dx * cpp);
+ dst_offset += (dy * dst_pitch) + (dx * cpp);
} else {
BEGIN_RING(chan, m2mf, 0x021c, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, 0);
+ OUT_RING (chan, dst_bo->tile_mode << 4);
OUT_RING (chan, dw * cpp);
OUT_RING (chan, dh);
OUT_RING (chan, 1);
@@ -77,13 +74,13 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src,
BEGIN_RING(chan, m2mf, 0x030c, 2);
OUT_RELOCl(chan, src_bo, src_offset, src_reloc);
OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc);
- if (src_bo->tiled) {
+ if (src_bo->tile_flags) {
BEGIN_RING(chan, m2mf, 0x0218, 1);
OUT_RING (chan, (dy << 16) | sx);
} else {
src_offset += (line_count * src_pitch);
}
- if (dst_bo->tiled) {
+ if (dst_bo->tile_flags) {
BEGIN_RING(chan, m2mf, 0x0234, 1);
OUT_RING (chan, (sy << 16) | dx);
} else {
@@ -108,10 +105,12 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
enum pipe_transfer_usage usage,
unsigned x, unsigned y, unsigned w, unsigned h)
{
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = nv50_miptree(pt);
struct nv50_miptree_level *lvl = &mt->level[level];
struct nv50_transfer *tx;
unsigned image = 0;
+ int ret;
if (pt->target == PIPE_TEXTURE_CUBE)
image = face;
@@ -133,20 +132,24 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
tx->base.stride = (w * pt->block.size);
tx->base.usage = usage;
- tx->level = lvl;
tx->level_pitch = lvl->pitch;
tx->level_width = mt->base.width[level];
tx->level_height = mt->base.height[level];
+ tx->level_offset = lvl->image_offset[image];
tx->level_x = x;
tx->level_y = y;
- tx->buffer =
- pipe_buffer_create(pscreen, 0, NOUVEAU_BUFFER_USAGE_TRANSFER,
- w * tx->base.block.size * h);
+ ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
+ w * pt->block.size * h, &tx->bo);
+ if (ret) {
+ FREE(tx);
+ return NULL;
+ }
if (usage != PIPE_TRANSFER_WRITE) {
- nv50_transfer_rect_m2mf(pscreen, mt->buffer, tx->level_pitch,
- x, y, tx->level_width, tx->level_height,
- tx->buffer, tx->base.stride, 0, 0,
+ nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset,
+ tx->level_pitch, x, y, tx->level_width,
+ tx->level_height, tx->bo, 0,
+ tx->base.stride, 0, 0,
tx->base.width, tx->base.height,
tx->base.block.size, w, h,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
@@ -164,17 +167,18 @@ nv50_transfer_del(struct pipe_transfer *ptx)
if (ptx->usage != PIPE_TRANSFER_READ) {
struct pipe_screen *pscreen = ptx->texture->screen;
- nv50_transfer_rect_m2mf(pscreen, tx->buffer, tx->base.stride,
+ nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride,
0, 0, tx->base.width, tx->base.height,
- mt->buffer, tx->level_pitch,
- tx->level_x, tx->level_y,
- tx->level_width, tx->level_height,
- tx->base.block.size, tx->base.width,
- tx->base.height, NOUVEAU_BO_GART,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+ mt->bo, tx->level_offset,
+ tx->level_pitch, tx->level_x,
+ tx->level_y, tx->level_width,
+ tx->level_height, tx->base.block.size,
+ tx->base.width, tx->base.height,
+ NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_GART);
}
- pipe_buffer_reference(&tx->buffer, NULL);
+ nouveau_bo_ref(NULL, &tx->bo);
pipe_texture_reference(&ptx->texture, NULL);
FREE(ptx);
}
@@ -184,13 +188,17 @@ nv50_transfer_map(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
unsigned flags = 0;
+ int ret;
if (ptx->usage & PIPE_TRANSFER_WRITE)
- flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
+ flags |= NOUVEAU_BO_WR;
if (ptx->usage & PIPE_TRANSFER_READ)
- flags |= PIPE_BUFFER_USAGE_CPU_READ;
+ flags |= NOUVEAU_BO_RD;
- return pipe_buffer_map(pscreen, tx->buffer, flags);
+ ret = nouveau_bo_map(tx->bo, flags);
+ if (ret)
+ return NULL;
+ return tx->bo->map;
}
static void
@@ -198,7 +206,7 @@ nv50_transfer_unmap(struct pipe_screen *pscreen, struct pipe_transfer *ptx)
{
struct nv50_transfer *tx = (struct nv50_transfer *)ptx;
- pipe_buffer_unmap(pscreen, tx->buffer);
+ nouveau_bo_unmap(tx->bo);
}
void
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 0749c90691..f81929f238 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -22,6 +22,7 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
#include "nv50_context.h"
@@ -53,7 +54,7 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
nv50_state_validate(nv50);
@@ -83,7 +84,7 @@ static INLINE void
nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
map += start;
@@ -112,7 +113,7 @@ static INLINE void
nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
map += start;
@@ -141,7 +142,7 @@ static INLINE void
nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map,
unsigned start, unsigned count)
{
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
map += start;
@@ -163,10 +164,12 @@ nv50_draw_elements(struct pipe_context *pipe,
unsigned mode, unsigned start, unsigned count)
{
struct nv50_context *nv50 = nv50_context(pipe);
- struct nouveau_channel *chan = nv50->screen->nvws->channel;
+ struct nouveau_channel *chan = nv50->screen->tesla->channel;
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct pipe_winsys *ws = pipe->winsys;
- void *map = ws->buffer_map(ws, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
+ struct pipe_screen *pscreen = pipe->screen;
+ void *map;
+
+ map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ);
nv50_state_validate(nv50);
@@ -193,6 +196,7 @@ nv50_draw_elements(struct pipe_context *pipe,
BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1);
OUT_RING (chan, 0);
+ pipe_buffer_unmap(pscreen, indexBuffer);
pipe->flush(pipe, 0, NULL);
return TRUE;
}
@@ -212,6 +216,7 @@ nv50_vbo_validate(struct nv50_context *nv50)
struct pipe_vertex_element *ve = &nv50->vtxelt[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
+ struct nouveau_bo *bo = nouveau_bo(vb->buffer);
switch (ve->src_format) {
case PIPE_FORMAT_R32G32B32A32_FLOAT:
@@ -240,10 +245,10 @@ nv50_vbo_validate(struct nv50_context *nv50)
so_method(vtxbuf, tesla, 0x900 + (i * 16), 3);
so_data (vtxbuf, 0x20000000 | vb->stride);
- so_reloc (vtxbuf, vb->buffer, vb->buffer_offset +
+ so_reloc (vtxbuf, bo, vb->buffer_offset +
ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
- so_reloc (vtxbuf, vb->buffer, vb->buffer_offset +
+ so_reloc (vtxbuf, bo, vb->buffer_offset +
ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
}
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 9d95ad918c..00fae8d26f 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -34,7 +34,6 @@ void r300_parse_chipset(struct r300_capabilities* caps)
caps->is_r500 = FALSE;
caps->num_vert_fpus = 4;
-
/* Note: These are not ordered by PCI ID. I leave that task to GCC,
* which will perform the ordering while collating jump tables. Instead,
* I've tried to group them according to capabilities and age. */
@@ -150,6 +149,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
caps->num_vert_fpus = 6;
break;
+ case 0x4B48:
case 0x4B49:
case 0x4B4A:
case 0x4B4B:
@@ -349,7 +349,4 @@ void r300_parse_chipset(struct r300_capabilities* caps)
caps->pci_id);
break;
}
-
- /* XXX SW TCL is broken so no forcing it off right now
- caps->has_tcl = FALSE; */
}
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index 21eebeae60..5b2e1f0568 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -34,8 +34,6 @@ struct r300_capabilities {
int family;
/* The number of vertex floating-point units */
int num_vert_fpus;
- /* The number of fragment pipes */
- int num_frag_pipes;
/* Whether or not TCL is physically present */
boolean has_tcl;
/* Whether or not this is an RV515 or newer; R500s have many differences
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 31efe91417..233a32b53c 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -34,10 +34,6 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
int i;
- if (r300->dirty_state) {
- r300_emit_dirty_state(r300);
- }
-
for (i = 0; i < r300->vertex_buffer_count; i++) {
void* buf = pipe_buffer_map(pipe->screen,
r300->vertex_buffers[i].buffer,
@@ -102,6 +98,29 @@ static void r300_destroy_context(struct pipe_context* context) {
FREE(r300);
}
+static unsigned int
+r300_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+static unsigned int
+r300_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ /**
+ * FIXME: Optimize.
+ */
+
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
struct pipe_context* r300_create_context(struct pipe_screen* screen,
struct r300_winsys* r300_winsys)
{
@@ -110,7 +129,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
if (!r300)
return NULL;
- /* XXX this could be refactored now? */
r300->winsys = r300_winsys;
r300->context.winsys = (struct pipe_winsys*)r300_winsys;
@@ -124,8 +142,18 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_draw_range_elements;
+ r300->context.is_texture_referenced = r300_is_texture_referenced;
+ r300->context.is_buffer_referenced = r300_is_buffer_referenced;
+
+ /* Create a Draw. This is used for vert collation and SW TCL. */
r300->draw = draw_create();
+ /* Enable our renderer. */
draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
+ /* Disable Draw's clipping if TCL is present. */
+ draw_set_driver_clipping(r300->draw, r300_screen(screen)->caps->has_tcl);
+ /* Force Draw to never do viewport transform, since (again) we can do
+ * transform in hardware, always. */
+ draw_set_viewport_state(r300->draw, &r300_viewport_identity);
r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
r300->rs_block = CALLOC_STRUCT(r300_rs_block);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index fec2bad546..27bc7fd1a9 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -60,9 +60,14 @@ struct r300_dsa_state {
};
struct r300_rs_state {
- /* XXX icky as fucking hell */
+ /* Draw-specific rasterizer state */
struct pipe_rasterizer_state rs;
+ /* Whether or not to enable the VTE. This is referenced at the very
+ * last moment during emission of VTE state, to decide whether or not
+ * the VTE should be used for transformation. */
+ boolean enable_vte;
+
uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */
uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */
uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */
@@ -112,23 +117,24 @@ struct r300_viewport_state {
uint32_t vte_control; /* R300_VAP_VTE_CNTL: 0x20b0 */
};
-#define R300_NEW_BLEND 0x0000001
-#define R300_NEW_BLEND_COLOR 0x0000002
-#define R300_NEW_CONSTANTS 0x0000004
-#define R300_NEW_DSA 0x0000008
-#define R300_NEW_FRAMEBUFFERS 0x0000010
-#define R300_NEW_FRAGMENT_SHADER 0x0000020
-#define R300_NEW_RASTERIZER 0x0000040
-#define R300_NEW_RS_BLOCK 0x0000080
-#define R300_NEW_SAMPLER 0x0000100
-#define R300_ANY_NEW_SAMPLERS 0x000ff00
-#define R300_NEW_SCISSOR 0x0010000
-#define R300_NEW_TEXTURE 0x0020000
-#define R300_ANY_NEW_TEXTURES 0x1fe0000
-#define R300_NEW_VERTEX_FORMAT 0x2000000
-#define R300_NEW_VERTEX_SHADER 0x4000000
-#define R300_NEW_VIEWPORT 0x8000000
-#define R300_NEW_KITCHEN_SINK 0xfffffff
+#define R300_NEW_BLEND 0x00000001
+#define R300_NEW_BLEND_COLOR 0x00000002
+#define R300_NEW_CLIP 0x00000004
+#define R300_NEW_CONSTANTS 0x00000008
+#define R300_NEW_DSA 0x00000010
+#define R300_NEW_FRAMEBUFFERS 0x00000020
+#define R300_NEW_FRAGMENT_SHADER 0x00000040
+#define R300_NEW_RASTERIZER 0x00000080
+#define R300_NEW_RS_BLOCK 0x00000100
+#define R300_NEW_SAMPLER 0x00000200
+#define R300_ANY_NEW_SAMPLERS 0x0001fe00
+#define R300_NEW_SCISSOR 0x00020000
+#define R300_NEW_TEXTURE 0x00040000
+#define R300_ANY_NEW_TEXTURES 0x03fc0000
+#define R300_NEW_VERTEX_FORMAT 0x04000000
+#define R300_NEW_VERTEX_SHADER 0x08000000
+#define R300_NEW_VIEWPORT 0x10000000
+#define R300_NEW_KITCHEN_SINK 0x1fffffff
/* The next several objects are not pure Radeon state; they inherit from
* various Gallium classes. */
@@ -136,11 +142,11 @@ struct r300_viewport_state {
struct r300_constant_buffer {
/* Buffer of constants */
/* XXX first number should be raised */
- float constants[8][4];
+ float constants[32][4];
/* Number of user-defined constants */
- int user_count;
+ unsigned user_count;
/* Total number of constants */
- int count;
+ unsigned count;
};
struct r3xx_fragment_shader {
@@ -153,6 +159,10 @@ struct r3xx_fragment_shader {
/* Pixel stack size */
int stack_size;
+
+ /* Are there immediates in this shader?
+ * If not, we can heavily optimize recompilation. */
+ boolean uses_imms;
};
struct r300_fragment_shader {
@@ -225,10 +235,11 @@ struct r300_vertex_format {
uint32_t vap_prog_stream_cntl[8];
/* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
uint32_t vap_prog_stream_cntl_ext[8];
- /* This is a map of VAP/SW TCL outputs into the GA/RS.
- * tab[i] is the location of input i in GA/RS input memory.
- * Named tab for historical reasons. */
- int tab[16];
+ /* Map of vertex attributes into PVS memory for HW TCL,
+ * or GA memory for SW TCL. */
+ int vs_tab[16];
+ /* Map of rasterizer attributes from GB through RS to US. */
+ int fs_tab[16];
};
struct r300_vertex_shader {
@@ -242,6 +253,10 @@ struct r300_vertex_shader {
/* Has this shader been translated yet? */
boolean translated;
+ /* Are there immediates in this shader?
+ * If not, we can heavily optimize recompilation. */
+ boolean uses_imms;
+
/* Number of used instructions */
int instruction_count;
@@ -254,6 +269,11 @@ struct r300_vertex_shader {
} instructions[128]; /*< XXX magic number */
};
+static struct pipe_viewport_state r300_viewport_identity = {
+ .scale = {1.0, 1.0, 1.0, 1.0},
+ .translate = {0.0, 0.0, 0.0, 0.0},
+};
+
struct r300_context {
/* Parent class */
struct pipe_context context;
@@ -263,11 +283,18 @@ struct r300_context {
/* Draw module. Used mostly for SW TCL. */
struct draw_context* draw;
+ /* Vertex buffer for rendering. */
+ struct pipe_buffer* vbo;
+ /* Offset into the VBO. */
+ size_t vbo_offset;
+
/* Various CSO state objects. */
/* Blend state. */
struct r300_blend_state* blend_state;
/* Blend color state. */
struct r300_blend_color_state* blend_color_state;
+ /* User clip planes. */
+ struct pipe_clip_state clip_state;
/* Shader constants. */
struct r300_constant_buffer shader_constants[PIPE_SHADER_TYPES];
/* Depth, stencil, and alpha state. */
@@ -288,7 +315,7 @@ struct r300_context {
/* Texture states. */
struct r300_texture* textures[8];
int texture_count;
- /* Vertex buffers. */
+ /* Vertex buffers for Gallium. */
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
int vertex_buffer_count;
/* Vertex information. */
@@ -313,11 +340,4 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300);
void r300_init_state_functions(struct r300_context* r300);
void r300_init_surface_functions(struct r300_context* r300);
-/* Fun with includes: r300_winsys also declares this prototype.
- * We'll just step out in that case... */
-#ifndef R300_WINSYS_H
-struct pipe_context* r300_create_context(struct pipe_screen* screen,
- struct r300_winsys* r300_winsys);
-#endif
-
#endif /* R300_CONTEXT_H */
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 5d9799dd72..71b142c0db 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -34,6 +34,7 @@
#define MAX_CS_SIZE 64 * 1024 / 4
+#define VERY_VERBOSE_CS 0
#define VERY_VERBOSE_REGISTERS 0
/* XXX stolen from radeon_drm.h */
@@ -49,27 +50,29 @@
#define CS_LOCALS(context) \
struct r300_winsys* cs_winsys = context->winsys; \
- struct radeon_cs* cs = cs_winsys->cs; \
int cs_count = 0;
#define CHECK_CS(size) \
- cs_winsys->check_cs(cs, (size))
+ cs_winsys->check_cs(cs_winsys, (size))
#define BEGIN_CS(size) do { \
CHECK_CS(size); \
- debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
- size, __FUNCTION__, __FILE__, __LINE__); \
- cs_winsys->begin_cs(cs, (size), __FILE__, __FUNCTION__, __LINE__); \
+ if (VERY_VERBOSE_CS) { \
+ debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
+ size, __FUNCTION__, __FILE__, __LINE__); \
+ } \
+ cs_winsys->begin_cs(cs_winsys, (size), \
+ __FILE__, __FUNCTION__, __LINE__); \
cs_count = size; \
} while (0)
#define OUT_CS(value) do { \
- cs_winsys->write_cs_dword(cs, (value)); \
+ cs_winsys->write_cs_dword(cs_winsys, (value)); \
cs_count--; \
} while (0)
#define OUT_CS_32F(value) do { \
- cs_winsys->write_cs_dword(cs, fui(value)); \
+ cs_winsys->write_cs_dword(cs_winsys, fui(value)); \
cs_count--; \
} while (0)
@@ -93,26 +96,31 @@
} while (0)
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
- debug_printf("r300: writing relocation for buffer %p, offset %d\n", \
- bo, offset); \
+ debug_printf("r300: writing relocation for buffer %p, offset %d, " \
+ "domains (%d, %d, %d)\n", \
+ bo, offset, rd, wd, flags); \
assert(bo); \
OUT_CS(offset); \
- cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \
+ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
cs_count -= 2; \
} while (0)
#define END_CS do { \
- debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \
- __LINE__); \
+ if (VERY_VERBOSE_CS) { \
+ debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \
+ __FILE__, __LINE__); \
+ } \
if (cs_count != 0) \
debug_printf("r300: Warning: cs_count off by %d\n", cs_count); \
- cs_winsys->end_cs(cs, __FILE__, __FUNCTION__, __LINE__); \
+ cs_winsys->end_cs(cs_winsys, __FILE__, __FUNCTION__, __LINE__); \
} while (0)
#define FLUSH_CS do { \
- debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, __FILE__, \
- __LINE__); \
- cs_winsys->flush_cs(cs); \
+ if (VERY_VERBOSE_CS) { \
+ debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \
+ __FILE__, __LINE__); \
+ } \
+ cs_winsys->flush_cs(cs_winsys); \
} while (0)
#define RADEON_ONE_REG_WR (1 << 15)
@@ -138,7 +146,7 @@
assert(bo); \
OUT_CS(offset); \
OUT_CS(count); \
- cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \
+ cs_winsys->write_cs_reloc(cs_winsys, bo, rd, wd, flags); \
cs_count -= 2; \
} while (0)
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index dd63136c9d..678cd2b812 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -30,81 +30,6 @@ static void r300_dump_fs(struct r300_fragment_shader* fs)
}
}
-static char* r500_fs_swiz[] = {
- " R",
- " G",
- " B",
- " A",
- " 0",
- ".5",
- " 1",
- " U",
-};
-
-static char* r500_fs_op_rgb[] = {
- "MAD",
- "DP3",
- "DP4",
- "D2A",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "SOP",
- "MDH",
- "MDV",
-};
-
-static char* r500_fs_op_alpha[] = {
- "MAD",
- " DP",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "EX2",
- "LN2",
- "RCP",
- "RSQ",
- "SIN",
- "COS",
- "MDH",
- "MDV",
-};
-
-static char* r500_fs_mask[] = {
- "NONE",
- "R ",
- " G ",
- "RG ",
- " B ",
- "R B ",
- " GB ",
- "RGB ",
- " A",
- "R A",
- " G A",
- "RG A",
- " BA",
- "R BA",
- " GBA",
- "RGBA",
-};
-
-static char* r500_fs_tex[] = {
- " NOP",
- " LD",
- "TEXKILL",
- " PROJ",
- "LODBIAS",
- " LOD",
- " DXDY",
-};
-
void r500_fs_dump(struct r500_fragment_shader* fs)
{
int i;
@@ -225,14 +150,49 @@ void r500_fs_dump(struct r500_fragment_shader* fs)
}
}
+static void r300_vs_op_dump(uint32_t op)
+{
+ debug_printf(" dst: %d%s op: ",
+ (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
+ if (op & 0x80) {
+ if (op & 0x1) {
+ debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
+ } else {
+ debug_printf(" PVS_MACRO_OP_2CLK_MADD\n");
+ }
+ } else if (op & 0x40) {
+ debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]);
+ } else {
+ debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]);
+ }
+}
+
+void r300_vs_src_dump(uint32_t src)
+{
+ debug_printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
+ (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
+ src & (1 << 25) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 13) & 0x7],
+ src & (1 << 26) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 16) & 0x7],
+ src & (1 << 27) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 19) & 0x7],
+ src & (1 << 28) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 22) & 0x7]);
+}
+
void r300_vs_dump(struct r300_vertex_shader* vs)
{
int i;
for (i = 0; i < vs->instruction_count; i++) {
- debug_printf("inst0: 0x%x\n", vs->instructions[i].inst0);
- debug_printf("inst1: 0x%x\n", vs->instructions[i].inst1);
- debug_printf("inst2: 0x%x\n", vs->instructions[i].inst2);
- debug_printf("inst3: 0x%x\n", vs->instructions[i].inst3);
+ debug_printf("%d: op: 0x%08x", i, vs->instructions[i].inst0);
+ r300_vs_op_dump(vs->instructions[i].inst0);
+ debug_printf(" src0: 0x%08x", vs->instructions[i].inst1);
+ r300_vs_src_dump(vs->instructions[i].inst1);
+ debug_printf(" src1: 0x%08x", vs->instructions[i].inst2);
+ r300_vs_src_dump(vs->instructions[i].inst2);
+ debug_printf(" src2: 0x%08x", vs->instructions[i].inst3);
+ r300_vs_src_dump(vs->instructions[i].inst3);
}
}
diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h
index a1f873656d..c86410ec0a 100644
--- a/src/gallium/drivers/r300/r300_debug.h
+++ b/src/gallium/drivers/r300/r300_debug.h
@@ -27,6 +27,182 @@
#include "r300_state_shader.h"
#include "r300_state_tcl.h"
+static char* r500_fs_swiz[] = {
+ " R",
+ " G",
+ " B",
+ " A",
+ " 0",
+ ".5",
+ " 1",
+ " U",
+};
+
+static char* r500_fs_op_rgb[] = {
+ "MAD",
+ "DP3",
+ "DP4",
+ "D2A",
+ "MIN",
+ "MAX",
+ "---",
+ "CND",
+ "CMP",
+ "FRC",
+ "SOP",
+ "MDH",
+ "MDV",
+};
+
+static char* r500_fs_op_alpha[] = {
+ "MAD",
+ " DP",
+ "MIN",
+ "MAX",
+ "---",
+ "CND",
+ "CMP",
+ "FRC",
+ "EX2",
+ "LN2",
+ "RCP",
+ "RSQ",
+ "SIN",
+ "COS",
+ "MDH",
+ "MDV",
+};
+
+static char* r500_fs_mask[] = {
+ "NONE",
+ "R ",
+ " G ",
+ "RG ",
+ " B ",
+ "R B ",
+ " GB ",
+ "RGB ",
+ " A",
+ "R A",
+ " G A",
+ "RG A",
+ " BA",
+ "R BA",
+ " GBA",
+ "RGBA",
+};
+
+static char* r500_fs_tex[] = {
+ " NOP",
+ " LD",
+ "TEXKILL",
+ " PROJ",
+ "LODBIAS",
+ " LOD",
+ " DXDY",
+};
+
+static char* r300_vs_ve_ops[] = {
+ /* R300 vector ops */
+ " VE_NO_OP",
+ " VE_DOT_PRODUCT",
+ " VE_MULTIPLY",
+ " VE_ADD",
+ " VE_MULTIPLY_ADD",
+ " VE_DISTANCE_FACTOR",
+ " VE_FRACTION",
+ " VE_MAXIMUM",
+ " VE_MINIMUM",
+ "VE_SET_GREATER_THAN_EQUAL",
+ " VE_SET_LESS_THAN",
+ " VE_MULTIPLYX2_ADD",
+ " VE_MULTIPLY_CLAMP",
+ " VE_FLT2FIX_DX",
+ " VE_FLT2FIX_DX_RND",
+ /* R500 vector ops */
+ " VE_PRED_SET_EQ_PUSH",
+ " VE_PRED_SET_GT_PUSH",
+ " VE_PRED_SET_GTE_PUSH",
+ " VE_PRED_SET_NEQ_PUSH",
+ " VE_COND_WRITE_EQ",
+ " VE_COND_WRITE_GT",
+ " VE_COND_WRITE_GTE",
+ " VE_COND_WRITE_NEQ",
+ " VE_SET_GREATER_THAN",
+ " VE_SET_EQUAL",
+ " VE_SET_NOT_EQUAL",
+ " (reserved)",
+ " (reserved)",
+ " (reserved)",
+};
+
+static char* r300_vs_me_ops[] = {
+ /* R300 math ops */
+ " ME_NO_OP",
+ " ME_EXP_BASE2_DX",
+ " ME_LOG_BASE2_DX",
+ " ME_EXP_BASEE_FF",
+ " ME_LIGHT_COEFF_DX",
+ " ME_POWER_FUNC_FF",
+ " ME_RECIP_DX",
+ " ME_RECIP_FF",
+ " ME_RECIP_SQRT_DX",
+ " ME_RECIP_SQRT_FF",
+ " ME_MULTIPLY",
+ " ME_EXP_BASE2_FULL_DX",
+ " ME_LOG_BASE2_FULL_DX",
+ " ME_POWER_FUNC_FF_CLAMP_B",
+ "ME_POWER_FUNC_FF_CLAMP_B1",
+ "ME_POWER_FUNC_FF_CLAMP_01",
+ " ME_SIN",
+ " ME_COS",
+ /* R500 math ops */
+ " ME_LOG_BASE2_IEEE",
+ " ME_RECIP_IEEE",
+ " ME_RECIP_SQRT_IEEE",
+ " ME_PRED_SET_EQ",
+ " ME_PRED_SET_GT",
+ " ME_PRED_SET_GTE",
+ " ME_PRED_SET_NEQ",
+ " ME_PRED_SET_CLR",
+ " ME_PRED_SET_INV",
+ " ME_PRED_SET_POP",
+ " ME_PRED_SET_RESTORE",
+ " (reserved)",
+ " (reserved)",
+ " (reserved)",
+};
+
+/* XXX refactor to avoid clashing symbols */
+static char* r300_vs_src_debug[] = {
+ "t",
+ "i",
+ "c",
+ "a",
+};
+
+static char* r300_vs_dst_debug[] = {
+ "t",
+ "a0",
+ "o",
+ "ox",
+ "a",
+ "i",
+ "u",
+ "u",
+};
+
+static char* r300_vs_swiz_debug[] = {
+ "X",
+ "Y",
+ "Z",
+ "W",
+ "0",
+ "1",
+ "U",
+ "U",
+};
+
void r500_fs_dump(struct r500_fragment_shader* fs);
void r300_vs_dump(struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index a3d83376b6..93cf6909a3 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -56,6 +56,36 @@ void r300_emit_blend_color_state(struct r300_context* r300,
}
}
+void r300_emit_clip_state(struct r300_context* r300,
+ struct pipe_clip_state* clip)
+{
+ int i;
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ CS_LOCALS(r300);
+
+ if (r300screen->caps->has_tcl) {
+ BEGIN_CS(5 + (6 * 4));
+ OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
+ (r300screen->caps->is_r500 ?
+ R500_PVS_UCP_START : R300_PVS_UCP_START));
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4);
+ for (i = 0; i < 6; i++) {
+ OUT_CS_32F(clip->ucp[i][0]);
+ OUT_CS_32F(clip->ucp[i][1]);
+ OUT_CS_32F(clip->ucp[i][2]);
+ OUT_CS_32F(clip->ucp[i][3]);
+ }
+ OUT_CS_REG(R300_VAP_CLIP_CNTL, ((1 << clip->nr) - 1) |
+ R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
+ END_CS;
+ } else {
+ BEGIN_CS(2);
+ OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
+ END_CS;
+ }
+
+}
+
void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa)
{
@@ -152,34 +182,41 @@ void r500_emit_fragment_shader(struct r300_context* r300,
END_CS;
}
-/* XXX add pitch, stride, clean up */
void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb)
{
- int i;
struct r300_texture* tex;
+ unsigned pixpitch;
+ int i;
CS_LOCALS(r300);
- BEGIN_CS((6 * fb->nr_cbufs) + (fb->zsbuf ? 6 : 0) + 4);
+ BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4);
for (i = 0; i < fb->nr_cbufs; i++) {
tex = (struct r300_texture*)fb->cbufs[i]->texture;
+ assert(tex && tex->buffer && "cbuf is marked, but NULL!");
+ pixpitch = tex->stride / tex->tex.block.size;
+
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pixpitch |
+ r300_translate_colorformat(tex->tex.format));
+
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),
r300_translate_out_fmt(fb->cbufs[i]->format));
}
if (fb->zsbuf) {
tex = (struct r300_texture*)fb->zsbuf->texture;
+ assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
+ pixpitch = tex->stride / tex->tex.block.size;
+
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- if (fb->zsbuf->format == PIPE_FORMAT_Z24S8_UNORM) {
- OUT_CS_REG(R300_ZB_FORMAT,
- R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL);
- } else {
- OUT_CS_REG(R300_ZB_FORMAT, 0x0);
- }
+
+ OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));
+
+ OUT_CS_REG(R300_ZB_DEPTHPITCH, pixpitch);
}
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
@@ -229,7 +266,7 @@ void r300_emit_rs_block_state(struct r300_context* r300,
}
for (i = 0; i < 8; i++) {
OUT_CS(rs->ip[i]);
- debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]);
+ /* debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); */
}
OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
@@ -243,11 +280,11 @@ void r300_emit_rs_block_state(struct r300_context* r300,
}
for (i = 0; i < 8; i++) {
OUT_CS(rs->inst[i]);
- debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]);
+ /* debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); */
}
- debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count,
- rs->inst_count);
+ /* debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count,
+ * rs->inst_count); */
END_CS;
}
@@ -291,6 +328,30 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
+void r300_emit_vertex_buffer(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ debug_printf("r300: Preparing vertex buffer %p for render, "
+ "vertex size %d\n", r300->vbo,
+ r300->vertex_info.vinfo.size);
+ /* Set the pointer to our vertex buffer. The emitted values are this:
+ * PACKET3 [3D_LOAD_VBPNTR]
+ * COUNT [1]
+ * FORMAT [size | stride << 8]
+ * OFFSET [offset into BO]
+ * VBPNTR [relocated BO]
+ */
+ BEGIN_CS(7);
+ OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
+ OUT_CS(1);
+ OUT_CS(r300->vertex_info.vinfo.size |
+ (r300->vertex_info.vinfo.size << 8));
+ OUT_CS(r300->vbo_offset);
+ OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
+}
+
void r300_emit_vertex_format_state(struct r300_context* r300)
{
int i;
@@ -305,22 +366,22 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
OUT_CS(r300->vertex_info.vinfo.hwfmt[2]);
OUT_CS(r300->vertex_info.vinfo.hwfmt[3]);
- for (i = 0; i < 4; i++) {
- debug_printf("hwfmt%d: 0x%08x\n", i,
- r300->vertex_info.vinfo.hwfmt[i]);
- }
+ /* for (i = 0; i < 4; i++) {
+ * debug_printf("hwfmt%d: 0x%08x\n", i,
+ * r300->vertex_info.vinfo.hwfmt[i]);
+ * } */
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
for (i = 0; i < 8; i++) {
OUT_CS(r300->vertex_info.vap_prog_stream_cntl[i]);
- debug_printf("prog_stream_cntl%d: 0x%08x\n", i,
- r300->vertex_info.vap_prog_stream_cntl[i]);
+ /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i,
+ * r300->vertex_info.vap_prog_stream_cntl[i]); */
}
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
for (i = 0; i < 8; i++) {
OUT_CS(r300->vertex_info.vap_prog_stream_cntl_ext[i]);
- debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i,
- r300->vertex_info.vap_prog_stream_cntl_ext[i]);
+ /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i,
+ * r300->vertex_info.vap_prog_stream_cntl_ext[i]); */
}
END_CS;
}
@@ -340,14 +401,23 @@ void r300_emit_vertex_shader(struct r300_context* r300,
return;
}
- BEGIN_CS(13 + (vs->instruction_count * 4) + (constants->count * 4));
+ if (constants->count) {
+ BEGIN_CS(14 + (vs->instruction_count * 4) + (constants->count * 4));
+ } else {
+ BEGIN_CS(11 + (vs->instruction_count * 4));
+ }
- OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, R300_PVS_FIRST_INST(0) |
+ /* R300_VAP_PVS_CODE_CNTL_0
+ * R300_VAP_PVS_CONST_CNTL
+ * R300_VAP_PVS_CODE_CNTL_1
+ * See the r5xx docs for instructions on how to use these.
+ * XXX these could be optimized to select better values... */
+ OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
+ OUT_CS(R300_PVS_FIRST_INST(0) |
+ R300_PVS_XYZW_VALID_INST(vs->instruction_count - 1) |
R300_PVS_LAST_INST(vs->instruction_count - 1));
- OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, vs->instruction_count - 1);
-
- /* XXX */
- OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x0);
+ OUT_CS(R300_PVS_MAX_CONST_ADDR(constants->count - 1));
+ OUT_CS(vs->instruction_count - 1);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4);
@@ -377,7 +447,6 @@ void r300_emit_vertex_shader(struct r300_context* r300,
R300_PVS_VF_MAX_VTX_NUM(12));
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
END_CS;
-
}
void r300_emit_viewport_state(struct r300_context* r300,
@@ -394,7 +463,11 @@ void r300_emit_viewport_state(struct r300_context* r300,
OUT_CS_32F(viewport->zscale);
OUT_CS_32F(viewport->zoffset);
- OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+ if (r300->rs_state->enable_vte) {
+ OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+ } else {
+ OUT_CS_REG(R300_VAP_VTE_CNTL, 0);
+ }
END_CS;
}
@@ -412,16 +485,67 @@ void r300_flush_textures(struct r300_context* r300)
void r300_emit_dirty_state(struct r300_context* r300)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- int i;
- int dirty_tex = 0;
+ struct r300_texture* tex;
+ int i, dirty_tex = 0;
+ boolean invalid = FALSE;
- if (!(r300->dirty_state) && !(r300->dirty_hw)) {
+ if (!(r300->dirty_state)) {
return;
}
r300_update_derived_state(r300);
/* XXX check size */
+validate:
+ /* Color buffers... */
+ for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
+ tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture;
+ assert(tex && tex->buffer && "cbuf is marked, but NULL!");
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ }
+ /* ...depth buffer... */
+ if (r300->framebuffer_state.zsbuf) {
+ tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture;
+ assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ }
+ /* ...textures... */
+ for (i = 0; i < r300->texture_count; i++) {
+ tex = r300->textures[i];
+ assert(tex && tex->buffer && "texture is marked, but NULL!");
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ }
+ /* ...and vertex buffer. */
+ if (r300->vbo) {
+ if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ } else {
+ debug_printf("No VBO while emitting dirty state!\n");
+ }
+ if (r300->winsys->validate(r300->winsys)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ /* Well, hell. */
+ exit(1);
+ }
+ invalid = TRUE;
+ goto validate;
+ }
if (r300->dirty_state & R300_NEW_BLEND) {
r300_emit_blend_state(r300, r300->blend_state);
@@ -433,6 +557,11 @@ void r300_emit_dirty_state(struct r300_context* r300)
r300->dirty_state &= ~R300_NEW_BLEND_COLOR;
}
+ if (r300->dirty_state & R300_NEW_CLIP) {
+ r300_emit_clip_state(r300, &r300->clip_state);
+ r300->dirty_state &= ~R300_NEW_CLIP;
+ }
+
if (r300->dirty_state & R300_NEW_DSA) {
r300_emit_dsa_state(r300, r300->dsa_state);
r300->dirty_state &= ~R300_NEW_DSA;
@@ -502,4 +631,14 @@ void r300_emit_dirty_state(struct r300_context* r300)
r300_emit_vertex_format_state(r300);
r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;
}
+
+ if (r300->dirty_state & R300_NEW_VERTEX_SHADER) {
+ r300_emit_vertex_shader(r300, r300->vs);
+ r300->dirty_state &= ~R300_NEW_VERTEX_SHADER;
+ }
+
+ /* Finally, emit the VBO. */
+ r300_emit_vertex_buffer(r300);
+
+ r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index 31dbc7ab85..946f625bd8 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -36,6 +36,9 @@ void r300_emit_blend_state(struct r300_context* r300,
void r300_emit_blend_color_state(struct r300_context* r300,
struct r300_blend_color_state* bc);
+void r300_emit_clip_state(struct r300_context* r300,
+ struct pipe_clip_state* clip);
+
void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa);
@@ -62,6 +65,8 @@ void r300_emit_scissor_state(struct r300_context* r300,
void r300_emit_texture(struct r300_context* r300,
struct r300_texture* tex, unsigned offset);
+void r300_emit_vertex_buffer(struct r300_context* r300);
+
void r300_emit_vertex_format_state(struct r300_context* r300);
void r300_emit_vertex_shader(struct r300_context* r300,
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 20ca6905ad..89a5f2b20c 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -29,6 +29,8 @@ static void r300_flush(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
CS_LOCALS(r300);
+ draw_flush(r300->draw);
+
if (r300->dirty_hw) {
FLUSH_CS;
r300_emit_invariant_state(r300);
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 660816e1da..3bb9bc47b5 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -511,11 +511,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_PVS_XYZW_VALID_INST_SHIFT 10
# define R300_PVS_LAST_INST_SHIFT 20
# define R300_PVS_FIRST_INST(x) ((x) << 0)
+# define R300_PVS_XYZW_VALID_INST(x) ((x) << 10)
# define R300_PVS_LAST_INST(x) ((x) << 20)
/* Addresses are relative the the vertex program parameters area. */
#define R300_VAP_PVS_CONST_CNTL 0x22D4
# define R300_PVS_CONST_BASE_OFFSET_SHIFT 0
# define R300_PVS_MAX_CONST_ADDR_SHIFT 16
+# define R300_PVS_MAX_CONST_ADDR(x) ((x) << 16)
#define R300_VAP_PVS_CODE_CNTL_1 0x22D8
# define R300_PVS_LAST_VTX_SRC_INST_SHIFT 0
#define R300_VAP_PVS_FLOW_CNTL_OPC 0x22DC
@@ -3040,6 +3042,7 @@ enum {
# define R500_INST_RGB_WMASK_R (1 << 11)
# define R500_INST_RGB_WMASK_G (1 << 12)
# define R500_INST_RGB_WMASK_B (1 << 13)
+# define R500_INST_RGB_WMASK_RGB (7 << 11)
# define R500_INST_ALPHA_WMASK (1 << 14)
# define R500_INST_RGB_OMASK_R (1 << 15)
# define R500_INST_RGB_OMASK_G (1 << 16)
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index b7ee8fb8a9..cd458d019a 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -45,11 +45,7 @@ struct r300_render {
/* VBO */
struct pipe_buffer* vbo;
- size_t vbo_size;
- size_t vbo_offset;
- void* vbo_map;
size_t vbo_alloc_size;
- size_t vbo_max_used;
};
static INLINE struct r300_render*
@@ -78,24 +74,21 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
struct pipe_screen* screen = r300->context.screen;
size_t size = (size_t)vertex_size * (size_t)count;
- if (r300render->vbo) {
+ if (r300render->vbo && (size > r300render->vbo_alloc_size)) {
pipe_buffer_reference(&r300render->vbo, NULL);
}
+
+ if (!r300render->vbo) {
+ r300render->vbo = pipe_buffer_create(screen,
+ 64,
+ PIPE_BUFFER_USAGE_VERTEX,
+ size);
+ }
- r300render->vbo_size = MAX2(size, r300render->vbo_alloc_size);
- r300render->vbo_offset = 0;
- r300render->vbo = pipe_buffer_create(screen,
- 64,
- PIPE_BUFFER_USAGE_VERTEX,
- r300render->vbo_size);
-
+ r300render->vbo_alloc_size = MAX2(size, r300render->vbo_alloc_size);
r300render->vertex_size = vertex_size;
- if (r300render->vbo) {
- return TRUE;
- } else {
- return FALSE;
- }
+ return (r300render->vbo) ? TRUE : FALSE;
}
static void* r300_render_map_vertices(struct vbuf_render* render)
@@ -103,10 +96,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render)
struct r300_render* r300render = r300_render(render);
struct pipe_screen* screen = r300render->r300->context.screen;
- r300render->vbo_map = pipe_buffer_map(screen, r300render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
-
- return (unsigned char*)r300render->vbo_map + r300render->vbo_offset;
+ return (unsigned char*)pipe_buffer_map(screen, r300render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
}
static void r300_render_unmap_vertices(struct vbuf_render* render,
@@ -116,9 +107,6 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
struct r300_render* r300render = r300_render(render);
struct pipe_screen* screen = r300render->r300->context.screen;
- r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
- r300render->vertex_size * (max + 1));
-
pipe_buffer_unmap(screen, r300render->vbo);
}
@@ -180,27 +168,9 @@ static void prepare_render(struct r300_render* render, unsigned count)
CS_LOCALS(r300);
- /* Make sure that all possible state is emitted. */
- r300_emit_dirty_state(r300);
+ r300->vbo = render->vbo;
- debug_printf("r300: Preparing vertex buffer %p for render, "
- "vertex size %d, vertex count %d\n", render->vbo,
- r300->vertex_info.vinfo.size, count);
- /* Set the pointer to our vertex buffer. The emitted values are this:
- * PACKET3 [3D_LOAD_VBPNTR]
- * COUNT [1]
- * FORMAT [size | stride << 8]
- * OFFSET [0]
- * VBPNTR [relocated BO]
- */
- BEGIN_CS(7);
- OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
- OUT_CS(1);
- OUT_CS(r300->vertex_info.vinfo.size |
- (r300->vertex_info.vinfo.size << 8));
- OUT_CS(render->vbo_offset);
- OUT_CS_RELOC(render->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
- END_CS;
+ r300_emit_dirty_state(r300);
}
static void r300_render_draw_arrays(struct vbuf_render* render,
@@ -212,8 +182,6 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
- r300render->vbo_offset = start;
-
prepare_render(r300render, count);
debug_printf("r300: Doing vbuf render, count %d\n", count);
@@ -234,6 +202,8 @@ static void r300_render_draw(struct vbuf_render* render,
struct pipe_screen* screen = r300->context.screen;
struct pipe_buffer* index_buffer;
void* index_map;
+ int i;
+ uint32_t index;
CS_LOCALS(r300);
@@ -246,6 +216,7 @@ static void r300_render_draw(struct vbuf_render* render,
return;
}
+/*
index_map = pipe_buffer_map(screen, index_buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
memcpy(index_map, indices, count);
@@ -253,13 +224,25 @@ static void r300_render_draw(struct vbuf_render* render,
debug_printf("r300: Doing indexbuf render, count %d\n", count);
- BEGIN_CS(6);
+ BEGIN_CS(8);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300render->hwprim);
OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2));
OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS; */
+
+ BEGIN_CS(2 + (count+1)/2);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
+ r300render->hwprim);
+ for (i = 0; i < count-1; i += 2) {
+ OUT_CS(indices[i+1] << 16 | indices[i]);
+ }
+ if (count % 2) {
+ OUT_CS(indices[count-1]);
+ }
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index d2c5998c26..a6f1efe356 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -87,23 +87,25 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
} else {
return 0;
}
- return 0;
case PIPE_CAP_GLSL:
- /* IN THEORY */
- return 0;
+ if (r300screen->caps->is_r500) {
+ return 1;
+ } else {
+ return 0;
+ }
case PIPE_CAP_S3TC:
/* IN THEORY */
return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
- /* IN THEORY */
- return 0;
+ return 1;
case PIPE_CAP_POINT_SPRITE:
/* IN THEORY */
return 0;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 4;
case PIPE_CAP_OCCLUSION_QUERY:
- return 1;
+ /* IN THEORY */
+ return 0;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
/* IN THEORY */
return 0;
@@ -152,17 +154,20 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
static float r300_get_paramf(struct pipe_screen* pscreen, int param)
{
+ struct r300_screen* r300screen = r300_screen(pscreen);
+
switch (param) {
case PIPE_CAP_MAX_LINE_WIDTH:
case PIPE_CAP_MAX_LINE_WIDTH_AA:
- /* XXX this is the biggest thing that will fit in that register.
- * Perhaps the actual rendering limits are less? */
- return 10922.0f;
case PIPE_CAP_MAX_POINT_WIDTH:
case PIPE_CAP_MAX_POINT_WIDTH_AA:
- /* XXX this is the biggest thing that will fit in that register.
- * Perhaps the actual rendering limits are less? */
- return 10922.0f;
+ /* The maximum dimensions of the colorbuffer are our practical
+ * rendering limits. 2048 pixels should be enough for anybody. */
+ if (r300screen->caps->is_r500) {
+ return 4096.0f;
+ } else {
+ return 2048.0f;
+ }
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
return 16.0f;
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
@@ -230,9 +235,16 @@ static boolean r300_is_format_supported(struct pipe_screen* pscreen,
case PIPE_TEXTURE_2D:
return check_tex_2d_format(format,
r300_screen(pscreen)->caps->is_r500);
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_3D:
+ case PIPE_TEXTURE_CUBE:
+ debug_printf("r300: Implementation error: Unsupported format "
+ "target: %d\n", target);
+ break;
default:
- debug_printf("r300: Warning: Got unknown format target: %d\n",
- format);
+ debug_printf("r300: Fatal: This is not a format target: %d\n",
+ target);
+ assert(0);
break;
}
@@ -337,7 +349,6 @@ struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)
return NULL;
caps->pci_id = r300_winsys->pci_id;
- caps->num_frag_pipes = r300_winsys->gb_pipes;
r300_parse_chipset(caps);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 2a77fd1739..01e2b51153 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -62,8 +62,6 @@ static void* r300_create_blend_state(struct pipe_context* pipe,
}
/* PIPE_LOGICOP_* don't need to be translated, fortunately. */
- /* XXX are logicops still allowed if blending's disabled?
- * Does Gallium take care of it for us? */
if (state->logicop_enable) {
blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE |
(state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT;
@@ -121,9 +119,14 @@ static void r300_set_clip_state(struct pipe_context* pipe,
const struct pipe_clip_state* state)
{
struct r300_context* r300 = r300_context(pipe);
- /* XXX Draw */
- draw_flush(r300->draw);
- draw_set_clip_state(r300->draw, state);
+
+ if (r300_screen(pipe->screen)->caps->has_tcl) {
+ r300->clip_state = *state;
+ r300->dirty_state |= R300_NEW_CLIP;
+ } else {
+ draw_flush(r300->draw);
+ draw_set_clip_state(r300->draw, state);
+ }
}
static void
@@ -153,10 +156,12 @@ static void
/* If the number of constants have changed, invalidate the shader. */
if (r300->shader_constants[shader].user_count != i) {
- if (shader == PIPE_SHADER_FRAGMENT && r300->fs) {
+ if (shader == PIPE_SHADER_FRAGMENT && r300->fs &&
+ r300->fs->uses_imms) {
r300->fs->translated = FALSE;
r300_translate_fragment_shader(r300, r300->fs);
- } else if (shader == PIPE_SHADER_VERTEX && r300->vs) {
+ } else if (shader == PIPE_SHADER_VERTEX && r300->vs &&
+ r300->vs->uses_imms) {
r300->vs->translated = FALSE;
r300_translate_vertex_shader(r300, r300->vs);
}
@@ -257,6 +262,7 @@ static void r300_set_edgeflags(struct pipe_context* pipe,
const unsigned* bitfield)
{
/* XXX you know it's bad when i915 has this blank too */
+ /* XXX and even worse, I have no idea WTF the bitfield is */
}
static void
@@ -289,6 +295,7 @@ static void* r300_create_fs_state(struct pipe_context* pipe,
/* Copy state directly into shader. */
fs->state = *shader;
+ fs->state.tokens = tgsi_dup_tokens(shader->tokens);
tgsi_scan_shader(shader->tokens, &fs->info);
@@ -317,13 +324,15 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
/* Delete fragment shader state. */
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
{
+ struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader;
+ FREE(fs->state.tokens);
FREE(shader);
}
static void r300_set_polygon_stipple(struct pipe_context* pipe,
const struct pipe_poly_stipple* state)
{
- /* XXX */
+ /* XXX no idea how to set this up, but not terribly important */
}
/* Create a new rasterizer state based on the CSO rasterizer state.
@@ -341,6 +350,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
/* Copy rasterizer state for Draw. */
rs->rs = *state;
+ rs->enable_vte = !state->bypass_vs_clip_and_viewport;
+
/* If bypassing TCL, or if no TCL engine is present, turn off the HW TCL.
* Else, enable HW TCL and force Draw's TCL off. */
if (state->bypass_vs_clip_and_viewport ||
@@ -421,6 +432,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
struct r300_context* r300 = r300_context(pipe);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ draw_flush(r300->draw);
draw_set_rasterizer_state(r300->draw, &rs->rs);
r300->rs_state = rs;
@@ -528,7 +540,6 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
const struct pipe_scissor_state* state)
{
struct r300_context* r300 = r300_context(pipe);
- draw_flush(r300->draw);
if (r300_screen(r300->context.screen)->caps->is_r500) {
r300->scissor_state->scissor_top_left =
@@ -555,25 +566,38 @@ static void r300_set_viewport_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- r300->viewport_state->xscale = state->scale[0];
- r300->viewport_state->yscale = state->scale[1];
- r300->viewport_state->zscale = state->scale[2];
-
- r300->viewport_state->xoffset = state->translate[0];
- r300->viewport_state->yoffset = state->translate[1];
- r300->viewport_state->zoffset = state->translate[2];
-
- r300->viewport_state->vte_control = 0;
- if (r300_screen(r300->context.screen)->caps->has_tcl) {
- /* Do the transform in HW. */
- r300->viewport_state->vte_control |=
- R300_VPORT_X_SCALE_ENA | R300_VPORT_X_OFFSET_ENA |
- R300_VPORT_Y_SCALE_ENA | R300_VPORT_Y_OFFSET_ENA |
- R300_VPORT_Z_SCALE_ENA | R300_VPORT_Z_OFFSET_ENA;
- } else {
- /* Have Draw do the actual transform. */
- draw_set_viewport_state(r300->draw, state);
+ /* Do the transform in HW. */
+ r300->viewport_state->vte_control = R300_VTX_W0_FMT;
+
+ if (state->scale[0] != 1.0f) {
+ assert(state->scale[0] != 0.0f);
+ r300->viewport_state->xscale = state->scale[0];
+ r300->viewport_state->vte_control |= R300_VPORT_X_SCALE_ENA;
+ }
+ if (state->scale[1] != 1.0f) {
+ assert(state->scale[1] != 0.0f);
+ r300->viewport_state->yscale = state->scale[1];
+ r300->viewport_state->vte_control |= R300_VPORT_Y_SCALE_ENA;
+ }
+ if (state->scale[2] != 1.0f) {
+ assert(state->scale[2] != 0.0f);
+ r300->viewport_state->zscale = state->scale[2];
+ r300->viewport_state->vte_control |= R300_VPORT_Z_SCALE_ENA;
+ }
+ if (state->translate[0] != 0.0f) {
+ r300->viewport_state->xoffset = state->translate[0];
+ r300->viewport_state->vte_control |= R300_VPORT_X_OFFSET_ENA;
+ }
+ if (state->translate[1] != 0.0f) {
+ r300->viewport_state->yoffset = state->translate[1];
+ r300->viewport_state->vte_control |= R300_VPORT_Y_OFFSET_ENA;
}
+ if (state->translate[2] != 0.0f) {
+ r300->viewport_state->zoffset = state->translate[2];
+ r300->viewport_state->vte_control |= R300_VPORT_Z_OFFSET_ENA;
+ }
+
+ r300->dirty_state |= R300_NEW_VIEWPORT;
}
static void r300_set_vertex_buffers(struct pipe_context* pipe,
@@ -610,6 +634,7 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader);
/* Copy state directly into shader. */
vs->state = *shader;
+ vs->state.tokens = tgsi_dup_tokens(shader->tokens);
tgsi_scan_shader(shader->tokens, &vs->info);
@@ -626,6 +651,8 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader)
{
struct r300_context* r300 = r300_context(pipe);
+ draw_flush(r300->draw);
+
if (r300_screen(pipe->screen)->caps->has_tcl) {
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
@@ -653,6 +680,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
draw_delete_vertex_shader(r300->draw, vs->draw);
+ FREE(vs->state.tokens);
FREE(shader);
} else {
draw_delete_vertex_shader(r300->draw,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index f1feafbcf9..2477b30822 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -25,62 +25,88 @@
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
-/* Update the vertex_info struct in our r300_context.
- *
- * The vertex_info struct describes the post-TCL format of vertices. It is
- * required for Draw when doing SW TCL, and also for describing the
- * dreaded RS block on R300 chipsets. */
-static void r300_update_vertex_layout(struct r300_context* r300)
+/* Set up the vs_tab and routes. */
+static void r300_vs_tab_routes(struct r300_context* r300,
+ struct r300_vertex_format* vformat)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_vertex_format vformat;
- struct vertex_info vinfo;
+ struct vertex_info* vinfo = &vformat->vinfo;
+ int* tab = vformat->vs_tab;
boolean pos = FALSE, psize = FALSE, fog = FALSE;
int i, texs = 0, cols = 0;
- int tab[16];
-
- struct tgsi_shader_info* info = &r300->fs->info;
+ struct tgsi_shader_info* info;
- memset(&vinfo, 0, sizeof(vinfo));
- for (i = 0; i < 16; i++) {
- tab[i] = -1;
+ if (r300screen->caps->has_tcl) {
+ /* Use vertex shader to determine required routes. */
+ info = &r300->vs->info;
+ } else {
+ /* Use fragment shader to determine required routes. */
+ info = &r300->fs->info;
}
assert(info->num_inputs <= 16);
- for (i = 0; i < info->num_inputs; i++) {
- switch (info->input_semantic_name[i]) {
- case TGSI_SEMANTIC_POSITION:
- pos = TRUE;
- tab[i] = 0;
- break;
- case TGSI_SEMANTIC_COLOR:
- tab[i] = 2 + cols++;
- break;
- case TGSI_SEMANTIC_PSIZE:
- psize = TRUE;
- tab[i] = 1;
- break;
- case TGSI_SEMANTIC_FOG:
- fog = TRUE;
- /* Fall through... */
- case TGSI_SEMANTIC_GENERIC:
- tab[i] = 6 + texs++;
- break;
- default:
- debug_printf("r300: Unknown vertex input %d\n",
- info->input_semantic_name[i]);
- break;
- }
- }
-
if (r300screen->caps->has_tcl) {
+ /* Just copy vert attribs over as-is. */
for (i = 0; i < info->num_inputs; i++) {
- /* XXX should probably do real lookup with vert shader */
tab[i] = i;
}
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ pos = TRUE;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ cols++;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ psize = TRUE;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ fog = TRUE;
+ /* Fall through */
+ case TGSI_SEMANTIC_GENERIC:
+ texs++;
+ break;
+ default:
+ debug_printf("r300: Unknown vertex output %d\n",
+ info->output_semantic_name[i]);
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ pos = TRUE;
+ tab[i] = 0;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ tab[i] = 2 + cols;
+ cols++;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ psize = TRUE;
+ tab[i] = 15;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ fog = TRUE;
+ /* Fall through */
+ case TGSI_SEMANTIC_GENERIC:
+ tab[i] = 6 + texs;
+ texs++;
+ break;
+ default:
+ debug_printf("r300: Unknown vertex input %d\n",
+ info->input_semantic_name[i]);
+ break;
+ }
+ }
}
+ /* XXX magic */
+ assert(texs <= 8);
+
/* Do the actual vertex_info setup.
*
* vertex_info has four uints of hardware-specific data in it.
@@ -89,7 +115,7 @@ static void r300_update_vertex_layout(struct r300_context* r300)
* vinfo.hwfmt[2] is R300_VAP_OUTPUT_VTX_FMT_0
* vinfo.hwfmt[3] is R300_VAP_OUTPUT_VTX_FMT_1 */
- vinfo.hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
+ vinfo->hwfmt[0] = 0x5555; /* XXX this is classic Mesa bonghits */
if (!pos) {
debug_printf("r300: Forcing vertex position attribute emit...\n");
@@ -99,109 +125,223 @@ static void r300_update_vertex_layout(struct r300_context* r300)
tab[i] = tab[i-1];
}
tab[0] = 0;
-
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_POS,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
- } else {
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
}
- vinfo.hwfmt[1] |= R300_INPUT_CNTL_POS;
- vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+ draw_find_vs_output(r300->draw, TGSI_SEMANTIC_POSITION, 0));
+ vinfo->hwfmt[1] |= R300_INPUT_CNTL_POS;
+ vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT;
if (psize) {
- draw_emit_vertex_attr(&vinfo, EMIT_1F_PSIZE, INTERP_POS,
+ draw_emit_vertex_attr(vinfo, EMIT_1F_PSIZE, INTERP_POS,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_PSIZE, 0));
- vinfo.hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
+ vinfo->hwfmt[2] |= R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT;
}
for (i = 0; i < cols; i++) {
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR,
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_LINEAR,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_COLOR, i));
- vinfo.hwfmt[1] |= R300_INPUT_CNTL_COLOR;
- vinfo.hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
+ vinfo->hwfmt[1] |= R300_INPUT_CNTL_COLOR;
+ vinfo->hwfmt[2] |= (R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << i);
}
- for (i = 0; i < texs; i++) {
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
- draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
- vinfo.hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
- vinfo.hwfmt[3] |= (4 << (3 * i));
- }
+ /* Init i right here, increment it if fog is enabled.
+ * This gets around a double-increment problem. */
+ i = 0;
if (fog) {
i++;
- draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
draw_find_vs_output(r300->draw, TGSI_SEMANTIC_FOG, 0));
- vinfo.hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
- vinfo.hwfmt[3] |= (4 << (3 * i));
+ vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
+ vinfo->hwfmt[3] |= (4 << (3 * i));
+ }
+
+ for (i; i < texs; i++) {
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE,
+ draw_find_vs_output(r300->draw, TGSI_SEMANTIC_GENERIC, i));
+ vinfo->hwfmt[1] |= (R300_INPUT_CNTL_TC0 << i);
+ vinfo->hwfmt[3] |= (4 << (3 * i));
}
- draw_compute_vertex_size(&vinfo);
+ /* Handle the case where the vertex shader will be generating some of
+ * the attribs based on its inputs. */
+ if (r300screen->caps->has_tcl &&
+ info->num_inputs < info->num_outputs) {
+ vinfo->num_attribs = info->num_inputs;
+ }
- if (memcmp(&r300->vertex_info, &vinfo, sizeof(struct vertex_info))) {
- uint32_t temp;
- debug_printf("attrib count: %d, fp input count: %d\n",
- vinfo.num_attribs, info->num_inputs);
- for (i = 0; i < vinfo.num_attribs; i++) {
- debug_printf("attrib: offset %d, interp %d, size %d,"
- " tab %d\n", vinfo.attrib[i].src_index,
- vinfo.attrib[i].interp_mode, vinfo.attrib[i].emit,
+ draw_compute_vertex_size(vinfo);
+}
+
+/* Update the PSC tables. */
+static void r300_vertex_psc(struct r300_context* r300,
+ struct r300_vertex_format* vformat)
+{
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ struct vertex_info* vinfo = &vformat->vinfo;
+ int* tab = vformat->vs_tab;
+ uint32_t temp;
+ int i, attrib_count;
+
+ /* Vertex shaders have no semantics on their inputs,
+ * so PSC should just route stuff based on their info,
+ * and not on attrib information. */
+ if (r300screen->caps->has_tcl) {
+ attrib_count = r300->vs->info.num_inputs;
+ debug_printf("r300: routing %d attribs in psc for vs\n",
+ attrib_count);
+ } else {
+ attrib_count = vinfo->num_attribs;
+ debug_printf("r300: attrib count: %d\n", attrib_count);
+ for (i = 0; i < attrib_count; i++) {
+ debug_printf("r300: attrib: offset %d, interp %d, size %d,"
+ " tab %d\n", vinfo->attrib[i].src_index,
+ vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
tab[i]);
}
+ }
- for (i = 0; i < vinfo.num_attribs; i++) {
- /* Make sure we have a proper destination for our attribute */
- assert(tab[i] != -1);
+ for (i = 0; i < attrib_count; i++) {
+ /* Make sure we have a proper destination for our attribute */
+ assert(tab[i] != -1);
- temp = translate_vertex_data_type(vinfo.attrib[i].emit) |
- (tab[i] << R300_DST_VEC_LOC_SHIFT);
- if (i & 1) {
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= temp << 16;
- } else {
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] &= 0xffff0000;
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= temp;
- }
+ /* Add the attribute to the PSC table. */
+ temp = r300screen->caps->has_tcl ?
+ R300_DATA_TYPE_FLOAT_4 :
+ translate_vertex_data_type(vinfo->attrib[i].emit);
+ temp |= tab[i] << R300_DST_VEC_LOC_SHIFT;
+
+ if (i & 1) {
+ vformat->vap_prog_stream_cntl[i >> 1] &= 0x0000ffff;
+ vformat->vap_prog_stream_cntl[i >> 1] |= temp << 16;
- r300->vertex_info.vap_prog_stream_cntl_ext[i >> 1] |=
- (R300_VAP_SWIZZLE_XYZW << (i & 1 ? 16 : 0));
+ vformat->vap_prog_stream_cntl_ext[i >> 1] |=
+ (R300_VAP_SWIZZLE_XYZW << 16);
+ } else {
+ vformat->vap_prog_stream_cntl[i >> 1] &= 0xffff0000;
+ vformat->vap_prog_stream_cntl[i >> 1] |= temp << 0;
+
+ vformat->vap_prog_stream_cntl_ext[i >> 1] |=
+ (R300_VAP_SWIZZLE_XYZW << 0);
}
- /* Set the last vector. */
- i--;
- r300->vertex_info.vap_prog_stream_cntl[i >> 1] |= (R300_LAST_VEC <<
- (i & 1 ? 16 : 0));
+ }
- memcpy(r300->vertex_info.tab, tab, sizeof(tab));
- memcpy(&r300->vertex_info, &vinfo, sizeof(struct vertex_info));
+ /* Set the last vector in the PSC. */
+ i--;
+ vformat->vap_prog_stream_cntl[i >> 1] |=
+ (R300_LAST_VEC << (i & 1 ? 16 : 0));
+}
+
+/* Update the vertex format. */
+static void r300_update_vertex_format(struct r300_context* r300)
+{
+ struct r300_vertex_format vformat;
+ int i;
+
+ memset(&vformat, 0, sizeof(struct r300_vertex_format));
+ for (i = 0; i < 16; i++) {
+ vformat.vs_tab[i] = -1;
+ vformat.fs_tab[i] = -1;
+ }
+
+ r300_vs_tab_routes(r300, &vformat);
+
+ r300_vertex_psc(r300, &vformat);
+
+ if (memcmp(&r300->vertex_info, &vformat,
+ sizeof(struct r300_vertex_format))) {
+ memcpy(&r300->vertex_info, &vformat,
+ sizeof(struct r300_vertex_format));
r300->dirty_state |= R300_NEW_VERTEX_FORMAT;
}
}
+/* Set up the mappings from GB to US, for RS block. */
+static void r300_update_fs_tab(struct r300_context* r300)
+{
+ struct r300_vertex_format* vformat = &r300->vertex_info;
+ struct tgsi_shader_info* info = &r300->fs->info;
+ int i, cols = 0, texs = 0, cols_emitted = 0;
+ int* tab = vformat->fs_tab;
+
+ for (i = 0; i < 16; i++) {
+ tab[i] = -1;
+ }
+
+ assert(info->num_inputs <= 16);
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ tab[i] = INTERP_LINEAR;
+ cols++;
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ case TGSI_SEMANTIC_PSIZE:
+ debug_printf("r300: Implementation error: Can't use "
+ "pos attribs in fragshader yet!\n");
+ /* Pass through for now */
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ tab[i] = INTERP_PERSPECTIVE;
+ break;
+ default:
+ debug_printf("r300: Unknown vertex input %d\n",
+ info->input_semantic_name[i]);
+ break;
+ }
+ }
+
+ /* Now that we know where everything is... */
+ debug_printf("r300: fp input count: %d\n", info->num_inputs);
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (tab[i]) {
+ case INTERP_LINEAR:
+ debug_printf("r300: attrib: "
+ "stack offset %d, color, tab %d\n",
+ i, cols_emitted);
+ tab[i] = cols_emitted;
+ cols_emitted++;
+ break;
+ case INTERP_PERSPECTIVE:
+ debug_printf("r300: attrib: "
+ "stack offset %d, texcoord, tab %d\n",
+ i, cols + texs);
+ tab[i] = cols + texs;
+ texs++;
+ break;
+ case -1:
+ debug_printf("r300: Implementation error: Bad fp interp!\n");
+ default:
+ break;
+ }
+ }
+
+}
+
/* Set up the RS block. This is the part of the chipset that actually does
* the rasterization of vertices into fragments. This is also the part of the
* chipset that locks up if any part of it is even slightly wrong. */
static void r300_update_rs_block(struct r300_context* r300)
{
struct r300_rs_block* rs = r300->rs_block;
- struct vertex_info* vinfo = &r300->vertex_info.vinfo;
- int* tab = r300->vertex_info.tab;
+ struct tgsi_shader_info* info = &r300->fs->info;
+ int* tab = r300->vertex_info.fs_tab;
int col_count = 0, fp_offset = 0, i, memory_pos, tex_count = 0;
memset(rs, 0, sizeof(struct r300_rs_block));
if (r300_screen(r300->context.screen)->caps->is_r500) {
- for (i = 0; i < vinfo->num_attribs; i++) {
- assert(tab[vinfo->attrib[i].src_index] != -1);
- memory_pos = tab[vinfo->attrib[i].src_index] * 4;
- switch (vinfo->attrib[i].interp_mode) {
- case INTERP_LINEAR:
+ for (i = 0; i < info->num_inputs; i++) {
+ assert(tab[i] != -1);
+ memory_pos = tab[i] * 4;
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
rs->ip[col_count] |=
R500_RS_COL_PTR(memory_pos) |
R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
col_count++;
break;
- case INTERP_PERSPECTIVE:
+ case TGSI_SEMANTIC_GENERIC:
rs->ip[tex_count] |=
R500_RS_SEL_S(memory_pos) |
R500_RS_SEL_T(memory_pos + 1) |
@@ -243,17 +383,17 @@ static void r300_update_rs_block(struct r300_context* r300)
fp_offset++;
}
} else {
- for (i = 0; i < vinfo->num_attribs; i++) {
- memory_pos = tab[vinfo->attrib[i].src_index] * 4;
- assert(tab[vinfo->attrib[i].src_index] != -1);
- switch (vinfo->attrib[i].interp_mode) {
- case INTERP_LINEAR:
+ for (i = 0; i < info->num_inputs; i++) {
+ assert(tab[i] != -1);
+ memory_pos = tab[i] * 4;
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
rs->ip[col_count] |=
R300_RS_COL_PTR(memory_pos) |
R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
col_count++;
break;
- case INTERP_PERSPECTIVE:
+ case TGSI_SEMANTIC_GENERIC:
rs->ip[tex_count] |=
R300_RS_TEX_PTR(memory_pos) |
R300_RS_SEL_S(R300_RS_SEL_C0) |
@@ -307,10 +447,11 @@ void r300_update_derived_state(struct r300_context* r300)
{
if (r300->dirty_state &
(R300_NEW_FRAGMENT_SHADER | R300_NEW_VERTEX_SHADER)) {
- r300_update_vertex_layout(r300);
+ r300_update_vertex_format(r300);
}
if (r300->dirty_state & R300_NEW_VERTEX_FORMAT) {
+ r300_update_fs_tab(r300);
r300_update_rs_block(r300);
}
}
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 91b93fc367..22c8e199ae 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -353,25 +353,6 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)
/* Non-CSO state. (For now.) */
-static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
-{
- switch (pipe_count) {
- case 1:
- return R300_GB_TILE_PIPE_COUNT_RV300;
- break;
- case 2:
- return R300_GB_TILE_PIPE_COUNT_R300;
- break;
- case 3:
- return R300_GB_TILE_PIPE_COUNT_R420_3P;
- break;
- case 4:
- return R300_GB_TILE_PIPE_COUNT_R420;
- break;
- }
- return 0;
-}
-
static INLINE uint32_t translate_vertex_data_type(int type) {
switch (type) {
case EMIT_1F:
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 8bd9b41bd7..e438114010 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -34,36 +34,19 @@ void r300_emit_invariant_state(struct r300_context* r300)
struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
CS_LOCALS(r300);
- BEGIN_CS(30 + (caps->has_tcl ? 2: 0));
+ BEGIN_CS(26 + (caps->has_tcl ? 2: 0));
/*** Graphics Backend (GB) ***/
/* Various GB enables */
OUT_CS_REG(R300_GB_ENABLE, 0x0);
/* Subpixel multisampling for AA */
OUT_CS_REG(R300_GB_MSPOS0, 0x66666666);
- OUT_CS_REG(R300_GB_MSPOS1, 0x66666666);
- /* GB tile config and pipe setup */
- OUT_CS_REG(R300_GB_TILE_CONFIG, R300_GB_TILE_DISABLE |
- r300_translate_gb_pipes(caps->num_frag_pipes));
+ OUT_CS_REG(R300_GB_MSPOS1, 0x6666666);
/* Source of fog depth */
OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W);
/* AA enable */
OUT_CS_REG(R300_GB_AA_CONFIG, 0x0);
- /*** Geometry Assembly (GA) ***/
- /* GA errata fixes. */
- if (caps->is_r500) {
- OUT_CS_REG(R300_GA_ENHANCE,
- R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL |
- R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE |
- R500_GA_ENHANCE_REG_READWRITE_ENABLE |
- R500_GA_ENHANCE_REG_NOSTALL_ENABLE);
- } else {
- OUT_CS_REG(R300_GA_ENHANCE,
- R300_GA_ENHANCE_DEADLOCK_CNTL_PREVENT_TCL |
- R300_GA_ENHANCE_FASTSYNC_CNTL_ENABLE);
- }
-
/*** Fog (FG) ***/
OUT_CS_REG(R300_FG_FOG_BLEND, 0x0);
OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x0);
@@ -86,7 +69,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(79 + (caps->has_tcl ? 7 : 0));
+ BEGIN_CS(77 + (caps->has_tcl ? 5 : 0));
/* Flush PVS. */
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
@@ -97,8 +80,6 @@ void r300_emit_invariant_state(struct r300_context* r300)
/* XXX endian */
if (caps->has_tcl) {
OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP);
- OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE |
- R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
OUT_CS_32F(1.0);
OUT_CS_32F(1.0);
@@ -113,11 +94,14 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_32F(0.0);
OUT_CS_REG_SEQ(R300_GA_POINT_S1, 1);
OUT_CS_32F(1.0);
+ /* XXX line tex stuffing */
+ OUT_CS_REG_SEQ(R300_GA_LINE_S0, 1);
+ OUT_CS_32F(0.0);
+ OUT_CS_REG_SEQ(R300_GA_LINE_S1, 1);
+ OUT_CS_32F(1.0);
OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 |
(0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT));
/* XXX this big chunk should be refactored into rs_state */
- OUT_CS_REG(R300_GA_LINE_S0, 0x00000000);
- OUT_CS_REG(R300_GA_LINE_S1, 0x3F800000);
OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000);
OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000);
OUT_CS_REG(R300_GA_POLY_MODE, 0x00000000);
@@ -144,8 +128,6 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1);
OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405);
OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F);
- /* Vertex size. */
- OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
/* XXX */
OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
diff --git a/src/gallium/drivers/r300/r300_state_shader.c b/src/gallium/drivers/r300/r300_state_shader.c
index 1b02239ee7..cc7f6a7c4b 100644
--- a/src/gallium/drivers/r300/r300_state_shader.c
+++ b/src/gallium/drivers/r300/r300_state_shader.c
@@ -22,24 +22,6 @@
#include "r300_state_shader.h"
-static void r300_copy_passthrough_shader(struct r300_fragment_shader* fs)
-{
- struct r300_fragment_shader* pt = &r300_passthrough_fragment_shader;
- fs->shader.stack_size = pt->shader.stack_size;
- fs->alu_instruction_count = pt->alu_instruction_count;
- fs->tex_instruction_count = pt->tex_instruction_count;
- fs->indirections = pt->indirections;
- fs->instructions[0] = pt->instructions[0];
-}
-
-static void r500_copy_passthrough_shader(struct r500_fragment_shader* fs)
-{
- struct r500_fragment_shader* pt = &r500_passthrough_fragment_shader;
- fs->shader.stack_size = pt->shader.stack_size;
- fs->instruction_count = pt->instruction_count;
- fs->instructions[0] = pt->instructions[0];
-}
-
static void r300_fs_declare(struct r300_fs_asm* assembler,
struct tgsi_full_declaration* decl)
{
@@ -49,6 +31,7 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,
case TGSI_SEMANTIC_COLOR:
assembler->color_count++;
break;
+ case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
assembler->tex_count++;
break;
@@ -59,6 +42,12 @@ static void r300_fs_declare(struct r300_fs_asm* assembler,
}
break;
case TGSI_FILE_OUTPUT:
+ /* Depth write. Mark the position of the output so we can
+ * identify it later. */
+ if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
+ assembler->depth_output = decl->DeclarationRange.First;
+ }
+ break;
case TGSI_FILE_CONSTANT:
break;
case TGSI_FILE_TEMPORARY:
@@ -120,6 +109,14 @@ static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
return 0;
}
+static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler,
+ struct tgsi_dst_register* dst)
+{
+ return (assembler->writes_depth &&
+ (dst->File == TGSI_FILE_OUTPUT) &&
+ (dst->Index == assembler->depth_output));
+}
+
static INLINE unsigned r500_fix_swiz(unsigned s)
{
/* For historical reasons, the swizzle values x, y, z, w, and 0 are
@@ -194,11 +191,17 @@ static INLINE uint32_t r300_alpha_op(unsigned op)
static INLINE uint32_t r500_rgba_op(unsigned op)
{
switch (op) {
+ case TGSI_OPCODE_COS:
case TGSI_OPCODE_EX2:
case TGSI_OPCODE_LG2:
case TGSI_OPCODE_RCP:
case TGSI_OPCODE_RSQ:
+ case TGSI_OPCODE_SIN:
return R500_ALU_RGBA_OP_SOP;
+ case TGSI_OPCODE_DDX:
+ return R500_ALU_RGBA_OP_MDH;
+ case TGSI_OPCODE_DDY:
+ return R500_ALU_RGBA_OP_MDV;
case TGSI_OPCODE_FRC:
return R500_ALU_RGBA_OP_FRC;
case TGSI_OPCODE_DP3:
@@ -224,6 +227,8 @@ static INLINE uint32_t r500_rgba_op(unsigned op)
static INLINE uint32_t r500_alpha_op(unsigned op)
{
switch (op) {
+ case TGSI_OPCODE_COS:
+ return R500_ALPHA_OP_COS;
case TGSI_OPCODE_EX2:
return R500_ALPHA_OP_EX2;
case TGSI_OPCODE_LG2:
@@ -234,6 +239,12 @@ static INLINE uint32_t r500_alpha_op(unsigned op)
return R500_ALPHA_OP_RSQ;
case TGSI_OPCODE_FRC:
return R500_ALPHA_OP_FRC;
+ case TGSI_OPCODE_SIN:
+ return R500_ALPHA_OP_SIN;
+ case TGSI_OPCODE_DDX:
+ return R500_ALPHA_OP_MDH;
+ case TGSI_OPCODE_DDY:
+ return R500_ALPHA_OP_MDV;
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
case TGSI_OPCODE_DPH:
@@ -295,38 +306,34 @@ static INLINE void r300_emit_maths(struct r300_fragment_shader* fs,
}
/* Setup an ALU operation. */
-static INLINE void r500_emit_alu(struct r500_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_dst_register* dst)
+static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
+ struct r300_fs_asm* assembler,
+ struct tgsi_full_src_register* src,
+ struct tgsi_full_dst_register* dst,
+ unsigned op,
+ unsigned count)
{
int i = fs->instruction_count;
if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
- fs->instructions[i].inst0 = R500_INST_TYPE_OUT |
- R500_ALU_OMASK(dst->DstRegister.WriteMask);
+ fs->instructions[i].inst0 = R500_INST_TYPE_OUT;
+ if (r300_fs_is_depr(assembler, dst)) {
+ fs->instructions[i].inst4 = R500_W_OMASK;
+ } else {
+ fs->instructions[i].inst0 |=
+ R500_ALU_OMASK(dst->DstRegister.WriteMask);
+ }
} else {
fs->instructions[i].inst0 = R500_INST_TYPE_ALU |
- R500_ALU_WMASK(dst->DstRegister.WriteMask);
+ R500_ALU_WMASK(dst->DstRegister.WriteMask);
}
fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT;
- fs->instructions[i].inst4 =
+ fs->instructions[i].inst4 |=
R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
fs->instructions[i].inst5 =
R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
-}
-
-static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count)
-{
- int i = fs->instruction_count;
-
- r500_emit_alu(fs, assembler, dst);
switch (count) {
case 3:
@@ -348,8 +355,8 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALU_RGB_SEL_B_SRC1 |
R500_SWIZ_RGB_B(r500_rgb_swiz(&src[1]));
fs->instructions[i].inst4 |=
- R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1])) |
- R500_ALPHA_SEL_B_SRC1;
+ R500_ALPHA_SEL_B_SRC1 |
+ R500_SWIZ_ALPHA_B(r500_alpha_swiz(&src[1]));
case 1:
case 0:
default:
@@ -361,8 +368,8 @@ static INLINE void r500_emit_maths(struct r500_fragment_shader* fs,
R500_ALU_RGB_SEL_A_SRC0 |
R500_SWIZ_RGB_A(r500_rgb_swiz(&src[0]));
fs->instructions[i].inst4 |=
- R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0])) |
- R500_ALPHA_SEL_A_SRC0;
+ R500_ALPHA_SEL_A_SRC0 |
+ R500_SWIZ_ALPHA_A(r500_alpha_swiz(&src[0]));
break;
}
@@ -441,6 +448,9 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
* AMD/ATI names for opcodes, please, as it facilitates using the
* documentation. */
switch (inst->Instruction.Opcode) {
+ /* XXX trig needs extra prep */
+ case TGSI_OPCODE_COS:
+ case TGSI_OPCODE_SIN:
/* The simple scalar ops. */
case TGSI_OPCODE_EX2:
case TGSI_OPCODE_LG2:
@@ -452,6 +462,8 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
/* Fall through */
+ case TGSI_OPCODE_DDX:
+ case TGSI_OPCODE_DDY:
case TGSI_OPCODE_FRC:
r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);
@@ -527,6 +539,60 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
&inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
break;
+ /* The compound and hybrid insts. */
+ case TGSI_OPCODE_LRP:
+ /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */
+ inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1];
+ inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2];
+ inst->FullSrcRegisters[0].SrcRegister.Negate =
+ !(inst->FullSrcRegisters[0].SrcRegister.Negate);
+ inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
+ inst->FullDstRegisters[0].DstRegister.Index =
+ assembler->temp_count;
+ inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
+ inst->FullSrcRegisters[2].SrcRegister.Index =
+ assembler->temp_count;
+ inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+ inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+ inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3];
+ inst->FullSrcRegisters[0].SrcRegister.Negate =
+ !(inst->FullSrcRegisters[0].SrcRegister.Negate);
+ inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
+ break;
+ case TGSI_OPCODE_POW:
+ /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
+ inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
+ inst->FullDstRegisters[0].DstRegister.Index =
+ assembler->temp_count;
+ inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);
+ inst->FullSrcRegisters[0].SrcRegister.Index =
+ assembler->temp_count;
+ inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+ inst->FullSrcRegisters[2] = r500_constant_zero;
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
+ inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
+ r500_emit_maths(fs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);
+ break;
+
/* The texture instruction set. */
case TGSI_OPCODE_KIL:
case TGSI_OPCODE_TEX:
@@ -555,7 +621,7 @@ static void r500_fs_instruction(struct r500_fragment_shader* fs,
static void r300_fs_finalize(struct r3xx_fragment_shader* fs,
struct r300_fs_asm* assembler)
{
- fs->stack_size = assembler->temp_count + assembler->temp_offset;
+ fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
}
static void r500_fs_finalize(struct r500_fragment_shader* fs,
@@ -581,6 +647,8 @@ void r300_translate_fragment_shader(struct r300_context* r300,
}
/* Setup starting offset for immediates. */
assembler->imm_offset = consts->user_count;
+ /* Enable depth writes, if needed. */
+ assembler->writes_depth = fs->info.writes_z;
/* Make sure we start at the beginning of the shader. */
if (is_r500) {
@@ -630,6 +698,7 @@ void r300_translate_fragment_shader(struct r300_context* r300,
assembler->tex_count + assembler->color_count);
consts->count = consts->user_count + assembler->imm_count;
+ fs->uses_imms = assembler->imm_count;
debug_printf("r300: fs: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
diff --git a/src/gallium/drivers/r300/r300_state_shader.h b/src/gallium/drivers/r300/r300_state_shader.h
index 185fdd90f0..b6087404ce 100644
--- a/src/gallium/drivers/r300/r300_state_shader.h
+++ b/src/gallium/drivers/r300/r300_state_shader.h
@@ -57,6 +57,7 @@
#define R500_TEX_WMASK(x) ((x) << 11)
#define R500_ALU_WMASK(x) ((x) << 11)
#define R500_ALU_OMASK(x) ((x) << 15)
+#define R500_W_OMASK (1 << 31)
/* TGSI constants. TGSI is like XML: If it can't solve your problems, you're
* not using enough of it. */
@@ -99,20 +100,17 @@ struct r300_fs_asm {
unsigned imm_offset;
/* Number of immediate constants. */
unsigned imm_count;
+ /* Are depth writes enabled? */
+ boolean writes_depth;
+ /* Depth write offset. This is the TGSI output that corresponds to
+ * depth writes. */
+ unsigned depth_output;
};
void r300_translate_fragment_shader(struct r300_context* r300,
struct r3xx_fragment_shader* fs);
static struct r300_fragment_shader r300_passthrough_fragment_shader = {
- /* XXX This is the emission code. TODO: decode
- OUT_CS_REG(R300_US_CONFIG, 0);
- OUT_CS_REG(R300_US_CODE_OFFSET, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000);
-*/
.alu_instruction_count = 1,
.tex_instruction_count = 0,
.indirections = 0,
@@ -159,14 +157,6 @@ static struct r500_fragment_shader r500_passthrough_fragment_shader = {
};
static struct r300_fragment_shader r300_texture_fragment_shader = {
- /* XXX This is the emission code. TODO: decode
- OUT_CS_REG(R300_US_CONFIG, 0);
- OUT_CS_REG(R300_US_CODE_OFFSET, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000);
-*/
.alu_instruction_count = 1,
.tex_instruction_count = 0,
.indirections = 0,
@@ -191,7 +181,7 @@ static struct r500_fragment_shader r500_texture_fragment_shader = {
.instruction_count = 2,
.instructions[0].inst0 = R500_INST_TYPE_TEX |
R500_INST_TEX_SEM_WAIT |
- R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
.instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
diff --git a/src/gallium/drivers/r300/r300_state_tcl.c b/src/gallium/drivers/r300/r300_state_tcl.c
index 47d6c6dfcd..8cf8250425 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.c
+++ b/src/gallium/drivers/r300/r300_state_tcl.c
@@ -34,11 +34,20 @@ static void r300_vs_declare(struct r300_vs_asm* assembler,
assembler->tab[decl->DeclarationRange.First] = 0;
break;
case TGSI_SEMANTIC_COLOR:
- assembler->tab[decl->DeclarationRange.First] = 2;
+ assembler->tab[decl->DeclarationRange.First] =
+ (assembler->point_size ? 1 : 0) +
+ assembler->out_colors;
break;
+ case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
/* XXX multiple? */
- assembler->tab[decl->DeclarationRange.First] = 6;
+ assembler->tab[decl->DeclarationRange.First] =
+ (assembler->point_size ? 1 : 0) +
+ assembler->out_colors +
+ assembler->out_texcoords;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ assembler->tab[decl->DeclarationRange.First] = 1;
break;
default:
debug_printf("r300: vs: Bad semantic declaration %d\n",
@@ -62,16 +71,13 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
{
switch (src->File) {
case TGSI_FILE_NULL:
- /* Probably a zero or one swizzle */
- return R300_PVS_SRC_REG_INPUT;
- break;
case TGSI_FILE_INPUT:
+ /* Probably a zero or one swizzle */
return R300_PVS_SRC_REG_INPUT;
- break;
case TGSI_FILE_TEMPORARY:
return R300_PVS_SRC_REG_TEMPORARY;
- break;
case TGSI_FILE_CONSTANT:
+ case TGSI_FILE_IMMEDIATE:
return R300_PVS_SRC_REG_CONSTANT;
default:
debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
@@ -80,16 +86,32 @@ static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
return 0;
}
+static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler,
+ struct tgsi_src_register* src)
+{
+ switch (src->File) {
+ case TGSI_FILE_NULL:
+ case TGSI_FILE_INPUT:
+ case TGSI_FILE_TEMPORARY:
+ case TGSI_FILE_CONSTANT:
+ return src->Index;
+ case TGSI_FILE_IMMEDIATE:
+ return src->Index + assembler->imm_offset;
+ default:
+ debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
+ break;
+ }
+ return 0;
+}
+
static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler,
struct tgsi_dst_register* dst)
{
switch (dst->File) {
case TGSI_FILE_TEMPORARY:
return R300_PVS_DST_REG_TEMPORARY;
- break;
case TGSI_FILE_OUTPUT:
return R300_PVS_DST_REG_OUT;
- break;
default:
debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File);
break;
@@ -103,10 +125,8 @@ static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
switch (dst->File) {
case TGSI_FILE_TEMPORARY:
return dst->Index;
- break;
case TGSI_FILE_OUTPUT:
return assembler->tab[dst->Index];
- break;
default:
debug_printf("r300: vs: Unimplemented dst %d\n", dst->File);
break;
@@ -117,12 +137,22 @@ static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
static uint32_t r300_vs_op(unsigned op)
{
switch (op) {
+ case TGSI_OPCODE_DP3:
+ case TGSI_OPCODE_DP4:
+ return R300_VE_DOT_PRODUCT;
case TGSI_OPCODE_MUL:
return R300_VE_MULTIPLY;
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_MOV:
+ case TGSI_OPCODE_SUB:
case TGSI_OPCODE_SWZ:
return R300_VE_ADD;
+ case TGSI_OPCODE_MAX:
+ return R300_VE_MAXIMUM;
+ case TGSI_OPCODE_SLT:
+ return R300_VE_SET_LESS_THAN;
+ case TGSI_OPCODE_RSQ:
+ return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX;
case TGSI_OPCODE_MAD:
return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD;
default:
@@ -134,51 +164,78 @@ static uint32_t r300_vs_op(unsigned op)
static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
{
if (reg->SrcRegister.Extended) {
- return reg->SrcRegisterExtSwz.ExtSwizzleX |
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegisterExtSwz.ExtSwizzleX |
(reg->SrcRegisterExtSwz.ExtSwizzleY << 3) |
(reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) |
(reg->SrcRegisterExtSwz.ExtSwizzleW << 9);
} else {
- return reg->SrcRegister.SwizzleX |
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegister.SwizzleX |
(reg->SrcRegister.SwizzleY << 3) |
(reg->SrcRegister.SwizzleZ << 6) |
(reg->SrcRegister.SwizzleW << 9);
}
}
+/* XXX icky icky icky icky */
+static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg)
+{
+ if (reg->SrcRegister.Extended) {
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegisterExtSwz.ExtSwizzleX |
+ (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) |
+ (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) |
+ (reg->SrcRegisterExtSwz.ExtSwizzleX << 9);
+ } else {
+ return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
+ reg->SrcRegister.SwizzleX |
+ (reg->SrcRegister.SwizzleX << 3) |
+ (reg->SrcRegister.SwizzleX << 6) |
+ (reg->SrcRegister.SwizzleX << 9);
+ }
+}
+
+/* XXX scalar stupidity */
static void r300_vs_emit_inst(struct r300_vertex_shader* vs,
struct r300_vs_asm* assembler,
struct tgsi_full_src_register* src,
struct tgsi_full_dst_register* dst,
unsigned op,
- unsigned count)
+ unsigned count,
+ boolean is_scalar)
{
int i = vs->instruction_count;
vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) |
R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) |
R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) |
- R300_PVS_DST_WE_XYZW;
+ R300_PVS_DST_WE(dst->DstRegister.WriteMask);
switch (count) {
case 3:
vs->instructions[i].inst3 =
R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
&src[2].SrcRegister)) |
- R300_PVS_SRC_OFFSET(src[2].SrcRegister.Index) |
+ R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
+ &src[2].SrcRegister)) |
R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2]));
/* Fall through */
case 2:
vs->instructions[i].inst2 =
R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
&src[1].SrcRegister)) |
- R300_PVS_SRC_OFFSET(src[1].SrcRegister.Index) |
+ R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
+ &src[1].SrcRegister)) |
R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1]));
/* Fall through */
case 1:
vs->instructions[i].inst1 =
R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
&src[0].SrcRegister)) |
- R300_PVS_SRC_OFFSET(src[0].SrcRegister.Index) |
- R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[0]));
+ R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
+ &src[0].SrcRegister)) |
+ /* XXX the icky, it burns */
+ R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0])
+ : r300_vs_swiz(&src[0]));
break;
}
vs->instruction_count++;
@@ -189,23 +246,64 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
struct tgsi_full_instruction* inst)
{
switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_RSQ:
+ r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], inst->Instruction.Opcode,
+ 1, TRUE);
+ break;
+ case TGSI_OPCODE_SUB:
+ inst->FullSrcRegisters[1].SrcRegister.Negate =
+ !inst->FullSrcRegisters[1].SrcRegister.Negate;
+ /* Fall through */
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_MUL:
+ case TGSI_OPCODE_MAX:
+ case TGSI_OPCODE_SLT:
+ r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
+ &inst->FullDstRegisters[0], inst->Instruction.Opcode,
+ 2, FALSE);
+ break;
+ case TGSI_OPCODE_DP3:
+ /* Set alpha swizzle to zero for src0 and src1 */
+ if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
+ inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
+ inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
+ }
+ inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
+ TGSI_EXTSWIZZLE_ZERO;
+ if (!inst->FullSrcRegisters[1].SrcRegister.Extended) {
+ inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE;
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX =
+ inst->FullSrcRegisters[1].SrcRegister.SwizzleX;
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY =
+ inst->FullSrcRegisters[1].SrcRegister.SwizzleY;
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ =
+ inst->FullSrcRegisters[1].SrcRegister.SwizzleZ;
+ }
+ inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW =
+ TGSI_EXTSWIZZLE_ZERO;
+ /* Fall through */
+ case TGSI_OPCODE_DP4:
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2);
+ 2, FALSE);
break;
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
inst->FullSrcRegisters[1] = r300_constant_zero;
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2);
+ 2, FALSE);
break;
case TGSI_OPCODE_MAD:
r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
&inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 3);
+ 3, FALSE);
break;
case TGSI_OPCODE_END:
break;
@@ -216,6 +314,30 @@ static void r300_vs_instruction(struct r300_vertex_shader* vs,
}
}
+static void r300_vs_init(struct r300_vertex_shader* vs,
+ struct r300_vs_asm* assembler)
+{
+ struct tgsi_shader_info* info = &vs->info;
+ int i;
+
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
+ case TGSI_SEMANTIC_PSIZE:
+ assembler->point_size = TRUE;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ assembler->out_colors++;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ assembler->out_texcoords++;
+ break;
+ }
+ }
+
+ vs->instruction_count = 0;
+}
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs)
{
@@ -228,6 +350,10 @@ void r300_translate_vertex_shader(struct r300_context* r300,
if (assembler == NULL) {
return;
}
+
+ /* Init assembler. */
+ r300_vs_init(vs, assembler);
+
/* Setup starting offset for immediates. */
assembler->imm_offset = consts->user_count;
@@ -269,6 +395,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
assembler->tex_count + assembler->color_count);
consts->count = consts->user_count + assembler->imm_count;
+ vs->uses_imms = assembler->imm_count;
debug_printf("r300: vs: %d total constants, "
"%d from user and %d from immediates\n", consts->count,
consts->user_count, assembler->imm_count);
diff --git a/src/gallium/drivers/r300/r300_state_tcl.h b/src/gallium/drivers/r300/r300_state_tcl.h
index 3d10e248e1..2c8b586c2f 100644
--- a/src/gallium/drivers/r300/r300_state_tcl.h
+++ b/src/gallium/drivers/r300/r300_state_tcl.h
@@ -32,8 +32,13 @@
/* XXX get these to r300_reg */
#define R300_PVS_DST_OPCODE(x) ((x) << 0)
+# define R300_VE_DOT_PRODUCT 1
# define R300_VE_MULTIPLY 2
# define R300_VE_ADD 3
+# define R300_VE_MAXIMUM 7
+# define R300_VE_SET_LESS_THAN 10
+#define R300_PVS_DST_MATH_INST (1 << 6)
+# define R300_ME_RECIP_DX 6
#define R300_PVS_DST_MACRO_INST (1 << 7)
# define R300_PVS_MACRO_OP_2CLK_MADD 0
#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
@@ -71,6 +76,13 @@
((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
(R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
(R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
+#define R300_PVS_MODIFIER_X (1 << 25)
+#define R300_PVS_MODIFIER_Y (1 << 26)
+#define R300_PVS_MODIFIER_Z (1 << 27)
+#define R300_PVS_MODIFIER_W (1 << 28)
+#define R300_PVS_NEGATE_XYZW \
+ (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
+ R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
static const struct tgsi_full_src_register r300_constant_zero = {
.SrcRegister.Extended = TRUE,
@@ -98,7 +110,13 @@ struct r300_vs_asm {
unsigned imm_offset;
/* Number of immediate constants. */
unsigned imm_count;
- /* Offsets into vertex output memory. */
+ /* Number of colors to write. */
+ unsigned out_colors;
+ /* Number of texcoords to write. */
+ unsigned out_texcoords;
+ /* Whether to emit point size. */
+ boolean point_size;
+ /* Tab of declared outputs to OVM outputs. */
unsigned tab[16];
};
@@ -114,7 +132,7 @@ static struct r300_vertex_shader r300_passthrough_vertex_shader = {
.instructions[0].inst3 = 0x0,
.instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(2) | R300_PVS_DST_WE_XYZW,
+ R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
.instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
.instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
@@ -133,7 +151,7 @@ static struct r300_vertex_shader r300_texture_vertex_shader = {
.instructions[0].inst3 = 0x0,
.instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(6) | R300_PVS_DST_WE_XYZW,
+ R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
.instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
.instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index 79bed03253..c9e2dff14e 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -23,15 +23,13 @@
#include "r300_surface.h"
-static void r300_surface_setup(struct pipe_context* pipe,
- struct pipe_surface* dest,
+static void r300_surface_setup(struct r300_context* r300,
+ struct r300_texture* dest,
unsigned x, unsigned y,
unsigned w, unsigned h)
{
- struct r300_context* r300 = r300_context(pipe);
- struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
- struct r300_texture* tex = (struct r300_texture*)dest->texture;
- unsigned pixpitch = tex->stride / tex->tex.block.size;
+ struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
+ unsigned pixpitch = dest->stride / dest->tex.block.size;
CS_LOCALS(r300);
r300_emit_blend_state(r300, &blend_clear_state);
@@ -39,7 +37,22 @@ static void r300_surface_setup(struct pipe_context* pipe,
r300_emit_dsa_state(r300, &dsa_clear_state);
r300_emit_rs_state(r300, &rs_clear_state);
- BEGIN_CS(15);
+ BEGIN_CS(24);
+
+ /* Viewport setup */
+ OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
+ OUT_CS_32F((float)w);
+ OUT_CS_32F((float)x);
+ OUT_CS_32F((float)h);
+ OUT_CS_32F((float)y);
+ OUT_CS_32F(1.0);
+ OUT_CS_32F(0.0);
+
+ OUT_CS_REG(R300_VAP_VTE_CNTL, R300_VPORT_X_SCALE_ENA |
+ R300_VPORT_X_OFFSET_ENA |
+ R300_VPORT_Y_SCALE_ENA |
+ R300_VPORT_Y_OFFSET_ENA |
+ R300_VTX_XY_FMT | R300_VTX_Z_FMT);
/* Pixel scissors. */
OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
@@ -64,9 +77,9 @@ static void r300_surface_setup(struct pipe_context* pipe,
/* Setup colorbuffer. */
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
- OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch |
- r300_translate_colorformat(tex->tex.format));
+ r300_translate_colorformat(dest->tex.format));
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);
END_CS;
@@ -86,6 +99,7 @@ static void r300_surface_fill(struct pipe_context* pipe,
struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
struct r300_texture* tex = (struct r300_texture*)dest->texture;
unsigned pixpitch = tex->stride / tex->tex.block.size;
+ boolean invalid = FALSE;
CS_LOCALS(r300);
a = (float)((color >> 24) & 0xff) / 255.0f;
@@ -98,12 +112,29 @@ static void r300_surface_fill(struct pipe_context* pipe,
/* Fallback? */
if (FALSE) {
+fallback:
debug_printf("r300: Falling back on surface clear...");
util_surface_fill(pipe, dest, x, y, w, h, color);
return;
}
- r300_surface_setup(r300, dest, x, y, w, h);
+ /* Make sure our target BO is okay. */
+validate:
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ if (r300->winsys->validate(r300->winsys)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ goto fallback;
+ }
+ invalid = TRUE;
+ goto validate;
+ }
+
+ r300_surface_setup(r300, tex, x, y, w, h);
/* Vertex shader setup */
if (caps->has_tcl) {
@@ -127,7 +158,7 @@ static void r300_surface_fill(struct pipe_context* pipe,
r300_emit_rs_block_state(r300, &r300_rs_block_clear_state);
}
- BEGIN_CS(31);
+ BEGIN_CS(26);
/* VAP stream control, mapping from input memory to PVS/RS memory */
if (caps->has_tcl) {
@@ -154,27 +185,21 @@ static void r300_surface_fill(struct pipe_context* pipe,
/* Disable textures */
OUT_CS_REG(R300_TX_ENABLE, 0x0);
- /* Viewport setup */
- OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
- OUT_CS_32F(1.0);
- OUT_CS_32F((float)x);
- OUT_CS_32F(1.0);
- OUT_CS_32F((float)y);
- OUT_CS_32F(1.0);
- OUT_CS_32F(0.0);
-
/* The size of the point we're about to draw, in sixths of pixels */
OUT_CS_REG(R300_GA_POINT_SIZE,
- ((h * 6) & R300_POINTSIZE_Y_MASK) |
+ ((h * 6) & R300_POINTSIZE_Y_MASK) |
((w * 6) << R300_POINTSIZE_X_SHIFT));
+ /* Vertex size. */
+ OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8);
+
/* Packet3 with our point vertex */
OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8);
OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
(1 << R300_PRIM_NUM_VERTICES_SHIFT));
/* Position */
- OUT_CS_32F(w / 2.0);
- OUT_CS_32F(h / 2.0);
+ OUT_CS_32F(0.5);
+ OUT_CS_32F(0.5);
OUT_CS_32F(1.0);
OUT_CS_32F(1.0);
/* Color */
@@ -183,11 +208,7 @@ static void r300_surface_fill(struct pipe_context* pipe,
OUT_CS_32F(b);
OUT_CS_32F(a);
- /* XXX figure out why this is 0xA and not 0x2 */
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
- /* XXX OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
- R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
- R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); */
END_CS;
@@ -206,6 +227,7 @@ static void r300_surface_copy(struct pipe_context* pipe,
struct r300_texture* srctex = (struct r300_texture*)src->texture;
struct r300_texture* desttex = (struct r300_texture*)dest->texture;
unsigned pixpitch = srctex->stride / srctex->tex.block.size;
+ boolean invalid = FALSE;
CS_LOCALS(r300);
debug_printf("r300: Copying surface %p at (%d,%d) to %p at (%d, %d),"
@@ -215,18 +237,48 @@ static void r300_surface_copy(struct pipe_context* pipe,
if ((srctex == desttex) &&
((destx < srcx + w) || (srcx < destx + w)) &&
((desty < srcy + h) || (srcy < desty + h))) {
+fallback:
debug_printf("r300: Falling back on surface_copy\n");
util_surface_copy(pipe, FALSE, dest, destx, desty, src,
srcx, srcy, w, h);
}
+ /* Add our target BOs to the list. */
+validate:
+ if (!r300->winsys->add_buffer(r300->winsys, srctex->buffer,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ if (!r300->winsys->add_buffer(r300->winsys, desttex->buffer,
+ 0, RADEON_GEM_DOMAIN_VRAM)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ if (r300->winsys->validate(r300->winsys)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ goto fallback;
+ }
+ invalid = TRUE;
+ goto validate;
+ }
+
+ r300_surface_setup(r300, desttex, destx, desty, w, h);
+
+ /* Setup the texture. */
r300_emit_sampler(r300, &r300_sampler_copy_state, 0);
r300_emit_texture(r300, srctex, 0);
- r300_flush_textures(r300);
+
+ /* Flush and enable. */
+ BEGIN_CS(4);
+ OUT_CS_REG(R300_TX_INVALTAGS, 0);
+ OUT_CS_REG(R300_TX_ENABLE, 0x1);
+ END_CS;
/* Vertex shader setup */
if (caps->has_tcl) {
- r300_emit_vertex_shader(r300, &r300_texture_vertex_shader);
+ r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
} else {
BEGIN_CS(4);
OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
@@ -246,6 +298,7 @@ static void r300_surface_copy(struct pipe_context* pipe,
r300_emit_rs_block_state(r300, &r300_rs_block_copy_state);
}
+ BEGIN_CS(30);
/* VAP stream control, mapping from input memory to PVS/RS memory */
if (caps->has_tcl) {
OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0,
@@ -268,33 +321,38 @@ static void r300_surface_copy(struct pipe_context* pipe,
/* Two components of texture 0 */
OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x2);
+ /* Vertex size. */
+ OUT_CS_REG(R300_VAP_VTX_SIZE, 0x4);
+
/* Packet3 with our texcoords */
- OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 8);
+ OUT_CS_PKT3(R200_3D_DRAW_IMMD_2, 16);
OUT_CS(R300_PRIM_TYPE_QUADS | R300_PRIM_WALK_RING |
(4 << R300_PRIM_NUM_VERTICES_SHIFT));
/* (x , y ) */
- OUT_CS_32F((float)destx);
- OUT_CS_32F((float)desty);
- OUT_CS_32F((float)srcx);
- OUT_CS_32F((float)srcy);
+ OUT_CS_32F((float)(destx / dest->width));
+ OUT_CS_32F((float)(desty / dest->height));
+ OUT_CS_32F((float)(srcx / dest->width));
+ OUT_CS_32F((float)(srcy / dest->height));
/* (x , y + h) */
- OUT_CS_32F((float)destx);
- OUT_CS_32F((float)(desty + h));
- OUT_CS_32F((float)srcx);
- OUT_CS_32F((float)(srcy + h));
+ OUT_CS_32F((float)(destx / dest->width));
+ OUT_CS_32F((float)((desty + h) / dest->height));
+ OUT_CS_32F((float)(srcx / dest->width));
+ OUT_CS_32F((float)((srcy + h) / dest->height));
/* (x + w, y + h) */
- OUT_CS_32F((float)(destx + w));
- OUT_CS_32F((float)(desty + h));
- OUT_CS_32F((float)(srcx + w));
- OUT_CS_32F((float)(srcy + h));
+ OUT_CS_32F((float)((destx + w) / dest->width));
+ OUT_CS_32F((float)((desty + h) / dest->height));
+ OUT_CS_32F((float)((srcx + w) / dest->width));
+ OUT_CS_32F((float)((srcy + h) / dest->height));
/* (x + w, y ) */
- OUT_CS_32F((float)(destx + w));
- OUT_CS_32F((float)desty);
- OUT_CS_32F((float)(srcx + w));
- OUT_CS_32F((float)srcy);
+ OUT_CS_32F((float)((destx + w) / dest->width));
+ OUT_CS_32F((float)(desty / dest->height));
+ OUT_CS_32F((float)((srcx + w) / dest->width));
+ OUT_CS_32F((float)(srcy / dest->height));
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA);
+ END_CS;
+
r300->dirty_hw++;
}
diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h
index 894def07aa..9a4c39f58b 100644
--- a/src/gallium/drivers/r300/r300_surface.h
+++ b/src/gallium/drivers/r300/r300_surface.h
@@ -101,7 +101,7 @@ static struct r300_rs_block r300_rs_block_copy_state = {
R500_RS_SEL_Q(R300_RS_SEL_K1),
.inst[0] = R300_RS_INST_COL_CN_WRITE,
.count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN,
- .inst_count = R300_RS_TX_OFFSET(6),
+ .inst_count = R300_RS_TX_OFFSET(0),
};
static struct r300_rs_block r500_rs_block_copy_state = {
@@ -111,7 +111,7 @@ static struct r300_rs_block r500_rs_block_copy_state = {
R500_RS_SEL_Q(R500_RS_IP_PTR_K1),
.inst[0] = R500_RS_INST_TEX_CN_WRITE,
.count = R300_IT_COUNT(2) | R300_IC_COUNT(0) | R300_HIRES_EN,
- .inst_count = R300_RS_TX_OFFSET(6),
+ .inst_count = R300_RS_TX_OFFSET(0),
};
static struct r300_sampler_state r300_sampler_copy_state = {
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index fe91f4e184..5ea9f56247 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -86,8 +86,6 @@ static struct pipe_texture*
r300_texture_create(struct pipe_screen* screen,
const struct pipe_texture* template)
{
- /* XXX struct r300_screen* r300screen = r300_screen(screen); */
-
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
if (!tex) {
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index baa95282c3..d2893c3b9d 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -35,8 +35,6 @@ extern "C" {
#include "pipe/p_state.h"
#include "pipe/internal/p_winsys_screen.h"
-struct radeon_cs;
-
struct r300_winsys {
/* Parent class */
struct pipe_winsys base;
@@ -47,42 +45,50 @@ struct r300_winsys {
/* PCI ID */
uint32_t pci_id;
- /* GB pipe count */
- uint32_t gb_pipes;
+ /* GART size. */
+ uint32_t gart_size;
+
+ /* VRAM size. */
+ uint32_t vram_size;
+
+ /* Add a pipe_buffer to the list of buffer objects to validate. */
+ boolean (*add_buffer)(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd);
- /* CS object. This is very much like Intel's batchbuffer.
- * Fill it full of dwords and relocs and then submit.
- * Repeat as needed. */
- struct radeon_cs* cs;
+ /* Revalidate all currently setup pipe_buffers.
+ * Returns TRUE if a flush is required. */
+ boolean (*validate)(struct r300_winsys* winsys);
/* Check to see if there's room for commands. */
- boolean (*check_cs)(struct radeon_cs* cs, int size);
+ boolean (*check_cs)(struct r300_winsys* winsys, int size);
/* Start a command emit. */
- void (*begin_cs)(struct radeon_cs* cs,
- int size,
- const char* file,
- const char* function,
- int line);
+ void (*begin_cs)(struct r300_winsys* winsys,
+ int size,
+ const char* file,
+ const char* function,
+ int line);
/* Write a dword to the command buffer. */
- void (*write_cs_dword)(struct radeon_cs* cs, uint32_t dword);
+ void (*write_cs_dword)(struct r300_winsys* winsys, uint32_t dword);
/* Write a relocated dword to the command buffer. */
- void (*write_cs_reloc)(struct radeon_cs* cs,
- struct pipe_buffer* bo,
- uint32_t rd,
- uint32_t wd,
- uint32_t flags);
+ void (*write_cs_reloc)(struct r300_winsys* winsys,
+ struct pipe_buffer* bo,
+ uint32_t rd,
+ uint32_t wd,
+ uint32_t flags);
/* Finish a command emit. */
- void (*end_cs)(struct radeon_cs* cs,
- const char* file,
- const char* function,
- int line);
+ void (*end_cs)(struct r300_winsys* winsys,
+ const char* file,
+ const char* function,
+ int line);
/* Flush the CS. */
- void (*flush_cs)(struct radeon_cs* cs);
+ void (*flush_cs)(struct r300_winsys* winsys);
};
struct pipe_context* r300_create_context(struct pipe_screen* screen,
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 06ace27d14..62e8d99cfd 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -121,11 +121,23 @@ static void softpipe_destroy( struct pipe_context *pipe )
FREE( softpipe );
}
+static unsigned int
+softpipe_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ return PIPE_UNREFERENCED;
+}
+
+static unsigned int
+softpipe_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ return PIPE_UNREFERENCED;
+}
struct pipe_context *
-softpipe_create( struct pipe_screen *screen,
- struct pipe_winsys *pipe_winsys,
- void *unused )
+softpipe_create( struct pipe_screen *screen )
{
struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context);
uint i;
@@ -140,7 +152,7 @@ softpipe_create( struct pipe_screen *screen,
softpipe->dump_fs = debug_get_bool_option( "GALLIUM_DUMP_FS", FALSE );
- softpipe->pipe.winsys = pipe_winsys;
+ softpipe->pipe.winsys = screen->winsys;
softpipe->pipe.screen = screen;
softpipe->pipe.destroy = softpipe_destroy;
@@ -190,6 +202,9 @@ softpipe_create( struct pipe_screen *screen,
softpipe->pipe.clear = softpipe_clear;
softpipe->pipe.flush = softpipe_flush;
+ softpipe->pipe.is_texture_referenced = softpipe_is_texture_referenced;
+ softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced;
+
softpipe_init_query_funcs( softpipe );
softpipe_init_texture_funcs( softpipe );
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 59d6df8f2d..b89a7292e5 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -92,6 +92,7 @@ struct softpipe_context {
* queries.
*/
uint64_t occlusion_count;
+ unsigned active_query_count;
/** Mapped vertex buffers */
ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index eef6e5806c..06725fd09b 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -236,7 +236,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
}
break;
-
case PIPE_PRIM_TRIANGLES:
for (i = 2; i < nr; i += 3) {
setup_tri( setup_ctx,
@@ -256,7 +255,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_TRIANGLE_FAN:
- case PIPE_PRIM_POLYGON:
for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[0], stride),
@@ -264,6 +262,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
get_vert(vertex_buffer, indices[i-0], stride));
}
break;
+
case PIPE_PRIM_QUADS:
for (i = 3; i < nr; i += 4) {
setup_tri( setup_ctx,
@@ -277,6 +276,7 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
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,
@@ -290,6 +290,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
get_vert(vertex_buffer, indices[i-0], stride));
}
break;
+
+ case PIPE_PRIM_POLYGON:
+ for (i = 2; i < nr; i += 1) {
+ setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[0-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[0], stride));
+ }
+ break;
+
default:
assert(0);
}
@@ -378,7 +388,6 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_TRIANGLE_FAN:
- case PIPE_PRIM_POLYGON:
for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, 0, stride),
@@ -386,6 +395,7 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
get_vert(vertex_buffer, i-0, stride));
}
break;
+
case PIPE_PRIM_QUADS:
for (i = 3; i < nr; i += 4) {
setup_tri( setup_ctx,
@@ -412,6 +422,20 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
get_vert(vertex_buffer, i-0, stride));
}
break;
+
+ case PIPE_PRIM_POLYGON:
+ /* Almost same as tri fan but the _first_ vertex specifies the flat
+ * shading color. Note that the first polygon vertex is passed as
+ * the last triangle vertex here.
+ */
+ for (i = 2; i < nr; i += 1) {
+ setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, 0, stride));
+ }
+ break;
+
default:
assert(0);
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c
index 892ef87ee9..b5f69b7426 100644
--- a/src/gallium/drivers/softpipe/sp_quad_pipe.c
+++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c
@@ -80,7 +80,7 @@ sp_build_quad_pipeline(struct softpipe_context *sp)
sp_push_quad_first( sp, sp->quad[i].blend, i );
}
- if (sp->depth_stencil->depth.occlusion_count) {
+ if (sp->active_query_count) {
sp_push_quad_first( sp, sp->quad[i].occlusion, i );
}
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index 93dab236d6..379cf4ad06 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -34,6 +34,7 @@
#include "util/u_memory.h"
#include "sp_context.h"
#include "sp_query.h"
+#include "sp_state.h"
struct softpipe_query {
uint64_t start;
@@ -69,6 +70,8 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
struct softpipe_query *sq = softpipe_query(q);
sq->start = softpipe->occlusion_count;
+ softpipe->active_query_count++;
+ softpipe->dirty |= SP_NEW_QUERY;
}
@@ -78,7 +81,9 @@ 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);
+ softpipe->active_query_count--;
sq->end = softpipe->occlusion_count;
+ softpipe->dirty |= SP_NEW_QUERY;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 7380a6ae2b..692deeb8fd 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -82,11 +82,11 @@ softpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_TEXTURE_SHADOW_MAP:
return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
- return 12; /* max 2Kx2K */
+ return 13; /* max 4Kx4K */
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
return 8; /* max 128x128x128 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
- return 12; /* max 2Kx2K */
+ return 13; /* max 4Kx4K */
default:
return 0;
}
@@ -106,7 +106,7 @@ softpipe_get_paramf(struct pipe_screen *screen, int param)
case PIPE_CAP_MAX_POINT_WIDTH_AA:
return 255.0; /* arbitrary */
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
- return 0.0;
+ return 16.0; /* not actually signficant at this time */
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
return 16.0; /* arbitrary */
default:
@@ -127,6 +127,11 @@ softpipe_is_format_supported( struct pipe_screen *screen,
unsigned tex_usage,
unsigned geom_flags )
{
+ assert(target == PIPE_TEXTURE_1D ||
+ target == PIPE_TEXTURE_2D ||
+ target == PIPE_TEXTURE_3D ||
+ target == PIPE_TEXTURE_CUBE);
+
switch(format) {
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index accc692b66..c6844a2649 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -504,6 +504,8 @@ static void print_vertex(const struct setup_context *setup,
#endif
/**
+ * Sort the vertices from top to bottom order, setting up the triangle
+ * edge fields (ebot, emaj, etop).
* \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise
*/
static boolean setup_sort_vertices( struct setup_context *setup,
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index c0113c47ad..7a533dad9f 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -42,6 +42,7 @@
#include "sp_texture.h"
#include "sp_tile_cache.h"
#include "sp_screen.h"
+#include "sp_winsys.h"
/* Simple, maximally packed layout.
@@ -399,3 +400,22 @@ softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
screen->transfer_map = softpipe_transfer_map;
screen->transfer_unmap = softpipe_transfer_unmap;
}
+
+
+boolean
+softpipe_get_texture_buffer( struct pipe_texture *texture,
+ struct pipe_buffer **buf,
+ unsigned *stride )
+{
+ struct softpipe_texture *tex = (struct softpipe_texture *)texture;
+
+ if (!tex)
+ return FALSE;
+
+ pipe_buffer_reference(buf, tex->buffer);
+
+ if (stride)
+ *stride = tex->stride[0];
+
+ return TRUE;
+}
diff --git a/src/gallium/drivers/softpipe/sp_winsys.h b/src/gallium/drivers/softpipe/sp_winsys.h
index 4ab666486c..9e571862b7 100644
--- a/src/gallium/drivers/softpipe/sp_winsys.h
+++ b/src/gallium/drivers/softpipe/sp_winsys.h
@@ -35,37 +35,29 @@
#define SP_WINSYS_H
-#include "pipe/p_compiler.h" /* for boolean */
-
-
#ifdef __cplusplus
extern "C" {
#endif
-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_screen;
struct pipe_winsys;
struct pipe_context;
-struct pipe_context *softpipe_create( struct pipe_screen *,
- struct pipe_winsys *,
- void *unused );
+struct pipe_context *softpipe_create( struct pipe_screen * );
struct pipe_screen *
softpipe_create_screen(struct pipe_winsys *);
+boolean
+softpipe_get_texture_buffer( struct pipe_texture *texture,
+ struct pipe_buffer **buf,
+ unsigned *stride );
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/drivers/trace/Makefile b/src/gallium/drivers/trace/Makefile
index e087db169a..4aeb8e3d7e 100644
--- a/src/gallium/drivers/trace/Makefile
+++ b/src/gallium/drivers/trace/Makefile
@@ -7,8 +7,10 @@ C_SOURCES = \
tr_buffer.c \
tr_context.c \
tr_dump.c \
+ tr_dump_state.c \
tr_screen.c \
tr_state.c \
+ tr_rbug.c \
tr_texture.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README
index 73dce20372..1000c31e49 100644
--- a/src/gallium/drivers/trace/README
+++ b/src/gallium/drivers/trace/README
@@ -3,7 +3,8 @@
= About =
-This directory contains a Gallium3D pipe driver which traces all incoming calls.
+This directory contains a Gallium3D debugger pipe driver.
+It can traces all incoming calls and/or provide remote debugging functionality.
= Build Instructions =
@@ -23,7 +24,9 @@ ensure the right libGL.so is being picked by doing
ldd progs/trivial/tri
-and then try running
+== Traceing ==
+
+For traceing then do
export XMESA_TRACE=y
GALLIUM_TRACE=tri.trace progs/trivial/tri
@@ -32,6 +35,16 @@ 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 such as
Firefox or Internet Explorer.
+== Remote debugging ==
+
+For remote debugging
+
+ export XMESA_TRACE=y
+ GALLIUM_RBUG=true progs/trivial/tri
+
+which should open gallium remote debugging session. While the program is running
+you can launch the small remote debugging application from progs/rbug. More
+information is in that directory.
= Integrating =
@@ -62,3 +75,4 @@ trace_screen with real_screen when creating them.
--
Jose Fonseca <jrfonseca@tungstengraphics.com>
+Jakob Bornecrantz <jakob@vmware.com>
diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript
index 4215215d1a..e635fed77d 100644
--- a/src/gallium/drivers/trace/SConscript
+++ b/src/gallium/drivers/trace/SConscript
@@ -8,8 +8,10 @@ trace = env.ConvenienceLibrary(
'tr_buffer.c',
'tr_context.c',
'tr_dump.c',
+ 'tr_dump_state.c',
'tr_screen.c',
'tr_state.c',
+ 'tr_rbug.c',
'tr_texture.c',
])
diff --git a/src/gallium/drivers/trace/tr_buffer.c b/src/gallium/drivers/trace/tr_buffer.c
index 6ffce1660e..4f0eff6a5a 100644
--- a/src/gallium/drivers/trace/tr_buffer.c
+++ b/src/gallium/drivers/trace/tr_buffer.c
@@ -27,10 +27,10 @@
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "tr_buffer.h"
-
struct pipe_buffer *
trace_buffer_create(struct trace_screen *tr_scr,
struct pipe_buffer *buffer)
@@ -52,6 +52,8 @@ trace_buffer_create(struct trace_screen *tr_scr,
tr_buf->base.screen = &tr_scr->base;
tr_buf->buffer = buffer;
+ trace_screen_add_to_list(tr_scr, buffers, tr_buf);
+
return &tr_buf->base;
error:
@@ -64,7 +66,10 @@ void
trace_buffer_destroy(struct trace_screen *tr_scr,
struct pipe_buffer *buffer)
{
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, buffer);
+ struct trace_buffer *tr_buf = trace_buffer(buffer);
+
+ trace_screen_remove_from_list(tr_scr, buffers, tr_buf);
+
pipe_buffer_reference(&tr_buf->buffer, NULL);
FREE(tr_buf);
}
diff --git a/src/gallium/drivers/trace/tr_buffer.h b/src/gallium/drivers/trace/tr_buffer.h
index e9e4d354da..1a2d0b9aea 100644
--- a/src/gallium/drivers/trace/tr_buffer.h
+++ b/src/gallium/drivers/trace/tr_buffer.h
@@ -41,19 +41,19 @@ struct trace_buffer
struct pipe_buffer *buffer;
+ struct tr_list list;
+
void *map;
boolean range_flushed;
};
static INLINE struct trace_buffer *
-trace_buffer(struct trace_screen *tr_scr,
- struct pipe_buffer *buffer)
+trace_buffer(struct pipe_buffer *buffer)
{
if(!buffer)
return NULL;
- assert(tr_scr);
- assert(buffer->screen == &tr_scr->base);
+ (void)trace_screen(buffer->screen);
return (struct trace_buffer *)buffer;
}
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index d8d5821a1d..4ab718f233 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -26,14 +26,16 @@
**************************************************************************/
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+
#include "pipe/p_screen.h"
#include "tr_dump.h"
+#include "tr_dump_state.h"
#include "tr_state.h"
#include "tr_buffer.h"
#include "tr_screen.h"
#include "tr_texture.h"
-#include "tr_context.h"
static INLINE struct pipe_buffer *
@@ -46,7 +48,7 @@ trace_buffer_unwrap(struct trace_context *tr_ctx,
if(!buffer)
return NULL;
- tr_buf = trace_buffer(tr_scr, buffer);
+ tr_buf = trace_buffer(buffer);
assert(tr_buf->buffer);
assert(tr_buf->buffer->screen == tr_scr->screen);
@@ -111,6 +113,65 @@ trace_context_set_edgeflags(struct pipe_context *_pipe,
}
+static INLINE void
+trace_context_draw_block(struct trace_context *tr_ctx, int flag)
+{
+ int k;
+
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+
+ if (tr_ctx->draw_blocker & flag) {
+ tr_ctx->draw_blocked |= flag;
+ } else if ((tr_ctx->draw_rule.blocker & flag) &&
+ (tr_ctx->draw_blocker & 4)) {
+ boolean block = FALSE;
+ debug_printf("%s (%lu %lu) (%lu %lu) (%lu %u) (%lu %u)\n", __FUNCTION__,
+ tr_ctx->draw_rule.fs, tr_ctx->curr.fs,
+ tr_ctx->draw_rule.vs, tr_ctx->curr.vs,
+ tr_ctx->draw_rule.surf, 0,
+ tr_ctx->draw_rule.tex, 0);
+ if (tr_ctx->draw_rule.fs &&
+ tr_ctx->draw_rule.fs == tr_ctx->curr.fs)
+ block = TRUE;
+ if (tr_ctx->draw_rule.vs &&
+ tr_ctx->draw_rule.vs == tr_ctx->curr.vs)
+ block = TRUE;
+ if (tr_ctx->draw_rule.surf &&
+ tr_ctx->draw_rule.surf == tr_ctx->curr.zsbuf)
+ block = TRUE;
+ if (tr_ctx->draw_rule.surf)
+ for (k = 0; k < tr_ctx->curr.nr_cbufs; k++)
+ if (tr_ctx->draw_rule.surf == tr_ctx->curr.cbufs[k])
+ block = TRUE;
+ if (tr_ctx->draw_rule.tex)
+ for (k = 0; k < tr_ctx->curr.num_texs; k++)
+ if (tr_ctx->draw_rule.tex == tr_ctx->curr.tex[k])
+ block = TRUE;
+
+ if (block)
+ tr_ctx->draw_blocked |= (flag | 4);
+ }
+
+ if (tr_ctx->draw_blocked)
+ trace_rbug_notify_draw_blocked(tr_ctx);
+
+ /* wait for rbug to clear the blocked flag */
+ while (tr_ctx->draw_blocked & flag) {
+ tr_ctx->draw_blocked |= flag;
+#ifdef PIPE_THREAD_HAVE_CONDVAR
+ pipe_condvar_wait(tr_ctx->draw_cond, tr_ctx->draw_mutex);
+#else
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
+ Sleep(1);
+#endif
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+#endif
+ }
+
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+}
+
static INLINE boolean
trace_context_draw_arrays(struct pipe_context *_pipe,
unsigned mode, unsigned start, unsigned count)
@@ -119,6 +180,11 @@ trace_context_draw_arrays(struct pipe_context *_pipe,
struct pipe_context *pipe = tr_ctx->pipe;
boolean result;
+ if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
+ return 0;
+
+ trace_context_draw_block(tr_ctx, 1);
+
trace_dump_call_begin("pipe_context", "draw_arrays");
trace_dump_arg(ptr, pipe);
@@ -132,6 +198,8 @@ trace_context_draw_arrays(struct pipe_context *_pipe,
trace_dump_call_end();
+ trace_context_draw_block(tr_ctx, 2);
+
return result;
}
@@ -142,13 +210,17 @@ trace_context_draw_elements(struct pipe_context *_pipe,
unsigned indexSize,
unsigned mode, unsigned start, unsigned count)
{
- struct trace_screen *tr_scr = trace_screen(_pipe->screen);
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _indexBuffer);
+ struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
struct pipe_context *pipe = tr_ctx->pipe;
struct pipe_buffer *indexBuffer = tr_buf->buffer;
boolean result;
+ if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
+ return 0;
+
+ trace_context_draw_block(tr_ctx, 1);
+
trace_screen_user_buffer_update(_pipe->screen, indexBuffer);
trace_dump_call_begin("pipe_context", "draw_elements");
@@ -166,6 +238,8 @@ trace_context_draw_elements(struct pipe_context *_pipe,
trace_dump_call_end();
+ trace_context_draw_block(tr_ctx, 2);
+
return result;
}
@@ -180,13 +254,17 @@ trace_context_draw_range_elements(struct pipe_context *_pipe,
unsigned start,
unsigned count)
{
- struct trace_screen *tr_scr = trace_screen(_pipe->screen);
struct trace_context *tr_ctx = trace_context(_pipe);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _indexBuffer);
+ struct trace_buffer *tr_buf = trace_buffer(_indexBuffer);
struct pipe_context *pipe = tr_ctx->pipe;
struct pipe_buffer *indexBuffer = tr_buf->buffer;
boolean result;
+ if (tr_ctx->curr.fs->disabled || tr_ctx->curr.vs->disabled)
+ return 0;
+
+ trace_context_draw_block(tr_ctx, 1);
+
trace_screen_user_buffer_update(_pipe->screen, indexBuffer);
trace_dump_call_begin("pipe_context", "draw_range_elements");
@@ -209,6 +287,8 @@ trace_context_draw_range_elements(struct pipe_context *_pipe,
trace_dump_call_end();
+ trace_context_draw_block(tr_ctx, 2);
+
return result;
}
@@ -573,23 +653,32 @@ trace_context_create_fs_state(struct pipe_context *_pipe,
trace_dump_call_end();
+ result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_FRAGMENT);
+
return result;
}
static INLINE void
trace_context_bind_fs_state(struct pipe_context *_pipe,
- void *state)
+ void *_state)
{
struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_shader *tr_shdr = trace_shader(_state);
struct pipe_context *pipe = tr_ctx->pipe;
+ void *state = tr_shdr ? tr_shdr->state : NULL;
trace_dump_call_begin("pipe_context", "bind_fs_state");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, state);
- pipe->bind_fs_state(pipe, state);;
+ tr_ctx->curr.fs = tr_shdr;
+
+ if (tr_shdr && tr_shdr->replaced)
+ state = tr_shdr->replaced;
+
+ pipe->bind_fs_state(pipe, state);
trace_dump_call_end();
}
@@ -597,19 +686,23 @@ trace_context_bind_fs_state(struct pipe_context *_pipe,
static INLINE void
trace_context_delete_fs_state(struct pipe_context *_pipe,
- void *state)
+ void *_state)
{
struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_shader *tr_shdr = trace_shader(_state);
struct pipe_context *pipe = tr_ctx->pipe;
+ void *state = tr_shdr->state;
trace_dump_call_begin("pipe_context", "delete_fs_state");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, state);
- pipe->delete_fs_state(pipe, state);;
+ pipe->delete_fs_state(pipe, state);
trace_dump_call_end();
+
+ trace_shader_destroy(tr_ctx, tr_shdr);
}
@@ -626,28 +719,37 @@ trace_context_create_vs_state(struct pipe_context *_pipe,
trace_dump_arg(ptr, pipe);
trace_dump_arg(shader_state, state);
- result = pipe->create_vs_state(pipe, state);;
+ result = pipe->create_vs_state(pipe, state);
trace_dump_ret(ptr, result);
trace_dump_call_end();
+ result = trace_shader_create(tr_ctx, state, result, TRACE_SHADER_VERTEX);
+
return result;
}
static INLINE void
trace_context_bind_vs_state(struct pipe_context *_pipe,
- void *state)
+ void *_state)
{
struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_shader *tr_shdr = trace_shader(_state);
struct pipe_context *pipe = tr_ctx->pipe;
+ void *state = tr_shdr ? tr_shdr->state : NULL;
trace_dump_call_begin("pipe_context", "bind_vs_state");
trace_dump_arg(ptr, pipe);
trace_dump_arg(ptr, state);
+ tr_ctx->curr.vs = tr_shdr;
+
+ if (tr_shdr && tr_shdr->replaced)
+ state = tr_shdr->replaced;
+
pipe->bind_vs_state(pipe, state);;
trace_dump_call_end();
@@ -656,10 +758,12 @@ trace_context_bind_vs_state(struct pipe_context *_pipe,
static INLINE void
trace_context_delete_vs_state(struct pipe_context *_pipe,
- void *state)
+ void *_state)
{
struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_shader *tr_shdr = trace_shader(_state);
struct pipe_context *pipe = tr_ctx->pipe;
+ void *state = tr_shdr->state;
trace_dump_call_begin("pipe_context", "delete_vs_state");
@@ -669,6 +773,8 @@ trace_context_delete_vs_state(struct pipe_context *_pipe,
pipe->delete_vs_state(pipe, state);;
trace_dump_call_end();
+
+ trace_shader_destroy(tr_ctx, tr_shdr);
}
@@ -747,6 +853,19 @@ trace_context_set_framebuffer_state(struct pipe_context *_pipe,
struct pipe_framebuffer_state unwrapped_state;
unsigned i;
+ {
+ tr_ctx->curr.nr_cbufs = state->nr_cbufs;
+ for (i = 0; i < state->nr_cbufs; i++)
+ if (state->cbufs[i])
+ tr_ctx->curr.cbufs[i] = trace_texture(state->cbufs[i]->texture);
+ else
+ tr_ctx->curr.cbufs[i] = NULL;
+ if (state->zsbuf)
+ tr_ctx->curr.zsbuf = trace_texture(state->zsbuf->texture);
+ else
+ tr_ctx->curr.zsbuf = NULL;
+ }
+
/* Unwrap the input state */
memcpy(&unwrapped_state, state, sizeof(unwrapped_state));
for(i = 0; i < state->nr_cbufs; ++i)
@@ -827,12 +946,17 @@ trace_context_set_sampler_textures(struct pipe_context *_pipe,
struct pipe_texture **textures)
{
struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_texture *tr_tex;
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]);
+ tr_ctx->curr.num_texs = num_textures;
+ for(i = 0; i < num_textures; ++i) {
+ tr_tex = trace_texture(textures[i]);
+ tr_ctx->curr.tex[i] = tr_tex;
+ unwrapped_textures[i] = tr_tex ? tr_tex->texture : NULL;
+ }
textures = unwrapped_textures;
trace_dump_call_begin("pipe_context", "set_sampler_textures");
@@ -1016,20 +1140,73 @@ trace_context_flush(struct pipe_context *_pipe,
static INLINE void
trace_context_destroy(struct pipe_context *_pipe)
{
+ struct trace_screen *tr_scr = trace_screen(_pipe->screen);
struct trace_context *tr_ctx = trace_context(_pipe);
struct pipe_context *pipe = tr_ctx->pipe;
trace_dump_call_begin("pipe_context", "destroy");
-
trace_dump_arg(ptr, pipe);
+ trace_dump_call_end();
+
+ trace_screen_remove_from_list(tr_scr, contexts, tr_ctx);
pipe->destroy(pipe);
+ FREE(tr_ctx);
+}
+
+static unsigned int
+trace_is_texture_referenced( struct pipe_context *_pipe,
+ struct pipe_texture *_texture,
+ unsigned face, unsigned level)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_texture *tr_tex = trace_texture(_texture);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_texture *texture = tr_tex->texture;
+ unsigned int referenced;
+
+ trace_dump_call_begin("pipe_context", "is_texture_referenced");
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, texture);
+ trace_dump_arg(uint, face);
+ trace_dump_arg(uint, level);
+
+ referenced = pipe->is_texture_referenced(pipe, texture, face, level);
+
+ trace_dump_ret(uint, referenced);
trace_dump_call_end();
- FREE(tr_ctx);
+ return referenced;
}
+static unsigned int
+trace_is_buffer_referenced( struct pipe_context *_pipe,
+ struct pipe_buffer *_buf)
+{
+ struct trace_context *tr_ctx = trace_context(_pipe);
+ struct trace_buffer *tr_buf = trace_buffer(_buf);
+ struct pipe_context *pipe = tr_ctx->pipe;
+ struct pipe_buffer *buf = tr_buf->buffer;
+ unsigned int referenced;
+
+ trace_dump_call_begin("pipe_context", "is_buffer_referenced");
+ trace_dump_arg(ptr, pipe);
+ trace_dump_arg(ptr, buf);
+
+ referenced = pipe->is_buffer_referenced(pipe, buf);
+
+ trace_dump_ret(uint, referenced);
+ trace_dump_call_end();
+
+ return referenced;
+}
+
+static const struct debug_named_value rbug_blocker_flags[] = {
+ {"before", 1},
+ {"after", 2},
+ {NULL, 0},
+};
struct pipe_context *
trace_context_create(struct pipe_screen *_screen,
@@ -1042,7 +1219,7 @@ trace_context_create(struct pipe_screen *_screen,
if(!pipe)
goto error1;
- if(!trace_dump_enabled())
+ if(!trace_enabled())
goto error1;
tr_scr = trace_screen(_screen);
@@ -1052,6 +1229,14 @@ trace_context_create(struct pipe_screen *_screen,
if(!tr_ctx)
goto error1;
+ tr_ctx->draw_blocker = debug_get_flags_option("RBUG_BLOCK",
+ rbug_blocker_flags,
+ 0);
+ pipe_mutex_init(tr_ctx->draw_mutex);
+ pipe_condvar_init(tr_ctx->draw_cond);
+ pipe_mutex_init(tr_ctx->list_mutex);
+ make_empty_list(&tr_ctx->shaders);
+
tr_ctx->base.winsys = _screen->winsys;
tr_ctx->base.screen = _screen;
tr_ctx->base.destroy = trace_context_destroy;
@@ -1096,6 +1281,8 @@ trace_context_create(struct pipe_screen *_screen,
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->base.is_texture_referenced = trace_is_texture_referenced;
+ tr_ctx->base.is_buffer_referenced = trace_is_buffer_referenced;
tr_ctx->pipe = pipe;
@@ -1104,6 +1291,8 @@ trace_context_create(struct pipe_screen *_screen,
trace_dump_ret(ptr, pipe);
trace_dump_call_end();
+ trace_screen_add_to_list(tr_scr, contexts, tr_ctx);
+
return &tr_ctx->base;
error1:
diff --git a/src/gallium/drivers/trace/tr_context.h b/src/gallium/drivers/trace/tr_context.h
index d02b22a069..6febe4b411 100644
--- a/src/gallium/drivers/trace/tr_context.h
+++ b/src/gallium/drivers/trace/tr_context.h
@@ -33,6 +33,7 @@
#include "util/u_debug.h"
#include "pipe/p_context.h"
+#include "tr_screen.h"
#ifdef __cplusplus
extern "C" {
@@ -44,6 +45,42 @@ struct trace_context
struct pipe_context base;
struct pipe_context *pipe;
+
+ /* current state */
+ struct {
+ struct trace_shader *fs;
+ struct trace_shader *vs;
+
+ struct trace_texture *tex[PIPE_MAX_SAMPLERS];
+ unsigned num_texs;
+
+ unsigned nr_cbufs;
+ struct trace_texture *cbufs[PIPE_MAX_COLOR_BUFS];
+ struct trace_texture *zsbuf;
+ } curr;
+
+ struct {
+ struct trace_shader *fs;
+ struct trace_shader *vs;
+
+ struct trace_texture *tex;
+ struct trace_texture *surf;
+
+ int blocker;
+ } draw_rule;
+ unsigned draw_num_rules;
+ pipe_condvar draw_cond;
+ pipe_mutex draw_mutex;
+ int draw_blocker;
+ int draw_blocked;
+
+ /* for list on screen */
+ struct tr_list list;
+
+ /* list of state objects */
+ pipe_mutex list_mutex;
+ unsigned num_shaders;
+ struct tr_list shaders;
};
@@ -60,6 +97,9 @@ struct pipe_context *
trace_context_create(struct pipe_screen *screen,
struct pipe_context *pipe);
+void
+trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx);
+
#ifdef __cplusplus
}
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 2618883e70..3a1409e95a 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -61,6 +61,8 @@ static struct util_stream *stream = NULL;
static unsigned refcount = 0;
static pipe_mutex call_mutex;
static long unsigned call_no = 0;
+static boolean dumping = FALSE;
+static boolean initialized = FALSE;
static INLINE void
@@ -226,10 +228,22 @@ trace_dump_trace_close(void)
}
}
+void trace_dump_init()
+{
+ if (initialized)
+ return;
+
+ pipe_mutex_init(call_mutex);
+ dumping = FALSE;
+ initialized = TRUE;
+}
+
boolean trace_dump_trace_begin()
{
const char *filename;
+ assert(initialized);
+
filename = debug_get_option("GALLIUM_TRACE", NULL);
if(!filename)
return FALSE;
@@ -240,8 +254,6 @@ boolean trace_dump_trace_begin()
if(!stream)
return FALSE;
- pipe_mutex_init(call_mutex);
-
trace_dump_writes("<?xml version='1.0' encoding='UTF-8'?>\n");
trace_dump_writes("<?xml-stylesheet type='text/xsl' href='trace.xsl'?>\n");
trace_dump_writes("<trace version='0.1'>\n");
@@ -258,7 +270,7 @@ boolean trace_dump_trace_begin()
return TRUE;
}
-boolean trace_dump_enabled(void)
+boolean trace_dump_trace_enabled(void)
{
return stream ? TRUE : FALSE;
}
@@ -270,9 +282,71 @@ void trace_dump_trace_end(void)
trace_dump_trace_close();
}
-void trace_dump_call_begin(const char *klass, const char *method)
+/*
+ * Call lock
+ */
+
+void trace_dump_call_lock(void)
{
pipe_mutex_lock(call_mutex);
+}
+
+void trace_dump_call_unlock(void)
+{
+ pipe_mutex_unlock(call_mutex);
+}
+
+/*
+ * Dumping control
+ */
+
+void trace_dumping_start_locked(void)
+{
+ dumping = TRUE;
+}
+
+void trace_dumping_stop_locked(void)
+{
+ dumping = FALSE;
+}
+
+boolean trace_dumping_enabled_locked(void)
+{
+ return dumping;
+}
+
+void trace_dumping_start(void)
+{
+ pipe_mutex_lock(call_mutex);
+ trace_dumping_start_locked();
+ pipe_mutex_unlock(call_mutex);
+}
+
+void trace_dumping_stop(void)
+{
+ pipe_mutex_lock(call_mutex);
+ trace_dumping_stop_locked();
+ pipe_mutex_unlock(call_mutex);
+}
+
+boolean trace_dumping_enabled(void)
+{
+ boolean ret;
+ pipe_mutex_lock(call_mutex);
+ ret = trace_dumping_enabled_locked();
+ pipe_mutex_unlock(call_mutex);
+ return ret;
+}
+
+/*
+ * Dump functions
+ */
+
+void trace_dump_call_begin_locked(const char *klass, const char *method)
+{
+ if (!dumping)
+ return;
+
++call_no;
trace_dump_indent(1);
trace_dump_writes("<call no=\'");
@@ -285,56 +359,94 @@ void trace_dump_call_begin(const char *klass, const char *method)
trace_dump_newline();
}
-void trace_dump_call_end(void)
+void trace_dump_call_end_locked(void)
{
+ if (!dumping)
+ return;
+
trace_dump_indent(1);
trace_dump_tag_end("call");
trace_dump_newline();
util_stream_flush(stream);
+}
+
+void trace_dump_call_begin(const char *klass, const char *method)
+{
+ pipe_mutex_lock(call_mutex);
+ trace_dump_call_begin_locked(klass, method);
+}
+
+void trace_dump_call_end(void)
+{
+ trace_dump_call_end_locked();
pipe_mutex_unlock(call_mutex);
}
void trace_dump_arg_begin(const char *name)
{
+ if (!dumping)
+ return;
+
trace_dump_indent(2);
trace_dump_tag_begin1("arg", "name", name);
}
void trace_dump_arg_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_tag_end("arg");
trace_dump_newline();
}
void trace_dump_ret_begin(void)
{
+ if (!dumping)
+ return;
+
trace_dump_indent(2);
trace_dump_tag_begin("ret");
}
void trace_dump_ret_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_tag_end("ret");
trace_dump_newline();
}
void trace_dump_bool(int value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<bool>%c</bool>", value ? '1' : '0');
}
void trace_dump_int(long long int value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<int>%lli</int>", value);
}
void trace_dump_uint(long long unsigned value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<uint>%llu</uint>", value);
}
void trace_dump_float(double value)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<float>%g</float>", value);
}
@@ -344,6 +456,10 @@ void trace_dump_bytes(const void *data,
static const char hex_table[16] = "0123456789ABCDEF";
const uint8_t *p = data;
long unsigned i;
+
+ if (!dumping)
+ return;
+
trace_dump_writes("<bytes>");
for(i = 0; i < size; ++i) {
uint8_t byte = *p++;
@@ -357,6 +473,9 @@ void trace_dump_bytes(const void *data,
void trace_dump_string(const char *str)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<string>");
trace_dump_escape(str);
trace_dump_writes("</string>");
@@ -364,6 +483,9 @@ void trace_dump_string(const char *str)
void trace_dump_enum(const char *value)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<enum>");
trace_dump_escape(value);
trace_dump_writes("</enum>");
@@ -371,51 +493,81 @@ void trace_dump_enum(const char *value)
void trace_dump_array_begin(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<array>");
}
void trace_dump_array_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</array>");
}
void trace_dump_elem_begin(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<elem>");
}
void trace_dump_elem_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</elem>");
}
void trace_dump_struct_begin(const char *name)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<struct name='%s'>", name);
}
void trace_dump_struct_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</struct>");
}
void trace_dump_member_begin(const char *name)
{
+ if (!dumping)
+ return;
+
trace_dump_writef("<member name='%s'>", name);
}
void trace_dump_member_end(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("</member>");
}
void trace_dump_null(void)
{
+ if (!dumping)
+ return;
+
trace_dump_writes("<null/>");
}
void trace_dump_ptr(const void *value)
{
+ if (!dumping)
+ return;
+
if(value)
trace_dump_writef("<ptr>0x%08lx</ptr>", (unsigned long)(uintptr_t)value);
else
@@ -424,9 +576,11 @@ void trace_dump_ptr(const void *value)
void trace_dump_buffer_ptr(struct pipe_buffer *_buffer)
{
+ if (!dumping)
+ return;
+
if (_buffer) {
- struct trace_screen *tr_scr = trace_screen(_buffer->screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
trace_dump_ptr(tr_buf->buffer);
} else {
trace_dump_null();
@@ -435,6 +589,9 @@ void trace_dump_buffer_ptr(struct pipe_buffer *_buffer)
void trace_dump_texture_ptr(struct pipe_texture *_texture)
{
+ if (!dumping)
+ return;
+
if (_texture) {
struct trace_texture *tr_tex = trace_texture(_texture);
trace_dump_ptr(tr_tex->texture);
@@ -445,6 +602,9 @@ void trace_dump_texture_ptr(struct pipe_texture *_texture)
void trace_dump_surface_ptr(struct pipe_surface *_surface)
{
+ if (!dumping)
+ return;
+
if (_surface) {
struct trace_surface *tr_surf = trace_surface(_surface);
trace_dump_ptr(tr_surf->surface);
@@ -455,6 +615,9 @@ void trace_dump_surface_ptr(struct pipe_surface *_surface)
void trace_dump_transfer_ptr(struct pipe_transfer *_transfer)
{
+ if (!dumping)
+ return;
+
if (_transfer) {
struct trace_transfer *tr_tran = trace_transfer(_transfer);
trace_dump_ptr(tr_tran->transfer);
diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h
index 26409f26c6..31ac70802f 100644
--- a/src/gallium/drivers/trace/tr_dump.h
+++ b/src/gallium/drivers/trace/tr_dump.h
@@ -42,11 +42,47 @@ struct pipe_texture;
struct pipe_surface;
struct pipe_transfer;
+/*
+ * Call before use.
+ */
+void trace_dump_init(void);
+
+/*
+ * Low level dumping controls.
+ *
+ * Opening the trace file and checking if that is opened.
+ */
boolean trace_dump_trace_begin(void);
-boolean trace_dump_enabled(void);
+boolean trace_dump_trace_enabled(void);
void trace_dump_trace_end(void);
+
+/*
+ * Lock and unlock the call mutex.
+ *
+ * It used by the none locked version of dumping control
+ * and begin/end call dump functions.
+ *
+ * Begin takes the lock while end unlocks it. Use the _locked
+ * version to avoid locking/unlocking it.
+ */
+void trace_dump_call_lock(void);
+void trace_dump_call_unlock(void);
+
+/*
+ * High level dumping control.
+ */
+void trace_dumping_start_locked(void);
+void trace_dumping_stop_locked(void);
+boolean trace_dumping_enabled_locked(void);
+void trace_dumping_start(void);
+void trace_dumping_stop(void);
+boolean trace_dumping_enabled(void);
+
+void trace_dump_call_begin_locked(const char *klass, const char *method);
+void trace_dump_call_end_locked(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);
diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c
new file mode 100644
index 0000000000..23a2473b57
--- /dev/null
+++ b/src/gallium/drivers/trace/tr_dump_state.c
@@ -0,0 +1,490 @@
+/**************************************************************************
+ *
+ * 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 "util/u_memory.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "tr_dump.h"
+#include "tr_dump_state.h"
+
+
+void trace_dump_format(enum pipe_format format)
+{
+ trace_dump_enum(pf_name(format) );
+}
+
+
+void trace_dump_block(const struct pipe_format_block *block)
+{
+ 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();
+}
+
+
+static void trace_dump_reference(const struct pipe_reference *reference)
+{
+ trace_dump_struct_begin("pipe_reference");
+ trace_dump_member(int, &reference->count, count);
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_template(const struct pipe_texture *templat)
+{
+ if(!templat) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_texture");
+
+ trace_dump_member(int, templat, target);
+ trace_dump_member(format, templat, format);
+
+ trace_dump_member_begin("width");
+ trace_dump_array(uint, templat->width, 1);
+ trace_dump_member_end();
+
+ trace_dump_member_begin("height");
+ trace_dump_array(uint, templat->height, 1);
+ trace_dump_member_end();
+
+ trace_dump_member_begin("depth");
+ trace_dump_array(uint, templat->depth, 1);
+ trace_dump_member_end();
+
+ trace_dump_member_begin("block");
+ trace_dump_block(&templat->block);
+ trace_dump_member_end();
+
+ trace_dump_member(uint, templat, last_level);
+ trace_dump_member(uint, templat, tex_usage);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ 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_vs_clip_and_viewport);
+ 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(uint, state, sprite_coord_mode);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_poly_stipple(const struct pipe_poly_stipple *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_poly_stipple");
+
+ trace_dump_member_begin("stipple");
+ trace_dump_array(uint,
+ state->stipple,
+ Elements(state->stipple));
+ trace_dump_member_end();
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_viewport_state(const struct pipe_viewport_state *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_viewport_state");
+
+ trace_dump_member_array(float, state, scale);
+ trace_dump_member_array(float, state, translate);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_scissor_state(const struct pipe_scissor_state *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_scissor_state");
+
+ 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();
+}
+
+
+void trace_dump_clip_state(const struct pipe_clip_state *state)
+{
+ unsigned i;
+
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ 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) {
+ trace_dump_elem_begin();
+ trace_dump_array(float, state->ucp[i], 4);
+ trace_dump_elem_end();
+ }
+ trace_dump_array_end();
+ trace_dump_member_end();
+
+ trace_dump_member(uint, state, nr);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_constant_buffer(const struct pipe_constant_buffer *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_constant_buffer");
+
+ trace_dump_member(buffer_ptr, state, buffer);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_shader_state(const struct pipe_shader_state *state)
+{
+ static char str[8192];
+
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ tgsi_dump_str(state->tokens, 0, str, sizeof(str));
+
+ trace_dump_struct_begin("pipe_shader_state");
+
+ trace_dump_member_begin("tokens");
+ trace_dump_string(str);
+ trace_dump_member_end();
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state)
+{
+ unsigned i;
+
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_depth_stencil_alpha_state");
+
+ 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_struct_end();
+ trace_dump_member_end();
+
+ trace_dump_member_begin("stencil");
+ trace_dump_array_begin();
+ for(i = 0; i < Elements(state->stencil); ++i) {
+ 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], valuemask);
+ trace_dump_member(uint, &state->stencil[i], writemask);
+ trace_dump_struct_end();
+ trace_dump_elem_end();
+ }
+ 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_value);
+ trace_dump_struct_end();
+ trace_dump_member_end();
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_blend_state(const struct pipe_blend_state *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_blend_state");
+
+ trace_dump_member(bool, state, blend_enable);
+
+ 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(uint, state, alpha_func);
+ trace_dump_member(uint, state, alpha_src_factor);
+ trace_dump_member(uint, state, alpha_dst_factor);
+
+ trace_dump_member(bool, state, logicop_enable);
+ trace_dump_member(uint, state, logicop_func);
+
+ trace_dump_member(uint, state, colormask);
+ trace_dump_member(bool, state, dither);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_blend_color(const struct pipe_blend_color *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_blend_color");
+
+ trace_dump_member_array(float, state, color);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state)
+{
+ trace_dump_struct_begin("pipe_framebuffer_state");
+
+ trace_dump_member(uint, state, width);
+ trace_dump_member(uint, state, height);
+ trace_dump_member(uint, state, nr_cbufs);
+ trace_dump_member_array(ptr, state, cbufs);
+ trace_dump_member(ptr, state, zsbuf);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_sampler_state(const struct pipe_sampler_state *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ 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(const struct pipe_surface *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_surface");
+
+ trace_dump_reference(&state->reference);
+
+ trace_dump_member(format, state, format);
+ trace_dump_member(uint, state, width);
+ trace_dump_member(uint, state, height);
+
+ trace_dump_member(uint, state, layout);
+ trace_dump_member(uint, state, offset);
+ 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_transfer(const struct pipe_transfer *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_transfer");
+
+ trace_dump_member(format, state, format);
+ trace_dump_member(uint, state, width);
+ trace_dump_member(uint, state, height);
+
+ trace_dump_member_begin("block");
+ trace_dump_block(&state->block);
+ trace_dump_member_end();
+
+ trace_dump_member(uint, state, nblocksx);
+ trace_dump_member(uint, state, nblocksy);
+ trace_dump_member(uint, state, stride);
+ 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(const struct pipe_vertex_buffer *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_vertex_buffer");
+
+ trace_dump_member(uint, state, stride);
+ trace_dump_member(uint, state, max_index);
+ trace_dump_member(uint, state, buffer_offset);
+ trace_dump_member(buffer_ptr, state, buffer);
+
+ trace_dump_struct_end();
+}
+
+
+void trace_dump_vertex_element(const struct pipe_vertex_element *state)
+{
+ if(!state) {
+ trace_dump_null();
+ return;
+ }
+
+ trace_dump_struct_begin("pipe_vertex_element");
+
+ trace_dump_member(uint, state, src_offset);
+
+ trace_dump_member(uint, state, vertex_buffer_index);
+ trace_dump_member(uint, state, nr_components);
+
+ trace_dump_member(format, state, src_format);
+
+ trace_dump_struct_end();
+}
diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h
new file mode 100644
index 0000000000..05b821adb6
--- /dev/null
+++ b/src/gallium/drivers/trace/tr_dump_state.h
@@ -0,0 +1,78 @@
+/**************************************************************************
+ *
+ * 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_DUMP_STATE_H_
+#define TR_DUMP_STATE_H_
+
+#include "pipe/p_format.h"
+#include "pipe/p_state.h"
+#include "pipe/p_shader_tokens.h"
+
+
+void trace_dump_format(enum pipe_format format);
+
+void trace_dump_block(const struct pipe_format_block *block);
+
+void trace_dump_template(const struct pipe_texture *templat);
+
+
+void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state);
+
+void trace_dump_poly_stipple(const struct pipe_poly_stipple *state);
+
+void trace_dump_viewport_state(const struct pipe_viewport_state *state);
+
+void trace_dump_scissor_state(const struct pipe_scissor_state *state);
+
+void trace_dump_clip_state(const struct pipe_clip_state *state);
+
+void trace_dump_constant_buffer(const struct pipe_constant_buffer *state);
+
+void trace_dump_token(const struct tgsi_token *token);
+
+void trace_dump_shader_state(const struct pipe_shader_state *state);
+
+void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state);
+
+void trace_dump_blend_state(const struct pipe_blend_state *state);
+
+void trace_dump_blend_color(const struct pipe_blend_color *state);
+
+void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state);
+
+void trace_dump_sampler_state(const struct pipe_sampler_state *state);
+
+void trace_dump_surface(const struct pipe_surface *state);
+
+void trace_dump_transfer(const struct pipe_transfer *state);
+
+void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state);
+
+void trace_dump_vertex_element(const struct pipe_vertex_element *state);
+
+
+#endif /* TR_STATE_H */
diff --git a/src/gallium/drivers/trace/tr_rbug.c b/src/gallium/drivers/trace/tr_rbug.c
new file mode 100644
index 0000000000..e85ac15edc
--- /dev/null
+++ b/src/gallium/drivers/trace/tr_rbug.c
@@ -0,0 +1,864 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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_string.h"
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
+#include "util/u_network.h"
+
+#include "tgsi/tgsi_parse.h"
+
+#include "tr_dump.h"
+#include "tr_state.h"
+#include "tr_buffer.h"
+#include "tr_texture.h"
+
+#include "rbug/rbug.h"
+
+#include <errno.h>
+
+#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
+# define sleep Sleep
+#elif defined(PIPE_OS_LINUX)
+void usleep(int);
+# define sleep usleep
+#else
+# warning "No socket implementation"
+#endif
+
+#define U642VOID(x) ((void *)(unsigned long)(x))
+#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
+
+struct trace_rbug
+{
+ struct trace_screen *tr_scr;
+ struct rbug_connection *con;
+ pipe_thread thread;
+ boolean running;
+};
+
+PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug);
+
+
+/**********************************************************
+ * Helper functions
+ */
+
+
+static struct trace_context *
+trace_rbug_get_context_locked(struct trace_screen *tr_scr, rbug_context_t ctx)
+{
+ struct trace_context *tr_ctx = NULL;
+ struct tr_list *ptr;
+
+ foreach(ptr, &tr_scr->contexts) {
+ tr_ctx = (struct trace_context *)((char*)ptr - offsetof(struct trace_context, list));
+ if (ctx == VOID2U64(tr_ctx))
+ break;
+ tr_ctx = NULL;
+ }
+
+ return tr_ctx;
+}
+
+static struct trace_shader *
+trace_rbug_get_shader_locked(struct trace_context *tr_ctx, rbug_shader_t shdr)
+{
+ struct trace_shader *tr_shdr = NULL;
+ struct tr_list *ptr;
+
+ foreach(ptr, &tr_ctx->shaders) {
+ tr_shdr = (struct trace_shader *)((char*)ptr - offsetof(struct trace_shader, list));
+ if (shdr == VOID2U64(tr_shdr))
+ break;
+ tr_shdr = NULL;
+ }
+
+ return tr_shdr;
+}
+
+static void *
+trace_shader_create_locked(struct pipe_context *pipe,
+ struct trace_shader *tr_shdr,
+ struct tgsi_token *tokens)
+{
+ void *state = NULL;
+ struct pipe_shader_state pss = { 0 };
+ pss.tokens = tokens;
+
+ if (tr_shdr->type == TRACE_SHADER_FRAGMENT) {
+ state = pipe->create_fs_state(pipe, &pss);
+ } else if (tr_shdr->type == TRACE_SHADER_VERTEX) {
+ state = pipe->create_vs_state(pipe, &pss);
+ } else
+ assert(0);
+
+ return state;
+}
+
+static void
+trace_shader_bind_locked(struct pipe_context *pipe,
+ struct trace_shader *tr_shdr,
+ void *state)
+{
+ if (tr_shdr->type == TRACE_SHADER_FRAGMENT) {
+ pipe->bind_fs_state(pipe, state);
+ } else if (tr_shdr->type == TRACE_SHADER_VERTEX) {
+ pipe->bind_vs_state(pipe, state);
+ } else
+ assert(0);
+}
+
+static void
+trace_shader_delete_locked(struct pipe_context *pipe,
+ struct trace_shader *tr_shdr,
+ void *state)
+{
+ if (tr_shdr->type == TRACE_SHADER_FRAGMENT) {
+ pipe->delete_fs_state(pipe, state);
+ } else if (tr_shdr->type == TRACE_SHADER_VERTEX) {
+ pipe->delete_vs_state(pipe, state);
+ } else
+ assert(0);
+}
+
+/************************************************
+ * Request handler functions
+ */
+
+
+static int
+trace_rbug_texture_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_texture *tr_tex = NULL;
+ struct tr_list *ptr;
+ rbug_texture_t *texs;
+ int i = 0;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ texs = MALLOC(tr_scr->num_textures * sizeof(rbug_texture_t));
+ foreach(ptr, &tr_scr->textures) {
+ tr_tex = (struct trace_texture *)((char*)ptr - offsetof(struct trace_texture, list));
+ texs[i++] = VOID2U64(tr_tex);
+ }
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ rbug_send_texture_list_reply(tr_rbug->con, serial, texs, i, NULL);
+ FREE(texs);
+
+ return 0;
+}
+
+static int
+trace_rbug_texture_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_texture *tr_tex;
+ struct rbug_proto_texture_info *gpti = (struct rbug_proto_texture_info *)header;
+ struct tr_list *ptr;
+ struct pipe_texture *t;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ foreach(ptr, &tr_scr->textures) {
+ tr_tex = (struct trace_texture *)((char*)ptr - offsetof(struct trace_texture, list));
+ if (gpti->texture == VOID2U64(tr_tex))
+ break;
+ tr_tex = NULL;
+ }
+
+ if (!tr_tex) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ t = tr_tex->texture;
+ rbug_send_texture_info_reply(tr_rbug->con, serial,
+ t->target, t->format,
+ t->width, t->last_level + 1,
+ t->height, t->last_level + 1,
+ t->depth, t->last_level + 1,
+ t->block.width, t->block.height, t->block.size,
+ t->last_level,
+ t->nr_samples,
+ t->tex_usage,
+ NULL);
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_texture_read(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_texture_read *gptr = (struct rbug_proto_texture_read *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_texture *tr_tex;
+ struct tr_list *ptr;
+
+ struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_texture *tex;
+ struct pipe_transfer *t;
+
+ void *map;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ foreach(ptr, &tr_scr->textures) {
+ tr_tex = (struct trace_texture *)((char*)ptr - offsetof(struct trace_texture, list));
+ if (gptr->texture == VOID2U64(tr_tex))
+ break;
+ tr_tex = NULL;
+ }
+
+ if (!tr_tex) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ tex = tr_tex->texture;
+ t = screen->get_tex_transfer(tr_scr->screen, tex,
+ gptr->face, gptr->level, gptr->zslice,
+ PIPE_TRANSFER_READ,
+ gptr->x, gptr->y, gptr->w, gptr->h);
+
+ map = screen->transfer_map(screen, t);
+
+ rbug_send_texture_read_reply(tr_rbug->con, serial,
+ t->format,
+ t->block.width, t->block.height, t->block.size,
+ (uint8_t*)map, t->stride * t->nblocksy,
+ t->stride,
+ NULL);
+
+ screen->transfer_unmap(screen, t);
+ screen->tex_transfer_destroy(t);
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct tr_list *ptr;
+ struct trace_context *tr_ctx = NULL;
+ rbug_context_t *ctxs;
+ int i = 0;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ ctxs = MALLOC(tr_scr->num_contexts * sizeof(rbug_context_t));
+ foreach(ptr, &tr_scr->contexts) {
+ tr_ctx = (struct trace_context *)((char*)ptr - offsetof(struct trace_context, list));
+ ctxs[i++] = VOID2U64(tr_ctx);
+ }
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ rbug_send_context_list_reply(tr_rbug->con, serial, ctxs, i, NULL);
+ FREE(ctxs);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_context_info *info = (struct rbug_proto_context_info *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+ rbug_texture_t cbufs[PIPE_MAX_COLOR_BUFS];
+ rbug_texture_t texs[PIPE_MAX_SAMPLERS];
+ int i;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ /* protect the pipe context */
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+ trace_dump_call_lock();
+
+ for (i = 0; i < tr_ctx->curr.nr_cbufs; i++)
+ cbufs[i] = VOID2U64(tr_ctx->curr.cbufs[i]);
+
+ for (i = 0; i < tr_ctx->curr.num_texs; i++)
+ texs[i] = VOID2U64(tr_ctx->curr.tex[i]);
+
+ rbug_send_context_info_reply(tr_rbug->con, serial,
+ VOID2U64(tr_ctx->curr.vs), VOID2U64(tr_ctx->curr.fs),
+ texs, tr_ctx->curr.num_texs,
+ cbufs, tr_ctx->curr.nr_cbufs,
+ VOID2U64(tr_ctx->curr.zsbuf),
+ tr_ctx->draw_blocker, tr_ctx->draw_blocked, NULL);
+
+ trace_dump_call_unlock();
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_draw_block(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_context_draw_block *block = (struct rbug_proto_context_draw_block *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, block->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+ tr_ctx->draw_blocker |= block->block;
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_draw_step(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_context_draw_step *step = (struct rbug_proto_context_draw_step *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, step->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+ if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) {
+ if (step->step & RBUG_BLOCK_RULE)
+ tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK;
+ } else {
+ tr_ctx->draw_blocked &= ~step->step;
+ }
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+
+#ifdef PIPE_THREAD_HAVE_CONDVAR
+ pipe_condvar_broadcast(tr_ctx->draw_cond);
+#endif
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_draw_unblock(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_context_draw_unblock *unblock = (struct rbug_proto_context_draw_unblock *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, unblock->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+ if (tr_ctx->draw_blocked & RBUG_BLOCK_RULE) {
+ if (unblock->unblock & RBUG_BLOCK_RULE)
+ tr_ctx->draw_blocked &= ~RBUG_BLOCK_MASK;
+ } else {
+ tr_ctx->draw_blocked &= ~unblock->unblock;
+ }
+ tr_ctx->draw_blocker &= ~unblock->unblock;
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+
+#ifdef PIPE_THREAD_HAVE_CONDVAR
+ pipe_condvar_broadcast(tr_ctx->draw_cond);
+#endif
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_draw_rule(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_context_draw_rule *rule = (struct rbug_proto_context_draw_rule *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, rule->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->draw_mutex);
+ tr_ctx->draw_rule.vs = U642VOID(rule->vertex);
+ tr_ctx->draw_rule.fs = U642VOID(rule->fragment);
+ tr_ctx->draw_rule.tex = U642VOID(rule->texture);
+ tr_ctx->draw_rule.surf = U642VOID(rule->surface);
+ tr_ctx->draw_rule.blocker = rule->block;
+ tr_ctx->draw_blocker |= RBUG_BLOCK_RULE;
+ pipe_mutex_unlock(tr_ctx->draw_mutex);
+
+#ifdef PIPE_THREAD_HAVE_CONDVAR
+ pipe_condvar_broadcast(tr_ctx->draw_cond);
+#endif
+
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_context_flush(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_context_flush *flush = (struct rbug_proto_context_flush *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, flush->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ /* protect the pipe context */
+ trace_dump_call_lock();
+
+ tr_ctx->pipe->flush(tr_ctx->pipe, flush->flags, NULL);
+
+ trace_dump_call_unlock();
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_shader_list(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_shader_list *list = (struct rbug_proto_shader_list *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+ struct trace_shader *tr_shdr = NULL;
+ struct tr_list *ptr;
+ rbug_shader_t *shdrs;
+ int i = 0;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, list->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->list_mutex);
+ shdrs = MALLOC(tr_ctx->num_shaders * sizeof(rbug_shader_t));
+ foreach(ptr, &tr_ctx->shaders) {
+ tr_shdr = (struct trace_shader *)((char*)ptr - offsetof(struct trace_shader, list));
+ shdrs[i++] = VOID2U64(tr_shdr);
+ }
+
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ rbug_send_shader_list_reply(tr_rbug->con, serial, shdrs, i, NULL);
+ FREE(shdrs);
+
+ return 0;
+}
+
+static int
+trace_rbug_shader_info(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ struct rbug_proto_shader_info *info = (struct rbug_proto_shader_info *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+ struct trace_shader *tr_shdr = NULL;
+ unsigned original_len;
+ unsigned replaced_len;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, info->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->list_mutex);
+
+ tr_shdr = trace_rbug_get_shader_locked(tr_ctx, info->shader);
+
+ if (!tr_shdr) {
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ /* just in case */
+ assert(sizeof(struct tgsi_token) == 4);
+
+ original_len = tgsi_num_tokens(tr_shdr->tokens);
+ if (tr_shdr->replaced_tokens)
+ replaced_len = tgsi_num_tokens(tr_shdr->replaced_tokens);
+ else
+ replaced_len = 0;
+
+ rbug_send_shader_info_reply(tr_rbug->con, serial,
+ (uint32_t*)tr_shdr->tokens, original_len,
+ (uint32_t*)tr_shdr->replaced_tokens, replaced_len,
+ tr_shdr->disabled,
+ NULL);
+
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_shader_disable(struct trace_rbug *tr_rbug, struct rbug_header *header)
+{
+ struct rbug_proto_shader_disable *dis = (struct rbug_proto_shader_disable *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+ struct trace_shader *tr_shdr = NULL;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, dis->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->list_mutex);
+
+ tr_shdr = trace_rbug_get_shader_locked(tr_ctx, dis->shader);
+
+ if (!tr_shdr) {
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ tr_shdr->disabled = dis->disable;
+
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+}
+
+static int
+trace_rbug_shader_replace(struct trace_rbug *tr_rbug, struct rbug_header *header)
+{
+ struct rbug_proto_shader_replace *rep = (struct rbug_proto_shader_replace *)header;
+
+ struct trace_screen *tr_scr = tr_rbug->tr_scr;
+ struct trace_context *tr_ctx = NULL;
+ struct trace_shader *tr_shdr = NULL;
+ struct pipe_context *pipe = NULL;
+ void *state;
+
+ pipe_mutex_lock(tr_scr->list_mutex);
+ tr_ctx = trace_rbug_get_context_locked(tr_scr, rep->context);
+
+ if (!tr_ctx) {
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ pipe_mutex_lock(tr_ctx->list_mutex);
+
+ tr_shdr = trace_rbug_get_shader_locked(tr_ctx, rep->shader);
+
+ if (!tr_shdr) {
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -ESRCH;
+ }
+
+ /* protect the pipe context */
+ trace_dump_call_lock();
+
+ pipe = tr_ctx->pipe;
+
+ /* remove old replaced shader */
+ if (tr_shdr->replaced) {
+ if (tr_ctx->curr.fs == tr_shdr || tr_ctx->curr.vs == tr_shdr)
+ trace_shader_bind_locked(pipe, tr_shdr, tr_shdr->state);
+
+ FREE(tr_shdr->replaced_tokens);
+ trace_shader_delete_locked(pipe, tr_shdr, tr_shdr->replaced);
+ tr_shdr->replaced = NULL;
+ tr_shdr->replaced_tokens = NULL;
+ }
+
+ /* empty inputs means restore old which we did above */
+ if (rep->tokens_len == 0)
+ goto out;
+
+ tr_shdr->replaced_tokens = tgsi_dup_tokens((struct tgsi_token *)rep->tokens);
+ if (!tr_shdr->replaced_tokens)
+ goto err;
+
+ state = trace_shader_create_locked(pipe, tr_shdr, tr_shdr->replaced_tokens);
+ if (!state)
+ goto err;
+
+ /* bind new shader if the shader is currently a bound */
+ if (tr_ctx->curr.fs == tr_shdr || tr_ctx->curr.vs == tr_shdr)
+ trace_shader_bind_locked(pipe, tr_shdr, state);
+
+ /* save state */
+ tr_shdr->replaced = state;
+
+out:
+ trace_dump_call_unlock();
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+
+ return 0;
+
+err:
+ FREE(tr_shdr->replaced_tokens);
+ tr_shdr->replaced = NULL;
+ tr_shdr->replaced_tokens = NULL;
+
+ trace_dump_call_unlock();
+ pipe_mutex_unlock(tr_ctx->list_mutex);
+ pipe_mutex_unlock(tr_scr->list_mutex);
+ return -EINVAL;
+}
+
+static boolean
+trace_rbug_header(struct trace_rbug *tr_rbug, struct rbug_header *header, uint32_t serial)
+{
+ int ret = 0;
+
+ switch(header->opcode) {
+ case RBUG_OP_PING:
+ rbug_send_ping_reply(tr_rbug->con, serial, NULL);
+ break;
+ case RBUG_OP_TEXTURE_LIST:
+ ret = trace_rbug_texture_list(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_TEXTURE_INFO:
+ ret = trace_rbug_texture_info(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_TEXTURE_READ:
+ ret = trace_rbug_texture_read(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_LIST:
+ ret = trace_rbug_context_list(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_INFO:
+ ret = trace_rbug_context_info(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_DRAW_BLOCK:
+ ret = trace_rbug_context_draw_block(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_DRAW_STEP:
+ ret = trace_rbug_context_draw_step(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_DRAW_UNBLOCK:
+ ret = trace_rbug_context_draw_unblock(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_DRAW_RULE:
+ ret = trace_rbug_context_draw_rule(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_CONTEXT_FLUSH:
+ ret = trace_rbug_context_flush(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_SHADER_LIST:
+ ret = trace_rbug_shader_list(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_SHADER_INFO:
+ ret = trace_rbug_shader_info(tr_rbug, header, serial);
+ break;
+ case RBUG_OP_SHADER_DISABLE:
+ ret = trace_rbug_shader_disable(tr_rbug, header);
+ break;
+ case RBUG_OP_SHADER_REPLACE:
+ ret = trace_rbug_shader_replace(tr_rbug, header);
+ break;
+ default:
+ debug_printf("%s - unsupported opcode %u\n", __FUNCTION__, header->opcode);
+ ret = -ENOSYS;
+ break;
+ }
+ rbug_free_header(header);
+
+ if (ret)
+ rbug_send_error_reply(tr_rbug->con, serial, ret, NULL);
+
+ return TRUE;
+}
+
+static void
+trace_rbug_con(struct trace_rbug *tr_rbug)
+{
+ struct rbug_header *header;
+ uint32_t serial;
+
+ debug_printf("%s - connection received\n", __FUNCTION__);
+
+ while(tr_rbug->running) {
+ header = rbug_get_message(tr_rbug->con, &serial);
+ if (!header)
+ break;
+
+ if (!trace_rbug_header(tr_rbug, header, serial))
+ break;
+ }
+
+ debug_printf("%s - connection closed\n", __FUNCTION__);
+
+ rbug_disconnect(tr_rbug->con);
+ tr_rbug->con = NULL;
+}
+
+PIPE_THREAD_ROUTINE(trace_rbug_thread, void_tr_rbug)
+{
+ struct trace_rbug *tr_rbug = void_tr_rbug;
+ uint16_t port = 13370;
+ int s = -1;
+ int c;
+
+ u_socket_init();
+
+ for (;port <= 13379 && s < 0; port++)
+ s = u_socket_listen_on_port(port);
+
+ if (s < 0) {
+ debug_printf("trace_rbug - failed to listen\n");
+ return NULL;
+ }
+
+ u_socket_block(s, false);
+
+ debug_printf("trace_rbug - remote debugging listening on port %u\n", --port);
+
+ while(tr_rbug->running) {
+ sleep(1);
+
+ c = u_socket_accept(s);
+ if (c < 0)
+ continue;
+
+ u_socket_block(c, true);
+ tr_rbug->con = rbug_from_socket(c);
+
+ trace_rbug_con(tr_rbug);
+
+ u_socket_close(c);
+ }
+
+ u_socket_close(s);
+
+ u_socket_stop();
+
+ return NULL;
+}
+
+/**********************************************************
+ *
+ */
+
+struct trace_rbug *
+trace_rbug_start(struct trace_screen *tr_scr)
+{
+ struct trace_rbug *tr_rbug = CALLOC_STRUCT(trace_rbug);
+ if (!tr_rbug)
+ return NULL;
+
+ tr_rbug->tr_scr = tr_scr;
+ tr_rbug->running = TRUE;
+ tr_rbug->thread = pipe_thread_create(trace_rbug_thread, tr_rbug);
+
+ return tr_rbug;
+}
+
+void
+trace_rbug_stop(struct trace_rbug *tr_rbug)
+{
+ if (!tr_rbug)
+ return;
+
+ tr_rbug->running = false;
+ pipe_thread_wait(tr_rbug->thread);
+
+ FREE(tr_rbug);
+
+ return;
+}
+
+void
+trace_rbug_notify_draw_blocked(struct trace_context *tr_ctx)
+{
+ struct trace_screen *tr_scr = trace_screen(tr_ctx->base.screen);
+ struct trace_rbug *tr_rbug = tr_scr->rbug;
+
+ if (tr_rbug && tr_rbug->con)
+ rbug_send_context_draw_blocked(tr_rbug->con,
+ VOID2U64(tr_ctx), tr_ctx->draw_blocked, NULL);
+}
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 6792505383..920f418ebf 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -26,16 +26,19 @@
**************************************************************************/
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "tr_buffer.h"
#include "tr_dump.h"
-#include "tr_state.h"
+#include "tr_dump_state.h"
#include "tr_texture.h"
#include "tr_screen.h"
#include "pipe/p_inlines.h"
+static boolean trace = FALSE;
+
static const char *
trace_screen_get_name(struct pipe_screen *_screen)
{
@@ -211,10 +214,12 @@ 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 pipe_buffer *_buffer)
{
struct trace_screen *tr_scr = trace_screen(_screen);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_buffer *buffer = tr_buf->buffer;
unsigned pitch = *ppitch;
struct pipe_texture *result;
@@ -603,7 +608,7 @@ trace_screen_buffer_map(struct pipe_screen *_screen,
unsigned usage)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
void *map;
@@ -628,7 +633,7 @@ trace_screen_buffer_map_range(struct pipe_screen *_screen,
unsigned usage)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
void *map;
@@ -680,7 +685,7 @@ trace_screen_buffer_flush_mapped_range(struct pipe_screen *_screen,
unsigned length)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
@@ -696,7 +701,7 @@ trace_screen_buffer_unmap(struct pipe_screen *_screen,
struct pipe_buffer *_buffer)
{
struct trace_screen *tr_scr = trace_screen(_screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
@@ -712,7 +717,7 @@ static void
trace_screen_buffer_destroy(struct pipe_buffer *_buffer)
{
struct trace_screen *tr_scr = trace_screen(_buffer->screen);
- struct trace_buffer *tr_buf = trace_buffer(tr_scr, _buffer);
+ struct trace_buffer *tr_buf = trace_buffer(_buffer);
struct pipe_screen *screen = tr_scr->screen;
struct pipe_buffer *buffer = tr_buf->buffer;
@@ -734,19 +739,23 @@ trace_screen_buffer_destroy(struct pipe_buffer *_buffer)
static void
trace_screen_fence_reference(struct pipe_screen *_screen,
- struct pipe_fence_handle **dst,
+ struct pipe_fence_handle **pdst,
struct pipe_fence_handle *src)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
+ struct pipe_fence_handle *dst;
+ assert(pdst);
+ dst = *pdst;
+
trace_dump_call_begin("pipe_screen", "fence_reference");
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, dst);
trace_dump_arg(ptr, src);
- screen->fence_reference(screen, dst, src);
+ screen->fence_reference(screen, pdst, src);
trace_dump_call_end();
}
@@ -755,7 +764,7 @@ trace_screen_fence_reference(struct pipe_screen *_screen,
static int
trace_screen_fence_signalled(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flag)
+ unsigned flags)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -765,9 +774,9 @@ trace_screen_fence_signalled(struct pipe_screen *_screen,
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
- trace_dump_arg(uint, flag);
+ trace_dump_arg(uint, flags);
- result = screen->fence_signalled(screen, fence, flag);
+ result = screen->fence_signalled(screen, fence, flags);
trace_dump_ret(int, result);
@@ -780,7 +789,7 @@ trace_screen_fence_signalled(struct pipe_screen *_screen,
static int
trace_screen_fence_finish(struct pipe_screen *_screen,
struct pipe_fence_handle *fence,
- unsigned flag)
+ unsigned flags)
{
struct trace_screen *tr_scr = trace_screen(_screen);
struct pipe_screen *screen = tr_scr->screen;
@@ -790,9 +799,9 @@ trace_screen_fence_finish(struct pipe_screen *_screen,
trace_dump_arg(ptr, screen);
trace_dump_arg(ptr, fence);
- trace_dump_arg(uint, flag);
+ trace_dump_arg(uint, flags);
- result = screen->fence_finish(screen, fence, flag);
+ result = screen->fence_finish(screen, fence, flags);
trace_dump_ret(int, result);
@@ -813,29 +822,47 @@ trace_screen_destroy(struct pipe_screen *_screen)
struct pipe_screen *screen = tr_scr->screen;
trace_dump_call_begin("pipe_screen", "destroy");
-
trace_dump_arg(ptr, screen);
-
- screen->destroy(screen);
-
trace_dump_call_end();
-
trace_dump_trace_end();
+ if (tr_scr->rbug)
+ trace_rbug_stop(tr_scr->rbug);
+
+ screen->destroy(screen);
+
FREE(tr_scr);
}
+boolean
+trace_enabled(void)
+{
+ return trace;
+}
struct pipe_screen *
trace_screen_create(struct pipe_screen *screen)
{
struct trace_screen *tr_scr;
struct pipe_winsys *winsys;
+ boolean rbug = FALSE;
if(!screen)
goto error1;
- if(!trace_dump_trace_begin())
+ trace_dump_init();
+
+ if(trace_dump_trace_begin()) {
+ trace_dumping_start();
+ trace = TRUE;
+ }
+
+ if (debug_get_bool_option("GALLIUM_RBUG", FALSE)) {
+ trace = TRUE;
+ rbug = TRUE;
+ }
+
+ if (!trace)
goto error1;
trace_dump_call_begin("", "pipe_screen_create");
@@ -851,6 +878,12 @@ trace_screen_create(struct pipe_screen *screen)
#else
winsys = screen->winsys;
#endif
+ pipe_mutex_init(tr_scr->list_mutex);
+ make_empty_list(&tr_scr->buffers);
+ make_empty_list(&tr_scr->contexts);
+ make_empty_list(&tr_scr->textures);
+ make_empty_list(&tr_scr->surfaces);
+ make_empty_list(&tr_scr->transfers);
tr_scr->base.winsys = winsys;
tr_scr->base.destroy = trace_screen_destroy;
@@ -889,6 +922,9 @@ trace_screen_create(struct pipe_screen *screen)
trace_dump_ret(ptr, screen);
trace_dump_call_end();
+ if (rbug)
+ tr_scr->rbug = trace_rbug_start(tr_scr);
+
return &tr_scr->base;
#if 0
diff --git a/src/gallium/drivers/trace/tr_screen.h b/src/gallium/drivers/trace/tr_screen.h
index 8c65516b50..dba8cd7c65 100644
--- a/src/gallium/drivers/trace/tr_screen.h
+++ b/src/gallium/drivers/trace/tr_screen.h
@@ -30,6 +30,7 @@
#include "pipe/p_screen.h"
+#include "pipe/p_thread.h"
#ifdef __cplusplus
@@ -37,6 +38,11 @@ extern "C" {
#endif
+struct tr_list {
+ struct tr_list *next;
+ struct tr_list *prev;
+};
+
/**
* It often happens that new data is written directly to the user buffers
* without mapping/unmapping. This flag marks user buffers, so that their
@@ -50,21 +56,72 @@ struct trace_screen
struct pipe_screen base;
struct pipe_screen *screen;
+
+ /* remote debugger */
+ struct trace_rbug *rbug;
+
+ pipe_mutex list_mutex;
+ int num_buffers;
+ int num_contexts;
+ int num_textures;
+ int num_surfaces;
+ int num_transfers;
+ struct tr_list buffers;
+ struct tr_list contexts;
+ struct tr_list textures;
+ struct tr_list surfaces;
+ struct tr_list transfers;
};
+/*
+ * tr_rbug.c
+ */
+
+
+struct trace_rbug;
+
+struct trace_rbug *
+trace_rbug_start(struct trace_screen *tr_scr);
+
+void
+trace_rbug_stop(struct trace_rbug *tr_rbug);
+
+
+/*
+ * tr_screen.c
+ */
+
+
+boolean
+trace_enabled(void);
+
struct trace_screen *
trace_screen(struct pipe_screen *screen);
-
struct pipe_screen *
trace_screen_create(struct pipe_screen *screen);
-
void
trace_screen_user_buffer_update(struct pipe_screen *screen,
struct pipe_buffer *buffer);
+#define trace_screen_add_to_list(tr_scr, name, obj) \
+ do { \
+ pipe_mutex_lock(tr_scr->list_mutex); \
+ insert_at_head(&tr_scr->name, &obj->list); \
+ tr_scr->num_##name++; \
+ pipe_mutex_unlock(tr_scr->list_mutex); \
+ } while (0)
+
+#define trace_screen_remove_from_list(tr_scr, name, obj) \
+ do { \
+ pipe_mutex_lock(tr_scr->list_mutex); \
+ remove_from_list(&obj->list); \
+ tr_scr->num_##name--; \
+ pipe_mutex_unlock(tr_scr->list_mutex); \
+ } while (0)
+
#ifdef __cplusplus
}
diff --git a/src/gallium/drivers/trace/tr_state.c b/src/gallium/drivers/trace/tr_state.c
index a9570c1aeb..d8c11640bf 100644
--- a/src/gallium/drivers/trace/tr_state.c
+++ b/src/gallium/drivers/trace/tr_state.c
@@ -1,491 +1,66 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+/*
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * 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
+ * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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.
*
- **************************************************************************/
-
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VMWARE 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 "pipe/p_compiler.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_dump.h"
-
-#include "tr_dump.h"
#include "tr_state.h"
+#include "util/u_memory.h"
+#include "util/u_simple_list.h"
-void trace_dump_format(enum pipe_format format)
-{
- trace_dump_enum(pf_name(format) );
-}
-
-
-void trace_dump_block(const struct pipe_format_block *block)
-{
- 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();
-}
-
-
-static void trace_dump_reference(const struct pipe_reference *reference)
-{
- trace_dump_struct_begin("pipe_reference");
- trace_dump_member(int, &reference->count, count);
- trace_dump_struct_end();
-}
-
-
-void trace_dump_template(const struct pipe_texture *templat)
-{
- if(!templat) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_texture");
-
- trace_dump_member(int, templat, target);
- trace_dump_member(format, templat, format);
-
- trace_dump_member_begin("width");
- trace_dump_array(uint, templat->width, 1);
- trace_dump_member_end();
-
- trace_dump_member_begin("height");
- trace_dump_array(uint, templat->height, 1);
- trace_dump_member_end();
-
- trace_dump_member_begin("depth");
- trace_dump_array(uint, templat->depth, 1);
- trace_dump_member_end();
-
- trace_dump_member_begin("block");
- trace_dump_block(&templat->block);
- trace_dump_member_end();
-
- trace_dump_member(uint, templat, last_level);
- trace_dump_member(uint, templat, tex_usage);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- 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_vs_clip_and_viewport);
- 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(uint, state, sprite_coord_mode);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_poly_stipple(const struct pipe_poly_stipple *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_poly_stipple");
-
- trace_dump_member_begin("stipple");
- trace_dump_array(uint,
- state->stipple,
- Elements(state->stipple));
- trace_dump_member_end();
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_viewport_state(const struct pipe_viewport_state *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_viewport_state");
-
- trace_dump_member_array(float, state, scale);
- trace_dump_member_array(float, state, translate);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_scissor_state(const struct pipe_scissor_state *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_scissor_state");
-
- 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();
-}
-
-
-void trace_dump_clip_state(const struct pipe_clip_state *state)
-{
- unsigned i;
-
- if(!state) {
- trace_dump_null();
- return;
- }
-
- 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) {
- trace_dump_elem_begin();
- trace_dump_array(float, state->ucp[i], 4);
- trace_dump_elem_end();
- }
- trace_dump_array_end();
- trace_dump_member_end();
-
- trace_dump_member(uint, state, nr);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_constant_buffer(const struct pipe_constant_buffer *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_constant_buffer");
-
- trace_dump_member(buffer_ptr, state, buffer);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_shader_state(const struct pipe_shader_state *state)
-{
- static char str[8192];
-
- if(!state) {
- trace_dump_null();
- return;
- }
-
- tgsi_dump_str(state->tokens, 0, str, sizeof(str));
-
- trace_dump_struct_begin("pipe_shader_state");
-
- trace_dump_member_begin("tokens");
- trace_dump_string(str);
- trace_dump_member_end();
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state)
-{
- unsigned i;
-
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_depth_stencil_alpha_state");
-
- 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("stencil");
- trace_dump_array_begin();
- for(i = 0; i < Elements(state->stencil); ++i) {
- 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], valuemask);
- trace_dump_member(uint, &state->stencil[i], writemask);
- trace_dump_struct_end();
- trace_dump_elem_end();
- }
- 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_value);
- trace_dump_struct_end();
- trace_dump_member_end();
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_blend_state(const struct pipe_blend_state *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_blend_state");
-
- trace_dump_member(bool, state, blend_enable);
-
- 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(uint, state, alpha_func);
- trace_dump_member(uint, state, alpha_src_factor);
- trace_dump_member(uint, state, alpha_dst_factor);
-
- trace_dump_member(bool, state, logicop_enable);
- trace_dump_member(uint, state, logicop_func);
-
- trace_dump_member(uint, state, colormask);
- trace_dump_member(bool, state, dither);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_blend_color(const struct pipe_blend_color *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_blend_color");
-
- trace_dump_member_array(float, state, color);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state)
-{
- trace_dump_struct_begin("pipe_framebuffer_state");
-
- trace_dump_member(uint, state, width);
- trace_dump_member(uint, state, height);
- trace_dump_member(uint, state, nr_cbufs);
- trace_dump_member_array(ptr, state, cbufs);
- trace_dump_member(ptr, state, zsbuf);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_sampler_state(const struct pipe_sampler_state *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- 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(const struct pipe_surface *state)
-{
- if(!state) {
- trace_dump_null();
- return;
- }
-
- trace_dump_struct_begin("pipe_surface");
-
- trace_dump_reference(&state->reference);
-
- trace_dump_member(format, state, format);
- trace_dump_member(uint, state, width);
- trace_dump_member(uint, state, height);
-
- trace_dump_member(uint, state, layout);
- trace_dump_member(uint, state, offset);
- 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();
-}
-
+#include "tgsi/tgsi_parse.h"
-void trace_dump_transfer(const struct pipe_transfer *state)
+struct trace_shader * trace_shader_create(struct trace_context *tr_ctx,
+ const struct pipe_shader_state *state,
+ void *result,
+ enum trace_shader_type type)
{
- if(!state) {
- trace_dump_null();
- return;
- }
+ struct trace_shader *tr_shdr = CALLOC_STRUCT(trace_shader);
- trace_dump_struct_begin("pipe_transfer");
+ tr_shdr->state = result;
+ tr_shdr->type = type;
+ tr_shdr->tokens = tgsi_dup_tokens(state->tokens);
- trace_dump_member(format, state, format);
- trace_dump_member(uint, state, width);
- trace_dump_member(uint, state, height);
+ /* works on context as well */
+ trace_screen_add_to_list(tr_ctx, shaders, tr_shdr);
- trace_dump_member_begin("block");
- trace_dump_block(&state->block);
- trace_dump_member_end();
-
- trace_dump_member(uint, state, nblocksx);
- trace_dump_member(uint, state, nblocksy);
- trace_dump_member(uint, state, stride);
- 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();
+ return tr_shdr;
}
-
-void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state)
+void trace_shader_destroy(struct trace_context *tr_ctx,
+ struct trace_shader *tr_shdr)
{
- if(!state) {
- trace_dump_null();
- return;
- }
+ trace_screen_remove_from_list(tr_ctx, shaders, tr_shdr);
- trace_dump_struct_begin("pipe_vertex_buffer");
-
- trace_dump_member(uint, state, stride);
- trace_dump_member(uint, state, max_index);
- trace_dump_member(uint, state, buffer_offset);
- trace_dump_member(buffer_ptr, state, buffer);
-
- trace_dump_struct_end();
-}
-
-
-void trace_dump_vertex_element(const struct pipe_vertex_element *state)
-{
- if(!state) {
- trace_dump_null();
- return;
+ if (tr_shdr->replaced) {
+ if (tr_shdr->type == TRACE_SHADER_FRAGMENT)
+ tr_ctx->pipe->delete_fs_state(tr_ctx->pipe, tr_shdr->replaced);
+ else if (tr_shdr->type == TRACE_SHADER_VERTEX)
+ tr_ctx->pipe->delete_vs_state(tr_ctx->pipe, tr_shdr->replaced);
+ else
+ assert(0);
}
- trace_dump_struct_begin("pipe_vertex_element");
-
- trace_dump_member(uint, state, src_offset);
-
- trace_dump_member(uint, state, vertex_buffer_index);
- trace_dump_member(uint, state, nr_components);
-
- trace_dump_member(format, state, src_format);
-
- trace_dump_struct_end();
+ FREE(tr_shdr->replaced_tokens);
+ FREE(tr_shdr->tokens);
+ FREE(tr_shdr);
}
diff --git a/src/gallium/drivers/trace/tr_state.h b/src/gallium/drivers/trace/tr_state.h
index 513ed0ac98..1c16042ee5 100644
--- a/src/gallium/drivers/trace/tr_state.h
+++ b/src/gallium/drivers/trace/tr_state.h
@@ -1,78 +1,68 @@
-/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+/*
+ * Copyright 2009 VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * 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
+ * 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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.
*
- **************************************************************************/
-
-#ifndef TR_STATE_H
-#define TR_STATE_H
-
-#include "pipe/p_format.h"
-#include "pipe/p_state.h"
-#include "pipe/p_shader_tokens.h"
-
-
-void trace_dump_format(enum pipe_format format);
-
-void trace_dump_block(const struct pipe_format_block *block);
-
-void trace_dump_template(const struct pipe_texture *templat);
-
-
-void trace_dump_rasterizer_state(const struct pipe_rasterizer_state *state);
-
-void trace_dump_poly_stipple(const struct pipe_poly_stipple *state);
-
-void trace_dump_viewport_state(const struct pipe_viewport_state *state);
-
-void trace_dump_scissor_state(const struct pipe_scissor_state *state);
-
-void trace_dump_clip_state(const struct pipe_clip_state *state);
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VMWARE 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.
+ */
-void trace_dump_constant_buffer(const struct pipe_constant_buffer *state);
+#ifndef TR_STATE_H_
+#define TR_STATE_H_
-void trace_dump_token(const struct tgsi_token *token);
+#include "tr_context.h"
-void trace_dump_shader_state(const struct pipe_shader_state *state);
+struct tgsi_token;
-void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_state *state);
+enum trace_shader_type {
+ TRACE_SHADER_FRAGMENT = 0,
+ TRACE_SHADER_VERTEX = 1,
+ TRACE_SHADER_GEOMETRY = 2,
+};
-void trace_dump_blend_state(const struct pipe_blend_state *state);
+struct trace_shader
+{
+ struct tr_list list;
-void trace_dump_blend_color(const struct pipe_blend_color *state);
+ enum trace_shader_type type;
-void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state);
+ void *state;
+ void *replaced;
-void trace_dump_sampler_state(const struct pipe_sampler_state *state);
+ struct tgsi_token *tokens;
+ struct tgsi_token *replaced_tokens;
-void trace_dump_surface(const struct pipe_surface *state);
+ boolean disabled;
+};
-void trace_dump_transfer(const struct pipe_transfer *state);
-void trace_dump_vertex_buffer(const struct pipe_vertex_buffer *state);
+static INLINE struct trace_shader *
+trace_shader(void *state)
+{
+ return (struct trace_shader *)state;
+}
-void trace_dump_vertex_element(const struct pipe_vertex_element *state);
+struct trace_shader * trace_shader_create(struct trace_context *tr_ctx,
+ const struct pipe_shader_state *state,
+ void *result,
+ enum trace_shader_type type);
+void trace_shader_destroy(struct trace_context *tr_ctx,
+ struct trace_shader *tr_shdr);
-#endif /* TR_STATE_H */
+#endif
diff --git a/src/gallium/drivers/trace/tr_texture.c b/src/gallium/drivers/trace/tr_texture.c
index f4e433792b..1f25fe38d4 100644
--- a/src/gallium/drivers/trace/tr_texture.c
+++ b/src/gallium/drivers/trace/tr_texture.c
@@ -27,6 +27,7 @@
#include "util/u_hash_table.h"
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "tr_screen.h"
#include "tr_texture.h"
@@ -53,6 +54,8 @@ trace_texture_create(struct trace_screen *tr_scr,
tr_tex->base.screen = &tr_scr->base;
tr_tex->texture = texture;
+ trace_screen_add_to_list(tr_scr, textures, tr_tex);
+
return &tr_tex->base;
error:
@@ -64,6 +67,10 @@ error:
void
trace_texture_destroy(struct trace_texture *tr_tex)
{
+ struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
+
+ trace_screen_remove_from_list(tr_scr, textures, tr_tex);
+
pipe_texture_reference(&tr_tex->texture, NULL);
FREE(tr_tex);
}
@@ -73,6 +80,7 @@ struct pipe_surface *
trace_surface_create(struct trace_texture *tr_tex,
struct pipe_surface *surface)
{
+ struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
struct trace_surface *tr_surf;
if(!surface)
@@ -91,6 +99,8 @@ trace_surface_create(struct trace_texture *tr_tex,
pipe_texture_reference(&tr_surf->base.texture, &tr_tex->base);
tr_surf->surface = surface;
+ trace_screen_add_to_list(tr_scr, surfaces, tr_surf);
+
return &tr_surf->base;
error:
@@ -102,6 +112,10 @@ error:
void
trace_surface_destroy(struct trace_surface *tr_surf)
{
+ struct trace_screen *tr_scr = trace_screen(tr_surf->base.texture->screen);
+
+ trace_screen_remove_from_list(tr_scr, surfaces, tr_surf);
+
pipe_texture_reference(&tr_surf->base.texture, NULL);
pipe_surface_reference(&tr_surf->surface, NULL);
FREE(tr_surf);
@@ -112,6 +126,7 @@ struct pipe_transfer *
trace_transfer_create(struct trace_texture *tr_tex,
struct pipe_transfer *transfer)
{
+ struct trace_screen *tr_scr = trace_screen(tr_tex->base.screen);
struct trace_transfer *tr_trans;
if(!transfer)
@@ -130,6 +145,8 @@ trace_transfer_create(struct trace_texture *tr_tex,
tr_trans->transfer = transfer;
assert(tr_trans->base.texture == &tr_tex->base);
+ trace_screen_add_to_list(tr_scr, transfers, tr_trans);
+
return &tr_trans->base;
error:
@@ -141,7 +158,11 @@ error:
void
trace_transfer_destroy(struct trace_transfer *tr_trans)
{
+ struct trace_screen *tr_scr = trace_screen(tr_trans->base.texture->screen);
struct pipe_screen *screen = tr_trans->transfer->texture->screen;
+
+ trace_screen_remove_from_list(tr_scr, transfers, tr_trans);
+
pipe_texture_reference(&tr_trans->base.texture, NULL);
screen->tex_transfer_destroy(tr_trans->transfer);
FREE(tr_trans);
diff --git a/src/gallium/drivers/trace/tr_texture.h b/src/gallium/drivers/trace/tr_texture.h
index 14dafd8b2c..395e523e73 100644
--- a/src/gallium/drivers/trace/tr_texture.h
+++ b/src/gallium/drivers/trace/tr_texture.h
@@ -40,6 +40,8 @@ struct trace_texture
struct pipe_texture base;
struct pipe_texture *texture;
+
+ struct tr_list list;
};
@@ -48,6 +50,8 @@ struct trace_surface
struct pipe_surface base;
struct pipe_surface *surface;
+
+ struct tr_list list;
};
@@ -57,6 +61,8 @@ struct trace_transfer
struct pipe_transfer *transfer;
+ struct tr_list list;
+
void *map;
};
diff --git a/src/gallium/include/pipe/p_atomic.h b/src/gallium/include/pipe/p_atomic.h
index f2fe083efa..0c3fbae428 100644
--- a/src/gallium/include/pipe/p_atomic.h
+++ b/src/gallium/include/pipe/p_atomic.h
@@ -18,58 +18,29 @@ extern "C" {
/* Favor OS-provided implementations.
+ *
+ * Where no OS-provided implementation is available, fall back to
+ * locally coded assembly, compiler intrinsic or ultimately a
+ * mutex-based implementation.
*/
-#define PIPE_ATOMIC_OS_UNLOCKED \
- (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \
- defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT))
-
-#define PIPE_ATOMIC_OS_MS_INTERLOCK \
- (!defined(PIPE_CC_GCC) && \
- !PIPE_ATOMIC_OS_UNLOCKED && \
- defined(PIPE_SUBSYSTEM_WINDOWS_USER))
-
-#define PIPE_ATOMIC_OS_PROVIDED \
- (PIPE_ATOMIC_OS_UNLOCKED || \
- PIPE_ATOMIC_OS_MS_INTERLOCK)
-
-/* Where no OS-provided implementation is available, fall back to
- * either locally coded assembly or ultimately a mutex-based
- * implementation:
- */
-#define PIPE_ATOMIC_ASM_GCC_X86 \
- (!PIPE_ATOMIC_OS_PROVIDED && \
- defined(PIPE_CC_GCC) && \
- defined(PIPE_ARCH_X86))
-
-/* KW: this was originally used when x86 asm wasn't available.
- * Maintain that logic here.
- */
-#define PIPE_ATOMIC_GCC_INTRINISIC \
- (!PIPE_ATOMIC_OS_PROVIDED && \
- !PIPE_ATOMIC_ASM_GCC_X86 && \
- defined(PIPE_CC_GCC))
-
-#define PIPE_ATOMIC_ASM_MSVC_X86 \
- (!PIPE_ATOMIC_OS_PROVIDED && \
- defined(PIPE_CC_MSVC) && \
- defined(PIPE_ARCH_X86))
-
-#define PIPE_ATOMIC_ASM \
- (PIPE_ATOMIC_ASM_GCC_X86 || \
- PIPE_ATOMIC_ASM_GCC_INTRINSIC || \
- PIPE_ATOMIC_ASM_MSVC_X86)
-
-
-/* Where no OS-provided or locally-coded assembly implemenation is
- * available, use pipe_mutex:
- */
-#define PIPE_ATOMIC_MUTEX \
- (!PIPE_ATOMIC_OS_PROVIDED && \
- !PIPE_ATOMIC_ASM)
+#if (defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || \
+ defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT))
+#define PIPE_ATOMIC_OS_UNLOCKED
+#elif (defined(PIPE_CC_MSVC) && defined(PIPE_SUBSYSTEM_WINDOWS_USER))
+#define PIPE_ATOMIC_OS_MS_INTERLOCK
+#elif (defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86))
+#define PIPE_ATOMIC_ASM_MSVC_X86
+#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86))
+#define PIPE_ATOMIC_ASM_GCC_X86
+#elif defined(PIPE_CC_GCC)
+#define PIPE_ATOMIC_GCC_INTRINSIC
+#else
+#define PIPE_ATOMIC_MUTEX
+#endif
-#if (PIPE_ATOMIC_ASM_GCC_X86)
+#if defined(PIPE_ATOMIC_ASM_GCC_X86)
#define PIPE_ATOMIC "GCC x86 assembly"
@@ -115,7 +86,7 @@ p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new)
/* Implementation using GCC-provided synchronization intrinsics
*/
-#if (PIPE_ATOMIC_ASM_GCC_INTRINSIC)
+#if defined(PIPE_ATOMIC_GCC_INTRINSIC)
#define PIPE_ATOMIC "GCC Sync Intrinsics"
@@ -157,7 +128,7 @@ p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new)
/* Unlocked version for single threaded environments, such as some
* windows kernel modules.
*/
-#if (PIPE_ATOMIC_OS_UNLOCKED)
+#if defined(PIPE_ATOMIC_OS_UNLOCKED)
#define PIPE_ATOMIC "Unlocked"
@@ -178,7 +149,7 @@ struct pipe_atomic
/* Locally coded assembly for MSVC on x86:
*/
-#if (PIPE_ATOMIC_ASM_MSVC_X86)
+#if defined(PIPE_ATOMIC_ASM_MSVC_X86)
#define PIPE_ATOMIC "MSVC x86 assembly"
@@ -246,7 +217,7 @@ p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new)
#endif
-#if (PIPE_ATOMIC_OS_MS_INTERLOCK)
+#if defined(PIPE_ATOMIC_OS_MS_INTERLOCK)
#define PIPE_ATOMIC "MS userspace interlocks"
@@ -254,7 +225,7 @@ p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new)
struct pipe_atomic
{
- long count;
+ volatile long count;
};
#define p_atomic_set(_v, _i) ((_v)->count = (_i))
@@ -263,7 +234,7 @@ struct pipe_atomic
static INLINE boolean
p_atomic_dec_zero(struct pipe_atomic *v)
{
- return InterlockedDecrement(&v->count);
+ return InterlockedDecrement(&v->count) == 0;
}
static INLINE void
@@ -288,7 +259,7 @@ p_atomic_cmpxchg(struct pipe_atomic *v, int32_t old, int32_t _new)
-#if (PIPE_ATOMIC_MUTEX)
+#if defined(PIPE_ATOMIC_MUTEX)
#define PIPE_ATOMIC "mutex-based fallback"
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 29095dcdc3..57e966ac3b 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -42,7 +42,6 @@ struct pipe_state_cache;
struct pipe_query;
struct pipe_winsys;
-
/**
* Gallium rendering context. Basically:
* - state setting functions
@@ -192,14 +191,21 @@ struct pipe_context {
* Surface functions
*/
/*@{*/
+
+ /**
+ * Copy a block of pixels from one surface to another.
+ * The surfaces must be of the same format.
+ */
void (*surface_copy)(struct pipe_context *pipe,
struct pipe_surface *dest,
unsigned destx, unsigned desty,
- struct pipe_surface *src, /* don't make this const -
- need to map/unmap */
+ struct pipe_surface *src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height);
+ /**
+ * Fill a region of a surface with a constant value.
+ */
void (*surface_fill)(struct pipe_context *pipe,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
@@ -224,6 +230,34 @@ struct pipe_context {
void (*flush)( struct pipe_context *pipe,
unsigned flags,
struct pipe_fence_handle **fence );
+
+ /**
+ * Check whether a texture is referenced by an unflushed hw command.
+ * The state-tracker uses this function to optimize away unnecessary
+ * flushes. It is safe (but wasteful) to always return.
+ * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
+ * \param pipe The pipe context whose unflushed hw commands will be
+ * checked.
+ * \param level mipmap level.
+ * \param texture texture to check.
+ * \param face cubemap face. Use 0 for non-cubemap texture.
+ */
+
+ unsigned int (*is_texture_referenced) (struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level);
+ /**
+ * Check whether a buffer is referenced by an unflushed hw command.
+ * The state-tracker uses this function to optimize away unnecessary
+ * flushes. It is safe (but wasteful) to always return
+ * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE.
+ * \param pipe The pipe context whose unflushed hw commands will be
+ * checked.
+ * \param buf Buffer to check.
+ */
+
+ unsigned int (*is_buffer_referenced) (struct pipe_context *pipe,
+ struct pipe_buffer *buf);
};
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 81defa445b..9924046cb2 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -132,6 +132,7 @@ enum pipe_texture_target {
#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
#define PIPE_TEX_WRAP_REPEAT 0
#define PIPE_TEX_WRAP_CLAMP 1
@@ -158,14 +159,6 @@ enum pipe_texture_target {
#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
-
#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 */
@@ -200,7 +193,7 @@ enum pipe_texture_target {
enum pipe_transfer_usage {
PIPE_TRANSFER_READ,
PIPE_TRANSFER_WRITE,
- PIPE_TRANSFER_READ_WRITE //< Read/modify/write
+ PIPE_TRANSFER_READ_WRITE /**< Read/modify/write */
};
@@ -280,9 +273,8 @@ enum pipe_transfer_usage {
/**
- * Implementation capabilities/limits
- * Passed to pipe->get_param()
- * XXX this will need some fine tuning...
+ * Implementation capabilities/limits which are queried through
+ * pipe_screen::get_param() and pipe_screen::get_paramf().
*/
#define PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS 1
#define PIPE_CAP_NPOT_TEXTURES 2
@@ -312,6 +304,13 @@ enum pipe_transfer_usage {
#define PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS 26
+/**
+ * Referenced query flags.
+ */
+
+#define PIPE_UNREFERENCED 0
+#define PIPE_REFERENCED_FOR_READ (1 << 0)
+#define PIPE_REFERENCED_FOR_WRITE (1 << 1)
#ifdef __cplusplus
}
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index a279eefef9..e31538c95f 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -536,14 +536,36 @@ 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 size_t
+pf_get_stride(const struct pipe_format_block *block, unsigned width)
+{
+ return pf_get_nblocksx(block, width)*block->size;
+}
+
+static INLINE size_t
+pf_get_2d_size(const struct pipe_format_block *block, size_t stride, unsigned height)
+{
+ return pf_get_nblocksy(block, height)*stride;
+}
+
static INLINE boolean
-pf_is_depth_stencil( enum pipe_format format )
+pf_is_depth_or_stencil( enum pipe_format format )
{
return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) +
pf_get_component_bits( format, PIPE_FORMAT_COMP_S )) != 0;
}
static INLINE boolean
+pf_is_depth_and_stencil( enum pipe_format format )
+{
+ return (pf_get_component_bits( format, PIPE_FORMAT_COMP_Z ) != 0 &&
+ pf_get_component_bits( format, PIPE_FORMAT_COMP_S ) != 0);
+}
+
+/** DEPRECATED: For backwards compatibility */
+#define pf_is_depth_stencil pf_is_depth_or_stencil
+
+static INLINE boolean
pf_is_compressed( enum pipe_format format )
{
return pf_layout(format) == PIPE_FORMAT_LAYOUT_DXT ? TRUE : FALSE;
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index ceac755e71..b449522fac 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -87,7 +87,7 @@ struct pipe_screen {
* Check if the given pipe_format is supported as a texture or
* drawing surface.
* \param tex_usage bitmask of PIPE_TEXTURE_USAGE_*
- * \param flags bitmask of PIPE_TEXTURE_GEOM_*
+ * \param geom_flags bitmask of PIPE_TEXTURE_GEOM_*
*/
boolean (*is_format_supported)( struct pipe_screen *,
enum pipe_format format,
@@ -102,7 +102,7 @@ struct pipe_screen {
const struct pipe_texture *templat);
/**
- * Create a new texture object, using the given template info, but on top of
+ * 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
@@ -144,8 +144,10 @@ struct pipe_screen {
/**
- * Buffer management. Buffer attributes are mostly fixed over its lifetime.
- *
+ * Create a new buffer.
+ * \param alignment buffer start address alignment in bytes
+ * \param usage bitmask of PIPE_BUFFER_USAGE_x
+ * \param size size in bytes
*/
struct pipe_buffer *(*buffer_create)( struct pipe_screen *screen,
unsigned alignment,
@@ -264,7 +266,7 @@ struct pipe_screen {
*/
int (*fence_signalled)( struct pipe_screen *screen,
struct pipe_fence_handle *fence,
- unsigned flag );
+ unsigned flags );
/**
* Wait for the fence to finish.
@@ -273,7 +275,7 @@ struct pipe_screen {
*/
int (*fence_finish)( struct pipe_screen *screen,
struct pipe_fence_handle *fence,
- unsigned flag );
+ unsigned flags );
};
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 705ae68ec6..4b590bdc90 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -336,7 +336,6 @@ struct pipe_texture
unsigned nblocksy[PIPE_MAX_TEXTURE_LEVELS]; /**< allocated height in blocks */
unsigned last_level:8; /**< Index of last mipmap level present/defined */
- unsigned compressed:1;
unsigned nr_samples:8; /**< for multisampled surfaces, nr of samples */
diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h
index de55e99ed4..df6d38904a 100644
--- a/src/gallium/include/pipe/p_thread.h
+++ b/src/gallium/include/pipe/p_thread.h
@@ -43,6 +43,8 @@
#include <pthread.h> /* POSIX threads headers */
#include <stdio.h> /* for perror() */
+#define PIPE_THREAD_HAVE_CONDVAR
+
typedef pthread_t pipe_thread;
#define PIPE_THREAD_ROUTINE( name, param ) \
diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h
new file mode 100644
index 0000000000..b173ba3683
--- /dev/null
+++ b/src/gallium/include/state_tracker/dri1_api.h
@@ -0,0 +1,82 @@
+#ifndef _DRI1_API_H_
+#define _DRI1_API_H_
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_format.h"
+
+#include "state_tracker/drm_api.h"
+
+#include <drm.h>
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_buffer;
+struct pipe_context;
+struct pipe_texture;
+
+struct dri1_api_version
+{
+ int major;
+ int minor;
+ int patch_level;
+};
+
+/**
+ * This callback struct is intended for drivers that need to take
+ * the hardware lock on command submission.
+ */
+
+struct dri1_api_lock_funcs
+{
+ void (*lock) (struct pipe_context * pipe);
+ void (*unlock) (struct pipe_context * locked_pipe);
+ boolean(*is_locked) (struct pipe_context * locked_pipe);
+ boolean(*is_lock_lost) (struct pipe_context * locked_pipe);
+ void (*clear_lost_lock) (struct pipe_context * locked_pipe);
+};
+
+struct dri1_api
+{
+ /**
+ * For flushing to the front buffer. A driver should implement one and only
+ * one of the functions below. The present_locked functions allows a dri1
+ * driver to pageflip.
+ */
+
+ /*@{ */
+
+ struct pipe_surface *(*front_srf_locked) (struct pipe_context *
+ locked_pipe);
+
+ void (*present_locked) (struct pipe_context * locked_pipe,
+ struct pipe_surface * surf,
+ const struct drm_clip_rect * rect,
+ unsigned int num_clip,
+ int x_draw, int y_draw,
+ const struct drm_clip_rect * src_bbox,
+ struct pipe_fence_handle ** fence);
+ /*@} */
+};
+
+struct dri1_create_screen_arg
+{
+ struct drm_create_screen_arg base;
+
+ struct dri1_api_lock_funcs *lf;
+ void *ddx_info;
+ int ddx_info_size;
+ void *sarea;
+
+ struct dri1_api_version ddx_version;
+ struct dri1_api_version dri_version;
+ struct dri1_api_version drm_version;
+
+ /*
+ * out parameters;
+ */
+
+ struct dri1_api *api;
+};
+
+#endif
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index 435435da29..5790b2f6c7 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -10,13 +10,30 @@ struct pipe_buffer;
struct pipe_context;
struct pipe_texture;
+enum drm_create_screen_mode {
+ DRM_CREATE_NORMAL = 0,
+ DRM_CREATE_DRI1,
+ DRM_CREATE_DRIVER = 1024,
+ DRM_CREATE_MAX
+};
+
+/**
+ * Modes other than DRM_CREATE_NORMAL derive from this struct.
+ */
+/*@{*/
+struct drm_create_screen_arg {
+ enum drm_create_screen_mode mode;
+};
+/*@}*/
+
struct drm_api
{
/**
* Special buffer functions
*/
/*@{*/
- struct pipe_screen* (*create_screen)(int drmFB, int pciID);
+ struct pipe_screen* (*create_screen)(int drm_fd,
+ struct drm_create_screen_arg *arg);
struct pipe_context* (*create_context)(struct pipe_screen *screen);
/*@}*/
diff --git a/src/gallium/state_trackers/dri2/Makefile b/src/gallium/state_trackers/dri/Makefile
index 47750e997e..ef8f19709a 100644
--- a/src/gallium/state_trackers/dri2/Makefile
+++ b/src/gallium/state_trackers/dri/Makefile
@@ -1,7 +1,7 @@
TOP = ../../../..
include $(TOP)/configs/current
-LIBNAME = dri2drm
+LIBNAME = dridrm
LIBRARY_INCLUDES = \
-I$(TOP)/include \
diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript
new file mode 100644
index 0000000000..ce2c273597
--- /dev/null
+++ b/src/gallium/state_trackers/dri/SConscript
@@ -0,0 +1,23 @@
+#######################################################################
+# SConscript for dri state_tracker
+
+Import('*')
+
+if env['dri']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ '#/src/mesa/drivers/dri/common',
+ ])
+
+ st_dri = env.ConvenienceLibrary(
+ target = 'st_dri',
+ source = [ 'dri_context.c',
+ 'dri_drawable.c',
+ 'dri_extensions.c',
+ 'dri_screen.c',
+ ]
+ )
+ Export('st_dri')
diff --git a/src/gallium/state_trackers/dri2/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 92c26ac70f..45eaec4ed3 100644
--- a/src/gallium/state_trackers/dri2/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -32,9 +32,8 @@
#include "dri_screen.h"
#include "dri_drawable.h"
-
-
#include "state_tracker/drm_api.h"
+#include "state_tracker/dri1_api.h"
#include "state_tracker/st_public.h"
#include "state_tracker/st_context.h"
#include "pipe/p_context.h"
@@ -43,11 +42,9 @@
#include "util/u_memory.h"
-
GLboolean
-dri_create_context(const __GLcontextModes *visual,
- __DRIcontextPrivate *cPriv,
- void *sharedContextPrivate)
+dri_create_context(const __GLcontextModes * visual,
+ __DRIcontextPrivate * cPriv, void *sharedContextPrivate)
{
__DRIscreenPrivate *sPriv = cPriv->driScreenPriv;
struct dri_screen *screen = dri_screen(sPriv);
@@ -55,7 +52,7 @@ dri_create_context(const __GLcontextModes *visual,
struct st_context *st_share = NULL;
if (sharedContextPrivate) {
- st_share = ((struct dri_context *) sharedContextPrivate)->st;
+ st_share = ((struct dri_context *)sharedContextPrivate)->st;
}
ctx = CALLOC_STRUCT(dri_context);
@@ -65,11 +62,12 @@ dri_create_context(const __GLcontextModes *visual,
cPriv->driverPrivate = ctx;
ctx->cPriv = cPriv;
ctx->sPriv = sPriv;
+ ctx->lock = screen->drmLock;
+ ctx->d_stamp = -1;
+ ctx->r_stamp = -1;
driParseConfigFiles(&ctx->optionCache,
- &screen->optionCache,
- sPriv->myNum,
- "dri");
+ &screen->optionCache, sPriv->myNum, "dri");
ctx->pipe = drm_api_hooks.create_context(screen->pipe_screen);
@@ -87,7 +85,7 @@ dri_create_context(const __GLcontextModes *visual,
return GL_TRUE;
-fail:
+ fail:
if (ctx && ctx->st)
st_destroy_context(ctx->st);
@@ -98,9 +96,8 @@ fail:
return FALSE;
}
-
void
-dri_destroy_context(__DRIcontextPrivate *cPriv)
+dri_destroy_context(__DRIcontextPrivate * cPriv)
{
struct dri_context *ctx = dri_context(cPriv);
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
@@ -122,44 +119,64 @@ dri_destroy_context(__DRIcontextPrivate *cPriv)
FREE(ctx);
}
-
GLboolean
-dri_unbind_context(__DRIcontextPrivate *cPriv)
+dri_unbind_context(__DRIcontextPrivate * cPriv)
{
- struct dri_context *ctx = dri_context(cPriv);
- st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
- /* XXX make_current(NULL)? */
+ if (cPriv) {
+ struct dri_context *ctx = dri_context(cPriv);
+
+ if (--ctx->bind_count == 0) {
+ if (ctx->st && ctx->st == st_get_current()) {
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ st_make_current(NULL, NULL, NULL);
+ }
+ }
+ }
+
return GL_TRUE;
}
-
GLboolean
-dri_make_current(__DRIcontextPrivate *cPriv,
- __DRIdrawablePrivate *driDrawPriv,
- __DRIdrawablePrivate *driReadPriv)
+dri_make_current(__DRIcontextPrivate * cPriv,
+ __DRIdrawablePrivate * driDrawPriv,
+ __DRIdrawablePrivate * driReadPriv)
{
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
+ struct st_context *old_st = st_get_current();
+
+ if (old_st && old_st != ctx->st)
+ st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ ++ctx->bind_count;
/* This is for situations in which we need a rendering context but
* there may not be any currently bound.
*/
screen->dummyContext = ctx;
- st_make_current(ctx->st,
- draw->stfb,
- read->stfb);
-
- /* used in dri_flush_frontbuffer */
- ctx->dPriv = driDrawPriv;
-
- if (driDrawPriv)
- dri_get_buffers(driDrawPriv);
- if (driDrawPriv != driReadPriv && driReadPriv)
- dri_get_buffers(driReadPriv);
+ if (ctx->dPriv != driDrawPriv) {
+ ctx->dPriv = driDrawPriv;
+ ctx->d_stamp = driDrawPriv->lastStamp - 1;
+ }
+ if (ctx->rPriv != driReadPriv) {
+ ctx->rPriv = driReadPriv;
+ ctx->r_stamp = driReadPriv->lastStamp - 1;
+ }
+
+ st_make_current(ctx->st, draw->stfb, read->stfb);
+
+ if (__dri1_api_hooks) {
+ dri1_update_drawables(ctx, draw, read);
+ } else {
+ if (driDrawPriv)
+ dri_get_buffers(driDrawPriv);
+ if (driDrawPriv != driReadPriv && driReadPriv)
+ dri_get_buffers(driReadPriv);
+ }
} else {
st_make_current(NULL, NULL, NULL);
}
@@ -167,4 +184,42 @@ dri_make_current(__DRIcontextPrivate *cPriv,
return GL_TRUE;
}
+static void
+st_dri_lock(struct pipe_context *pipe)
+{
+ dri_lock((struct dri_context *)pipe->priv);
+}
+
+static void
+st_dri_unlock(struct pipe_context *pipe)
+{
+ dri_unlock((struct dri_context *)pipe->priv);
+}
+
+static boolean
+st_dri_is_locked(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->isLocked;
+}
+
+static boolean
+st_dri_lost_lock(struct pipe_context *pipe)
+{
+ return ((struct dri_context *)pipe->priv)->wsLostLock;
+}
+
+static void
+st_dri_clear_lost_lock(struct pipe_context *pipe)
+{
+ ((struct dri_context *)pipe->priv)->wsLostLock = FALSE;
+}
+
+struct dri1_api_lock_funcs dri1_lf = {
+ .lock = st_dri_lock,
+ .unlock = st_dri_unlock,
+ .is_locked = st_dri_is_locked,
+ .is_lock_lost = st_dri_lost_lock,
+ .clear_lost_lock = st_dri_clear_lost_lock
+};
+
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri2/dri_context.h b/src/gallium/state_trackers/dri/dri_context.h
index e910472700..4650178734 100644
--- a/src/gallium/state_trackers/dri2/dri_context.h
+++ b/src/gallium/state_trackers/dri/dri_context.h
@@ -36,60 +36,87 @@
#include "drm.h"
#include "dri_util.h"
-
struct pipe_context;
struct pipe_fence;
struct st_context;
struct dri_drawable;
-
struct dri_context
{
/* dri */
__DRIscreenPrivate *sPriv;
__DRIcontextPrivate *cPriv;
__DRIdrawablePrivate *dPriv;
+ __DRIdrawablePrivate *rPriv;
driOptionCache optionCache;
+ unsigned int d_stamp;
+ unsigned int r_stamp;
+
+ drmLock *lock;
+ boolean isLocked;
+ boolean stLostLock;
+ boolean wsLostLock;
+
+ unsigned int bind_count;
+
/* gallium */
struct st_context *st;
struct pipe_context *pipe;
};
-
static INLINE struct dri_context *
-dri_context(__DRIcontextPrivate *driContextPriv)
+dri_context(__DRIcontextPrivate * driContextPriv)
+{
+ return (struct dri_context *)driContextPriv->driverPrivate;
+}
+
+static INLINE void
+dri_lock(struct dri_context *ctx)
{
- return (struct dri_context *) driContextPriv->driverPrivate;
+ drm_context_t hw_context = ctx->cPriv->hHWContext;
+ char ret = 0;
+
+ DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret);
+ if (ret) {
+ drmGetLock(ctx->sPriv->fd, hw_context, 0);
+ ctx->stLostLock = TRUE;
+ ctx->wsLostLock = TRUE;
+ }
+ ctx->isLocked = TRUE;
}
+static INLINE void
+dri_unlock(struct dri_context *ctx)
+{
+ ctx->isLocked = FALSE;
+ DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext);
+}
/***********************************************************************
* dri_context.c
*/
-void
-dri_destroy_context(__DRIcontextPrivate * driContextPriv);
+extern struct dri1_api_lock_funcs dri1_lf;
-boolean
-dri_unbind_context(__DRIcontextPrivate * driContextPriv);
+void dri_destroy_context(__DRIcontextPrivate * driContextPriv);
+
+boolean dri_unbind_context(__DRIcontextPrivate * driContextPriv);
boolean
dri_make_current(__DRIcontextPrivate * driContextPriv,
- __DRIdrawablePrivate * driDrawPriv,
- __DRIdrawablePrivate * driReadPriv);
+ __DRIdrawablePrivate * driDrawPriv,
+ __DRIdrawablePrivate * driReadPriv);
boolean
dri_create_context(const __GLcontextModes * visual,
- __DRIcontextPrivate * driContextPriv,
- void *sharedContextPrivate);
-
+ __DRIcontextPrivate * driContextPriv,
+ void *sharedContextPrivate);
/***********************************************************************
* dri_extensions.c
*/
-void
-dri_init_extensions(struct dri_context *ctx);
+void dri_init_extensions(struct dri_context *ctx);
#endif
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
new file mode 100644
index 0000000000..09cd3091d2
--- /dev/null
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -0,0 +1,605 @@
+/**************************************************************************
+ *
+ * Copyright 2009, VMware, 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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 <keithw@vmware.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ */
+
+#include "dri_screen.h"
+#include "dri_context.h"
+#include "dri_drawable.h"
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_inlines.h"
+#include "state_tracker/drm_api.h"
+#include "state_tracker/dri1_api.h"
+#include "state_tracker/st_public.h"
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_cb_fbo.h"
+
+#include "util/u_memory.h"
+
+static void
+dri_copy_to_front(__DRIdrawablePrivate * dPriv,
+ struct pipe_surface *from,
+ int x, int y, unsigned w, unsigned h)
+{
+ /* TODO send a message to the Xserver to copy to the real front buffer */
+}
+
+static struct pipe_surface *
+dri_surface_from_handle(struct pipe_screen *screen,
+ unsigned handle,
+ enum pipe_format format,
+ unsigned width, unsigned height, unsigned pitch)
+{
+ struct pipe_surface *surface = NULL;
+ struct pipe_texture *texture = NULL;
+ struct pipe_texture templat;
+ struct pipe_buffer *buf = NULL;
+
+ buf = drm_api_hooks.buffer_from_handle(screen, "dri2 buffer", handle);
+ if (!buf)
+ return NULL;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.target = PIPE_TEXTURE_2D;
+ templat.last_level = 0;
+ templat.depth[0] = 1;
+ templat.format = format;
+ templat.width[0] = width;
+ templat.height[0] = height;
+ pf_get_block(templat.format, &templat.block);
+
+ texture = screen->texture_blanket(screen, &templat, &pitch, buf);
+
+ /* we don't need the buffer from this point on */
+ pipe_buffer_reference(&buf, NULL);
+
+ if (!texture)
+ return NULL;
+
+ surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ /* we don't need the texture from this point on */
+ pipe_texture_reference(&texture, NULL);
+ return surface;
+}
+
+/**
+ * This will be called a drawable is known to have been resized.
+ */
+void
+dri_get_buffers(__DRIdrawablePrivate * dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_surface *surface = NULL;
+ struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+ __DRIbuffer *buffers = NULL;
+ __DRIscreen *dri_screen = drawable->sPriv;
+ __DRIdrawable *dri_drawable = drawable->dPriv;
+ boolean have_depth = FALSE;
+ int i, count;
+
+ buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
+ &dri_drawable->w,
+ &dri_drawable->h,
+ drawable->attachments,
+ drawable->
+ num_attachments, &count,
+ dri_drawable->
+ loaderPrivate);
+
+ if (buffers == NULL) {
+ return;
+ }
+
+ /* set one cliprect to cover the whole dri_drawable */
+ dri_drawable->x = 0;
+ dri_drawable->y = 0;
+ dri_drawable->backX = 0;
+ dri_drawable->backY = 0;
+ dri_drawable->numClipRects = 1;
+ dri_drawable->pClipRects[0].x1 = 0;
+ dri_drawable->pClipRects[0].y1 = 0;
+ dri_drawable->pClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pClipRects[0].y2 = dri_drawable->h;
+ dri_drawable->numBackClipRects = 1;
+ dri_drawable->pBackClipRects[0].x1 = 0;
+ dri_drawable->pBackClipRects[0].y1 = 0;
+ dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
+ dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
+
+ if (drawable->old_num == count &&
+ drawable->old_w == dri_drawable->w &&
+ drawable->old_h == dri_drawable->h &&
+ memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) {
+ return;
+ } else {
+ drawable->old_num = count;
+ drawable->old_w = dri_drawable->w;
+ drawable->old_h = dri_drawable->h;
+ memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
+ }
+
+ for (i = 0; i < count; i++) {
+ enum pipe_format format = 0;
+ int index = 0;
+
+ switch (buffers[i].attachment) {
+ case __DRI_BUFFER_FRONT_LEFT:
+ index = ST_SURFACE_FRONT_LEFT;
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ index = ST_SURFACE_FRONT_LEFT;
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ case __DRI_BUFFER_BACK_LEFT:
+ index = ST_SURFACE_BACK_LEFT;
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ case __DRI_BUFFER_DEPTH:
+ index = ST_SURFACE_DEPTH;
+ format = PIPE_FORMAT_Z24S8_UNORM;
+ break;
+ case __DRI_BUFFER_STENCIL:
+ index = ST_SURFACE_DEPTH;
+ format = PIPE_FORMAT_Z24S8_UNORM;
+ break;
+ case __DRI_BUFFER_ACCUM:
+ default:
+ assert(0);
+ }
+ assert(buffers[i].cpp == 4);
+
+ if (index == ST_SURFACE_DEPTH) {
+ if (have_depth)
+ continue;
+ else
+ have_depth = TRUE;
+ }
+
+ surface = dri_surface_from_handle(screen,
+ buffers[i].name,
+ format,
+ dri_drawable->w,
+ dri_drawable->h, buffers[i].pitch);
+
+ st_set_framebuffer_surface(drawable->stfb, index, surface);
+ pipe_surface_reference(&surface, NULL);
+ }
+ /* this needed, or else the state tracker fails to pick the new buffers */
+ st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
+}
+
+void
+dri_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf, void *context_private)
+{
+ struct dri_context *ctx = (struct dri_context *)context_private;
+
+ dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height);
+}
+
+/**
+ * This is called when we need to set up GL rendering to a new X window.
+ */
+boolean
+dri_create_buffer(__DRIscreenPrivate * sPriv,
+ __DRIdrawablePrivate * dPriv,
+ const __GLcontextModes * visual, boolean isPixmap)
+{
+ enum pipe_format colorFormat, depthFormat, stencilFormat;
+ struct dri_screen *screen = sPriv->private;
+ struct dri_drawable *drawable = NULL;
+ struct pipe_screen *pscreen = screen->pipe_screen;
+ int i;
+
+ if (isPixmap)
+ goto fail; /* not implemented */
+
+ drawable = CALLOC_STRUCT(dri_drawable);
+ if (drawable == NULL)
+ goto fail;
+
+ /* XXX: todo: use the pipe_screen queries to figure out which
+ * render targets are supportable.
+ */
+ assert(visual->redBits == 8);
+ assert(visual->depthBits == 24 || visual->depthBits == 0);
+ assert(visual->stencilBits == 8 || visual->stencilBits == 0);
+
+ colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+ if (visual->depthBits) {
+ if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
+ depthFormat = PIPE_FORMAT_Z24S8_UNORM;
+ else
+ depthFormat = PIPE_FORMAT_S8Z24_UNORM;
+ } else
+ depthFormat = PIPE_FORMAT_NONE;
+
+ if (visual->stencilBits) {
+ if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
+ stencilFormat = PIPE_FORMAT_Z24S8_UNORM;
+ else
+ stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
+ } else
+ stencilFormat = PIPE_FORMAT_NONE;
+
+ drawable->stfb = st_create_framebuffer(visual,
+ colorFormat,
+ depthFormat,
+ stencilFormat,
+ dPriv->w,
+ dPriv->h, (void *)drawable);
+ if (drawable->stfb == NULL)
+ goto fail;
+
+ drawable->sPriv = sPriv;
+ drawable->dPriv = dPriv;
+ dPriv->driverPrivate = (void *)drawable;
+
+ /* setup dri2 buffers information */
+ i = 0;
+ drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
+#if 0
+ /* TODO incase of double buffer visual, delay fake creation */
+ drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
+#endif
+ if (visual->doubleBufferMode)
+ drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
+ if (visual->depthBits)
+ drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
+ if (visual->stencilBits)
+ drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
+ drawable->num_attachments = i;
+
+ drawable->desired_fences = 2;
+
+ return GL_TRUE;
+ fail:
+ FREE(drawable);
+ return GL_FALSE;
+}
+
+static struct pipe_fence_handle *
+dri_swap_fences_pop_front(struct dri_drawable *draw)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence = NULL;
+
+ if (draw->cur_fences >= draw->desired_fences) {
+ screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]);
+ screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL);
+ --draw->cur_fences;
+ draw->tail &= DRI_SWAP_FENCES_MASK;
+ }
+ return fence;
+}
+
+static void
+dri_swap_fences_push_back(struct dri_drawable *draw,
+ struct pipe_fence_handle *fence)
+{
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+
+ if (!fence)
+ return;
+
+ if (draw->cur_fences < DRI_SWAP_FENCES_MAX) {
+ draw->cur_fences++;
+ screen->fence_reference(screen, &draw->swap_fences[draw->head++],
+ fence);
+ draw->head &= DRI_SWAP_FENCES_MASK;
+ }
+}
+
+void
+dri_destroy_buffer(__DRIdrawablePrivate * dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_fence_handle *fence;
+ struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
+
+ st_unreference_framebuffer(drawable->stfb);
+ drawable->desired_fences = 0;
+ while (drawable->cur_fences) {
+ fence = dri_swap_fences_pop_front(drawable);
+ screen->fence_reference(screen, &fence, NULL);
+ }
+
+ FREE(drawable);
+}
+
+static void
+dri1_update_drawables_locked(struct dri_context *ctx,
+ __DRIdrawablePrivate * driDrawPriv,
+ __DRIdrawablePrivate * driReadPriv)
+{
+ if (ctx->stLostLock) {
+ ctx->stLostLock = FALSE;
+ if (driDrawPriv == driReadPriv)
+ DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv);
+ else
+ DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv,
+ driReadPriv);
+ }
+}
+
+/**
+ * This ensures all contexts which bind to a drawable pick up the
+ * drawable change and signal new buffer state.
+ * Calling st_resize_framebuffer for each context may seem like overkill,
+ * but no new buffers will actually be allocated if the dimensions don't
+ * change.
+ */
+
+static void
+dri1_propagate_drawable_change(struct dri_context *ctx)
+{
+ __DRIdrawablePrivate *dPriv = ctx->dPriv;
+ __DRIdrawablePrivate *rPriv = ctx->rPriv;
+ boolean flushed = FALSE;
+
+ if (dPriv && ctx->d_stamp != dPriv->lastStamp) {
+
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ flushed = TRUE;
+ ctx->d_stamp = dPriv->lastStamp;
+ st_resize_framebuffer(dri_drawable(dPriv)->stfb, dPriv->w, dPriv->h);
+
+ }
+
+ if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) {
+
+ if (!flushed)
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ ctx->r_stamp = rPriv->lastStamp;
+ st_resize_framebuffer(dri_drawable(rPriv)->stfb, rPriv->w, rPriv->h);
+
+ } else if (rPriv && dPriv == rPriv) {
+
+ ctx->r_stamp = ctx->d_stamp;
+
+ }
+}
+
+void
+dri1_update_drawables(struct dri_context *ctx,
+ struct dri_drawable *draw, struct dri_drawable *read)
+{
+ dri_lock(ctx);
+ dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv);
+ dri_unlock(ctx);
+
+ dri1_propagate_drawable_change(ctx);
+}
+
+static INLINE boolean
+dri1_intersect_src_bbox(struct drm_clip_rect *dst,
+ int dst_x,
+ int dst_y,
+ const struct drm_clip_rect *src,
+ const struct drm_clip_rect *bbox)
+{
+ int xy1;
+ int xy2;
+
+ xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 :
+ (int)bbox->x1 + dst_x;
+ xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 :
+ (int)bbox->x2 + dst_x;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->x1 = xy1;
+ dst->x2 = xy2;
+
+ xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 :
+ (int)bbox->y1 + dst_y;
+ xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 :
+ (int)bbox->y2 + dst_y;
+ if (xy1 >= xy2 || xy1 < 0)
+ return FALSE;
+
+ dst->y1 = xy1;
+ dst->y2 = xy2;
+ return TRUE;
+}
+
+static void
+dri1_swap_copy(struct dri_context *ctx,
+ struct pipe_surface *dst,
+ struct pipe_surface *src,
+ __DRIdrawablePrivate * dPriv, const struct drm_clip_rect *bbox)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ struct drm_clip_rect clip;
+ struct drm_clip_rect *cur;
+ int i;
+
+ cur = dPriv->pClipRects;
+
+ for (i = 0; i < dPriv->numClipRects; ++i) {
+ if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox))
+ pipe->surface_copy(pipe, dst, clip.x1, clip.y1,
+ src,
+ (int)clip.x1 - dPriv->x,
+ (int)clip.y1 - dPriv->y,
+ clip.x2 - clip.x1, clip.y2 - clip.y1);
+ }
+}
+
+static void
+dri1_copy_to_front(struct dri_context *ctx,
+ struct pipe_surface *surf,
+ __DRIdrawablePrivate * dPriv,
+ const struct drm_clip_rect *sub_box,
+ struct pipe_fence_handle **fence)
+{
+ struct pipe_context *pipe = ctx->pipe;
+ boolean save_lost_lock;
+ uint cur_w;
+ uint cur_h;
+ struct drm_clip_rect bbox;
+ boolean visible = TRUE;
+
+ *fence = NULL;
+
+ dri_lock(ctx);
+ save_lost_lock = ctx->stLostLock;
+ dri1_update_drawables_locked(ctx, dPriv, dPriv);
+ st_get_framebuffer_dimensions(dri_drawable(dPriv)->stfb, &cur_w, &cur_h);
+
+ bbox.x1 = 0;
+ bbox.x2 = cur_w;
+ bbox.y1 = 0;
+ bbox.y2 = cur_h;
+
+ if (sub_box)
+ visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box);
+
+ if (visible && __dri1_api_hooks->present_locked) {
+
+ __dri1_api_hooks->present_locked(pipe,
+ surf,
+ dPriv->pClipRects,
+ dPriv->numClipRects,
+ dPriv->x, dPriv->y, &bbox, fence);
+
+ } else if (visible && __dri1_api_hooks->front_srf_locked) {
+
+ struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe);
+
+ if (front)
+ dri1_swap_copy(ctx, front, surf, dPriv, &bbox);
+
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence);
+ }
+
+ ctx->stLostLock = save_lost_lock;
+
+ /**
+ * FIXME: Revisit this: Update drawables on copy_sub_buffer ?
+ */
+
+ if (!sub_box)
+ dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv);
+
+ dri_unlock(ctx);
+ dri1_propagate_drawable_change(ctx);
+}
+
+void
+dri1_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf, void *context_private)
+{
+ struct dri_context *ctx = (struct dri_context *)context_private;
+ struct pipe_fence_handle *dummy_fence;
+
+ dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence);
+ screen->fence_reference(screen, &dummy_fence, NULL);
+
+ /**
+ * FIXME: Do we need swap throttling here?
+ */
+}
+
+void
+dri_swap_buffers(__DRIdrawablePrivate * dPriv)
+{
+ struct dri_context *ctx;
+ struct pipe_surface *back_surf;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen;
+ struct pipe_fence_handle *fence;
+ struct st_context *st = st_get_current();
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!st)
+ return; /* For now */
+
+ ctx = (struct dri_context *)st->pipe->priv;
+
+ st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
+ if (back_surf) {
+ st_notify_swapbuffers(draw->stfb);
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ fence = dri_swap_fences_pop_front(draw);
+ if (fence) {
+ (void)screen->fence_finish(screen, fence, 0);
+ screen->fence_reference(screen, &fence, NULL);
+ }
+ dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence);
+ dri_swap_fences_push_back(draw, fence);
+ screen->fence_reference(screen, &fence, NULL);
+ }
+}
+
+void
+dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
+{
+ struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen;
+ struct drm_clip_rect sub_bbox;
+ struct dri_context *ctx;
+ struct pipe_surface *back_surf;
+ struct dri_drawable *draw = dri_drawable(dPriv);
+ struct pipe_fence_handle *dummy_fence;
+ struct st_context *st = st_get_current();
+
+ assert(__dri1_api_hooks != NULL);
+
+ if (!st)
+ return;
+
+ ctx = (struct dri_context *)st->pipe->priv;
+
+ sub_bbox.x1 = x;
+ sub_bbox.x2 = x + w;
+ sub_bbox.y1 = y;
+ sub_bbox.y2 = y + h;
+
+ st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf);
+ if (back_surf) {
+ st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+ dri1_copy_to_front(ctx, back_surf, dPriv, &sub_bbox, &dummy_fence);
+ screen->fence_reference(screen, &dummy_fence, NULL);
+ }
+}
+
+/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri2/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index 185c657b35..0f654d804a 100644
--- a/src/gallium/state_trackers/dri2/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -31,9 +31,11 @@
#include "pipe/p_compiler.h"
struct pipe_surface;
-struct pipe_fence;
+struct pipe_fence_handle;
struct st_framebuffer;
+#define DRI_SWAP_FENCES_MAX 8
+#define DRI_SWAP_FENCES_MASK 7
struct dri_drawable
{
@@ -44,46 +46,54 @@ struct dri_drawable
unsigned attachments[8];
unsigned num_attachments;
+ __DRIbuffer old[8];
+ unsigned old_num;
+ unsigned old_w;
+ unsigned old_h;
+
/* gallium */
struct st_framebuffer *stfb;
+ struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX];
+ unsigned int head;
+ unsigned int tail;
+ unsigned int desired_fences;
+ unsigned int cur_fences;
};
-
static INLINE struct dri_drawable *
dri_drawable(__DRIdrawablePrivate * driDrawPriv)
{
- return (struct dri_drawable *) driDrawPriv->driverPrivate;
+ return (struct dri_drawable *)driDrawPriv->driverPrivate;
}
-
/***********************************************************************
* dri_drawable.c
*/
boolean
-dri_create_buffer(__DRIscreenPrivate *sPriv,
- __DRIdrawablePrivate *dPriv,
- const __GLcontextModes *visual,
- boolean isPixmap);
+dri_create_buffer(__DRIscreenPrivate * sPriv,
+ __DRIdrawablePrivate * dPriv,
+ const __GLcontextModes * visual, boolean isPixmap);
void
dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf,
- void *context_private);
+ struct pipe_surface *surf, void *context_private);
-void
-dri_swap_buffers(__DRIdrawablePrivate * dPriv);
+void dri_swap_buffers(__DRIdrawablePrivate * dPriv);
void
-dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv,
- int x, int y,
- int w, int h);
+dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h);
-void
-dri_get_buffers(__DRIdrawablePrivate * dPriv);
+void dri_get_buffers(__DRIdrawablePrivate * dPriv);
+
+void dri_destroy_buffer(__DRIdrawablePrivate * dPriv);
void
-dri_destroy_buffer(__DRIdrawablePrivate *dPriv);
+dri1_update_drawables(struct dri_context *ctx,
+ struct dri_drawable *draw, struct dri_drawable *read);
+void
+dri1_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf, void *context_private);
#endif
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri2/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 732d1e89b0..2f48162526 100644
--- a/src/gallium/state_trackers/dri2/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -36,9 +36,11 @@
#define need_GL_ARB_multisample
#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
+#define need_GL_ARB_shader_objects
#define need_GL_ARB_texture_compression
#define need_GL_ARB_vertex_buffer_object
#define need_GL_ARB_vertex_program
+#define need_GL_ARB_vertex_shader
#define need_GL_ARB_window_pos
#define need_GL_EXT_blend_color
#define need_GL_EXT_blend_equation_separate
@@ -50,17 +52,23 @@
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
#define need_GL_NV_vertex_program
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
#include "extension_helper.h"
-
/**
* Extension strings exported by the driver.
*/
const struct dri_extension card_extensions[] = {
+ {"GL_ARB_fragment_shader", NULL},
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
+ {"GL_ARB_pixel_buffer_object", NULL},
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
+ {"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_texture_border_clamp", NULL},
{"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
{"GL_ARB_texture_cube_map", NULL},
@@ -70,11 +78,12 @@ const struct dri_extension card_extensions[] = {
{"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_shader", GL_ARB_vertex_shader_functions},
{"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_subtract", NULL},
@@ -98,11 +107,10 @@ 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}
};
-
void
dri_init_extensions(struct dri_context *ctx)
{
diff --git a/src/gallium/state_trackers/dri2/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index ab5878a4bc..d3392ee690 100644
--- a/src/gallium/state_trackers/dri2/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -40,68 +40,38 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_inlines.h"
+#include "pipe/p_format.h"
#include "state_tracker/drm_api.h"
+#include "state_tracker/dri1_api.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_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_FORCE_S3TC_ENABLE(false) */
+ DRI_CONF_ALLOW_LARGE_TEXTURES(1)
DRI_CONF_SECTION_END DRI_CONF_END;
+ const uint __driNConfigOptions = 3;
-const uint __driNConfigOptions = 3;
-
-
-static const __DRIextension *dri_screen_extensions[] = {
- &driReadDrawableExtension,
- &driCopySubBufferExtension.base,
- &driSwapControlExtension.base,
- &driFrameTrackingExtension.base,
- &driMediaStreamCounterExtension.base,
- NULL
-};
-
-
-static void
-dri_get_drm_minor(struct dri_screen *screen)
-{
- /* TODO get the real minor */
- screen->minor = 0;
-}
-
-
-static void
-dri_get_device_id(struct dri_screen *screen)
-{
- char path[512];
- FILE *file;
-
- /*
- * There must be a better way to get the deviceID.
- * XXX this only works on Linux.
- */
- snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", screen->minor);
- file = fopen(path, "r");
- if (!file) {
- return;
- }
-
- fgets(path, sizeof(path), file);
- sscanf(path, "%x", &screen->deviceID);
- fclose(file);
-}
+ static const __DRIextension *dri_screen_extensions[] = {
+ &driReadDrawableExtension,
+ &driCopySubBufferExtension.base,
+ &driSwapControlExtension.base,
+ &driFrameTrackingExtension.base,
+ &driMediaStreamCounterExtension.base,
+ NULL
+ };
+struct dri1_api *__dri1_api_hooks = NULL;
static const __DRIconfig **
-dri_fill_in_modes(__DRIscreenPrivate *psp,
- unsigned pixel_bits, unsigned depth_bits,
- unsigned stencil_bits, GLboolean have_back_buffer)
+dri_fill_in_modes(__DRIscreenPrivate * psp,
+ unsigned pixel_bits, unsigned depth_bits,
+ unsigned stencil_bits, GLboolean have_back_buffer)
{
__DRIconfig **configs;
__GLcontextModes *m;
@@ -125,9 +95,9 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,
depth_bits_array[1] = 24;
depth_bits_array[2] = 24;
- stencil_bits_array[0] = 0; /* no depth or stencil */
- stencil_bits_array[1] = 0; /* z24x8 */
- stencil_bits_array[2] = 8; /* z24s8 */
+ stencil_bits_array[0] = 0; /* no depth or stencil */
+ stencil_bits_array[1] = 0; /* z24x8 */
+ stencil_bits_array[2] = 8; /* z24s8 */
msaa_samples_array[0] = 0;
@@ -135,22 +105,22 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,
back_buffer_factor = 3;
msaa_samples_factor = 1;
- num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
+ num_modes =
+ depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
if (pixel_bits == 16) {
fb_format = GL_RGB;
fb_type = GL_UNSIGNED_SHORT_5_6_5;
- }
- else {
+ } else {
fb_format = GL_BGRA;
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,
- msaa_samples_array, msaa_samples_factor);
+ stencil_bits_array, depth_buffer_factor,
+ back_buffer_modes, back_buffer_factor,
+ msaa_samples_array, msaa_samples_factor);
if (configs == NULL) {
debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);
return NULL;
@@ -159,49 +129,99 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,
for (i = 0; configs[i]; i++) {
m = &configs[i]->modes;
if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) {
- m->visualRating = GLX_SLOW_CONFIG;
+ m->visualRating = GLX_SLOW_CONFIG;
}
}
- return (const const __DRIconfig **) configs;
+ return (const const __DRIconfig **)configs;
}
-
/**
* Get information about previous buffer swaps.
*/
-int
-dri_get_swap_info(__DRIdrawablePrivate * dPriv,
- __DRIswapInfo * sInfo)
+static int
+dri_get_swap_info(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo)
{
- if (dPriv == NULL ||
- dPriv->driverPrivate == NULL ||
- sInfo == NULL)
+ if (dPriv == NULL || dPriv->driverPrivate == NULL || sInfo == NULL)
return -1;
else
return 0;
}
+static INLINE void
+dri_copy_version(struct dri1_api_version *dst,
+ const struct __DRIversionRec *src)
+{
+ dst->major = src->major;
+ dst->minor = src->minor;
+ dst->patch_level = src->patch;
+}
-/**
- * NULL stub for old dri loaders
- */
-const __DRIconfig **
-dri_init_screen(__DRIscreenPrivate *sPriv)
+static const __DRIconfig **
+dri_init_screen(__DRIscreenPrivate * sPriv)
{
+ struct dri_screen *screen;
+ const __DRIconfig **configs;
+ struct dri1_create_screen_arg arg;
+
+ dri_init_extensions(NULL);
+
+ screen = CALLOC_STRUCT(dri_screen);
+ if (!screen)
+ return NULL;
+
+ screen->sPriv = sPriv;
+ screen->fd = sPriv->fd;
+ screen->drmLock = (drmLock *) & sPriv->pSAREA->lock;
+
+ sPriv->private = (void *)screen;
+ sPriv->extensions = dri_screen_extensions;
+
+ arg.base.mode = DRM_CREATE_DRI1;
+ arg.lf = &dri1_lf;
+ arg.ddx_info = sPriv->pDevPriv;
+ arg.ddx_info_size = sPriv->devPrivSize;
+ arg.sarea = sPriv->pSAREA;
+ dri_copy_version(&arg.ddx_version, &sPriv->ddx_version);
+ dri_copy_version(&arg.dri_version, &sPriv->dri_version);
+ dri_copy_version(&arg.drm_version, &sPriv->drm_version);
+ arg.api = NULL;
+
+ screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg.base);
+
+ if (!screen->pipe_screen || !arg.api) {
+ debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__);
+ goto out_no_screen;
+ }
+
+ __dri1_api_hooks = arg.api;
+
+ screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer;
+ driParseOptionInfo(&screen->optionCache,
+ __driConfigOptions, __driNConfigOptions);
+
+ configs = dri_fill_in_modes(sPriv, sPriv->fbBPP, 24, 8, 1);
+ if (!configs)
+ goto out_no_configs;
+
+ return configs;
+ out_no_configs:
+ screen->pipe_screen->destroy(screen->pipe_screen);
+ out_no_screen:
+ FREE(screen);
return NULL;
}
-
/**
* This is the driver specific part of the createNewScreen entry point.
*
* Returns the __GLcontextModes supported by this driver.
*/
-const __DRIconfig **
-dri_init_screen2(__DRIscreenPrivate *sPriv)
+static const __DRIconfig **
+dri_init_screen2(__DRIscreenPrivate * sPriv)
{
struct dri_screen *screen;
+ struct drm_create_screen_arg arg;
/* Set up dispatch table to cope with all known extensions */
dri_init_extensions(NULL);
@@ -212,13 +232,11 @@ dri_init_screen2(__DRIscreenPrivate *sPriv)
screen->sPriv = sPriv;
screen->fd = sPriv->fd;
- dri_get_drm_minor(screen);
- dri_get_device_id(screen);
- sPriv->private = (void *) screen;
+ sPriv->private = (void *)screen;
sPriv->extensions = dri_screen_extensions;
+ arg.mode = DRM_CREATE_NORMAL;
-
- screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, screen->deviceID);
+ screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg);
if (!screen->pipe_screen) {
debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__);
goto fail;
@@ -228,20 +246,14 @@ dri_init_screen2(__DRIscreenPrivate *sPriv)
screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer;
driParseOptionInfo(&screen->optionCache,
- __driConfigOptions,
- __driNConfigOptions);
-
- return dri_fill_in_modes(sPriv,
- 4 * 8,
- 24,
- 8,
- 1);
-fail:
+ __driConfigOptions, __driNConfigOptions);
+
+ return dri_fill_in_modes(sPriv, 4 * 8, 24, 8, 1);
+ fail:
return NULL;
}
-
-void
+static void
dri_destroy_screen(__DRIscreenPrivate * sPriv)
{
struct dri_screen *screen = dri_screen(sPriv);
@@ -251,22 +263,22 @@ dri_destroy_screen(__DRIscreenPrivate * sPriv)
sPriv->private = NULL;
}
-
PUBLIC const struct __DriverAPIRec driDriverAPI = {
- .InitScreen = dri_init_screen, /* not supported but exported */
- .DestroyScreen = dri_destroy_screen,
- .CreateContext = dri_create_context,
- .DestroyContext = dri_destroy_context,
- .CreateBuffer = dri_create_buffer,
- .DestroyBuffer = dri_destroy_buffer,
- .SwapBuffers = dri_swap_buffers, /* not supported but exported */
- .MakeCurrent = dri_make_current,
- .UnbindContext = dri_unbind_context,
- .GetSwapInfo = dri_get_swap_info,
- .GetDrawableMSC = driDrawableGetMSC32,
- .WaitForMSC = driWaitForMSC32,
- .CopySubBuffer = dri_copy_sub_buffer, /* not supported but exported */
- .InitScreen2 = dri_init_screen2,
+ .InitScreen = dri_init_screen,
+ .DestroyScreen = dri_destroy_screen,
+ .CreateContext = dri_create_context,
+ .DestroyContext = dri_destroy_context,
+ .CreateBuffer = dri_create_buffer,
+ .DestroyBuffer = dri_destroy_buffer,
+ .SwapBuffers = dri_swap_buffers,
+ .MakeCurrent = dri_make_current,
+ .UnbindContext = dri_unbind_context,
+ .GetSwapInfo = dri_get_swap_info,
+ .GetDrawableMSC = driDrawableGetMSC32,
+ .WaitForMSC = driWaitForMSC32,
+ .CopySubBuffer = dri_copy_sub_buffer,
+ .InitScreen = dri_init_screen,
+ .InitScreen2 = dri_init_screen2,
};
/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/dri2/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index fe2676d0be..100d9e50e0 100644
--- a/src/gallium/state_trackers/dri2/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -37,6 +37,8 @@
#include "pipe/p_compiler.h"
+#include "state_tracker/dri1_api.h"
+
struct dri_screen
{
/* dri */
@@ -54,36 +56,26 @@ struct dri_screen
struct dri_context *dummyContext;
/* drm */
- int deviceID;
int fd;
- int minor;
+ drmLock *drmLock;
/* gallium */
struct pipe_winsys *pipe_winsys;
struct pipe_screen *pipe_screen;
};
-
/** cast wrapper */
static INLINE struct dri_screen *
-dri_screen(__DRIscreenPrivate *sPriv)
+dri_screen(__DRIscreenPrivate * sPriv)
{
- return (struct dri_screen *) sPriv->private;
+ return (struct dri_screen *)sPriv->private;
}
-
/***********************************************************************
* dri_screen.c
*/
-const __DRIconfig **
-dri_init_screen2(__DRIscreenPrivate *sPriv);
-
-void
-dri_destroy_screen(__DRIscreenPrivate * sPriv);
-int
-dri_get_swap_info(__DRIdrawablePrivate * dPriv,
- __DRIswapInfo * sInfo);
+extern struct dri1_api *__dri1_api_hooks;
#endif
diff --git a/src/gallium/state_trackers/dri2/dri_drawable.c b/src/gallium/state_trackers/dri2/dri_drawable.c
deleted file mode 100644
index 2e3f4099e2..0000000000
--- a/src/gallium/state_trackers/dri2/dri_drawable.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009, VMware, 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 the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 <keithw@vmware.com>
- * Author: Jakob Bornecrantz <wallbraker@gmail.com>
- */
-
-#include "dri_screen.h"
-#include "dri_context.h"
-#include "dri_drawable.h"
-
-#include "pipe/p_context.h"
-#include "pipe/p_screen.h"
-#include "pipe/p_inlines.h"
-#include "state_tracker/drm_api.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-
-#include "util/u_memory.h"
-
-
-static void
-dri_copy_to_front(__DRIdrawablePrivate *dPriv,
- struct pipe_surface *from,
- int x, int y, unsigned w, unsigned h)
-{
- /* TODO send a message to the Xserver to copy to the real front buffer */
-}
-
-
-static struct pipe_surface *
-dri_surface_from_handle(struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width,
- unsigned height,
- unsigned pitch)
-{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
-
- buf = drm_api_hooks.buffer_from_handle(screen, "dri2 buffer", handle);
- if (!buf)
- return NULL;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth[0] = 1;
- templat.format = format;
- templat.width[0] = width;
- templat.height[0] = height;
- pf_get_block(templat.format, &templat.block);
-
- texture = screen->texture_blanket(screen,
- &templat,
- &pitch,
- buf);
-
- /* we don't need the buffer from this point on */
- pipe_buffer_reference(&buf, NULL);
-
- if (!texture)
- return NULL;
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
-}
-
-
-/**
- * This will be called a drawable is known to have been resized.
- */
-void
-dri_get_buffers(__DRIdrawablePrivate *dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
- struct pipe_surface *surface = NULL;
- struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen;
- __DRIbuffer *buffers = NULL;
- __DRIscreen *dri_screen = drawable->sPriv;
- __DRIdrawable *dri_drawable = drawable->dPriv;
- boolean have_depth = FALSE;
- int i, count;
-
- buffers = (*dri_screen->dri2.loader->getBuffers)(dri_drawable,
- &dri_drawable->w,
- &dri_drawable->h,
- drawable->attachments,
- drawable->num_attachments,
- &count,
- dri_drawable->loaderPrivate);
-
- if (buffers == NULL) {
- return;
- }
-
- /* set one cliprect to cover the whole dri_drawable */
- dri_drawable->x = 0;
- dri_drawable->y = 0;
- dri_drawable->backX = 0;
- dri_drawable->backY = 0;
- dri_drawable->numClipRects = 1;
- dri_drawable->pClipRects[0].x1 = 0;
- dri_drawable->pClipRects[0].y1 = 0;
- dri_drawable->pClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pClipRects[0].y2 = dri_drawable->h;
- dri_drawable->numBackClipRects = 1;
- dri_drawable->pBackClipRects[0].x1 = 0;
- dri_drawable->pBackClipRects[0].y1 = 0;
- dri_drawable->pBackClipRects[0].x2 = dri_drawable->w;
- dri_drawable->pBackClipRects[0].y2 = dri_drawable->h;
-
- for (i = 0; i < count; i++) {
- enum pipe_format format = 0;
- int index = 0;
-
- switch (buffers[i].attachment) {
- case __DRI_BUFFER_FRONT_LEFT:
- index = ST_SURFACE_FRONT_LEFT;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
- break;
- case __DRI_BUFFER_FAKE_FRONT_LEFT:
- index = ST_SURFACE_FRONT_LEFT;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
- break;
- case __DRI_BUFFER_BACK_LEFT:
- index = ST_SURFACE_BACK_LEFT;
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
- break;
- case __DRI_BUFFER_DEPTH:
- index = ST_SURFACE_DEPTH;
- format = PIPE_FORMAT_Z24S8_UNORM;
- break;
- case __DRI_BUFFER_STENCIL:
- index = ST_SURFACE_DEPTH;
- format = PIPE_FORMAT_Z24S8_UNORM;
- break;
- case __DRI_BUFFER_ACCUM:
- default:
- assert(0);
- }
- assert(buffers[i].cpp == 4);
-
- if (index == ST_SURFACE_DEPTH) {
- if (have_depth)
- continue;
- else
- have_depth = TRUE;
- }
-
- surface = dri_surface_from_handle(screen,
- buffers[i].name,
- format,
- dri_drawable->w,
- dri_drawable->h,
- buffers[i].pitch);
-
- st_set_framebuffer_surface(drawable->stfb, index, surface);
- pipe_surface_reference(&surface, NULL);
- }
- /* this needed, or else the state tracker fails to pick the new buffers */
- st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
-}
-
-
-void
-dri_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surf,
- void *context_private)
-{
- struct dri_context *ctx = (struct dri_context *)context_private;
- dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height);
-}
-
-
-void
-dri_swap_buffers(__DRIdrawablePrivate * dPriv)
-{
- /* not needed for dri2 */
- assert(0);
-}
-
-
-void
-dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h)
-{
- /* not needed for dri2 */
- assert(0);
-}
-
-
-/**
- * This is called when we need to set up GL rendering to a new X window.
- */
-boolean
-dri_create_buffer(__DRIscreenPrivate *sPriv,
- __DRIdrawablePrivate *dPriv,
- const __GLcontextModes *visual,
- boolean isPixmap)
-{
- enum pipe_format colorFormat, depthFormat, stencilFormat;
- struct dri_screen *screen = sPriv->private;
- struct dri_drawable *drawable = NULL;
- struct pipe_screen *pscreen = screen->pipe_screen;
- int i;
-
- if (isPixmap)
- goto fail; /* not implemented */
-
- drawable = CALLOC_STRUCT(dri_drawable);
- if (drawable == NULL)
- goto fail;
-
- /* XXX: todo: use the pipe_screen queries to figure out which
- * render targets are supportable.
- */
- assert(visual->redBits == 8);
- assert(visual->depthBits == 24 || visual->depthBits == 0);
- assert(visual->stencilBits == 8 || visual->stencilBits == 0);
-
- colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
-
- if (visual->depthBits) {
- if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET |
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
- depthFormat = PIPE_FORMAT_Z24S8_UNORM;
- else
- depthFormat = PIPE_FORMAT_S8Z24_UNORM;
- } else
- depthFormat = PIPE_FORMAT_NONE;
-
- if (visual->stencilBits) {
- if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET |
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
- stencilFormat = PIPE_FORMAT_Z24S8_UNORM;
- else
- stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
- } else
- stencilFormat = PIPE_FORMAT_NONE;
-
- drawable->stfb = st_create_framebuffer(visual,
- colorFormat,
- depthFormat,
- stencilFormat,
- dPriv->w,
- dPriv->h,
- (void*) drawable);
- if (drawable->stfb == NULL)
- goto fail;
-
- drawable->sPriv = sPriv;
- drawable->dPriv = dPriv;
- dPriv->driverPrivate = (void *) drawable;
-
- /* setup dri2 buffers information */
- i = 0;
- drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-#if 0
- /* TODO incase of double buffer visual, delay fake creation */
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
-#endif
- if (visual->doubleBufferMode)
- drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (visual->depthBits)
- drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- if (visual->stencilBits)
- drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
- drawable->num_attachments = i;
-
- return GL_TRUE;
-fail:
- FREE(drawable);
- return GL_FALSE;
-}
-
-
-void
-dri_destroy_buffer(__DRIdrawablePrivate *dPriv)
-{
- struct dri_drawable *drawable = dri_drawable(dPriv);
-
- st_unreference_framebuffer(drawable->stfb);
-
- FREE(drawable);
-}
-
-/* vim: set sw=3 ts=8 sts=3 expandtab: */
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
index 692a3c8b76..e825aa718b 100644
--- a/src/gallium/state_trackers/egl/Makefile
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -1,29 +1,19 @@
-TARGET = libegldrm.a
-CFILES = $(wildcard ./*.c)
-OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
-GALLIUMDIR = ../..
-TOP = ../../../..
+TOP = ../../../..
+include $(TOP)/configs/current
-include ${TOP}/configs/current
+LIBNAME = egldrm
-CFLAGS := \
- -I${GALLIUMDIR}/include \
- -I${GALLIUMDIR}/auxiliary \
- -I${TOP}/src/mesa/drivers/dri/common \
- -I${TOP}/src/mesa \
- -I$(TOP)/include \
- -I$(TOP)/src/egl/main \
- ${LIBDRM_CFLAGS} \
- ${CFLAGS}
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/mesa/drivers/dri/common \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/include \
+ -I$(TOP)/src/egl/main \
+ $(shell pkg-config --cflags-only-I libdrm)
-#############################################
-.PHONY = all clean
+C_SOURCES = $(wildcard ./*.c)
-all: ${TARGET}
-${TARGET}: ${OBJECTS}
- ar rcs $@ $^
-
-clean:
- rm -rf ${OBJECTS} ${TARGET}
+include ../../Makefile.template
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
index abdf84544f..8e62008461 100644
--- a/src/gallium/state_trackers/egl/egl_tracker.c
+++ b/src/gallium/state_trackers/egl/egl_tracker.c
@@ -146,7 +146,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
dev->drmFD = fd;
drm_get_device_id(dev);
- dev->screen = drm_api_hooks.create_screen(dev->drmFD, dev->deviceID);
+ dev->screen = drm_api_hooks.create_screen(dev->drmFD, NULL);
if (!dev->screen)
goto err_screen;
dev->winsys = dev->screen->winsys;
diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/fakeglx.c
index 65e7048188..85e7ecfb9e 100644
--- a/src/gallium/state_trackers/glx/xlib/fakeglx.c
+++ b/src/gallium/state_trackers/glx/xlib/fakeglx.c
@@ -97,6 +97,9 @@ struct fake_glx_context {
+#define DEFAULT_DIRECT GL_TRUE
+
+
/**********************************************************************/
/*** GLX Visual Code ***/
/**********************************************************************/
@@ -1059,7 +1062,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
return NULL;
}
- glxCtx->glxContext.isDirect = GL_FALSE;
+ glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
glxCtx->glxContext.currentDpy = dpy;
glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
@@ -1296,9 +1299,9 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
static Bool
Fake_glXIsDirect( Display *dpy, GLXContext ctx )
{
- (void) dpy;
+ struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
(void) ctx;
- return False;
+ return glxCtx->glxContext.isDirect;
}
@@ -2055,7 +2058,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
return NULL;
}
- glxCtx->glxContext.isDirect = GL_FALSE;
+ glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
glxCtx->glxContext.currentDpy = dpy;
glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
@@ -2277,7 +2280,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re
return NULL;
}
- glxCtx->glxContext.isDirect = GL_FALSE;
+ glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
glxCtx->glxContext.currentDpy = dpy;
glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index a3d1651653..79c2230588 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -1100,26 +1100,19 @@ XMesaContext XMesaGetCurrentContext( void )
-
-
-
-/*
- * Copy the back buffer to the front buffer. If there's no back buffer
- * this is a no-op.
+/**
+ * Swap front and back color buffers and have winsys display front buffer.
+ * If there's no front color buffer no swap actually occurs.
*/
PUBLIC
void XMesaSwapBuffers( XMesaBuffer b )
{
- struct pipe_surface *surf;
+ struct pipe_surface *frontLeftSurf;
- /* 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);
+ st_swapbuffers(b->stfb, &frontLeftSurf, NULL);
- st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf);
- if (surf) {
- driver.display_surface(b, surf);
+ if (frontLeftSurf) {
+ driver.display_surface(b, frontLeftSurf);
}
xmesa_check_and_update_buffer_size(NULL, b);
diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i
index f41a95e6eb..1d513abf3c 100644
--- a/src/gallium/state_trackers/python/p_texture.i
+++ b/src/gallium/state_trackers/python/p_texture.i
@@ -426,7 +426,7 @@ struct st_surface
if(!*STRING)
return;
- pipe_buffer_read(screen, $self, 0, $self->size, STRING);
+ pipe_buffer_read(screen, $self, 0, $self->size, *STRING);
}
%cstring_input_binary(const char *STRING, unsigned LENGTH);
diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py
index 5ea07724a5..5885e162c2 100755
--- a/src/gallium/state_trackers/python/retrace/interpreter.py
+++ b/src/gallium/state_trackers/python/retrace/interpreter.py
@@ -32,7 +32,7 @@ import struct
import gallium
import model
-import parser
+import parse as parser
try:
@@ -43,19 +43,27 @@ except ImportError:
return struct.unpack(fmt, buf[offset:offset + size])
-def make_image(surface):
+def make_image(surface, x=None, y=None, w=None, h=None):
+ if x is None:
+ x = 0
+ if y is None:
+ y = 0
+ if w is None:
+ w = surface.width - x
+ if h is None:
+ h = surface.height - y
data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
import Image
outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
return outimage
-def save_image(filename, surface):
- outimage = make_image(surface)
+def save_image(filename, surface, x=None, y=None, w=None, h=None):
+ outimage = make_image(surface, x, y, w, h)
outimage.save(filename, "PNG")
-def show_image(surface, title):
- outimage = make_image(surface)
+def show_image(surface, title, x=None, y=None, w=None, h=None):
+ outimage = make_image(surface, x, y, w, h)
import Tkinter as tk
from PIL import Image, ImageTk
@@ -305,7 +313,11 @@ class Screen(Object):
def get_tex_transfer(self, texture, face, level, zslice, usage, x, y, w, h):
if texture is None:
return None
- return Transfer(texture.get_surface(face, level, zslice), x, y, w, h)
+ transfer = Transfer(texture.get_surface(face, level, zslice), x, y, w, h)
+ if transfer and usage != gallium.PIPE_TRANSFER_WRITE:
+ if self.interpreter.options.all:
+ self.interpreter.present(transfer.surface, 'transf_read', x, y, w, h)
+ return transfer
def tex_transfer_destroy(self, transfer):
self.interpreter.unregister_object(transfer)
@@ -314,6 +326,8 @@ class Screen(Object):
if transfer is None:
return
transfer.surface.put_tile_raw(transfer.x, transfer.y, transfer.w, transfer.h, data, stride)
+ if self.interpreter.options.all:
+ self.interpreter.present(transfer.surface, 'transf_write', transfer.x, transfer.y, transfer.w, transfer.h)
def user_buffer_create(self, data, size):
# We don't really care to distinguish between user and regular buffers
@@ -577,6 +591,14 @@ class Context(Object):
self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count)
self._set_dirty()
+ def is_texture_referenced(self, texture, face, level):
+ #return self.real.is_texture_referenced(format, texture, face, level)
+ pass
+
+ def is_buffer_referenced(self, buf):
+ #return self.real.is_buffer_referenced(format, buf)
+ pass
+
def _set_dirty(self):
if self.interpreter.options.step:
self._present()
@@ -602,6 +624,9 @@ class Context(Object):
if self.cbufs and self.cbufs[0]:
self.interpreter.present(self.cbufs[0], "cbuf")
+ if self.zsbuf:
+ if self.interpreter.options.all:
+ self.interpreter.present(self.zsbuf, "zsbuf")
class Interpreter(parser.TraceDumper):
@@ -671,16 +696,16 @@ class Interpreter(parser.TraceDumper):
def verbosity(self, level):
return self.options.verbosity >= level
- def present(self, surface, description):
+ def present(self, surface, description, x=None, y=None, w=None, h=None):
if self.call_no < self.options.start:
return
if self.options.images:
- filename = '%s_%04u.png' % (description, self.call_no)
- save_image(filename, surface)
+ filename = '%04u_%s.png' % (self.call_no, description)
+ save_image(filename, surface, x, y, w, h)
else:
title = '%u. %s' % (self.call_no, description)
- show_image(surface, title)
+ show_image(surface, title, x, y, w, h)
class Main(parser.Main):
@@ -690,6 +715,7 @@ class Main(parser.Main):
optparser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbosity", help="no messages")
optparser.add_option("-v", "--verbose", action="count", dest="verbosity", default=1, help="increase verbosity level")
optparser.add_option("-i", "--images", action="store_true", dest="images", default=False, help="save images instead of showing them")
+ optparser.add_option("-a", "--all", action="store_true", dest="all", default=False, help="show depth, stencil, and transfers")
optparser.add_option("-s", "--step", action="store_true", dest="step", default=False, help="step trhough every draw")
optparser.add_option("-f", "--from", action="store", type="int", dest="start", default=0, help="from call no")
optparser.add_option("-t", "--to", action="store", type="int", dest="stop", default=0, help="until call no")
diff --git a/src/gallium/state_trackers/python/retrace/parse.py b/src/gallium/state_trackers/python/retrace/parse.py
new file mode 100755
index 0000000000..b0f3e8a432
--- /dev/null
+++ b/src/gallium/state_trackers/python/retrace/parse.py
@@ -0,0 +1,392 @@
+#!/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.
+#
+##########################################################################
+
+
+import sys
+import xml.parsers.expat
+import binascii
+import optparse
+
+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 '</' + self.name_or_data + '>'
+ 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
+ data = data.rstrip('\0')
+ 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 __init__(self, fp):
+ XmlParser.__init__(self, fp)
+ self.last_call_no = 0
+
+ def parse(self):
+ self.element_start('trace')
+ while self.token.type not in (ELEMENT_END, EOF):
+ call = self.parse_call()
+ self.handle_call(call)
+ if self.token.type != EOF:
+ self.element_end('trace')
+
+ def parse_call(self):
+ attrs = self.element_start('call')
+ try:
+ no = int(attrs['no'])
+ except KeyError:
+ self.last_call_no += 1
+ no = self.last_call_no
+ else:
+ self.last_call_no = no
+ 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("<arg ...> or <ret ...>", self.token)
+ self.element_end('call')
+
+ return Call(no, 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')
+
+ return Pointer(address)
+
+ def handle_call(self, call):
+ pass
+
+
+class TraceDumper(TraceParser):
+
+ def __init__(self, fp):
+ TraceParser.__init__(self, fp)
+ self.formatter = format.DefaultFormatter(sys.stdout)
+ self.pretty_printer = PrettyPrinter(self.formatter)
+
+ def handle_call(self, call):
+ call.visit(self.pretty_printer)
+ self.formatter.newline()
+
+
+class Main:
+ '''Common main class for all retrace command line utilities.'''
+
+ def __init__(self):
+ pass
+
+ def main(self):
+ optparser = self.get_optparser()
+ (options, args) = optparser.parse_args(sys.argv[1:])
+
+ if args:
+ for arg in args:
+ if arg.endswith('.gz'):
+ from gzip import GzipFile
+ stream = GzipFile(arg, 'rt')
+ elif arg.endswith('.bz2'):
+ from bz2 import BZ2File
+ stream = BZ2File(arg, 'rt')
+ else:
+ stream = open(arg, 'rt')
+ self.process_arg(stream, options)
+ else:
+ self.process_arg(stream, options)
+
+ def get_optparser(self):
+ optparser = optparse.OptionParser(
+ usage="\n\t%prog [options] [traces] ...")
+ return optparser
+
+ def process_arg(self, stream, options):
+ parser = TraceDumper(stream)
+ parser.parse()
+
+
+if __name__ == '__main__':
+ Main().main()
diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py
index b0f3e8a432..bd47c9a6b0 100755
--- a/src/gallium/state_trackers/python/retrace/parser.py
+++ b/src/gallium/state_trackers/python/retrace/parser.py
@@ -27,365 +27,7 @@
##########################################################################
-import sys
-import xml.parsers.expat
-import binascii
-import optparse
-
-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 '</' + self.name_or_data + '>'
- 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
- data = data.rstrip('\0')
- 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 __init__(self, fp):
- XmlParser.__init__(self, fp)
- self.last_call_no = 0
-
- def parse(self):
- self.element_start('trace')
- while self.token.type not in (ELEMENT_END, EOF):
- call = self.parse_call()
- self.handle_call(call)
- if self.token.type != EOF:
- self.element_end('trace')
-
- def parse_call(self):
- attrs = self.element_start('call')
- try:
- no = int(attrs['no'])
- except KeyError:
- self.last_call_no += 1
- no = self.last_call_no
- else:
- self.last_call_no = no
- 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("<arg ...> or <ret ...>", self.token)
- self.element_end('call')
-
- return Call(no, 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')
-
- return Pointer(address)
-
- def handle_call(self, call):
- pass
-
-
-class TraceDumper(TraceParser):
-
- def __init__(self, fp):
- TraceParser.__init__(self, fp)
- self.formatter = format.DefaultFormatter(sys.stdout)
- self.pretty_printer = PrettyPrinter(self.formatter)
-
- def handle_call(self, call):
- call.visit(self.pretty_printer)
- self.formatter.newline()
-
-
-class Main:
- '''Common main class for all retrace command line utilities.'''
-
- def __init__(self):
- pass
-
- def main(self):
- optparser = self.get_optparser()
- (options, args) = optparser.parse_args(sys.argv[1:])
-
- if args:
- for arg in args:
- if arg.endswith('.gz'):
- from gzip import GzipFile
- stream = GzipFile(arg, 'rt')
- elif arg.endswith('.bz2'):
- from bz2 import BZ2File
- stream = BZ2File(arg, 'rt')
- else:
- stream = open(arg, 'rt')
- self.process_arg(stream, options)
- else:
- self.process_arg(stream, options)
-
- def get_optparser(self):
- optparser = optparse.OptionParser(
- usage="\n\t%prog [options] [traces] ...")
- return optparser
-
- def process_arg(self, stream, options):
- parser = TraceDumper(stream)
- parser.parse()
+from parse import *
if __name__ == '__main__':
diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c
index 41cdeaa6fd..f0a4826a00 100644
--- a/src/gallium/state_trackers/python/st_softpipe_winsys.c
+++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c
@@ -260,7 +260,7 @@ st_softpipe_screen_create(void)
static struct pipe_context *
st_softpipe_context_create(struct pipe_screen *screen)
{
- return softpipe_create(screen, screen->winsys, NULL);
+ return softpipe_create(screen);
}
diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py
index a382424667..06130ea1c9 100755
--- a/src/gallium/state_trackers/python/tests/texture_sample.py
+++ b/src/gallium/state_trackers/python/tests/texture_sample.py
@@ -99,7 +99,7 @@ def is_pot(n):
return n & (n - 1) == 0
-class TextureTest(TestCase):
+class TextureColorSampleTest(TestCase):
tags = (
'target',
@@ -286,6 +286,206 @@ class TextureTest(TestCase):
self.assert_rgba(cbuf, x, y, w, h, expected_rgba, 4.0/256, 0.85)
+class TextureDepthSampleTest(TestCase):
+
+ tags = (
+ 'target',
+ 'format',
+ 'width',
+ 'height',
+ 'depth',
+ 'last_level',
+ 'face',
+ 'level',
+ 'zslice',
+ )
+
+ def test(self):
+ dev = self.dev
+
+ target = self.target
+ format = self.format
+ width = self.width
+ height = self.height
+ depth = self.depth
+ last_level = self.last_level
+ face = self.face
+ level = self.level
+ zslice = self.zslice
+
+ 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()
+
+ # 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)
+
+ # depth/stencil/alpha
+ depth_stencil_alpha = DepthStencilAlpha()
+ depth_stencil_alpha.depth.enabled = 1
+ depth_stencil_alpha.depth.writemask = 1
+ depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
+ 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_vs_clip_and_viewport = 1
+ ctx.set_rasterizer(rasterizer)
+
+ # 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_NEAREST
+ sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
+ sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
+ sampler.normalized_coords = 1
+ sampler.min_lod = 0
+ sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
+ ctx.set_sampler(0, sampler)
+
+ # texture
+ texture = dev.texture_create(
+ target = target,
+ format = format,
+ width = width,
+ height = height,
+ depth = depth,
+ last_level = last_level,
+ tex_usage = tex_usage,
+ )
+
+ expected_rgba = FloatArray(height*width*4)
+ texture.get_surface(
+ face = face,
+ level = level,
+ zslice = zslice,
+ ).sample_rgba(expected_rgba)
+
+ ctx.set_sampler_texture(0, texture)
+
+ # framebuffer
+ cbuf_tex = dev.texture_create(
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ width,
+ height,
+ tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET,
+ )
+
+ zsbuf_tex = dev.texture_create(
+ PIPE_FORMAT_Z24X8_UNORM,
+ width,
+ height,
+ tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET,
+ )
+
+ cbuf = cbuf_tex.get_surface()
+ zsbuf = zsbuf_tex.get_surface()
+ fb = Framebuffer()
+ fb.width = width
+ fb.height = height
+ fb.nr_cbufs = 1
+ fb.set_cbuf(0, cbuf)
+ fb.set_zsbuf(zsbuf)
+ ctx.set_framebuffer(fb)
+ rgba = FloatArray(4);
+ rgba[0] = 0.5
+ rgba[1] = 0.5
+ rgba[2] = 0.5
+ rgba[3] = 0.5
+ ctx.clear(PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0)
+ del 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
+ 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], LINEAR
+ DCL SAMP[0], CONSTANT
+ DCL OUT[0].z, POSITION
+ 0:TEX OUT[0].z, IN[0], SAMP[0], %s
+ 1:END
+ ''' % op)
+ #fs.dump()
+ ctx.set_fragment_shader(fs)
+
+ nverts = 4
+ nattrs = 2
+ verts = FloatArray(nverts * nattrs * 4)
+
+ x = 0
+ y = 0
+ w, h = minify((width, height), level)
+
+ pos = [
+ [x, y],
+ [x+w, y],
+ [x+w, y+h],
+ [x, y+h],
+ ]
+
+ tex = tex_coords(texture, face, level, zslice)
+
+ 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,
+ nattrs,
+ verts)
+
+ ctx.flush()
+
+ zsbuf = zsbuf_tex.get_surface()
+
+ self.assert_rgba(zsbuf, x, y, w, h, expected_rgba, 4.0/256, 0.85)
+
+
+
def main():
dev = Device()
@@ -304,11 +504,10 @@ def main():
PIPE_FORMAT_R5G6B5_UNORM,
PIPE_FORMAT_A1R5G5B5_UNORM,
PIPE_FORMAT_A4R4G4B4_UNORM,
- #PIPE_FORMAT_Z32_UNORM,
- #PIPE_FORMAT_Z24S8_UNORM,
- #PIPE_FORMAT_Z24X8_UNORM,
- #PIPE_FORMAT_Z16_UNORM,
- #PIPE_FORMAT_S8_UNORM,
+ PIPE_FORMAT_Z32_UNORM,
+ PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_FORMAT_Z24X8_UNORM,
+ PIPE_FORMAT_Z16_UNORM,
PIPE_FORMAT_A8_UNORM,
PIPE_FORMAT_L8_UNORM,
PIPE_FORMAT_YCBCR,
@@ -347,7 +546,17 @@ def main():
for level in range(0, last_level + 1):
zslice = 0
while zslice < depth >> level:
- test = TextureTest(
+ if format in (
+ PIPE_FORMAT_Z32_UNORM,
+ PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_FORMAT_Z24X8_UNORM,
+ PIPE_FORMAT_Z16_UNORM,
+ ):
+ klass = TextureDepthSampleTest
+ else:
+ klass = TextureColorSampleTest
+
+ test = klass(
dev = dev,
target = target,
format = format,
diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript
index 038a7a31b3..5bbcc7175f 100644
--- a/src/gallium/state_trackers/wgl/SConscript
+++ b/src/gallium/state_trackers/wgl/SConscript
@@ -26,8 +26,7 @@ if env['platform'] in ['windows']:
'shared/stw_device.c',
'shared/stw_framebuffer.c',
'shared/stw_pixelformat.c',
- 'shared/stw_quirks.c',
- 'shared/stw_arbextensionsstring.c',
+ 'shared/stw_extensionsstring.c',
'shared/stw_getprocaddress.c',
'shared/stw_arbpixelformat.c',
'shared/stw_tls.c',
diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.c b/src/gallium/state_trackers/wgl/icd/stw_icd.c
index faf7f2f410..347f40aa06 100644
--- a/src/gallium/state_trackers/wgl/icd/stw_icd.c
+++ b/src/gallium/state_trackers/wgl/icd/stw_icd.c
@@ -38,9 +38,6 @@
#define DBG 0
-static GLCLTPROCTABLE cpt;
-static boolean cpt_initialized = FALSE;
-
BOOL APIENTRY
DrvCopyContext(
@@ -57,7 +54,15 @@ DrvCreateLayerContext(
HDC hdc,
INT iLayerPlane )
{
- return stw_create_layer_context( hdc, iLayerPlane );
+ DHGLRC r;
+
+ r = stw_create_layer_context( hdc, iLayerPlane );
+
+ if (DBG)
+ debug_printf( "%s( %p, %i ) = %u\n",
+ __FUNCTION__, hdc, iLayerPlane, r );
+
+ return r;
}
DHGLRC APIENTRY
@@ -71,7 +76,15 @@ BOOL APIENTRY
DrvDeleteContext(
DHGLRC dhglrc )
{
- return stw_delete_context( dhglrc );
+ BOOL r;
+
+ r = stw_delete_context( dhglrc );
+
+ if (DBG)
+ debug_printf( "%s( %u ) = %u\n",
+ __FUNCTION__, dhglrc, r );
+
+ return r;
}
BOOL APIENTRY
@@ -129,7 +142,7 @@ DrvGetProcAddress(
r = stw_get_proc_address( lpszProc );
if (DBG)
- debug_printf( "%s( \", __FUNCTION__%s\" ) = %p\n", lpszProc, r );
+ debug_printf( "%s( \"%s\" ) = %p\n", __FUNCTION__, lpszProc, r );
return r;
}
@@ -165,351 +178,352 @@ DrvSetCallbackProcs(
}
-static void init_proc_table( GLCLTPROCTABLE *cpt )
-{
- GLDISPATCHTABLE *disp = &cpt->glDispatchTable;
-
- memset( cpt, 0, sizeof *cpt );
- cpt->cEntries = OPENGL_VERSION_110_ENTRIES;
-
-#define GPA_GL( NAME ) disp->NAME = gl##NAME
- GPA_GL( NewList );
- GPA_GL( EndList );
- GPA_GL( CallList );
- GPA_GL( CallLists );
- GPA_GL( DeleteLists );
- GPA_GL( GenLists );
- GPA_GL( ListBase );
- GPA_GL( Begin );
- GPA_GL( Bitmap );
- GPA_GL( Color3b );
- GPA_GL( Color3bv );
- GPA_GL( Color3d );
- GPA_GL( Color3dv );
- GPA_GL( Color3f );
- GPA_GL( Color3fv );
- GPA_GL( Color3i );
- GPA_GL( Color3iv );
- GPA_GL( Color3s );
- GPA_GL( Color3sv );
- GPA_GL( Color3ub );
- GPA_GL( Color3ubv );
- GPA_GL( Color3ui );
- GPA_GL( Color3uiv );
- GPA_GL( Color3us );
- GPA_GL( Color3usv );
- GPA_GL( Color4b );
- GPA_GL( Color4bv );
- GPA_GL( Color4d );
- GPA_GL( Color4dv );
- GPA_GL( Color4f );
- GPA_GL( Color4fv );
- GPA_GL( Color4i );
- GPA_GL( Color4iv );
- GPA_GL( Color4s );
- GPA_GL( Color4sv );
- GPA_GL( Color4ub );
- GPA_GL( Color4ubv );
- GPA_GL( Color4ui );
- GPA_GL( Color4uiv );
- GPA_GL( Color4us );
- GPA_GL( Color4usv );
- GPA_GL( EdgeFlag );
- GPA_GL( EdgeFlagv );
- GPA_GL( End );
- GPA_GL( Indexd );
- GPA_GL( Indexdv );
- GPA_GL( Indexf );
- GPA_GL( Indexfv );
- GPA_GL( Indexi );
- GPA_GL( Indexiv );
- GPA_GL( Indexs );
- GPA_GL( Indexsv );
- GPA_GL( Normal3b );
- GPA_GL( Normal3bv );
- GPA_GL( Normal3d );
- GPA_GL( Normal3dv );
- GPA_GL( Normal3f );
- GPA_GL( Normal3fv );
- GPA_GL( Normal3i );
- GPA_GL( Normal3iv );
- GPA_GL( Normal3s );
- GPA_GL( Normal3sv );
- GPA_GL( RasterPos2d );
- GPA_GL( RasterPos2dv );
- GPA_GL( RasterPos2f );
- GPA_GL( RasterPos2fv );
- GPA_GL( RasterPos2i );
- GPA_GL( RasterPos2iv );
- GPA_GL( RasterPos2s );
- GPA_GL( RasterPos2sv );
- GPA_GL( RasterPos3d );
- GPA_GL( RasterPos3dv );
- GPA_GL( RasterPos3f );
- GPA_GL( RasterPos3fv );
- GPA_GL( RasterPos3i );
- GPA_GL( RasterPos3iv );
- GPA_GL( RasterPos3s );
- GPA_GL( RasterPos3sv );
- GPA_GL( RasterPos4d );
- GPA_GL( RasterPos4dv );
- GPA_GL( RasterPos4f );
- GPA_GL( RasterPos4fv );
- GPA_GL( RasterPos4i );
- GPA_GL( RasterPos4iv );
- GPA_GL( RasterPos4s );
- GPA_GL( RasterPos4sv );
- GPA_GL( Rectd );
- GPA_GL( Rectdv );
- GPA_GL( Rectf );
- GPA_GL( Rectfv );
- GPA_GL( Recti );
- GPA_GL( Rectiv );
- GPA_GL( Rects );
- GPA_GL( Rectsv );
- GPA_GL( TexCoord1d );
- GPA_GL( TexCoord1dv );
- GPA_GL( TexCoord1f );
- GPA_GL( TexCoord1fv );
- GPA_GL( TexCoord1i );
- GPA_GL( TexCoord1iv );
- GPA_GL( TexCoord1s );
- GPA_GL( TexCoord1sv );
- GPA_GL( TexCoord2d );
- GPA_GL( TexCoord2dv );
- GPA_GL( TexCoord2f );
- GPA_GL( TexCoord2fv );
- GPA_GL( TexCoord2i );
- GPA_GL( TexCoord2iv );
- GPA_GL( TexCoord2s );
- GPA_GL( TexCoord2sv );
- GPA_GL( TexCoord3d );
- GPA_GL( TexCoord3dv );
- GPA_GL( TexCoord3f );
- GPA_GL( TexCoord3fv );
- GPA_GL( TexCoord3i );
- GPA_GL( TexCoord3iv );
- GPA_GL( TexCoord3s );
- GPA_GL( TexCoord3sv );
- GPA_GL( TexCoord4d );
- GPA_GL( TexCoord4dv );
- GPA_GL( TexCoord4f );
- GPA_GL( TexCoord4fv );
- GPA_GL( TexCoord4i );
- GPA_GL( TexCoord4iv );
- GPA_GL( TexCoord4s );
- GPA_GL( TexCoord4sv );
- GPA_GL( Vertex2d );
- GPA_GL( Vertex2dv );
- GPA_GL( Vertex2f );
- GPA_GL( Vertex2fv );
- GPA_GL( Vertex2i );
- GPA_GL( Vertex2iv );
- GPA_GL( Vertex2s );
- GPA_GL( Vertex2sv );
- GPA_GL( Vertex3d );
- GPA_GL( Vertex3dv );
- GPA_GL( Vertex3f );
- GPA_GL( Vertex3fv );
- GPA_GL( Vertex3i );
- GPA_GL( Vertex3iv );
- GPA_GL( Vertex3s );
- GPA_GL( Vertex3sv );
- GPA_GL( Vertex4d );
- GPA_GL( Vertex4dv );
- GPA_GL( Vertex4f );
- GPA_GL( Vertex4fv );
- GPA_GL( Vertex4i );
- GPA_GL( Vertex4iv );
- GPA_GL( Vertex4s );
- GPA_GL( Vertex4sv );
- GPA_GL( ClipPlane );
- GPA_GL( ColorMaterial );
- GPA_GL( CullFace );
- GPA_GL( Fogf );
- GPA_GL( Fogfv );
- GPA_GL( Fogi );
- GPA_GL( Fogiv );
- GPA_GL( FrontFace );
- GPA_GL( Hint );
- GPA_GL( Lightf );
- GPA_GL( Lightfv );
- GPA_GL( Lighti );
- GPA_GL( Lightiv );
- GPA_GL( LightModelf );
- GPA_GL( LightModelfv );
- GPA_GL( LightModeli );
- GPA_GL( LightModeliv );
- GPA_GL( LineStipple );
- GPA_GL( LineWidth );
- GPA_GL( Materialf );
- GPA_GL( Materialfv );
- GPA_GL( Materiali );
- GPA_GL( Materialiv );
- GPA_GL( PointSize );
- GPA_GL( PolygonMode );
- GPA_GL( PolygonStipple );
- GPA_GL( Scissor );
- GPA_GL( ShadeModel );
- GPA_GL( TexParameterf );
- GPA_GL( TexParameterfv );
- GPA_GL( TexParameteri );
- GPA_GL( TexParameteriv );
- GPA_GL( TexImage1D );
- GPA_GL( TexImage2D );
- GPA_GL( TexEnvf );
- GPA_GL( TexEnvfv );
- GPA_GL( TexEnvi );
- GPA_GL( TexEnviv );
- GPA_GL( TexGend );
- GPA_GL( TexGendv );
- GPA_GL( TexGenf );
- GPA_GL( TexGenfv );
- GPA_GL( TexGeni );
- GPA_GL( TexGeniv );
- GPA_GL( FeedbackBuffer );
- GPA_GL( SelectBuffer );
- GPA_GL( RenderMode );
- GPA_GL( InitNames );
- GPA_GL( LoadName );
- GPA_GL( PassThrough );
- GPA_GL( PopName );
- GPA_GL( PushName );
- GPA_GL( DrawBuffer );
- GPA_GL( Clear );
- GPA_GL( ClearAccum );
- GPA_GL( ClearIndex );
- GPA_GL( ClearColor );
- GPA_GL( ClearStencil );
- GPA_GL( ClearDepth );
- GPA_GL( StencilMask );
- GPA_GL( ColorMask );
- GPA_GL( DepthMask );
- GPA_GL( IndexMask );
- GPA_GL( Accum );
- GPA_GL( Disable );
- GPA_GL( Enable );
- GPA_GL( Finish );
- GPA_GL( Flush );
- GPA_GL( PopAttrib );
- GPA_GL( PushAttrib );
- GPA_GL( Map1d );
- GPA_GL( Map1f );
- GPA_GL( Map2d );
- GPA_GL( Map2f );
- GPA_GL( MapGrid1d );
- GPA_GL( MapGrid1f );
- GPA_GL( MapGrid2d );
- GPA_GL( MapGrid2f );
- GPA_GL( EvalCoord1d );
- GPA_GL( EvalCoord1dv );
- GPA_GL( EvalCoord1f );
- GPA_GL( EvalCoord1fv );
- GPA_GL( EvalCoord2d );
- GPA_GL( EvalCoord2dv );
- GPA_GL( EvalCoord2f );
- GPA_GL( EvalCoord2fv );
- GPA_GL( EvalMesh1 );
- GPA_GL( EvalPoint1 );
- GPA_GL( EvalMesh2 );
- GPA_GL( EvalPoint2 );
- GPA_GL( AlphaFunc );
- GPA_GL( BlendFunc );
- GPA_GL( LogicOp );
- GPA_GL( StencilFunc );
- GPA_GL( StencilOp );
- GPA_GL( DepthFunc );
- GPA_GL( PixelZoom );
- GPA_GL( PixelTransferf );
- GPA_GL( PixelTransferi );
- GPA_GL( PixelStoref );
- GPA_GL( PixelStorei );
- GPA_GL( PixelMapfv );
- GPA_GL( PixelMapuiv );
- GPA_GL( PixelMapusv );
- GPA_GL( ReadBuffer );
- GPA_GL( CopyPixels );
- GPA_GL( ReadPixels );
- GPA_GL( DrawPixels );
- GPA_GL( GetBooleanv );
- GPA_GL( GetClipPlane );
- GPA_GL( GetDoublev );
- GPA_GL( GetError );
- GPA_GL( GetFloatv );
- GPA_GL( GetIntegerv );
- GPA_GL( GetLightfv );
- GPA_GL( GetLightiv );
- GPA_GL( GetMapdv );
- GPA_GL( GetMapfv );
- GPA_GL( GetMapiv );
- GPA_GL( GetMaterialfv );
- GPA_GL( GetMaterialiv );
- GPA_GL( GetPixelMapfv );
- GPA_GL( GetPixelMapuiv );
- GPA_GL( GetPixelMapusv );
- GPA_GL( GetPolygonStipple );
- GPA_GL( GetString );
- GPA_GL( GetTexEnvfv );
- GPA_GL( GetTexEnviv );
- GPA_GL( GetTexGendv );
- GPA_GL( GetTexGenfv );
- GPA_GL( GetTexGeniv );
- GPA_GL( GetTexImage );
- GPA_GL( GetTexParameterfv );
- GPA_GL( GetTexParameteriv );
- GPA_GL( GetTexLevelParameterfv );
- GPA_GL( GetTexLevelParameteriv );
- GPA_GL( IsEnabled );
- GPA_GL( IsList );
- GPA_GL( DepthRange );
- GPA_GL( Frustum );
- GPA_GL( LoadIdentity );
- GPA_GL( LoadMatrixf );
- GPA_GL( LoadMatrixd );
- GPA_GL( MatrixMode );
- GPA_GL( MultMatrixf );
- GPA_GL( MultMatrixd );
- GPA_GL( Ortho );
- GPA_GL( PopMatrix );
- GPA_GL( PushMatrix );
- GPA_GL( Rotated );
- GPA_GL( Rotatef );
- GPA_GL( Scaled );
- GPA_GL( Scalef );
- GPA_GL( Translated );
- GPA_GL( Translatef );
- GPA_GL( Viewport );
- GPA_GL( ArrayElement );
- GPA_GL( BindTexture );
- GPA_GL( ColorPointer );
- GPA_GL( DisableClientState );
- GPA_GL( DrawArrays );
- GPA_GL( DrawElements );
- GPA_GL( EdgeFlagPointer );
- GPA_GL( EnableClientState );
- GPA_GL( IndexPointer );
- GPA_GL( Indexub );
- GPA_GL( Indexubv );
- GPA_GL( InterleavedArrays );
- GPA_GL( NormalPointer );
- GPA_GL( PolygonOffset );
- GPA_GL( TexCoordPointer );
- GPA_GL( VertexPointer );
- GPA_GL( AreTexturesResident );
- GPA_GL( CopyTexImage1D );
- GPA_GL( CopyTexImage2D );
- GPA_GL( CopyTexSubImage1D );
- GPA_GL( CopyTexSubImage2D );
- GPA_GL( DeleteTextures );
- GPA_GL( GenTextures );
- GPA_GL( GetPointerv );
- GPA_GL( IsTexture );
- GPA_GL( PrioritizeTextures );
- GPA_GL( TexSubImage1D );
- GPA_GL( TexSubImage2D );
- GPA_GL( PopClientAttrib );
- GPA_GL( PushClientAttrib );
-}
+/**
+ * Although WGL allows different dispatch entrypoints per context
+ */
+static const GLCLTPROCTABLE cpt =
+{
+ OPENGL_VERSION_110_ENTRIES,
+ {
+ &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,
+ &glBindTexture,
+ &glColorPointer,
+ &glDisableClientState,
+ &glDrawArrays,
+ &glDrawElements,
+ &glEdgeFlagPointer,
+ &glEnableClientState,
+ &glIndexPointer,
+ &glIndexub,
+ &glIndexubv,
+ &glInterleavedArrays,
+ &glNormalPointer,
+ &glPolygonOffset,
+ &glTexCoordPointer,
+ &glVertexPointer,
+ &glAreTexturesResident,
+ &glCopyTexImage1D,
+ &glCopyTexImage2D,
+ &glCopyTexSubImage1D,
+ &glCopyTexSubImage2D,
+ &glDeleteTextures,
+ &glGenTextures,
+ &glGetPointerv,
+ &glIsTexture,
+ &glPrioritizeTextures,
+ &glTexSubImage1D,
+ &glTexSubImage2D,
+ &glPopClientAttrib,
+ &glPushClientAttrib
+ }
+};
+
PGLCLTPROCTABLE APIENTRY
DrvSetContext(
@@ -517,21 +531,16 @@ DrvSetContext(
DHGLRC dhglrc,
PFN_SETPROCTABLE pfnSetProcTable )
{
- if (DBG)
- debug_printf( "%s( 0x%p, %u, 0x%p )\n",
- __FUNCTION__, hdc, dhglrc, pfnSetProcTable );
-
- /* Although WGL allows different dispatch entrypoints per
- */
- if (!cpt_initialized) {
- init_proc_table( &cpt );
- cpt_initialized = TRUE;
- }
-
+ PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
+
if (!stw_make_current( hdc, dhglrc ))
- return NULL;
+ r = NULL;
- return &cpt;
+ if (DBG)
+ debug_printf( "%s( 0x%p, %u, 0x%p ) = %p\n",
+ __FUNCTION__, hdc, dhglrc, pfnSetProcTable, r );
+
+ return r;
}
int APIENTRY
@@ -571,7 +580,7 @@ DrvShareLists(
if (DBG)
debug_printf( "%s\n", __FUNCTION__ );
- return FALSE;
+ return stw_share_lists(dhglrc1, dhglrc2);
}
BOOL APIENTRY
@@ -592,7 +601,7 @@ DrvSwapLayerBuffers(
if (DBG)
debug_printf( "%s\n", __FUNCTION__ );
- return FALSE;
+ return stw_swap_layer_buffers( hdc, fuPlanes );
}
BOOL APIENTRY
diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.h b/src/gallium/state_trackers/wgl/icd/stw_icd.h
index 8e676fb5b7..cbc1a66548 100644
--- a/src/gallium/state_trackers/wgl/icd/stw_icd.h
+++ b/src/gallium/state_trackers/wgl/icd/stw_icd.h
@@ -25,8 +25,8 @@
*
**************************************************************************/
-#ifndef DRV_H
-#define DRV_H
+#ifndef STW_ICD_H
+#define STW_ICD_H
#include <windows.h>
@@ -486,4 +486,4 @@ BOOL APIENTRY
DrvValidateVersion(
ULONG ulVersion );
-#endif /* DRV_H */
+#endif /* STW_ICD_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c b/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c
index f563635420..0e2d407699 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c
@@ -25,75 +25,30 @@
*
**************************************************************************/
+/**
+ * @file
+ *
+ * WGL_ARB_pixel_format extension implementation.
+ *
+ * @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt
+ */
+
+
#include <windows.h>
+#define WGL_WGLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
#include "pipe/p_compiler.h"
#include "util/u_memory.h"
#include "stw_public.h"
#include "stw_pixelformat.h"
-#include "stw_arbpixelformat.h"
-
-#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
-#define WGL_DRAW_TO_WINDOW_ARB 0x2001
-#define WGL_DRAW_TO_BITMAP_ARB 0x2002
-#define WGL_ACCELERATION_ARB 0x2003
-#define WGL_NEED_PALETTE_ARB 0x2004
-#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
-#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
-#define WGL_SWAP_METHOD_ARB 0x2007
-#define WGL_NUMBER_OVERLAYS_ARB 0x2008
-#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
-#define WGL_TRANSPARENT_ARB 0x200A
-#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
-#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
-#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
-#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
-#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
-#define WGL_SHARE_DEPTH_ARB 0x200C
-#define WGL_SHARE_STENCIL_ARB 0x200D
-#define WGL_SHARE_ACCUM_ARB 0x200E
-#define WGL_SUPPORT_GDI_ARB 0x200F
-#define WGL_SUPPORT_OPENGL_ARB 0x2010
-#define WGL_DOUBLE_BUFFER_ARB 0x2011
-#define WGL_STEREO_ARB 0x2012
-#define WGL_PIXEL_TYPE_ARB 0x2013
-#define WGL_COLOR_BITS_ARB 0x2014
-#define WGL_RED_BITS_ARB 0x2015
-#define WGL_RED_SHIFT_ARB 0x2016
-#define WGL_GREEN_BITS_ARB 0x2017
-#define WGL_GREEN_SHIFT_ARB 0x2018
-#define WGL_BLUE_BITS_ARB 0x2019
-#define WGL_BLUE_SHIFT_ARB 0x201A
-#define WGL_ALPHA_BITS_ARB 0x201B
-#define WGL_ALPHA_SHIFT_ARB 0x201C
-#define WGL_ACCUM_BITS_ARB 0x201D
-#define WGL_ACCUM_RED_BITS_ARB 0x201E
-#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
-#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
-#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
-#define WGL_DEPTH_BITS_ARB 0x2022
-#define WGL_STENCIL_BITS_ARB 0x2023
-#define WGL_AUX_BUFFERS_ARB 0x2024
-
-#define WGL_NO_ACCELERATION_ARB 0x2025
-#define WGL_GENERIC_ACCELERATION_ARB 0x2026
-#define WGL_FULL_ACCELERATION_ARB 0x2027
-
-#define WGL_SWAP_EXCHANGE_ARB 0x2028
-#define WGL_SWAP_COPY_ARB 0x2029
-#define WGL_SWAP_UNDEFINED_ARB 0x202A
-
-#define WGL_TYPE_RGBA_ARB 0x202B
-#define WGL_TYPE_COLORINDEX_ARB 0x202C
-
-/* From arb_multisample:
- */
-#define WGL_SAMPLE_BUFFERS_ARB 0x2041
-#define WGL_SAMPLES_ARB 0x2042
static boolean
-query_attrib(
+stw_query_attrib(
int iPixelFormat,
int iLayerPlane,
int attrib,
@@ -101,9 +56,9 @@ query_attrib(
{
uint count;
uint index;
- const struct pixelformat_info *pf;
+ const struct stw_pixelformat_info *pfi;
- count = pixelformat_get_extended_count();
+ count = stw_pixelformat_get_extended_count();
if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {
*pvalue = (int) count;
@@ -114,30 +69,27 @@ query_attrib(
if (index >= count)
return FALSE;
- pf = pixelformat_get_info( index );
+ pfi = stw_pixelformat_get_info( index );
switch (attrib) {
case WGL_DRAW_TO_WINDOW_ARB:
- *pvalue = TRUE;
+ *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE;
return TRUE;
case WGL_DRAW_TO_BITMAP_ARB:
- *pvalue = FALSE;
+ *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE;
return TRUE;
case WGL_NEED_PALETTE_ARB:
- *pvalue = FALSE;
+ *pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE;
return TRUE;
case WGL_NEED_SYSTEM_PALETTE_ARB:
- *pvalue = FALSE;
+ *pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE;
return TRUE;
case WGL_SWAP_METHOD_ARB:
- if (pf->flags & PF_FLAG_DOUBLEBUFFER)
- *pvalue = WGL_SWAP_COPY_ARB;
- else
- *pvalue = WGL_SWAP_UNDEFINED_ARB;
+ *pvalue = pfi->pfd.dwFlags & PFD_SWAP_COPY ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB;
return TRUE;
case WGL_SWAP_LAYER_BUFFERS_ARB:
@@ -179,96 +131,108 @@ query_attrib(
break;
case WGL_SUPPORT_GDI_ARB:
- *pvalue = FALSE;
+ *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE;
break;
case WGL_SUPPORT_OPENGL_ARB:
- *pvalue = TRUE;
+ *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE;
break;
case WGL_DOUBLE_BUFFER_ARB:
- if (pf->flags & PF_FLAG_DOUBLEBUFFER)
- *pvalue = TRUE;
- else
- *pvalue = FALSE;
+ *pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE;
break;
case WGL_STEREO_ARB:
- *pvalue = FALSE;
+ *pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE;
break;
case WGL_PIXEL_TYPE_ARB:
- *pvalue = WGL_TYPE_RGBA_ARB;
+ switch (pfi->pfd.iPixelType) {
+ case PFD_TYPE_RGBA:
+ *pvalue = WGL_TYPE_RGBA_ARB;
+ break;
+ case PFD_TYPE_COLORINDEX:
+ *pvalue = WGL_TYPE_COLORINDEX_ARB;
+ break;
+ default:
+ return FALSE;
+ }
break;
case WGL_COLOR_BITS_ARB:
- *pvalue = (int) (pf->color.redbits + pf->color.greenbits + pf->color.bluebits);
+ *pvalue = pfi->pfd.cColorBits;
break;
case WGL_RED_BITS_ARB:
- *pvalue = (int) pf->color.redbits;
+ *pvalue = pfi->pfd.cRedBits;
break;
case WGL_RED_SHIFT_ARB:
- *pvalue = (int) pf->color.redshift;
+ *pvalue = pfi->pfd.cRedShift;
break;
case WGL_GREEN_BITS_ARB:
- *pvalue = (int) pf->color.greenbits;
+ *pvalue = pfi->pfd.cGreenBits;
break;
case WGL_GREEN_SHIFT_ARB:
- *pvalue = (int) pf->color.greenshift;
+ *pvalue = pfi->pfd.cGreenShift;
break;
case WGL_BLUE_BITS_ARB:
- *pvalue = (int) pf->color.bluebits;
+ *pvalue = pfi->pfd.cBlueBits;
break;
case WGL_BLUE_SHIFT_ARB:
- *pvalue = (int) pf->color.blueshift;
+ *pvalue = pfi->pfd.cBlueShift;
break;
case WGL_ALPHA_BITS_ARB:
- *pvalue = (int) pf->alpha.alphabits;
+ *pvalue = pfi->pfd.cAlphaBits;
break;
case WGL_ALPHA_SHIFT_ARB:
- *pvalue = (int) pf->alpha.alphashift;
+ *pvalue = pfi->pfd.cAlphaShift;
break;
case WGL_ACCUM_BITS_ARB:
+ *pvalue = pfi->pfd.cAccumBits;
+ break;
+
case WGL_ACCUM_RED_BITS_ARB:
+ *pvalue = pfi->pfd.cAccumRedBits;
+ break;
+
case WGL_ACCUM_GREEN_BITS_ARB:
+ *pvalue = pfi->pfd.cAccumGreenBits;
+ break;
+
case WGL_ACCUM_BLUE_BITS_ARB:
+ *pvalue = pfi->pfd.cAccumBlueBits;
+ break;
+
case WGL_ACCUM_ALPHA_BITS_ARB:
- *pvalue = 0;
+ *pvalue = pfi->pfd.cAccumAlphaBits;
break;
case WGL_DEPTH_BITS_ARB:
- *pvalue = (int) pf->depth.depthbits;
+ *pvalue = pfi->pfd.cDepthBits;
break;
case WGL_STENCIL_BITS_ARB:
- *pvalue = (int) pf->depth.stencilbits;
+ *pvalue = pfi->pfd.cStencilBits;
break;
case WGL_AUX_BUFFERS_ARB:
- *pvalue = 0;
+ *pvalue = pfi->pfd.cAuxBuffers;
break;
case WGL_SAMPLE_BUFFERS_ARB:
- if (pf->flags & PF_FLAG_MULTISAMPLED)
- *pvalue = stw_query_sample_buffers();
- else
- *pvalue = 0;
+ *pvalue = pfi->numSampleBuffers;
break;
case WGL_SAMPLES_ARB:
- if (pf->flags & PF_FLAG_MULTISAMPLED)
- *pvalue = stw_query_samples();
- else
- *pvalue = 0;
+ *pvalue = pfi->numSamples;
break;
default:
@@ -285,7 +249,7 @@ struct attrib_match_info
BOOL exact;
};
-static struct attrib_match_info attrib_match[] = {
+static const struct attrib_match_info attrib_match[] = {
/* WGL_ARB_pixel_format */
{ WGL_DRAW_TO_WINDOW_ARB, 0, TRUE },
@@ -324,7 +288,7 @@ static struct attrib_match_info attrib_match[] = {
{ WGL_SAMPLES_ARB, 2, FALSE }
};
-struct pixelformat_score
+struct stw_pixelformat_score
{
int points;
uint index;
@@ -332,13 +296,13 @@ struct pixelformat_score
static BOOL
score_pixelformats(
- struct pixelformat_score *scores,
+ struct stw_pixelformat_score *scores,
uint count,
int attribute,
int expected_value )
{
uint i;
- struct attrib_match_info *ami = NULL;
+ const struct attrib_match_info *ami = NULL;
uint index;
/* Find out if a given attribute should be considered for score calculation.
@@ -358,7 +322,7 @@ score_pixelformats(
for (index = 0; index < count; index++) {
int actual_value;
- if (!query_attrib( index + 1, 0, attribute, &actual_value ))
+ if (!stw_query_attrib( index + 1, 0, attribute, &actual_value ))
return FALSE;
if (ami->exact) {
@@ -395,7 +359,7 @@ wglChoosePixelFormatARB(
UINT *nNumFormats )
{
uint count;
- struct pixelformat_score *scores;
+ struct stw_pixelformat_score *scores;
uint i;
*nNumFormats = 0;
@@ -405,8 +369,8 @@ wglChoosePixelFormatARB(
* points for a mismatch when the match does not have to be exact.
* Set a score to 0 if there is a mismatch for an exact match criteria.
*/
- count = pixelformat_get_extended_count();
- scores = (struct pixelformat_score *) MALLOC( count * sizeof( struct pixelformat_score ) );
+ count = stw_pixelformat_get_extended_count();
+ scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) );
if (scores == NULL)
return FALSE;
for (i = 0; i < count; i++) {
@@ -446,7 +410,7 @@ wglChoosePixelFormatARB(
swapped = FALSE;
for (i = 1; i < n; i++) {
if (scores[i - 1].points < scores[i].points) {
- struct pixelformat_score score = scores[i - 1];
+ struct stw_pixelformat_score score = scores[i - 1];
scores[i - 1] = scores[i];
scores[i] = score;
@@ -489,7 +453,7 @@ wglGetPixelFormatAttribfvARB(
for (i = 0; i < nAttributes; i++) {
int value;
- if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
+ if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
return FALSE;
pfValues[i] = (FLOAT) value;
}
@@ -511,7 +475,7 @@ wglGetPixelFormatAttribivARB(
(void) hdc;
for (i = 0; i < nAttributes; i++) {
- if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
+ if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h b/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h
deleted file mode 100644
index a6c4259942..0000000000
--- a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h
+++ /dev/null
@@ -1,61 +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 WGL_ARBPIXELFORMAT_H
-#define WGL_ARBPIXELFORMAT_H
-
-
-/* Extension functions for get_proc_address:
- */
-WINGDIAPI BOOL APIENTRY
-wglChoosePixelFormatARB(
- HDC hdc,
- const int *piAttribIList,
- const FLOAT *pfAttribFList,
- UINT nMaxFormats,
- int *piFormats,
- UINT *nNumFormats );
-
-WINGDIAPI BOOL APIENTRY
-wglGetPixelFormatAttribfvARB(
- HDC hdc,
- int iPixelFormat,
- int iLayerPlane,
- UINT nAttributes,
- const int *piAttributes,
- FLOAT *pfValues );
-
-WINGDIAPI BOOL APIENTRY
-wglGetPixelFormatAttribivARB(
- HDC hdc,
- int iPixelFormat,
- int iLayerPlane,
- UINT nAttributes,
- const int *piAttributes,
- int *piValues );
-
-#endif /* WGL_ARBPIXELFORMAT_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c
index f890225242..662b5fbcd2 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_context.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_context.c
@@ -59,11 +59,12 @@ stw_copy_context(
pipe_mutex_lock( stw_dev->mutex );
- src = stw_lookup_context( hglrcSrc );
- dst = stw_lookup_context( hglrcDst );
+ src = stw_lookup_context_locked( hglrcSrc );
+ dst = stw_lookup_context_locked( hglrcDst );
if (src && dst) {
/* FIXME */
+ assert(0);
(void) src;
(void) dst;
(void) mask;
@@ -74,58 +75,61 @@ stw_copy_context(
return ret;
}
+BOOL
+stw_share_lists(
+ UINT_PTR hglrc1,
+ UINT_PTR hglrc2 )
+{
+ struct stw_context *ctx1;
+ struct stw_context *ctx2;
+ BOOL ret = FALSE;
+
+ pipe_mutex_lock( stw_dev->mutex );
+
+ ctx1 = stw_lookup_context_locked( hglrc1 );
+ ctx2 = stw_lookup_context_locked( hglrc2 );
+
+ if (ctx1 && ctx2 &&
+ ctx1->iPixelFormat == ctx2->iPixelFormat) {
+ ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
+ }
+
+ pipe_mutex_unlock( stw_dev->mutex );
+
+ return ret;
+}
+
UINT_PTR
stw_create_layer_context(
HDC hdc,
int iLayerPlane )
{
- uint pfi;
- const struct pixelformat_info *pf = NULL;
+ int iPixelFormat;
+ const struct stw_pixelformat_info *pfi;
+ GLvisual visual;
struct stw_context *ctx = NULL;
- GLvisual *visual = NULL;
struct pipe_screen *screen = NULL;
struct pipe_context *pipe = NULL;
- UINT_PTR hglrc = 0;
-
+
if(!stw_dev)
return 0;
if (iLayerPlane != 0)
return 0;
- pfi = stw_pixelformat_get( hdc );
- if (pfi == 0)
+ iPixelFormat = GetPixelFormat(hdc);
+ if(!iPixelFormat)
return 0;
-
- pf = pixelformat_get_info( pfi - 1 );
-
+
+ pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
+ stw_pixelformat_visual(&visual, pfi);
+
ctx = CALLOC_STRUCT( stw_context );
if (ctx == NULL)
- return 0;
+ goto no_ctx;
ctx->hdc = hdc;
- ctx->color_bits = GetDeviceCaps( ctx->hdc, BITSPIXEL );
-
- /* Create visual based on flags
- */
- visual = _mesa_create_visual(
- GL_TRUE,
- (pf->flags & PF_FLAG_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE,
- GL_FALSE,
- pf->color.redbits,
- pf->color.greenbits,
- pf->color.bluebits,
- pf->alpha.alphabits,
- 0,
- pf->depth.depthbits,
- pf->depth.stencilbits,
- 0,
- 0,
- 0,
- 0,
- (pf->flags & PF_FLAG_MULTISAMPLED) ? stw_query_samples() : 0 );
- if (visual == NULL)
- goto fail;
+ ctx->iPixelFormat = iPixelFormat;
screen = stw_dev->screen;
@@ -137,7 +141,7 @@ stw_create_layer_context(
pipe = stw_dev->stw_winsys->create_context( screen );
if (pipe == NULL)
- goto fail;
+ goto no_pipe;
#ifdef DEBUG
/* Wrap context */
@@ -145,34 +149,32 @@ stw_create_layer_context(
pipe = trace_context_create(stw_dev->screen, pipe);
#endif
+ /* pass to stw_flush_frontbuffer as context_private */
assert(!pipe->priv);
pipe->priv = hdc;
- ctx->st = st_create_context( pipe, visual, NULL );
+ ctx->st = st_create_context( pipe, &visual, NULL );
if (ctx->st == NULL)
- goto fail;
+ goto no_st_ctx;
ctx->st->ctx->DriverCtx = ctx;
pipe_mutex_lock( stw_dev->mutex );
- {
- hglrc = handle_table_add(stw_dev->ctx_table, ctx);
- }
+ ctx->hglrc = handle_table_add(stw_dev->ctx_table, ctx);
pipe_mutex_unlock( stw_dev->mutex );
-
- /* Success?
- */
- if (hglrc != 0)
- return hglrc;
-
-fail:
- if (visual)
- _mesa_destroy_visual( visual );
-
- if (pipe)
- pipe->destroy( pipe );
-
- FREE( ctx );
+ if (!ctx->hglrc)
+ goto no_hglrc;
+
+ return ctx->hglrc;
+
+no_hglrc:
+ st_destroy_context(ctx->st);
+ goto no_pipe; /* st_context_destroy already destroys pipe */
+no_st_ctx:
+ pipe->destroy( pipe );
+no_pipe:
+ FREE(ctx);
+no_ctx:
return 0;
}
@@ -187,38 +189,24 @@ stw_delete_context(
return FALSE;
pipe_mutex_lock( stw_dev->mutex );
+ ctx = stw_lookup_context_locked(hglrc);
+ handle_table_remove(stw_dev->ctx_table, hglrc);
+ pipe_mutex_unlock( stw_dev->mutex );
- ctx = stw_lookup_context(hglrc);
if (ctx) {
GLcontext *glctx = ctx->st->ctx;
GET_CURRENT_CONTEXT( glcurctx );
- struct stw_framebuffer *fb;
- /* Unbind current if deleting current context.
- */
+ /* Unbind current if deleting current context. */
if (glcurctx == glctx)
st_make_current( NULL, NULL, NULL );
- fb = framebuffer_from_hdc( ctx->hdc );
- if (fb)
- framebuffer_destroy( fb );
-
- if (WindowFromDC( ctx->hdc ) != NULL)
- ReleaseDC( WindowFromDC( ctx->hdc ), ctx->hdc );
-
- pipe_mutex_lock(stw_dev->mutex);
- {
- st_destroy_context(ctx->st);
- FREE(ctx);
- handle_table_remove(stw_dev->ctx_table, hglrc);
- }
- pipe_mutex_unlock(stw_dev->mutex);
+ st_destroy_context(ctx->st);
+ FREE(ctx);
ret = TRUE;
}
- pipe_mutex_unlock( stw_dev->mutex );
-
return ret;
}
@@ -226,62 +214,69 @@ BOOL
stw_release_context(
UINT_PTR hglrc )
{
- BOOL ret = FALSE;
+ struct stw_context *ctx;
if (!stw_dev)
- return ret;
+ return FALSE;
pipe_mutex_lock( stw_dev->mutex );
- {
- struct stw_context *ctx;
-
- /* XXX: The expectation is that ctx is the same context which is
- * current for this thread. We should check that and return False
- * if not the case.
- */
- ctx = stw_lookup_context( hglrc );
- if (ctx == NULL)
- goto done;
+ ctx = stw_lookup_context_locked( hglrc );
+ pipe_mutex_unlock( stw_dev->mutex );
- if (stw_make_current( NULL, 0 ) == FALSE)
- goto done;
+ if (!ctx)
+ return FALSE;
+
+ /* The expectation is that ctx is the same context which is
+ * current for this thread. We should check that and return False
+ * if not the case.
+ */
+ {
+ GLcontext *glctx = ctx->st->ctx;
+ GET_CURRENT_CONTEXT( glcurctx );
- ret = TRUE;
+ if (glcurctx != glctx)
+ return FALSE;
}
-done:
- pipe_mutex_unlock( stw_dev->mutex );
-
- return ret;
-}
-/* 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;
+ if (stw_make_current( NULL, 0 ) == FALSE)
+ return FALSE;
- GetClientRect( WindowFromDC( hdc ), &rect );
- *width = rect.right - rect.left;
- *height = rect.bottom - rect.top;
- }
- else {
- *width = GetDeviceCaps( hdc, HORZRES );
- *height = GetDeviceCaps( hdc, VERTRES );
- }
+ return TRUE;
}
+
UINT_PTR
stw_get_current_context( void )
{
- return stw_tls_get_data()->currentGLRC;
+ GET_CURRENT_CONTEXT( glcurctx );
+ struct stw_context *ctx;
+
+ if(!glcurctx)
+ return 0;
+
+ ctx = (struct stw_context *)glcurctx->DriverCtx;
+ assert(ctx);
+ if(!ctx)
+ return 0;
+
+ return ctx->hglrc;
}
HDC
stw_get_current_dc( void )
{
- return stw_tls_get_data()->currentDC;
+ GET_CURRENT_CONTEXT( glcurctx );
+ struct stw_context *ctx;
+
+ if(!glcurctx)
+ return NULL;
+
+ ctx = (struct stw_context *)glcurctx->DriverCtx;
+ assert(ctx);
+ if(!ctx)
+ return NULL;
+
+ return ctx->hdc;
}
BOOL
@@ -292,64 +287,68 @@ stw_make_current(
struct stw_context *ctx;
GET_CURRENT_CONTEXT( glcurctx );
struct stw_framebuffer *fb;
- GLuint width = 0;
- GLuint height = 0;
- struct stw_context *curctx;
if (!stw_dev)
- return FALSE;
-
- pipe_mutex_lock( stw_dev->mutex );
- ctx = stw_lookup_context( hglrc );
- pipe_mutex_unlock( stw_dev->mutex );
-
- stw_tls_get_data()->currentDC = hdc;
- stw_tls_get_data()->currentGLRC = hglrc;
+ goto fail;
if (glcurctx != NULL) {
+ struct stw_context *curctx;
curctx = (struct stw_context *) glcurctx->DriverCtx;
- if (curctx != ctx)
+ if (curctx->hglrc != hglrc)
st_flush(glcurctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ /* Return if already current. */
+ if (curctx->hglrc == hglrc && curctx->hdc == hdc)
+ return TRUE;
}
if (hdc == NULL || hglrc == 0) {
- st_make_current( NULL, NULL, NULL );
- return TRUE;
+ return st_make_current( NULL, NULL, NULL );
}
- /* Return if already current.
- */
- if (glcurctx != NULL) {
- if (curctx != NULL && curctx == ctx && ctx->hdc == hdc)
- return TRUE;
- }
+ pipe_mutex_lock( stw_dev->mutex );
- fb = framebuffer_from_hdc( hdc );
+ ctx = stw_lookup_context_locked( hglrc );
+ if(!ctx)
+ goto fail;
- if (hdc != NULL)
- get_window_size( hdc, &width, &height );
+ fb = stw_framebuffer_from_hdc_locked( hdc );
+ if(!fb) {
+ /* Applications should call SetPixelFormat before creating a context,
+ * but not all do, and the opengl32 runtime seems to use a default pixel
+ * format in some cases, so we must create a framebuffer for those here
+ */
+ int iPixelFormat = GetPixelFormat(hdc);
+ if(iPixelFormat)
+ fb = stw_framebuffer_create_locked( hdc, iPixelFormat );
+ if(!fb)
+ goto fail;
+ }
+
+ pipe_mutex_unlock( stw_dev->mutex );
- /* Lazy creation of framebuffers.
- */
- if (fb == NULL && ctx != NULL && hdc != NULL) {
- GLvisual *visual = &ctx->st->ctx->Visual;
+ if(fb->iPixelFormat != ctx->iPixelFormat)
+ goto fail;
- fb = framebuffer_create( hdc, visual, width, height );
- if (fb == NULL)
- return FALSE;
- }
+ /* Lazy allocation of the frame buffer */
+ if(!stw_framebuffer_allocate(fb))
+ goto fail;
- if (ctx && fb) {
- st_make_current( ctx->st, fb->stfb, fb->stfb );
- framebuffer_resize( fb, width, height );
- ctx->hdc = hdc;
- ctx->st->pipe->priv = hdc;
- }
- else {
- /* Detach */
- st_make_current( NULL, NULL, NULL );
- }
+ /* Bind the new framebuffer */
+ ctx->hdc = hdc;
+
+ /* pass to stw_flush_frontbuffer as context_private */
+ ctx->st->pipe->priv = hdc;
+
+ if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
+ goto fail;
+ stw_framebuffer_resize(fb);
+
return TRUE;
+
+fail:
+ st_make_current( NULL, NULL, NULL );
+ return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.h b/src/gallium/state_trackers/wgl/shared/stw_context.h
index b289615272..166471de5e 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_context.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_context.h
@@ -35,8 +35,9 @@ struct st_context;
struct stw_context
{
struct st_context *st;
+ UINT_PTR hglrc;
+ int iPixelFormat;
HDC hdc;
- DWORD color_bits;
};
#endif /* STW_CONTEXT_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.c b/src/gallium/state_trackers/wgl/shared/stw_device.c
index 51936c2bdd..1a6b29807d 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_device.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_device.c
@@ -41,6 +41,7 @@
#include "shared/stw_pixelformat.h"
#include "shared/stw_public.h"
#include "shared/stw_tls.h"
+#include "shared/stw_framebuffer.h"
#ifdef WIN32_THREADS
extern _glthread_Mutex OneTimeLock;
@@ -56,7 +57,7 @@ struct stw_device *stw_dev = NULL;
* stw_winsys::flush_front_buffer.
*/
static void
-st_flush_frontbuffer(struct pipe_screen *screen,
+stw_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surface,
void *context_private )
{
@@ -75,7 +76,7 @@ st_flush_frontbuffer(struct pipe_screen *screen,
boolean
-st_init(const struct stw_winsys *stw_winsys)
+stw_init(const struct stw_winsys *stw_winsys)
{
static struct stw_device stw_dev_storage;
struct pipe_screen *screen;
@@ -110,7 +111,7 @@ st_init(const struct stw_winsys *stw_winsys)
stw_dev->screen = screen;
#endif
- stw_dev->screen->flush_frontbuffer = st_flush_frontbuffer;
+ stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
pipe_mutex_init( stw_dev->mutex );
@@ -119,7 +120,7 @@ st_init(const struct stw_winsys *stw_winsys)
goto error1;
}
- pixelformat_init();
+ stw_pixelformat_init();
return TRUE;
@@ -130,25 +131,28 @@ error1:
boolean
-st_init_thread(void)
+stw_init_thread(void)
{
- if (!stw_tls_init_thread()) {
+ if (!stw_tls_init_thread())
+ return FALSE;
+
+ if (!stw_framebuffer_init_thread())
return FALSE;
- }
return TRUE;
}
void
-st_cleanup_thread(void)
+stw_cleanup_thread(void)
{
+ stw_framebuffer_cleanup_thread();
stw_tls_cleanup_thread();
}
void
-st_cleanup(void)
+stw_cleanup(void)
{
unsigned i;
@@ -169,6 +173,8 @@ st_cleanup(void)
}
pipe_mutex_unlock( stw_dev->mutex );
+ stw_framebuffer_cleanup();
+
pipe_mutex_destroy( stw_dev->mutex );
stw_dev->screen->destroy(stw_dev->screen);
@@ -189,7 +195,7 @@ st_cleanup(void)
struct stw_context *
-stw_lookup_context( UINT_PTR dhglrc )
+stw_lookup_context_locked( UINT_PTR dhglrc )
{
if (dhglrc == 0)
return NULL;
diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.h b/src/gallium/state_trackers/wgl/shared/stw_device.h
index 703cb67081..e097f1f71e 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_device.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_device.h
@@ -29,12 +29,19 @@
#define STW_DEVICE_H_
+#include <windows.h>
+
#include "pipe/p_compiler.h"
#include "pipe/p_thread.h"
#include "util/u_handle_table.h"
+#include "stw_pixelformat.h"
+
+
+#define STW_MAX_PIXELFORMATS 256
struct pipe_screen;
+struct stw_framebuffer;
struct stw_device
{
@@ -45,18 +52,24 @@ struct stw_device
#ifdef DEBUG
boolean trace_running;
#endif
-
+
+ struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
+ unsigned pixelformat_count;
+ unsigned pixelformat_extended_count;
+
pipe_mutex mutex;
struct handle_table *ctx_table;
+ struct stw_framebuffer *fb_head;
+
#ifdef DEBUG
unsigned long memdbg_no;
#endif
};
struct stw_context *
-stw_lookup_context( UINT_PTR hglrc );
+stw_lookup_context_locked( UINT_PTR hglrc );
extern struct stw_device *stw_dev;
diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.c b/src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c
index b3934cb464..2660c591f9 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c
@@ -1,5 +1,6 @@
/**************************************************************************
*
+ * Copyright 2009 VMware, Inc.
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
@@ -27,7 +28,18 @@
#include <windows.h>
-#include "stw_arbextensionsstring.h"
+#define WGL_WGLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
+
+static const char *stw_extension_string =
+ "WGL_ARB_extensions_string "
+ "WGL_ARB_multisample "
+ "WGL_ARB_pixel_format "
+ "WGL_EXT_extensions_string";
+
WINGDIAPI const char * APIENTRY
wglGetExtensionsStringARB(
@@ -35,8 +47,12 @@ wglGetExtensionsStringARB(
{
(void) hdc;
- return
- "WGL_ARB_extensions_string "
- "WGL_ARB_multisample "
- "WGL_ARB_pixel_format";
+ return stw_extension_string;
+}
+
+
+WINGDIAPI const char * APIENTRY
+wglGetExtensionsStringEXT( void )
+{
+ return stw_extension_string;
}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
index c96c4b8dfa..58f1830319 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
@@ -42,208 +42,329 @@
#include "stw_device.h"
#include "stw_public.h"
#include "stw_winsys.h"
+#include "stw_tls.h"
-void
-framebuffer_resize(
- struct stw_framebuffer *fb,
- GLuint width,
- GLuint height )
+static INLINE struct stw_framebuffer *
+stw_framebuffer_from_hwnd_locked(
+ HWND hwnd )
+{
+ struct stw_framebuffer *fb;
+
+ for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
+ if (fb->hWnd == hwnd)
+ break;
+
+ return fb;
+}
+
+
+static INLINE void
+stw_framebuffer_destroy_locked(
+ struct stw_framebuffer *fb )
{
- st_resize_framebuffer( fb->stfb, width, height );
+ struct stw_framebuffer **link;
+
+ link = &stw_dev->fb_head;
+ while (*link != fb)
+ link = &(*link)->next;
+ assert(*link);
+ *link = fb->next;
+ fb->next = NULL;
+
+ st_unreference_framebuffer(fb->stfb);
+
+ pipe_mutex_destroy( fb->mutex );
+
+ FREE( fb );
}
-static struct stw_framebuffer *fb_head = NULL;
+/**
+ * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
+ * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
+ */
static LRESULT CALLBACK
-window_proc(
- HWND hWnd,
- UINT uMsg,
+stw_call_window_proc(
+ int nCode,
WPARAM wParam,
LPARAM lParam )
{
- struct stw_framebuffer *fb;
-
- for (fb = fb_head; fb != NULL; fb = fb->next)
- if (fb->hWnd == hWnd)
- break;
- assert( fb != NULL );
+ struct stw_tls_data *tls_data;
+ PCWPSTRUCT pParams = (PCWPSTRUCT)lParam;
+
+ tls_data = stw_tls_get_data();
+ if(!tls_data)
+ return 0;
+
+ if (nCode < 0)
+ return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
+
+ if (pParams->message == WM_SIZE && pParams->wParam != SIZE_MINIMIZED) {
+ struct stw_framebuffer *fb;
+
+ pipe_mutex_lock( stw_dev->mutex );
+ fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
+ pipe_mutex_unlock( stw_dev->mutex );
+
+ if(fb) {
+ unsigned width = LOWORD( pParams->lParam );
+ unsigned height = HIWORD( pParams->lParam );
+
+ /* FIXME: The mesa statetracker makes the assumptions that only
+ * one context is using the framebuffer, and that that context is the
+ * current one. However neither holds true, as WGL allows more than
+ * one context to be bound to the same drawable, and this function can
+ * be called from any thread.
+ */
+ pipe_mutex_lock( fb->mutex );
+ if (fb->stfb)
+ st_resize_framebuffer( fb->stfb, width, height );
+ pipe_mutex_unlock( fb->mutex );
+ }
+ }
- if (uMsg == WM_SIZE && wParam != SIZE_MINIMIZED)
- framebuffer_resize( fb, LOWORD( lParam ), HIWORD( lParam ) );
+ if (pParams->message == WM_DESTROY) {
+ struct stw_framebuffer *fb;
- return CallWindowProc( fb->WndProc, hWnd, uMsg, wParam, lParam );
-}
+ pipe_mutex_lock( stw_dev->mutex );
+
+ fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd );
+ if(fb)
+ stw_framebuffer_destroy_locked(fb);
+
+ pipe_mutex_unlock( stw_dev->mutex );
+ }
-static INLINE boolean
-stw_is_supported_color(enum pipe_format format)
-{
- struct pipe_screen *screen = stw_dev->screen;
- return screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+ return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
}
-static INLINE boolean
-stw_is_supported_depth_stencil(enum pipe_format format)
-{
- struct pipe_screen *screen = stw_dev->screen;
- return screen->is_format_supported(screen, format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
-}
-/* Create a new framebuffer object which will correspond to the given HDC.
+/**
+ * Create a new framebuffer object which will correspond to the given HDC.
*/
struct stw_framebuffer *
-framebuffer_create(
+stw_framebuffer_create_locked(
HDC hdc,
- GLvisual *visual,
- GLuint width,
- GLuint height )
+ int iPixelFormat )
{
+ HWND hWnd;
struct stw_framebuffer *fb;
- enum pipe_format colorFormat, depthFormat, stencilFormat;
-
- /* Determine PIPE_FORMATs for buffers.
- */
+ const struct stw_pixelformat_info *pfi;
- if(visual->alphaBits <= 0 && visual->redBits <= 5 && visual->blueBits <= 6 && visual->greenBits <= 5 &&
- stw_is_supported_color(PIPE_FORMAT_R5G6B5_UNORM)) {
- colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
- }
- else if(visual->alphaBits <= 0 && visual->redBits <= 8 && visual->blueBits <= 8 && visual->greenBits <= 8 &&
- stw_is_supported_color(PIPE_FORMAT_X8R8G8B8_UNORM)) {
- colorFormat = PIPE_FORMAT_X8R8G8B8_UNORM;
- }
- else if(visual->alphaBits <= 1 && visual->redBits <= 5 && visual->blueBits <= 5 && visual->greenBits <= 5 &&
- stw_is_supported_color(PIPE_FORMAT_A1R5G5B5_UNORM)) {
- colorFormat = PIPE_FORMAT_A1R5G5B5_UNORM;
- }
- else if(visual->alphaBits <= 4 && visual->redBits <= 4 && visual->blueBits <= 4 && visual->greenBits <= 4 &&
- stw_is_supported_color(PIPE_FORMAT_A4R4G4B4_UNORM)) {
- colorFormat = PIPE_FORMAT_A4R4G4B4_UNORM;
- }
- else if(visual->alphaBits <= 8 && visual->redBits <= 8 && visual->blueBits <= 8 && visual->greenBits <= 8 &&
- stw_is_supported_color(PIPE_FORMAT_A8R8G8B8_UNORM)) {
- colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
- }
- else {
- assert(0);
+ /* We only support drawing to a window. */
+ hWnd = WindowFromDC( hdc );
+ if(!hWnd)
+ return NULL;
+
+ fb = CALLOC_STRUCT( stw_framebuffer );
+ if (fb == NULL)
return NULL;
- }
- if (visual->depthBits == 0)
- depthFormat = PIPE_FORMAT_NONE;
- else if (visual->depthBits <= 16 &&
- stw_is_supported_depth_stencil(PIPE_FORMAT_Z16_UNORM))
- depthFormat = PIPE_FORMAT_Z16_UNORM;
- else if (visual->depthBits <= 24 && visual->stencilBits != 8 &&
- stw_is_supported_depth_stencil(PIPE_FORMAT_X8Z24_UNORM)) {
- depthFormat = PIPE_FORMAT_X8Z24_UNORM;
- }
- else if (visual->depthBits <= 24 && visual->stencilBits != 8 &&
- stw_is_supported_depth_stencil(PIPE_FORMAT_Z24X8_UNORM)) {
- depthFormat = PIPE_FORMAT_Z24X8_UNORM;
- }
- else if (visual->depthBits <= 24 && visual->stencilBits == 8 &&
- stw_is_supported_depth_stencil(PIPE_FORMAT_S8Z24_UNORM)) {
- depthFormat = PIPE_FORMAT_S8Z24_UNORM;
- }
- else if (visual->depthBits <= 24 && visual->stencilBits == 8 &&
- stw_is_supported_depth_stencil(PIPE_FORMAT_Z24S8_UNORM)) {
- depthFormat = PIPE_FORMAT_Z24S8_UNORM;
- }
- else if(stw_is_supported_depth_stencil(PIPE_FORMAT_Z32_UNORM)) {
- depthFormat = PIPE_FORMAT_Z32_UNORM;
- }
- else if(stw_is_supported_depth_stencil(PIPE_FORMAT_Z32_FLOAT)) {
- depthFormat = PIPE_FORMAT_Z32_FLOAT;
- }
- else {
- assert(0);
- depthFormat = PIPE_FORMAT_NONE;
- }
+ fb->hDC = hdc;
+ fb->hWnd = hWnd;
+ fb->iPixelFormat = iPixelFormat;
- if (depthFormat == PIPE_FORMAT_S8Z24_UNORM ||
- depthFormat == PIPE_FORMAT_Z24S8_UNORM) {
- stencilFormat = depthFormat;
- }
- else if (visual->stencilBits == 8 &&
- stw_is_supported_depth_stencil(PIPE_FORMAT_S8_UNORM)) {
- stencilFormat = PIPE_FORMAT_S8_UNORM;
+ fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
+
+ stw_pixelformat_visual(&fb->visual, pfi);
+
+ pipe_mutex_init( fb->mutex );
+
+ fb->next = stw_dev->fb_head;
+ stw_dev->fb_head = fb;
+
+ return fb;
+}
+
+
+static void
+stw_framebuffer_get_size( struct stw_framebuffer *fb, GLuint *pwidth, GLuint *pheight )
+{
+ GLuint width, height;
+
+ if (fb->hWnd) {
+ RECT rect;
+ GetClientRect( fb->hWnd, &rect );
+ width = rect.right - rect.left;
+ height = rect.bottom - rect.top;
}
else {
- stencilFormat = PIPE_FORMAT_NONE;
+ width = GetDeviceCaps( fb->hDC, HORZRES );
+ height = GetDeviceCaps( fb->hDC, VERTRES );
}
- fb = CALLOC_STRUCT( stw_framebuffer );
- if (fb == NULL)
- return NULL;
+ if(width < 1)
+ width = 1;
+ if(height < 1)
+ height = 1;
- fb->stfb = st_create_framebuffer(
- visual,
- colorFormat,
- depthFormat,
- stencilFormat,
- width,
- height,
- (void *) fb );
+ *pwidth = width;
+ *pheight = height;
+}
- fb->cColorBits = GetDeviceCaps( hdc, BITSPIXEL );
- fb->hDC = hdc;
- /* Subclass a window associated with the device context.
- */
- fb->hWnd = WindowFromDC( hdc );
- if (fb->hWnd != NULL) {
- fb->WndProc = (WNDPROC) SetWindowLongPtr(
- fb->hWnd,
- GWLP_WNDPROC,
- (LONG_PTR) window_proc );
+BOOL
+stw_framebuffer_allocate(
+ struct stw_framebuffer *fb)
+{
+ pipe_mutex_lock( fb->mutex );
+
+ if(!fb->stfb) {
+ const struct stw_pixelformat_info *pfi = fb->pfi;
+ enum pipe_format colorFormat, depthFormat, stencilFormat;
+ GLuint width, height;
+
+ colorFormat = pfi->color_format;
+
+ assert(pf_layout( pfi->depth_stencil_format ) == PIPE_FORMAT_LAYOUT_RGBAZS );
+
+ if(pf_get_component_bits( pfi->depth_stencil_format, PIPE_FORMAT_COMP_Z ))
+ depthFormat = pfi->depth_stencil_format;
+ else
+ depthFormat = PIPE_FORMAT_NONE;
+
+ if(pf_get_component_bits( pfi->depth_stencil_format, PIPE_FORMAT_COMP_S ))
+ stencilFormat = pfi->depth_stencil_format;
+ else
+ stencilFormat = PIPE_FORMAT_NONE;
+
+ stw_framebuffer_get_size(fb, &width, &height);
+
+ fb->stfb = st_create_framebuffer(
+ &fb->visual,
+ colorFormat,
+ depthFormat,
+ stencilFormat,
+ width,
+ height,
+ (void *) fb );
}
+
+ pipe_mutex_unlock( fb->mutex );
- fb->next = fb_head;
- fb_head = fb;
- return fb;
+ return fb->stfb ? TRUE : FALSE;
}
+
void
-framebuffer_destroy(
- struct stw_framebuffer *fb )
+stw_framebuffer_resize(
+ struct stw_framebuffer *fb)
{
- struct stw_framebuffer **link = &fb_head;
- struct stw_framebuffer *pfb = fb_head;
-
- while (pfb != NULL) {
- if (pfb == fb) {
- if (fb->hWnd != NULL) {
- SetWindowLongPtr(
- fb->hWnd,
- GWLP_WNDPROC,
- (LONG_PTR) fb->WndProc );
- }
-
- *link = fb->next;
- FREE( fb );
- return;
- }
+ GLuint width, height;
+ assert(fb->stfb);
+ stw_framebuffer_get_size(fb, &width, &height);
+ st_resize_framebuffer(fb->stfb, width, height);
+}
+
+
+void
+stw_framebuffer_cleanup( void )
+{
+ struct stw_framebuffer *fb;
+ struct stw_framebuffer *next;
+
+ pipe_mutex_lock( stw_dev->mutex );
- link = &pfb->next;
- pfb = pfb->next;
+ fb = stw_dev->fb_head;
+ while (fb) {
+ next = fb->next;
+ stw_framebuffer_destroy_locked(fb);
+ fb = next;
}
+ stw_dev->fb_head = NULL;
+
+ pipe_mutex_unlock( stw_dev->mutex );
}
-/* Given an hdc, return the corresponding stw_framebuffer.
+
+/**
+ * Given an hdc, return the corresponding stw_framebuffer.
*/
struct stw_framebuffer *
-framebuffer_from_hdc(
+stw_framebuffer_from_hdc_locked(
HDC hdc )
{
struct stw_framebuffer *fb;
- for (fb = fb_head; fb != NULL; fb = fb->next)
+ for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
if (fb->hDC == hdc)
- return fb;
- return NULL;
+ break;
+
+ return fb;
+}
+
+
+/**
+ * Given an hdc, return the corresponding stw_framebuffer.
+ */
+struct stw_framebuffer *
+stw_framebuffer_from_hdc(
+ HDC hdc )
+{
+ struct stw_framebuffer *fb;
+
+ pipe_mutex_lock( stw_dev->mutex );
+ fb = stw_framebuffer_from_hdc_locked(hdc);
+ pipe_mutex_unlock( stw_dev->mutex );
+
+ return fb;
+}
+
+
+BOOL
+stw_pixelformat_set(
+ HDC hdc,
+ int iPixelFormat )
+{
+ uint count;
+ uint index;
+ struct stw_framebuffer *fb;
+
+ index = (uint) iPixelFormat - 1;
+ count = stw_pixelformat_get_extended_count();
+ if (index >= count)
+ return FALSE;
+
+ pipe_mutex_lock( stw_dev->mutex );
+
+ fb = stw_framebuffer_from_hdc_locked(hdc);
+ if(fb) {
+ /* SetPixelFormat must be called only once */
+ pipe_mutex_unlock( stw_dev->mutex );
+ return FALSE;
+ }
+
+ fb = stw_framebuffer_create_locked(hdc, iPixelFormat);
+ if(!fb) {
+ pipe_mutex_unlock( stw_dev->mutex );
+ return FALSE;
+ }
+
+ pipe_mutex_unlock( stw_dev->mutex );
+
+ /* Some applications mistakenly use the undocumented wglSetPixelFormat
+ * function instead of SetPixelFormat, so we call SetPixelFormat here to
+ * avoid opengl32.dll's wglCreateContext to fail */
+ if (GetPixelFormat(hdc) == 0) {
+ SetPixelFormat(hdc, iPixelFormat, NULL);
+ }
+
+ return TRUE;
+}
+
+
+int
+stw_pixelformat_get(
+ HDC hdc )
+{
+ struct stw_framebuffer *fb;
+
+ fb = stw_framebuffer_from_hdc(hdc);
+ if(!fb)
+ return 0;
+
+ return fb->iPixelFormat;
}
@@ -255,10 +376,15 @@ stw_swap_buffers(
struct pipe_screen *screen;
struct pipe_surface *surface;
- fb = framebuffer_from_hdc( hdc );
+ fb = stw_framebuffer_from_hdc( hdc );
if (fb == NULL)
return FALSE;
+ if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER))
+ return TRUE;
+
+ pipe_mutex_lock( fb->mutex );
+
/* If we're swapping the buffer associated with the current context
* we have to flush any pending rendering commands first.
*/
@@ -266,9 +392,11 @@ stw_swap_buffers(
screen = stw_dev->screen;
- if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface ))
+ if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) {
/* FIXME: this shouldn't happen, but does on glean */
+ pipe_mutex_unlock( fb->mutex );
return FALSE;
+ }
#ifdef DEBUG
if(stw_dev->trace_running) {
@@ -279,5 +407,54 @@ stw_swap_buffers(
stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc );
+ pipe_mutex_unlock( fb->mutex );
+
return TRUE;
}
+
+
+BOOL
+stw_swap_layer_buffers(
+ HDC hdc,
+ UINT fuPlanes )
+{
+ if(fuPlanes & WGL_SWAP_MAIN_PLANE)
+ return stw_swap_buffers(hdc);
+
+ return FALSE;
+}
+
+
+boolean
+stw_framebuffer_init_thread(void)
+{
+ struct stw_tls_data *tls_data;
+
+ tls_data = stw_tls_get_data();
+ if(!tls_data)
+ return FALSE;
+
+ tls_data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC,
+ stw_call_window_proc,
+ NULL,
+ GetCurrentThreadId());
+ if(tls_data->hCallWndProcHook == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+stw_framebuffer_cleanup_thread(void)
+{
+ struct stw_tls_data *tls_data;
+
+ tls_data = stw_tls_get_data();
+ if(!tls_data)
+ return;
+
+ if(tls_data->hCallWndProcHook) {
+ UnhookWindowsHookEx(tls_data->hCallWndProcHook);
+ tls_data->hCallWndProcHook = NULL;
+ }
+}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
index 5abdf18997..e7fa51c3a8 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
@@ -28,39 +28,61 @@
#ifndef STW_FRAMEBUFFER_H
#define STW_FRAMEBUFFER_H
+#include <windows.h>
+
#include "main/mtypes.h"
-/* Windows framebuffer, derived from gl_framebuffer.
+#include "pipe/p_thread.h"
+
+struct stw_pixelformat_info;
+
+/**
+ * Windows framebuffer, derived from gl_framebuffer.
*/
struct stw_framebuffer
{
- struct st_framebuffer *stfb;
HDC hDC;
- BYTE cColorBits;
HWND hWnd;
- WNDPROC WndProc;
+
+ int iPixelFormat;
+ const struct stw_pixelformat_info *pfi;
+ GLvisual visual;
+
+ pipe_mutex mutex;
+ struct st_framebuffer *stfb;
+
+ /** This is protected by stw_device::mutex, not the mutex above */
struct stw_framebuffer *next;
};
struct stw_framebuffer *
-framebuffer_create(
+stw_framebuffer_create_locked(
HDC hdc,
- GLvisual *visual,
- GLuint width,
- GLuint height );
+ int iPixelFormat );
-void
-framebuffer_destroy(
+BOOL
+stw_framebuffer_allocate(
struct stw_framebuffer *fb );
void
-framebuffer_resize(
- struct stw_framebuffer *fb,
- GLuint width,
- GLuint height );
+stw_framebuffer_resize(
+ struct stw_framebuffer *fb);
+
+void
+stw_framebuffer_cleanup(void);
+
+struct stw_framebuffer *
+stw_framebuffer_from_hdc_locked(
+ HDC hdc );
struct stw_framebuffer *
-framebuffer_from_hdc(
+stw_framebuffer_from_hdc(
HDC hdc );
+boolean
+stw_framebuffer_init_thread(void);
+
+void
+stw_framebuffer_cleanup_thread(void);
+
#endif /* STW_FRAMEBUFFER_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
index ac2d6fc260..4070cbd5c0 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
@@ -27,28 +27,34 @@
#include <windows.h>
+#define WGL_WGLEXT_PROTOTYPES
+
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
#include "glapi/glapi.h"
-#include "stw_arbextensionsstring.h"
-#include "stw_arbpixelformat.h"
#include "stw_public.h"
-struct extension_entry
+struct stw_extension_entry
{
const char *name;
PROC proc;
};
-#define EXTENTRY(P) { #P, (PROC) P }
+#define STW_EXTENSION_ENTRY(P) { #P, (PROC) P }
-static struct extension_entry extension_entries[] = {
+static const struct stw_extension_entry stw_extension_entries[] = {
/* WGL_ARB_extensions_string */
- EXTENTRY( wglGetExtensionsStringARB ),
+ STW_EXTENSION_ENTRY( wglGetExtensionsStringARB ),
/* WGL_ARB_pixel_format */
- EXTENTRY( wglChoosePixelFormatARB ),
- EXTENTRY( wglGetPixelFormatAttribfvARB ),
- EXTENTRY( wglGetPixelFormatAttribivARB ),
+ STW_EXTENSION_ENTRY( wglChoosePixelFormatARB ),
+ STW_EXTENSION_ENTRY( wglGetPixelFormatAttribfvARB ),
+ STW_EXTENSION_ENTRY( wglGetPixelFormatAttribivARB ),
+
+ /* WGL_EXT_extensions_string */
+ STW_EXTENSION_ENTRY( wglGetExtensionsStringEXT ),
{ NULL, NULL }
};
@@ -57,13 +63,13 @@ PROC
stw_get_proc_address(
LPCSTR lpszProc )
{
- struct extension_entry *entry;
+ const struct stw_extension_entry *entry;
- PROC p = (PROC) _glapi_get_proc_address( (const char *) lpszProc );
+ PROC p = (PROC) _glapi_get_proc_address( lpszProc );
if (p)
return p;
- for (entry = extension_entries; entry->name; entry++)
+ for (entry = stw_extension_entries; entry->name; entry++)
if (strcmp( lpszProc, entry->name ) == 0)
return entry->proc;
diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c
index b216ca5c82..c296744838 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c
@@ -25,113 +25,266 @@
*
**************************************************************************/
+#include "main/mtypes.h"
+#include "main/context.h"
+
+#include "pipe/p_format.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
#include "util/u_debug.h"
+
+#include "stw_device.h"
#include "stw_pixelformat.h"
#include "stw_public.h"
#include "stw_tls.h"
-#define MAX_PIXELFORMATS 16
-static struct pixelformat_info pixelformats[MAX_PIXELFORMATS];
-static uint pixelformat_count = 0;
-static uint pixelformat_extended_count = 0;
+struct stw_pf_color_info
+{
+ enum pipe_format format;
+ struct {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned char alpha;
+ } bits;
+ struct {
+ unsigned char red;
+ unsigned char green;
+ unsigned char blue;
+ unsigned char alpha;
+ } shift;
+};
+
+struct stw_pf_depth_info
+{
+ enum pipe_format format;
+ struct {
+ unsigned char depth;
+ unsigned char stencil;
+ } bits;
+};
+
+
+/* NOTE: order matters, since in otherwise equal circumstances the first
+ * format listed will get chosen */
+
+static const struct stw_pf_color_info
+stw_pf_color[] = {
+ /* no-alpha */
+ { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} },
+ { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} },
+ { PIPE_FORMAT_R5G6B5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} },
+ /* alpha */
+ { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} },
+ { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} },
+#if 0
+ { PIPE_FORMAT_A2B10G10R10_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} },
+#endif
+ { PIPE_FORMAT_A1R5G5B5_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} },
+ { PIPE_FORMAT_A4R4G4B4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} }
+};
+
+
+static const struct stw_pf_depth_info
+stw_pf_depth_stencil[] = {
+ /* pure depth */
+ { PIPE_FORMAT_Z32_UNORM, {32, 0} },
+ { PIPE_FORMAT_Z24X8_UNORM, {24, 0} },
+ { PIPE_FORMAT_X8Z24_UNORM, {24, 0} },
+ { PIPE_FORMAT_Z16_UNORM, {16, 0} },
+ /* pure stencil */
+ { PIPE_FORMAT_S8_UNORM, { 0, 8} },
+ /* combined depth-stencil */
+ { PIPE_FORMAT_S8Z24_UNORM, {24, 8} },
+ { PIPE_FORMAT_Z24S8_UNORM, {24, 8} }
+};
+
+
+static const boolean
+stw_pf_doublebuffer[] = {
+ FALSE,
+ TRUE,
+};
+
+
+const unsigned
+stw_pf_multisample[] = {
+ 0,
+ 4
+};
static void
-add_standard_pixelformats(
- struct pixelformat_info **ppf,
- uint flags )
+stw_pixelformat_add(
+ struct stw_device *stw_dev,
+ const struct stw_pf_color_info *color,
+ const struct stw_pf_depth_info *depth,
+ unsigned accum,
+ boolean doublebuffer,
+ unsigned samples )
{
- struct pixelformat_info *pf = *ppf;
- struct pixelformat_color_info color24 = { 8, 0, 8, 8, 8, 16 };
- struct pixelformat_alpha_info alpha8 = { 8, 24 };
- struct pixelformat_alpha_info noalpha = { 0, 0 };
- struct pixelformat_depth_info depth24s8 = { 24, 8 };
- struct pixelformat_depth_info depth16 = { 16, 0 };
-
- pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
- pf->color = color24;
- pf->alpha = alpha8;
- pf->depth = depth16;
- pf++;
-
- pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
- pf->color = color24;
- pf->alpha = alpha8;
- pf->depth = depth24s8;
- pf++;
-
- pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
- pf->color = color24;
- pf->alpha = noalpha;
- pf->depth = depth16;
- pf++;
-
- pf->flags = PF_FLAG_DOUBLEBUFFER | flags;
- pf->color = color24;
- pf->alpha = noalpha;
- pf->depth = depth24s8;
- pf++;
-
- pf->flags = flags;
- pf->color = color24;
- pf->alpha = alpha8;
- pf->depth = depth16;
- pf++;
-
- pf->flags = flags;
- pf->color = color24;
- pf->alpha = alpha8;
- pf->depth = depth24s8;
- pf++;
-
- pf->flags = flags;
- pf->color = color24;
- pf->alpha = noalpha;
- pf->depth = depth16;
- pf++;
-
- pf->flags = flags;
- pf->color = color24;
- pf->alpha = noalpha;
- pf->depth = depth24s8;
- pf++;
-
- *ppf = pf;
+ boolean extended = FALSE;
+ struct stw_pixelformat_info *pfi;
+
+ assert(stw_dev->pixelformat_extended_count < STW_MAX_PIXELFORMATS);
+ if(stw_dev->pixelformat_extended_count >= STW_MAX_PIXELFORMATS)
+ return;
+
+ assert(pf_layout( color->format ) == PIPE_FORMAT_LAYOUT_RGBAZS );
+ assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_R ) == color->bits.red );
+ assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_G ) == color->bits.green );
+ assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_B ) == color->bits.blue );
+ assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_A ) == color->bits.alpha );
+ assert(pf_layout( depth->format ) == PIPE_FORMAT_LAYOUT_RGBAZS );
+ assert(pf_get_component_bits( depth->format, PIPE_FORMAT_COMP_Z ) == depth->bits.depth );
+ assert(pf_get_component_bits( depth->format, PIPE_FORMAT_COMP_S ) == depth->bits.stencil );
+
+ pfi = &stw_dev->pixelformats[stw_dev->pixelformat_extended_count];
+
+ memset(pfi, 0, sizeof *pfi);
+
+ pfi->color_format = color->format;
+ pfi->depth_stencil_format = depth->format;
+
+ pfi->pfd.nSize = sizeof pfi->pfd;
+ pfi->pfd.nVersion = 1;
+
+ pfi->pfd.dwFlags = PFD_SUPPORT_OPENGL;
+
+ /* TODO: also support non-native pixel formats */
+ pfi->pfd.dwFlags |= PFD_DRAW_TO_WINDOW ;
+
+ if (doublebuffer)
+ pfi->pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY;
+
+ pfi->pfd.iPixelType = PFD_TYPE_RGBA;
+
+ pfi->pfd.cColorBits = color->bits.red + color->bits.green + color->bits.blue + color->bits.alpha;
+ pfi->pfd.cRedBits = color->bits.red;
+ pfi->pfd.cRedShift = color->shift.red;
+ pfi->pfd.cGreenBits = color->bits.green;
+ pfi->pfd.cGreenShift = color->shift.green;
+ pfi->pfd.cBlueBits = color->bits.blue;
+ pfi->pfd.cBlueShift = color->shift.blue;
+ pfi->pfd.cAlphaBits = color->bits.alpha;
+ pfi->pfd.cAlphaShift = color->shift.alpha;
+ pfi->pfd.cAccumBits = 4*accum;
+ pfi->pfd.cAccumRedBits = accum;
+ pfi->pfd.cAccumGreenBits = accum;
+ pfi->pfd.cAccumBlueBits = accum;
+ pfi->pfd.cAccumAlphaBits = accum;
+ pfi->pfd.cDepthBits = depth->bits.depth;
+ pfi->pfd.cStencilBits = depth->bits.stencil;
+ pfi->pfd.cAuxBuffers = 0;
+ pfi->pfd.iLayerType = 0;
+ pfi->pfd.bReserved = 0;
+ pfi->pfd.dwLayerMask = 0;
+ pfi->pfd.dwVisibleMask = 0;
+ pfi->pfd.dwDamageMask = 0;
+
+ if(samples) {
+ pfi->numSampleBuffers = 1;
+ pfi->numSamples = samples;
+ extended = TRUE;
+ }
+
+ ++stw_dev->pixelformat_extended_count;
+
+ if(!extended) {
+ ++stw_dev->pixelformat_count;
+ assert(stw_dev->pixelformat_count == stw_dev->pixelformat_extended_count);
+ }
}
void
-pixelformat_init( void )
+stw_pixelformat_init( void )
{
- struct pixelformat_info *pf = pixelformats;
-
- add_standard_pixelformats( &pf, 0 );
- pixelformat_count = pf - pixelformats;
-
- add_standard_pixelformats( &pf, PF_FLAG_MULTISAMPLED );
- pixelformat_extended_count = pf - pixelformats;
+ struct pipe_screen *screen = stw_dev->screen;
+ unsigned i, j, k, l;
+
+ assert( !stw_dev->pixelformat_count );
+ assert( !stw_dev->pixelformat_extended_count );
+
+ for(i = 0; i < Elements(stw_pf_multisample); ++i) {
+ unsigned samples = stw_pf_multisample[i];
+
+ /* FIXME: re-enabled MSAA when we can query it */
+ if(samples)
+ continue;
- assert( pixelformat_extended_count <= MAX_PIXELFORMATS );
+ for(j = 0; j < Elements(stw_pf_color); ++j) {
+ const struct stw_pf_color_info *color = &stw_pf_color[j];
+
+ if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ continue;
+
+ for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) {
+ unsigned doublebuffer = stw_pf_doublebuffer[k];
+
+ for(l = 0; l < Elements(stw_pf_depth_stencil); ++l) {
+ const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[l];
+
+ if(!screen->is_format_supported(screen, depth->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0))
+ continue;
+
+ stw_pixelformat_add( stw_dev, color, depth, 0, doublebuffer, samples );
+ stw_pixelformat_add( stw_dev, color, depth, 16, doublebuffer, samples );
+ }
+ }
+ }
+ }
+
+ assert( stw_dev->pixelformat_count <= stw_dev->pixelformat_extended_count );
+ assert( stw_dev->pixelformat_extended_count <= STW_MAX_PIXELFORMATS );
}
uint
-pixelformat_get_count( void )
+stw_pixelformat_get_count( void )
{
- return pixelformat_count;
+ return stw_dev->pixelformat_count;
}
uint
-pixelformat_get_extended_count( void )
+stw_pixelformat_get_extended_count( void )
{
- return pixelformat_extended_count;
+ return stw_dev->pixelformat_extended_count;
}
-const struct pixelformat_info *
-pixelformat_get_info( uint index )
+const struct stw_pixelformat_info *
+stw_pixelformat_get_info( uint index )
{
- assert( index < pixelformat_extended_count );
+ assert( index < stw_dev->pixelformat_extended_count );
+
+ return &stw_dev->pixelformats[index];
+}
+
- return &pixelformats[index];
+void
+stw_pixelformat_visual(GLvisual *visual,
+ const struct stw_pixelformat_info *pfi )
+{
+ memset(visual, 0, sizeof *visual);
+ _mesa_initialize_visual(
+ visual,
+ (pfi->pfd.iPixelType == PFD_TYPE_RGBA) ? GL_TRUE : GL_FALSE,
+ (pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE,
+ (pfi->pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE,
+ pfi->pfd.cRedBits,
+ pfi->pfd.cGreenBits,
+ pfi->pfd.cBlueBits,
+ pfi->pfd.cAlphaBits,
+ (pfi->pfd.iPixelType == PFD_TYPE_COLORINDEX) ? pfi->pfd.cColorBits : 0,
+ pfi->pfd.cDepthBits,
+ pfi->pfd.cStencilBits,
+ pfi->pfd.cAccumRedBits,
+ pfi->pfd.cAccumGreenBits,
+ pfi->pfd.cAccumBlueBits,
+ pfi->pfd.cAccumAlphaBits,
+ pfi->numSamples );
}
@@ -144,11 +297,11 @@ stw_pixelformat_describe(
{
uint count;
uint index;
- const struct pixelformat_info *pf;
+ const struct stw_pixelformat_info *pfi;
(void) hdc;
- count = pixelformat_get_extended_count();
+ count = stw_pixelformat_get_extended_count();
index = (uint) iPixelFormat - 1;
if (ppfd == NULL)
@@ -156,36 +309,9 @@ stw_pixelformat_describe(
if (index >= count || nBytes != sizeof( PIXELFORMATDESCRIPTOR ))
return 0;
- pf = pixelformat_get_info( index );
-
- ppfd->nSize = sizeof( PIXELFORMATDESCRIPTOR );
- ppfd->nVersion = 1;
- ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
- if (pf->flags & PF_FLAG_DOUBLEBUFFER)
- ppfd->dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY;
- ppfd->iPixelType = PFD_TYPE_RGBA;
- ppfd->cColorBits = pf->color.redbits + pf->color.greenbits + pf->color.bluebits;
- ppfd->cRedBits = pf->color.redbits;
- ppfd->cRedShift = pf->color.redshift;
- ppfd->cGreenBits = pf->color.greenbits;
- ppfd->cGreenShift = pf->color.greenshift;
- ppfd->cBlueBits = pf->color.bluebits;
- ppfd->cBlueShift = pf->color.blueshift;
- ppfd->cAlphaBits = pf->alpha.alphabits;
- ppfd->cAlphaShift = pf->alpha.alphashift;
- ppfd->cAccumBits = 0;
- ppfd->cAccumRedBits = 0;
- ppfd->cAccumGreenBits = 0;
- ppfd->cAccumBlueBits = 0;
- ppfd->cAccumAlphaBits = 0;
- ppfd->cDepthBits = pf->depth.depthbits;
- ppfd->cStencilBits = pf->depth.stencilbits;
- ppfd->cAuxBuffers = 0;
- ppfd->iLayerType = 0;
- ppfd->bReserved = 0;
- ppfd->dwLayerMask = 0;
- ppfd->dwVisibleMask = 0;
- ppfd->dwDamageMask = 0;
+ pfi = stw_pixelformat_get_info( index );
+
+ memcpy(ppfd, &pfi->pfd, sizeof( PIXELFORMATDESCRIPTOR ));
return count;
}
@@ -203,29 +329,30 @@ int stw_pixelformat_choose( HDC hdc,
(void) hdc;
- count = pixelformat_get_count();
+ count = stw_pixelformat_get_count();
bestindex = count;
- bestdelta = 0xffffffff;
+ bestdelta = ~0U;
for (index = 0; index < count; index++) {
uint delta = 0;
- const struct pixelformat_info *pf = pixelformat_get_info( index );
+ const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info( index );
if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
!!(ppfd->dwFlags & PFD_DOUBLEBUFFER) !=
- !!(pf->flags & PF_FLAG_DOUBLEBUFFER))
+ !!(pfi->pfd.dwFlags & PFD_DOUBLEBUFFER))
continue;
- if (ppfd->cColorBits != pf->color.redbits + pf->color.greenbits + pf->color.bluebits)
+ /* FIXME: Take in account individual channel bits */
+ if (ppfd->cColorBits != pfi->pfd.cColorBits)
delta += 8;
- if (ppfd->cDepthBits != pf->depth.depthbits)
+ if (ppfd->cDepthBits != pfi->pfd.cDepthBits)
delta += 4;
- if (ppfd->cStencilBits != pf->depth.stencilbits)
+ if (ppfd->cStencilBits != pfi->pfd.cStencilBits)
delta += 2;
- if (ppfd->cAlphaBits != pf->alpha.alphabits)
+ if (ppfd->cAlphaBits != pfi->pfd.cAlphaBits)
delta++;
if (delta < bestdelta) {
@@ -241,57 +368,3 @@ int stw_pixelformat_choose( HDC hdc,
return bestindex + 1;
}
-
-
-int
-stw_pixelformat_get(
- HDC hdc )
-{
- return stw_tls_get_data()->currentPixelFormat;
-}
-
-
-BOOL
-stw_pixelformat_set(
- HDC hdc,
- int iPixelFormat )
-{
- uint count;
- uint index;
-
- (void) hdc;
-
- index = (uint) iPixelFormat - 1;
- count = pixelformat_get_extended_count();
- if (index >= count)
- return FALSE;
-
- stw_tls_get_data()->currentPixelFormat = iPixelFormat;
-
- /* Some applications mistakenly use the undocumented wglSetPixelFormat
- * function instead of SetPixelFormat, so we call SetPixelFormat here to
- * avoid opengl32.dll's wglCreateContext to fail */
- if (GetPixelFormat(hdc) == 0) {
- SetPixelFormat(hdc, iPixelFormat, NULL);
- }
-
- return TRUE;
-}
-
-
-
-/* XXX: this needs to be turned into queries on pipe_screen or
- * stw_winsys.
- */
-int
-stw_query_sample_buffers( void )
-{
- return 1;
-}
-
-int
-stw_query_samples( void )
-{
- return 4;
-}
-
diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h
index 7ca4194a2a..bec429231b 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h
@@ -25,59 +25,41 @@
*
**************************************************************************/
-#ifndef PIXELFORMAT_H
-#define PIXELFORMAT_H
+#ifndef STW_PIXELFORMAT_H
+#define STW_PIXELFORMAT_H
#include <windows.h>
-#include "pipe/p_compiler.h"
-
-#define PF_FLAG_DOUBLEBUFFER 0x00000001
-#define PF_FLAG_MULTISAMPLED 0x00000002
-
-struct pixelformat_color_info
-{
- uint redbits;
- uint redshift;
- uint greenbits;
- uint greenshift;
- uint bluebits;
- uint blueshift;
-};
-struct pixelformat_alpha_info
-{
- uint alphabits;
- uint alphashift;
-};
+#include "main/mtypes.h"
-struct pixelformat_depth_info
-{
- uint depthbits;
- uint stencilbits;
-};
+#include "pipe/p_compiler.h"
+#include "pipe/p_format.h"
-struct pixelformat_info
+struct stw_pixelformat_info
{
- uint flags;
- struct pixelformat_color_info color;
- struct pixelformat_alpha_info alpha;
- struct pixelformat_depth_info depth;
+ enum pipe_format color_format;
+ enum pipe_format depth_stencil_format;
+
+ PIXELFORMATDESCRIPTOR pfd;
+
+ unsigned numSampleBuffers;
+ unsigned numSamples;
};
void
-pixelformat_init( void );
+stw_pixelformat_init( void );
uint
-pixelformat_get_count( void );
+stw_pixelformat_get_count( void );
uint
-pixelformat_get_extended_count( void );
-
-const struct pixelformat_info *
-pixelformat_get_info( uint index );
+stw_pixelformat_get_extended_count( void );
-int stw_query_sample_buffers( void );
-int stw_query_samples( void );
+const struct stw_pixelformat_info *
+stw_pixelformat_get_info( uint index );
+void
+stw_pixelformat_visual(GLvisual *visual,
+ const struct stw_pixelformat_info *pfi );
-#endif /* PIXELFORMAT_H */
+#endif /* STW_PIXELFORMAT_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_public.h b/src/gallium/state_trackers/wgl/shared/stw_public.h
index 39d377c16b..7fe9cfb356 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_public.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_public.h
@@ -37,6 +37,8 @@ BOOL stw_copy_context( UINT_PTR hglrcSrc,
UINT_PTR stw_create_layer_context( HDC hdc,
int iLayerPlane );
+BOOL stw_share_lists( UINT_PTR hglrc1, UINT_PTR hglrc2 );
+
BOOL stw_delete_context( UINT_PTR hglrc );
BOOL
@@ -50,6 +52,9 @@ BOOL stw_make_current( HDC hdc, UINT_PTR hglrc );
BOOL stw_swap_buffers( HDC hdc );
+BOOL
+stw_swap_layer_buffers( HDC hdc, UINT fuPlanes );
+
PROC stw_get_proc_address( LPCSTR lpszProc );
int stw_pixelformat_describe( HDC hdc,
diff --git a/src/gallium/state_trackers/wgl/shared/stw_quirks.c b/src/gallium/state_trackers/wgl/shared/stw_quirks.c
deleted file mode 100644
index 2f7091a52c..0000000000
--- a/src/gallium/state_trackers/wgl/shared/stw_quirks.c
+++ /dev/null
@@ -1,116 +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.
- *
- **************************************************************************/
-
-/**
- * @file
- *
- * 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.
- */
-
-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_570(void){}
-void gl_dispatch_stub_577(void){}
-void gl_dispatch_stub_578(void){}
-void gl_dispatch_stub_582(void){}
-void gl_dispatch_stub_603(void){}
-void gl_dispatch_stub_607(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_657(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_764(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){}
-void gl_dispatch_stub_774(void){}
-void gl_dispatch_stub_750(void){}
-void gl_dispatch_stub_742(void){}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.c b/src/gallium/state_trackers/wgl/shared/stw_tls.c
index e72bafb880..0c18a52352 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_tls.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_tls.c
@@ -44,6 +44,18 @@ stw_tls_init(void)
return TRUE;
}
+static INLINE struct stw_tls_data *
+stw_tls_data_create()
+{
+ struct stw_tls_data *data;
+
+ data = CALLOC_STRUCT(stw_tls_data);
+ if (!data)
+ return NULL;
+
+ return data;
+}
+
boolean
stw_tls_init_thread(void)
{
@@ -53,14 +65,9 @@ stw_tls_init_thread(void)
return FALSE;
}
- data = MALLOC(sizeof(*data));
- if (!data) {
+ data = stw_tls_data_create();
+ if(!data)
return FALSE;
- }
-
- data->currentPixelFormat = 0;
- data->currentDC = NULL;
- data->currentGLRC = 0;
TlsSetValue(tlsIndex, data);
@@ -93,9 +100,23 @@ stw_tls_cleanup(void)
struct stw_tls_data *
stw_tls_get_data(void)
{
+ struct stw_tls_data *data;
+
if (tlsIndex == TLS_OUT_OF_INDEXES) {
return NULL;
}
+
+ data = (struct stw_tls_data *) TlsGetValue(tlsIndex);
+ if(!data) {
+ /* DllMain is called with DLL_THREAD_ATTACH only by threads created after
+ * the DLL is loaded by the process */
+
+ data = stw_tls_data_create();
+ if(!data)
+ return NULL;
+
+ TlsSetValue(tlsIndex, data);
+ }
- return (struct stw_tls_data *) TlsGetValue(tlsIndex);
+ return data;
}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.h b/src/gallium/state_trackers/wgl/shared/stw_tls.h
index 23b61e68ff..6af8be70c9 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_tls.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_tls.h
@@ -28,11 +28,11 @@
#ifndef STW_TLS_H
#define STW_TLS_H
+#include <windows.h>
+
struct stw_tls_data
{
- uint currentPixelFormat;
- HDC currentDC;
- UINT_PTR currentGLRC;
+ HHOOK hCallWndProcHook;
};
boolean
diff --git a/src/gallium/state_trackers/wgl/shared/stw_winsys.h b/src/gallium/state_trackers/wgl/shared/stw_winsys.h
index e4a1d4f979..c0bf82c9ed 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_winsys.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_winsys.h
@@ -51,15 +51,15 @@ struct stw_winsys
};
boolean
-st_init(const struct stw_winsys *stw_winsys);
+stw_init(const struct stw_winsys *stw_winsys);
boolean
-st_init_thread(void);
+stw_init_thread(void);
void
-st_cleanup_thread(void);
+stw_cleanup_thread(void);
void
-st_cleanup(void);
+stw_cleanup(void);
#endif /* STW_WINSYS_H */
diff --git a/src/gallium/state_trackers/wgl/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/wgl/stw_wgl.c
index e06d2640b4..a131292f7a 100644
--- a/src/gallium/state_trackers/wgl/wgl/stw_wgl.c
+++ b/src/gallium/state_trackers/wgl/wgl/stw_wgl.c
@@ -100,10 +100,7 @@ wglSwapLayerBuffers(
HDC hdc,
UINT fuPlanes )
{
- (void) hdc;
- (void) fuPlanes;
-
- return FALSE;
+ return stw_swap_layer_buffers( hdc, fuPlanes );
}
WINGDIAPI PROC APIENTRY
@@ -189,12 +186,7 @@ wglShareLists(
HGLRC hglrc1,
HGLRC hglrc2 )
{
- (void) hglrc1;
- (void) hglrc2;
-
- assert( 0 );
-
- return FALSE;
+ return stw_share_lists( (UINT_PTR)hglrc1, (UINT_PTR)hglrc2);;
}
WINGDIAPI BOOL APIENTRY
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index d04204e1bf..401bd39dac 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -28,6 +28,7 @@
*
*/
+#include "xorg-server.h"
#include "xf86.h"
#include "xf86_OSproc.h"
@@ -85,7 +86,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- template.compressed = 0;
template.format = PIPE_FORMAT_S8Z24_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
@@ -98,7 +98,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- template.compressed = 0;
template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 8a2711e70c..45e831f0c2 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -476,7 +476,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
if (!ms->screen) {
- ms->screen = drm_api_hooks.create_screen(ms->fd, ms->PciInfo->device_id);
+ ms->screen = drm_api_hooks.create_screen(ms->fd, NULL);
if (!ms->screen) {
FatalError("Could not init pipe_screen\n");
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 56c8fdccb2..7913174354 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -28,6 +28,7 @@
*
*/
+#include "xorg-server.h"
#include "xf86.h"
#include "xorg_tracker.h"
@@ -36,6 +37,8 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_rect.h"
+
struct exa_entity
{
ExaDriverPtr pExa;
@@ -425,7 +428,6 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- template.compressed = 0;
exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
pf_get_block(template.format, &template.block);
template.width[0] = width;
@@ -436,6 +438,18 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
priv->tex = exa->scrn->texture_create(exa->scrn, &template);
}
+ if (pPixData) {
+ struct pipe_transfer *transfer =
+ exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, width, height);
+ pipe_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+ &priv->tex->block, transfer->stride, 0, 0,
+ width, height, pPixData, pPixmap->devKind, 0, 0);
+ exa->scrn->transfer_unmap(exa->scrn, transfer);
+ exa->scrn->tex_transfer_destroy(transfer);
+ }
+
return TRUE;
}
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template
index 9f92cb4207..985e5a861f 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/winsys/drm/Makefile.template
@@ -118,7 +118,7 @@ clean:
install: $(LIBNAME)
$(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
- $(INSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
include depend
diff --git a/src/gallium/winsys/drm/intel/SConscript b/src/gallium/winsys/drm/intel/SConscript
new file mode 100644
index 0000000000..50d7b75ed6
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/SConscript
@@ -0,0 +1,7 @@
+Import('*')
+
+SConscript(['gem/SConscript',])
+
+if 'mesa' in env['statetrackers']:
+
+ SConscript(['dri/SConscript'])
diff --git a/src/gallium/winsys/drm/intel/dri2/Makefile b/src/gallium/winsys/drm/intel/dri/Makefile
index 1a02109274..de39e759d8 100644
--- a/src/gallium/winsys/drm/intel/dri2/Makefile
+++ b/src/gallium/winsys/drm/intel/dri/Makefile
@@ -4,8 +4,10 @@ include $(TOP)/configs/current
LIBNAME = i915_dri.so
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \
+ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a
@@ -19,4 +21,6 @@ include ../../Makefile.template
DRI_LIB_DEPS += -ldrm_intel
-symlinks:
+symlinks: $(TOP)/$(LIB_DIR)/gallium
+ @rm -f $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
+ ln -s i915_dri.so $(TOP)/$(LIB_DIR)/gallium/i965_dri.so
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
new file mode 100644
index 0000000000..e14e96e32f
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/dri/SConscript
@@ -0,0 +1,16 @@
+Import('*')
+
+env = drienv.Clone()
+
+drivers = [
+ softpipe,
+ i915simple,
+ trace,
+ inteldrm
+]
+
+env.SharedLibrary(
+ target ='i915_dri.so',
+ source = COMMON_GALLIUM_SOURCES,
+ LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+)
diff --git a/src/gallium/winsys/drm/intel/gem/SConscript b/src/gallium/winsys/drm/intel/gem/SConscript
new file mode 100644
index 0000000000..ea8a2e55f6
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/SConscript
@@ -0,0 +1,17 @@
+Import('*')
+
+env = drienv.Clone()
+
+inteldrm_sources = [
+ 'intel_be_api.c',
+ 'intel_be_batchbuffer.c',
+ 'intel_be_context.c',
+ 'intel_be_device.c',
+]
+
+inteldrm = env.ConvenienceLibrary(
+ target ='inteldrm',
+ source = inteldrm_sources,
+)
+
+Export('inteldrm')
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.c b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
index f4ef7c2d88..a74be13bf7 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
@@ -2,7 +2,13 @@
#include "intel_be_api.h"
#include "i915simple/i915_winsys.h"
+#ifdef DEBUG
+#include "trace/trace_drm.h"
+
+struct drm_api hooks =
+#else
struct drm_api drm_api_hooks =
+#endif
{
/* intel_be_context.c */
.create_context = intel_be_create_context,
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.h b/src/gallium/winsys/drm/intel/gem/intel_be_api.h
index 73e458d4ba..1c622f3b97 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_api.h
@@ -8,7 +8,8 @@
#include "intel_be_device.h"
-struct pipe_screen *intel_be_create_screen(int drmFD, int pciID);
+struct pipe_screen *intel_be_create_screen(int drmFD,
+ struct drm_create_screen_arg *arg);
struct pipe_context *intel_be_create_context(struct pipe_screen *screen);
#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
index bb6f1b916c..fe0b138fbe 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
@@ -1,6 +1,8 @@
#include "pipe/p_screen.h"
+#include "softpipe/sp_winsys.h"
+
#include "intel_be_device.h"
#include "intel_be_context.h"
#include "intel_be_batchbuffer.h"
@@ -106,13 +108,13 @@ intel_be_create_context(struct pipe_screen *screen)
intel_be_init_context(intel, device);
-#if 0
- pipe = intel_create_softpipe(intel, screen->winsys);
-#else
- pipe = i915_create_context(screen, &device->base, &intel->base);
-#endif
+ if (device->softpipe)
+ pipe = softpipe_create(screen);
+ else
+ pipe = i915_create_context(screen, &device->base, &intel->base);
- pipe->priv = intel;
+ if (pipe)
+ pipe->priv = intel;
return pipe;
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
index 0f6300323b..907ac86637 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -6,12 +6,15 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
#include "util/u_memory.h"
+#include "util/u_debug.h"
#include "intel_be_fence.h"
#include "i915simple/i915_winsys.h"
+#include "softpipe/sp_winsys.h"
#include "intel_be_api.h"
+#include <stdio.h>
/*
* Buffer
@@ -175,8 +178,6 @@ intel_be_handle_from_buffer(struct pipe_screen *screen,
struct pipe_buffer *buffer,
unsigned *handle)
{
- drm_intel_bo *bo;
-
if (!buffer)
return FALSE;
@@ -285,14 +286,47 @@ intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
+ dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
+
return true;
}
+static void
+intel_be_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ fgets(path, sizeof(path), file);
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
struct pipe_screen *
-intel_be_create_screen(int drmFD, int deviceID)
+intel_be_create_screen(int drmFD, struct drm_create_screen_arg *arg)
{
struct intel_be_device *dev;
struct pipe_screen *screen;
+ unsigned int deviceID;
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_NORMAL:
+ break;
+ default:
+ return NULL;
+ }
+ }
/* Allocate the private area */
dev = malloc(sizeof(*dev));
@@ -300,9 +334,14 @@ intel_be_create_screen(int drmFD, int deviceID)
return NULL;
memset(dev, 0, sizeof(*dev));
+ intel_be_get_device_id(&deviceID);
intel_be_init_device(dev, drmFD, deviceID);
- screen = i915_create_screen(&dev->base, deviceID);
+ if (dev->softpipe) {
+ screen = softpipe_create_screen(&dev->base);
+ drm_api_hooks.buffer_from_texture = softpipe_get_texture_buffer;
+ } else
+ screen = i915_create_screen(&dev->base, deviceID);
return screen;
}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
index 47d2176cb4..b32637ece2 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -16,6 +16,8 @@ struct intel_be_device
{
struct pipe_winsys base;
+ boolean softpipe;
+
int fd; /**< Drm file discriptor */
unsigned id;
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile
index a45ca570db..d9aa5d54e1 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/winsys/drm/intel/xorg/Makefile
@@ -21,6 +21,7 @@ LIBS = \
$(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(GALLIUM_AUXILIARIES)
#############################################
@@ -29,7 +30,7 @@ LIBS = \
all default: $(TARGET)
-$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a
+$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a $(LIBS)
$(TOP)/bin/mklib -noprefix -o $@ \
$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel
@@ -38,6 +39,6 @@ clean:
install:
$(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
- $(INSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
.PHONY = all clean install
diff --git a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
index aea39247e5..46a7971f60 100644
--- a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
+++ b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
@@ -37,20 +37,17 @@ static Bool intel_xorg_pci_probe(DriverPtr driver,
intptr_t match_data);
static const struct pci_id_match intel_xorg_device_match[] = {
- {0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0},
- {0x8086, 0x27A2, 0xffff, 0xffff, 0, 0, 0},
+ {0x8086, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
{0, 0, 0},
};
static SymTabRec intel_xorg_chipsets[] = {
- {0x2592, "Intel Graphics Device"},
- {0x27A2, "Intel Graphics Device"},
+ {PCI_MATCH_ANY, "Intel Graphics Device"},
{-1, NULL}
};
static PciChipsets intel_xorg_pci_devices[] = {
- {0x2592, 0x2592, RES_SHARED_VGA},
- {0x27A2, 0x27A2, RES_SHARED_VGA},
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
diff --git a/src/gallium/winsys/drm/nouveau/Makefile b/src/gallium/winsys/drm/nouveau/Makefile
index f8c8135854..6c9cbef26d 100644
--- a/src/gallium/winsys/drm/nouveau/Makefile
+++ b/src/gallium/winsys/drm/nouveau/Makefile
@@ -2,7 +2,7 @@
TOP = ../../../../..
include $(TOP)/configs/current
-SUBDIRS = drm dri dri2
+SUBDIRS = drm $(GALLIUM_STATE_TRACKERS_DIRS)
default install clean:
@for dir in $(SUBDIRS) ; do \
diff --git a/src/gallium/winsys/drm/nouveau/dri/Makefile b/src/gallium/winsys/drm/nouveau/dri/Makefile
index f7db6201fe..0937f68c34 100644
--- a/src/gallium/winsys/drm/nouveau/dri/Makefile
+++ b/src/gallium/winsys/drm/nouveau/dri/Makefile
@@ -3,32 +3,25 @@ include $(TOP)/configs/current
LIBNAME = nouveau_dri.so
-MINIGLX_SOURCES =
-
PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
$(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
$(TOP)/src/gallium/drivers/nv04/libnv04.a \
$(TOP)/src/gallium/drivers/nv10/libnv10.a \
$(TOP)/src/gallium/drivers/nv20/libnv20.a \
$(TOP)/src/gallium/drivers/nv30/libnv30.a \
$(TOP)/src/gallium/drivers/nv40/libnv40.a \
- $(TOP)/src/gallium/drivers/nv50/libnv50.a
-
-DRIVER_SOURCES = \
- nouveau_context.c \
- nouveau_screen.c \
- nouveau_swapbuffers.c \
- nouveau_lock.c
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
+
+DRIVER_SOURCES =
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
-ASM_SOURCES =
+include ../../Makefile.template
-DRIVER_DEFINES = $(shell pkg-config libdrm_nouveau --cflags)
DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
-include ../../Makefile.template
-
symlinks:
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c
deleted file mode 100644
index deb6ffcff1..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.c
+++ /dev/null
@@ -1,118 +0,0 @@
-#include <main/glheader.h>
-#include <glapi/glthread.h>
-#include <GL/internal/glcore.h>
-#include <utils.h>
-
-#include <state_tracker/st_public.h>
-#include <state_tracker/st_context.h>
-#include <state_tracker/drm_api.h>
-#include <pipe/p_defines.h>
-#include <pipe/p_context.h>
-#include <pipe/p_screen.h>
-
-#include "nouveau_context.h"
-#include "nouveau_screen.h"
-
-#include "nouveau_drmif.h"
-
-GLboolean
-nouveau_context_create(const __GLcontextModes *glVis,
- __DRIcontextPrivate *driContextPriv,
- void *sharedContextPrivate)
-{
- __DRIscreenPrivate *driScrnPriv = driContextPriv->driScreenPriv;
- struct nouveau_screen *nv_screen = driScrnPriv->private;
- struct nouveau_context *nv;
- struct pipe_context *pipe;
- struct st_context *st_share = NULL;
-
- if (sharedContextPrivate)
- st_share = ((struct nouveau_context *)sharedContextPrivate)->st;
-
- nv = CALLOC_STRUCT(nouveau_context);
- if (!nv)
- return GL_FALSE;
-
- {
- struct nouveau_device_priv *nvdev =
- nouveau_device(nv_screen->device);
-
- nvdev->ctx = driContextPriv->hHWContext;
- nvdev->lock = (drmLock *)&driScrnPriv->pSAREA->lock;
- }
-
- pipe = drm_api_hooks.create_context(nv_screen->pscreen);
- if (!pipe) {
- FREE(nv);
- return GL_FALSE;
- }
- pipe->priv = nv;
-
- driContextPriv->driverPrivate = nv;
- nv->dri_screen = driScrnPriv;
-
- driParseConfigFiles(&nv->dri_option_cache, &nv_screen->option_cache,
- nv->dri_screen->myNum, "nouveau");
-
- nv->st = st_create_context(pipe, glVis, st_share);
- return GL_TRUE;
-}
-
-void
-nouveau_context_destroy(__DRIcontextPrivate *driContextPriv)
-{
- struct nouveau_context *nv = driContextPriv->driverPrivate;
-
- assert(nv);
-
- st_finish(nv->st);
- st_destroy_context(nv->st);
-
- FREE(nv);
-}
-
-GLboolean
-nouveau_context_bind(__DRIcontextPrivate *driContextPriv,
- __DRIdrawablePrivate *driDrawPriv,
- __DRIdrawablePrivate *driReadPriv)
-{
- struct nouveau_context *nv;
- struct nouveau_framebuffer *draw, *read;
-
- if (!driContextPriv) {
- st_make_current(NULL, NULL, NULL);
- return GL_TRUE;
- }
-
- nv = driContextPriv->driverPrivate;
- draw = driDrawPriv->driverPrivate;
- read = driReadPriv->driverPrivate;
-
- st_make_current(nv->st, draw->stfb, read->stfb);
-
- if ((nv->dri_drawable != driDrawPriv) ||
- (nv->last_stamp != driDrawPriv->lastStamp)) {
- nv->dri_drawable = driDrawPriv;
- st_resize_framebuffer(draw->stfb, driDrawPriv->w,
- driDrawPriv->h);
- nv->last_stamp = driDrawPriv->lastStamp;
- }
-
- if (driDrawPriv != driReadPriv) {
- st_resize_framebuffer(read->stfb, driReadPriv->w,
- driReadPriv->h);
- }
-
- return GL_TRUE;
-}
-
-GLboolean
-nouveau_context_unbind(__DRIcontextPrivate *driContextPriv)
-{
- struct nouveau_context *nv = driContextPriv->driverPrivate;
- (void)nv;
-
- st_flush(nv->st, 0, NULL);
- return GL_TRUE;
-}
-
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h
deleted file mode 100644
index 2779b092e6..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context.h
+++ /dev/null
@@ -1,53 +0,0 @@
-#ifndef __NOUVEAU_CONTEXT_DRI_H__
-#define __NOUVEAU_CONTEXT_DRI_H__
-
-#include <dri_util.h>
-#include <xmlconfig.h>
-
-#include "nouveau/nouveau_winsys.h"
-
-#define NOUVEAU_ERR(fmt, args...) debug_printf("%s: "fmt, __func__, ##args)
-
-struct nouveau_framebuffer {
- struct st_framebuffer *stfb;
-};
-
-struct nouveau_context {
- struct st_context *st;
-
- /* DRI stuff */
- __DRIscreenPrivate *dri_screen;
- __DRIdrawablePrivate *dri_drawable;
- unsigned int last_stamp;
- driOptionCache dri_option_cache;
- drm_context_t drm_context;
- drmLock drm_lock;
- int locked;
-};
-
-extern GLboolean nouveau_context_create(const __GLcontextModes *,
- __DRIcontextPrivate *, void *);
-extern void nouveau_context_destroy(__DRIcontextPrivate *);
-extern GLboolean nouveau_context_bind(__DRIcontextPrivate *,
- __DRIdrawablePrivate *draw,
- __DRIdrawablePrivate *read);
-extern GLboolean nouveau_context_unbind(__DRIcontextPrivate *);
-
-extern void nouveau_contended_lock(struct nouveau_context *nv);
-extern void LOCK_HARDWARE(struct nouveau_context *nv);
-extern void UNLOCK_HARDWARE(struct nouveau_context *nv);
-
-#ifdef DEBUG
-extern int __nouveau_debug;
-
-#define DEBUG_BO (1 << 0)
-
-#define DBG(flag, ...) do { \
- if (__nouveau_debug & (DEBUG_##flag)) \
- NOUVEAU_ERR(__VA_ARGS__); \
-} while(0)
-#else
-#define DBG(flag, ...)
-#endif
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c
deleted file mode 100644
index 92f5bd09c9..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_lock.c
+++ /dev/null
@@ -1,73 +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 <pipe/p_thread.h>
-#include "nouveau_context.h"
-#include "nouveau_screen.h"
-#include "nouveau_drmif.h"
-
-pipe_static_mutex(lockMutex);
-
-/* Lock the hardware and validate our state.
- */
-void
-LOCK_HARDWARE(struct nouveau_context *nv)
-{
- struct nouveau_screen *nv_screen = nv->dri_screen->private;
- struct nouveau_device *dev = nv_screen->device;
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
- char __ret=0;
-
- assert(!nv->locked);
- pipe_mutex_lock(lockMutex);
-
- DRM_CAS(nvdev->lock, nvdev->ctx,
- (DRM_LOCK_HELD | nvdev->ctx), __ret);
-
- if (__ret) {
- drmGetLock(nvdev->fd, nvdev->ctx, 0);
- nouveau_contended_lock(nv);
- }
- nv->locked = 1;
-}
-
-/* Unlock the hardware using the global current context
- */
-void
-UNLOCK_HARDWARE(struct nouveau_context *nv)
-{
- struct nouveau_screen *nv_screen = nv->dri_screen->private;
- struct nouveau_device *dev = nv_screen->device;
- struct nouveau_device_priv *nvdev = nouveau_device(dev);
-
- assert(nv->locked);
- nv->locked = 0;
-
- DRM_UNLOCK(nvdev->fd, nvdev->lock, nvdev->ctx);
-
- pipe_mutex_unlock(lockMutex);
-}
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c
deleted file mode 100644
index 0b45b1ff1f..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.c
+++ /dev/null
@@ -1,330 +0,0 @@
-#include <utils.h>
-#include <vblank.h>
-#include <xmlpool.h>
-
-#include <pipe/p_context.h>
-#include <state_tracker/st_public.h>
-#include <state_tracker/st_cb_fbo.h>
-#include <state_tracker/drm_api.h>
-
-#include "nouveau_context.h"
-#include "nouveau_screen.h"
-#include "nouveau_swapbuffers.h"
-#include "nouveau_dri.h"
-
-#include "nouveau_drm.h"
-#include "nouveau_drmif.h"
-
-#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12
-#error nouveau_drm.h version does not match expected version
-#endif
-
-/* Extension stuff, enabling of extensions handled by Gallium's GL state
- * tracker. But, we still need to define the entry points we want.
- */
-#define need_GL_ARB_fragment_program
-#define need_GL_ARB_multisample
-#define need_GL_ARB_occlusion_query
-#define need_GL_ARB_point_parameters
-#define need_GL_ARB_shader_objects
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_vertex_program
-#define need_GL_ARB_vertex_shader
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_EXT_compiled_vertex_array
-#define need_GL_EXT_fog_coord
-#define need_GL_EXT_secondary_color
-#define need_GL_EXT_framebuffer_object
-#define need_GL_VERSION_2_0
-#define need_GL_VERSION_2_1
-#include "extension_helper.h"
-
-const struct dri_extension card_extensions[] =
-{
- { "GL_ARB_multisample", GL_ARB_multisample_functions },
- { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
- { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
- { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
- { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
- { "GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
- { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
- { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
- { "GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions },
- { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
- { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
- { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
- { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
- { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
- { NULL, 0 }
-};
-
-PUBLIC const char __driConfigOptions[] =
-DRI_CONF_BEGIN
-DRI_CONF_END;
-static const GLuint __driNConfigOptions = 0;
-
-extern const struct dri_extension common_extensions[];
-extern const struct dri_extension nv40_extensions[];
-
-static GLboolean
-nouveau_create_buffer(__DRIscreenPrivate * driScrnPriv,
- __DRIdrawablePrivate * driDrawPriv,
- const __GLcontextModes *glVis, GLboolean pixmapBuffer)
-{
- struct nouveau_framebuffer *nvfb;
- enum pipe_format colour, depth, stencil;
-
- if (pixmapBuffer)
- return GL_FALSE;
-
- nvfb = CALLOC_STRUCT(nouveau_framebuffer);
- if (!nvfb)
- return GL_FALSE;
-
- if (glVis->redBits == 5)
- colour = PIPE_FORMAT_R5G6B5_UNORM;
- else
- colour = PIPE_FORMAT_A8R8G8B8_UNORM;
-
- if (glVis->depthBits == 16)
- depth = PIPE_FORMAT_Z16_UNORM;
- else if (glVis->depthBits == 24)
- depth = PIPE_FORMAT_Z24S8_UNORM;
- else
- depth = PIPE_FORMAT_NONE;
-
- if (glVis->stencilBits == 8)
- stencil = PIPE_FORMAT_Z24S8_UNORM;
- else
- stencil = PIPE_FORMAT_NONE;
-
- nvfb->stfb = st_create_framebuffer(glVis, colour, depth, stencil,
- driDrawPriv->w, driDrawPriv->h,
- (void*)nvfb);
- if (!nvfb->stfb) {
- free(nvfb);
- return GL_FALSE;
- }
-
- driDrawPriv->driverPrivate = (void *)nvfb;
- return GL_TRUE;
-}
-
-static void
-nouveau_destroy_buffer(__DRIdrawablePrivate * driDrawPriv)
-{
- struct nouveau_framebuffer *nvfb;
-
- nvfb = (struct nouveau_framebuffer *)driDrawPriv->driverPrivate;
- st_unreference_framebuffer(nvfb->stfb);
- free(nvfb);
-}
-
-static __DRIconfig **
-nouveau_fill_in_modes(__DRIscreenPrivate *psp,
- unsigned pixel_bits, unsigned depth_bits,
- unsigned stencil_bits, GLboolean have_back_buffer)
-{
- __DRIconfig **configs;
- unsigned depth_buffer_factor;
- unsigned back_buffer_factor;
- GLenum fb_format;
- GLenum fb_type;
-
- static const GLenum back_buffer_modes[] = {
- GLX_NONE, GLX_SWAP_UNDEFINED_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;
-
- /* 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;
-
- msaa_samples_array[0] = 0;
-
- depth_buffer_factor =
- ((depth_bits != 0) || (stencil_bits != 0)) ? 3 : 1;
- back_buffer_factor = (have_back_buffer) ? 3 : 1;
-
- 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;
- }
-
- configs = driCreateConfigs(fb_format, fb_type,
- depth_bits_array, stencil_bits_array,
- depth_buffer_factor, back_buffer_modes,
- back_buffer_factor, msaa_samples_array, 1);
- if (configs == NULL) {
- fprintf(stderr, "[%s:%u] Error creating FBConfig!\n",
- __func__, __LINE__);
- return NULL;
- }
-
- return configs;
-}
-
-static struct pipe_surface *
-dri_surface_from_handle(struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width,
- unsigned height,
- unsigned pitch)
-{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
-
- buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle);
- if (!buf)
- return NULL;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth[0] = 1;
- templat.format = format;
- templat.width[0] = width;
- templat.height[0] = height;
- pf_get_block(templat.format, &templat.block);
-
- texture = screen->texture_blanket(screen,
- &templat,
- &pitch,
- buf);
-
- /* we don't need the buffer from this point on */
- pipe_buffer_reference(&buf, NULL);
-
- if (!texture)
- return NULL;
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
-}
-
-static const __DRIconfig **
-nouveau_screen_create(__DRIscreenPrivate *psp)
-{
- struct nouveau_dri *nv_dri = psp->pDevPriv;
- struct nouveau_screen *nv_screen;
- static const __DRIversion ddx_expected =
- { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
- static const __DRIversion dri_expected = { 4, 0, 0 };
- static const __DRIversion drm_expected =
- { 0, 0, NOUVEAU_DRM_HEADER_PATCHLEVEL };
-
- if (!driCheckDriDdxDrmVersions2("nouveau",
- &psp->dri_version, &dri_expected,
- &psp->ddx_version, &ddx_expected,
- &psp->drm_version, &drm_expected)) {
- return NULL;
- }
-
- if (drm_expected.patch != psp->drm_version.patch) {
- fprintf(stderr, "Incompatible DRM patch level.\n"
- "Expected: %d\n" "Current : %d\n",
- drm_expected.patch, psp->drm_version.patch);
- return NULL;
- }
-
- driInitExtensions(NULL, card_extensions, GL_FALSE);
-
- if (psp->devPrivSize != sizeof(struct nouveau_dri)) {
- NOUVEAU_ERR("DRI struct mismatch between DDX/DRI\n");
- return NULL;
- }
-
- nv_screen = CALLOC_STRUCT(nouveau_screen);
- if (!nv_screen)
- return NULL;
-
- nouveau_device_open_existing(&nv_screen->device, 0, psp->fd, 0);
-
- nv_screen->pscreen = drm_api_hooks.create_screen(psp->fd, 0);
- if (!nv_screen->pscreen) {
- FREE(nv_screen);
- return NULL;
- }
- nv_screen->pscreen->flush_frontbuffer = nouveau_flush_frontbuffer;
-
- {
- enum pipe_format format;
-
- if (nv_dri->bpp == 16)
- format = PIPE_FORMAT_R5G6B5_UNORM;
- else
- format = PIPE_FORMAT_A8R8G8B8_UNORM;
-
- nv_screen->fb = dri_surface_from_handle(nv_screen->pscreen,
- nv_dri->front_offset,
- format,
- nv_dri->width,
- nv_dri->height,
- nv_dri->front_pitch *
- nv_dri->bpp / 8);
- }
-
- driParseOptionInfo(&nv_screen->option_cache,
- __driConfigOptions, __driNConfigOptions);
-
- nv_screen->driScrnPriv = psp;
- psp->private = (void *)nv_screen;
-
- return (const __DRIconfig **)
- nouveau_fill_in_modes(psp, nv_dri->bpp,
- (nv_dri->bpp == 16) ? 16 : 24,
- (nv_dri->bpp == 16) ? 0 : 8, 1);
-}
-
-static void
-nouveau_screen_destroy(__DRIscreenPrivate *driScrnPriv)
-{
- struct nouveau_screen *nv_screen = driScrnPriv->private;
-
- driScrnPriv->private = NULL;
- FREE(nv_screen);
-}
-
-const struct __DriverAPIRec
-driDriverAPI = {
- .InitScreen = nouveau_screen_create,
- .DestroyScreen = nouveau_screen_destroy,
- .CreateContext = nouveau_context_create,
- .DestroyContext = nouveau_context_destroy,
- .CreateBuffer = nouveau_create_buffer,
- .DestroyBuffer = nouveau_destroy_buffer,
- .SwapBuffers = nouveau_swap_buffers,
- .MakeCurrent = nouveau_context_bind,
- .UnbindContext = nouveau_context_unbind,
- .CopySubBuffer = nouveau_copy_sub_buffer,
-
- .InitScreen2 = NULL, /* one day, I promise! */
-};
-
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h
deleted file mode 100644
index ac078f3c63..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_screen.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef __NOUVEAU_SCREEN_DRI_H__
-#define __NOUVEAU_SCREEN_DRI_H__
-
-#include "xmlconfig.h"
-
-struct nouveau_screen {
- __DRIscreenPrivate *driScrnPriv;
- driOptionCache option_cache;
-
- struct nouveau_device *device;
-
- struct pipe_screen *pscreen;
- struct pipe_surface *fb;
-};
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
deleted file mode 100644
index 9c841a0b2d..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <main/glheader.h>
-#include <glapi/glthread.h>
-#include <GL/internal/glcore.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 "nouveau_context.h"
-#include "nouveau_screen.h"
-#include "nouveau_swapbuffers.h"
-
-#include "nouveau_pushbuf.h"
-
-void
-nouveau_copy_buffer(__DRIdrawablePrivate *dPriv, struct pipe_surface *surf,
- const drm_clip_rect_t *rect)
-{
- struct nouveau_context *nv = dPriv->driContextPriv->driverPrivate;
- struct nouveau_screen *nv_screen = nv->dri_screen->private;
- struct pipe_context *pipe = nv->st->pipe;
- drm_clip_rect_t *pbox;
- int nbox, i;
-
- LOCK_HARDWARE(nv);
- if (!dPriv->numClipRects) {
- UNLOCK_HARDWARE(nv);
- return;
- }
- pbox = dPriv->pClipRects;
- nbox = dPriv->numClipRects;
-
- for (i = 0; i < nbox; i++, pbox++) {
- int sx, sy, dx, dy, w, h;
-
- sx = pbox->x1 - dPriv->x;
- sy = pbox->y1 - dPriv->y;
- dx = pbox->x1;
- dy = pbox->y1;
- w = pbox->x2 - pbox->x1;
- h = pbox->y2 - pbox->y1;
-
- pipe->surface_copy(pipe, nv_screen->fb, dx, dy, surf,
- sx, sy, w, h);
- }
-
- pipe->flush(pipe, 0, NULL);
- UNLOCK_HARDWARE(nv);
-
- if (nv->last_stamp != dPriv->lastStamp) {
- struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
- st_resize_framebuffer(nvfb->stfb, dPriv->w, dPriv->h);
- nv->last_stamp = dPriv->lastStamp;
- }
-}
-
-void
-nouveau_copy_sub_buffer(__DRIdrawablePrivate *dPriv, int x, int y, int w, int h)
-{
- struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
- struct pipe_surface *surf;
-
- st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf);
- if (surf) {
- drm_clip_rect_t rect;
- rect.x1 = x;
- rect.y1 = y;
- rect.x2 = x + w;
- rect.y2 = y + h;
-
- st_notify_swapbuffers(nvfb->stfb);
- nouveau_copy_buffer(dPriv, surf, &rect);
- }
-}
-
-void
-nouveau_swap_buffers(__DRIdrawablePrivate *dPriv)
-{
- struct nouveau_framebuffer *nvfb = dPriv->driverPrivate;
- struct pipe_surface *surf;
-
- st_get_framebuffer_surface(nvfb->stfb, ST_SURFACE_BACK_LEFT, &surf);
- if (surf) {
- st_notify_swapbuffers(nvfb->stfb);
- nouveau_copy_buffer(dPriv, surf, NULL);
- }
-}
-
-void
-nouveau_flush_frontbuffer(struct pipe_screen *pscreen, struct pipe_surface *ps,
- void *context_private)
-{
- struct nouveau_context *nv = context_private;
- __DRIdrawablePrivate *dPriv = nv->dri_drawable;
-
- nouveau_copy_buffer(dPriv, ps, NULL);
-}
-
-void
-nouveau_contended_lock(struct nouveau_context *nv)
-{
- struct nouveau_context *nv_sub = (struct nouveau_context*)nv;
- __DRIdrawablePrivate *dPriv = nv_sub->dri_drawable;
- __DRIscreenPrivate *sPriv = nv_sub->dri_screen;
-
- /* 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);
-}
-
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h b/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
deleted file mode 100644
index 4ca9cc2283..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_swapbuffers.h
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef __NOUVEAU_SWAPBUFFERS_H__
-#define __NOUVEAU_SWAPBUFFERS_H__
-
-void nouveau_copy_buffer(__DRIdrawablePrivate *, struct pipe_surface *,
- const drm_clip_rect_t *);
-void nouveau_copy_sub_buffer(__DRIdrawablePrivate *, int x, int y, int w, int h);
-void nouveau_swap_buffers(__DRIdrawablePrivate *);
-void nouveau_flush_frontbuffer(struct pipe_screen *, struct pipe_surface *,
- void *context_private);
-
-#endif
diff --git a/src/gallium/winsys/drm/nouveau/dri2/Makefile b/src/gallium/winsys/drm/nouveau/dri2/Makefile
deleted file mode 100644
index 728870d2e1..0000000000
--- a/src/gallium/winsys/drm/nouveau/dri2/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-TOP = ../../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = nouveau_dri2.so
-
-PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \
- $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
- $(TOP)/src/gallium/drivers/nv04/libnv04.a \
- $(TOP)/src/gallium/drivers/nv10/libnv10.a \
- $(TOP)/src/gallium/drivers/nv20/libnv20.a \
- $(TOP)/src/gallium/drivers/nv30/libnv30.a \
- $(TOP)/src/gallium/drivers/nv40/libnv40.a \
- $(TOP)/src/gallium/drivers/nv50/libnv50.a
-
-DRIVER_SOURCES =
-
-C_SOURCES = \
- $(COMMON_GALLIUM_SOURCES) \
- $(DRIVER_SOURCES)
-
-include ../../Makefile.template
-
-DRI_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
-
-symlinks:
diff --git a/src/gallium/winsys/drm/nouveau/drm/Makefile b/src/gallium/winsys/drm/nouveau/drm/Makefile
index 2da78d8690..54c3b26c75 100644
--- a/src/gallium/winsys/drm/nouveau/drm/Makefile
+++ b/src/gallium/winsys/drm/nouveau/drm/Makefile
@@ -3,9 +3,7 @@ include $(TOP)/configs/current
LIBNAME = nouveaudrm
-C_SOURCES = nouveau_drm_api.c \
- nouveau_winsys_pipe.c \
- nouveau_winsys.c
+C_SOURCES = nouveau_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I)
LIBRARY_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h
index 1207c2d609..1207c2d609 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_dri.h
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_dri.h
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index c0127e803f..395b21ec7a 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -1,20 +1,83 @@
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
#include "util/u_memory.h"
#include "nouveau_drm_api.h"
-#include "nouveau_winsys_pipe.h"
#include "nouveau_drmif.h"
#include "nouveau_channel.h"
#include "nouveau_bo.h"
+#include "nouveau/nouveau_winsys.h"
+#include "nouveau/nouveau_screen.h"
+
+static struct pipe_surface *
+dri_surface_from_handle(struct pipe_screen *screen,
+ unsigned handle,
+ enum pipe_format format,
+ unsigned width,
+ unsigned height,
+ unsigned pitch)
+{
+ struct pipe_surface *surface = NULL;
+ struct pipe_texture *texture = NULL;
+ struct pipe_texture templat;
+ struct pipe_buffer *buf = NULL;
+
+ buf = drm_api_hooks.buffer_from_handle(screen, "front buffer", handle);
+ if (!buf)
+ return NULL;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
+ NOUVEAU_TEXTURE_USAGE_LINEAR;
+ templat.target = PIPE_TEXTURE_2D;
+ templat.last_level = 0;
+ templat.depth[0] = 1;
+ templat.format = format;
+ templat.width[0] = width;
+ templat.height[0] = height;
+ pf_get_block(templat.format, &templat.block);
+
+ texture = screen->texture_blanket(screen,
+ &templat,
+ &pitch,
+ buf);
+
+ /* we don't need the buffer from this point on */
+ pipe_buffer_reference(&buf, NULL);
+
+ if (!texture)
+ return NULL;
+
+ surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ /* we don't need the texture from this point on */
+ pipe_texture_reference(&texture, NULL);
+ return surface;
+}
+
+static struct pipe_surface *
+nouveau_dri1_front_surface(struct pipe_context *pipe)
+{
+ return nouveau_winsys_screen(pipe->screen)->front;
+}
+
+static struct dri1_api nouveau_dri1_api = {
+ nouveau_dri1_front_surface,
+};
+
static struct pipe_screen *
-nouveau_drm_create_screen(int fd, int pciid)
+nouveau_drm_create_screen(int fd, struct drm_create_screen_arg *arg)
{
- struct pipe_winsys *ws;
+ struct dri1_create_screen_arg *dri1 = (void *)arg;
struct nouveau_winsys *nvws;
+ struct pipe_winsys *ws;
struct nouveau_device *dev = NULL;
struct pipe_screen *(*init)(struct pipe_winsys *,
- struct nouveau_winsys *);
+ struct nouveau_device *);
int ret;
ret = nouveau_device_open_existing(&dev, 0, fd, 0);
@@ -49,33 +112,54 @@ nouveau_drm_create_screen(int fd, int pciid)
return NULL;
}
- ws = nouveau_pipe_winsys_new(dev);
- if (!ws) {
+ nvws = CALLOC_STRUCT(nouveau_winsys);
+ if (!nvws) {
nouveau_device_close(&dev);
return NULL;
}
+ ws = &nvws->base;
- nvws = nouveau_winsys_new(ws);
- if (!nvws) {
+ nvws->pscreen = init(ws, dev);
+ if (!nvws->pscreen) {
ws->destroy(ws);
return NULL;
}
- nouveau_pipe_winsys(ws)->pscreen = init(ws, nvws);
- if (!nouveau_pipe_winsys(ws)->pscreen) {
- ws->destroy(ws);
- return NULL;
+ if (arg->mode == DRM_CREATE_DRI1) {
+ struct nouveau_dri *nvdri = dri1->ddx_info;
+ enum pipe_format format;
+
+ if (nvdri->bpp == 16)
+ format = PIPE_FORMAT_R5G6B5_UNORM;
+ else
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+ nvws->front = dri_surface_from_handle(nvws->pscreen,
+ nvdri->front_offset,
+ format,
+ nvdri->width,
+ nvdri->height,
+ nvdri->front_pitch *
+ (nvdri->bpp / 8));
+ if (!nvws->front) {
+ debug_printf("%s: error referencing front buffer\n",
+ __func__);
+ ws->destroy(ws);
+ return NULL;
+ }
+
+ dri1->api = &nouveau_dri1_api;
}
- return nouveau_pipe_winsys(ws)->pscreen;
+ return nvws->pscreen;
}
static struct pipe_context *
nouveau_drm_create_context(struct pipe_screen *pscreen)
{
- struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen);
+ struct nouveau_winsys *nvws = nouveau_winsys_screen(pscreen);
struct pipe_context *(*init)(struct pipe_screen *, unsigned);
- unsigned chipset = nvpws->channel->device->chipset;
+ unsigned chipset = nouveau_screen(pscreen)->device->chipset;
int i;
switch (chipset & 0xf0) {
@@ -106,19 +190,19 @@ nouveau_drm_create_context(struct pipe_screen *pscreen)
}
/* Find a free slot for a pipe context, allocate a new one if needed */
- for (i = 0; i < nvpws->nr_pctx; i++) {
- if (nvpws->pctx[i] == NULL)
+ for (i = 0; i < nvws->nr_pctx; i++) {
+ if (nvws->pctx[i] == NULL)
break;
}
- if (i == nvpws->nr_pctx) {
- nvpws->nr_pctx++;
- nvpws->pctx = realloc(nvpws->pctx,
- sizeof(*nvpws->pctx) * nvpws->nr_pctx);
+ if (i == nvws->nr_pctx) {
+ nvws->nr_pctx++;
+ nvws->pctx = realloc(nvws->pctx,
+ sizeof(*nvws->pctx) * nvws->nr_pctx);
}
- nvpws->pctx[i] = init(pscreen, i);
- return nvpws->pctx[i];
+ nvws->pctx[i] = init(pscreen, i);
+ return nvws->pctx[i];
}
static boolean
@@ -132,42 +216,41 @@ static struct pipe_buffer *
nouveau_drm_pb_from_handle(struct pipe_screen *pscreen, const char *name,
unsigned handle)
{
- struct nouveau_pipe_winsys *nvpws = nouveau_screen(pscreen);
- struct nouveau_device *dev = nvpws->channel->device;
- struct nouveau_pipe_buffer *nvpb;
+ struct nouveau_device *dev = nouveau_screen(pscreen)->device;
+ struct pipe_buffer *pb;
int ret;
- nvpb = CALLOC_STRUCT(nouveau_pipe_buffer);
- if (!nvpb)
+ pb = CALLOC(1, sizeof(struct pipe_buffer) + sizeof(struct nouveau_bo*));
+ if (!pb)
return NULL;
- ret = nouveau_bo_handle_ref(dev, handle, &nvpb->bo);
+ ret = nouveau_bo_handle_ref(dev, handle, (struct nouveau_bo**)(pb+1));
if (ret) {
debug_printf("%s: ref name 0x%08x failed with %d\n",
__func__, handle, ret);
- FREE(nvpb);
+ FREE(pb);
return NULL;
}
- pipe_reference_init(&nvpb->base.reference, 1);
- nvpb->base.screen = pscreen;
- nvpb->base.alignment = 0;
- nvpb->base.usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ_WRITE;
- nvpb->base.size = nvpb->bo->size;
- return &nvpb->base;
+ pipe_reference_init(&pb->reference, 1);
+ pb->screen = pscreen;
+ pb->alignment = 0;
+ pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ_WRITE;
+ pb->size = nouveau_bo(pb)->size;
+ return pb;
}
static boolean
nouveau_drm_handle_from_pb(struct pipe_screen *pscreen, struct pipe_buffer *pb,
unsigned *handle)
{
- struct nouveau_pipe_buffer *nvpb = nouveau_pipe_buffer(pb);
+ struct nouveau_bo *bo = nouveau_bo(pb);
- if (!nvpb)
+ if (!bo)
return FALSE;
- *handle = nvpb->bo->handle;
+ *handle = bo->handle;
return TRUE;
}
@@ -175,12 +258,12 @@ static boolean
nouveau_drm_name_from_pb(struct pipe_screen *pscreen, struct pipe_buffer *pb,
unsigned *handle)
{
- struct nouveau_pipe_buffer *nvpb = nouveau_pipe_buffer(pb);
+ struct nouveau_bo *bo = nouveau_bo(pb);
- if (!nvpb)
+ if (!bo)
return FALSE;
- return nouveau_bo_handle_get(nvpb->bo, handle) == 0;
+ return nouveau_bo_handle_get(bo, handle) == 0;
}
struct drm_api drm_api_hooks = {
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
index 2782c83c0e..e61e0e0957 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.h
@@ -1,5 +1,34 @@
#ifndef __NOUVEAU_DRM_API_H__
#define __NOUVEAU_DRM_API_H__
+
#include "state_tracker/drm_api.h"
+#include "state_tracker/dri1_api.h"
+
+#include "pipe/internal/p_winsys_screen.h"
+
+#include "nouveau_dri.h"
+
+struct nouveau_winsys {
+ struct pipe_winsys base;
+
+ struct pipe_screen *pscreen;
+
+ unsigned nr_pctx;
+ struct pipe_context **pctx;
+
+ struct pipe_surface *front;
+};
+
+static INLINE struct nouveau_winsys *
+nouveau_winsys(struct pipe_winsys *ws)
+{
+ return (struct nouveau_winsys *)ws;
+}
+
+static INLINE struct nouveau_winsys *
+nouveau_winsys_screen(struct pipe_screen *pscreen)
+{
+ return nouveau_winsys(pscreen->winsys);
+}
#endif
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c
deleted file mode 100644
index e3175fd775..0000000000
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys.c
+++ /dev/null
@@ -1,94 +0,0 @@
-#include "util/u_memory.h"
-
-#include "nouveau_winsys_pipe.h"
-
-static int
-nouveau_pipe_notifier_alloc(struct nouveau_winsys *nvws, int count,
- struct nouveau_notifier **notify)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
-
- return nouveau_notifier_alloc(nvpws->channel, nvpws->next_handle++,
- count, notify);
-}
-
-static int
-nouveau_pipe_grobj_alloc(struct nouveau_winsys *nvws, int grclass,
- struct nouveau_grobj **grobj)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(nvws->ws);
- struct nouveau_channel *chan = nvpws->channel;
- int ret;
-
- ret = nouveau_grobj_alloc(chan, nvpws->next_handle++, grclass, grobj);
- if (ret)
- return ret;
-
- BEGIN_RING(chan, *grobj, 0x0000, 1);
- OUT_RING (chan, (*grobj)->handle);
- (*grobj)->bound = NOUVEAU_GROBJ_BOUND_EXPLICIT;
- return 0;
-}
-
-static int
-nouveau_pipe_push_reloc(struct nouveau_winsys *nvws, void *ptr,
- struct pipe_buffer *buf, uint32_t data,
- uint32_t flags, uint32_t vor, uint32_t tor)
-{
- struct nouveau_bo *bo = nouveau_pipe_buffer(buf)->bo;
-
- return nouveau_pushbuf_emit_reloc(nvws->channel, ptr, bo,
- data, flags, vor, tor);
-}
-
-static int
-nouveau_pipe_push_flush(struct nouveau_winsys *nvws, unsigned size,
- struct pipe_fence_handle **fence)
-{
- if (fence)
- *fence = NULL;
-
- return nouveau_pushbuf_flush(nvws->channel, size);
-}
-
-static struct nouveau_bo *
-nouveau_pipe_get_bo(struct pipe_buffer *pb)
-{
- return nouveau_pipe_buffer(pb)->bo;
-}
-
-struct nouveau_winsys *
-nouveau_winsys_new(struct pipe_winsys *ws)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
- struct nouveau_winsys *nvws;
-
- nvws = CALLOC_STRUCT(nouveau_winsys);
- if (!nvws)
- return NULL;
-
- nvws->ws = ws;
- nvws->channel = nvpws->channel;
-
- nvws->res_init = nouveau_resource_init;
- nvws->res_alloc = nouveau_resource_alloc;
- nvws->res_free = nouveau_resource_free;
-
- nvws->push_reloc = nouveau_pipe_push_reloc;
- nvws->push_flush = nouveau_pipe_push_flush;
-
- nvws->grobj_alloc = nouveau_pipe_grobj_alloc;
- nvws->grobj_free = nouveau_grobj_free;
-
- nvws->notifier_alloc = nouveau_pipe_notifier_alloc;
- nvws->notifier_free = nouveau_notifier_free;
- nvws->notifier_reset = nouveau_notifier_reset;
- nvws->notifier_status = nouveau_notifier_status;
- nvws->notifier_retval = nouveau_notifier_return_val;
- nvws->notifier_wait = nouveau_notifier_wait_status;
-
- nvws->get_bo = nouveau_pipe_get_bo;
-
- return nvws;
-}
-
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c
deleted file mode 100644
index 9e03a9f5db..0000000000
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.c
+++ /dev/null
@@ -1,204 +0,0 @@
-#include "pipe/internal/p_winsys_screen.h"
-#include <pipe/p_defines.h>
-#include <pipe/p_inlines.h>
-#include <util/u_memory.h>
-
-#include "nouveau_winsys_pipe.h"
-
-#include "nouveau_drmif.h"
-#include "nouveau_bo.h"
-
-static const char *
-nouveau_get_name(struct pipe_winsys *pws)
-{
- return "Nouveau/DRI";
-}
-
-static uint32_t
-nouveau_flags_from_usage(struct pipe_winsys *ws, unsigned usage)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
- struct pipe_screen *pscreen = nvpws->pscreen;
- uint32_t flags = NOUVEAU_BO_LOCAL;
-
- if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER)
- flags |= NOUVEAU_BO_GART;
-
- if (usage & PIPE_BUFFER_USAGE_PIXEL) {
- if (usage & NOUVEAU_BUFFER_USAGE_TEXTURE)
- flags |= NOUVEAU_BO_GART;
- if (!(usage & PIPE_BUFFER_USAGE_CPU_READ_WRITE))
- flags |= NOUVEAU_BO_VRAM;
-
- switch (nvpws->channel->device->chipset & 0xf0) {
- case 0x50:
- case 0x80:
- case 0x90:
- flags |= NOUVEAU_BO_TILED;
- if (usage & NOUVEAU_BUFFER_USAGE_ZETA)
- flags |= NOUVEAU_BO_ZTILE;
- break;
- default:
- break;
- }
- }
-
- if (usage & PIPE_BUFFER_USAGE_VERTEX) {
- if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_VTXBUF))
- flags |= NOUVEAU_BO_GART;
- }
-
- if (usage & PIPE_BUFFER_USAGE_INDEX) {
- if (pscreen->get_param(pscreen, NOUVEAU_CAP_HW_IDXBUF))
- flags |= NOUVEAU_BO_GART;
- }
-
- return flags;
-}
-
-static struct pipe_buffer *
-nouveau_pipe_bo_create(struct pipe_winsys *ws, unsigned alignment,
- unsigned usage, unsigned size)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
- struct nouveau_device *dev = nvpws->channel->device;
- struct nouveau_pipe_buffer *nvbuf;
- uint32_t flags;
-
- nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
- if (!nvbuf)
- return NULL;
- pipe_reference_init(&nvbuf->base.reference, 1);
- nvbuf->base.alignment = alignment;
- nvbuf->base.usage = usage;
- nvbuf->base.size = size;
-
- flags = nouveau_flags_from_usage(ws, usage);
- if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
- FREE(nvbuf);
- return NULL;
- }
-
- return &nvbuf->base;
-}
-
-static struct pipe_buffer *
-nouveau_pipe_bo_user_create(struct pipe_winsys *ws, void *ptr, unsigned bytes)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
- struct nouveau_device *dev = nvpws->channel->device;
- struct nouveau_pipe_buffer *nvbuf;
-
- nvbuf = CALLOC_STRUCT(nouveau_pipe_buffer);
- if (!nvbuf)
- return NULL;
- pipe_reference_init(&nvbuf->base.reference, 1);
- nvbuf->base.size = bytes;
-
- if (nouveau_bo_user(dev, ptr, bytes, &nvbuf->bo)) {
- FREE(nvbuf);
- return NULL;
- }
-
- return &nvbuf->base;
-}
-
-static void
-nouveau_pipe_bo_del(struct pipe_buffer *buf)
-{
- struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
-
- nouveau_bo_ref(NULL, &nvbuf->bo);
- FREE(nvbuf);
-}
-
-static void *
-nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
- unsigned flags)
-{
- struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
- uint32_t map_flags = 0;
-
- if (flags & PIPE_BUFFER_USAGE_CPU_READ)
- map_flags |= NOUVEAU_BO_RD;
- if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
- map_flags |= NOUVEAU_BO_WR;
-
- if (nouveau_bo_map(nvbuf->bo, map_flags))
- return NULL;
- return nvbuf->bo->map;
-}
-
-static void
-nouveau_pipe_bo_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
-{
- struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);
-
- nouveau_bo_unmap(nvbuf->bo);
-}
-
-static void
-nouveau_pipe_fence_reference(struct pipe_winsys *ws,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *pfence)
-{
- *ptr = pfence;
-}
-
-static int
-nouveau_pipe_fence_signalled(struct pipe_winsys *ws,
- struct pipe_fence_handle *pfence, unsigned flag)
-{
- return 0;
-}
-
-static int
-nouveau_pipe_fence_finish(struct pipe_winsys *ws,
- struct pipe_fence_handle *pfence, unsigned flag)
-{
- return 0;
-}
-
-static void
-nouveau_destroy(struct pipe_winsys *ws)
-{
- struct nouveau_pipe_winsys *nvpws = nouveau_pipe_winsys(ws);
-
- nouveau_device_close(&nvpws->channel->device);
- FREE(nvpws);
-}
-
-struct pipe_winsys *
-nouveau_pipe_winsys_new(struct nouveau_device *dev)
-{
- struct nouveau_pipe_winsys *nvpws;
- int ret;
-
- nvpws = CALLOC_STRUCT(nouveau_pipe_winsys);
- if (!nvpws)
- return NULL;
-
- ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202,
- &nvpws->channel);
- if (ret) {
- debug_printf("%s: error opening GPU channel: %d\n",
- __func__, ret);
- FREE(nvpws);
- return NULL;
- }
- nvpws->next_handle = 0x77000000;
-
- nvpws->base.buffer_create = nouveau_pipe_bo_create;
- nvpws->base.buffer_destroy = nouveau_pipe_bo_del;
- nvpws->base.user_buffer_create = nouveau_pipe_bo_user_create;
- nvpws->base.buffer_map = nouveau_pipe_bo_map;
- nvpws->base.buffer_unmap = nouveau_pipe_bo_unmap;
-
- nvpws->base.fence_reference = nouveau_pipe_fence_reference;
- nvpws->base.fence_signalled = nouveau_pipe_fence_signalled;
- nvpws->base.fence_finish = nouveau_pipe_fence_finish;
-
- nvpws->base.get_name = nouveau_get_name;
- nvpws->base.destroy = nouveau_destroy;
- return &nvpws->base;
-}
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h b/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h
deleted file mode 100644
index 10e1e269e8..0000000000
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_winsys_pipe.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef NOUVEAU_PIPE_WINSYS_H
-#define NOUVEAU_PIPE_WINSYS_H
-
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_context.h"
-
-#include "nouveau/nouveau_winsys.h"
-
-#include "nouveau_device.h"
-
-struct nouveau_pipe_buffer {
- struct pipe_buffer base;
- struct nouveau_bo *bo;
-};
-
-static INLINE struct nouveau_pipe_buffer *
-nouveau_pipe_buffer(struct pipe_buffer *buf)
-{
- return (struct nouveau_pipe_buffer *)buf;
-}
-
-struct nouveau_pipe_winsys {
- struct pipe_winsys base;
-
- struct pipe_screen *pscreen;
-
- struct nouveau_channel *channel;
- uint32_t next_handle;
-
- unsigned nr_pctx;
- struct pipe_context **pctx;
-};
-
-static INLINE struct nouveau_pipe_winsys *
-nouveau_pipe_winsys(struct pipe_winsys *ws)
-{
- return (struct nouveau_pipe_winsys *)ws;
-}
-
-static INLINE struct nouveau_pipe_winsys *
-nouveau_screen(struct pipe_screen *pscreen)
-{
- return nouveau_pipe_winsys(pscreen->winsys);
-}
-
-struct pipe_winsys *
-nouveau_pipe_winsys_new(struct nouveau_device *);
-
-struct nouveau_winsys *
-nouveau_winsys_new(struct pipe_winsys *ws);
-
-#endif
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 611ee68da6..0d0fdc5bd8 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -68,8 +68,8 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
domain |= RADEON_GEM_DOMAIN_GTT;
}
- radeon_buffer->bo = radeon_bo_open(radeon_ws->bom, 0, size, alignment,
- domain, 0);
+ radeon_buffer->bo = radeon_bo_open(radeon_ws->priv->bom, 0, size,
+ alignment, domain, 0);
if (radeon_buffer->bo == NULL) {
FREE(radeon_buffer);
}
@@ -93,6 +93,29 @@ static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws,
return &radeon_buffer->base;
}
+static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
+ unsigned width,
+ unsigned height,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned *stride)
+{
+ struct pipe_format_block block;
+ unsigned nblocksx, nblocksy, size;
+
+ pf_get_block(format, &block);
+
+ nblocksx = pf_get_nblocksx(&block, width);
+ nblocksy = pf_get_nblocksy(&block, height);
+
+ /* Radeons enjoy things in multiples of 32. */
+ /* XXX this can be 32 when POT */
+ *stride = (nblocksx * block.size + 63) & ~63;
+ size = *stride * nblocksy;
+
+ return radeon_buffer_create(ws, 64, usage, size);
+}
+
static void radeon_buffer_del(struct pipe_buffer *buffer)
{
struct radeon_pipe_buffer *radeon_buffer =
@@ -169,16 +192,22 @@ struct radeon_winsys* radeon_pipe_winsys(int fd)
return NULL;
}
- bom = radeon_bo_manager_gem_ctor(fd);
- radeon_ws->bom = bom;
+ radeon_ws->priv = CALLOC_STRUCT(radeon_winsys_priv);
+ if (radeon_ws->priv == NULL) {
+ FREE(radeon_ws);
+ return NULL;
+ }
+
+ radeon_ws->priv->bom = radeon_bo_manager_gem_ctor(fd);
radeon_ws->base.flush_frontbuffer = radeon_flush_frontbuffer;
radeon_ws->base.buffer_create = radeon_buffer_create;
- radeon_ws->base.buffer_destroy = radeon_buffer_del;
radeon_ws->base.user_buffer_create = radeon_buffer_user_create;
+ radeon_ws->base.surface_buffer_create = radeon_surface_buffer_create;
radeon_ws->base.buffer_map = radeon_buffer_map;
radeon_ws->base.buffer_unmap = radeon_buffer_unmap;
+ radeon_ws->base.buffer_destroy = radeon_buffer_del;
radeon_ws->base.fence_reference = radeon_fence_reference;
radeon_ws->base.fence_signalled = radeon_fence_signalled;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index 163422f296..ca8bbb3c11 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -41,6 +41,7 @@
#include "util/u_memory.h"
#include "radeon_bo.h"
+#include "radeon_cs.h"
#include "radeon_drm.h"
@@ -49,13 +50,30 @@ struct radeon_pipe_buffer {
struct radeon_bo *bo;
};
+#define RADEON_MAX_BOS 24
+
+struct radeon_winsys_priv {
+ /* Radeon BO manager. */
+ struct radeon_bo_manager* bom;
+
+ /* Radeon BO space checker. */
+ struct radeon_cs_space_check sc[RADEON_MAX_BOS];
+ /* Current BO count. */
+ unsigned bo_count;
+
+ /* Radeon CS manager. */
+ struct radeon_cs_manager* csm;
+
+ /* Current CS. */
+ struct radeon_cs* cs;
+};
+
struct radeon_winsys {
/* Parent class. */
struct pipe_winsys base;
- /* Radeon BO manager.
- * This corresponds to void* radeon_winsys in r300_winsys. */
- struct radeon_bo_manager* bom;
+ /* This corresponds to void* radeon_winsys in r300_winsys. */
+ struct radeon_winsys_priv* priv;
};
struct radeon_winsys* radeon_pipe_winsys(int fb);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index 3446654e28..5406d2bbea 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -30,8 +30,13 @@
#include "radeon_drm.h"
+#ifdef DEBUG
+#include "trace/trace_drm.h"
+#endif
+
/* Create a pipe_screen. */
-struct pipe_screen* radeon_create_screen(int drmFB, int pciID)
+struct pipe_screen* radeon_create_screen(int drmFB,
+ struct drm_create_screen_arg *arg)
{
struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
@@ -68,7 +73,7 @@ struct pipe_buffer* radeon_buffer_from_handle(struct pipe_screen* screen,
unsigned handle)
{
struct radeon_bo_manager* bom =
- ((struct radeon_winsys*)screen->winsys)->bom;
+ ((struct radeon_winsys*)screen->winsys)->priv->bom;
struct radeon_pipe_buffer* radeon_buffer;
struct radeon_bo* bo = NULL;
@@ -111,7 +116,11 @@ boolean radeon_global_handle_from_buffer(struct pipe_screen* screen,
return TRUE;
}
+#ifdef DEBUG
+struct drm_api hooks = {
+#else
struct drm_api drm_api_hooks = {
+#endif
.create_screen = radeon_create_screen,
.create_context = radeon_create_context,
/* XXX fix this */
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index ca2d98ed1a..049f9984db 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -40,7 +40,8 @@
#include "radeon_r300.h"
#include "radeon_winsys_softpipe.h"
-struct pipe_screen* radeon_create_screen(int drmFB, int pciID);
+struct pipe_screen* radeon_create_screen(int drmFB,
+ struct drm_create_screen_arg *arg);
struct pipe_context* radeon_create_context(struct pipe_screen* screen);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 293b6c2d38..63aa3179ac 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -22,86 +22,224 @@
#include "radeon_r300.h"
-static boolean radeon_r300_check_cs(struct radeon_cs* cs, int size)
+static boolean radeon_r300_add_buffer(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd)
+{
+ int i;
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+ struct radeon_cs_space_check* sc = priv->sc;
+ struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
+
+ /* Check to see if this BO is already in line for validation;
+ * find a slot for it otherwise. */
+ for (i = 0; i < priv->bo_count; i++) {
+ if (sc[i].bo == bo) {
+ sc[i].read_domains |= rd;
+ sc[i].write_domain |= wd;
+ return;
+ }
+ }
+
+ if (priv->bo_count >= RADEON_MAX_BOS) {
+ /* Dohoho. Not falling for that one again. Request a flush. */
+ return FALSE;
+ }
+
+ sc[priv->bo_count].bo = bo;
+ sc[priv->bo_count].read_domains = rd;
+ sc[priv->bo_count].write_domain = wd;
+ priv->bo_count++;
+
+ return TRUE;
+}
+
+static boolean radeon_r300_validate(struct r300_winsys* winsys)
+{
+ int retval, i;
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+ struct radeon_cs_space_check* sc = priv->sc;
+
+ retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count);
+
+ if (retval == RADEON_CS_SPACE_OP_TO_BIG) {
+ /* We might as well HCF, since this is not going to fit in the card,
+ * period. */
+ /* XXX just drop it on the floor instead */
+ exit(1);
+ } else if (retval == RADEON_CS_SPACE_FLUSH) {
+ /* We must flush before more rendering can commence. */
+ return TRUE;
+ }
+
+ /* XXX should probably be its own function */
+ for (i = 0; i < priv->bo_count; i++) {
+ if (sc[i].read_domains && sc[i].write_domain) {
+ /* Cute, cute. We need to flush first. */
+ debug_printf("radeon: BO %p can't be read and written; "
+ "requesting flush.\n", sc[i].bo);
+ return TRUE;
+ }
+ }
+
+ /* Things are fine, we can proceed as normal. */
+ return FALSE;
+}
+
+static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
{
/* XXX check size here, lazy ass! */
+ /* XXX also validate buffers */
return TRUE;
}
-static void radeon_r300_write_cs_reloc(struct radeon_cs* cs,
- struct pipe_buffer* pbuffer,
- uint32_t rd,
- uint32_t wd,
- uint32_t flags)
+static void radeon_r300_begin_cs(struct r300_winsys* winsys,
+ int size,
+ const char* file,
+ const char* function,
+ int line)
{
- radeon_cs_write_reloc(cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags);
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+
+ radeon_cs_begin(priv->cs, size, file, function, line);
}
-static void radeon_r300_flush_cs(struct radeon_cs* cs)
+static void radeon_r300_write_cs_dword(struct r300_winsys* winsys,
+ uint32_t dword)
{
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+
+ radeon_cs_write_dword(priv->cs, dword);
+}
+
+static void radeon_r300_write_cs_reloc(struct r300_winsys* winsys,
+ struct pipe_buffer* pbuffer,
+ uint32_t rd,
+ uint32_t wd,
+ uint32_t flags)
+{
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
int retval = 0;
- retval = radeon_cs_emit(cs);
+ retval = radeon_cs_write_reloc(priv->cs,
+ ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags);
+
+ if (retval) {
+ debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
+ pbuffer, rd, wd, flags);
+ }
+}
+
+static void radeon_r300_end_cs(struct r300_winsys* winsys,
+ const char* file,
+ const char* function,
+ int line)
+{
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+
+ radeon_cs_end(priv->cs, file, function, line);
+}
+
+static void radeon_r300_flush_cs(struct r300_winsys* winsys)
+{
+ struct radeon_winsys_priv* priv =
+ (struct radeon_winsys_priv*)winsys->radeon_winsys;
+ struct radeon_cs_space_check* sc = priv->sc;
+ int retval = 1;
+
+ /* Emit the CS. */
+ retval = radeon_cs_emit(priv->cs);
if (retval) {
debug_printf("radeon: Bad CS, dumping...\n");
- radeon_cs_print(cs, stderr);
+ radeon_cs_print(priv->cs, stderr);
}
- radeon_cs_erase(cs);
+ radeon_cs_erase(priv->cs);
+
+ /* Clean out BOs. */
+ memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS);
+ priv->bo_count = 0;
}
/* Helper function to do the ioctls needed for setup and init. */
static void do_ioctls(struct r300_winsys* winsys, int fd)
{
- drm_radeon_getparam_t gp;
- uint32_t target;
+ struct drm_radeon_gem_info gem_info = {0};
+ drm_radeon_getparam_t gp = {0};
+ struct drm_radeon_info info = {0};
+ int target = 0;
int retval;
- /* XXX is this cast safe? */
- gp.value = (int*)&target;
+ info.value = &target;
+ gp.value = &target;
/* First, get PCI ID */
- gp.param = RADEON_PARAM_DEVICE_ID;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+ info.request = RADEON_INFO_DEVICE_ID;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
- fprintf(stderr, "%s: Failed to get PCI ID, error number %d",
+ fprintf(stderr, "%s: New ioctl for PCI ID failed "
+ "(error number %d), trying classic ioctl...\n",
__FUNCTION__, retval);
- exit(1);
+ gp.param = RADEON_PARAM_DEVICE_ID;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp,
+ sizeof(gp));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get PCI ID, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
+ }
}
winsys->pci_id = target;
- /* Then, get the number of pixel pipes */
- gp.param = RADEON_PARAM_NUM_GB_PIPES;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp));
+ /* Then, retrieve MM info */
+ retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
+ &gem_info, sizeof(gem_info));
if (retval) {
- fprintf(stderr, "%s: Failed to get GB pipe count, error number %d",
+ fprintf(stderr, "%s: Failed to get MM info, error number %d\n",
__FUNCTION__, retval);
exit(1);
}
- winsys->gb_pipes = target;
-
+ winsys->gart_size = gem_info.gart_size;
+ /* XXX */
+ winsys->vram_size = gem_info.vram_visible;
}
struct r300_winsys*
radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys)
{
struct r300_winsys* winsys = CALLOC_STRUCT(r300_winsys);
- struct radeon_cs_manager* csm;
+ struct radeon_winsys_priv* priv;
if (winsys == NULL) {
return NULL;
}
+ priv = old_winsys->priv;
+
do_ioctls(winsys, fd);
- csm = radeon_cs_manager_gem_ctor(fd);
+ priv->csm = radeon_cs_manager_gem_ctor(fd);
+
+ priv->cs = radeon_cs_create(priv->csm, 1024 * 64 / 4);
+ radeon_cs_set_limit(priv->cs,
+ RADEON_GEM_DOMAIN_GTT, winsys->gart_size);
+ radeon_cs_set_limit(priv->cs,
+ RADEON_GEM_DOMAIN_VRAM, winsys->vram_size);
- winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4);
+ winsys->add_buffer = radeon_r300_add_buffer;
+ winsys->validate = radeon_r300_validate;
winsys->check_cs = radeon_r300_check_cs;
- winsys->begin_cs = radeon_cs_begin;
- winsys->write_cs_dword = radeon_cs_write_dword;
+ winsys->begin_cs = radeon_r300_begin_cs;
+ winsys->write_cs_dword = radeon_r300_write_cs_dword;
winsys->write_cs_reloc = radeon_r300_write_cs_reloc;
- winsys->end_cs = radeon_cs_end;
+ winsys->end_cs = radeon_r300_end_cs;
winsys->flush_cs = radeon_r300_flush_cs;
memcpy(winsys, old_winsys, sizeof(struct radeon_winsys));
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
index 5c373cd084..a2e0e58248 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
@@ -31,5 +31,18 @@
#include "radeon_buffer.h"
+/* protect us from bonghits */
+#ifndef RADEON_INFO_DEVICE_ID
+#define RADEON_INFO_DEVICE_ID 0
+#endif
+#ifndef DRM_RADEON_INFO
+#define DRM_RADEON_INFO 0x1
+struct drm_radeon_info {
+ uint32_t request;
+ uint32_t pad;
+ uint64_t value;
+};
+#endif
+
struct r300_winsys*
radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
index 33f9ac15ab..f038bfa40e 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_winsys_softpipe.c
@@ -31,42 +31,11 @@
#include "radeon_winsys_softpipe.h"
-struct radeon_softpipe_winsys {
- struct softpipe_winsys sp_winsys;
- struct radeon_context *radeon_context;
-};
-
-/**
- * Return list of surface formats supported by this driver.
- */
-static boolean radeon_is_format_supported(struct softpipe_winsys *sws,
- uint format)
-{
- switch (format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- case PIPE_FORMAT_R5G6B5_UNORM:
- case PIPE_FORMAT_Z24S8_UNORM:
- return TRUE;
- default:
- break;
- }
- return FALSE;
-}
-
struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys)
{
- struct softpipe_winsys *sp_winsys;
struct pipe_screen *pipe_screen;
pipe_screen = softpipe_create_screen(winsys);
- sp_winsys = CALLOC_STRUCT(softpipe_winsys);
- if (sp_winsys == NULL) {
- return NULL;
- }
-
- sp_winsys->is_format_supported = radeon_is_format_supported;
- return softpipe_create(pipe_screen,
- winsys,
- sp_winsys);
+ return softpipe_create(pipe_screen);
}
diff --git a/src/gallium/winsys/drm/radeon/dri2/Makefile b/src/gallium/winsys/drm/radeon/dri/Makefile
index f471c44349..a9889444de 100644
--- a/src/gallium/winsys/drm/radeon/dri2/Makefile
+++ b/src/gallium/winsys/drm/radeon/dri/Makefile
@@ -7,9 +7,10 @@ LIBNAME = radeon_dri.so
MINIGLX_SOURCES =
PIPE_DRIVERS = \
- $(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \
+ $(TOP)/src/gallium/state_trackers/dri/libdridrm.a \
$(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
C_SOURCES = \
diff --git a/src/gallium/winsys/drm/radeon/dri2/SConscript b/src/gallium/winsys/drm/radeon/dri/SConscript
index f2cdee97d9..f2cdee97d9 100644
--- a/src/gallium/winsys/drm/radeon/dri2/SConscript
+++ b/src/gallium/winsys/drm/radeon/dri/SConscript
diff --git a/src/gallium/winsys/drm/radeon/egl/Makefile b/src/gallium/winsys/drm/radeon/egl/Makefile
index d989b3aa93..6a1448d1b9 100644
--- a/src/gallium/winsys/drm/radeon/egl/Makefile
+++ b/src/gallium/winsys/drm/radeon/egl/Makefile
@@ -8,6 +8,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
$(GALLIUMDIR)/winsys/drm/radeon/core/libradeonwinsys.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/r300/libr300.a
DRIVER_SOURCES =
diff --git a/src/gallium/winsys/drm/radeon/xorg/Makefile b/src/gallium/winsys/drm/radeon/xorg/Makefile
index 6ffd4a3a54..0241625f69 100644
--- a/src/gallium/winsys/drm/radeon/xorg/Makefile
+++ b/src/gallium/winsys/drm/radeon/xorg/Makefile
@@ -37,6 +37,6 @@ clean:
install:
$(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
- $(INSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
.PHONY = all clean install
diff --git a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
index 6f77fbe5de..36824251f0 100644
--- a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
+++ b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
@@ -38,20 +38,17 @@ static Bool radeon_xorg_pci_probe(DriverPtr driver,
intptr_t match_data);
static const struct pci_id_match radeon_xorg_device_match[] = {
- {0x1002, 0x5E4D, 0xffff, 0xffff, 0, 0, 0},
- {0x1002, 0x7249, 0xffff, 0xffff, 0, 0, 0},
+ {0x1002, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
{0, 0, 0},
};
static SymTabRec radeon_xorg_chipsets[] = {
- {0x5E4D, "Radeon RV410 PCIE (X700)"},
- {0x7249, "Radeon R580 PCIE (X1900 XT)"},
+ {PCI_MATCH_ANY, "ATI/AMD Radeon Graphics Chipset"},
{-1, NULL}
};
static PciChipsets radeon_xorg_pci_devices[] = {
- {0x5E4D, 0x5E4D, RES_SHARED_VGA},
- {0x7249, 0x7249, RES_SHARED_VGA},
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, RES_SHARED_VGA},
{-1, -1, RES_UNDEFINED}
};
diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile
index 02ac47caa4..a33a50ec22 100644
--- a/src/gallium/winsys/egl_xlib/Makefile
+++ b/src/gallium/winsys/egl_xlib/Makefile
@@ -60,7 +60,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(WINSYS_OBJECTS) $(LIBS)
-noprefix \
-install $(TOP)/$(LIB_DIR) \
$(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \
- --whole-archive $(LIBS) --no-whole-archive
+ -Wl,--whole-archive $(LIBS) -Wl,--no-whole-archive
depend: $(ALL_SOURCES)
@@ -74,7 +74,7 @@ depend: $(ALL_SOURCES)
install: default
$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
@if [ -e $(TOP)/$(LIB_DIR) ]; then \
- $(INSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(INSTALL_DIR)/$(LIB_DIR); \
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/$(DRIVER_NAME) $(INSTALL_DIR)/$(LIB_DIR); \
fi
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index 9ceb67d2ac..c10e3c00ff 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -359,7 +359,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
/* fall-through */
case EGL_OPENGL_API:
/* create a softpipe context */
- ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL);
+ ctx->pipe = softpipe_create(xdrv->screen);
/* Now do xlib / state tracker inits here */
_eglConfigToContextModesRec(conf, &visual);
ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx);
@@ -388,6 +388,7 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
/* API-dependent clean-up */
switch (context->Base.ClientAPI) {
case EGL_OPENGL_ES_API:
+ case EGL_OPENVG_API:
/* fall-through */
case EGL_OPENGL_API:
st_destroy_context(context->Context);
@@ -587,7 +588,9 @@ find_supported_apis(void)
EGLint mask = 0;
void *handle;
- handle = dlopen(NULL, 0);
+ handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL);
+ if(!handle)
+ return mask;
if (dlsym(handle, "st_api_OpenGL_ES1"))
mask |= EGL_OPENGL_ES_BIT;
diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c
index 5b9fdb5c1f..698c2856a4 100644
--- a/src/gallium/winsys/g3dvl/xsp_winsys.c
+++ b/src/gallium/winsys/g3dvl/xsp_winsys.c
@@ -261,7 +261,7 @@ struct pipe_context* create_pipe_context(Display *display, int screen)
}
sp_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys);
- sp_pipe = softpipe_create(sp_screen, (struct pipe_winsys*)xsp_winsys, NULL);
+ sp_pipe = softpipe_create(sp_screen);
xsp_context = calloc(1, sizeof(struct xsp_context));
xsp_context->display = display;
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript
index aabab95f3a..86eb9ef55e 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/winsys/gdi/SConscript
@@ -15,6 +15,7 @@ if env['platform'] == 'windows':
'gdi32',
'user32',
'kernel32',
+ 'ws2_32',
])
sources = [
diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
index d5d9431865..33826524d7 100644
--- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
@@ -263,7 +263,7 @@ gdi_softpipe_screen_create(void)
static struct pipe_context *
gdi_softpipe_context_create(struct pipe_screen *screen)
{
- return softpipe_create(screen, screen->winsys, NULL);
+ return softpipe_create(screen);
}
@@ -312,21 +312,21 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason) {
case DLL_PROCESS_ATTACH:
- if (!st_init(&stw_winsys)) {
+ if (!stw_init(&stw_winsys)) {
return FALSE;
}
- return st_init_thread();
+ return stw_init_thread();
case DLL_THREAD_ATTACH:
- return st_init_thread();
+ return stw_init_thread();
case DLL_THREAD_DETACH:
- st_cleanup_thread();
+ stw_cleanup_thread();
break;
case DLL_PROCESS_DETACH:
- st_cleanup_thread();
- st_cleanup();
+ stw_cleanup_thread();
+ stw_cleanup();
break;
}
return TRUE;
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index bb187cc14a..522f6dc5ae 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/xlib/Makefile
@@ -74,7 +74,7 @@ $(TOP)/$(LIB_DIR)/gallium/$(GL_LIB_NAME): $(XLIB_WINSYS_OBJECTS) $(LIBS) Makefil
-major $(GL_MAJOR) -minor $(GL_MINOR) -patch $(GL_TINY) \
-install $(TOP)/$(LIB_DIR)/gallium \
$(MKLIB_OPTIONS) $(XLIB_WINSYS_OBJECTS) \
- --start-group $(LIBS) --end-group $(GL_LIB_DEPS)
+ -Wl,--start-group $(LIBS) -Wl,--end-group $(GL_LIB_DEPS)
depend: $(XLIB_WINSYS_SOURCES)
@@ -90,7 +90,7 @@ install: default
$(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); \
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
fi
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 762ebd9847..44b8464518 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -482,7 +482,7 @@ xlib_create_softpipe_context( struct pipe_screen *screen,
{
struct pipe_context *pipe;
- pipe = softpipe_create(screen, screen->winsys, NULL);
+ pipe = softpipe_create(screen);
if (pipe == NULL)
goto fail;
diff --git a/src/gallium/winsys/xlib/xlib_trace.c b/src/gallium/winsys/xlib/xlib_trace.c
index 37095c5d8e..dbea655ab4 100644
--- a/src/gallium/winsys/xlib/xlib_trace.c
+++ b/src/gallium/winsys/xlib/xlib_trace.c
@@ -37,6 +37,7 @@
#include "trace/tr_screen.h"
#include "trace/tr_context.h"
+#include "trace/tr_texture.h"
#include "pipe/p_screen.h"
@@ -66,9 +67,11 @@ fail:
}
static struct pipe_context *
-xlib_create_trace_context( struct pipe_screen *screen,
+xlib_create_trace_context( struct pipe_screen *_screen,
void *priv )
{
+ struct trace_screen *tr_scr = trace_screen( _screen );
+ struct pipe_screen *screen = tr_scr->screen;
struct pipe_context *pipe, *trace_pipe;
pipe = xlib_softpipe_driver.create_pipe_context( screen, priv );
@@ -77,7 +80,7 @@ xlib_create_trace_context( struct pipe_screen *screen,
/* Wrap it:
*/
- trace_pipe = trace_context_create(screen, pipe);
+ trace_pipe = trace_context_create(_screen, pipe);
if (trace_pipe == NULL)
goto fail;
@@ -86,15 +89,18 @@ xlib_create_trace_context( struct pipe_screen *screen,
return trace_pipe;
fail:
+ if (pipe)
+ pipe->destroy( pipe );
return NULL;
}
static void
xlib_trace_display_surface( struct xmesa_buffer *buffer,
- struct pipe_surface *surf )
+ struct pipe_surface *_surf )
{
- /* ??
- */
+ struct trace_surface *tr_surf = trace_surface( _surf );
+ struct pipe_surface *surf = tr_surf->surface;
+
xlib_softpipe_driver.display_surface( buffer, surf );
}