summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SConscript4
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c82
-rw-r--r--src/egl/main/SConscript49
-rw-r--r--src/egl/main/eglapi.c4
-rw-r--r--src/egl/main/eglcompiler.h16
-rw-r--r--src/egl/main/egldriver.c12
-rw-r--r--src/egl/main/egllog.c3
-rw-r--r--src/egl/main/eglmisc.c4
-rw-r--r--src/egl/main/eglstring.c2
-rw-r--r--src/egl/main/eglstring.h9
-rw-r--r--src/gallium/SConscript2
-rw-r--r--src/gallium/auxiliary/Makefile1
-rw-r--r--src/gallium/auxiliary/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c33
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_arit.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.c39
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_const.h4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.c4
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.c18
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_misc.cpp23
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_quad.c101
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_quad.h96
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample.c12
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c228
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c57
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.c20
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.h12
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt1127
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.c32
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.h3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c32
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_util.c146
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_util.h5
-rw-r--r--src/gallium/auxiliary/util/u_blit.c6
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c67
-rw-r--r--src/gallium/auxiliary/util/u_debug.c14
-rw-r--r--src/gallium/auxiliary/util/u_debug.h6
-rw-r--r--src/gallium/auxiliary/util/u_dl.h3
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c6
-rw-r--r--src/gallium/auxiliary/util/u_math.h12
-rw-r--r--src/gallium/auxiliary/util/u_pointer.h12
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c19
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.h7
-rw-r--r--src/gallium/docs/source/tgsi.rst2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_context.c16
-rw-r--r--src/gallium/drivers/i915/i915_screen.c9
-rw-r--r--src/gallium/drivers/i915/i915_screen.h1
-rw-r--r--src/gallium/drivers/i915/i915_winsys.h4
-rw-r--r--src/gallium/drivers/i965/brw_screen.c58
-rw-r--r--src/gallium/drivers/llvmpipe/README5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.c362
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.h26
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h30
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.c49
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast.h8
-rw-r--r--src/gallium/drivers/llvmpipe/lp_rast_priv.h10
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c25
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup_tri.c98
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h54
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c37
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c101
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.h100
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_blend.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_conv.c14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_format.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_printf.c15
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_sincos.c4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c6
-rw-r--r--src/gallium/drivers/r300/Makefile1
-rw-r--r--src/gallium/drivers/r300/SConscript1
-rw-r--r--src/gallium/drivers/r300/r300_context.c8
-rw-r--r--src/gallium/drivers/r300/r300_context.h27
-rw-r--r--src/gallium/drivers/r300/r300_cs.h7
-rw-r--r--src/gallium/drivers/r300/r300_debug.c59
-rw-r--r--src/gallium/drivers/r300/r300_defines.h7
-rw-r--r--src/gallium/drivers/r300/r300_emit.c77
-rw-r--r--src/gallium/drivers/r300/r300_emit.h2
-rw-r--r--src/gallium/drivers/r300/r300_flush.c1
-rw-r--r--src/gallium/drivers/r300/r300_query.c8
-rw-r--r--src/gallium/drivers/r300/r300_render.c411
-rw-r--r--src/gallium/drivers/r300/r300_resource.c10
-rw-r--r--src/gallium/drivers/r300/r300_screen.c14
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.c25
-rw-r--r--src/gallium/drivers/r300/r300_screen_buffer.h10
-rw-r--r--src/gallium/drivers/r300/r300_state.c131
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c29
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h29
-rw-r--r--src/gallium/drivers/r300/r300_texture.c38
-rw-r--r--src/gallium/drivers/r300/r300_texture.h1
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c58
-rw-r--r--src/gallium/drivers/r300/r300_transfer.h2
-rw-r--r--src/gallium/drivers/r300/r300_vs.h4
-rw-r--r--src/gallium/drivers/r300/r300_vs_draw.c358
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h23
-rw-r--r--src/gallium/drivers/r600/Makefile27
-rw-r--r--src/gallium/drivers/r600/SConscript37
-rw-r--r--src/gallium/drivers/r600/r600_blit.c82
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c232
-rw-r--r--src/gallium/drivers/r600/r600_compiler.c446
-rw-r--r--src/gallium/drivers/r600/r600_compiler.h328
-rw-r--r--src/gallium/drivers/r600/r600_compiler_dump.c270
-rw-r--r--src/gallium/drivers/r600/r600_compiler_r600.c869
-rw-r--r--src/gallium/drivers/r600/r600_compiler_r700.c214
-rw-r--r--src/gallium/drivers/r600/r600_compiler_tgsi.c703
-rw-r--r--src/gallium/drivers/r600/r600_context.c152
-rw-r--r--src/gallium/drivers/r600/r600_context.h90
-rw-r--r--src/gallium/drivers/r600/r600_draw.c217
-rw-r--r--src/gallium/drivers/r600/r600_helper.c157
-rw-r--r--src/gallium/drivers/r600/r600_query.c65
-rw-r--r--src/gallium/drivers/r600/r600_resource.c68
-rw-r--r--src/gallium/drivers/r600/r600_resource.h33
-rw-r--r--src/gallium/drivers/r600/r600_screen.c261
-rw-r--r--src/gallium/drivers/r600/r600_screen.h119
-rw-r--r--src/gallium/drivers/r600/r600_shader.c217
-rw-r--r--src/gallium/drivers/r600/r600_shader.h262
-rw-r--r--src/gallium/drivers/r600/r600_sq.h606
-rw-r--r--src/gallium/drivers/r600/r600_state.c484
-rw-r--r--src/gallium/drivers/r600/r600_texture.c231
-rw-r--r--src/gallium/drivers/r600/r600_texture.h53
-rw-r--r--src/gallium/drivers/r600/r600d.h677
-rw-r--r--src/gallium/drivers/r600/r700_sq.h609
-rw-r--r--src/gallium/drivers/r600/radeon.h602
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c3
-rw-r--r--src/gallium/drivers/svga/svga_context.c5
-rw-r--r--src/gallium/drivers/svga/svga_screen.c30
-rw-r--r--src/gallium/drivers/svga/svga_winsys.h3
-rw-r--r--src/gallium/drivers/trace/tr_context.c6
-rw-r--r--src/gallium/include/pipe/p_compiler.h2
-rw-r--r--src/gallium/state_trackers/dri/common/dri_context.h2
-rw-r--r--src/gallium/state_trackers/dri/drm/SConscript1
-rw-r--r--src/gallium/state_trackers/egl/SConscript32
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.c2
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d.h3
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_api.c102
-rw-r--r--src/gallium/state_trackers/egl/common/egl_g3d_st.c83
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.c235
-rw-r--r--src/gallium/state_trackers/egl/common/native_helper.h70
-rw-r--r--src/gallium/state_trackers/egl/gdi/native_gdi.c427
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.c111
-rw-r--r--src/gallium/state_trackers/egl/kms/native_kms.h6
-rw-r--r--src/gallium/state_trackers/egl/x11/native_ximage.c244
-rw-r--r--src/gallium/state_trackers/python/p_context.i42
-rw-r--r--src/gallium/state_trackers/vega/SConscript51
-rw-r--r--src/gallium/state_trackers/vega/api_filters.c11
-rw-r--r--src/gallium/state_trackers/vega/arc.c3
-rw-r--r--src/gallium/state_trackers/vega/renderer.c3
-rw-r--r--src/gallium/state_trackers/vega/stroker.c5
-rw-r--r--src/gallium/state_trackers/vega/util_array.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c9
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c14
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c63
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c3
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h12
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c14
-rw-r--r--src/gallium/targets/Makefile.dri6
-rw-r--r--src/gallium/targets/Makefile.egl12
-rw-r--r--src/gallium/targets/Makefile.xorg72
-rw-r--r--src/gallium/targets/SConscript23
-rw-r--r--src/gallium/targets/SConscript.dri5
-rw-r--r--src/gallium/targets/dri-r600/Makefile22
-rw-r--r--src/gallium/targets/dri-r600/SConscript27
-rw-r--r--src/gallium/targets/dri-r600/dummy.c0
-rw-r--r--src/gallium/targets/egl-apis/SConscript33
-rw-r--r--src/gallium/targets/egl-swrast/SConscript30
-rw-r--r--src/gallium/targets/egl-swrast/swrast_glue.c6
-rw-r--r--src/gallium/targets/xorg-vmwgfx/Makefile62
-rw-r--r--src/gallium/targets/xorg-vmwgfx/vmw_screen.c44
-rwxr-xr-xsrc/gallium/tests/python/retrace/interpreter.py16
-rw-r--r--src/gallium/winsys/SConscript5
-rw-r--r--src/gallium/winsys/i915/drm/Makefile2
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_winsys.c (renamed from src/gallium/winsys/i915/drm/i915_drm_api.c)4
-rw-r--r--src/gallium/winsys/i915/drm/i915_drm_winsys.h2
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_winsys.c4
-rw-r--r--src/gallium/winsys/i915/sw/i915_sw_winsys.h2
-rw-r--r--src/gallium/winsys/r600/drm/Makefile23
-rw-r--r--src/gallium/winsys/r600/drm/bof.c477
-rw-r--r--src/gallium/winsys/r600/drm/bof.h90
-rw-r--r--src/gallium/winsys/r600/drm/r600_drm.c86
-rw-r--r--src/gallium/winsys/r600/drm/r600_state.c399
-rw-r--r--src/gallium/winsys/r600/drm/r600_states.h461
-rw-r--r--src/gallium/winsys/r600/drm/r600d.h2122
-rw-r--r--src/gallium/winsys/r600/drm/radeon.c195
-rw-r--r--src/gallium/winsys/r600/drm/radeon_bo.c170
-rw-r--r--src/gallium/winsys/r600/drm/radeon_ctx.c406
-rw-r--r--src/gallium/winsys/r600/drm/radeon_draw.c141
-rw-r--r--src/gallium/winsys/r600/drm/radeon_pciid.c528
-rw-r--r--src/gallium/winsys/r600/drm/radeon_priv.h130
-rw-r--r--src/gallium/winsys/r600/drm/radeon_state.c168
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h8
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c59
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c26
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.c19
-rw-r--r--src/gallium/winsys/svga/drm/vmw_context.h3
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.c10
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen.h12
-rw-r--r--src/gallium/winsys/svga/drm/vmw_screen_ioctl.c6
-rw-r--r--src/gallium/winsys/sw/xlib/xlib_sw_winsys.c2
-rw-r--r--src/glx/glxext.c6
-rw-r--r--src/mapi/glapi/SConscript20
-rw-r--r--src/mapi/mapi/u_compiler.h4
-rw-r--r--src/mapi/vgapi/SConscript55
-rw-r--r--src/mesa/Makefile4
-rw-r--r--src/mesa/SConscript1
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_queryobj.c84
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_cache.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c9
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c15
-rw-r--r--src/mesa/drivers/dri/intel/intel_decode.c27
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c7
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c8
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c6
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c8
-rw-r--r--src/mesa/drivers/dri/r300/r300_blit.c14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c22
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c68
-rw-r--r--src/mesa/drivers/fbdev/glfbdev.c8
-rw-r--r--src/mesa/main/compiler.h4
-rw-r--r--src/mesa/main/es_generator.py3
-rw-r--r--src/mesa/main/fbobject.c21
-rw-r--r--src/mesa/main/get.c4
-rw-r--r--src/mesa/main/shaders.c153
-rw-r--r--src/mesa/main/shaders.h239
-rw-r--r--src/mesa/shader/prog_print.c2
-rw-r--r--src/mesa/shader/program_parse.tab.c2
-rw-r--r--src/mesa/shader/program_parse.y2
-rw-r--r--src/mesa/shader/shader_api.c883
-rw-r--r--src/mesa/shader/shader_api.h4
-rw-r--r--src/mesa/shader/slang/slang_emit.c2
-rw-r--r--src/mesa/shader/slang/slang_link.c137
-rw-r--r--src/mesa/shader/uniforms.c937
-rw-r--r--src/mesa/shader/uniforms.h33
-rw-r--r--src/mesa/sources.mak3
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c2
-rw-r--r--src/mesa/state_tracker/st_cb_viewport.c2
-rw-r--r--src/mesa/state_tracker/st_context.c2
-rw-r--r--src/mesa/state_tracker/st_debug.c18
-rw-r--r--src/mesa/state_tracker/st_extensions.c7
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c13
-rw-r--r--src/mesa/vbo/vbo_exec.c12
-rw-r--r--src/mesa/vbo/vbo_exec.h3
-rw-r--r--src/mesa/vbo/vbo_exec_array.c99
251 files changed, 19179 insertions, 4199 deletions
diff --git a/src/SConscript b/src/SConscript
index b72491d96f..9eda35e7c5 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -3,6 +3,10 @@ Import('*')
SConscript('glsl/SConscript')
SConscript('mapi/glapi/SConscript')
+if 'egl' in env['statetrackers']:
+ SConscript('mapi/vgapi/SConscript')
+ SConscript('egl/main/SConscript')
+
if 'mesa' in env['statetrackers']:
SConscript('mesa/SConscript')
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index eb9a6510ed..aa384cb117 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -628,40 +628,12 @@ dri2_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
return EGL_TRUE;
}
-/**
- * Called via eglInitialize(), GLX_drv->API.Initialize().
- */
static EGLBoolean
-dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
- EGLint *major, EGLint *minor)
+dri2_load_driver(_EGLDisplay *disp)
{
+ struct dri2_egl_display *dri2_dpy = disp->DriverData;
const __DRIextension **extensions;
- struct dri2_egl_display *dri2_dpy;
char path[PATH_MAX], *search_paths, *p, *next, *end;
- unsigned int api_mask;
-
- dri2_dpy = malloc(sizeof *dri2_dpy);
- if (!dri2_dpy)
- return _eglError(EGL_BAD_ALLOC, "eglInitialize");
-
- disp->DriverData = (void *) dri2_dpy;
- if (disp->NativeDisplay == NULL) {
- dri2_dpy->conn = xcb_connect(0, 0);
- if (!dri2_dpy->conn) {
- _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
- goto cleanup_dpy;
- }
- } else {
- dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
- }
-
- if (dri2_dpy->conn == NULL)
- goto cleanup_conn;
-
- if (dri2_dpy->conn) {
- if (!dri2_connect(dri2_dpy))
- goto cleanup_conn;
- }
search_paths = NULL;
if (geteuid() == getuid()) {
@@ -698,7 +670,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
_eglLog(_EGL_WARNING,
"DRI2: failed to open any driver (search paths %s)",
search_paths);
- goto cleanup_conn;
+ return EGL_FALSE;
}
_eglLog(_EGL_DEBUG, "DRI2: dlopen(%s)", path);
@@ -706,11 +678,53 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
if (extensions == NULL) {
_eglLog(_EGL_WARNING,
"DRI2: driver exports no extensions (%s)", dlerror());
- goto cleanup_driver;
+ dlclose(dri2_dpy->driver);
+ return EGL_FALSE;
}
- if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions))
- goto cleanup_driver;
+ if (!dri2_bind_extensions(dri2_dpy, dri2_driver_extensions, extensions)) {
+ dlclose(dri2_dpy->driver);
+ return EGL_FALSE;
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * Called via eglInitialize(), GLX_drv->API.Initialize().
+ */
+static EGLBoolean
+dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
+ EGLint *major, EGLint *minor)
+{
+ const __DRIextension **extensions;
+ struct dri2_egl_display *dri2_dpy;
+ unsigned int api_mask;
+
+ dri2_dpy = malloc(sizeof *dri2_dpy);
+ if (!dri2_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ disp->DriverData = (void *) dri2_dpy;
+ if (disp->NativeDisplay == NULL) {
+ dri2_dpy->conn = xcb_connect(0, 0);
+ } else {
+ dri2_dpy->conn = XGetXCBConnection(disp->NativeDisplay);
+ }
+
+ if (xcb_connection_has_error(dri2_dpy->conn)) {
+ _eglLog(_EGL_WARNING, "DRI2: xcb_connect failed");
+ goto cleanup_dpy;
+ }
+
+ if (dri2_dpy->conn) {
+ if (!dri2_connect(dri2_dpy))
+ goto cleanup_conn;
+ }
+
+ if (!dri2_load_driver(disp))
+ goto cleanup_conn;
dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
if (dri2_dpy->fd == -1) {
diff --git a/src/egl/main/SConscript b/src/egl/main/SConscript
new file mode 100644
index 0000000000..f3fe9966b3
--- /dev/null
+++ b/src/egl/main/SConscript
@@ -0,0 +1,49 @@
+#######################################################################
+# SConscript for EGL
+
+
+Import('*')
+
+if env['platform'] != 'winddk':
+
+ env = env.Clone()
+
+ env.Append(CPPDEFINES = [
+ '_EGL_DEFAULT_DISPLAY=\\"gdi\\"',
+ '_EGL_DRIVER_SEARCH_DIR=\\"\\"',
+ '_EGL_PLATFORM_WINDOWS',
+ 'KHRONOS_DLL_EXPORTS',
+ ])
+
+ env.Append(CPPPATH = [
+ '#/include',
+ ])
+
+ egl_sources = [
+ 'eglapi.c',
+ 'eglconfig.c',
+ 'eglconfigutil.c',
+ 'eglcontext.c',
+ 'eglcurrent.c',
+ 'egldisplay.c',
+ 'egldriver.c',
+ 'eglglobals.c',
+ 'eglimage.c',
+ 'egllog.c',
+ 'eglmisc.c',
+ 'eglmode.c',
+ 'eglscreen.c',
+ 'eglstring.c',
+ 'eglsurface.c',
+ ]
+
+ egl = env.SharedLibrary(
+ target = 'libEGL',
+ source = egl_sources,
+ )
+
+ env.InstallSharedLibrary(egl, version=(1, 4, 0))
+
+ egl = [env.FindIxes(egl, 'LIBPREFIX', 'LIBSUFFIX')]
+
+ Export('egl')
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 1a533e0880..9912043e06 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -56,6 +56,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+#include "eglstring.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egltypedefs.h"
@@ -284,7 +286,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
disp->APImajor = major_int;
disp->APIminor = minor_int;
- snprintf(disp->Version, sizeof(disp->Version),
+ _eglsnprintf(disp->Version, sizeof(disp->Version),
"%d.%d (%s)", major_int, minor_int, drv->Name);
/* limit to APIs supported by core */
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
index 401a9cf56a..90c75e84b2 100644
--- a/src/egl/main/eglcompiler.h
+++ b/src/egl/main/eglcompiler.h
@@ -12,9 +12,7 @@
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
-# ifndef __eglplatform_h_
- typedef __int32 int32_t;
-# endif
+ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
@@ -64,10 +62,14 @@
/**
* Function visibility
*/
-#if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
-# define PUBLIC __attribute__((visibility("default")))
-#else
-# define PUBLIC
+#ifndef PUBLIC
+# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
+# define PUBLIC __attribute__((visibility("default")))
+# elif defined(_MSC_VER)
+# define PUBLIC __declspec(dllexport)
+# else
+# define PUBLIC
+# endif
#endif
/**
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index 566554d51d..631a8710ac 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -7,6 +7,8 @@
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+
+#include "eglstring.h"
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldefines.h"
@@ -36,8 +38,8 @@
/* XXX Need to decide how to do dynamic name lookup on Windows */
-static const char DefaultDriverNames[] = {
- "TBD",
+static const char *DefaultDriverNames[] = {
+ "egl_gdi_swrast"
};
typedef HMODULE lib_handle;
@@ -411,7 +413,7 @@ _eglGetSearchPath(void)
#endif /* _EGL_PLATFORM_POSIX */
if (p) {
- ret = snprintf(buffer, sizeof(buffer),
+ ret = _eglsnprintf(buffer, sizeof(buffer),
"%s:%s", p, _EGL_DRIVER_SEARCH_DIR);
if (ret > 0 && ret < sizeof(buffer))
search_path = buffer;
@@ -483,7 +485,7 @@ _eglPreloadDisplayDrivers(void)
if (!dpy || !dpy[0])
return EGL_FALSE;
- ret = snprintf(prefix, sizeof(prefix), "egl_%s_", dpy);
+ ret = _eglsnprintf(prefix, sizeof(prefix), "egl_%s_", dpy);
if (ret < 0 || ret >= sizeof(prefix))
return EGL_FALSE;
@@ -571,7 +573,7 @@ _eglLoadDefaultDriver(EGLDisplay dpy, EGLint *major, EGLint *minor)
_eglUnlockMutex(_eglGlobal.Mutex);
- return drv;
+ return _eglGlobal.NumDrivers > 0 ? drv : NULL;
}
diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c
index 11a9bf7275..8f3bae2243 100644
--- a/src/egl/main/egllog.c
+++ b/src/egl/main/egllog.c
@@ -11,6 +11,7 @@
#include <string.h>
#include "egllog.h"
+#include "eglstring.h"
#include "eglmutex.h"
#define MAXSTRING 1000
@@ -116,7 +117,7 @@ _eglInitLogger(void)
log_env = getenv("EGL_LOG_LEVEL");
if (log_env) {
for (i = 0; level_strings[i]; i++) {
- if (strcasecmp(log_env, level_strings[i]) == 0) {
+ if (_eglstrcasecmp(log_env, level_strings[i]) == 0) {
level = i;
break;
}
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index e62a9e7de8..4652969659 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -45,7 +45,7 @@ static EGLint
_eglAppendExtension(char **str, const char *ext)
{
char *s = *str;
- EGLint len = strlen(ext);
+ size_t len = strlen(ext);
if (s) {
memcpy(s, ext, len);
@@ -58,7 +58,7 @@ _eglAppendExtension(char **str, const char *ext)
len++;
}
- return len;
+ return (EGLint) len;
}
diff --git a/src/egl/main/eglstring.c b/src/egl/main/eglstring.c
index ba7406158c..e4ab19136f 100644
--- a/src/egl/main/eglstring.c
+++ b/src/egl/main/eglstring.c
@@ -11,7 +11,7 @@ char *
_eglstrdup(const char *s)
{
if (s) {
- int l = strlen(s);
+ size_t l = strlen(s);
char *s2 = malloc(l + 1);
if (s2)
strcpy(s2, s);
diff --git a/src/egl/main/eglstring.h b/src/egl/main/eglstring.h
index 10468636e8..bebb758dd8 100644
--- a/src/egl/main/eglstring.h
+++ b/src/egl/main/eglstring.h
@@ -1,6 +1,15 @@
#ifndef EGLSTRING_INCLUDED
#define EGLSTRING_INCLUDED
+#include <string.h>
+
+#ifdef _EGL_PLATFORM_WINDOWS
+#define _eglstrcasecmp _stricmp
+#define _eglsnprintf _snprintf
+#else
+#define _eglstrcasecmp strcasecmp
+#define _eglsnprintf snprintf
+#endif
extern char *
_eglstrdup(const char *s);
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index e5e9578b5e..c0d48a8268 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -15,6 +15,8 @@ if platform != 'embedded':
SConscript('state_trackers/glx/xlib/SConscript')
SConscript('state_trackers/dri/SConscript')
SConscript('state_trackers/xorg/SConscript')
+ SConscript('state_trackers/egl/SConscript')
+ SConscript('state_trackers/vega/SConscript')
if platform == 'windows':
SConscript('state_trackers/wgl/SConscript')
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 1abf12e95b..3b202b5bc7 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -158,6 +158,7 @@ GALLIVM_SOURCES = \
gallivm/lp_bld_logic.c \
gallivm/lp_bld_pack.c \
gallivm/lp_bld_printf.c \
+ gallivm/lp_bld_quad.c \
gallivm/lp_bld_sample.c \
gallivm/lp_bld_sample_soa.c \
gallivm/lp_bld_struct.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index 7039d5f0c5..af4d5edcf8 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -208,6 +208,7 @@ if env['llvm']:
'gallivm/lp_bld_misc.cpp',
'gallivm/lp_bld_pack.c',
'gallivm/lp_bld_printf.c',
+ 'gallivm/lp_bld_quad.c',
'gallivm/lp_bld_sample.c',
'gallivm/lp_bld_sample_soa.c',
'gallivm/lp_bld_struct.c',
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 7ea51621f7..bd5d8853cf 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -16,40 +16,13 @@
#include "util/u_cpu_detect.h"
#include "util/u_string.h"
+#include "util/u_pointer.h"
#include <llvm-c/Transforms/Scalar.h>
#define DEBUG_STORE 0
-/** cast wrapper */
-static INLINE draw_jit_vert_func_elts
-voidptr_to_draw_vert_func_elts(void *v)
-{
- union {
- void *v;
- draw_jit_vert_func_elts f;
- } u;
- assert(sizeof(u.v) == sizeof(u.f));
- u.v = v;
- return u.f;
-}
-
-
-/** cast wrapper */
-static INLINE draw_jit_vert_func
-voidptr_to_draw_jit_vert_func(void *v)
-{
- union {
- void *v;
- draw_jit_vert_func f;
- } u;
- assert(sizeof(u.v) == sizeof(u.f));
- u.v = v;
- return u.f;
-}
-
-
/* generates the draw jit function */
static void
draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var);
@@ -744,7 +717,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
}
code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function);
- variant->jit_func = voidptr_to_draw_jit_vert_func(code);
+ variant->jit_func = (draw_jit_vert_func)pointer_to_func(code);
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code);
@@ -899,7 +872,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
}
code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function_elts);
- variant->jit_func_elts = voidptr_to_draw_vert_func_elts(code);
+ variant->jit_func_elts = (draw_jit_vert_func_elts)pointer_to_func(code);
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(code);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
index 47aa9aa362..d926b2de18 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c
@@ -54,12 +54,10 @@
#include "lp_bld_type.h"
#include "lp_bld_const.h"
#include "lp_bld_intr.h"
-#include "lp_bld_init.h" /* for lp_build_engine */
#include "lp_bld_logic.h"
#include "lp_bld_pack.h"
#include "lp_bld_debug.h"
#include "lp_bld_arit.h"
-#include "lp_bld_printf.h"
/**
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c
index 031ce9d1a3..e42ff31ac7 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c
@@ -280,34 +280,45 @@ lp_build_one(struct lp_type type)
/**
- * Build constant-valued vector from a scalar value.
+ * Build constant-valued element from a scalar value.
*/
LLVMValueRef
-lp_build_const_vec(struct lp_type type,
- double val)
+lp_build_const_elem(struct lp_type type,
+ double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
- LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
- unsigned i;
-
- assert(type.length <= LP_MAX_VECTOR_LENGTH);
+ LLVMValueRef elem;
if(type.floating) {
- elems[0] = LLVMConstReal(elem_type, val);
+ elem = LLVMConstReal(elem_type, val);
}
else {
double dscale = lp_const_scale(type);
- elems[0] = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
+ elem = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
}
- if (type.length == 1)
- return elems[0];
+ return elem;
+}
- for(i = 1; i < type.length; ++i)
- elems[i] = elems[0];
- return LLVMConstVector(elems, type.length);
+/**
+ * Build constant-valued vector from a scalar value.
+ */
+LLVMValueRef
+lp_build_const_vec(struct lp_type type,
+ double val)
+{
+ if (type.length == 1) {
+ return lp_build_const_elem(type, val);
+ } else {
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+ elems[0] = lp_build_const_elem(type, val);
+ for(i = 1; i < type.length; ++i)
+ elems[i] = elems[0];
+ return LLVMConstVector(elems, type.length);
+ }
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h
index 9ca2f0664e..d46b9f882b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_const.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h
@@ -85,6 +85,10 @@ lp_build_one(struct lp_type type);
LLVMValueRef
+lp_build_const_elem(struct lp_type type,
+ double val);
+
+LLVMValueRef
lp_build_const_vec(struct lp_type type, double val);
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
index 823a8ec7b7..5bc9c741a8 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
@@ -38,7 +38,7 @@
#include "lp_bld_flow.h"
-#define LP_BUILD_FLOW_MAX_VARIABLES 32
+#define LP_BUILD_FLOW_MAX_VARIABLES 64
#define LP_BUILD_FLOW_MAX_DEPTH 32
/**
@@ -407,6 +407,7 @@ lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
/* for each variable, update the Phi node with a (variable, block) pair */
for(i = 0; i < skip->num_variables; ++i) {
assert(*flow->variables[i]);
+ assert(LLVMTypeOf(skip->phi[i]) == LLVMTypeOf(*flow->variables[i]));
LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
}
@@ -433,6 +434,7 @@ lp_build_flow_skip_end(struct lp_build_flow_context *flow)
/* add (variable, block) tuples to the phi nodes */
for(i = 0; i < skip->num_variables; ++i) {
assert(*flow->variables[i]);
+ assert(LLVMTypeOf(skip->phi[i]) == LLVMTypeOf(*flow->variables[i]));
LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
*flow->variables[i] = skip->phi[i];
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index e02a45114b..0a690ea747 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -37,11 +37,11 @@
unsigned gallivm_debug = 0;
static const struct debug_named_value lp_bld_debug_flags[] = {
- { "tgsi", GALLIVM_DEBUG_TGSI },
- { "ir", GALLIVM_DEBUG_IR },
- { "asm", GALLIVM_DEBUG_ASM },
- { "nopt", GALLIVM_DEBUG_NO_OPT },
- {NULL, 0}
+ { "tgsi", GALLIVM_DEBUG_TGSI, NULL },
+ { "ir", GALLIVM_DEBUG_IR, NULL },
+ { "asm", GALLIVM_DEBUG_ASM, NULL },
+ { "nopt", GALLIVM_DEBUG_NO_OPT, NULL },
+ DEBUG_NAMED_VALUE_END
};
#endif
@@ -75,6 +75,10 @@ enum LLVM_CodeGenOpt_Level {
};
+extern void
+lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE);
+
+
void
lp_build_init(void)
{
@@ -109,6 +113,10 @@ lp_build_init(void)
LLVMDisposeMessage(error);
assert(0);
}
+
+#if defined(DEBUG) || defined(PROFILE)
+ lp_register_oprofile_jit_event_listener(lp_build_engine);
+#endif
}
if (!lp_build_target)
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
index db0ca606e5..f004c0ae45 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
+++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp
@@ -34,7 +34,10 @@
#define __STDC_CONSTANT_MACROS
#endif
-#include "llvm-c/Core.h"
+#include <llvm-c/Core.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
+#include <llvm/ExecutionEngine/JITEventListener.h>
#include "pipe/p_config.h"
#include "util/u_debug.h"
@@ -98,3 +101,21 @@ lp_debug_dump_value(LLVMValueRef value)
#endif
+
+
+/**
+ * Register the engine with oprofile.
+ *
+ * This allows to see the LLVM IR function names in oprofile output.
+ *
+ * To actually work LLVM needs to be built with the --with-oprofile configure
+ * option.
+ *
+ * Also a oprofile:oprofile user:group is necessary. Which is not created by
+ * default on some distributions.
+ */
+extern "C" void
+lp_register_oprofile_jit_event_listener(LLVMExecutionEngineRef EE)
+{
+ llvm::unwrap(EE)->RegisterJITEventListener(llvm::createOProfileJITEventListener());
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_quad.c b/src/gallium/auxiliary/gallivm/lp_bld_quad.c
new file mode 100644
index 0000000000..38fd5a39ef
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_quad.c
@@ -0,0 +1,101 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#include "lp_bld_type.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_quad.h"
+
+
+static const unsigned char
+swizzle_left[4] = {
+ LP_BLD_QUAD_TOP_LEFT, LP_BLD_QUAD_TOP_LEFT,
+ LP_BLD_QUAD_BOTTOM_LEFT, LP_BLD_QUAD_BOTTOM_LEFT
+};
+
+static const unsigned char
+swizzle_right[4] = {
+ LP_BLD_QUAD_TOP_RIGHT, LP_BLD_QUAD_TOP_RIGHT,
+ LP_BLD_QUAD_BOTTOM_RIGHT, LP_BLD_QUAD_BOTTOM_RIGHT
+};
+
+static const unsigned char
+swizzle_top[4] = {
+ LP_BLD_QUAD_TOP_LEFT, LP_BLD_QUAD_TOP_RIGHT,
+ LP_BLD_QUAD_TOP_LEFT, LP_BLD_QUAD_TOP_RIGHT
+};
+
+static const unsigned char
+swizzle_bottom[4] = {
+ LP_BLD_QUAD_BOTTOM_LEFT, LP_BLD_QUAD_BOTTOM_RIGHT,
+ LP_BLD_QUAD_BOTTOM_LEFT, LP_BLD_QUAD_BOTTOM_RIGHT
+};
+
+
+LLVMValueRef
+lp_build_ddx(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ LLVMValueRef a_left = lp_build_swizzle1_aos(bld, a, swizzle_left);
+ LLVMValueRef a_right = lp_build_swizzle1_aos(bld, a, swizzle_right);
+ return lp_build_sub(bld, a_right, a_left);
+}
+
+
+LLVMValueRef
+lp_build_ddy(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ LLVMValueRef a_top = lp_build_swizzle1_aos(bld, a, swizzle_top);
+ LLVMValueRef a_bottom = lp_build_swizzle1_aos(bld, a, swizzle_bottom);
+ return lp_build_sub(bld, a_bottom, a_top);
+}
+
+
+LLVMValueRef
+lp_build_scalar_ddx(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ LLVMValueRef idx_left = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_LEFT, 0);
+ LLVMValueRef idx_right = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_RIGHT, 0);
+ LLVMValueRef a_left = LLVMBuildExtractElement(bld->builder, a, idx_left, "");
+ LLVMValueRef a_right = LLVMBuildExtractElement(bld->builder, a, idx_right, "");
+ return LLVMBuildSub(bld->builder, a_right, a_left, "");
+}
+
+
+LLVMValueRef
+lp_build_scalar_ddy(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ LLVMValueRef idx_top = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_TOP_LEFT, 0);
+ LLVMValueRef idx_bottom = LLVMConstInt(LLVMInt32Type(), LP_BLD_QUAD_BOTTOM_LEFT, 0);
+ LLVMValueRef a_top = LLVMBuildExtractElement(bld->builder, a, idx_top, "");
+ LLVMValueRef a_bottom = LLVMBuildExtractElement(bld->builder, a, idx_bottom, "");
+ return LLVMBuildSub(bld->builder, a_bottom, a_top, "");
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_quad.h b/src/gallium/auxiliary/gallivm/lp_bld_quad.h
new file mode 100644
index 0000000000..b799291292
--- /dev/null
+++ b/src/gallium/auxiliary/gallivm/lp_bld_quad.h
@@ -0,0 +1,96 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_BLD_QUAD_H_
+#define LP_BLD_QUAD_H_
+
+
+#include "gallivm/lp_bld.h"
+
+
+struct lp_build_context;
+
+
+/*
+ * Each quad is composed of four elements.
+ *
+ * #########
+ * # 0 | 1 #
+ * #---+---#
+ * # 2 | 3 #
+ * #########
+ */
+
+enum lp_bld_quad {
+ LP_BLD_QUAD_TOP_LEFT = 0,
+ LP_BLD_QUAD_TOP_RIGHT = 1,
+ LP_BLD_QUAD_BOTTOM_LEFT = 2,
+ LP_BLD_QUAD_BOTTOM_RIGHT = 3
+};
+
+
+/*
+ * (Vector) derivates.
+ *
+ * More than one quad is supported. The only requirement is that the vector
+ * contains a whole number of quads:
+ *
+ * ######### ######### ...
+ * # 0 | 1 # # 4 | 5 #
+ * #---+---# #---+---# ...
+ * # 2 | 3 # # 6 | 7 #
+ * ######### ######### ...
+ */
+
+LLVMValueRef
+lp_build_ddx(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+
+LLVMValueRef
+lp_build_ddy(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+
+/*
+ * Scalar derivatives.
+ *
+ * Same as getting the first value of above.
+ */
+
+LLVMValueRef
+lp_build_scalar_ddx(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+
+LLVMValueRef
+lp_build_scalar_ddy(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+
+#endif /* LP_BLD_QUAD_H_ */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
index c7f9b1083b..946c23e317 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c
@@ -92,7 +92,7 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->wrap_r = sampler->wrap_r;
state->min_img_filter = sampler->min_img_filter;
state->mag_img_filter = sampler->mag_img_filter;
- if (texture->last_level) {
+ if (view->last_level) {
state->min_mip_filter = sampler->min_mip_filter;
} else {
state->min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
@@ -105,8 +105,14 @@ lp_sampler_static_state(struct lp_sampler_static_state *state,
state->normalized_coords = sampler->normalized_coords;
state->lod_bias = sampler->lod_bias;
- state->min_lod = sampler->min_lod;
- state->max_lod = sampler->max_lod;
+ if (!view->last_level &&
+ sampler->min_img_filter == sampler->mag_img_filter) {
+ state->min_lod = 0.0f;
+ state->max_lod = 0.0f;
+ } else {
+ state->min_lod = MAX2(sampler->min_lod, 0.0f);
+ state->max_lod = sampler->max_lod;
+ }
state->border_color[0] = sampler->border_color[0];
state->border_color[1] = sampler->border_color[1];
state->border_color[2] = sampler->border_color[2];
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
index bc7213db8b..84c04fe272 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
@@ -415,10 +415,8 @@ is_simple_wrap_mode(unsigned mode)
{
switch (mode) {
case PIPE_TEX_WRAP_REPEAT:
- case PIPE_TEX_WRAP_CLAMP:
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return TRUE;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
default:
return FALSE;
}
@@ -455,24 +453,17 @@ lp_build_sample_wrap_int(struct lp_build_sample_context *bld,
coord = LLVMBuildURem(bld->builder, coord, length, "");
break;
- case PIPE_TEX_WRAP_CLAMP:
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
coord = lp_build_min(int_coord_bld, coord, length_minus_one);
break;
+ case PIPE_TEX_WRAP_CLAMP:
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
case PIPE_TEX_WRAP_MIRROR_REPEAT:
case PIPE_TEX_WRAP_MIRROR_CLAMP:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- /* FIXME */
- _debug_printf("llvmpipe: failed to translate texture wrap mode %s\n",
- util_dump_tex_wrap(wrap_mode, TRUE));
- coord = lp_build_max(uint_coord_bld, coord, uint_coord_bld->zero);
- coord = lp_build_min(uint_coord_bld, coord, length_minus_one);
- break;
-
default:
assert(0);
}
@@ -500,11 +491,9 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef half = lp_build_const_vec(coord_bld->type, 0.5);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
- LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
LLVMValueRef coord0, coord1, weight;
switch(wrap_mode) {
@@ -532,16 +521,18 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_CLAMP:
if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
+
+ /* clamp to [0, length] */
+ coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f);
+
+ coord = lp_build_sub(coord_bld, coord, half);
+
weight = lp_build_fract(coord_bld, coord);
- coord0 = lp_build_clamp(coord_bld, coord, coord_bld->zero,
- length_f_minus_one);
- coord1 = lp_build_add(coord_bld, coord, coord_bld->one);
- coord1 = lp_build_clamp(coord_bld, coord1, coord_bld->zero,
- length_f_minus_one);
- coord0 = lp_build_ifloor(coord_bld, coord0);
- coord1 = lp_build_ifloor(coord_bld, coord1);
+ coord0 = lp_build_ifloor(coord_bld, coord);
+ coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
break;
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
@@ -555,7 +546,7 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
else {
LLVMValueRef min, max;
/* clamp to [0.5, length - 0.5] */
- min = lp_build_const_vec(coord_bld->type, 0.5F);
+ min = half;
max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
}
@@ -574,25 +565,14 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
{
LLVMValueRef min, max;
if (bld->static_state->normalized_coords) {
- /* min = -1.0 / (2 * length) = -0.5 / length */
- min = lp_build_mul(coord_bld,
- lp_build_const_vec(coord_bld->type, -0.5F),
- lp_build_rcp(coord_bld, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
- /* scale coord to length (and sub 0.5?) */
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_sub(coord_bld, coord, half);
- }
- else {
- /* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_vec(coord_bld->type, -0.5F);
- max = lp_build_sub(coord_bld, length_f, min);
- coord = lp_build_clamp(coord_bld, coord, min, max);
- coord = lp_build_sub(coord_bld, coord, half);
}
+ /* clamp to [-0.5, length + 0.5] */
+ min = lp_build_const_vec(coord_bld->type, -0.5F);
+ max = lp_build_sub(coord_bld, length_f, min);
+ coord = lp_build_clamp(coord_bld, coord, min, max);
+ coord = lp_build_sub(coord_bld, coord, half);
/* compute lerp weight */
weight = lp_build_fract(coord_bld, coord);
/* convert to int */
@@ -623,35 +603,41 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
+ coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_clamp(coord_bld, coord, min, max);
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- if(0)coord = lp_build_sub(coord_bld, coord, half);
- weight = lp_build_fract(coord_bld, coord);
- coord0 = lp_build_ifloor(coord_bld, coord);
- coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
}
+
+ /* clamp to [0, length] */
+ coord = lp_build_min(coord_bld, coord, length_f);
+
+ coord = lp_build_sub(coord_bld, coord, half);
+
+ weight = lp_build_fract(coord_bld, coord);
+ coord0 = lp_build_ifloor(coord_bld, coord);
+ coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
{
LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
coord = lp_build_abs(coord_bld, coord);
+
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
+ coord = lp_build_mul(coord_bld, coord, length_f);
+ }
+
+ /* clamp to [0.5, length - 0.5] */
+ min = half;
+ max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
- coord = lp_build_mul(coord_bld, coord, length_f);
+
coord = lp_build_sub(coord_bld, coord, half);
+
weight = lp_build_fract(coord_bld, coord);
coord0 = lp_build_ifloor(coord_bld, coord);
coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
@@ -661,17 +647,21 @@ lp_build_sample_wrap_linear(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
{
LLVMValueRef min, max;
- /* min = -1.0 / (2 * length) = -0.5 / length */
- min = lp_build_mul(coord_bld,
- lp_build_const_vec(coord_bld->type, -0.5F),
- lp_build_rcp(coord_bld, length_f));
- /* max = 1.0 - min */
- max = lp_build_sub(coord_bld, coord_bld->one, min);
coord = lp_build_abs(coord_bld, coord);
+
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
+ coord = lp_build_mul(coord_bld, coord, length_f);
+ }
+
+ /* clamp to [-0.5, length + 0.5] */
+ min = lp_build_negate(coord_bld, half);
+ max = lp_build_sub(coord_bld, length_f, min);
coord = lp_build_clamp(coord_bld, coord, min, max);
- coord = lp_build_mul(coord_bld, coord, length_f);
+
coord = lp_build_sub(coord_bld, coord, half);
+
weight = lp_build_fract(coord_bld, coord);
coord0 = lp_build_ifloor(coord_bld, coord);
coord1 = lp_build_add(int_coord_bld, coord0, int_coord_bld->one);
@@ -708,10 +698,8 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
struct lp_build_context *coord_bld = &bld->coord_bld;
struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
struct lp_build_context *uint_coord_bld = &bld->uint_coord_bld;
- LLVMValueRef two = lp_build_const_vec(coord_bld->type, 2.0);
LLVMValueRef length_f = lp_build_int_to_float(coord_bld, length);
LLVMValueRef length_minus_one = lp_build_sub(uint_coord_bld, length, uint_coord_bld->one);
- LLVMValueRef length_f_minus_one = lp_build_sub(coord_bld, length_f, coord_bld->one);
LLVMValueRef icoord;
switch(wrap_mode) {
@@ -727,120 +715,80 @@ lp_build_sample_wrap_nearest(struct lp_build_sample_context *bld,
break;
case PIPE_TEX_WRAP_CLAMP:
- /* mul by size */
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
+
/* floor */
icoord = lp_build_ifloor(coord_bld, coord);
- /* clamp to [0, size-1]. Note: int coord builder type */
+
+ /* clamp to [0, length - 1]. */
icoord = lp_build_clamp(int_coord_bld, icoord, int_coord_bld->zero,
length_minus_one);
break;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- {
- LLVMValueRef min, max;
- if (bld->static_state->normalized_coords) {
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
- /* scale coord to length */
- coord = lp_build_mul(coord_bld, coord, length_f);
- }
- else {
- /* clamp to [0.5, length - 0.5] */
- min = lp_build_const_vec(coord_bld->type, 0.5F);
- max = lp_build_sub(coord_bld, length_f, min);
- }
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
- }
- break;
-
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
/* Note: this is the same as CLAMP_TO_EDGE, except min = -min */
{
LLVMValueRef min, max;
+
if (bld->static_state->normalized_coords) {
- /* min = -1.0 / (2 * length) = -0.5 / length */
- min = lp_build_mul(coord_bld,
- lp_build_const_vec(coord_bld->type, -0.5F),
- lp_build_rcp(coord_bld, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
/* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
}
- else {
- /* clamp to [-0.5, length + 0.5] */
- min = lp_build_const_vec(coord_bld->type, -0.5F);
- max = lp_build_sub(coord_bld, length_f, min);
- }
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
+
icoord = lp_build_ifloor(coord_bld, coord);
+
+ /* clamp to [-1, length] */
+ min = lp_build_negate(int_coord_bld, int_coord_bld->one);
+ max = length;
+ icoord = lp_build_clamp(int_coord_bld, icoord, min, max);
}
break;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
+ /* compute mirror function */
+ coord = lp_build_coord_mirror(bld, coord);
- /* compute mirror function */
- coord = lp_build_coord_mirror(bld, coord);
+ /* scale coord to length */
+ assert(bld->static_state->normalized_coords);
+ coord = lp_build_mul(coord_bld, coord, length_f);
- /* scale coord to length */
- coord = lp_build_mul(coord_bld, coord, length_f);
+ icoord = lp_build_ifloor(coord_bld, coord);
- /* coord = clamp(coord, min, max) */
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
- }
+ /* clamp to [0, length - 1] */
+ icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
- coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_clamp(coord_bld, coord, coord_bld->zero, length_f_minus_one);
- icoord = lp_build_ifloor(coord_bld, coord);
- break;
-
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
+ coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_abs(coord_bld, coord);
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
}
+
+ icoord = lp_build_ifloor(coord_bld, coord);
+
+ /* clamp to [0, length - 1] */
+ icoord = lp_build_min(int_coord_bld, icoord, length_minus_one);
break;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- {
- LLVMValueRef min, max;
- /* min = 1.0 / (2 * length) */
- min = lp_build_rcp(coord_bld, lp_build_mul(coord_bld, two, length_f));
- min = lp_build_negate(coord_bld, min);
- /* max = length - min */
- max = lp_build_sub(coord_bld, length_f, min);
+ coord = lp_build_abs(coord_bld, coord);
- coord = lp_build_abs(coord_bld, coord);
+ if (bld->static_state->normalized_coords) {
+ /* scale coord to length */
coord = lp_build_mul(coord_bld, coord, length_f);
- coord = lp_build_clamp(coord_bld, coord, min, max);
- icoord = lp_build_ifloor(coord_bld, coord);
}
+
+ icoord = lp_build_ifloor(coord_bld, coord);
+
+ /* clamp to [0, length] */
+ icoord = lp_build_min(int_coord_bld, icoord, length);
break;
default:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 40ea94c493..ea949a1363 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -53,6 +53,7 @@
#include "lp_bld_logic.h"
#include "lp_bld_swizzle.h"
#include "lp_bld_flow.h"
+#include "lp_bld_quad.h"
#include "lp_bld_tgsi.h"
#include "lp_bld_limits.h"
#include "lp_bld_debug.h"
@@ -76,11 +77,6 @@
#define CHAN_Z 2
#define CHAN_W 3
-#define QUAD_TOP_LEFT 0
-#define QUAD_TOP_RIGHT 1
-#define QUAD_BOTTOM_LEFT 2
-#define QUAD_BOTTOM_RIGHT 3
-
#define LP_MAX_INSTRUCTIONS 256
@@ -148,30 +144,6 @@ struct lp_build_tgsi_soa_context
uint max_instructions;
};
-static const unsigned char
-swizzle_left[4] = {
- QUAD_TOP_LEFT, QUAD_TOP_LEFT,
- QUAD_BOTTOM_LEFT, QUAD_BOTTOM_LEFT
-};
-
-static const unsigned char
-swizzle_right[4] = {
- QUAD_TOP_RIGHT, QUAD_TOP_RIGHT,
- QUAD_BOTTOM_RIGHT, QUAD_BOTTOM_RIGHT
-};
-
-static const unsigned char
-swizzle_top[4] = {
- QUAD_TOP_LEFT, QUAD_TOP_RIGHT,
- QUAD_TOP_LEFT, QUAD_TOP_RIGHT
-};
-
-static const unsigned char
-swizzle_bottom[4] = {
- QUAD_BOTTOM_LEFT, QUAD_BOTTOM_RIGHT,
- QUAD_BOTTOM_LEFT, QUAD_BOTTOM_RIGHT
-};
-
static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld)
{
mask->bld = bld;
@@ -433,25 +405,6 @@ static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
}
static LLVMValueRef
-emit_ddx(struct lp_build_tgsi_soa_context *bld,
- LLVMValueRef src)
-{
- LLVMValueRef src_left = lp_build_swizzle1_aos(&bld->base, src, swizzle_left);
- LLVMValueRef src_right = lp_build_swizzle1_aos(&bld->base, src, swizzle_right);
- return lp_build_sub(&bld->base, src_right, src_left);
-}
-
-
-static LLVMValueRef
-emit_ddy(struct lp_build_tgsi_soa_context *bld,
- LLVMValueRef src)
-{
- LLVMValueRef src_top = lp_build_swizzle1_aos(&bld->base, src, swizzle_top);
- LLVMValueRef src_bottom = lp_build_swizzle1_aos(&bld->base, src, swizzle_bottom);
- return lp_build_sub(&bld->base, src_top, src_bottom);
-}
-
-static LLVMValueRef
get_temp_ptr(struct lp_build_tgsi_soa_context *bld,
unsigned index,
unsigned chan,
@@ -599,10 +552,10 @@ emit_fetch_deriv(
/* TODO: use interpolation coeffs for inputs */
if(ddx)
- *ddx = emit_ddx(bld, src);
+ *ddx = lp_build_ddx(&bld->base, src);
if(ddy)
- *ddy = emit_ddy(bld, src);
+ *ddy = lp_build_ddy(&bld->base, src);
}
@@ -842,8 +795,8 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
unit = inst->Src[3].Register.Index;
} else {
for (i = 0; i < num_coords; i++) {
- ddx[i] = emit_ddx( bld, coords[i] );
- ddy[i] = emit_ddy( bld, coords[i] );
+ ddx[i] = lp_build_ddx( &bld->base, coords[i] );
+ ddy[i] = lp_build_ddy( &bld->base, coords[i] );
}
unit = inst->Src[1].Register.Index;
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c
index aac3a57bc7..06f1aae6dc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c
@@ -372,7 +372,23 @@ lp_build_context_init(struct lp_build_context *bld,
{
bld->builder = builder;
bld->type = type;
- bld->undef = lp_build_undef(type);
- bld->zero = lp_build_zero(type);
+
+ bld->int_elem_type = lp_build_int_elem_type(type);
+ if (type.floating)
+ bld->elem_type = lp_build_elem_type(type);
+ else
+ bld->elem_type = bld->int_elem_type;
+
+ if (type.length == 1) {
+ bld->int_vec_type = bld->int_elem_type;
+ bld->vec_type = bld->elem_type;
+ }
+ else {
+ bld->int_vec_type = LLVMVectorType(bld->int_elem_type, type.length);
+ bld->vec_type = LLVMVectorType(bld->elem_type, type.length);
+ }
+
+ bld->undef = LLVMGetUndef(bld->vec_type);
+ bld->zero = LLVMConstNull(bld->vec_type);
bld->one = lp_build_one(type);
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h
index 17819d4d32..df77ef2155 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -129,6 +129,18 @@ struct lp_build_context
struct lp_type type;
/** Same as lp_build_undef(type) */
+ LLVMTypeRef elem_type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMTypeRef vec_type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMTypeRef int_elem_type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMTypeRef int_vec_type;
+
+ /** Same as lp_build_undef(type) */
LLVMValueRef undef;
/** Same as lp_build_zero(type) */
diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
deleted file mode 100644
index 5d9eed9258..0000000000
--- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
+++ /dev/null
@@ -1,1127 +0,0 @@
-TGSI Instruction Specification
-==============================
-==============================
-
-
-1 Instruction Set Operations
-=============================
-
-
-1.1 GL_NV_vertex_program
--------------------------
-
-
-1.1.1 ARL - Address Register Load
-
- dst.x = floor(src.x)
- dst.y = floor(src.y)
- dst.z = floor(src.z)
- dst.w = floor(src.w)
-
-
-1.1.2 MOV - Move
-
- dst.x = src.x
- dst.y = src.y
- dst.z = src.z
- dst.w = src.w
-
-
-1.1.3 LIT - Light Coefficients
-
- dst.x = 1.0
- dst.y = max(src.x, 0.0)
- dst.z = (src.x > 0.0) ? pow(max(src.y, 0.0), clamp(src.w, -128.0, 128.0)) : 0.0
- dst.w = 1.0
-
-
-1.1.4 RCP - Reciprocal
-
- dst.x = 1.0 / src.x
- dst.y = 1.0 / src.x
- dst.z = 1.0 / src.x
- dst.w = 1.0 / src.x
-
-
-1.1.5 RSQ - Reciprocal Square Root
-
- dst.x = 1.0 / sqrt(abs(src.x))
- dst.y = 1.0 / sqrt(abs(src.x))
- dst.z = 1.0 / sqrt(abs(src.x))
- dst.w = 1.0 / sqrt(abs(src.x))
-
-
-1.1.6 EXP - Approximate Exponential Base 2
-
- dst.x = pow(2.0, floor(src.x))
- dst.y = src.x - floor(src.x)
- dst.z = pow(2.0, src.x)
- dst.w = 1.0
-
-
-1.1.7 LOG - Approximate Logarithm Base 2
-
- dst.x = floor(lg2(abs(src.x)))
- dst.y = abs(src.x) / pow(2.0, floor(lg2(abs(src.x))))
- dst.z = lg2(abs(src.x))
- dst.w = 1.0
-
-
-1.1.8 MUL - Multiply
-
- dst.x = src0.x * src1.x
- dst.y = src0.y * src1.y
- dst.z = src0.z * src1.z
- dst.w = src0.w * src1.w
-
-
-1.1.9 ADD - Add
-
- dst.x = src0.x + src1.x
- dst.y = src0.y + src1.y
- dst.z = src0.z + src1.z
- dst.w = src0.w + src1.w
-
-
-1.1.10 DP3 - 3-component Dot Product
-
- dst.x = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z
- dst.y = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z
- dst.z = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z
- dst.w = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z
-
-
-1.1.11 DP4 - 4-component Dot Product
-
- dst.x = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src0.w * src1.w
- dst.y = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src0.w * src1.w
- dst.z = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src0.w * src1.w
- dst.w = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src0.w * src1.w
-
-
-1.1.12 DST - Distance Vector
-
- dst.x = 1.0
- dst.y = src0.y * src1.y
- dst.z = src0.z
- dst.w = src1.w
-
-
-1.1.13 MIN - Minimum
-
- dst.x = min(src0.x, src1.x)
- dst.y = min(src0.y, src1.y)
- dst.z = min(src0.z, src1.z)
- dst.w = min(src0.w, src1.w)
-
-
-1.1.14 MAX - Maximum
-
- dst.x = max(src0.x, src1.x)
- dst.y = max(src0.y, src1.y)
- dst.z = max(src0.z, src1.z)
- dst.w = max(src0.w, src1.w)
-
-
-1.1.15 SLT - Set On Less Than
-
- dst.x = (src0.x < src1.x) ? 1.0 : 0.0
- dst.y = (src0.y < src1.y) ? 1.0 : 0.0
- dst.z = (src0.z < src1.z) ? 1.0 : 0.0
- dst.w = (src0.w < src1.w) ? 1.0 : 0.0
-
-
-1.1.16 SGE - Set On Greater Equal Than
-
- dst.x = (src0.x >= src1.x) ? 1.0 : 0.0
- dst.y = (src0.y >= src1.y) ? 1.0 : 0.0
- dst.z = (src0.z >= src1.z) ? 1.0 : 0.0
- dst.w = (src0.w >= src1.w) ? 1.0 : 0.0
-
-
-1.1.17 MAD - Multiply And Add
-
- dst.x = src0.x * src1.x + src2.x
- dst.y = src0.y * src1.y + src2.y
- dst.z = src0.z * src1.z + src2.z
- dst.w = src0.w * src1.w + src2.w
-
-
-1.2 GL_ATI_fragment_shader
----------------------------
-
-
-1.2.1 SUB - Subtract
-
- dst.x = src0.x - src1.x
- dst.y = src0.y - src1.y
- dst.z = src0.z - src1.z
- dst.w = src0.w - src1.w
-
-
-1.2.2 DOT3 - 3-component Dot Product
-
- Alias for DP3.
-
-
-1.2.3 DOT4 - 4-component Dot Product
-
- Alias for DP4.
-
-
-1.2.4 LERP - Linear Interpolate
-
- dst.x = src0.x * (src1.x - src2.x) + src2.x
- dst.y = src0.y * (src1.y - src2.y) + src2.y
- dst.z = src0.z * (src1.z - src2.z) + src2.z
- dst.w = src0.w * (src1.w - src2.w) + src2.w
-
-
-1.2.5 CND - Condition
-
- dst.x = (src2.x > 0.5) ? src0.x : src1.x
- dst.y = (src2.y > 0.5) ? src0.y : src1.y
- dst.z = (src2.z > 0.5) ? src0.z : src1.z
- dst.w = (src2.w > 0.5) ? src0.w : src1.w
-
-
-1.2.6 CND0 - Condition Zero
-
- Removed. Use (CMP src2, src1, src0) instead.
-
-1.2.7 DOT2ADD - 2-component Dot Product And Add
-
- dst.x = src0.x * src1.x + src0.y * src1.y + src2.x
- dst.y = src0.x * src1.x + src0.y * src1.y + src2.x
- dst.z = src0.x * src1.x + src0.y * src1.y + src2.x
- dst.w = src0.x * src1.x + src0.y * src1.y + src2.x
-
-
-1.3 GL_EXT_vertex_shader
--------------------------
-
-
-1.3.1 INDEX - Array Lookup
-
- Considered for removal from language.
-
-
-1.3.2 NEGATE - Negate
-
- Considered for removal from language.
-
-
-1.3.3 MADD - Multiply And Add
-
- Alias for MAD.
-
-
-1.3.4 FRAC - Fraction
-
- dst.x = src.x - floor(src.x)
- dst.y = src.y - floor(src.y)
- dst.z = src.z - floor(src.z)
- dst.w = src.w - floor(src.w)
-
-
-1.3.5 SETGE - Set On Greater Equal
-
- Alias for SGE.
-
-
-1.3.6 SETLT - Set On Less Than
-
- Alias for SLT.
-
-
-1.3.7 CLAMP - Clamp
-
- dst.x = clamp(src0.x, src1.x, src2.x)
- dst.y = clamp(src0.y, src1.y, src2.y)
- dst.z = clamp(src0.z, src1.z, src2.z)
- dst.w = clamp(src0.w, src1.w, src2.w)
-
-
-1.3.8 FLOOR - Floor
-
- dst.x = floor(src.x)
- dst.y = floor(src.y)
- dst.z = floor(src.z)
- dst.w = floor(src.w)
-
-
-1.3.9 ROUND - Round
-
- dst.x = round(src.x)
- dst.y = round(src.y)
- dst.z = round(src.z)
- dst.w = round(src.w)
-
-
-1.3.10 EXPBASE2 - Exponential Base 2
-
- dst.x = pow(2.0, src.x)
- dst.y = pow(2.0, src.x)
- dst.z = pow(2.0, src.x)
- dst.w = pow(2.0, src.x)
-
-
-1.3.11 LOGBASE2 - Logarithm Base 2
-
- dst.x = lg2(src.x)
- dst.y = lg2(src.x)
- dst.z = lg2(src.x)
- dst.w = lg2(src.x)
-
-
-1.3.12 POWER - Power
-
- dst.x = pow(src0.x, src1.x)
- dst.y = pow(src0.x, src1.x)
- dst.z = pow(src0.x, src1.x)
- dst.w = pow(src0.x, src1.x)
-
-
-1.3.13 RECIP - Reciprocal
-
- Alias for RCP.
-
-
-1.3.14 RECIPSQRT - Reciprocal Square Root
-
- Alias for RSQ.
-
-
-1.3.15 CROSSPRODUCT - Cross Product
-
- dst.x = src0.y * src1.z - src1.y * src0.z
- dst.y = src0.z * src1.x - src1.z * src0.x
- dst.z = src0.x * src1.y - src1.x * src0.y
- dst.w = 1.0
-
-
-1.3.16 MULTIPLYMATRIX - Multiply Matrix
-
- Considered for removal from language.
-
-
-1.4 GL_NV_vertex_program1_1
-----------------------------
-
-
-1.4.1 ABS - Absolute
-
- dst.x = abs(src.x)
- dst.y = abs(src.y)
- dst.z = abs(src.z)
- dst.w = abs(src.w)
-
-
-1.4.2 RCC - Reciprocal Clamped
-
- dst.x = (1.0 / src.x) > 0.0 ? clamp(1.0 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1.0 / src.x, -1.884467e+019, -5.42101e-020)
- dst.y = (1.0 / src.x) > 0.0 ? clamp(1.0 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1.0 / src.x, -1.884467e+019, -5.42101e-020)
- dst.z = (1.0 / src.x) > 0.0 ? clamp(1.0 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1.0 / src.x, -1.884467e+019, -5.42101e-020)
- dst.w = (1.0 / src.x) > 0.0 ? clamp(1.0 / src.x, 5.42101e-020, 1.884467e+019) : clamp(1.0 / src.x, -1.884467e+019, -5.42101e-020)
-
-
-1.4.3 DPH - Homogeneous Dot Product
-
- dst.x = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w
- dst.y = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w
- dst.z = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w
- dst.w = src0.x * src1.x + src0.y * src1.y + src0.z * src1.z + src1.w
-
-
-1.5 GL_NV_fragment_program
----------------------------
-
-
-1.5.1 COS - Cosine
-
- dst.x = cos(src.x)
- dst.y = cos(src.x)
- dst.z = cos(src.x)
- dst.w = cos(src.w)
-
-
-1.5.2 DDX - Derivative Relative To X
-
- dst.x = partialx(src.x)
- dst.y = partialx(src.y)
- dst.z = partialx(src.z)
- dst.w = partialx(src.w)
-
-
-1.5.3 DDY - Derivative Relative To Y
-
- dst.x = partialy(src.x)
- dst.y = partialy(src.y)
- dst.z = partialy(src.z)
- dst.w = partialy(src.w)
-
-
-1.5.4 EX2 - Exponential Base 2
-
- Alias for EXPBASE2.
-
-
-1.5.5 FLR - Floor
-
- Alias for FLOOR.
-
-
-1.5.6 FRC - Fraction
-
- Alias for FRAC.
-
-
-1.5.7 KILP - Predicated Discard
-
- discard
-
-
-1.5.8 LG2 - Logarithm Base 2
-
- Alias for LOGBASE2.
-
-
-1.5.9 LRP - Linear Interpolate
-
- Alias for LERP.
-
-
-1.5.10 PK2H - Pack Two 16-bit Floats
-
- TBD
-
-
-1.5.11 PK2US - Pack Two Unsigned 16-bit Scalars
-
- TBD
-
-
-1.5.12 PK4B - Pack Four Signed 8-bit Scalars
-
- TBD
-
-
-1.5.13 PK4UB - Pack Four Unsigned 8-bit Scalars
-
- TBD
-
-
-1.5.14 POW - Power
-
- Alias for POWER.
-
-
-1.5.15 RFL - Reflection Vector
-
- dst.x = 2.0 * (src0.x * src1.x + src0.y * src1.y + src0.z * src1.z) / (src0.x * src0.x + src0.y * src0.y + src0.z * src0.z) * src0.x - src1.x
- dst.y = 2.0 * (src0.x * src1.x + src0.y * src1.y + src0.z * src1.z) / (src0.x * src0.x + src0.y * src0.y + src0.z * src0.z) * src0.y - src1.y
- dst.z = 2.0 * (src0.x * src1.x + src0.y * src1.y + src0.z * src1.z) / (src0.x * src0.x + src0.y * src0.y + src0.z * src0.z) * src0.z - src1.z
- dst.w = 1.0
-
-
-1.5.16 SEQ - Set On Equal
-
- dst.x = (src0.x == src1.x) ? 1.0 : 0.0
- dst.y = (src0.y == src1.y) ? 1.0 : 0.0
- dst.z = (src0.z == src1.z) ? 1.0 : 0.0
- dst.w = (src0.w == src1.w) ? 1.0 : 0.0
-
-
-1.5.17 SFL - Set On False
-
- dst.x = 0.0
- dst.y = 0.0
- dst.z = 0.0
- dst.w = 0.0
-
-
-1.5.18 SGT - Set On Greater Than
-
- dst.x = (src0.x > src1.x) ? 1.0 : 0.0
- dst.y = (src0.y > src1.y) ? 1.0 : 0.0
- dst.z = (src0.z > src1.z) ? 1.0 : 0.0
- dst.w = (src0.w > src1.w) ? 1.0 : 0.0
-
-
-1.5.19 SIN - Sine
-
- dst.x = sin(src.x)
- dst.y = sin(src.x)
- dst.z = sin(src.x)
- dst.w = sin(src.w)
-
-
-1.5.20 SLE - Set On Less Equal Than
-
- dst.x = (src0.x <= src1.x) ? 1.0 : 0.0
- dst.y = (src0.y <= src1.y) ? 1.0 : 0.0
- dst.z = (src0.z <= src1.z) ? 1.0 : 0.0
- dst.w = (src0.w <= src1.w) ? 1.0 : 0.0
-
-
-1.5.21 SNE - Set On Not Equal
-
- dst.x = (src0.x != src1.x) ? 1.0 : 0.0
- dst.y = (src0.y != src1.y) ? 1.0 : 0.0
- dst.z = (src0.z != src1.z) ? 1.0 : 0.0
- dst.w = (src0.w != src1.w) ? 1.0 : 0.0
-
-
-1.5.22 STR - Set On True
-
- dst.x = 1.0
- dst.y = 1.0
- dst.z = 1.0
- dst.w = 1.0
-
-
-1.5.23 TEX - Texture Lookup
-
- TBD
-
-
-1.5.24 TXD - Texture Lookup with Derivatives
-
- TBD
-
-
-1.5.25 TXP - Projective Texture Lookup
-
- TBD
-
-
-1.5.26 UP2H - Unpack Two 16-Bit Floats
-
- TBD
-
-
-1.5.27 UP2US - Unpack Two Unsigned 16-Bit Scalars
-
- TBD
-
-
-1.5.28 UP4B - Unpack Four Signed 8-Bit Values
-
- TBD
-
-
-1.5.29 UP4UB - Unpack Four Unsigned 8-Bit Scalars
-
- TBD
-
-
-1.5.30 X2D - 2D Coordinate Transformation
-
- dst.x = src0.x + src1.x * src2.x + src1.y * src2.y
- dst.y = src0.y + src1.x * src2.z + src1.y * src2.w
- dst.z = src0.x + src1.x * src2.x + src1.y * src2.y
- dst.w = src0.y + src1.x * src2.z + src1.y * src2.w
-
-
-1.6 GL_NV_vertex_program2
---------------------------
-
-
-1.6.1 ARA - Address Register Add
-
- TBD
-
-
-1.6.2 ARR - Address Register Load With Round
-
- dst.x = round(src.x)
- dst.y = round(src.y)
- dst.z = round(src.z)
- dst.w = round(src.w)
-
-
-1.6.3 BRA - Branch
-
- pc = target
-
-
-1.6.4 CAL - Subroutine Call
-
- push(pc)
- pc = target
-
-
-1.6.5 RET - Subroutine Call Return
-
- pc = pop()
-
-
-1.6.6 SSG - Set Sign
-
- dst.x = (src.x > 0.0) ? 1.0 : (src.x < 0.0) ? -1.0 : 0.0
- dst.y = (src.y > 0.0) ? 1.0 : (src.y < 0.0) ? -1.0 : 0.0
- dst.z = (src.z > 0.0) ? 1.0 : (src.z < 0.0) ? -1.0 : 0.0
- dst.w = (src.w > 0.0) ? 1.0 : (src.w < 0.0) ? -1.0 : 0.0
-
-
-1.7 GL_ARB_vertex_program
---------------------------
-
-
-1.7.1 SWZ - Extended Swizzle
-
- dst.x = src.x
- dst.y = src.y
- dst.z = src.z
- dst.w = src.w
-
-
-1.7.2 XPD - Cross Product
-
- Alias for CROSSPRODUCT.
-
-
-1.8 GL_ARB_fragment_program
-----------------------------
-
-
-1.8.1 CMP - Compare
-
- dst.x = (src0.x < 0.0) ? src1.x : src2.x
- dst.y = (src0.y < 0.0) ? src1.y : src2.y
- dst.z = (src0.z < 0.0) ? src1.z : src2.z
- dst.w = (src0.w < 0.0) ? src1.w : src2.w
-
-
-1.8.2 KIL - Conditional Discard
-
- if (src.x < 0.0 || src.y < 0.0 || src.z < 0.0 || src.w < 0.0)
- discard
- endif
-
-
-1.8.3 SCS - Sine Cosine
-
- dst.x = cos(src.x)
- dst.y = sin(src.x)
- dst.z = 0.0
- dst.y = 1.0
-
-
-1.8.4 TXB - Texture Lookup With Bias
-
- TBD
-
-
-1.9 GL_NV_fragment_program2
-----------------------------
-
-
-1.9.1 NRM - 3-component Vector Normalise
-
- dst.x = src.x / (src.x * src.x + src.y * src.y + src.z * src.z)
- dst.y = src.y / (src.x * src.x + src.y * src.y + src.z * src.z)
- dst.z = src.z / (src.x * src.x + src.y * src.y + src.z * src.z)
- dst.w = 1.0
-
-
-1.9.2 DIV - Divide
-
- dst.x = src0.x / src1.x
- dst.y = src0.y / src1.y
- dst.z = src0.z / src1.z
- dst.w = src0.w / src1.w
-
-
-1.9.3 DP2 - 2-component Dot Product
-
- dst.x = src0.x * src1.x + src0.y * src1.y
- dst.y = src0.x * src1.x + src0.y * src1.y
- dst.z = src0.x * src1.x + src0.y * src1.y
- dst.w = src0.x * src1.x + src0.y * src1.y
-
-
-1.9.4 DP2A - 2-component Dot Product And Add
-
- Alias for DOT2ADD.
-
-
-1.9.5 TXL - Texture Lookup With LOD
-
- TBD
-
-
-1.9.6 BRK - Break
-
- TBD
-
-
-1.9.7 IF - If
-
- TBD
-
-
-1.9.10 ELSE - Else
-
- TBD
-
-
-1.9.11 ENDIF - End If
-
- TBD
-
-
-1.10 GL_NV_vertex_program3
----------------------------
-
-
-1.10.1 PUSHA - Push Address Register On Stack
-
- push(src.x)
- push(src.y)
- push(src.z)
- push(src.w)
-
-
-1.10.2 POPA - Pop Address Register From Stack
-
- dst.w = pop()
- dst.z = pop()
- dst.y = pop()
- dst.x = pop()
-
-
-1.11 GL_NV_gpu_program4
-------------------------
-
-
-1.11.1 CEIL - Ceiling
-
- dst.x = ceil(src.x)
- dst.y = ceil(src.y)
- dst.z = ceil(src.z)
- dst.w = ceil(src.w)
-
-
-1.11.2 I2F - Integer To Float
-
- dst.x = (float) src.x
- dst.y = (float) src.y
- dst.z = (float) src.z
- dst.w = (float) src.w
-
-
-1.11.3 NOT - Bitwise Not
-
- dst.x = ~src.x
- dst.y = ~src.y
- dst.z = ~src.z
- dst.w = ~src.w
-
-
-1.11.4 TRUNC - Truncate
-
- dst.x = trunc(src.x)
- dst.y = trunc(src.y)
- dst.z = trunc(src.z)
- dst.w = trunc(src.w)
-
-
-1.11.5 SHL - Shift Left
-
- dst.x = src0.x << src1.x
- dst.y = src0.y << src1.x
- dst.z = src0.z << src1.x
- dst.w = src0.w << src1.x
-
-
-1.11.6 SHR - Shift Right
-
- dst.x = src0.x >> src1.x
- dst.y = src0.y >> src1.x
- dst.z = src0.z >> src1.x
- dst.w = src0.w >> src1.x
-
-
-1.11.7 AND - Bitwise And
-
- dst.x = src0.x & src1.x
- dst.y = src0.y & src1.y
- dst.z = src0.z & src1.z
- dst.w = src0.w & src1.w
-
-
-1.11.8 OR - Bitwise Or
-
- dst.x = src0.x | src1.x
- dst.y = src0.y | src1.y
- dst.z = src0.z | src1.z
- dst.w = src0.w | src1.w
-
-
-1.11.9 MOD - Modulus
-
- dst.x = src0.x % src1.x
- dst.y = src0.y % src1.y
- dst.z = src0.z % src1.z
- dst.w = src0.w % src1.w
-
-
-1.11.10 XOR - Bitwise Xor
-
- dst.x = src0.x ^ src1.x
- dst.y = src0.y ^ src1.y
- dst.z = src0.z ^ src1.z
- dst.w = src0.w ^ src1.w
-
-
-1.11.11 SAD - Sum Of Absolute Differences
-
- dst.x = abs(src0.x - src1.x) + src2.x
- dst.y = abs(src0.y - src1.y) + src2.y
- dst.z = abs(src0.z - src1.z) + src2.z
- dst.w = abs(src0.w - src1.w) + src2.w
-
-
-1.11.12 TXF - Texel Fetch
-
- TBD
-
-
-1.11.13 TXQ - Texture Size Query
-
- TBD
-
-
-1.11.14 CONT - Continue
-
- TBD
-
-
-1.12 GL_NV_geometry_program4
------------------------------
-
-
-1.12.1 EMIT - Emit
-
- TBD
-
-
-1.12.2 ENDPRIM - End Primitive
-
- TBD
-
-
-1.13 GLSL
-----------
-
-
-1.13.1 BGNLOOP - Begin a Loop
-
- TBD
-
-
-1.13.2 BGNSUB - Begin Subroutine
-
- TBD
-
-
-1.13.3 ENDLOOP - End a Loop
-
- TBD
-
-
-1.13.4 ENDSUB - End Subroutine
-
- TBD
-
-
-1.13.5 INT - Truncate
-
- Alias for TRUNC.
-
-
-1.13.6 NOISE1 - 1D Noise
-
- TBD
-
-
-1.13.7 NOISE2 - 2D Noise
-
- TBD
-
-
-1.13.8 NOISE3 - 3D Noise
-
- TBD
-
-
-1.13.9 NOISE4 - 4D Noise
-
- TBD
-
-
-1.13.10 NOP - No Operation
-
- Do nothing.
-
-
-1.14 ps_1_1
-------------
-
-
-1.14.1 TEXKILL - Conditional Discard
-
- Alias for KIL.
-
-
-1.15 ps_1_4
-------------
-
-
-1.15.1 TEXLD - Texture Lookup
-
- Alias for TEX.
-
-
-1.16 ps_2_0
-------------
-
-
-1.16.1 M4X4 - Multiply Matrix
-
- Alias for MULTIPLYMATRIX.
-
-
-1.16.2 M4X3 - Multiply Matrix
-
- Considered for removal from language.
-
-
-1.16.3 M3X4 - Multiply Matrix
-
- Considered for removal from language.
-
-
-1.16.4 M3X3 - Multiply Matrix
-
- Considered for removal from language.
-
-
-1.16.5 M3X2 - Multiply Matrix
-
- Considered for removal from language.
-
-
-1.16.6 CRS - Cross Product
-
- Alias for XPD.
-
-
-1.16.7 NRM4 - 4-component Vector Normalise
-
- dst.x = src.x / (src.x * src.x + src.y * src.y + src.z * src.z + src.w * src.w)
- dst.y = src.y / (src.x * src.x + src.y * src.y + src.z * src.z + src.w * src.w)
- dst.z = src.z / (src.x * src.x + src.y * src.y + src.z * src.z + src.w * src.w)
- dst.w = src.w / (src.x * src.x + src.y * src.y + src.z * src.z + src.w * src.w)
-
-
-1.16.8 SINCOS - Sine Cosine
-
- Alias for SCS.
-
-
-1.16.9 TEXLDB - Texture Lookup With Bias
-
- Alias for TXB.
-
-
-1.16.10 DP2ADD - 2-component Dot Product And Add
-
- Alias for DP2A.
-
-
-1.17 ps_2_x
-------------
-
-
-1.17.1 CALL - Subroutine Call
-
- Alias for CAL.
-
-
-1.17.2 CALLNZ - Subroutine Call If Not Zero
-
- TBD
-
-
-1.17.3 IFC - If
-
- TBD
-
-
-1.17.4 BREAK - Break
-
- Alias for BRK.
-
-
-1.17.5 BREAKC - Break Conditional
-
- TBD
-
-
-1.17.6 DSX - Derivative Relative To X
-
- Alias for DDX.
-
-
-1.17.7 DSY - Derivative Relative To Y
-
- Alias for DDY.
-
-
-1.17.8 TEXLDD - Texture Lookup with Derivatives
-
- Alias for TXD.
-
-
-1.18 vs_1_1
-------------
-
-
-1.18.1 EXPP - Approximate Exponential Base 2
-
- Use EXP. See also 1.19.3.
-
-
-1.18.2 LOGP - Logarithm Base 2
-
- Use LOG. See also 1.19.4.
-
-
-1.19 vs_2_0
-------------
-
-
-1.19.1 SGN - Set Sign
-
- Alias for SSG.
-
-
-1.19.2 MOVA - Move Address Register
-
- Alias for ARR.
-
-
-1.19.3 EXPP - Approximate Exponential Base 2
-
- Use EX2.
-
-
-1.19.4 LOGP - Logarithm Base 2
-
- Use LG2.
-
-
-2 Explanation of symbols used
-==============================
-
-
-2.1 Functions
---------------
-
-
- abs(x) Absolute value of x.
- |x|
- (x < 0.0) ? -x : x
-
- ceil(x) Ceiling of x.
-
- clamp(x,y,z) Clamp x between y and z.
- (x < y) ? y : (x > z) ? z : x
-
- cos(x) Cosine of x.
-
- floor(x) Floor of x.
-
- lg2(x) Logarithm base 2 of x.
-
- max(x,y) Maximum of x and y.
- (x > y) ? x : y
-
- min(x,y) Minimum of x and y.
- (x < y) ? x : y
-
- partialx(x) Derivative of x relative to fragment's X.
-
- partialy(x) Derivative of x relative to fragment's Y.
-
- pop() Pop from stack.
-
- pow(x,y) Raise x to power of y.
-
- push(x) Push x on stack.
-
- round(x) Round x.
-
- sin(x) Sine of x.
-
- sqrt(x) Square root of x.
-
- trunc(x) Truncate x.
-
-
-2.2 Keywords
--------------
-
-
- discard Discard fragment.
-
- dst First destination register.
-
- dst0 First destination register.
-
- pc Program counter.
-
- src First source register.
-
- src0 First source register.
-
- src1 Second source register.
-
- src2 Third source register.
-
- target Label of target instruction.
-
-
-3 Other tokens
-===============
-
-
-3.1 Declaration Semantic
--------------------------
-
-
- Follows Declaration token if Semantic bit is set.
-
- Since its purpose is to link a shader with other stages of the pipeline,
- it is valid to follow only those Declaration tokens that declare a register
- either in INPUT or OUTPUT file.
-
- SemanticName field contains the semantic name of the register being declared.
- There is no default value.
-
- SemanticIndex is an optional subscript that can be used to distinguish
- different register declarations with the same semantic name. The default value
- is 0.
-
- The meanings of the individual semantic names are explained in the following
- sections.
-
-
-3.1.1 FACE
-
- Valid only in a fragment shader INPUT declaration.
-
- FACE.x is negative when the primitive is back facing. FACE.x is positive
- when the primitive is front facing.
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index e0c5d3d3d6..ced9c94f46 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -36,6 +36,7 @@
#include "util/u_math.h"
#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_util.h"
#include "tgsi/tgsi_scan.h"
@@ -84,25 +85,28 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
{
const struct tgsi_full_instruction *fullinst
= &parse.FullToken.FullInstruction;
+ uint i;
assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST);
info->opcode_count[fullinst->Instruction.Opcode]++;
- /* check if we read the frag shader FOG or FACE inputs */
- if (procType == TGSI_PROCESSOR_FRAGMENT) {
- uint i;
- for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
- const struct tgsi_full_src_register *src =
- &fullinst->Src[i];
- if (src->Register.File == TGSI_FILE_INPUT ||
- src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
- const int ind = src->Register.Index;
- if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
- info->uses_fogcoord = TRUE;
- }
- else if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FACE) {
- info->uses_frontfacing = TRUE;
+ for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
+ const struct tgsi_full_src_register *src =
+ &fullinst->Src[i];
+ int ind = src->Register.Index;
+
+ /* Mark which inputs are effectively used */
+ if (src->Register.File == TGSI_FILE_INPUT) {
+ unsigned usage_mask;
+ usage_mask = tgsi_util_get_inst_usage_mask(fullinst, i);
+ if (src->Register.Indirect) {
+ for (ind = 0; ind < info->num_inputs; ++ind) {
+ info->input_usage_mask[ind] |= usage_mask;
}
+ } else {
+ assert(ind >= 0);
+ assert(ind < PIPE_MAX_SHADER_INPUTS);
+ info->input_usage_mask[ind] |= usage_mask;
}
}
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
index 27de33f799..e75280336f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -45,6 +45,7 @@ struct tgsi_shader_info
ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
ubyte input_interpolate[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_usage_mask[PIPE_MAX_SHADER_INPUTS];
ubyte input_cylindrical_wrap[PIPE_MAX_SHADER_INPUTS];
ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */
ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
@@ -61,8 +62,6 @@ struct tgsi_shader_info
boolean writes_z; /**< does fragment shader write Z value? */
boolean writes_edgeflag; /**< vertex shader outputs edgeflag */
boolean uses_kill; /**< KIL or KILP instruction used? */
- boolean uses_fogcoord; /**< fragment shader uses fog coord? */
- boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
struct {
unsigned name;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index d5061f8b51..785a9fb035 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -1244,16 +1244,9 @@ emit_sub(
make_xmm( xmm_src ) );
}
-
-
-
-
-
-
/**
* Register fetch.
*/
-
static void
emit_fetch(
struct x86_function *func,
@@ -1338,7 +1331,6 @@ emit_fetch(
/**
* Register store.
*/
-
static void
emit_store(
struct x86_function *func,
@@ -1455,7 +1447,6 @@ fetch_texel( struct tgsi_sampler **sampler,
/**
* High-level instruction translators.
*/
-
static void
emit_tex( struct x86_function *func,
const struct tgsi_full_instruction *inst,
@@ -1507,7 +1498,6 @@ emit_tex( struct x86_function *func,
get_temp( TEMP_R0, 3 ),
make_xmm( 3 ) );
-
if (projected) {
FETCH( func, *inst, 3, 0, 3 );
@@ -1535,7 +1525,6 @@ emit_tex( struct x86_function *func,
args[0] = get_temp( TEMP_R0, 0 );
args[1] = get_sampler_ptr( unit );
-
emit_func_call( func,
0,
args,
@@ -1569,7 +1558,8 @@ emit_kil(
/* This mask stores component bits that were already tested. Note that
* we test if the value is less than zero, so 1.0 and 0.0 need not to be
- * tested. */
+ * tested.
+ */
uniquemask = 0;
FOR_EACH_CHANNEL( chan_index ) {
@@ -1715,22 +1705,26 @@ emit_cmp(
/**
- * Check if inst src/dest regs use indirect addressing into temporary
- * register file.
+ * Check if inst src/dest regs use indirect addressing into temporary,
+ * input or output register files.
*/
static boolean
-indirect_temp_reference(const struct tgsi_full_instruction *inst)
+indirect_reg_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->Src[i];
- if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+ if ((reg->Register.File == TGSI_FILE_TEMPORARY ||
+ reg->Register.File == TGSI_FILE_INPUT ||
+ reg->Register.File == TGSI_FILE_OUTPUT) &&
reg->Register.Indirect)
return TRUE;
}
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
const struct tgsi_full_dst_register *reg = &inst->Dst[i];
- if (reg->Register.File == TGSI_FILE_TEMPORARY &&
+ if ((reg->Register.File == TGSI_FILE_TEMPORARY ||
+ reg->Register.File == TGSI_FILE_INPUT ||
+ reg->Register.File == TGSI_FILE_OUTPUT) &&
reg->Register.Indirect)
return TRUE;
}
@@ -1746,7 +1740,7 @@ emit_instruction(
unsigned chan_index;
/* we can't handle indirect addressing into temp register file yet */
- if (indirect_temp_reference(inst))
+ if (indirect_reg_reference(inst))
return FALSE;
switch (inst->Instruction.Opcode) {
@@ -2931,7 +2925,6 @@ tgsi_emit_sse2(
x86_make_disp( get_machine_base(),
Offset( struct tgsi_exec_machine, Samplers ) ) );
-
while( !tgsi_parse_end_of_tokens( &parse ) && ok ) {
tgsi_parse_token( &parse );
@@ -3015,4 +3008,3 @@ tgsi_emit_sse2(
}
#endif /* PIPE_ARCH_X86 */
-
diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.c b/src/gallium/auxiliary/tgsi/tgsi_util.c
index 0a7e4105a8..3ec5496416 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_util.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_util.c
@@ -163,3 +163,149 @@ tgsi_util_set_full_src_register_sign_mode(
assert( 0 );
}
}
+
+/**
+ * Determine which channels of the specificed src register are effectively
+ * used by this instruction.
+ */
+unsigned
+tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
+ unsigned src_idx)
+{
+ const struct tgsi_full_src_register *src = &inst->Src[src_idx];
+ unsigned write_mask = inst->Dst[0].Register.WriteMask;
+ unsigned read_mask;
+ unsigned usage_mask;
+ unsigned chan;
+
+ switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_MOV:
+ case TGSI_OPCODE_ARL:
+ case TGSI_OPCODE_ARR:
+ case TGSI_OPCODE_RCP:
+ case TGSI_OPCODE_MUL:
+ case TGSI_OPCODE_DIV:
+ case TGSI_OPCODE_ADD:
+ case TGSI_OPCODE_MIN:
+ case TGSI_OPCODE_MAX:
+ case TGSI_OPCODE_SLT:
+ case TGSI_OPCODE_SGE:
+ case TGSI_OPCODE_MAD:
+ case TGSI_OPCODE_SUB:
+ case TGSI_OPCODE_LRP:
+ case TGSI_OPCODE_CND:
+ case TGSI_OPCODE_FRC:
+ case TGSI_OPCODE_CEIL:
+ case TGSI_OPCODE_CLAMP:
+ case TGSI_OPCODE_FLR:
+ case TGSI_OPCODE_ROUND:
+ case TGSI_OPCODE_POW:
+ case TGSI_OPCODE_ABS:
+ case TGSI_OPCODE_COS:
+ case TGSI_OPCODE_SIN:
+ case TGSI_OPCODE_DDX:
+ case TGSI_OPCODE_DDY:
+ case TGSI_OPCODE_SEQ:
+ case TGSI_OPCODE_SGT:
+ case TGSI_OPCODE_SLE:
+ case TGSI_OPCODE_SNE:
+ case TGSI_OPCODE_SSG:
+ case TGSI_OPCODE_CMP:
+ case TGSI_OPCODE_TRUNC:
+ case TGSI_OPCODE_NOT:
+ case TGSI_OPCODE_AND:
+ case TGSI_OPCODE_OR:
+ case TGSI_OPCODE_XOR:
+ case TGSI_OPCODE_SAD:
+ /* Channel-wise operations */
+ read_mask = write_mask;
+ break;
+
+ case TGSI_OPCODE_EX2:
+ case TGSI_OPCODE_LG2:
+ case TGSI_OPCODE_RCC:
+ read_mask = TGSI_WRITEMASK_X;
+ break;
+
+ case TGSI_OPCODE_SCS:
+ read_mask = write_mask & TGSI_WRITEMASK_XY ? TGSI_WRITEMASK_X : 0;
+ break;
+
+ case TGSI_OPCODE_EXP:
+ case TGSI_OPCODE_LOG:
+ read_mask = write_mask & TGSI_WRITEMASK_XYZ ? TGSI_WRITEMASK_X : 0;
+ break;
+
+ case TGSI_OPCODE_DP2A:
+ read_mask = src_idx == 2 ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_XY;
+ break;
+
+ case TGSI_OPCODE_DP2:
+ read_mask = TGSI_WRITEMASK_XY;
+ break;
+
+ case TGSI_OPCODE_DP3:
+ read_mask = TGSI_WRITEMASK_XYZ;
+ break;
+
+ case TGSI_OPCODE_DP4:
+ read_mask = TGSI_WRITEMASK_XYZW;
+ break;
+
+ case TGSI_OPCODE_DPH:
+ read_mask = src_idx == 0 ? TGSI_WRITEMASK_XYZ : TGSI_WRITEMASK_XYZW;
+ break;
+
+ case TGSI_OPCODE_TEX:
+ case TGSI_OPCODE_TXD:
+ case TGSI_OPCODE_TXB:
+ case TGSI_OPCODE_TXL:
+ case TGSI_OPCODE_TXP:
+ if (src_idx == 0) {
+ switch (inst->Texture.Texture) {
+ case TGSI_TEXTURE_1D:
+ case TGSI_TEXTURE_SHADOW1D:
+ read_mask = TGSI_WRITEMASK_X;
+ break;
+
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+ read_mask = TGSI_WRITEMASK_XY;
+ break;
+
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+ read_mask = TGSI_WRITEMASK_XYZ;
+ break;
+
+ default:
+ assert(0);
+ read_mask = 0;
+ }
+
+ if (inst->Instruction.Opcode != TGSI_OPCODE_TEX) {
+ read_mask |= TGSI_WRITEMASK_W;
+ }
+ } else {
+ /* A safe approximation */
+ read_mask = TGSI_WRITEMASK_XYZW;
+ }
+ break;
+
+ default:
+ /* Assume all channels are read */
+ read_mask = TGSI_WRITEMASK_XYZW;
+ break;
+ }
+
+ usage_mask = 0;
+ for (chan = 0; chan < 4; ++chan) {
+ if (read_mask & (1 << chan)) {
+ usage_mask |= 1 << tgsi_util_get_full_src_register_swizzle(src, chan);
+ }
+ }
+
+ return usage_mask;
+}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.h b/src/gallium/auxiliary/tgsi/tgsi_util.h
index 19ee2e7cf2..04702ba982 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_util.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_util.h
@@ -34,6 +34,7 @@ extern "C" {
struct tgsi_src_register;
struct tgsi_full_src_register;
+struct tgsi_full_instruction;
void *
tgsi_align_128bit(
@@ -71,6 +72,10 @@ tgsi_util_set_full_src_register_sign_mode(
struct tgsi_full_src_register *reg,
unsigned sign_mode );
+unsigned
+tgsi_util_get_inst_usage_mask(const struct tgsi_full_instruction *inst,
+ unsigned src_idx);
+
#if defined __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index d4fbd658f4..97fa99ec65 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -42,12 +42,10 @@
#include "util/u_blit.h"
#include "util/u_draw_quad.h"
-#include "util/u_format.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
#include "util/u_simple_shaders.h"
-#include "util/u_surface.h"
#include "cso_cache/cso_context.h"
@@ -136,7 +134,8 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
/* fragment shader */
ctx->fs[TGSI_WRITEMASK_XYZW] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+ util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@@ -476,6 +475,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
if (ctx->fs[writemask] == NULL)
ctx->fs[writemask] =
util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR,
writemask);
/* shaders */
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 9ae7b38e6e..183ffe5670 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -522,6 +522,26 @@ void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
return ctx->fs_col[num_cbufs];
}
+/** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */
+static unsigned
+pipe_tex_to_tgsi_tex(unsigned pipe_tex_target)
+{
+ switch (pipe_tex_target) {
+ case PIPE_TEXTURE_1D:
+ return TGSI_TEXTURE_1D;
+ case PIPE_TEXTURE_2D:
+ return TGSI_TEXTURE_2D;
+ case PIPE_TEXTURE_3D:
+ return TGSI_TEXTURE_3D;
+ case PIPE_TEXTURE_CUBE:
+ return TGSI_TEXTURE_CUBE;
+ default:
+ assert(0 && "unexpected texture target");
+ return TGSI_TEXTURE_UNKNOWN;
+ }
+}
+
+
static INLINE
void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
unsigned tex_target)
@@ -532,25 +552,10 @@ void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
/* Create the fragment shader on-demand. */
if (!ctx->fs_texfetch_col[tex_target]) {
- switch (tex_target) {
- case PIPE_TEXTURE_2D:
- ctx->fs_texfetch_col[PIPE_TEXTURE_2D] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
- break;
- case PIPE_TEXTURE_3D:
- ctx->fs_texfetch_col[PIPE_TEXTURE_3D] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D);
- break;
- case PIPE_TEXTURE_CUBE:
- ctx->fs_texfetch_col[PIPE_TEXTURE_CUBE] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
- break;
- case PIPE_TEXTURE_1D:
- default:
- ctx->fs_texfetch_col[PIPE_TEXTURE_1D] =
- util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D);
- tex_target = PIPE_TEXTURE_1D; /* for the default case */
- }
+ unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target);
+
+ ctx->fs_texfetch_col[tex_target] =
+ util_make_fragment_tex_shader(pipe, tgsi_tex, TGSI_INTERPOLATE_LINEAR);
}
return ctx->fs_texfetch_col[tex_target];
@@ -566,25 +571,11 @@ void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
/* Create the fragment shader on-demand. */
if (!ctx->fs_texfetch_depth[tex_target]) {
- switch (tex_target) {
- case PIPE_TEXTURE_2D:
- ctx->fs_texfetch_depth[PIPE_TEXTURE_2D] =
- util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D);
- break;
- case PIPE_TEXTURE_3D:
- ctx->fs_texfetch_depth[PIPE_TEXTURE_3D] =
- util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_3D);
- break;
- case PIPE_TEXTURE_CUBE:
- ctx->fs_texfetch_depth[PIPE_TEXTURE_CUBE] =
- util_make_fragment_tex_shader_writedepth(pipe,TGSI_TEXTURE_CUBE);
- break;
- case PIPE_TEXTURE_1D:
- default:
- ctx->fs_texfetch_depth[PIPE_TEXTURE_1D] =
- util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_1D);
- tex_target = PIPE_TEXTURE_1D; /* for the default case */
- }
+ unsigned tgsi_tex = pipe_tex_to_tgsi_tex(tex_target);
+
+ ctx->fs_texfetch_depth[tex_target] =
+ util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex,
+ TGSI_INTERPOLATE_LINEAR);
}
return ctx->fs_texfetch_depth[tex_target];
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index 86db2c2e4b..954f5706ef 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -42,6 +42,7 @@
#include "util/u_tile.h"
#include "util/u_prim.h"
+#include <limits.h> /* CHAR_BIT */
void _debug_vprintf(const char *format, va_list ap)
{
@@ -181,16 +182,21 @@ debug_get_flags_option(const char *name,
{
unsigned long result;
const char *str;
+ const struct debug_named_value *orig = flags;
+ int namealign = 0;
str = os_get_option(name);
if(!str)
result = dfault;
else if (!util_strcmp(str, "help")) {
result = dfault;
- while (flags->name) {
- debug_printf("%s: help for %s: %s [0x%lx]\n", __FUNCTION__, name, flags->name, flags->value);
- flags++;
- }
+ debug_printf("%s: help for %s:\n", __FUNCTION__, name);
+ for (; flags->name; ++flags)
+ namealign = MAX2(namealign, strlen(flags->name));
+ for (flags = orig; flags->name; ++flags)
+ debug_printf("| %*s [0x%0*lx]%s%s\n", namealign, flags->name,
+ sizeof(unsigned long)*CHAR_BIT/4, flags->value,
+ flags->desc ? " " : "", flags->desc ? flags->desc : "");
}
else {
result = 0;
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index e8ff2773e6..1c9624ea3e 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -230,6 +230,7 @@ struct debug_named_value
{
const char *name;
unsigned long value;
+ const char *desc;
};
@@ -252,8 +253,9 @@ struct debug_named_value
* ...
* @endcode
*/
-#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol}
-#define DEBUG_NAMED_VALUE_END {NULL, 0}
+#define DEBUG_NAMED_VALUE(__symbol) DEBUG_NAMED_VALUE_WITH_DESCRIPTION(__symbol, NULL)
+#define DEBUG_NAMED_VALUE_WITH_DESCRIPTION(__symbol, __desc) {#__symbol, (unsigned long)__symbol, __desc}
+#define DEBUG_NAMED_VALUE_END {NULL, 0, NULL}
/**
diff --git a/src/gallium/auxiliary/util/u_dl.h b/src/gallium/auxiliary/util/u_dl.h
index 2853b447c6..80a00ed679 100644
--- a/src/gallium/auxiliary/util/u_dl.h
+++ b/src/gallium/auxiliary/util/u_dl.h
@@ -35,10 +35,13 @@
#if defined(PIPE_OS_WINDOWS)
# define UTIL_DL_EXT ".dll"
+# define UTIL_DL_PREFIX ""
#elif defined(PIPE_OS_APPLE)
# define UTIL_DL_EXT ".dylib"
+# define UTIL_DL_PREFIX "lib"
#else
# define UTIL_DL_EXT ".so"
+# define UTIL_DL_PREFIX "lib"
#endif
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index d19267be72..b7fe2d3003 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1327,8 +1327,10 @@ util_create_gen_mipmap(struct pipe_context *pipe,
}
/* fragment shader */
- ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
- ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
+ ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR);
+ ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE,
+ TGSI_INTERPOLATE_LINEAR);
/* vertex data that doesn't change */
for (i = 0; i < 4; i++) {
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index d1ec13def3..6370e77986 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -168,6 +168,9 @@ static INLINE float logf( float f )
#undef logf
#define logf(x) ((float)log((double)(x)))
#endif /* logf */
+
+#define isfinite(x) _finite((double)(x))
+#define isnan(x) _isnan((double)(x))
#endif
static INLINE double log2( double x )
@@ -335,6 +338,15 @@ util_iround(float f)
}
+/**
+ * Approximate floating point comparison
+ */
+static INLINE boolean
+util_is_approx(float a, float b, float tol)
+{
+ return fabs(b - a) <= tol;
+}
+
/**
* Test if x is NaN or +/- infinity.
diff --git a/src/gallium/auxiliary/util/u_pointer.h b/src/gallium/auxiliary/util/u_pointer.h
index e1af9f11cb..ae6f43bff8 100644
--- a/src/gallium/auxiliary/util/u_pointer.h
+++ b/src/gallium/auxiliary/util/u_pointer.h
@@ -98,6 +98,18 @@ align16( void *unaligned )
return align_pointer( unaligned, 16 );
}
+typedef void (*func_pointer)(void);
+
+static INLINE func_pointer
+pointer_to_func( void *p )
+{
+ union {
+ void *p;
+ func_pointer f;
+ } pf;
+ pf.p = p;
+ return pf.f;
+}
#ifdef __cplusplus
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index 019dda767d..5b682f496c 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -87,10 +87,15 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
* MOV OUT[0], IMM[0] // (if writemask != 0xf)
* TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
* END;
+ *
+ * \param tex_target one of PIPE_TEXTURE_x
+ * \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE
+ * \param writemask mask of TGSI_WRITEMASK_x
*/
void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned tex_target,
+ unsigned interp_mode,
unsigned writemask )
{
struct ureg_program *ureg;
@@ -98,6 +103,9 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
struct ureg_src tex;
struct ureg_dst out;
+ assert(interp_mode == TGSI_INTERPOLATE_LINEAR ||
+ interp_mode == TGSI_INTERPOLATE_PERSPECTIVE);
+
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
if (ureg == NULL)
return NULL;
@@ -106,7 +114,7 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
tex = ureg_DECL_fs_input( ureg,
TGSI_SEMANTIC_GENERIC, 0,
- TGSI_INTERPOLATE_PERSPECTIVE );
+ interp_mode );
out = ureg_DECL_output( ureg,
TGSI_SEMANTIC_COLOR,
@@ -133,10 +141,12 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
* \param tex_target one of PIPE_TEXTURE_x
*/
void *
-util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
+ unsigned interp_mode)
{
return util_make_fragment_tex_shader_writemask( pipe,
tex_target,
+ interp_mode,
TGSI_WRITEMASK_XYZW );
}
@@ -147,7 +157,8 @@ util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
*/
void *
util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
- unsigned tex_target)
+ unsigned tex_target,
+ unsigned interp_mode)
{
struct ureg_program *ureg;
struct ureg_src sampler;
@@ -163,7 +174,7 @@ util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
tex = ureg_DECL_fs_input( ureg,
TGSI_SEMANTIC_GENERIC, 0,
- TGSI_INTERPOLATE_PERSPECTIVE );
+ interp_mode );
out = ureg_DECL_output( ureg,
TGSI_SEMANTIC_COLOR,
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 6e760942e2..4aa34bc475 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -52,15 +52,18 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
extern void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned tex_target,
+ unsigned interp_mode,
unsigned writemask);
extern void *
-util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target);
+util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target,
+ unsigned interp_mode);
extern void *
util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
- unsigned tex_target);
+ unsigned tex_target,
+ unsigned interp_mode);
extern void *
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
index e2c8602da0..411dce856a 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -287,7 +287,7 @@ This instruction replicates its result.
dst.w = src0.x \times src1.x + src0.y \times src1.y + src2.x
-.. opcode:: FRAC - Fraction
+.. opcode:: FRC - Fraction
.. math::
diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c
index 411f204f15..143eca848f 100644
--- a/src/gallium/drivers/cell/ppu/cell_context.c
+++ b/src/gallium/drivers/cell/ppu/cell_context.c
@@ -88,14 +88,14 @@ cell_draw_create(struct cell_context *cell)
static const struct debug_named_value cell_debug_flags[] = {
- {"checker", CELL_DEBUG_CHECKER},/**< modulate tile clear color by SPU ID */
- {"asm", CELL_DEBUG_ASM}, /**< dump SPU asm code */
- {"sync", CELL_DEBUG_SYNC}, /**< SPUs do synchronous DMA */
- {"fragops", CELL_DEBUG_FRAGMENT_OPS}, /**< SPUs emit fragment ops debug messages*/
- {"fragopfallback", CELL_DEBUG_FRAGMENT_OP_FALLBACK}, /**< SPUs use reference implementation for fragment ops*/
- {"cmd", CELL_DEBUG_CMD}, /**< SPUs dump command buffer info */
- {"cache", CELL_DEBUG_CACHE}, /**< report texture cache stats on exit */
- {NULL, 0}
+ {"checker", CELL_DEBUG_CHECKER, NULL},/**< modulate tile clear color by SPU ID */
+ {"asm", CELL_DEBUG_ASM, NULL}, /**< dump SPU asm code */
+ {"sync", CELL_DEBUG_SYNC, NULL}, /**< SPUs do synchronous DMA */
+ {"fragops", CELL_DEBUG_FRAGMENT_OPS, NULL}, /**< SPUs emit fragment ops debug messages*/
+ {"fragopfallback", CELL_DEBUG_FRAGMENT_OP_FALLBACK, NULL}, /**< SPUs use reference implementation for fragment ops*/
+ {"cmd", CELL_DEBUG_CMD, NULL}, /**< SPUs dump command buffer info */
+ {"cache", CELL_DEBUG_CACHE, NULL}, /**< report texture cache stats on exit */
+ DEBUG_NAMED_VALUE_END
};
static unsigned int
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index 3e2d0824ff..f82426520c 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -55,7 +55,7 @@ i915_get_name(struct pipe_screen *screen)
static char buffer[128];
const char *chipset;
- switch (i915_screen(screen)->pci_id) {
+ switch (i915_screen(screen)->iws->pci_id) {
case PCI_CHIP_I915_G:
chipset = "915G";
break;
@@ -280,14 +280,14 @@ i915_destroy_screen(struct pipe_screen *screen)
* Create a new i915_screen object
*/
struct pipe_screen *
-i915_create_screen(struct i915_winsys *iws, uint pci_id)
+i915_screen_create(struct i915_winsys *iws)
{
struct i915_screen *is = CALLOC_STRUCT(i915_screen);
if (!is)
return NULL;
- switch (pci_id) {
+ switch (iws->pci_id) {
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
is->is_i945 = FALSE;
@@ -304,12 +304,11 @@ i915_create_screen(struct i915_winsys *iws, uint pci_id)
default:
debug_printf("%s: unknown pci id 0x%x, cannot create screen\n",
- __FUNCTION__, pci_id);
+ __FUNCTION__, iws->pci_id);
FREE(is);
return NULL;
}
- is->pci_id = pci_id;
is->iws = iws;
is->base.winsys = NULL;
diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h
index 7f9e02fc0f..0c4186c68e 100644
--- a/src/gallium/drivers/i915/i915_screen.h
+++ b/src/gallium/drivers/i915/i915_screen.h
@@ -45,7 +45,6 @@ struct i915_screen
struct i915_winsys *iws;
boolean is_i945;
- uint pci_id;
};
/**
diff --git a/src/gallium/drivers/i915/i915_winsys.h b/src/gallium/drivers/i915/i915_winsys.h
index 8a6f579ad9..3aba19fe6a 100644
--- a/src/gallium/drivers/i915/i915_winsys.h
+++ b/src/gallium/drivers/i915/i915_winsys.h
@@ -81,6 +81,8 @@ struct i915_winsys_batchbuffer {
struct i915_winsys {
+ unsigned pci_id; /**< PCI ID for the device */
+
/**
* Batchbuffer functions.
*/
@@ -224,7 +226,7 @@ struct i915_winsys {
/**
* Create i915 pipe_screen.
*/
-struct pipe_screen *i915_create_screen(struct i915_winsys *iws, unsigned pci_id);
+struct pipe_screen *i915_screen_create(struct i915_winsys *iws);
#endif
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index 36b0eb6954..50a446db91 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -39,38 +39,38 @@
#ifdef DEBUG
static const struct debug_named_value debug_names[] = {
- { "tex", DEBUG_TEXTURE},
- { "state", DEBUG_STATE},
- { "ioctl", DEBUG_IOCTL},
- { "blit", DEBUG_BLIT},
- { "curbe", DEBUG_CURBE},
- { "fall", DEBUG_FALLBACKS},
- { "verb", DEBUG_VERBOSE},
- { "bat", DEBUG_BATCH},
- { "pix", DEBUG_PIXEL},
- { "wins", DEBUG_WINSYS},
- { "min", DEBUG_MIN_URB},
- { "dis", DEBUG_DISASSEM},
- { "sync", DEBUG_SYNC},
- { "prim", DEBUG_PRIMS },
- { "vert", DEBUG_VERTS },
- { "dma", DEBUG_DMA },
- { "san", DEBUG_SANITY },
- { "sleep", DEBUG_SLEEP },
- { "stats", DEBUG_STATS },
- { "sing", DEBUG_SINGLE_THREAD },
- { "thre", DEBUG_SINGLE_THREAD },
- { "wm", DEBUG_WM },
- { "urb", DEBUG_URB },
- { "vs", DEBUG_VS },
- { NULL, 0 }
+ { "tex", DEBUG_TEXTURE, NULL },
+ { "state", DEBUG_STATE, NULL },
+ { "ioctl", DEBUG_IOCTL, NULL },
+ { "blit", DEBUG_BLIT, NULL },
+ { "curbe", DEBUG_CURBE, NULL },
+ { "fall", DEBUG_FALLBACKS, NULL },
+ { "verb", DEBUG_VERBOSE, NULL },
+ { "bat", DEBUG_BATCH, NULL },
+ { "pix", DEBUG_PIXEL, NULL },
+ { "wins", DEBUG_WINSYS, NULL },
+ { "min", DEBUG_MIN_URB, NULL },
+ { "dis", DEBUG_DISASSEM, NULL },
+ { "sync", DEBUG_SYNC, NULL },
+ { "prim", DEBUG_PRIMS, NULL },
+ { "vert", DEBUG_VERTS, NULL },
+ { "dma", DEBUG_DMA, NULL },
+ { "san", DEBUG_SANITY, NULL },
+ { "sleep", DEBUG_SLEEP, NULL },
+ { "stats", DEBUG_STATS, NULL },
+ { "sing", DEBUG_SINGLE_THREAD, NULL },
+ { "thre", DEBUG_SINGLE_THREAD, NULL },
+ { "wm", DEBUG_WM, NULL },
+ { "urb", DEBUG_URB, NULL },
+ { "vs", DEBUG_VS, NULL },
+ DEBUG_NAMED_VALUE_END
};
static const struct debug_named_value dump_names[] = {
- { "asm", DUMP_ASM},
- { "state", DUMP_STATE},
- { "batch", DUMP_BATCH},
- { NULL, 0 }
+ { "asm", DUMP_ASM, NULL },
+ { "state", DUMP_STATE, NULL },
+ { "batch", DUMP_BATCH, NULL },
+ DEBUG_NAMED_VALUE_END
};
int BRW_DEBUG = 0;
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
index 9c874acded..8b5539d2c5 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -82,9 +82,10 @@ Requirements
- scons (optional)
- - udis86, http://udis86.sourceforge.net/ (optional):
+ - udis86, http://udis86.sourceforge.net/ (optional). My personal repository
+ supports more opcodes which haven't been merged upstream yet:
- git clone git://udis86.git.sourceforge.net/gitroot/udis86/udis86
+ git clone git://anongit.freedesktop.org/~jrfonseca/udis86
cd udis86
./autogen.sh
./configure --with-pic
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
index 838691e14b..90d2b26f9f 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
@@ -37,7 +37,7 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_math.h"
-#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
#include "gallivm/lp_bld_debug.h"
#include "gallivm/lp_bld_const.h"
#include "gallivm/lp_bld_arit.h"
@@ -75,6 +75,10 @@
*/
+static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
+static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
+
+
static void
attrib_name(LLVMValueRef val, unsigned attrib, unsigned chan, const char *suffix)
{
@@ -95,104 +99,143 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr)
{
- LLVMBuilderRef builder = bld->base.builder;
+ struct lp_build_context *coeff_bld = &bld->coeff_bld;
+ LLVMBuilderRef builder = coeff_bld->builder;
+ LLVMValueRef zero = LLVMConstNull(coeff_bld->elem_type);
+ LLVMValueRef one = LLVMConstReal(coeff_bld->elem_type, 1.0);
+ LLVMValueRef i0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ LLVMValueRef i1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
+ LLVMValueRef i2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
+ LLVMValueRef i3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+ LLVMValueRef oow = NULL;
unsigned attrib;
unsigned chan;
- for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+ /* TODO: Use more vector operations */
+
+ for (attrib = 0; attrib < bld->num_attribs; ++attrib) {
const unsigned mask = bld->mask[attrib];
const unsigned interp = bld->interp[attrib];
- for(chan = 0; chan < NUM_CHANNELS; ++chan) {
- if(mask & (1 << chan)) {
+ for (chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if (mask & (1 << chan)) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), attrib*NUM_CHANNELS + chan, 0);
- LLVMValueRef a0 = NULL;
- LLVMValueRef dadx = NULL;
- LLVMValueRef dady = NULL;
-
- switch( interp ) {
- case TGSI_INTERPOLATE_PERSPECTIVE:
+ LLVMValueRef a0 = zero;
+ LLVMValueRef dadx = zero;
+ LLVMValueRef dady = zero;
+ LLVMValueRef dadxy = zero;
+ LLVMValueRef dadq;
+ LLVMValueRef dadq2;
+ LLVMValueRef a;
+
+ switch (interp) {
+ case LP_INTERP_PERSPECTIVE:
/* fall-through */
- case TGSI_INTERPOLATE_LINEAR:
- dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
- dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
- dadx = lp_build_broadcast_scalar(&bld->base, dadx);
- dady = lp_build_broadcast_scalar(&bld->base, dady);
- attrib_name(dadx, attrib, chan, ".dadx");
- attrib_name(dady, attrib, chan, ".dady");
+ case LP_INTERP_LINEAR:
+ if (attrib == 0 && chan == 0) {
+ dadxy = dadx = one;
+ }
+ else if (attrib == 0 && chan == 1) {
+ dadxy = dady = one;
+ }
+ else {
+ dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
+ dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
+ dadxy = LLVMBuildAdd(builder, dadx, dady, "");
+ attrib_name(dadx, attrib, chan, ".dadx");
+ attrib_name(dady, attrib, chan, ".dady");
+ attrib_name(dadxy, attrib, chan, ".dadxy");
+ }
/* fall-through */
- case TGSI_INTERPOLATE_CONSTANT:
+ case LP_INTERP_CONSTANT:
+ case LP_INTERP_FACING:
a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), "");
- a0 = lp_build_broadcast_scalar(&bld->base, a0);
attrib_name(a0, attrib, chan, ".a0");
break;
+ case LP_INTERP_POSITION:
+ /* Nothing to do as the position coeffs are already setup in slot 0 */
+ continue;
+
default:
assert(0);
break;
}
- bld->a0 [attrib][chan] = a0;
- bld->dadx[attrib][chan] = dadx;
- bld->dady[attrib][chan] = dady;
- }
- }
- }
-}
+ /*
+ * dadq = {0, dadx, dady, dadx + dady}
+ */
+ dadq = coeff_bld->undef;
+ dadq = LLVMBuildInsertElement(builder, dadq, zero, i0, "");
+ dadq = LLVMBuildInsertElement(builder, dadq, dadx, i1, "");
+ dadq = LLVMBuildInsertElement(builder, dadq, dady, i2, "");
+ dadq = LLVMBuildInsertElement(builder, dadq, dadxy, i3, "");
-/**
- * Emit LLVM code to compute the fragment shader input attribute values.
- * For example, for a color input, we'll compute red, green, blue and alpha
- * values for the four pixels in a quad.
- * Recall that we're operating on 4-element vectors so each arithmetic
- * operation is operating on the four pixels in a quad.
- */
-static void
-attribs_init(struct lp_build_interp_soa_context *bld)
-{
- LLVMValueRef x = bld->pos[0];
- LLVMValueRef y = bld->pos[1];
- LLVMValueRef oow = NULL;
- unsigned attrib;
- unsigned chan;
+ /*
+ * dadq2 = 2 * dq
+ */
- for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
- const unsigned mask = bld->mask[attrib];
- const unsigned interp = bld->interp[attrib];
- for(chan = 0; chan < NUM_CHANNELS; ++chan) {
- if(mask & (1 << chan)) {
- LLVMValueRef a0 = bld->a0 [attrib][chan];
- LLVMValueRef dadx = bld->dadx[attrib][chan];
- LLVMValueRef dady = bld->dady[attrib][chan];
- LLVMValueRef res;
-
- res = a0;
-
- if (interp != TGSI_INTERPOLATE_CONSTANT) {
- /* res = res + x * dadx */
- res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, x, dadx));
- /* res = res + y * dady */
- res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, y, dady));
+ dadq2 = LLVMBuildAdd(builder, dadq, dadq, "");
+
+ /*
+ * a = a0 + x * dadx + y * dady
+ */
+
+ if (attrib == 0 && chan == 0) {
+ a = bld->x;
+ }
+ else if (attrib == 0 && chan == 1) {
+ a = bld->y;
+ }
+ else {
+ a = a0;
+ if (interp != LP_INTERP_CONSTANT &&
+ interp != LP_INTERP_FACING) {
+ a = LLVMBuildAdd(builder, a,
+ LLVMBuildMul(builder, bld->x, dadx, ""),
+ "");
+ a = LLVMBuildAdd(builder, a,
+ LLVMBuildMul(builder, bld->y, dady, ""),
+ "");
+ }
}
- /* Keep the value of the attribute before perspective divide
- * for faster updates.
+ /*
+ * a = {a, a, a, a}
+ */
+
+ a = lp_build_broadcast(builder, coeff_bld->vec_type, a);
+
+ /*
+ * Compute the attrib values on the upper-left corner of each quad.
+ */
+
+ a = LLVMBuildAdd(builder, a, dadq2, "");
+
+ /*
+ * a *= 1 / w
+ * dadq *= 1 / w
*/
- bld->attribs_pre[attrib][chan] = res;
- if (interp == TGSI_INTERPOLATE_PERSPECTIVE) {
- LLVMValueRef w = bld->pos[3];
+ if (interp == LP_INTERP_PERSPECTIVE) {
+ LLVMValueRef w = bld->a[0][3];
assert(attrib != 0);
- if(!oow)
- oow = lp_build_rcp(&bld->base, w);
- res = lp_build_mul(&bld->base, res, oow);
+ assert(bld->mask[0] & TGSI_WRITEMASK_W);
+ if (!oow) {
+ oow = lp_build_rcp(coeff_bld, w);
+ lp_build_name(oow, "oow");
+ }
+ a = lp_build_mul(coeff_bld, a, oow);
+ dadq = lp_build_mul(coeff_bld, dadq, oow);
}
- attrib_name(res, attrib, chan, "");
+ attrib_name(a, attrib, chan, ".a");
+ attrib_name(dadq, attrib, chan, ".dadq");
- bld->attribs[attrib][chan] = res;
+ bld->a [attrib][chan] = a;
+ bld->dadq[attrib][chan] = dadq;
}
}
}
@@ -206,7 +249,8 @@ attribs_init(struct lp_build_interp_soa_context *bld)
static void
attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
{
- LLVMValueRef oow = NULL;
+ struct lp_build_context *coeff_bld = &bld->coeff_bld;
+ LLVMValueRef shuffle = lp_build_const_int_vec(coeff_bld->type, quad_index);
unsigned attrib;
unsigned chan;
@@ -215,42 +259,36 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
const unsigned mask = bld->mask[attrib];
const unsigned interp = bld->interp[attrib];
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if(mask & (1 << chan)) {
+ LLVMValueRef a = coeff_bld->undef;
+ if (interp == LP_INTERP_CONSTANT ||
+ interp == LP_INTERP_FACING) {
+ a = bld->a[attrib][chan];
+ }
+ else if (interp == LP_INTERP_POSITION) {
+ assert(attrib > 0);
+ a = bld->attribs[0][chan];
+ }
+ else {
+ a = bld->a[attrib][chan];
- if (interp != TGSI_INTERPOLATE_CONSTANT) {
- for(chan = 0; chan < NUM_CHANNELS; ++chan) {
- if(mask & (1 << chan)) {
- LLVMValueRef dadx = bld->dadx[attrib][chan];
- LLVMValueRef dady = bld->dady[attrib][chan];
- LLVMValueRef res;
-
- res = bld->attribs_pre[attrib][chan];
+ /*
+ * Broadcast the attribute value for this quad into all elements
+ */
- if (quad_index == 1 || quad_index == 3) {
- /* top-right or bottom-right quad */
- /* build res = res + dadx + dadx */
- res = lp_build_add(&bld->base, res, dadx);
- res = lp_build_add(&bld->base, res, dadx);
- }
+ a = LLVMBuildShuffleVector(coeff_bld->builder,
+ a, coeff_bld->undef, shuffle, "");
- if (quad_index == 2 || quad_index == 3) {
- /* bottom-left or bottom-right quad */
- /* build res = res + dady + dady */
- res = lp_build_add(&bld->base, res, dady);
- res = lp_build_add(&bld->base, res, dady);
- }
-
- if (interp == TGSI_INTERPOLATE_PERSPECTIVE) {
- LLVMValueRef w = bld->pos[3];
- assert(attrib != 0);
- if(!oow)
- oow = lp_build_rcp(&bld->base, w);
- res = lp_build_mul(&bld->base, res, oow);
- }
+ /*
+ * Add the derivatives
+ */
- attrib_name(res, attrib, chan, "");
+ a = lp_build_add(coeff_bld, a, bld->dadq[attrib][chan]);
- bld->attribs[attrib][chan] = res;
+ attrib_name(a, attrib, chan, "");
}
+ bld->attribs[attrib][chan] = a;
}
}
}
@@ -260,53 +298,17 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
/**
* Generate the position vectors.
*
- * Parameter x0, y0 are the integer values with the quad upper left coordinates.
+ * Parameter x0, y0 are the integer values with upper left coordinates.
*/
static void
pos_init(struct lp_build_interp_soa_context *bld,
LLVMValueRef x0,
LLVMValueRef y0)
{
- lp_build_name(x0, "pos.x");
- lp_build_name(y0, "pos.y");
+ struct lp_build_context *coeff_bld = &bld->coeff_bld;
- bld->attribs[0][0] = x0;
- bld->attribs[0][1] = y0;
-}
-
-
-/**
- * Update quad position values when moving to the next quad.
- */
-static void
-pos_update(struct lp_build_interp_soa_context *bld, int quad_index)
-{
- LLVMValueRef x = bld->attribs[0][0];
- LLVMValueRef y = bld->attribs[0][1];
- const int xstep = 2, ystep = 2;
-
- if (quad_index == 1 || quad_index == 3) {
- /* top-right or bottom-right quad in block */
- /* build x += xstep */
- x = lp_build_add(&bld->base, x,
- lp_build_const_vec(bld->base.type, xstep));
- }
-
- if (quad_index == 2) {
- /* bottom-left quad in block */
- /* build y += ystep */
- y = lp_build_add(&bld->base, y,
- lp_build_const_vec(bld->base.type, ystep));
- /* build x -= xstep */
- x = lp_build_sub(&bld->base, x,
- lp_build_const_vec(bld->base.type, xstep));
- }
-
- lp_build_name(x, "pos.x");
- lp_build_name(y, "pos.y");
-
- bld->attribs[0][0] = x;
- bld->attribs[0][1] = y;
+ bld->x = LLVMBuildSIToFP(coeff_bld->builder, x0, coeff_bld->elem_type, "");
+ bld->y = LLVMBuildSIToFP(coeff_bld->builder, y0, coeff_bld->elem_type, "");
}
@@ -315,8 +317,8 @@ pos_update(struct lp_build_interp_soa_context *bld, int quad_index)
*/
void
lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
- const struct tgsi_token *tokens,
- boolean flatshade,
+ unsigned num_inputs,
+ const struct lp_shader_input *inputs,
LLVMBuilderRef builder,
struct lp_type type,
LLVMValueRef a0_ptr,
@@ -325,12 +327,22 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
LLVMValueRef x0,
LLVMValueRef y0)
{
- struct tgsi_parse_context parse;
- struct tgsi_full_declaration *decl;
+ struct lp_type coeff_type;
+ unsigned attrib;
+ unsigned chan;
memset(bld, 0, sizeof *bld);
- lp_build_context_init(&bld->base, builder, type);
+ memset(&coeff_type, 0, sizeof coeff_type);
+ coeff_type.floating = TRUE;
+ coeff_type.sign = TRUE;
+ coeff_type.width = 32;
+ coeff_type.length = QUAD_SIZE;
+
+ /* XXX: we don't support interpolating into any other types */
+ assert(memcmp(&coeff_type, &type, sizeof coeff_type) == 0);
+
+ lp_build_context_init(&bld->coeff_bld, builder, coeff_type);
/* For convenience */
bld->pos = bld->attribs[0];
@@ -338,58 +350,28 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
/* Position */
bld->num_attribs = 1;
- bld->mask[0] = TGSI_WRITEMASK_ZW;
- bld->interp[0] = TGSI_INTERPOLATE_LINEAR;
+ bld->mask[0] = TGSI_WRITEMASK_XYZW;
+ bld->interp[0] = LP_INTERP_LINEAR;
/* Inputs */
- tgsi_parse_init( &parse, tokens );
- while( !tgsi_parse_end_of_tokens( &parse ) ) {
- tgsi_parse_token( &parse );
-
- switch( parse.FullToken.Token.Type ) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- decl = &parse.FullToken.FullDeclaration;
- if( decl->Declaration.File == TGSI_FILE_INPUT ) {
- unsigned first, last, mask;
- unsigned attrib;
-
- first = decl->Range.First;
- last = decl->Range.Last;
- mask = decl->Declaration.UsageMask;
-
- for( attrib = first; attrib <= last; ++attrib ) {
- bld->mask[1 + attrib] = mask;
-
- /* XXX: have mesa set INTERP_CONSTANT in the fragment
- * shader.
- */
- if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
- flatshade)
- bld->interp[1 + attrib] = TGSI_INTERPOLATE_CONSTANT;
- else
- bld->interp[1 + attrib] = decl->Declaration.Interpolate;
- }
-
- bld->num_attribs = MAX2(bld->num_attribs, 1 + last + 1);
- }
- break;
-
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- case TGSI_TOKEN_TYPE_PROPERTY:
- break;
+ for (attrib = 0; attrib < num_inputs; ++attrib) {
+ bld->mask[1 + attrib] = inputs[attrib].usage_mask;
+ bld->interp[1 + attrib] = inputs[attrib].interp;
+ }
+ bld->num_attribs = 1 + num_inputs;
- default:
- assert( 0 );
+ /* Ensure all masked out input channels have a valid value */
+ for (attrib = 0; attrib < bld->num_attribs; ++attrib) {
+ for (chan = 0; chan < NUM_CHANNELS; ++chan) {
+ bld->attribs[attrib][chan] = bld->coeff_bld.undef;
}
}
- tgsi_parse_free( &parse );
-
- coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr);
pos_init(bld, x0, y0);
- attribs_init(bld);
+ coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr);
+
+ attribs_update(bld, 0);
}
@@ -402,7 +384,5 @@ lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld,
{
assert(quad_index < 4);
- pos_update(bld, quad_index);
-
attribs_update(bld, quad_index);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
index 99a432957c..2905513301 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
@@ -46,25 +46,23 @@
#include "tgsi/tgsi_exec.h"
-
-
-struct tgsi_token;
+#include "lp_setup.h"
struct lp_build_interp_soa_context
{
- struct lp_build_context base;
+ /* QUAD_SIZE x float */
+ struct lp_build_context coeff_bld;
unsigned num_attribs;
unsigned mask[1 + PIPE_MAX_SHADER_INPUTS]; /**< TGSI_WRITE_MASK_x */
- unsigned interp[1 + PIPE_MAX_SHADER_INPUTS]; /**< TGSI_INTERPOLATE_x */
+ enum lp_interp interp[1 + PIPE_MAX_SHADER_INPUTS];
- LLVMValueRef a0 [1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
- LLVMValueRef dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
- LLVMValueRef dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ LLVMValueRef x;
+ LLVMValueRef y;
- /* Attribute values before perspective divide */
- LLVMValueRef attribs_pre[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ LLVMValueRef a [1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ LLVMValueRef dadq[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
LLVMValueRef attribs[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
@@ -78,15 +76,15 @@ struct lp_build_interp_soa_context
void
lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
- const struct tgsi_token *tokens,
- boolean flatshade,
+ unsigned num_inputs,
+ const struct lp_shader_input *inputs,
LLVMBuilderRef builder,
struct lp_type type,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr,
- LLVMValueRef x0,
- LLVMValueRef y0);
+ LLVMValueRef x,
+ LLVMValueRef y);
void
lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld,
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
index de7fe7a179..689265fa30 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.h
+++ b/src/gallium/drivers/llvmpipe/lp_context.h
@@ -37,6 +37,7 @@
#include "lp_tex_sample.h"
#include "lp_jit.h"
+#include "lp_setup.h"
struct llvmpipe_vbuf_render;
@@ -90,6 +91,10 @@ struct llvmpipe_context {
/** Vertex format */
struct vertex_info vertex_info;
+ /** Fragment shader input interpolation info */
+ unsigned num_inputs;
+ struct lp_shader_input inputs[PIPE_MAX_SHADER_INPUTS];
+
/** The tiling engine */
struct lp_setup_context *setup;
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index 8dee041301..8d06e65725 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -169,36 +169,6 @@ typedef void
uint32_t *counter);
-/** cast wrapper to avoid compiler warnings */
-static INLINE lp_jit_frag_func
-cast_voidptr_to_lp_jit_frag_func(void *v)
-{
- union {
- void *v;
- lp_jit_frag_func f;
- } u;
- assert(sizeof(u.v) == sizeof(u.f));
- u.v = v;
- return u.f;
-}
-
-
-/** cast wrapper */
-static INLINE void *
-cast_lp_jit_frag_func_to_voidptr(lp_jit_frag_func f)
-{
- union {
- void *v;
- lp_jit_frag_func f;
- } u;
- assert(sizeof(u.v) == sizeof(u.f));
- u.f = f;
- return u.v;
-}
-
-
-
-
void
lp_jit_screen_cleanup(struct llvmpipe_screen *screen);
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
index 080e169ea1..c486442286 100644
--- a/src/gallium/drivers/llvmpipe/lp_query.c
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -39,7 +39,6 @@
#include "lp_rast.h"
#include "lp_rast_priv.h"
#include "lp_state.h"
-#include "lp_setup_context.h"
static struct llvmpipe_query *llvmpipe_query( struct pipe_query *p )
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c
index 2280c71c36..50e44dcb2b 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -61,16 +61,12 @@ lp_rast_begin( struct lp_rasterizer *rast,
for (i = 0; i < rast->state.nr_cbufs; i++) {
struct pipe_surface *cbuf = scene->fb.cbufs[i];
- rast->cbuf[i].format = cbuf->texture->format;
- rast->cbuf[i].tiles_per_row = align(cbuf->width, TILE_SIZE) / TILE_SIZE;
- rast->cbuf[i].blocksize =
- util_format_get_blocksize(cbuf->texture->format);
- rast->cbuf[i].map = llvmpipe_resource_map(cbuf->texture,
- cbuf->face,
- cbuf->level,
- cbuf->zslice,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_NONE);
+ llvmpipe_resource_map(cbuf->texture,
+ cbuf->face,
+ cbuf->level,
+ cbuf->zslice,
+ LP_TEX_USAGE_READ_WRITE,
+ LP_TEX_LAYOUT_NONE);
}
if (fb->zsbuf) {
@@ -105,7 +101,6 @@ lp_rast_end( struct lp_rasterizer *rast )
cbuf->face,
cbuf->level,
cbuf->zslice);
- rast->cbuf[i].map = NULL;
}
/* Unmap z/stencil buffer */
@@ -428,6 +423,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
struct lp_rasterizer *rast = task->rast;
const struct lp_rast_state *state = task->current_state;
const struct lp_rast_shader_inputs *inputs = arg.shade_tile;
+ struct lp_fragment_shader_variant *variant = state->variant;
const unsigned tile_x = task->x, tile_y = task->y;
unsigned x, y;
@@ -449,7 +445,7 @@ lp_rast_shade_tile(struct lp_rasterizer_task *task,
depth = lp_rast_get_depth_block_pointer(rast, tile_x + x, tile_y + y);
/* run shader on 4x4 block */
- state->jit_function[RAST_WHOLE]( &state->jit_context,
+ variant->jit_function[RAST_WHOLE]( &state->jit_context,
tile_x + x, tile_y + y,
inputs->facing,
inputs->a0,
@@ -476,6 +472,7 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
int32_t c1, int32_t c2, int32_t c3)
{
const struct lp_rast_state *state = task->current_state;
+ struct lp_fragment_shader_variant *variant = state->variant;
struct lp_rasterizer *rast = task->rast;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
void *depth;
@@ -507,7 +504,7 @@ void lp_rast_shade_quads( struct lp_rasterizer_task *task,
assert(lp_check_alignment(inputs->step[2], 16));
/* run shader on 4x4 block */
- state->jit_function[RAST_EDGE_TEST]( &state->jit_context,
+ variant->jit_function[RAST_EDGE_TEST]( &state->jit_context,
x, y,
inputs->facing,
inputs->a0,
@@ -582,18 +579,20 @@ outline_subtiles(uint8_t *tile)
static void
lp_rast_tile_end(struct lp_rasterizer_task *task)
{
-#if DEBUG
- struct lp_rasterizer *rast = task->rast;
- unsigned buf;
-
- for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
- uint8_t *color = lp_rast_get_color_block_pointer(task, buf,
- task->x, task->y);
-
- if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
- outline_subtiles(color);
- else if (LP_DEBUG & DEBUG_SHOW_TILES)
- outline_tile(color);
+#ifdef DEBUG
+ if (LP_DEBUG & (DEBUG_SHOW_SUBTILES | DEBUG_SHOW_TILES)) {
+ struct lp_rasterizer *rast = task->rast;
+ unsigned buf;
+
+ for (buf = 0; buf < rast->state.nr_cbufs; buf++) {
+ uint8_t *color = lp_rast_get_color_block_pointer(task, buf,
+ task->x, task->y);
+
+ if (LP_DEBUG & DEBUG_SHOW_SUBTILES)
+ outline_subtiles(color);
+ else if (LP_DEBUG & DEBUG_SHOW_TILES)
+ outline_tile(color);
+ }
}
#else
(void) outline_subtiles;
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.h b/src/gallium/drivers/llvmpipe/lp_rast.h
index 757009d13f..80ca68f5a2 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast.h
@@ -66,13 +66,9 @@ struct lp_rast_state {
struct lp_jit_context jit_context;
/* The shader itself. Probably we also need to pass a pointer to
- * the tile color/z/stencil data somehow:
- * jit_function[0] skips the triangle in/out test code
- * jit_function[1] does triangle in/out testing
+ * the tile color/z/stencil data somehow
*/
- lp_jit_frag_func jit_function[2];
-
- boolean opaque;
+ struct lp_fragment_shader_variant *variant;
};
diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
index efc013ff3f..d33dd49f3a 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h
+++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h
@@ -80,13 +80,6 @@ struct lp_rasterizer
/* Framebuffer stuff
*/
struct {
- void *map;
- unsigned tiles_per_row;
- unsigned blocksize;
- enum pipe_format format;
- } cbuf[PIPE_MAX_COLOR_BUFS];
-
- struct {
uint8_t *map;
unsigned stride;
unsigned blocksize;
@@ -205,6 +198,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
{
struct lp_rasterizer *rast = task->rast;
const struct lp_rast_state *state = task->current_state;
+ struct lp_fragment_shader_variant *variant = state->variant;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
void *depth;
unsigned i;
@@ -216,7 +210,7 @@ lp_rast_shade_quads_all( struct lp_rasterizer_task *task,
depth = lp_rast_get_depth_block_pointer(rast, x, y);
/* run shader on 4x4 block */
- state->jit_function[RAST_WHOLE]( &state->jit_context,
+ variant->jit_function[RAST_WHOLE]( &state->jit_context,
x, y,
inputs->facing,
inputs->a0,
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index e24b86d938..2fc5d6ecff 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -50,17 +50,17 @@
int LP_DEBUG = 0;
static const struct debug_named_value lp_debug_flags[] = {
- { "pipe", DEBUG_PIPE },
- { "tgsi", DEBUG_TGSI },
- { "tex", DEBUG_TEX },
- { "setup", DEBUG_SETUP },
- { "rast", DEBUG_RAST },
- { "query", DEBUG_QUERY },
- { "screen", DEBUG_SCREEN },
- { "show_tiles", DEBUG_SHOW_TILES },
- { "show_subtiles", DEBUG_SHOW_SUBTILES },
- { "counters", DEBUG_COUNTERS },
- {NULL, 0}
+ { "pipe", DEBUG_PIPE, NULL },
+ { "tgsi", DEBUG_TGSI, NULL },
+ { "tex", DEBUG_TEX, NULL },
+ { "setup", DEBUG_SETUP, NULL },
+ { "rast", DEBUG_RAST, NULL },
+ { "query", DEBUG_QUERY, NULL },
+ { "screen", DEBUG_SCREEN, NULL },
+ { "show_tiles", DEBUG_SHOW_TILES, NULL },
+ { "show_subtiles", DEBUG_SHOW_SUBTILES, NULL },
+ { "counters", DEBUG_COUNTERS, NULL },
+ DEBUG_NAMED_VALUE_END
};
#endif
@@ -220,7 +220,8 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
if (!format_desc)
return FALSE;
- assert(target == PIPE_TEXTURE_1D ||
+ assert(target == PIPE_BUFFER ||
+ target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
target == PIPE_TEXTURE_3D ||
target == PIPE_TEXTURE_CUBE);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index 1970173af4..8556dc87b4 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -472,18 +472,14 @@ lp_setup_set_fs_inputs( struct lp_setup_context *setup,
}
void
-lp_setup_set_fs_functions( struct lp_setup_context *setup,
- lp_jit_frag_func jit_function0,
- lp_jit_frag_func jit_function1,
- boolean opaque )
+lp_setup_set_fs_variant( struct lp_setup_context *setup,
+ struct lp_fragment_shader_variant *variant)
{
LP_DBG(DEBUG_SETUP, "%s %p\n", __FUNCTION__,
- cast_lp_jit_frag_func_to_voidptr(jit_function0));
+ variant);
/* FIXME: reference count */
- setup->fs.current.jit_function[0] = jit_function0;
- setup->fs.current.jit_function[1] = jit_function1;
- setup->fs.current.opaque = opaque;
+ setup->fs.current.variant = variant;
setup->dirty |= LP_SETUP_NEW_FS;
}
@@ -682,7 +678,7 @@ lp_setup_update_state( struct lp_setup_context *setup )
scene = lp_setup_get_current_scene(setup);
- assert(setup->fs.current.jit_function);
+ assert(setup->fs.current.variant);
/* Some of the 'draw' pipeline stages may have changed some driver state.
* Make sure we've processed those state changes before anything else.
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
index 10db03b9c6..6a0dc55129 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.h
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -41,8 +41,11 @@ enum lp_interp {
LP_INTERP_FACING
};
-/* Describes how to generate all the fragment shader inputs from the
- * the vertices passed into our triangle/line/point functions.
+
+/**
+ * Describes how to compute the interpolation coefficients (a0, dadx, dady)
+ * from the vertices passed into our triangle/line/point functions by the
+ * draw module.
*
* Vertices are treated as an array of float[4] values, indexed by
* src_index.
@@ -50,6 +53,7 @@ enum lp_interp {
struct lp_shader_input {
enum lp_interp interp; /* how to interpolate values */
unsigned src_index; /* where to find values in incoming vertices */
+ unsigned usage_mask; /* bitmask of TGSI_WRITEMASK_x flags */
};
struct pipe_resource;
@@ -58,7 +62,7 @@ struct pipe_surface;
struct pipe_blend_color;
struct pipe_screen;
struct pipe_framebuffer_state;
-struct lp_fragment_shader;
+struct lp_fragment_shader_variant;
struct lp_jit_context;
struct llvmpipe_query;
@@ -100,10 +104,8 @@ lp_setup_set_fs_inputs( struct lp_setup_context *setup,
unsigned nr );
void
-lp_setup_set_fs_functions( struct lp_setup_context *setup,
- lp_jit_frag_func jit_function0,
- lp_jit_frag_func jit_function1,
- boolean opaque );
+lp_setup_set_fs_variant( struct lp_setup_context *setup,
+ struct lp_fragment_shader_variant *variant );
void
lp_setup_set_fs_constants(struct lp_setup_context *setup,
diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
index 306cb6e27d..0557d35f8b 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c
@@ -34,6 +34,7 @@
#include "lp_perf.h"
#include "lp_setup_context.h"
#include "lp_rast.h"
+#include "lp_state_fs.h"
#define NUM_CHANNELS 4
@@ -146,20 +147,32 @@ setup_fragcoord_coef(struct lp_setup_context *setup,
unsigned slot,
const float (*v1)[4],
const float (*v2)[4],
- const float (*v3)[4])
+ const float (*v3)[4],
+ unsigned usage_mask)
{
/*X*/
- tri->inputs.a0[slot][0] = 0.0;
- tri->inputs.dadx[slot][0] = 1.0;
- tri->inputs.dady[slot][0] = 0.0;
+ if (usage_mask & TGSI_WRITEMASK_X) {
+ tri->inputs.a0[slot][0] = 0.0;
+ tri->inputs.dadx[slot][0] = 1.0;
+ tri->inputs.dady[slot][0] = 0.0;
+ }
+
/*Y*/
- tri->inputs.a0[slot][1] = 0.0;
- tri->inputs.dadx[slot][1] = 0.0;
- tri->inputs.dady[slot][1] = 1.0;
+ if (usage_mask & TGSI_WRITEMASK_Y) {
+ tri->inputs.a0[slot][1] = 0.0;
+ tri->inputs.dadx[slot][1] = 0.0;
+ tri->inputs.dady[slot][1] = 1.0;
+ }
+
/*Z*/
- linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 2);
+ if (usage_mask & TGSI_WRITEMASK_Z) {
+ linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 2);
+ }
+
/*W*/
- linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 3);
+ if (usage_mask & TGSI_WRITEMASK_W) {
+ linear_coef(setup, tri, oneoverarea, slot, v1, v2, v3, 0, 3);
+ }
}
@@ -170,13 +183,21 @@ setup_fragcoord_coef(struct lp_setup_context *setup,
static void setup_facing_coef( struct lp_setup_context *setup,
struct lp_rast_triangle *tri,
unsigned slot,
- boolean frontface )
+ boolean frontface,
+ unsigned usage_mask)
{
/* convert TRUE to 1.0 and FALSE to -1.0 */
- constant_coef( setup, tri, slot, 2.0f * frontface - 1.0f, 0 );
- constant_coef( setup, tri, slot, 0.0f, 1 ); /* wasted */
- constant_coef( setup, tri, slot, 0.0f, 2 ); /* wasted */
- constant_coef( setup, tri, slot, 0.0f, 3 ); /* wasted */
+ if (usage_mask & TGSI_WRITEMASK_X)
+ constant_coef( setup, tri, slot, 2.0f * frontface - 1.0f, 0 );
+
+ if (usage_mask & TGSI_WRITEMASK_Y)
+ constant_coef( setup, tri, slot, 0.0f, 1 ); /* wasted */
+
+ if (usage_mask & TGSI_WRITEMASK_Z)
+ constant_coef( setup, tri, slot, 0.0f, 2 ); /* wasted */
+
+ if (usage_mask & TGSI_WRITEMASK_W)
+ constant_coef( setup, tri, slot, 0.0f, 3 ); /* wasted */
}
@@ -191,54 +212,65 @@ static void setup_tri_coefficients( struct lp_setup_context *setup,
const float (*v3)[4],
boolean frontface)
{
+ unsigned fragcoord_usage_mask = TGSI_WRITEMASK_XYZ;
unsigned slot;
- /* The internal position input is in slot zero:
- */
- setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v3);
-
/* setup interpolation for all the remaining attributes:
*/
for (slot = 0; slot < setup->fs.nr_inputs; slot++) {
unsigned vert_attr = setup->fs.input[slot].src_index;
+ unsigned usage_mask = setup->fs.input[slot].usage_mask;
unsigned i;
switch (setup->fs.input[slot].interp) {
case LP_INTERP_CONSTANT:
if (setup->flatshade_first) {
for (i = 0; i < NUM_CHANNELS; i++)
- constant_coef(setup, tri, slot+1, v1[vert_attr][i], i);
+ if (usage_mask & (1 << i))
+ constant_coef(setup, tri, slot+1, v1[vert_attr][i], i);
}
else {
for (i = 0; i < NUM_CHANNELS; i++)
- constant_coef(setup, tri, slot+1, v3[vert_attr][i], i);
+ if (usage_mask & (1 << i))
+ constant_coef(setup, tri, slot+1, v3[vert_attr][i], i);
}
break;
case LP_INTERP_LINEAR:
for (i = 0; i < NUM_CHANNELS; i++)
- linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+ if (usage_mask & (1 << i))
+ linear_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
break;
case LP_INTERP_PERSPECTIVE:
for (i = 0; i < NUM_CHANNELS; i++)
- perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+ if (usage_mask & (1 << i))
+ perspective_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3, vert_attr, i);
+ fragcoord_usage_mask |= TGSI_WRITEMASK_W;
break;
case LP_INTERP_POSITION:
- /* XXX: fix me - duplicates the values in slot zero.
+ /*
+ * The generated pixel interpolators will pick up the coeffs from
+ * slot 0, so all need to ensure that the usage mask is covers all
+ * usages.
*/
- setup_fragcoord_coef(setup, tri, oneoverarea, slot+1, v1, v2, v3);
+ fragcoord_usage_mask |= usage_mask;
break;
case LP_INTERP_FACING:
- setup_facing_coef(setup, tri, slot+1, frontface);
+ setup_facing_coef(setup, tri, slot+1, frontface, usage_mask);
break;
default:
assert(0);
}
}
+
+ /* The internal position input is in slot zero:
+ */
+ setup_fragcoord_coef(setup, tri, oneoverarea, 0, v1, v2, v3,
+ fragcoord_usage_mask);
}
@@ -272,12 +304,14 @@ alloc_triangle(struct lp_scene *scene, unsigned nr_inputs, unsigned *tri_size)
tri = lp_scene_alloc_aligned( scene, bytes, 16 );
- inputs = (char *) (tri + 1);
- tri->inputs.a0 = (float (*)[4]) inputs;
- tri->inputs.dadx = (float (*)[4]) (inputs + input_array_sz);
- tri->inputs.dady = (float (*)[4]) (inputs + 2 * input_array_sz);
+ if (tri) {
+ inputs = (char *) (tri + 1);
+ tri->inputs.a0 = (float (*)[4]) inputs;
+ tri->inputs.dadx = (float (*)[4]) (inputs + input_array_sz);
+ tri->inputs.dady = (float (*)[4]) (inputs + 2 * input_array_sz);
- *tri_size = bytes;
+ *tri_size = bytes;
+ }
return tri;
}
@@ -341,6 +375,8 @@ do_triangle_ccw(struct lp_setup_context *setup,
print_triangle(setup, v1, v2, v3);
tri = alloc_triangle(scene, setup->fs.nr_inputs, &tri_bytes);
+ if (!tri)
+ return;
#ifdef DEBUG
tri->v[0][0] = v1[0][0];
@@ -575,7 +611,7 @@ do_triangle_ccw(struct lp_setup_context *setup,
/* triangle covers the whole tile- shade whole tile */
LP_COUNT(nr_fully_covered_64);
in = TRUE;
- if(setup->fs.current.opaque) {
+ if (setup->fs.current.variant->opaque) {
lp_scene_bin_reset( scene, x, y );
lp_scene_bin_command( scene, x, y,
lp_rast_set_state,
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
index bae5de0cb3..c268f96647 100644
--- a/src/gallium/drivers/llvmpipe/lp_state.h
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -32,10 +32,9 @@
#define LP_STATE_H
#include "pipe/p_state.h"
-#include "tgsi/tgsi_scan.h"
#include "lp_jit.h"
+#include "lp_state_fs.h"
#include "gallivm/lp_bld.h"
-#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */
#define LP_NEW_VIEWPORT 0x1
@@ -60,57 +59,6 @@ struct vertex_info;
struct pipe_context;
struct llvmpipe_context;
-struct lp_fragment_shader;
-
-
-/** Indexes into jit_function[] array */
-#define RAST_WHOLE 0
-#define RAST_EDGE_TEST 1
-
-
-struct lp_fragment_shader_variant_key
-{
- struct pipe_depth_state depth;
- struct pipe_stencil_state stencil[2];
- struct pipe_alpha_state alpha;
- struct pipe_blend_state blend;
- enum pipe_format zsbuf_format;
- unsigned nr_cbufs:8;
- unsigned flatshade:1;
- unsigned scissor:1;
- unsigned occlusion_count:1;
-
- struct {
- ubyte colormask;
- } cbuf_blend[PIPE_MAX_COLOR_BUFS];
-
- struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
-};
-
-
-struct lp_fragment_shader_variant
-{
- struct lp_fragment_shader_variant_key key;
-
- boolean opaque;
-
- LLVMValueRef function[2];
-
- lp_jit_frag_func jit_function[2];
-
- struct lp_fragment_shader_variant *next;
-};
-
-
-/** Subclass of pipe_shader_state */
-struct lp_fragment_shader
-{
- struct pipe_shader_state base;
-
- struct tgsi_shader_info info;
-
- struct lp_fragment_shader_variant *variants;
-};
/** Subclass of pipe_shader_state */
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index 2edfcb28ce..9e066f5c65 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -50,7 +50,7 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
{
const struct lp_fragment_shader *lpfs = llvmpipe->fs;
struct vertex_info *vinfo = &llvmpipe->vertex_info;
- struct lp_shader_input inputs[1 + PIPE_MAX_SHADER_INPUTS];
+ struct lp_shader_input *inputs = llvmpipe->inputs;
unsigned vs_index;
uint i;
@@ -77,6 +77,23 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
/* This can be pre-computed, except for flatshade:
*/
+ inputs[i].usage_mask = lpfs->info.input_usage_mask[i];
+
+ switch (lpfs->info.input_interpolate[i]) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ inputs[i].interp = LP_INTERP_CONSTANT;
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ inputs[i].interp = LP_INTERP_LINEAR;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ inputs[i].interp = LP_INTERP_PERSPECTIVE;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
switch (lpfs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_FACE:
inputs[i].interp = LP_INTERP_FACING;
@@ -95,25 +112,10 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
*/
if (llvmpipe->rasterizer->flatshade)
inputs[i].interp = LP_INTERP_CONSTANT;
- else
- inputs[i].interp = LP_INTERP_LINEAR;
break;
default:
- switch (lpfs->info.input_interpolate[i]) {
- case TGSI_INTERPOLATE_CONSTANT:
- inputs[i].interp = LP_INTERP_CONSTANT;
- break;
- case TGSI_INTERPOLATE_LINEAR:
- inputs[i].interp = LP_INTERP_LINEAR;
- break;
- case TGSI_INTERPOLATE_PERSPECTIVE:
- inputs[i].interp = LP_INTERP_PERSPECTIVE;
- break;
- default:
- assert(0);
- break;
- }
+ break;
}
/*
@@ -123,6 +125,7 @@ compute_vertex_info(struct llvmpipe_context *llvmpipe)
inputs[i].src_index = vinfo->num_attribs;
draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, vs_index);
}
+ llvmpipe->num_inputs = lpfs->info.num_inputs;
draw_compute_vertex_size(vinfo);
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 9ef78e6bad..6896bedf18 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -64,8 +64,10 @@
#include "pipe/p_defines.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
+#include "util/u_pointer.h"
#include "util/u_format.h"
#include "util/u_dump.h"
+#include "util/u_string.h"
#include "os/os_time.h"
#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
@@ -87,6 +89,7 @@
#include "lp_bld_depth.h"
#include "lp_bld_interp.h"
#include "lp_context.h"
+#include "lp_debug.h"
#include "lp_perf.h"
#include "lp_screen.h"
#include "lp_setup.h"
@@ -97,43 +100,7 @@
#include <llvm-c/Analysis.h>
-static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
-static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
-
-
-/*
- * Derive from the quad's upper left scalar coordinates the coordinates for
- * all other quad pixels
- */
-static void
-generate_pos0(LLVMBuilderRef builder,
- LLVMValueRef x,
- LLVMValueRef y,
- LLVMValueRef *x0,
- LLVMValueRef *y0)
-{
- LLVMTypeRef int_elem_type = LLVMInt32Type();
- LLVMTypeRef int_vec_type = LLVMVectorType(int_elem_type, QUAD_SIZE);
- LLVMTypeRef elem_type = LLVMFloatType();
- LLVMTypeRef vec_type = LLVMVectorType(elem_type, QUAD_SIZE);
- LLVMValueRef x_offsets[QUAD_SIZE];
- LLVMValueRef y_offsets[QUAD_SIZE];
- unsigned i;
-
- x = lp_build_broadcast(builder, int_vec_type, x);
- y = lp_build_broadcast(builder, int_vec_type, y);
-
- for(i = 0; i < QUAD_SIZE; ++i) {
- x_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_x[i], 0);
- y_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_y[i], 0);
- }
-
- x = LLVMBuildAdd(builder, x, LLVMConstVector(x_offsets, QUAD_SIZE), "");
- y = LLVMBuildAdd(builder, y, LLVMConstVector(y_offsets, QUAD_SIZE), "");
-
- *x0 = LLVMBuildSIToFP(builder, x, vec_type, "");
- *y0 = LLVMBuildSIToFP(builder, y, vec_type, "");
-}
+static unsigned fs_no = 0;
/**
@@ -614,6 +581,7 @@ generate_fragment(struct llvmpipe_context *lp,
{
struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
const struct lp_fragment_shader_variant_key *key = &variant->key;
+ char func_name[256];
struct lp_type fs_type;
struct lp_type blend_type;
LLVMTypeRef fs_elem_type;
@@ -633,8 +601,6 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMValueRef c0, c1, c2, step0_ptr, step1_ptr, step2_ptr, counter = NULL;
LLVMBasicBlockRef block;
LLVMBuilderRef builder;
- LLVMValueRef x0;
- LLVMValueRef y0;
struct lp_build_sampler_soa *sampler;
struct lp_build_interp_soa_context interp;
LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
@@ -676,6 +642,9 @@ generate_fragment(struct llvmpipe_context *lp,
blend_vec_type = lp_build_vec_type(blend_type);
+ util_snprintf(func_name, sizeof(func_name), "fs%u_variant%u_%s",
+ shader->no, variant->no, do_tri_test ? "edge" : "whole");
+
arg_types[0] = screen->context_ptr_type; /* context */
arg_types[1] = LLVMInt32Type(); /* x */
arg_types[2] = LLVMInt32Type(); /* y */
@@ -698,7 +667,7 @@ generate_fragment(struct llvmpipe_context *lp,
func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
- function = LLVMAddFunction(screen->module, "shader", func_type);
+ function = LLVMAddFunction(screen->module, func_name, func_type);
LLVMSetFunctionCallConv(function, LLVMCCallConv);
variant->function[do_tri_test] = function;
@@ -755,14 +724,17 @@ generate_fragment(struct llvmpipe_context *lp,
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
- generate_pos0(builder, x, y, &x0, &y0);
-
+ /*
+ * The shader input interpolation info is not explicitely baked in the
+ * shader key, but everything it derives from (TGSI, and flatshade) is
+ * already included in the shader key.
+ */
lp_build_interp_soa_init(&interp,
- shader->base.tokens,
- key->flatshade,
+ lp->num_inputs,
+ lp->inputs,
builder, fs_type,
a0_ptr, dadx_ptr, dady_ptr,
- x0, y0);
+ x, y);
/* code generated texture sampling */
sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
@@ -873,7 +845,7 @@ generate_fragment(struct llvmpipe_context *lp,
{
void *f = LLVMGetPointerToGlobal(screen->engine, function);
- variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f);
+ variant->jit_function[do_tri_test] = (lp_jit_frag_func)pointer_to_func(f);
if (gallivm_debug & GALLIVM_DEBUG_ASM) {
lp_disassemble(f);
@@ -960,17 +932,21 @@ generate_variant(struct llvmpipe_context *lp,
{
struct lp_fragment_shader_variant *variant;
- if (gallivm_debug & GALLIVM_DEBUG_IR) {
- tgsi_dump(shader->base.tokens, 0);
- dump_fs_variant_key(key);
- }
-
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
if(!variant)
return NULL;
+ variant->no = shader->variant_no++;
+
memcpy(&variant->key, key, sizeof *key);
+ if (gallivm_debug & GALLIVM_DEBUG_IR) {
+ debug_printf("llvmpipe: Creating fragment shader #%u variant #%u:\n",
+ shader->no, variant->no);
+ tgsi_dump(shader->base.tokens, 0);
+ dump_fs_variant_key(key);
+ }
+
generate_fragment(lp, shader, variant, RAST_WHOLE);
generate_fragment(lp, shader, variant, RAST_EDGE_TEST);
@@ -1004,15 +980,29 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
if (!shader)
return NULL;
+ shader->no = fs_no++;
+
/* get/save the summary info for this shader */
tgsi_scan_shader(templ->tokens, &shader->info);
/* we need to keep a local copy of the tokens */
shader->base.tokens = tgsi_dup_tokens(templ->tokens);
- if (gallivm_debug & GALLIVM_DEBUG_TGSI) {
- debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader);
+ if (LP_DEBUG & DEBUG_TGSI) {
+ unsigned attrib;
+ debug_printf("llvmpipe: Create fragment shader #%u %p:\n", shader->no, (void *) shader);
tgsi_dump(templ->tokens, 0);
+ debug_printf("usage masks:\n");
+ for (attrib = 0; attrib < shader->info.num_inputs; ++attrib) {
+ unsigned usage_mask = shader->info.input_usage_mask[attrib];
+ debug_printf(" IN[%u].%s%s%s%s\n",
+ attrib,
+ usage_mask & TGSI_WRITEMASK_X ? "x" : "",
+ usage_mask & TGSI_WRITEMASK_Y ? "y" : "",
+ usage_mask & TGSI_WRITEMASK_Z ? "z" : "",
+ usage_mask & TGSI_WRITEMASK_W ? "w" : "");
+ }
+ debug_printf("\n");
}
return shader;
@@ -1260,10 +1250,7 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */
}
- lp_setup_set_fs_functions(lp->setup,
- variant->jit_function[RAST_WHOLE],
- variant->jit_function[RAST_EDGE_TEST],
- variant->opaque);
+ lp_setup_set_fs_variant(lp->setup, variant);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.h b/src/gallium/drivers/llvmpipe/lp_state_fs.h
new file mode 100644
index 0000000000..64ead2a997
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.h
@@ -0,0 +1,100 @@
+/**************************************************************************
+ *
+ * Copyright 2010 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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_STATE_FS_H_
+#define LP_STATE_FS_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_scan.h" /* for tgsi_shader_info */
+#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */
+
+
+struct tgsi_token;
+struct lp_fragment_shader;
+
+
+/** Indexes into jit_function[] array */
+#define RAST_WHOLE 0
+#define RAST_EDGE_TEST 1
+
+
+struct lp_fragment_shader_variant_key
+{
+ struct pipe_depth_state depth;
+ struct pipe_stencil_state stencil[2];
+ struct pipe_alpha_state alpha;
+ struct pipe_blend_state blend;
+ enum pipe_format zsbuf_format;
+ unsigned nr_cbufs:8;
+ unsigned flatshade:1;
+ unsigned scissor:1;
+ unsigned occlusion_count:1;
+
+ struct {
+ ubyte colormask;
+ } cbuf_blend[PIPE_MAX_COLOR_BUFS];
+
+ struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
+};
+
+
+struct lp_fragment_shader_variant
+{
+ struct lp_fragment_shader_variant_key key;
+
+ boolean opaque;
+
+ LLVMValueRef function[2];
+
+ lp_jit_frag_func jit_function[2];
+
+ struct lp_fragment_shader_variant *next;
+
+ /* For debugging/profiling purposes */
+ unsigned no;
+};
+
+
+/** Subclass of pipe_shader_state */
+struct lp_fragment_shader
+{
+ struct pipe_shader_state base;
+
+ struct tgsi_shader_info info;
+
+ struct lp_fragment_shader_variant *variants;
+
+ /* For debugging/profiling purposes */
+ unsigned no;
+ unsigned variant_no;
+};
+
+
+#endif /* LP_STATE_FS_H_ */
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 072d699666..557eb8e3e6 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -805,7 +805,7 @@ test_all(unsigned verbose, FILE *fp)
struct pipe_blend_state blend;
enum vector_mode mode;
const struct lp_type *type;
- bool success = TRUE;
+ boolean success = TRUE;
for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
for(alpha_func = blend_funcs; alpha_func < &blend_funcs[num_funcs]; ++alpha_func) {
@@ -859,7 +859,7 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
enum vector_mode mode;
const struct lp_type *type;
unsigned long i;
- bool success = TRUE;
+ boolean success = TRUE;
for(i = 0; i < n; ++i) {
rgb_func = &blend_funcs[rand() % num_funcs];
diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c
index 254f0daea3..cb0d02ab32 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c
@@ -34,6 +34,7 @@
*/
+#include "util/u_pointer.h"
#include "gallivm/lp_bld_type.h"
#include "gallivm/lp_bld_const.h"
#include "gallivm/lp_bld_conv.h"
@@ -43,17 +44,6 @@
typedef void (*conv_test_ptr_t)(const void *src, const void *dst);
-/** cast wrapper */
-static conv_test_ptr_t
-voidptr_to_conv_test_ptr_t(void *p)
-{
- union {
- void *v;
- conv_test_ptr_t f;
- } u;
- u.v = p;
- return u.f;
-}
void
write_tsv_header(FILE *fp)
@@ -234,7 +224,7 @@ test_one(unsigned verbose,
LLVMDumpModule(module);
code = LLVMGetPointerToGlobal(engine, func);
- conv_test_ptr = voidptr_to_conv_test_ptr_t(code);
+ conv_test_ptr = (conv_test_ptr_t)pointer_to_func(code);
if(verbose >= 2)
lp_disassemble(code);
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
index e5f8bf9633..7c0d7d2e65 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_format.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -37,6 +37,7 @@
#include <llvm-c/Transforms/Scalar.h>
#include "util/u_memory.h"
+#include "util/u_pointer.h"
#include "util/u_format.h"
#include "util/u_format_tests.h"
#include "util/u_format_s3tc.h"
@@ -73,19 +74,6 @@ typedef void
(*fetch_ptr_t)(float *, const void *packed,
unsigned i, unsigned j);
-/** cast wrapper to avoid warnings */
-static fetch_ptr_t
-void_to_fetch_ptr_t(void *p)
-{
- union {
- void *v;
- fetch_ptr_t f;
- } u;
- u.v = p;
- return u.f;
-}
-
-
static LLVMValueRef
add_fetch_rgba_test(LLVMModuleRef lp_build_module,
@@ -162,7 +150,7 @@ test_format(unsigned verbose, FILE *fp,
(void)pass;
#endif
- fetch_ptr = void_to_fetch_ptr_t(LLVMGetPointerToGlobal(lp_build_engine, fetch));
+ fetch_ptr = (fetch_ptr_t)pointer_to_func(LLVMGetPointerToGlobal(lp_build_engine, fetch));
for (i = 0; i < desc->block.height; ++i) {
for (j = 0; j < desc->block.width; ++j) {
diff --git a/src/gallium/drivers/llvmpipe/lp_test_printf.c b/src/gallium/drivers/llvmpipe/lp_test_printf.c
index 13485c3774..d99ca81638 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_printf.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_printf.c
@@ -29,6 +29,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include "util/u_pointer.h"
#include "gallivm/lp_bld.h"
#include "gallivm/lp_bld_printf.h"
@@ -58,18 +59,6 @@ write_tsv_header(FILE *fp)
typedef void (*test_printf_t)(int i);
-/** cast wrapper */
-static test_printf_t
-voidptr_to_test_printf_t(void *p)
-{
- union {
- void *v;
- test_printf_t f;
- } u;
- u.v = p;
- return u.f;
-}
-
static LLVMValueRef
add_printf_test(LLVMModuleRef module)
@@ -140,7 +129,7 @@ test_printf(unsigned verbose, FILE *fp, const struct printf_test_case *testcase)
#endif
code = LLVMGetPointerToGlobal(engine, test);
- test_printf = voidptr_to_test_printf_t(code);
+ test_printf = (test_printf_t)pointer_to_func(code);
memset(unpacked, 0, sizeof unpacked);
packed = 0;
diff --git a/src/gallium/drivers/llvmpipe/lp_test_sincos.c b/src/gallium/drivers/llvmpipe/lp_test_sincos.c
index 386f852be0..da16fea7bd 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_sincos.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_sincos.c
@@ -60,7 +60,7 @@ write_tsv_header(FILE *fp)
typedef __m128 (*test_sincos_t)(__m128);
static LLVMValueRef
-add_sincos_test(LLVMModuleRef module, bool sin)
+add_sincos_test(LLVMModuleRef module, boolean sin)
{
LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
LLVMTypeRef args[1] = { v4sf };
@@ -185,7 +185,7 @@ test_sincos(unsigned verbose, FILE *fp)
boolean
test_all(unsigned verbose, FILE *fp)
{
- bool success = TRUE;
+ boolean success = TRUE;
test_sincos(verbose, fp);
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 5696683f45..d86056ca34 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -1045,6 +1045,7 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
lpr->tiles_per_row[level]);
}
else {
+ assert(layout == LP_TEX_LAYOUT_LINEAR);
lp_tiled_to_linear(other_data, target_data,
x * TILE_SIZE, y * TILE_SIZE,
TILE_SIZE, TILE_SIZE,
@@ -1054,8 +1055,9 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
}
}
- llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y,
- new_layout);
+ if (new_layout != cur_layout)
+ llvmpipe_set_texture_tile_layout(lpr, face_slice, level, x, y,
+ new_layout);
}
}
}
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index d3cd6bef96..6bb82e5ed0 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -21,6 +21,7 @@ C_SOURCES = \
r300_state_derived.c \
r300_state_invariant.c \
r300_vs.c \
+ r300_vs_draw.c \
r300_texture.c \
r300_tgsi_to_rc.c \
r300_transfer.c
diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript
index 3921085d76..eb3e1d365e 100644
--- a/src/gallium/drivers/r300/SConscript
+++ b/src/gallium/drivers/r300/SConscript
@@ -31,6 +31,7 @@ r300 = env.ConvenienceLibrary(
'r300_state_derived.c',
'r300_state_invariant.c',
'r300_vs.c',
+ 'r300_vs_draw.c',
'r300_texture.c',
'r300_tgsi_to_rc.c',
'r300_transfer.c',
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 85e45d8647..88ce186798 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -236,6 +236,14 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
return NULL;
}
+boolean r300_check_cs(struct r300_context *r300, unsigned size)
+{
+ struct r300_cs_info cs_info;
+
+ r300->rws->get_cs_info(r300->rws, &cs_info);
+ return size <= cs_info.free;
+}
+
void r300_finish(struct r300_context *r300)
{
struct pipe_framebuffer_state *fb;
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index efc6df3fab..48ec52d26c 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -36,9 +36,9 @@
struct u_upload_mgr;
struct r300_context;
-
struct r300_fragment_shader;
struct r300_vertex_shader;
+struct r300_stencilref_context;
struct r300_atom {
/* List pointers. */
@@ -86,7 +86,7 @@ struct r300_dsa_state {
/* Whether a two-sided stencil is enabled. */
boolean two_sided;
/* Whether a fallback should be used for a two-sided stencil ref value. */
- boolean stencil_ref_bf_fallback;
+ boolean two_sided_stencil_ref;
};
struct r300_rs_state {
@@ -272,6 +272,8 @@ struct r300_texture {
/* Parent class */
struct u_resource b;
+ enum r300_buffer_domain domain;
+
/* Offsets into the buffer. */
unsigned offset[R300_MAX_TEXTURE_LEVELS];
@@ -331,21 +333,6 @@ struct r300_context {
/* Parent class */
struct pipe_context context;
- /* Emission of drawing packets. */
- void (*emit_draw_arrays_immediate)(
- struct r300_context *r300,
- unsigned mode, unsigned start, unsigned count);
-
- void (*emit_draw_arrays)(
- struct r300_context *r300,
- unsigned mode, unsigned count);
-
- void (*emit_draw_elements)(
- struct r300_context *r300, struct pipe_resource* indexBuffer,
- unsigned indexSize, unsigned minIndex, unsigned maxIndex,
- unsigned mode, unsigned start, unsigned count);
-
-
/* The interface to the windowing system, etc. */
struct r300_winsys_screen *rws;
/* Screen. */
@@ -354,6 +341,8 @@ struct r300_context {
struct draw_context* draw;
/* Accelerated blit support. */
struct blitter_context* blitter;
+ /* Stencil two-sided reference value fallback. */
+ struct r300_stencilref_context *stencilref_fallback;
/* Vertex buffer for rendering. */
struct pipe_resource* vbo;
@@ -441,9 +430,6 @@ struct r300_context {
uint32_t zbuffer_bpp;
/* Whether rendering is conditional and should be skipped. */
boolean skip_rendering;
- /* Whether the two-sided stencil ref value is different for front and
- * back faces, and fallback should be used for r3xx-r4xx. */
- boolean stencil_ref_bf_fallback;
/* Point sprites texcoord index, 1 bit per texcoord */
int sprite_coord_enable;
/* Whether two-sided color selection is enabled (AKA light_twoside). */
@@ -490,6 +476,7 @@ void r300_init_render_functions(struct r300_context *r300);
void r300_init_state_functions(struct r300_context* r300);
void r300_init_resource_functions(struct r300_context* r300);
+boolean r300_check_cs(struct r300_context *r300, unsigned size);
void r300_finish(struct r300_context *r300);
void r500_dump_rs_block(struct r300_rs_block *rs);
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 996a4f491e..9c8c273902 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -37,11 +37,6 @@
#define VERY_VERBOSE_CS 1
#define VERY_VERBOSE_REGISTERS 1
-/* XXX stolen from radeon_drm.h */
-#define RADEON_GEM_DOMAIN_CPU 0x1
-#define RADEON_GEM_DOMAIN_GTT 0x2
-#define RADEON_GEM_DOMAIN_VRAM 0x4
-
/* XXX stolen from radeon_reg.h */
#define RADEON_CP_PACKET0 0x0
@@ -54,7 +49,7 @@
int cs_count = 0; (void) cs_count;
#define CHECK_CS(size) \
- assert(cs_winsys->check_cs(cs_winsys, (size)))
+ assert(r300_check_cs(cs_context_copy, (size)))
#define BEGIN_CS(size) do { \
CHECK_CS(size); \
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index 024731a22a..297791f3ff 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -22,16 +22,11 @@
#include "r300_context.h"
-#include <stdio.h>
+#include "util/u_debug.h"
-struct debug_option {
- const char * name;
- unsigned flag;
- const char * description;
-};
+#include <stdio.h>
-static struct debug_option debug_options[] = {
- { "help", DBG_HELP, "Helpful meta-information about the driver" },
+static const struct debug_named_value debug_options[] = {
{ "fp", DBG_FP, "Fragment program handling (for debugging)" },
{ "vp", DBG_VP, "Vertex program handling (for debugging)" },
{ "cs", DBG_CS, "Command submissions (for debugging)" },
@@ -46,57 +41,13 @@ static struct debug_option debug_options[] = {
{ "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" },
{ "stats", DBG_STATS, "Gather statistics (for lulz)" },
- { "all", ~0, "Convenience option that enables all debug flags" },
-
/* must be last */
- { 0, 0, 0 }
+ DEBUG_NAMED_VALUE_END
};
void r300_init_debug(struct r300_screen * screen)
{
- const char * options = debug_get_option("RADEON_DEBUG", 0);
- boolean printhint = FALSE;
- size_t length;
- struct debug_option * opt;
-
- if (options) {
- while(*options) {
- if (*options == ' ' || *options == ',') {
- options++;
- continue;
- }
-
- length = strcspn(options, " ,");
-
- for(opt = debug_options; opt->name; ++opt) {
- if (!strncmp(options, opt->name, length)) {
- screen->debug |= opt->flag;
- break;
- }
- }
-
- if (!opt->name) {
- fprintf(stderr, "Unknown debug option: %s\n", options);
- printhint = TRUE;
- }
-
- options += length;
- }
-
- if (!screen->debug)
- printhint = TRUE;
- }
-
- if (printhint || screen->debug & DBG_HELP) {
- fprintf(stderr, "You can enable debug output by setting "
- "the RADEON_DEBUG environment variable\n"
- "to a comma-separated list of debug options. "
- "Available options are:\n");
-
- for(opt = debug_options; opt->name; ++opt) {
- fprintf(stderr, " %s: %s\n", opt->name, opt->description);
- }
- }
+ screen->debug = debug_get_flags_option("RADEON_DEBUG", debug_options, 0);
}
void r500_dump_rs_block(struct r300_rs_block *rs)
diff --git a/src/gallium/drivers/r300/r300_defines.h b/src/gallium/drivers/r300/r300_defines.h
index 98ee3c1ede..83c9ec7e39 100644
--- a/src/gallium/drivers/r300/r300_defines.h
+++ b/src/gallium/drivers/r300/r300_defines.h
@@ -30,6 +30,8 @@
#define R300_RESOURCE_FLAG_TRANSFER PIPE_RESOURCE_FLAG_DRV_PRIV
+#define R300_INVALID_FORMAT (~0)
+
/* XXX: this is just a bandaid on larger problems in
* r300_screen_buffer.h which doesn't seem to be fully ported to
* gallium-resources.
@@ -43,4 +45,9 @@ enum r300_buffer_tiling {
R300_BUFFER_SQUARETILED
};
+enum r300_buffer_domain { /* bitfield */
+ R300_DOMAIN_GTT = 1,
+ R300_DOMAIN_VRAM = 2
+};
+
#endif
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 7f7f2929cc..55c6ce5030 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -134,7 +134,6 @@ static const float * get_rc_constant_state(
struct r300_context * r300,
struct rc_constant * constant)
{
- struct r300_viewport_state* viewport = r300->viewport_state.state;
struct r300_textures_state* texstate = r300->textures_state.state;
static float vec[4] = { 0.0, 0.0, 0.0, 1.0 };
struct pipe_resource *tex;
@@ -151,15 +150,15 @@ static const float * get_rc_constant_state(
break;
case RC_STATE_R300_VIEWPORT_SCALE:
- vec[0] = viewport->xscale;
- vec[1] = viewport->yscale;
- vec[2] = viewport->zscale;
+ vec[0] = r300->viewport.scale[0];
+ vec[1] = r300->viewport.scale[1];
+ vec[2] = r300->viewport.scale[2];
break;
case RC_STATE_R300_VIEWPORT_OFFSET:
- vec[0] = viewport->xoffset;
- vec[1] = viewport->yoffset;
- vec[2] = viewport->zoffset;
+ vec[0] = r300->viewport.translate[0];
+ vec[1] = r300->viewport.translate[1];
+ vec[2] = r300->viewport.translate[2];
break;
default:
@@ -486,11 +485,11 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
- OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_TEX_RELOC(tex, surf->offset, 0, tex->domain, 0);
OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level],
- 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ 0, tex->domain, 0);
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt);
}
@@ -505,13 +504,13 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
- OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_TEX_RELOC(tex, surf->offset, 0, tex->domain, 0);
OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format);
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level],
- 0, RADEON_GEM_DOMAIN_VRAM, 0);
+ 0, tex->domain, 0);
}
OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
@@ -571,13 +570,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
- 0, RADEON_GEM_DOMAIN_GTT, 0);
+ 0, r300_buffer(r300->oqbo)->domain, 0);
case 3:
/* pipe 2 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
- 0, RADEON_GEM_DOMAIN_GTT, 0);
+ 0, r300_buffer(r300->oqbo)->domain, 0);
case 2:
/* pipe 1 only */
/* As mentioned above, accomodate RV380 and older. */
@@ -585,13 +584,13 @@ static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
1 << (caps->high_second_pipe ? 3 : 1));
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
- 0, RADEON_GEM_DOMAIN_GTT, 0);
+ 0, r300_buffer(r300->oqbo)->domain, 0);
case 1:
/* pipe 0 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
- 0, RADEON_GEM_DOMAIN_GTT, 0);
+ 0, r300_buffer(r300->oqbo)->domain, 0);
break;
default:
fprintf(stderr, "r300: Implementation error: Chipset reports %d"
@@ -612,7 +611,7 @@ static void rv530_emit_query_end_single_z(struct r300_context *r300,
BEGIN_CS(8);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, r300_buffer(r300->oqbo)->domain, 0);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -625,10 +624,10 @@ static void rv530_emit_query_end_double_z(struct r300_context *r300,
BEGIN_CS(14);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, r300_buffer(r300->oqbo)->domain, 0);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, r300_buffer(r300->oqbo)->domain, 0);
OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
END_CS;
}
@@ -787,6 +786,7 @@ void r300_emit_textures_state(struct r300_context *r300,
{
struct r300_textures_state *allstate = (struct r300_textures_state*)state;
struct r300_texture_sampler_state *texstate;
+ struct r300_texture *tex;
unsigned i;
CS_LOCALS(r300);
@@ -796,6 +796,7 @@ void r300_emit_textures_state(struct r300_context *r300,
for (i = 0; i < allstate->count; i++) {
if ((1 << i) & allstate->tx_enable) {
texstate = &allstate->regs[i];
+ tex = r300_texture(allstate->sampler_views[i]->base.texture);
OUT_CS_REG(R300_TX_FILTER0_0 + (i * 4), texstate->filter0);
OUT_CS_REG(R300_TX_FILTER1_0 + (i * 4), texstate->filter1);
@@ -807,9 +808,8 @@ void r300_emit_textures_state(struct r300_context *r300,
OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format.format2);
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_CS_TEX_RELOC(r300_texture(allstate->sampler_views[i]->base.texture),
- texstate->format.tile_config,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ OUT_CS_TEX_RELOC(tex, texstate->format.tile_config, tex->domain,
+ 0, 0);
}
}
END_CS;
@@ -819,6 +819,7 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset, boolean indexed)
{
struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->velems->velem;
+ struct r300_buffer *buf;
int i;
unsigned size1, size2, aos_count = r300->velems->count;
unsigned packet_size = (aos_count * 3 + 1) / 2;
@@ -858,13 +859,13 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset, boolean indexed)
}
for (i = 0; i < aos_count; i++) {
- OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
+ buf = r300_buffer(vbuf[velem[i].vertex_buffer_index].buffer);
+ OUT_CS_BUF_RELOC_NO_OFFSET(&buf->b.b, buf->domain, 0, 0);
}
END_CS;
}
-void r300_emit_vertex_buffer(struct r300_context* r300)
+void r300_emit_aos_swtcl(struct r300_context *r300, boolean indexed)
{
CS_LOCALS(r300);
@@ -880,11 +881,11 @@ void r300_emit_vertex_buffer(struct r300_context* r300)
*/
BEGIN_CS(7);
OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3);
- OUT_CS(1);
+ OUT_CS(1 | (!indexed ? R300_VC_FORCE_PREFETCH : 0));
OUT_CS(r300->vertex_info.size |
(r300->vertex_info.size << 8));
OUT_CS(r300->vbo_offset);
- OUT_CS_BUF_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ OUT_CS_BUF_RELOC(r300->vbo, 0, r300_buffer(r300->vbo)->domain, 0, 0);
END_CS;
}
@@ -1057,7 +1058,7 @@ void r300_emit_buffer_validate(struct r300_context *r300,
boolean invalid = FALSE;
/* upload buffers first */
- if (r300->any_user_vbs) {
+ if (r300->screen->caps.has_tcl && r300->any_user_vbs) {
r300_upload_user_buffers(r300);
r300->any_user_vbs = false;
}
@@ -1070,8 +1071,7 @@ validate:
for (i = 0; i < fb->nr_cbufs; i++) {
tex = r300_texture(fb->cbufs[i]->texture);
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- if (!r300_add_texture(r300->rws, tex,
- 0, RADEON_GEM_DOMAIN_VRAM)) {
+ if (!r300_add_texture(r300->rws, tex, 0, tex->domain)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1081,7 +1081,7 @@ validate:
tex = r300_texture(fb->zsbuf->texture);
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
if (!r300_add_texture(r300->rws, tex,
- 0, RADEON_GEM_DOMAIN_VRAM)) {
+ 0, tex->domain)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1093,8 +1093,7 @@ validate:
}
tex = r300_texture(texstate->sampler_views[i]->base.texture);
- if (!r300_add_texture(r300->rws, tex,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ if (!r300_add_texture(r300->rws, tex, tex->domain, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1103,7 +1102,7 @@ validate:
if (r300->query_start.dirty ||
(r300->query_current && r300->query_current->begin_emitted)) {
if (!r300_add_buffer(r300->rws, r300->oqbo,
- 0, RADEON_GEM_DOMAIN_GTT)) {
+ 0, r300_buffer(r300->oqbo)->domain)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1111,7 +1110,7 @@ validate:
/* ...vertex buffer for SWTCL path... */
if (r300->vbo) {
if (!r300_add_buffer(r300->rws, r300->vbo,
- RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300_buffer(r300->vbo)->domain, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1122,7 +1121,7 @@ validate:
pbuf = vbuf[velem[i].vertex_buffer_index].buffer;
if (!r300_add_buffer(r300->rws, pbuf,
- RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300_buffer(pbuf)->domain, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1131,7 +1130,7 @@ validate:
/* ...and index buffer for HWTCL path. */
if (index_buffer) {
if (!r300_add_buffer(r300->rws, index_buffer,
- RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300_buffer(index_buffer)->domain, 0)) {
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
@@ -1168,7 +1167,6 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300)
/* Emit all dirty state. */
void r300_emit_dirty_state(struct r300_context* r300)
{
- struct r300_screen* r300screen = r300->screen;
struct r300_atom* atom;
foreach(atom, &r300->atom_list) {
@@ -1181,10 +1179,5 @@ void r300_emit_dirty_state(struct r300_context* r300)
}
}
- /* Emit the VBO for SWTCL. */
- if (!r300screen->caps.has_tcl) {
- 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 3c0edf6fdc..55e5898ea8 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -76,7 +76,7 @@ void r300_emit_scissor_state(struct r300_context* r300,
void r300_emit_textures_state(struct r300_context *r300,
unsigned size, void *state);
-void r300_emit_vertex_buffer(struct r300_context* r300);
+void r300_emit_aos_swtcl(struct r300_context *r300, boolean indexed);
void r300_emit_vertex_stream_state(struct r300_context* r300,
unsigned size, void* state);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index 9cda940c85..360b19a0c1 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -77,6 +77,7 @@ static void r300_flush(struct pipe_context* pipe,
/* Create a new fence. */
if (rfence) {
*rfence = CALLOC_STRUCT(r300_fence);
+ pipe_reference_init(&(*rfence)->reference, 1);
(*rfence)->ctx = r300;
}
}
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 4ce7114d82..97081c4a00 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -146,9 +146,13 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
/* Looks like our results aren't ready yet. */
if (wait) {
fprintf(stderr, "r300: Despite waiting, OQ results haven't "
- "come in yet.\n");
+ "come in yet. This is a driver bug.\n"
+ "r300: Returning bogus results to avoid "
+ "a possible infinite loop...\n");
+ temp = 987654321;
+ } else {
+ temp = ~0U;
}
- temp = ~0U;
break;
}
temp += *map;
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 42716552c7..83780037cf 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -136,7 +136,8 @@ enum r300_prepare_flags {
PREP_FIRST_DRAW = (1 << 0),
PREP_VALIDATE_VBOS = (1 << 1),
PREP_EMIT_AOS = (1 << 2),
- PREP_INDEXED = (1 << 3)
+ PREP_EMIT_AOS_SWTCL = (1 << 3),
+ PREP_INDEXED = (1 << 4)
};
/* Check if the requested number of dwords is available in the CS and
@@ -147,16 +148,14 @@ static void r300_prepare_for_rendering(struct r300_context *r300,
struct pipe_resource *index_buffer,
unsigned cs_dwords,
unsigned aos_offset,
- int index_bias)
+ int index_bias,
+ unsigned *end_cs_dwords)
{
boolean flushed = FALSE;
boolean first_draw = flags & PREP_FIRST_DRAW;
boolean emit_aos = flags & PREP_EMIT_AOS;
-
- /* Stencil ref fallback. */
- if (r300->stencil_ref_bf_fallback) {
- cs_dwords = cs_dwords * 2 + 10;
- }
+ boolean emit_aos_swtcl = flags & PREP_EMIT_AOS_SWTCL;
+ unsigned end_dwords = 0;
/* Add dirty state, index offset, and AOS. */
if (first_draw) {
@@ -167,13 +166,18 @@ static void r300_prepare_for_rendering(struct r300_context *r300,
if (emit_aos)
cs_dwords += 55; /* emit_aos */
+
+ if (emit_aos_swtcl)
+ cs_dwords += 7; /* emit_aos_swtcl */
}
/* Emitted in flush. */
- cs_dwords += 26; /* emit_query_end */
+ end_dwords += 26; /* emit_query_end */
+
+ cs_dwords += end_dwords;
/* Reserve requested CS space. */
- if (!r300->rws->check_cs(r300->rws, cs_dwords)) {
+ if (!r300_check_cs(r300, cs_dwords)) {
r300->context.flush(&r300->context, 0, NULL);
flushed = TRUE;
}
@@ -185,7 +189,12 @@ static void r300_prepare_for_rendering(struct r300_context *r300,
r500_emit_index_offset(r300, index_bias);
if (emit_aos)
r300_emit_aos(r300, aos_offset, flags & PREP_INDEXED);
+ if (emit_aos_swtcl)
+ r300_emit_aos_swtcl(r300, flags & PREP_INDEXED);
}
+
+ if (end_cs_dwords)
+ *end_cs_dwords = end_dwords;
}
static boolean immd_is_good_idea(struct r300_context *r300,
@@ -236,7 +245,7 @@ static boolean immd_is_good_idea(struct r300_context *r300,
* after resolving fallback issues (e.g. stencil ref two-sided). *
****************************************************************************/
-static void r500_emit_draw_arrays_immediate(struct r300_context *r300,
+static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
unsigned mode,
unsigned start,
unsigned count)
@@ -287,7 +296,7 @@ static void r500_emit_draw_arrays_immediate(struct r300_context *r300,
dwords = 9 + count * vertex_size;
- r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
+ r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0, NULL);
BEGIN_CS(dwords);
OUT_CS_REG(R300_GA_COLOR_CONTROL,
@@ -326,7 +335,7 @@ static void r500_emit_draw_arrays_immediate(struct r300_context *r300,
}
}
-static void r500_emit_draw_arrays(struct r300_context *r300,
+static void r300_emit_draw_arrays(struct r300_context *r300,
unsigned mode,
unsigned count)
{
@@ -355,7 +364,7 @@ static void r500_emit_draw_arrays(struct r300_context *r300,
END_CS;
}
-static void r500_emit_draw_elements(struct r300_context *r300,
+static void r300_emit_draw_elements(struct r300_context *r300,
struct pipe_resource* indexBuffer,
unsigned indexSize,
unsigned minIndex,
@@ -413,109 +422,11 @@ static void r500_emit_draw_elements(struct r300_context *r300,
(0 << R300_INDX_BUFFER_SKIP_SHIFT));
OUT_CS(offset_dwords << 2);
OUT_CS_BUF_RELOC(indexBuffer, count_dwords,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
-
- END_CS;
-}
+ r300_buffer(indexBuffer)->domain, 0, 0);
-/*****************************************************************************
- * The emission of draw packets for r300 which take care of the two-sided *
- * stencil ref fallback and call r500's functions. *
- ****************************************************************************/
-
-/* Set drawing for front faces. */
-static void r300_begin_stencil_ref_fallback(struct r300_context *r300)
-{
- struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
- CS_LOCALS(r300);
-
- BEGIN_CS(2);
- OUT_CS_REG(R300_SU_CULL_MODE, rs->cull_mode | R300_CULL_BACK);
END_CS;
}
-/* Set drawing for back faces. */
-static void r300_switch_stencil_ref_side(struct r300_context *r300)
-{
- struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
- struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
- CS_LOCALS(r300);
-
- BEGIN_CS(4);
- OUT_CS_REG(R300_SU_CULL_MODE, rs->cull_mode | R300_CULL_FRONT);
- OUT_CS_REG(R300_ZB_STENCILREFMASK,
- dsa->stencil_ref_bf | r300->stencil_ref.ref_value[1]);
- END_CS;
-}
-
-/* Restore the original state. */
-static void r300_end_stencil_ref_fallback(struct r300_context *r300)
-{
- struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
- struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
- CS_LOCALS(r300);
-
- BEGIN_CS(4);
- OUT_CS_REG(R300_SU_CULL_MODE, rs->cull_mode);
- OUT_CS_REG(R300_ZB_STENCILREFMASK,
- dsa->stencil_ref_mask | r300->stencil_ref.ref_value[0]);
- END_CS;
-}
-
-static void r300_emit_draw_arrays_immediate(struct r300_context *r300,
- unsigned mode,
- unsigned start,
- unsigned count)
-{
- if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_arrays_immediate(r300, mode, start, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_arrays_immediate(r300, mode, start, count);
- r300_switch_stencil_ref_side(r300);
- r500_emit_draw_arrays_immediate(r300, mode, start, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
-
-static void r300_emit_draw_arrays(struct r300_context *r300,
- unsigned mode,
- unsigned count)
-{
- if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_arrays(r300, mode, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_arrays(r300, mode, count);
- r300_switch_stencil_ref_side(r300);
- r500_emit_draw_arrays(r300, mode, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
-
-static void r300_emit_draw_elements(struct r300_context *r300,
- struct pipe_resource* indexBuffer,
- unsigned indexSize,
- unsigned minIndex,
- unsigned maxIndex,
- unsigned mode,
- unsigned start,
- unsigned count)
-{
- if (!r300->stencil_ref_bf_fallback) {
- r500_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count);
- r300_switch_stencil_ref_side(r300);
- r500_emit_draw_elements(r300, indexBuffer, indexSize,
- minIndex, maxIndex, mode, start, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
-
static void r300_shorten_ubyte_elts(struct r300_context* r300,
struct pipe_resource** elts,
unsigned start,
@@ -619,17 +530,17 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
/* 15 dwords for emit_draw_elements */
r300_prepare_for_rendering(r300,
PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
- indexBuffer, 15, 0, indexBias);
+ indexBuffer, 15, 0, indexBias, NULL);
u_upload_flush(r300->upload_vb);
u_upload_flush(r300->upload_ib);
if (alt_num_verts || count <= 65535) {
- r300->emit_draw_elements(r300, indexBuffer, indexSize,
+ r300_emit_draw_elements(r300, indexBuffer, indexSize,
minIndex, maxIndex, mode, start, count);
} else {
do {
short_count = MIN2(count, 65534);
- r300->emit_draw_elements(r300, indexBuffer, indexSize,
+ r300_emit_draw_elements(r300, indexBuffer, indexSize,
minIndex, maxIndex,
mode, start, short_count);
@@ -640,7 +551,7 @@ static void r300_draw_range_elements(struct pipe_context* pipe,
if (count) {
r300_prepare_for_rendering(r300,
PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED,
- indexBuffer, 15, 0, indexBias);
+ indexBuffer, 15, 0, indexBias, NULL);
}
} while (count);
}
@@ -683,18 +594,18 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
r300_update_derived_state(r300);
if (immd_is_good_idea(r300, count)) {
- r300->emit_draw_arrays_immediate(r300, mode, start, count);
+ r300_emit_draw_arrays_immediate(r300, mode, start, count);
} else {
/* 9 spare dwords for emit_draw_arrays. */
r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS,
- NULL, 9, start, 0);
+ NULL, 9, start, 0, NULL);
if (alt_num_verts || count <= 65535) {
- r300->emit_draw_arrays(r300, mode, count);
+ r300_emit_draw_arrays(r300, mode, count);
} else {
do {
short_count = MIN2(count, 65535);
- r300->emit_draw_arrays(r300, mode, short_count);
+ r300_emit_draw_arrays(r300, mode, short_count);
start += short_count;
count -= short_count;
@@ -703,7 +614,7 @@ static void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
if (count) {
r300_prepare_for_rendering(r300,
PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9,
- start, 0);
+ start, 0, NULL);
}
} while (count);
}
@@ -886,6 +797,8 @@ static void* r300_render_map_vertices(struct vbuf_render* render)
{
struct r300_render* r300render = r300_render(render);
+ assert(!r300render->vbo_transfer);
+
r300render->vbo_ptr = pipe_buffer_map(&r300render->r300->context,
r300render->vbo,
PIPE_TRANSFER_WRITE,
@@ -901,9 +814,13 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
struct r300_render* r300render = r300_render(render);
struct pipe_context* context = &r300render->r300->context;
+ assert(r300render->vbo_transfer);
+
r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
r300render->vertex_size * (max + 1));
pipe_buffer_unmap(context, r300render->vbo, r300render->vbo_transfer);
+
+ r300render->vbo_transfer = NULL;
}
static void r300_render_release_vertices(struct vbuf_render* render)
@@ -925,7 +842,7 @@ static boolean r300_render_set_primitive(struct vbuf_render* render,
return TRUE;
}
-static void r500_render_draw_arrays(struct vbuf_render* render,
+static void r300_render_draw_arrays(struct vbuf_render* render,
unsigned start,
unsigned count)
{
@@ -939,7 +856,8 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
(void) i; (void) ptr;
- r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
+ r300_prepare_for_rendering(r300, PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL,
+ NULL, dwords, 0, 0, NULL);
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
@@ -970,68 +888,59 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
END_CS;
}
-static void r500_render_draw_elements(struct vbuf_render* render,
+static void r300_render_draw_elements(struct vbuf_render* render,
const ushort* indices,
uint count)
{
struct r300_render* r300render = r300_render(render);
struct r300_context* r300 = r300render->r300;
int i;
- unsigned dwords = 6 + (count+1)/2;
+ unsigned end_cs_dwords;
unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) /
(r300render->r300->vertex_info.size * 4) - 1;
+ unsigned short_count;
+ struct r300_cs_info cs_info;
CS_LOCALS(r300);
- r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
-
- BEGIN_CS(dwords);
- OUT_CS_REG(R300_GA_COLOR_CONTROL,
- r300_provoking_vertex_fixes(r300, r300render->prim));
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
- 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;
-}
-
-static void r300_render_draw_arrays(struct vbuf_render* render,
- unsigned start,
- unsigned count)
-{
- struct r300_context* r300 = r300_render(render)->r300;
-
- if (!r300->stencil_ref_bf_fallback) {
- r500_render_draw_arrays(render, start, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_render_draw_arrays(render, start, count);
- r300_switch_stencil_ref_side(r300);
- r500_render_draw_arrays(render, start, count);
- r300_end_stencil_ref_fallback(r300);
- }
-}
+ /* Reserve at least 256 dwords.
+ *
+ * Below we manage the CS space manually because there may be more
+ * indices than it can fit in CS. */
+ r300_prepare_for_rendering(r300,
+ PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ NULL, 256, 0, 0, &end_cs_dwords);
+
+ while (count) {
+ r300->rws->get_cs_info(r300->rws, &cs_info);
+
+ short_count = MIN2(count, (cs_info.free - end_cs_dwords - 6) * 2);
+
+ BEGIN_CS(6 + (short_count+1)/2);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, r300render->prim));
+ OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
+ OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (short_count+1)/2);
+ OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (short_count << 16) |
+ r300render->hwprim);
+ for (i = 0; i < short_count-1; i += 2) {
+ OUT_CS(indices[i+1] << 16 | indices[i]);
+ }
+ if (short_count % 2) {
+ OUT_CS(indices[short_count-1]);
+ }
+ END_CS;
-static void r300_render_draw_elements(struct vbuf_render* render,
- const ushort* indices,
- uint count)
-{
- struct r300_context* r300 = r300_render(render)->r300;
+ /* OK now subtract the emitted indices and see if we need to emit
+ * another draw packet. */
+ indices += short_count;
+ count -= short_count;
- if (!r300->stencil_ref_bf_fallback) {
- r500_render_draw_elements(render, indices, count);
- } else {
- r300_begin_stencil_ref_fallback(r300);
- r500_render_draw_elements(render, indices, count);
- r300_switch_stencil_ref_side(r300);
- r500_render_draw_elements(render, indices, count);
- r300_end_stencil_ref_fallback(r300);
+ if (count) {
+ r300_prepare_for_rendering(r300,
+ PREP_EMIT_AOS_SWTCL | PREP_INDEXED,
+ NULL, 256, 0, 0, &end_cs_dwords);
+ }
}
}
@@ -1055,13 +964,8 @@ static struct vbuf_render* r300_render_create(struct r300_context* r300)
r300render->base.map_vertices = r300_render_map_vertices;
r300render->base.unmap_vertices = r300_render_unmap_vertices;
r300render->base.set_primitive = r300_render_set_primitive;
- if (r300->screen->caps.is_r500) {
- r300render->base.draw_elements = r500_render_draw_elements;
- r300render->base.draw_arrays = r500_render_draw_arrays;
- } else {
- r300render->base.draw_elements = r300_render_draw_elements;
- r300render->base.draw_arrays = r300_render_draw_arrays;
- }
+ r300render->base.draw_elements = r300_render_draw_elements;
+ r300render->base.draw_arrays = r300_render_draw_arrays;
r300render->base.release_vertices = r300_render_release_vertices;
r300render->base.destroy = r300_render_destroy;
@@ -1095,25 +999,150 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300)
return stage;
}
+/****************************************************************************
+ * Two-sided stencil reference value fallback. It's designed to be as much
+ * separate from rest of the driver as possible.
+ ***************************************************************************/
+
+struct r300_stencilref_context {
+ void (*draw_arrays)(struct pipe_context *pipe,
+ unsigned mode, unsigned start, unsigned count);
+
+ void (*draw_range_elements)(
+ struct pipe_context *pipe, struct pipe_resource *indexBuffer,
+ unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex,
+ unsigned mode, unsigned start, unsigned count);
+
+ uint32_t rs_cull_mode;
+ uint32_t zb_stencilrefmask;
+ ubyte ref_value_front;
+};
+
+static boolean r300_stencilref_needed(struct r300_context *r300)
+{
+ struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
+
+ return dsa->two_sided_stencil_ref ||
+ (dsa->two_sided &&
+ r300->stencil_ref.ref_value[0] != r300->stencil_ref.ref_value[1]);
+}
+
+/* Set drawing for front faces. */
+static void r300_stencilref_begin(struct r300_context *r300)
+{
+ struct r300_stencilref_context *sr = r300->stencilref_fallback;
+ struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
+ struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
+
+ /* Save state. */
+ sr->rs_cull_mode = rs->cull_mode;
+ sr->zb_stencilrefmask = dsa->stencil_ref_mask;
+ sr->ref_value_front = r300->stencil_ref.ref_value[0];
+
+ /* We *cull* pixels, therefore no need to mask out the bits. */
+ rs->cull_mode |= R300_CULL_BACK;
+
+ r300->rs_state.dirty = TRUE;
+}
+
+/* Set drawing for back faces. */
+static void r300_stencilref_switch_side(struct r300_context *r300)
+{
+ struct r300_stencilref_context *sr = r300->stencilref_fallback;
+ struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
+ struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
+
+ rs->cull_mode = sr->rs_cull_mode | R300_CULL_FRONT;
+ dsa->stencil_ref_mask = dsa->stencil_ref_bf;
+ r300->stencil_ref.ref_value[0] = r300->stencil_ref.ref_value[1];
+
+ r300->rs_state.dirty = TRUE;
+ r300->dsa_state.dirty = TRUE;
+}
+
+/* Restore the original state. */
+static void r300_stencilref_end(struct r300_context *r300)
+{
+ struct r300_stencilref_context *sr = r300->stencilref_fallback;
+ struct r300_rs_state *rs = (struct r300_rs_state*)r300->rs_state.state;
+ struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
+
+ /* Restore state. */
+ rs->cull_mode = sr->rs_cull_mode;
+ dsa->stencil_ref_mask = sr->zb_stencilrefmask;
+ r300->stencil_ref.ref_value[0] = sr->ref_value_front;
+
+ r300->rs_state.dirty = TRUE;
+ r300->dsa_state.dirty = TRUE;
+}
+
+static void r300_stencilref_draw_arrays(struct pipe_context *pipe, unsigned mode,
+ unsigned start, unsigned count)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_stencilref_context *sr = r300->stencilref_fallback;
+
+ if (!r300_stencilref_needed(r300)) {
+ sr->draw_arrays(pipe, mode, start, count);
+ } else {
+ r300_stencilref_begin(r300);
+ sr->draw_arrays(pipe, mode, start, count);
+ r300_stencilref_switch_side(r300);
+ sr->draw_arrays(pipe, mode, start, count);
+ r300_stencilref_end(r300);
+ }
+}
+
+static void r300_stencilref_draw_range_elements(
+ struct pipe_context *pipe, struct pipe_resource *indexBuffer,
+ unsigned indexSize, int indexBias, unsigned minIndex, unsigned maxIndex,
+ unsigned mode, unsigned start, unsigned count)
+{
+ struct r300_context *r300 = r300_context(pipe);
+ struct r300_stencilref_context *sr = r300->stencilref_fallback;
+
+ if (!r300_stencilref_needed(r300)) {
+ sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
+ } else {
+ r300_stencilref_begin(r300);
+ sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
+ r300_stencilref_switch_side(r300);
+ sr->draw_range_elements(pipe, indexBuffer, indexSize, indexBias,
+ minIndex, maxIndex, mode, start, count);
+ r300_stencilref_end(r300);
+ }
+}
+
+static void r300_plug_in_stencil_ref_fallback(struct r300_context *r300)
+{
+ r300->stencilref_fallback = CALLOC_STRUCT(r300_stencilref_context);
+
+ /* Save original draw functions. */
+ r300->stencilref_fallback->draw_arrays = r300->context.draw_arrays;
+ r300->stencilref_fallback->draw_range_elements = r300->context.draw_range_elements;
+
+ /* Override the draw functions. */
+ r300->context.draw_arrays = r300_stencilref_draw_arrays;
+ r300->context.draw_range_elements = r300_stencilref_draw_range_elements;
+}
+
void r300_init_render_functions(struct r300_context *r300)
{
+ /* Set generic functions. */
+ r300->context.draw_elements = r300_draw_elements;
+
+ /* Set draw functions based on presence of HW TCL. */
if (r300->screen->caps.has_tcl) {
r300->context.draw_arrays = r300_draw_arrays;
- r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_draw_range_elements;
-
- if (r300->screen->caps.is_r500) {
- r300->emit_draw_arrays_immediate = r500_emit_draw_arrays_immediate;
- r300->emit_draw_arrays = r500_emit_draw_arrays;
- r300->emit_draw_elements = r500_emit_draw_elements;
- } else {
- r300->emit_draw_arrays_immediate = r300_emit_draw_arrays_immediate;
- r300->emit_draw_arrays = r300_emit_draw_arrays;
- r300->emit_draw_elements = r300_emit_draw_elements;
- }
} else {
r300->context.draw_arrays = r300_swtcl_draw_arrays;
- r300->context.draw_elements = r300_draw_elements;
r300->context.draw_range_elements = r300_swtcl_draw_range_elements;
}
+
+ /* Plug in two-sided stencil reference value fallback if needed. */
+ if (!r300->screen->caps.is_r500)
+ r300_plug_in_stencil_ref_fallback(r300);
}
diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c
index 7ed47eaa60..f6f33028dc 100644
--- a/src/gallium/drivers/r300/r300_resource.c
+++ b/src/gallium/drivers/r300/r300_resource.c
@@ -23,19 +23,9 @@
* Authors: Dave Airlie
*/
-#include <stdio.h>
-
-#include "util/u_inlines.h"
-#include "util/u_format.h"
-#include "util/u_memory.h"
-#include "util/u_upload_mgr.h"
-#include "util/u_math.h"
-
#include "r300_context.h"
#include "r300_texture.h"
-#include "r300_screen.h"
#include "r300_screen_buffer.h"
-#include "r300_winsys.h"
static struct pipe_resource *
r300_resource_create(struct pipe_screen *screen,
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index a5ad6d9c0e..e7db074be6 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -28,6 +28,7 @@
#include "r300_context.h"
#include "r300_texture.h"
#include "r300_screen_buffer.h"
+#include "r300_state_inlines.h"
#include "r300_winsys.h"
/* Return the identifier behind whom the brave coders responsible for this
@@ -251,6 +252,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
uint32_t retval = 0;
boolean is_r500 = r300_screen(screen)->caps.is_r500;
boolean is_r400 = r300_screen(screen)->caps.is_r400;
+ boolean is_rv350 = r300_screen(screen)->caps.is_rv350;
boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM ||
format == PIPE_FORMAT_S8_USCALED_Z24_UNORM;
boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM ||
@@ -261,6 +263,10 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
format == PIPE_FORMAT_RGTC1_SNORM;
boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM ||
format == PIPE_FORMAT_RGTC2_SNORM;
+ boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT ||
+ format == PIPE_FORMAT_R16G16_FLOAT ||
+ format == PIPE_FORMAT_R16G16B16_FLOAT ||
+ format == PIPE_FORMAT_R16G16B16A16_FLOAT;
if (target >= PIPE_MAX_TEXTURE_TYPES) {
fprintf(stderr, "r300: Implementation error: Received bogus texture "
@@ -304,6 +310,14 @@ static boolean r300_is_format_supported(struct pipe_screen* screen,
retval |= PIPE_BIND_DEPTH_STENCIL;
}
+ /* Check vertex buffer format support. */
+ if (usage & PIPE_BIND_VERTEX_BUFFER &&
+ /* Half float is supported on >= RV350. */
+ (is_rv350 || !is_half_float) &&
+ r300_translate_vertex_data_type(format) != R300_INVALID_FORMAT) {
+ retval |= PIPE_BIND_VERTEX_BUFFER;
+ }
+
return retval == usage;
}
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c
index 3e2b5afe6f..44179f19ed 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.c
+++ b/src/gallium/drivers/r300/r300_screen_buffer.c
@@ -116,19 +116,6 @@ int r300_upload_user_buffers(struct r300_context *r300)
return ret;
}
-static struct r300_winsys_buffer *
-r300_winsys_buffer_create(struct r300_screen *r300screen,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct r300_winsys_screen *rws = r300screen->rws;
- struct r300_winsys_buffer *buf;
-
- buf = rws->buffer_create(rws, alignment, usage, size);
- return buf;
-}
-
static void r300_winsys_buffer_destroy(struct r300_screen *r300screen,
struct r300_buffer *rbuf)
{
@@ -180,9 +167,9 @@ r300_buffer_transfer_map( struct pipe_context *pipe,
rws->buffer_reference(rws, &rbuf->buf, NULL);
rbuf->num_ranges = 0;
- rbuf->buf = r300_winsys_buffer_create(r300screen,
- 16,
- rbuf->b.b.bind, /* XXX */
+ rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, 16,
+ rbuf->b.b.bind,
+ rbuf->domain,
rbuf->b.b.width0);
break;
}
@@ -278,9 +265,12 @@ struct pipe_resource *r300_buffer_create(struct pipe_screen *screen,
if (rbuf->b.b.bind & R300_BIND_OQBO)
alignment = 4096;
- rbuf->buf = r300_winsys_buffer_create(r300screen,
+ rbuf->domain = R300_DOMAIN_GTT;
+
+ rbuf->buf = r300screen->rws->buffer_create(r300screen->rws,
alignment,
rbuf->b.b.bind,
+ rbuf->domain,
rbuf->b.b.width0);
if (!rbuf->buf)
@@ -315,6 +305,7 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen,
rbuf->b.b.width0 = bytes;
rbuf->b.b.height0 = 1;
rbuf->b.b.depth0 = 1;
+ rbuf->domain = R300_DOMAIN_GTT;
rbuf->user_buffer = ptr;
return &rbuf->b.b;
diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h
index 57f48229b2..87b42b9412 100644
--- a/src/gallium/drivers/r300/r300_screen_buffer.h
+++ b/src/gallium/drivers/r300/r300_screen_buffer.h
@@ -52,6 +52,8 @@ struct r300_buffer
struct r300_winsys_buffer *buf;
+ enum r300_buffer_domain domain;
+
void *user_buffer;
struct r300_buffer_range ranges[R300_BUFFER_MAX_RANGES];
unsigned num_ranges;
@@ -116,7 +118,9 @@ static INLINE boolean r300_add_texture(struct r300_winsys_screen *rws,
static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws,
struct r300_buffer *buf,
- uint32_t rd, uint32_t wd, uint32_t flags)
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
+ uint32_t flags)
{
if (!buf->buf)
return;
@@ -126,7 +130,9 @@ static INLINE void r300_buffer_write_reloc(struct r300_winsys_screen *rws,
static INLINE void r300_texture_write_reloc(struct r300_winsys_screen *rws,
struct r300_texture *texture,
- uint32_t rd, uint32_t wd, uint32_t flags)
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
+ uint32_t flags)
{
rws->write_cs_reloc(rws, texture->buffer, rd, wd, flags);
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 67e09362d8..cfec8ac2b7 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -474,7 +474,7 @@ static void*
if (caps->is_r500) {
dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK;
} else {
- dsa->stencil_ref_bf_fallback =
+ dsa->two_sided_stencil_ref =
(state->stencil[0].valuemask != state->stencil[1].valuemask ||
state->stencil[0].writemask != state->stencil[1].writemask);
}
@@ -497,20 +497,6 @@ static void*
return (void*)dsa;
}
-static void r300_update_stencil_ref_fallback_status(struct r300_context *r300)
-{
- struct r300_dsa_state *dsa = (struct r300_dsa_state*)r300->dsa_state.state;
-
- if (r300->screen->caps.is_r500) {
- return;
- }
-
- r300->stencil_ref_bf_fallback =
- dsa->stencil_ref_bf_fallback ||
- (dsa->two_sided &&
- r300->stencil_ref.ref_value[0] != r300->stencil_ref.ref_value[1]);
-}
-
/* Bind DSA state. */
static void r300_bind_dsa_state(struct pipe_context* pipe,
void* state)
@@ -522,8 +508,6 @@ static void r300_bind_dsa_state(struct pipe_context* pipe,
}
UPDATE_STATE(state, r300->dsa_state);
-
- r300_update_stencil_ref_fallback_status(r300);
}
/* Free DSA state. */
@@ -540,8 +524,6 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
r300->stencil_ref = *sr;
r300->dsa_state.dirty = TRUE;
-
- r300_update_stencil_ref_fallback_status(r300);
}
/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */
@@ -558,18 +540,18 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300,
level = new_state->cbufs[i]->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->mip_macrotile[level]);
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
if (new_state->zsbuf) {
tex = r300_texture(new_state->zsbuf->texture);
level = new_state->zsbuf->level;
r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->mip_macrotile[level]);
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
+ tex->microtile,
+ tex->mip_macrotile[level]);
}
}
@@ -1183,48 +1165,61 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
return;
}
- /* Check if the stride is aligned to the size of DWORD. */
- for (i = 0; i < count; i++) {
- if (buffers[i].buffer) {
- if (buffers[i].stride % 4 != 0) {
- // XXX Shouldn't we align the buffer?
- fprintf(stderr, "r300: set_vertex_buffers: "
- "Unaligned buffer stride %i isn't supported.\n",
- buffers[i].stride);
- abort();
+ if (r300->screen->caps.has_tcl) {
+ /* HW TCL. */
+ /* Check if the stride is aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ if (buffers[i].buffer) {
+ if (buffers[i].stride % 4 != 0) {
+ // XXX Shouldn't we align the buffer?
+ fprintf(stderr, "r300: set_vertex_buffers: "
+ "Unaligned buffer stride %i isn't supported.\n",
+ buffers[i].stride);
+ abort();
+ }
}
}
- }
- for (i = 0; i < count; i++) {
- /* Why, yes, I AM casting away constness. How did you know? */
- vbo = (struct pipe_vertex_buffer*)&buffers[i];
+ for (i = 0; i < count; i++) {
+ /* Why, yes, I AM casting away constness. How did you know? */
+ vbo = (struct pipe_vertex_buffer*)&buffers[i];
- /* Reference our buffer. */
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
+ /* Skip NULL buffers */
+ if (!buffers[i].buffer) {
+ continue;
+ }
- /* Skip NULL buffers */
- if (!buffers[i].buffer) {
- continue;
- }
+ if (r300_buffer_is_user_buffer(vbo->buffer)) {
+ any_user_buffer = TRUE;
+ }
- if (r300_buffer_is_user_buffer(vbo->buffer)) {
- any_user_buffer = TRUE;
- }
+ if (vbo->max_index == ~0) {
+ /* if no VBO stride then only one vertex value so max index is 1 */
+ /* should think about converting to VS constants like svga does */
+ if (!vbo->stride)
+ vbo->max_index = 1;
+ else
+ vbo->max_index =
+ (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
+ }
- if (vbo->max_index == ~0) {
- /* if no VBO stride then only one vertex value so max index is 1 */
- /* should think about converting to VS constants like svga does */
- if (!vbo->stride)
- vbo->max_index = 1;
- else
- vbo->max_index =
- (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
+ max_index = MIN2(vbo->max_index, max_index);
}
- max_index = MIN2(vbo->max_index, max_index);
+ r300->any_user_vbs = any_user_buffer;
+ r300->vertex_buffer_max_index = max_index;
+
+ } else {
+ /* SW TCL. */
+ draw_flush(r300->draw);
+ draw_set_vertex_buffers(r300->draw, count, buffers);
}
+ /* Common code. */
+ for (i = 0; i < count; i++) {
+ /* Reference our buffer. */
+ pipe_resource_reference(&r300->vertex_buffer[i].buffer, buffers[i].buffer);
+ }
for (; i < r300->vertex_buffer_count; i++) {
/* Dereference any old buffers. */
pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
@@ -1232,15 +1227,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
memcpy(r300->vertex_buffer, buffers,
sizeof(struct pipe_vertex_buffer) * count);
-
r300->vertex_buffer_count = count;
- r300->vertex_buffer_max_index = max_index;
- r300->any_user_vbs = any_user_buffer;
-
- if (r300->draw) {
- draw_flush(r300->draw);
- draw_set_vertex_buffers(r300->draw, count, buffers);
- }
}
/* Initialize the PSC tables. */
@@ -1263,8 +1250,15 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
for (i = 0; i < velems->count; i++) {
format = velems->velem[i].src_format;
- type = r300_translate_vertex_data_type(format) |
- (i << R300_DST_VEC_LOC_SHIFT);
+ type = r300_translate_vertex_data_type(format);
+ if (type == R300_INVALID_FORMAT) {
+ fprintf(stderr, "r300: Bad vertex format %s.\n",
+ util_format_short_name(format));
+ assert(0);
+ abort();
+ }
+
+ type |= i << R300_DST_VEC_LOC_SHIFT;
swizzle = r300_translate_vertex_data_swizzle(format);
if (i & 1) {
@@ -1425,12 +1419,11 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
vs->state = *shader;
vs->state.tokens = tgsi_dup_tokens(shader->tokens);
- r300_init_vs_outputs(vs);
-
if (r300->screen->caps.has_tcl) {
+ r300_init_vs_outputs(vs);
r300_translate_vertex_shader(r300, vs);
} else {
- vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
+ r300_draw_init_vertex_shader(r300->draw, vs);
}
return vs;
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 7583862a1a..cc75fad3bb 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -90,7 +90,13 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
}
}
- /* XXX Back-face colors. */
+ /* Back-face colors. */
+ for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ if (vs_outputs->bcolor[i] != ATTR_UNUSED) {
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_LINEAR,
+ vs_outputs->bcolor[i]);
+ }
+ }
/* Texture coordinates. */
/* Only 8 generic vertex attributes can be used. If there are more,
@@ -110,6 +116,14 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
vs_outputs->fog);
gen_count++;
}
+
+ /* WPOS. */
+ if (r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED && gen_count < 8) {
+ DBG(r300, DBG_DRAW, "draw_emit_attrib: WPOS, index: %i\n",
+ vs_outputs->wpos);
+ r300_draw_emit_attrib(r300, EMIT_4F, INTERP_PERSPECTIVE,
+ vs_outputs->wpos);
+ }
}
/* Update the PSC tables for SW TCL, using Draw. */
@@ -129,7 +143,7 @@ static void r300_swtcl_vertex_psc(struct r300_context *r300)
attrib_count = vinfo->num_attribs;
DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
for (i = 0; i < attrib_count; i++) {
- DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
+ DBG(r300, DBG_DRAW, "r300: attrib: index %d, interp %d, emit %d,"
" vs_output_tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
vs_output_tab[i]);
@@ -140,8 +154,15 @@ static void r300_swtcl_vertex_psc(struct r300_context *r300)
format = draw_translate_vinfo_format(vinfo->attrib[i].emit);
/* Obtain the type of data in this attribute. */
- type = r300_translate_vertex_data_type(format) |
- vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
+ type = r300_translate_vertex_data_type(format);
+ if (type == R300_INVALID_FORMAT) {
+ fprintf(stderr, "r300: Bad vertex format %s.\n",
+ util_format_short_name(format));
+ assert(0);
+ abort();
+ }
+
+ type |= vs_output_tab[i] << R300_DST_VEC_LOC_SHIFT;
/* Obtain the swizzle for this attribute. Note that the default
* swizzle in the hardware is not XYZW! */
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 715601042f..03ec127ff7 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -348,20 +348,17 @@ 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;
}
+
/* Translate pipe_formats into PSC vertex types. */
static INLINE uint16_t
r300_translate_vertex_data_type(enum pipe_format format) {
@@ -371,10 +368,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
desc = util_format_description(format);
if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
- fprintf(stderr, "r300: Bad format %s in %s:%d\n", util_format_short_name(format),
- __FUNCTION__, __LINE__);
- assert(0);
- abort();
+ return R300_INVALID_FORMAT;
}
switch (desc->channel[0].type) {
@@ -382,7 +376,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
case UTIL_FORMAT_TYPE_FLOAT:
switch (desc->channel[0].size) {
case 16:
- /* XXX Supported only on RV350 and later. */
+ /* Supported only on RV350 and later. */
if (desc->nr_channels > 2) {
result = R300_DATA_TYPE_FLT16_4;
} else {
@@ -393,10 +387,7 @@ r300_translate_vertex_data_type(enum pipe_format format) {
result = R300_DATA_TYPE_FLOAT_1 + (desc->nr_channels - 1);
break;
default:
- fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_short_name(format), __FUNCTION__, __LINE__);
- assert(0);
- abort();
+ return R300_INVALID_FORMAT;
}
break;
/* Unsigned ints */
@@ -415,19 +406,11 @@ r300_translate_vertex_data_type(enum pipe_format format) {
}
break;
default:
- fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_short_name(format), __FUNCTION__, __LINE__);
- fprintf(stderr, "r300: desc->channel[0].size == %d\n",
- desc->channel[0].size);
- assert(0);
- abort();
+ return R300_INVALID_FORMAT;
}
break;
default:
- fprintf(stderr, "r300: Bad format %s in %s:%d\n",
- util_format_short_name(format), __FUNCTION__, __LINE__);
- assert(0);
- abort();
+ return R300_INVALID_FORMAT;
}
if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED) {
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 4a5c932b7e..4823755fb7 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -696,7 +696,7 @@ static boolean r300_texture_macro_switch(struct r300_texture *tex,
unsigned r300_texture_get_stride(struct r300_screen* screen,
struct r300_texture* tex, unsigned level)
{
- unsigned tile_width, width;
+ unsigned tile_width, width, stride;
if (tex->stride_override)
return tex->stride_override;
@@ -715,7 +715,19 @@ unsigned r300_texture_get_stride(struct r300_screen* screen,
tex->mip_macrotile[level]);
width = align(width, tile_width);
- return util_format_get_stride(tex->b.b.format, width);
+ stride = util_format_get_stride(tex->b.b.format, width);
+
+ /* Some IGPs need a minimum stride of 64 bytes, hmm...
+ * This doesn't seem to apply to tiled textures, according to r300c. */
+ if (!tex->microtile && !tex->mip_macrotile[level] &&
+ (screen->caps.family == CHIP_FAMILY_RS600 ||
+ screen->caps.family == CHIP_FAMILY_RS690 ||
+ screen->caps.family == CHIP_FAMILY_RS740)) {
+ return stride < 64 ? 64 : stride;
+ }
+
+ /* The alignment to 32 bytes is sort of implied by the layout... */
+ return stride;
} else {
return align(util_format_get_stride(tex->b.b.format, width), 32);
}
@@ -959,13 +971,16 @@ struct pipe_resource* r300_texture_create(struct pipe_screen* screen,
base->width0, base->height0, base->depth0, base->last_level,
util_format_short_name(base->format));
- tex->buffer = rws->buffer_create(rws, 2048,
- base->bind,
- tex->size);
+ tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ? R300_DOMAIN_GTT :
+ R300_DOMAIN_VRAM;
+
+ tex->buffer = rws->buffer_create(rws, 2048, base->bind, tex->domain,
+ tex->size);
+
rws->buffer_set_tiling(rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->macrotile);
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
+ tex->microtile,
+ tex->macrotile);
if (!tex->buffer) {
FREE(tex);
@@ -1048,6 +1063,7 @@ r300_texture_from_handle(struct pipe_screen* screen,
tex->b.vtbl = &r300_texture_vtbl;
pipe_reference_init(&tex->b.b.reference, 1);
tex->b.b.screen = screen;
+ tex->domain = R300_DOMAIN_VRAM;
tex->stride_override = stride;
@@ -1093,9 +1109,9 @@ r300_texture_from_handle(struct pipe_screen* screen,
if (override_zb_flags) {
rws->buffer_set_tiling(rws, tex->buffer,
- tex->pitch[0],
- tex->microtile,
- tex->macrotile);
+ tex->pitch[0] * util_format_get_blocksize(tex->b.b.format),
+ tex->microtile,
+ tex->macrotile);
}
return (struct pipe_resource*)tex;
}
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 2d8f0e1439..ff640c56ee 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -26,6 +26,7 @@
#include "util/u_format.h"
struct r300_texture;
+struct r300_screen;
unsigned r300_get_swizzle_combined(const unsigned char *swizzle_format,
const unsigned char *swizzle_view);
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index beb321cb23..0d88d745c0 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -21,12 +21,9 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "r300_context.h"
#include "r300_transfer.h"
#include "r300_texture.h"
-#include "r300_screen.h"
-
-#include "r300_winsys.h"
+#include "r300_screen_buffer.h"
#include "util/u_memory.h"
#include "util/u_format.h"
@@ -40,9 +37,6 @@ struct r300_transfer {
/* Detiled texture. */
struct r300_texture *detiled_texture;
-
- /* Transfer and format flags. */
- unsigned render_target_usage;
};
/* Convenience cast wrapper. */
@@ -63,11 +57,22 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
subdst.face = 0;
subdst.level = 0;
+ /* XXX if we don't flush before copying the texture and mapping it,
+ * we get wrong pixels, i.e. it's like latest draw calls didn't happen,
+ * including this blit. Tests: e.g. piglit/provoking-vertex
+ *
+ * Since the flush immediately before mapping is implicit (the buffer is
+ * always referenced in resource_copy_region), every read transfer costs
+ * 2 flushes. That sucks. */
+ ctx->flush(ctx, 0, NULL);
+
ctx->resource_copy_region(ctx, &r300transfer->detiled_texture->b.b, subdst,
0, 0, 0,
tex, transfer->sr,
transfer->box.x, transfer->box.y, transfer->box.z,
transfer->box.width, transfer->box.height);
+
+ /* Flushing after the copy is implicit, issued by winsys. */
}
/* Copy a detiled texture to a tiled one. */
@@ -81,11 +86,6 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
subsrc.face = 0;
subsrc.level = 0;
- /* XXX this flush prevents the following DRM error from occuring:
- * [drm:radeon_cs_ioctl] *ERROR* Failed to parse relocation !
- * Reproducible with perf/copytex. */
- ctx->flush(ctx, 0, NULL);
-
ctx->resource_copy_region(ctx, tex, transfer->sr,
transfer->box.x, transfer->box.y, transfer->box.z,
&r300transfer->detiled_texture->b.b, subsrc,
@@ -107,12 +107,16 @@ r300_texture_get_transfer(struct pipe_context *ctx,
struct r300_screen *r300screen = r300_screen(ctx->screen);
struct r300_transfer *trans;
struct pipe_resource base;
+ boolean referenced_cs, referenced_hw;
- /* XXX Why aren't flushes taken care of by winsys automatically?
- * Winsys seems to sometimes return a cached buffer instead of
- * a mapped hardware buffer if this flush is commented out. */
- if (ctx->is_resource_referenced(ctx, texture, sr.face, sr.level))
- ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+ referenced_cs = r300screen->rws->is_buffer_referenced(
+ r300screen->rws, tex->buffer, R300_REF_CS);
+ if (referenced_cs) {
+ referenced_hw = TRUE;
+ } else {
+ referenced_hw = r300screen->rws->is_buffer_referenced(
+ r300screen->rws, tex->buffer, R300_REF_HW);
+ }
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
@@ -123,13 +127,10 @@ r300_texture_get_transfer(struct pipe_context *ctx,
trans->transfer.box = *box;
/* If the texture is tiled, we must create a temporary detiled texture
- * for this transfer. */
- if (tex->microtile || tex->macrotile) {
- trans->render_target_usage =
- util_format_is_depth_or_stencil(texture->format) ?
- PIPE_BIND_DEPTH_STENCIL :
- PIPE_BIND_RENDER_TARGET;
-
+ * for this transfer.
+ * Also make write transfers pipelined. */
+ if (tex->microtile || tex->macrotile ||
+ (referenced_hw & !(usage & PIPE_TRANSFER_READ))) {
base.target = PIPE_TEXTURE_2D;
base.format = texture->format;
base.width0 = box->width;
@@ -144,7 +145,7 @@ r300_texture_get_transfer(struct pipe_context *ctx,
/* For texture reading, the temporary (detiled) texture is used as
* a render target when blitting from a tiled texture. */
if (usage & PIPE_TRANSFER_READ) {
- base.bind |= trans->render_target_usage;
+ base.bind |= PIPE_BIND_RENDER_TARGET;
}
/* For texture writing, the temporary texture is used as a sampler
* when blitting into a tiled texture. */
@@ -174,11 +175,17 @@ r300_texture_get_transfer(struct pipe_context *ctx,
/* We cannot map a tiled texture directly because the data is
* in a different order, therefore we do detiling using a blit. */
r300_copy_from_tiled_texture(ctx, trans);
+
+ /* Always referenced in the blit. */
+ ctx->flush(ctx, 0, NULL);
}
} else {
trans->transfer.stride =
r300_texture_get_stride(r300screen, tex, sr.level);
trans->offset = r300_texture_get_offset(tex, sr.level, box->z, sr.face);
+
+ if (referenced_cs && (usage & PIPE_TRANSFER_READ))
+ ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
}
}
return &trans->transfer;
@@ -244,4 +251,3 @@ void r300_texture_transfer_unmap(struct pipe_context *ctx,
rws->buffer_unmap(rws, tex->buffer);
}
}
-
diff --git a/src/gallium/drivers/r300/r300_transfer.h b/src/gallium/drivers/r300/r300_transfer.h
index d72e54e5ed..0d32a68d1f 100644
--- a/src/gallium/drivers/r300/r300_transfer.h
+++ b/src/gallium/drivers/r300/r300_transfer.h
@@ -24,7 +24,7 @@
#ifndef R300_TRANSFER
#define R300_TRANSFER
-#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
struct r300_context;
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 31890d78ca..170de6c79d 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -60,4 +60,8 @@ void r300_init_vs_outputs(struct r300_vertex_shader *vs);
void r300_translate_vertex_shader(struct r300_context *r300,
struct r300_vertex_shader *vs);
+
+void r300_draw_init_vertex_shader(struct draw_context *draw,
+ struct r300_vertex_shader *vs);
+
#endif /* R300_VS_H */
diff --git a/src/gallium/drivers/r300/r300_vs_draw.c b/src/gallium/drivers/r300/r300_vs_draw.c
new file mode 100644
index 0000000000..d64040b891
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_vs_draw.c
@@ -0,0 +1,358 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Marek Olšák <maraeo@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 the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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 vertex shader tranformations for SW TCL needed
+ * to overcome the limitations of the r300 rasterizer.
+ *
+ * Transformations:
+ * 1) If the secondary color output is present, the primary color must be
+ * inserted before it.
+ * 2) If any back-face color output is present, there must be all 4 color
+ * outputs and missing ones must be inserted.
+ * 3) Insert a trailing texcoord output containing a copy of POS, for WPOS.
+ *
+ * I know this code is cumbersome, but I don't know of any nicer way
+ * of transforming TGSI shaders. ~ M.
+ */
+
+#include "r300_vs.h"
+
+#include <stdio.h>
+
+#include "tgsi/tgsi_transform.h"
+#include "tgsi/tgsi_dump.h"
+
+#include "draw/draw_context.h"
+
+struct vs_transform_context {
+ struct tgsi_transform_context base;
+
+ boolean color_used[2];
+ boolean bcolor_used[2];
+ boolean temp_used[128];
+
+ /* Index of the pos output, typically 0. */
+ unsigned pos_output;
+ /* Index of the pos temp where all writes of pos are redirected to. */
+ unsigned pos_temp;
+ /* The index of the last generic output, after which we insert a new
+ * output for WPOS. */
+ int last_generic;
+
+ unsigned num_outputs;
+ /* Used to shift output decl. indices when inserting new ones. */
+ unsigned decl_shift;
+ /* Used to remap writes to output decls if their indices changed. */
+ unsigned out_remap[32];
+
+ /* First instruction processed? */
+ boolean first_instruction;
+ /* End instruction processed? */
+ boolean end_instruction;
+};
+
+static void emit_temp(struct tgsi_transform_context *ctx, unsigned reg)
+{
+ struct tgsi_full_declaration decl;
+
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_TEMPORARY;
+ decl.Range.First = decl.Range.Last = reg;
+ ctx->emit_declaration(ctx, &decl);
+}
+
+static void emit_output(struct tgsi_transform_context *ctx,
+ unsigned name, unsigned index, unsigned interp,
+ unsigned reg)
+{
+ struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
+ struct tgsi_full_declaration decl;
+
+ decl = tgsi_default_full_declaration();
+ decl.Declaration.File = TGSI_FILE_OUTPUT;
+ decl.Declaration.Interpolate = interp;
+ decl.Declaration.Semantic = TRUE;
+ decl.Semantic.Name = name;
+ decl.Semantic.Index = index;
+ decl.Range.First = decl.Range.Last = reg;
+ ctx->emit_declaration(ctx, &decl);
+ ++vsctx->num_outputs;
+}
+
+static void insert_output(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *before,
+ unsigned name, unsigned index, unsigned interp)
+{
+ struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
+ unsigned i;
+
+ /* Make a place for the new output. */
+ for (i = before->Range.First; i < Elements(vsctx->out_remap); i++) {
+ ++vsctx->out_remap[i];
+ }
+
+ /* Insert the new output. */
+ emit_output(ctx, name, index, interp, before->Range.First);
+
+ ++vsctx->decl_shift;
+}
+
+static void insert_trailing_bcolor(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *before)
+{
+ struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
+
+ /* If BCOLOR0 is used, make sure BCOLOR1 is present too. Otherwise
+ * the rasterizer doesn't do the color selection correctly. */
+ if (vsctx->bcolor_used[0] && !vsctx->bcolor_used[1]) {
+ if (before) {
+ insert_output(ctx, before, TGSI_SEMANTIC_BCOLOR, 1,
+ TGSI_INTERPOLATE_LINEAR);
+ } else {
+ emit_output(ctx, TGSI_SEMANTIC_BCOLOR, 1,
+ TGSI_INTERPOLATE_LINEAR, vsctx->num_outputs);
+ }
+ vsctx->bcolor_used[1] = TRUE;
+ }
+}
+
+static void transform_decl(struct tgsi_transform_context *ctx,
+ struct tgsi_full_declaration *decl)
+{
+ struct vs_transform_context *vsctx = (struct vs_transform_context *)ctx;
+ unsigned i;
+
+ if (decl->Declaration.File == TGSI_FILE_OUTPUT) {
+ switch (decl->Semantic.Name) {
+ case TGSI_SEMANTIC_POSITION:
+ vsctx->pos_output = decl->Range.First;
+ break;
+
+ case TGSI_SEMANTIC_COLOR:
+ assert(decl->Semantic.Index < 2);
+ vsctx->color_used[decl->Semantic.Index] = TRUE;
+
+ /* We must rasterize the first color if the second one is
+ * used, otherwise the rasterizer doesn't do the color
+ * selection correctly. Declare it, but don't write to it. */
+ if (decl->Semantic.Index == 1 && !vsctx->color_used[0]) {
+ insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_LINEAR);
+ vsctx->color_used[0] = TRUE;
+ }
+ break;
+
+ case TGSI_SEMANTIC_BCOLOR:
+ assert(decl->Semantic.Index < 2);
+ vsctx->bcolor_used[decl->Semantic.Index] = TRUE;
+
+ /* We must rasterize all 4 colors if back-face colors are
+ * used, otherwise the rasterizer doesn't do the color
+ * selection correctly. Declare it, but don't write to it. */
+ if (!vsctx->color_used[0]) {
+ insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_LINEAR);
+ vsctx->color_used[0] = TRUE;
+ }
+ if (!vsctx->color_used[1]) {
+ insert_output(ctx, decl, TGSI_SEMANTIC_COLOR, 1,
+ TGSI_INTERPOLATE_LINEAR);
+ vsctx->color_used[1] = TRUE;
+ }
+ if (decl->Semantic.Index == 1 && !vsctx->bcolor_used[0]) {
+ insert_output(ctx, decl, TGSI_SEMANTIC_BCOLOR, 0,
+ TGSI_INTERPOLATE_LINEAR);
+ vsctx->color_used[2] = TRUE;
+ }
+ /* One more case is handled in insert_trailing_bcolor. */
+ break;
+
+ case TGSI_SEMANTIC_GENERIC:
+ vsctx->last_generic = MAX2(vsctx->last_generic, decl->Semantic.Index);
+ break;
+ }
+
+ if (decl->Semantic.Name != TGSI_SEMANTIC_BCOLOR) {
+ /* Insert it as soon as possible. */
+ insert_trailing_bcolor(ctx, decl);
+ }
+
+ /* Since we're inserting new outputs in between, the following outputs
+ * should be moved to the right so that they don't overlap with
+ * the newly added ones. */
+ decl->Range.First += vsctx->decl_shift;
+ decl->Range.Last += vsctx->decl_shift;
+
+ ++vsctx->num_outputs;
+ } else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+ for (i = decl->Range.First; i <= decl->Range.Last; i++) {
+ vsctx->temp_used[i] = TRUE;
+ }
+ }
+
+ ctx->emit_declaration(ctx, decl);
+}
+
+static void transform_inst(struct tgsi_transform_context *ctx,
+ struct tgsi_full_instruction *inst)
+{
+ struct vs_transform_context *vsctx = (struct vs_transform_context *) ctx;
+ struct tgsi_full_instruction new_inst;
+ unsigned i;
+
+ if (!vsctx->first_instruction) {
+ vsctx->first_instruction = TRUE;
+
+ /* The trailing BCOLOR should be inserted before the code
+ * if it hasn't already been done so. */
+ insert_trailing_bcolor(ctx, NULL);
+
+ /* Insert the generic output for WPOS. */
+ emit_output(ctx, TGSI_SEMANTIC_GENERIC, vsctx->last_generic + 1,
+ TGSI_INTERPOLATE_PERSPECTIVE, vsctx->num_outputs);
+
+ /* Find a free temp for POSITION. */
+ for (i = 0; i < Elements(vsctx->temp_used); i++) {
+ if (!vsctx->temp_used[i]) {
+ emit_temp(ctx, i);
+ vsctx->pos_temp = i;
+ break;
+ }
+ }
+ }
+
+ if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
+ /* MOV OUT[pos_output], TEMP[pos_temp]; */
+ new_inst = tgsi_default_full_instruction();
+ new_inst.Instruction.Opcode = TGSI_OPCODE_MOV;
+ new_inst.Instruction.NumDstRegs = 1;
+ new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
+ new_inst.Dst[0].Register.Index = vsctx->pos_output;
+ new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
+ new_inst.Instruction.NumSrcRegs = 1;
+ new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+ new_inst.Src[0].Register.Index = vsctx->pos_temp;
+ ctx->emit_instruction(ctx, &new_inst);
+
+ /* MOV OUT[n-1], TEMP[pos_temp]; */
+ new_inst = tgsi_default_full_instruction();
+ new_inst.Instruction.Opcode = TGSI_OPCODE_MOV;
+ new_inst.Instruction.NumDstRegs = 1;
+ new_inst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
+ new_inst.Dst[0].Register.Index = vsctx->num_outputs - 1;
+ new_inst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZW;
+ new_inst.Instruction.NumSrcRegs = 1;
+ new_inst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
+ new_inst.Src[0].Register.Index = vsctx->pos_temp;
+ ctx->emit_instruction(ctx, &new_inst);
+
+ vsctx->end_instruction = TRUE;
+ } else {
+ /* Not an END instruction. */
+ /* Fix writes to outputs. */
+ for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+ struct tgsi_full_dst_register *dst = &inst->Dst[i];
+ if (dst->Register.File == TGSI_FILE_OUTPUT) {
+ if (dst->Register.Index == vsctx->pos_output) {
+ /* Replace writes to OUT[pos_output] with TEMP[pos_temp]. */
+ dst->Register.File = TGSI_FILE_TEMPORARY;
+ dst->Register.Index = vsctx->pos_temp;
+ } else {
+ /* Not a position, good...
+ * Since we were changing the indices of output decls,
+ * we must redirect writes into them too. */
+ dst->Register.Index = vsctx->out_remap[dst->Register.Index];
+ }
+ }
+ }
+
+ /* Inserting 2 instructions before the END opcode moves all following
+ * labels by 2. Subroutines are always after the END opcode so
+ * they're always moved. */
+ if (inst->Instruction.Opcode == TGSI_OPCODE_CAL) {
+ inst->Label.Label += 2;
+ }
+ /* The labels of the following opcodes are moved only after
+ * the END opcode. */
+ if (vsctx->end_instruction &&
+ (inst->Instruction.Opcode == TGSI_OPCODE_IF ||
+ inst->Instruction.Opcode == TGSI_OPCODE_ELSE ||
+ inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP ||
+ inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP)) {
+ inst->Label.Label += 2;
+ }
+ }
+
+ ctx->emit_instruction(ctx, inst);
+}
+
+void r300_draw_init_vertex_shader(struct draw_context *draw,
+ struct r300_vertex_shader *vs)
+{
+ struct pipe_shader_state new_vs;
+ struct vs_transform_context transform;
+ const uint newLen = tgsi_num_tokens(vs->state.tokens) + 100 /* XXX */;
+ unsigned i;
+
+ new_vs.tokens = tgsi_alloc_tokens(newLen);
+ if (new_vs.tokens == NULL)
+ return;
+
+ memset(&transform, 0, sizeof(transform));
+ for (i = 0; i < Elements(transform.out_remap); i++) {
+ transform.out_remap[i] = i;
+ }
+ transform.last_generic = -1;
+ transform.base.transform_instruction = transform_inst;
+ transform.base.transform_declaration = transform_decl;
+
+ tgsi_transform_shader(vs->state.tokens,
+ (struct tgsi_token*)new_vs.tokens,
+ newLen, &transform.base);
+
+#if 0
+ printf("----------------------------------------------\norig shader:\n");
+ tgsi_dump(vs->state.tokens, 0);
+ printf("----------------------------------------------\nnew shader:\n");
+ tgsi_dump(new_vs.tokens, 0);
+ printf("----------------------------------------------\n");
+#endif
+
+ /* Free old tokens. */
+ FREE((void*)vs->state.tokens);
+
+ vs->draw_vs = draw_create_vertex_shader(draw, &new_vs);
+
+ /* Instead of duplicating and freeing the tokens, copy the pointer directly. */
+ vs->state.tokens = new_vs.tokens;
+
+ /* Init the VS output table for the rasterizer. */
+ r300_init_vs_outputs(vs);
+
+ /* Make the last generic be WPOS. */
+ vs->outputs.wpos = vs->outputs.generic[transform.last_generic + 1];
+ vs->outputs.generic[transform.last_generic + 1] = ATTR_UNUSED;
+}
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 3d0413f90a..6ce218923b 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -47,6 +47,13 @@ enum r300_reference_domain { /* bitfield */
R300_REF_HW = 2
};
+struct r300_cs_info {
+ /* In DWORDs. */
+ unsigned used;
+ unsigned free;
+ unsigned capacity;
+};
+
struct r300_winsys_screen {
void (*destroy)(struct r300_winsys_screen *ws);
@@ -67,8 +74,9 @@ struct r300_winsys_screen {
struct r300_winsys_buffer *(*buffer_create)(struct r300_winsys_screen *ws,
unsigned alignment,
unsigned usage,
+ enum r300_buffer_domain domain,
unsigned size);
-
+
/**
* Map the entire data store of a buffer object into the client's address.
* flags is bitmask of R300_WINSYS_BUFFER_USAGE_CPU_READ/WRITE flags.
@@ -93,16 +101,17 @@ struct r300_winsys_screen {
/* Add a pipe_resource to the list of buffer objects to validate. */
boolean (*add_buffer)(struct r300_winsys_screen *winsys,
struct r300_winsys_buffer *buf,
- uint32_t rd,
- uint32_t wd);
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd);
/* Revalidate all currently setup pipe_buffers.
* Returns TRUE if a flush is required. */
boolean (*validate)(struct r300_winsys_screen* winsys);
- /* Check to see if there's room for commands. */
- boolean (*check_cs)(struct r300_winsys_screen* winsys, int size);
+ /* Return current CS info. */
+ void (*get_cs_info)(struct r300_winsys_screen *winsys,
+ struct r300_cs_info *info);
/* Start a command emit. */
void (*begin_cs)(struct r300_winsys_screen* winsys,
@@ -121,8 +130,8 @@ struct r300_winsys_screen {
/* Write a relocated dword to the command buffer. */
void (*write_cs_reloc)(struct r300_winsys_screen *winsys,
struct r300_winsys_buffer *buf,
- uint32_t rd,
- uint32_t wd,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
uint32_t flags);
/* Finish a command emit. */
diff --git a/src/gallium/drivers/r600/Makefile b/src/gallium/drivers/r600/Makefile
new file mode 100644
index 0000000000..aae31a6a6e
--- /dev/null
+++ b/src/gallium/drivers/r600/Makefile
@@ -0,0 +1,27 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r600
+
+LIBRARY_INCLUDES = \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+C_SOURCES = \
+ r600_buffer.c \
+ r600_context.c \
+ r600_draw.c \
+ r600_blit.c \
+ r600_helper.c \
+ r600_query.c \
+ r600_resource.c \
+ r600_screen.c \
+ r600_state.c \
+ r600_texture.c \
+ r600_shader.c \
+ r600_compiler.c \
+ r600_compiler_tgsi.c \
+ r600_compiler_dump.c \
+ r600_compiler_r600.c \
+ r600_compiler_r700.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript
new file mode 100644
index 0000000000..26e2f1941c
--- /dev/null
+++ b/src/gallium/drivers/r600/SConscript
@@ -0,0 +1,37 @@
+Import('*')
+
+env = env.Clone()
+
+try:
+ env.ParseConfig('pkg-config --cflags libdrm_radeon')
+except OSError:
+ print 'warning: not building r600'
+ Return()
+
+env.Append(CPPPATH = [
+ '#/include',
+ '#/src/mesa',
+])
+
+r600 = env.ConvenienceLibrary(
+ target = 'r600',
+ source = [
+ 'r600_buffer.c',
+ 'r600_context.c',
+ 'r600_draw.c',
+ 'r600_blit.c',
+ 'r600_helper.c',
+ 'r600_query.c',
+ 'r600_resource.c',
+ 'r600_screen.c',
+ 'r600_state.c',
+ 'r600_texture.c',
+ 'r600_shader.c',
+ 'r600_compiler.c',
+ 'r600_compiler_tgsi.c',
+ 'r600_compiler_dump.c',
+ 'r600_compiler_r600.c',
+ 'r600_compiler_r700.c'
+ ])
+
+Export('r600')
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
new file mode 100644
index 0000000000..413c8ec403
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2009 Marek Olšák <maraeo@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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Marek Olšák
+ */
+#include <pipe/p_screen.h>
+#include <util/u_blitter.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include "r600_screen.h"
+#include "r600_context.h"
+
+static void r600_blitter_save_states(struct pipe_context *ctx)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+
+ util_blitter_save_blend(rctx->blitter,
+ rctx->draw->state[R600_BLEND]);
+ util_blitter_save_depth_stencil_alpha(rctx->blitter,
+ rctx->draw->state[R600_DSA]);
+ util_blitter_save_stencil_ref(rctx->blitter, &rctx->stencil_ref);
+ util_blitter_save_rasterizer(rctx->blitter,
+ rctx->draw->state[R600_RASTERIZER]);
+ util_blitter_save_fragment_shader(rctx->blitter,
+ rctx->ps_shader);
+ util_blitter_save_vertex_shader(rctx->blitter,
+ rctx->vs_shader);
+ util_blitter_save_vertex_elements(rctx->blitter,
+ rctx->vertex_elements);
+ util_blitter_save_viewport(rctx->blitter,
+ &rctx->viewport);
+}
+
+void r600_clear(struct pipe_context *ctx, unsigned buffers,
+ const float *rgba, double depth, unsigned stencil)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct pipe_framebuffer_state *fb = &rctx->fb_state;
+
+ r600_blitter_save_states(ctx);
+ util_blitter_clear(rctx->blitter, fb->width, fb->height,
+ fb->nr_cbufs, buffers, rgba, depth,
+ stencil);
+}
+
+void r600_surface_copy(struct pipe_context *ctx,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
+{
+}
+
+void r600_surface_fill(struct pipe_context *ctx,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value)
+{
+}
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
new file mode 100644
index 0000000000..272f4dd673
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ */
+#include <pipe/p_screen.h>
+#include <util/u_format.h>
+#include <util/u_math.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include "state_tracker/drm_api.h"
+#include "r600_screen.h"
+#include "r600_context.h"
+
+extern struct u_resource_vtbl r600_buffer_vtbl;
+
+static u32 r600_domain_from_usage(unsigned usage)
+{
+ u32 domain = RADEON_GEM_DOMAIN_GTT;
+
+ if (usage & PIPE_BIND_RENDER_TARGET) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
+ }
+ if (usage & PIPE_BIND_DEPTH_STENCIL) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
+ }
+ if (usage & PIPE_BIND_SAMPLER_VIEW) {
+ domain |= RADEON_GEM_DOMAIN_VRAM;
+ }
+ /* also need BIND_BLIT_SOURCE/DESTINATION ? */
+ if (usage & PIPE_BIND_VERTEX_BUFFER) {
+ domain |= RADEON_GEM_DOMAIN_GTT;
+ }
+ if (usage & PIPE_BIND_INDEX_BUFFER) {
+ domain |= RADEON_GEM_DOMAIN_GTT;
+ }
+
+ return domain;
+}
+
+struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
+{
+ struct r600_screen *rscreen = r600_screen(screen);
+ struct r600_buffer *rbuffer;
+ struct radeon_bo *bo;
+ struct pb_desc desc;
+ /* XXX We probably want a different alignment for buffers and textures. */
+ unsigned alignment = 4096;
+
+ rbuffer = CALLOC_STRUCT(r600_buffer);
+ if (rbuffer == NULL)
+ return NULL;
+
+ rbuffer->b.b = *templ;
+ pipe_reference_init(&rbuffer->b.b.reference, 1);
+ rbuffer->b.b.screen = screen;
+ rbuffer->b.vtbl = &r600_buffer_vtbl;
+
+ if (rbuffer->b.b.bind & PIPE_BIND_CONSTANT_BUFFER) {
+ desc.alignment = alignment;
+ desc.usage = rbuffer->b.b.bind;
+ rbuffer->pb = pb_malloc_buffer_create(rbuffer->b.b.width0,
+ &desc);
+ if (rbuffer->pb == NULL) {
+ free(rbuffer);
+ return NULL;
+ }
+ return &rbuffer->b.b;
+ }
+ rbuffer->domain = r600_domain_from_usage(rbuffer->b.b.bind);
+ bo = radeon_bo(rscreen->rw, 0, rbuffer->b.b.width0, alignment, NULL);
+ if (bo == NULL) {
+ FREE(rbuffer);
+ return NULL;
+ }
+ rbuffer->bo = bo;
+ return &rbuffer->b.b;
+}
+
+struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
+ void *ptr, unsigned bytes,
+ unsigned bind)
+{
+ struct r600_buffer *rbuffer;
+ struct r600_screen *rscreen = r600_screen(screen);
+ struct pipe_resource templ;
+
+ memset(&templ, 0, sizeof(struct pipe_resource));
+ templ.target = PIPE_BUFFER;
+ templ.format = PIPE_FORMAT_R8_UNORM;
+ templ.usage = PIPE_USAGE_IMMUTABLE;
+ templ.bind = bind;
+ templ.width0 = bytes;
+ templ.height0 = 1;
+ templ.depth0 = 1;
+
+ rbuffer = (struct r600_buffer*)r600_buffer_create(screen, &templ);
+ if (rbuffer == NULL) {
+ return NULL;
+ }
+ radeon_bo_map(rscreen->rw, rbuffer->bo);
+ memcpy(rbuffer->bo->data, ptr, bytes);
+ radeon_bo_unmap(rscreen->rw, rbuffer->bo);
+ return &rbuffer->b.b;
+}
+
+static void r600_buffer_destroy(struct pipe_screen *screen,
+ struct pipe_resource *buf)
+{
+ struct r600_buffer *rbuffer = (struct r600_buffer*)buf;
+ struct r600_screen *rscreen = r600_screen(screen);
+
+ if (rbuffer->pb) {
+ pipe_reference_init(&rbuffer->pb->base.reference, 0);
+ pb_destroy(rbuffer->pb);
+ rbuffer->pb = NULL;
+ }
+ if (rbuffer->bo) {
+ radeon_bo_decref(rscreen->rw, rbuffer->bo);
+ }
+ FREE(rbuffer);
+}
+
+static void *r600_buffer_transfer_map(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource;
+ struct r600_screen *rscreen = r600_screen(pipe->screen);
+ int write = 0;
+
+ if (rbuffer->pb) {
+ return (uint8_t*)pb_map(rbuffer->pb, transfer->usage) + transfer->box.x;
+ }
+ if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) {
+ /* FIXME */
+ }
+ if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ write = 1;
+ }
+ if (radeon_bo_map(rscreen->rw, rbuffer->bo)) {
+ return NULL;
+ }
+ return (uint8_t*)rbuffer->bo->data + transfer->box.x;
+}
+
+static void r600_buffer_transfer_unmap(struct pipe_context *pipe,
+ struct pipe_transfer *transfer)
+{
+ struct r600_buffer *rbuffer = (struct r600_buffer*)transfer->resource;
+ struct r600_screen *rscreen = r600_screen(pipe->screen);
+
+ if (rbuffer->pb) {
+ pb_unmap(rbuffer->pb);
+ } else {
+ radeon_bo_unmap(rscreen->rw, rbuffer->bo);
+ }
+}
+
+static void r600_buffer_transfer_flush_region(struct pipe_context *pipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
+{
+}
+
+unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
+ struct pipe_resource *buf,
+ unsigned face, unsigned level)
+{
+ /* XXX */
+ return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+}
+
+struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
+ struct winsys_handle *whandle)
+{
+ struct radeon *rw = (struct radeon*)screen->winsys;
+ struct r600_buffer *rbuffer;
+ struct radeon_bo *bo = NULL;
+
+ bo = radeon_bo(rw, whandle->handle, 0, 0, NULL);
+ if (bo == NULL) {
+ return NULL;
+ }
+
+ rbuffer = CALLOC_STRUCT(r600_buffer);
+ if (rbuffer == NULL) {
+ radeon_bo_decref(rw, bo);
+ return NULL;
+ }
+
+ pipe_reference_init(&rbuffer->b.b.reference, 1);
+ rbuffer->b.b.target = PIPE_BUFFER;
+ rbuffer->b.b.screen = screen;
+ rbuffer->b.vtbl = &r600_buffer_vtbl;
+ rbuffer->bo = bo;
+ return &rbuffer->b.b;
+}
+
+struct u_resource_vtbl r600_buffer_vtbl =
+{
+ u_default_resource_get_handle, /* get_handle */
+ r600_buffer_destroy, /* resource_destroy */
+ r600_buffer_is_referenced_by_cs, /* is_buffer_referenced */
+ u_default_get_transfer, /* get_transfer */
+ u_default_transfer_destroy, /* transfer_destroy */
+ r600_buffer_transfer_map, /* transfer_map */
+ r600_buffer_transfer_flush_region, /* transfer_flush_region */
+ r600_buffer_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
diff --git a/src/gallium/drivers/r600/r600_compiler.c b/src/gallium/drivers/r600/r600_compiler.c
new file mode 100644
index 0000000000..f1be2bbdf4
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_compiler.c
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include "r600_compiler.h"
+
+struct c_vector *c_vector_new(void)
+{
+ struct c_vector *v = calloc(1, sizeof(struct c_vector));
+
+ if (v == NULL) {
+ return NULL;
+ }
+ c_list_init(v);
+ return v;
+}
+
+static unsigned c_opcode_is_alu(unsigned opcode)
+{
+ switch (opcode) {
+ case C_OPCODE_MOV:
+ case C_OPCODE_MUL:
+ case C_OPCODE_MAD:
+ case C_OPCODE_ARL:
+ case C_OPCODE_LIT:
+ case C_OPCODE_RCP:
+ case C_OPCODE_RSQ:
+ case C_OPCODE_EXP:
+ case C_OPCODE_LOG:
+ case C_OPCODE_ADD:
+ case C_OPCODE_DP3:
+ case C_OPCODE_DP4:
+ case C_OPCODE_DST:
+ case C_OPCODE_MIN:
+ case C_OPCODE_MAX:
+ case C_OPCODE_SLT:
+ case C_OPCODE_SGE:
+ case C_OPCODE_SUB:
+ case C_OPCODE_LRP:
+ case C_OPCODE_CND:
+ case C_OPCODE_DP2A:
+ case C_OPCODE_FRC:
+ case C_OPCODE_CLAMP:
+ case C_OPCODE_FLR:
+ case C_OPCODE_ROUND:
+ case C_OPCODE_EX2:
+ case C_OPCODE_LG2:
+ case C_OPCODE_POW:
+ case C_OPCODE_XPD:
+ case C_OPCODE_ABS:
+ case C_OPCODE_RCC:
+ case C_OPCODE_DPH:
+ case C_OPCODE_COS:
+ case C_OPCODE_DDX:
+ case C_OPCODE_DDY:
+ case C_OPCODE_PK2H:
+ case C_OPCODE_PK2US:
+ case C_OPCODE_PK4B:
+ case C_OPCODE_PK4UB:
+ case C_OPCODE_RFL:
+ case C_OPCODE_SEQ:
+ case C_OPCODE_SFL:
+ case C_OPCODE_SGT:
+ case C_OPCODE_SIN:
+ case C_OPCODE_SLE:
+ case C_OPCODE_SNE:
+ case C_OPCODE_STR:
+ case C_OPCODE_UP2H:
+ case C_OPCODE_UP2US:
+ case C_OPCODE_UP4B:
+ case C_OPCODE_UP4UB:
+ case C_OPCODE_X2D:
+ case C_OPCODE_ARA:
+ case C_OPCODE_ARR:
+ case C_OPCODE_BRA:
+ case C_OPCODE_SSG:
+ case C_OPCODE_CMP:
+ case C_OPCODE_SCS:
+ case C_OPCODE_NRM:
+ case C_OPCODE_DIV:
+ case C_OPCODE_DP2:
+ case C_OPCODE_CEIL:
+ case C_OPCODE_I2F:
+ case C_OPCODE_NOT:
+ case C_OPCODE_TRUNC:
+ case C_OPCODE_SHL:
+ case C_OPCODE_AND:
+ case C_OPCODE_OR:
+ case C_OPCODE_MOD:
+ case C_OPCODE_XOR:
+ case C_OPCODE_SAD:
+ case C_OPCODE_NRM4:
+ case C_OPCODE_F2I:
+ case C_OPCODE_IDIV:
+ case C_OPCODE_IMAX:
+ case C_OPCODE_IMIN:
+ case C_OPCODE_INEG:
+ case C_OPCODE_ISGE:
+ case C_OPCODE_ISHR:
+ case C_OPCODE_ISLT:
+ case C_OPCODE_F2U:
+ case C_OPCODE_U2F:
+ case C_OPCODE_UADD:
+ case C_OPCODE_UDIV:
+ case C_OPCODE_UMAD:
+ case C_OPCODE_UMAX:
+ case C_OPCODE_UMIN:
+ case C_OPCODE_UMOD:
+ case C_OPCODE_UMUL:
+ case C_OPCODE_USEQ:
+ case C_OPCODE_USGE:
+ case C_OPCODE_USHR:
+ case C_OPCODE_USLT:
+ case C_OPCODE_USNE:
+ return 1;
+ case C_OPCODE_END:
+ case C_OPCODE_VFETCH:
+ case C_OPCODE_KILP:
+ case C_OPCODE_CAL:
+ case C_OPCODE_RET:
+ case C_OPCODE_TXB:
+ case C_OPCODE_TXL:
+ case C_OPCODE_BRK:
+ case C_OPCODE_IF:
+ case C_OPCODE_BGNFOR:
+ case C_OPCODE_REP:
+ case C_OPCODE_ELSE:
+ case C_OPCODE_ENDIF:
+ case C_OPCODE_ENDFOR:
+ case C_OPCODE_ENDREP:
+ case C_OPCODE_PUSHA:
+ case C_OPCODE_POPA:
+ case C_OPCODE_TXF:
+ case C_OPCODE_TXQ:
+ case C_OPCODE_CONT:
+ case C_OPCODE_EMIT:
+ case C_OPCODE_ENDPRIM:
+ case C_OPCODE_BGNLOOP:
+ case C_OPCODE_BGNSUB:
+ case C_OPCODE_ENDLOOP:
+ case C_OPCODE_ENDSUB:
+ case C_OPCODE_NOP:
+ case C_OPCODE_CALLNZ:
+ case C_OPCODE_IFC:
+ case C_OPCODE_BREAKC:
+ case C_OPCODE_KIL:
+ case C_OPCODE_TEX:
+ case C_OPCODE_TXD:
+ case C_OPCODE_TXP:
+ case C_OPCODE_SWITCH:
+ case C_OPCODE_CASE:
+ case C_OPCODE_DEFAULT:
+ case C_OPCODE_ENDSWITCH:
+ default:
+ return 0;
+ }
+}
+
+
+/* NEW */
+void c_node_init(struct c_node *node)
+{
+ memset(node, 0, sizeof(struct c_node));
+ c_list_init(&node->predecessors);
+ c_list_init(&node->successors);
+ c_list_init(&node->childs);
+ c_list_init(&node->insts);
+ node->parent = NULL;
+}
+
+static struct c_node_link *c_node_link_new(struct c_node *node)
+{
+ struct c_node_link *link;
+
+ link = calloc(1, sizeof(struct c_node_link));
+ if (link == NULL)
+ return NULL;
+ c_list_init(link);
+ link->node = node;
+ return link;
+}
+
+int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor)
+{
+ struct c_node_link *pedge, *sedge;
+
+ pedge = c_node_link_new(successor);
+ sedge = c_node_link_new(predecessor);
+ if (sedge == NULL || pedge == NULL) {
+ free(sedge);
+ free(pedge);
+ return -ENOMEM;
+ }
+ c_list_add_tail(pedge, &predecessor->successors);
+ c_list_add_tail(sedge, &successor->predecessors);
+ return 0;
+}
+
+int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction)
+{
+ struct c_instruction *inst = calloc(1, sizeof(struct c_instruction));
+
+ if (inst == NULL)
+ return -ENOMEM;
+ memcpy(inst, instruction, sizeof(struct c_instruction));
+ c_list_add(inst, &node->insts);
+ return 0;
+}
+
+int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction)
+{
+ struct c_instruction *inst = calloc(1, sizeof(struct c_instruction));
+
+ if (inst == NULL)
+ return -ENOMEM;
+ memcpy(inst, instruction, sizeof(struct c_instruction));
+ c_list_add_tail(inst, &node->insts);
+ return 0;
+}
+
+struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor)
+{
+ struct c_node *node = calloc(1, sizeof(struct c_node));
+
+ if (node == NULL)
+ return NULL;
+ c_node_init(node);
+ if (c_node_cfg_link(predecessor, node)) {
+ free(node);
+ return NULL;
+ }
+ c_list_add_tail(node, &shader->nodes);
+ return node;
+}
+
+int c_shader_init(struct c_shader *shader, unsigned type)
+{
+ unsigned i;
+ int r;
+
+ shader->type = type;
+ for (i = 0; i < C_FILE_COUNT; i++) {
+ shader->files[i].nvectors = 0;
+ c_list_init(&shader->files[i].vectors);
+ }
+ c_list_init(&shader->nodes);
+ c_node_init(&shader->entry);
+ c_node_init(&shader->end);
+ shader->entry.opcode = C_OPCODE_ENTRY;
+ shader->end.opcode = C_OPCODE_END;
+ r = c_node_cfg_link(&shader->entry, &shader->end);
+ if (r)
+ return r;
+ return 0;
+}
+
+struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid)
+{
+ struct c_vector *v = calloc(1, sizeof(struct c_vector));
+ int i;
+
+ if (v == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < 4; i++) {
+ v->channel[i] = calloc(1, sizeof(struct c_channel));
+ if (v->channel[i] == NULL)
+ goto out_err;
+ v->channel[i]->vindex = i;
+ v->channel[i]->vector = v;
+ }
+ v->file = file;
+ v->name = name;
+ v->sid = sid;
+ shader->files[v->file].nvectors++;
+ v->id = shader->nvectors++;
+ c_list_add_tail(v, &shader->files[v->file].vectors);
+ return v;
+out_err:
+ for (i = 0; i < 4; i++) {
+ free(v->channel[i]);
+ }
+ free(v);
+ return NULL;
+}
+
+static void c_node_remove_link(struct c_node_link *head, struct c_node *node)
+{
+ struct c_node_link *link, *tmp;
+
+ c_list_for_each_safe(link, tmp, head) {
+ if (link->node == node) {
+ c_list_del(link);
+ free(link);
+ }
+ }
+}
+
+static void c_node_destroy(struct c_node *node)
+{
+ struct c_instruction *i, *ni;
+ struct c_node_link *link, *tmp;
+
+ c_list_for_each_safe(i, ni, &node->insts) {
+ c_list_del(i);
+ free(i);
+ }
+ if (node->parent)
+ c_node_remove_link(&node->parent->childs, node);
+ node->parent = NULL;
+ c_list_for_each_safe(link, tmp, &node->predecessors) {
+ c_node_remove_link(&link->node->successors, node);
+ c_list_del(link);
+ free(link);
+ }
+ c_list_for_each_safe(link, tmp, &node->successors) {
+ c_node_remove_link(&link->node->predecessors, node);
+ c_list_del(link);
+ free(link);
+ }
+ c_list_for_each_safe(link, tmp, &node->childs) {
+ link->node->parent = NULL;
+ c_list_del(link);
+ free(link);
+ }
+}
+
+void c_shader_destroy(struct c_shader *shader)
+{
+ struct c_node *n, *nn;
+ struct c_vector *v, *nv;
+ unsigned i;
+
+ for (i = 0; i < C_FILE_COUNT; i++) {
+ shader->files[i].nvectors = 0;
+ c_list_for_each_safe(v, nv, &shader->files[i].vectors) {
+ c_list_del(v);
+ free(v->channel[0]);
+ free(v->channel[1]);
+ free(v->channel[2]);
+ free(v->channel[3]);
+ free(v);
+ }
+ }
+ c_list_for_each_safe(n, nn, &shader->nodes) {
+ c_list_del(n);
+ c_node_destroy(n);
+ }
+ memset(shader, 0, sizeof(struct c_shader));
+}
+
+static void c_shader_dfs_without_rec(struct c_node *entry, struct c_node *node)
+{
+ struct c_node_link *link;
+
+ if (entry == node || entry->visited)
+ return;
+ entry->visited = 1;
+ c_list_for_each(link, &entry->successors) {
+ c_shader_dfs_without_rec(link->node, node);
+ }
+}
+
+static void c_shader_dfs_without(struct c_shader *shader, struct c_node *node)
+{
+ struct c_node *n;
+
+ shader->entry.visited = 0;
+ shader->end.visited = 0;
+ c_list_for_each(n, &shader->nodes) {
+ n->visited = 0;
+ }
+ c_shader_dfs_without_rec(&shader->entry, node);
+}
+
+static int c_shader_build_dominator_tree_rec(struct c_shader *shader, struct c_node *node)
+{
+ struct c_node_link *link, *nlink;
+ unsigned found = 0;
+ int r;
+
+ if (node->done)
+ return 0;
+ node->done = 1;
+ c_list_for_each(link, &node->predecessors) {
+ /* if we remove this predecessor can we reach the current node ? */
+ c_shader_dfs_without(shader, link->node);
+ if (node->visited == 0) {
+ /* we were unable to visit current node thus current
+ * predecessor is the immediate dominator of node, as
+ * their can be only one immediate dominator we break
+ */
+ node->parent = link->node;
+ nlink = c_node_link_new(node);
+ if (nlink == NULL)
+ return -ENOMEM;
+ c_list_add_tail(nlink, &link->node->childs);
+ found = 1;
+ break;
+ }
+ }
+ /* this shouldn't happen there should at least be 1 denominator for each node */
+ if (!found && node->opcode != C_OPCODE_ENTRY) {
+ fprintf(stderr, "invalid flow control graph node %p (%d) has no immediate dominator\n",
+ node, node->opcode);
+ return -EINVAL;
+ }
+ c_list_for_each(link, &node->predecessors) {
+ r = c_shader_build_dominator_tree_rec(shader, link->node);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+int c_shader_build_dominator_tree(struct c_shader *shader)
+{
+ struct c_node *node;
+ c_list_for_each(node, &shader->nodes) {
+ node->done = 0;
+ }
+ return c_shader_build_dominator_tree_rec(shader, &shader->end);
+}
diff --git a/src/gallium/drivers/r600/r600_compiler.h b/src/gallium/drivers/r600/r600_compiler.h
new file mode 100644
index 0000000000..64dab5000b
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_compiler.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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 R600_COMPILER_H
+#define R600_COMPILER_H
+
+struct c_vector;
+
+/* operand are the basic source/destination of each operation */
+struct c_channel {
+ struct c_channel *next;
+ struct c_channel *prev;
+ unsigned vindex; /**< index in vector X,Y,Z,W (0,1,2,3) */
+ unsigned value; /**< immediate value 32bits */
+ struct c_vector *vector; /**< vector to which it belongs */
+};
+
+/* in GPU world most of the time operand are grouped into vector
+ * of 4 component this structure is mostly and handler to group
+ * operand into a same vector
+ */
+struct c_vector {
+ struct c_vector *next;
+ struct c_vector *prev;
+ unsigned id; /**< vector uniq id */
+ unsigned name; /**< semantic name */
+ unsigned file; /**< operand file C_FILE_* */
+ int sid; /**< semantic id */
+ struct c_channel *channel[4]; /**< operands */
+};
+
+#define c_list_init(e) do { (e)->next = e; (e)->prev = e; } while(0)
+#define c_list_add(e, h) do { (e)->next = (h)->next; (e)->prev = h; (h)->next = e; (e)->next->prev = e; } while(0)
+#define c_list_add_tail(e, h) do { (e)->next = h; (e)->prev = (h)->prev; (h)->prev = e; (e)->prev->next = e; } while(0)
+#define c_list_del(e) do { (e)->next->prev = (e)->prev; (e)->prev->next = (e)->next; c_list_init(e); } while(0)
+#define c_list_for_each(p, h) for (p = (h)->next; p != (h); p = p->next)
+#define c_list_for_each_from(p, s, h) for (p = s; p != (h); p = p->next)
+#define c_list_for_each_safe(p, n, h) for (p = (h)->next, n = p->next; p != (h); p = n, n = p->next)
+#define c_list_empty(h) ((h)->next == h)
+
+
+#define C_PROGRAM_TYPE_VS 0
+#define C_PROGRAM_TYPE_FS 1
+#define C_PROGRAM_TYPE_COUNT 2
+
+#define C_NODE_FLAG_ALU 1
+#define C_NODE_FLAG_FETCH 2
+
+#define C_SWIZZLE_X 0
+#define C_SWIZZLE_Y 1
+#define C_SWIZZLE_Z 2
+#define C_SWIZZLE_W 3
+#define C_SWIZZLE_0 4
+#define C_SWIZZLE_1 5
+#define C_SWIZZLE_D 6 /**< discard */
+
+#define C_FILE_NULL 0
+#define C_FILE_CONSTANT 1
+#define C_FILE_INPUT 2
+#define C_FILE_OUTPUT 3
+#define C_FILE_TEMPORARY 4
+#define C_FILE_SAMPLER 5
+#define C_FILE_ADDRESS 6
+#define C_FILE_IMMEDIATE 7
+#define C_FILE_LOOP 8
+#define C_FILE_PREDICATE 9
+#define C_FILE_SYSTEM_VALUE 10
+#define C_FILE_RESOURCE 11
+#define C_FILE_COUNT 12
+
+#define C_SEMANTIC_POSITION 0
+#define C_SEMANTIC_COLOR 1
+#define C_SEMANTIC_BCOLOR 2 /**< back-face color */
+#define C_SEMANTIC_FOG 3
+#define C_SEMANTIC_PSIZE 4
+#define C_SEMANTIC_GENERIC 5
+#define C_SEMANTIC_NORMAL 6
+#define C_SEMANTIC_FACE 7
+#define C_SEMANTIC_EDGEFLAG 8
+#define C_SEMANTIC_PRIMID 9
+#define C_SEMANTIC_INSTANCEID 10
+#define C_SEMANTIC_VERTEXID 11
+#define C_SEMANTIC_COUNT 12 /**< number of semantic values */
+
+#define C_OPCODE_NOP 0
+#define C_OPCODE_MOV 1
+#define C_OPCODE_LIT 2
+#define C_OPCODE_RCP 3
+#define C_OPCODE_RSQ 4
+#define C_OPCODE_EXP 5
+#define C_OPCODE_LOG 6
+#define C_OPCODE_MUL 7
+#define C_OPCODE_ADD 8
+#define C_OPCODE_DP3 9
+#define C_OPCODE_DP4 10
+#define C_OPCODE_DST 11
+#define C_OPCODE_MIN 12
+#define C_OPCODE_MAX 13
+#define C_OPCODE_SLT 14
+#define C_OPCODE_SGE 15
+#define C_OPCODE_MAD 16
+#define C_OPCODE_SUB 17
+#define C_OPCODE_LRP 18
+#define C_OPCODE_CND 19
+/* gap */
+#define C_OPCODE_DP2A 21
+/* gap */
+#define C_OPCODE_FRC 24
+#define C_OPCODE_CLAMP 25
+#define C_OPCODE_FLR 26
+#define C_OPCODE_ROUND 27
+#define C_OPCODE_EX2 28
+#define C_OPCODE_LG2 29
+#define C_OPCODE_POW 30
+#define C_OPCODE_XPD 31
+/* gap */
+#define C_OPCODE_ABS 33
+#define C_OPCODE_RCC 34
+#define C_OPCODE_DPH 35
+#define C_OPCODE_COS 36
+#define C_OPCODE_DDX 37
+#define C_OPCODE_DDY 38
+#define C_OPCODE_KILP 39 /* predicated kill */
+#define C_OPCODE_PK2H 40
+#define C_OPCODE_PK2US 41
+#define C_OPCODE_PK4B 42
+#define C_OPCODE_PK4UB 43
+#define C_OPCODE_RFL 44
+#define C_OPCODE_SEQ 45
+#define C_OPCODE_SFL 46
+#define C_OPCODE_SGT 47
+#define C_OPCODE_SIN 48
+#define C_OPCODE_SLE 49
+#define C_OPCODE_SNE 50
+#define C_OPCODE_STR 51
+#define C_OPCODE_TEX 52
+#define C_OPCODE_TXD 53
+#define C_OPCODE_TXP 54
+#define C_OPCODE_UP2H 55
+#define C_OPCODE_UP2US 56
+#define C_OPCODE_UP4B 57
+#define C_OPCODE_UP4UB 58
+#define C_OPCODE_X2D 59
+#define C_OPCODE_ARA 60
+#define C_OPCODE_ARR 61
+#define C_OPCODE_BRA 62
+#define C_OPCODE_CAL 63
+#define C_OPCODE_RET 64
+#define C_OPCODE_SSG 65 /* SGN */
+#define C_OPCODE_CMP 66
+#define C_OPCODE_SCS 67
+#define C_OPCODE_TXB 68
+#define C_OPCODE_NRM 69
+#define C_OPCODE_DIV 70
+#define C_OPCODE_DP2 71
+#define C_OPCODE_TXL 72
+#define C_OPCODE_BRK 73
+#define C_OPCODE_IF 74
+#define C_OPCODE_BGNFOR 75
+#define C_OPCODE_REP 76
+#define C_OPCODE_ELSE 77
+#define C_OPCODE_ENDIF 78
+#define C_OPCODE_ENDFOR 79
+#define C_OPCODE_ENDREP 80
+#define C_OPCODE_PUSHA 81
+#define C_OPCODE_POPA 82
+#define C_OPCODE_CEIL 83
+#define C_OPCODE_I2F 84
+#define C_OPCODE_NOT 85
+#define C_OPCODE_TRUNC 86
+#define C_OPCODE_SHL 87
+/* gap */
+#define C_OPCODE_AND 89
+#define C_OPCODE_OR 90
+#define C_OPCODE_MOD 91
+#define C_OPCODE_XOR 92
+#define C_OPCODE_SAD 93
+#define C_OPCODE_TXF 94
+#define C_OPCODE_TXQ 95
+#define C_OPCODE_CONT 96
+#define C_OPCODE_EMIT 97
+#define C_OPCODE_ENDPRIM 98
+#define C_OPCODE_BGNLOOP 99
+#define C_OPCODE_BGNSUB 100
+#define C_OPCODE_ENDLOOP 101
+#define C_OPCODE_ENDSUB 102
+/* gap */
+#define C_OPCODE_NRM4 112
+#define C_OPCODE_CALLNZ 113
+#define C_OPCODE_IFC 114
+#define C_OPCODE_BREAKC 115
+#define C_OPCODE_KIL 116 /* conditional kill */
+#define C_OPCODE_END 117 /* aka HALT */
+/* gap */
+#define C_OPCODE_F2I 119
+#define C_OPCODE_IDIV 120
+#define C_OPCODE_IMAX 121
+#define C_OPCODE_IMIN 122
+#define C_OPCODE_INEG 123
+#define C_OPCODE_ISGE 124
+#define C_OPCODE_ISHR 125
+#define C_OPCODE_ISLT 126
+#define C_OPCODE_F2U 127
+#define C_OPCODE_U2F 128
+#define C_OPCODE_UADD 129
+#define C_OPCODE_UDIV 130
+#define C_OPCODE_UMAD 131
+#define C_OPCODE_UMAX 132
+#define C_OPCODE_UMIN 133
+#define C_OPCODE_UMOD 134
+#define C_OPCODE_UMUL 135
+#define C_OPCODE_USEQ 136
+#define C_OPCODE_USGE 137
+#define C_OPCODE_USHR 138
+#define C_OPCODE_USLT 139
+#define C_OPCODE_USNE 140
+#define C_OPCODE_SWITCH 141
+#define C_OPCODE_CASE 142
+#define C_OPCODE_DEFAULT 143
+#define C_OPCODE_ENDSWITCH 144
+#define C_OPCODE_VFETCH 145
+#define C_OPCODE_ENTRY 146
+#define C_OPCODE_ARL 147
+#define C_OPCODE_LAST 148
+
+#define C_OPERAND_FLAG_ABS (1 << 0)
+#define C_OPERAND_FLAG_NEG (1 << 1)
+
+struct c_operand {
+ struct c_vector *vector;
+ unsigned swizzle[4];
+ unsigned flag[4];
+};
+
+struct c_instruction {
+ struct c_instruction *next, *prev;
+ unsigned opcode;
+ unsigned ninput;
+ struct c_operand input[3];
+ struct c_operand output;
+ unsigned write_mask;
+ void *backend;
+};
+
+struct c_node;
+
+struct c_node_link {
+ struct c_node_link *next;
+ struct c_node_link *prev;
+ struct c_node *node;
+};
+
+/**
+ * struct c_node
+ *
+ * @next: all node are in a double linked list, this point to
+ * next node
+ * @next: all node are in a double linked list, this point to
+ * previous node
+ * @predecessors: list of all predecessor nodes in the flow graph
+ * @successors: list of all sucessor nodes in the flow graph
+ * @parent: parent node in the depth first walk tree
+ * @childs: child nodes in the depth first walk tree
+ */
+struct c_node {
+ struct c_node *next, *prev;
+ struct c_node_link predecessors;
+ struct c_node_link successors;
+ struct c_node *parent;
+ struct c_node_link childs;
+ struct c_instruction insts;
+ unsigned opcode;
+ unsigned visited;
+ unsigned done;
+ void *backend;
+};
+
+struct c_file {
+ unsigned nvectors;
+ struct c_vector vectors;
+};
+
+struct c_shader {
+ unsigned nvectors;
+ struct c_file files[C_FILE_COUNT];
+ struct c_node nodes;
+ struct c_node entry;
+ struct c_node end;
+ unsigned type;
+};
+
+int c_shader_init(struct c_shader *shader, unsigned type);
+void c_shader_destroy(struct c_shader *shader);
+struct c_vector *c_shader_vector_new(struct c_shader *shader, unsigned file, unsigned name, int sid);
+int c_shader_build_dominator_tree(struct c_shader *shader);
+void c_shader_dump(struct c_shader *shader);
+
+void c_node_init(struct c_node *node);
+int c_node_add_new_instruction(struct c_node *node, struct c_instruction *instruction);
+int c_node_add_new_instruction_head(struct c_node *node, struct c_instruction *instruction);
+
+/* control flow graph functions */
+int c_node_cfg_link(struct c_node *predecessor, struct c_node *successor);
+struct c_node *c_node_cfg_new_after(struct c_node *predecessor);
+struct c_node *c_shader_cfg_new_node_after(struct c_shader *shader, struct c_node *predecessor);
+
+struct c_vector *c_vector_new(void);
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_compiler_dump.c b/src/gallium/drivers/r600/r600_compiler_dump.c
new file mode 100644
index 0000000000..9df6a38598
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_compiler_dump.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "r600_compiler.h"
+
+static const char *c_file_swz[] = {
+ "x",
+ "y",
+ "z",
+ "w",
+ "0",
+ "1",
+ ".",
+};
+
+static const char *c_file_str[] = {
+ "NULL",
+ "CONSTANT",
+ "INPUT",
+ "OUTPUT",
+ "TEMPORARY",
+ "SAMPLER",
+ "ADDRESS",
+ "IMMEDIATE",
+ "LOOP",
+ "PREDICATE",
+ "SYSTEM_VALUE",
+};
+
+static const char *c_semantic_str[] = {
+ "POSITION",
+ "COLOR",
+ "BCOLOR",
+ "FOG",
+ "PSIZE",
+ "GENERIC",
+ "NORMAL",
+ "FACE",
+ "EDGEFLAG",
+ "PRIMID",
+ "INSTANCEID",
+};
+
+static const char *c_opcode_str[] = {
+ "ARL",
+ "MOV",
+ "LIT",
+ "RCP",
+ "RSQ",
+ "EXP",
+ "LOG",
+ "MUL",
+ "ADD",
+ "DP3",
+ "DP4",
+ "DST",
+ "MIN",
+ "MAX",
+ "SLT",
+ "SGE",
+ "MAD",
+ "SUB",
+ "LRP",
+ "CND",
+ "(INVALID)",
+ "DP2A",
+ "(INVALID)",
+ "(INVALID)",
+ "FRC",
+ "CLAMP",
+ "FLR",
+ "ROUND",
+ "EX2",
+ "LG2",
+ "POW",
+ "XPD",
+ "(INVALID)",
+ "ABS",
+ "RCC",
+ "DPH",
+ "COS",
+ "DDX",
+ "DDY",
+ "KILP",
+ "PK2H",
+ "PK2US",
+ "PK4B",
+ "PK4UB",
+ "RFL",
+ "SEQ",
+ "SFL",
+ "SGT",
+ "SIN",
+ "SLE",
+ "SNE",
+ "STR",
+ "TEX",
+ "TXD",
+ "TXP",
+ "UP2H",
+ "UP2US",
+ "UP4B",
+ "UP4UB",
+ "X2D",
+ "ARA",
+ "ARR",
+ "BRA",
+ "CAL",
+ "RET",
+ "SSG",
+ "CMP",
+ "SCS",
+ "TXB",
+ "NRM",
+ "DIV",
+ "DP2",
+ "TXL",
+ "BRK",
+ "IF",
+ "BGNFOR",
+ "REP",
+ "ELSE",
+ "ENDIF",
+ "ENDFOR",
+ "ENDREP",
+ "PUSHA",
+ "POPA",
+ "CEIL",
+ "I2F",
+ "NOT",
+ "TRUNC",
+ "SHL",
+ "(INVALID)",
+ "AND",
+ "OR",
+ "MOD",
+ "XOR",
+ "SAD",
+ "TXF",
+ "TXQ",
+ "CONT",
+ "EMIT",
+ "ENDPRIM",
+ "BGNLOOP",
+ "BGNSUB",
+ "ENDLOOP",
+ "ENDSUB",
+ "(INVALID)",
+ "(INVALID)",
+ "(INVALID)",
+ "(INVALID)",
+ "NOP",
+ "(INVALID)",
+ "(INVALID)",
+ "(INVALID)",
+ "(INVALID)",
+ "NRM4",
+ "CALLNZ",
+ "IFC",
+ "BREAKC",
+ "KIL",
+ "END",
+ "(INVALID)",
+ "F2I",
+ "IDIV",
+ "IMAX",
+ "IMIN",
+ "INEG",
+ "ISGE",
+ "ISHR",
+ "ISLT",
+ "F2U",
+ "U2F",
+ "UADD",
+ "UDIV",
+ "UMAD",
+ "UMAX",
+ "UMIN",
+ "UMOD",
+ "UMUL",
+ "USEQ",
+ "USGE",
+ "USHR",
+ "USLT",
+ "USNE",
+ "SWITCH",
+ "CASE",
+ "DEFAULT",
+ "ENDSWITCH",
+ "VFETCH",
+ "ENTRY",
+};
+
+static inline const char *c_get_name(const char *name[], unsigned i)
+{
+ return name[i];
+}
+
+static void pindent(unsigned indent)
+{
+ unsigned i;
+ for (i = 0; i < indent; i++)
+ fprintf(stderr, " ");
+}
+
+static void c_node_dump(struct c_node *node, unsigned indent)
+{
+ struct c_instruction *i;
+ unsigned j;
+
+ pindent(indent); fprintf(stderr, "# node %s\n", c_get_name(c_opcode_str, node->opcode));
+ c_list_for_each(i, &node->insts) {
+ pindent(indent); fprintf(stderr, "%s", c_get_name(c_opcode_str, i->opcode));
+ fprintf(stderr, " %s[%d][%s%s%s%s]",
+ c_get_name(c_file_str, i->output.vector->file),
+ i->output.vector->id,
+ c_get_name(c_file_swz, i->output.swizzle[0]),
+ c_get_name(c_file_swz, i->output.swizzle[1]),
+ c_get_name(c_file_swz, i->output.swizzle[2]),
+ c_get_name(c_file_swz, i->output.swizzle[3]));
+ for (j = 0; j < i->ninput; j++) {
+ fprintf(stderr, " %s[%d][%s%s%s%s]",
+ c_get_name(c_file_str, i->input[j].vector->file),
+ i->input[j].vector->id,
+ c_get_name(c_file_swz, i->input[j].swizzle[0]),
+ c_get_name(c_file_swz, i->input[j].swizzle[1]),
+ c_get_name(c_file_swz, i->input[j].swizzle[2]),
+ c_get_name(c_file_swz, i->input[j].swizzle[3]));
+ }
+ fprintf(stderr, ";\n");
+ }
+}
+
+static void c_shader_dump_rec(struct c_shader *shader, struct c_node *node, unsigned indent)
+{
+ struct c_node_link *link;
+
+ c_node_dump(node, indent);
+ c_list_for_each(link, &node->childs) {
+ c_shader_dump_rec(shader, link->node, indent + 1);
+ }
+}
+
+void c_shader_dump(struct c_shader *shader)
+{
+ c_shader_dump_rec(shader, &shader->entry, 0);
+}
diff --git a/src/gallium/drivers/r600/r600_compiler_r600.c b/src/gallium/drivers/r600/r600_compiler_r600.c
new file mode 100644
index 0000000000..1be5bf2b4a
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_compiler_r600.c
@@ -0,0 +1,869 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <util/u_format.h>
+#include "r600_screen.h"
+#include "r600_context.h"
+#include "r600_sq.h"
+
+
+struct r600_alu_instruction {
+ unsigned copcode;
+ enum r600_instruction instruction;
+};
+
+static int r600_shader_alu_translate(struct r600_shader *rshader,
+ struct r600_shader_node *node,
+ struct c_instruction *instruction);
+struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST];
+struct r600_instruction_info r600_instruction_info[];
+
+int r600_shader_insert_fetch(struct c_shader *shader)
+{
+ struct c_vector *vi, *vr, *v, *nv;
+ struct c_instruction instruction;
+ int r;
+
+ if (shader->type != C_PROGRAM_TYPE_VS)
+ return 0;
+ vi = c_shader_vector_new(shader, C_FILE_INPUT, C_SEMANTIC_VERTEXID, -1);
+ if (vi == NULL)
+ return -ENOMEM;
+ c_list_for_each_safe(v, nv, &shader->files[C_FILE_INPUT].vectors) {
+ if (v == vi)
+ continue;
+ vr = c_shader_vector_new(shader, C_FILE_RESOURCE, C_SEMANTIC_GENERIC, -1);
+ if (vr == NULL)
+ return -ENOMEM;
+ memset(&instruction, 0, sizeof(struct c_instruction));
+ instruction.opcode = C_OPCODE_VFETCH;
+ instruction.write_mask = 0xF;
+ instruction.ninput = 2;
+ instruction.output.vector = v;
+ instruction.input[0].vector = vi;
+ instruction.input[1].vector = vr;
+ instruction.output.swizzle[0] = C_SWIZZLE_X;
+ instruction.output.swizzle[1] = C_SWIZZLE_Y;
+ instruction.output.swizzle[2] = C_SWIZZLE_Z;
+ instruction.output.swizzle[3] = C_SWIZZLE_W;
+ r = c_node_add_new_instruction_head(&shader->entry, &instruction);
+ if (r)
+ return r;
+ c_list_del(v);
+ shader->files[C_FILE_INPUT].nvectors--;
+ c_list_add_tail(v, &shader->files[C_FILE_TEMPORARY].vectors);
+ shader->files[C_FILE_TEMPORARY].nvectors++;
+ v->file = C_FILE_TEMPORARY;
+ }
+ return 0;
+}
+
+void r600_shader_cleanup(struct r600_shader *rshader)
+{
+ struct r600_shader_node *n, *nn;
+ struct r600_shader_vfetch *vf, *nvf;
+ struct r600_shader_alu *alu, *nalu;
+ int i;
+
+ if (rshader == NULL)
+ return;
+ if (rshader->gpr) {
+ for (i = 0; i < rshader->nvector; i++) {
+ free(rshader->gpr[i]);
+ }
+ free(rshader->gpr);
+ rshader->gpr = NULL;
+ }
+ c_list_for_each_safe(n, nn, &rshader->nodes) {
+ c_list_del(n);
+ c_list_for_each_safe(vf, nvf, &n->vfetch) {
+ c_list_del(vf);
+ free(vf);
+ }
+ c_list_for_each_safe(alu, nalu, &n->alu) {
+ c_list_del(alu);
+ free(alu);
+ }
+ free(n);
+ }
+ free(rshader->bcode);
+ return;
+}
+
+int r600_shader_vfetch_bytecode(struct r600_shader *rshader,
+ struct r600_shader_node *rnode,
+ struct r600_shader_vfetch *vfetch,
+ unsigned *cid)
+{
+ unsigned id = *cid;
+
+ vfetch->cf_addr = id;
+ rshader->bcode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vfetch->src[1].sel) |
+ S_SQ_VTX_WORD0_SRC_GPR(vfetch->src[0].sel) |
+ S_SQ_VTX_WORD0_SRC_SEL_X(vfetch->src[0].sel) |
+ S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(0x1F);
+ rshader->bcode[id++] = S_SQ_VTX_WORD1_DST_SEL_X(vfetch->dst[0].chan) |
+ S_SQ_VTX_WORD1_DST_SEL_Y(vfetch->dst[1].chan) |
+ S_SQ_VTX_WORD1_DST_SEL_Z(vfetch->dst[2].chan) |
+ S_SQ_VTX_WORD1_DST_SEL_W(vfetch->dst[3].chan) |
+ S_SQ_VTX_WORD1_USE_CONST_FIELDS(1) |
+ S_SQ_VTX_WORD1_GPR_DST_GPR(vfetch->dst[0].sel);
+ rshader->bcode[id++] = S_SQ_VTX_WORD2_MEGA_FETCH(1);
+ rshader->bcode[id++] = 0;
+ *cid = id;
+ return 0;
+}
+
+int r600_shader_update(struct r600_shader *rshader, enum pipe_format *resource_format)
+{
+ struct r600_shader_node *rnode;
+ struct r600_shader_vfetch *vfetch;
+ unsigned i;
+
+ memcpy(rshader->resource_format, resource_format,
+ rshader->nresource * sizeof(enum pipe_format));
+ c_list_for_each(rnode, &rshader->nodes) {
+ c_list_for_each(vfetch, &rnode->vfetch) {
+ const struct util_format_description *desc;
+ i = vfetch->cf_addr + 1;
+ rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_X;
+ rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Y;
+ rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_Z;
+ rshader->bcode[i] &= C_SQ_VTX_WORD1_DST_SEL_W;
+ desc = util_format_description(resource_format[vfetch->src[1].sel]);
+ if (desc == NULL) {
+ fprintf(stderr, "%s unknown format %d\n", __func__, resource_format[vfetch->src[1].sel]);
+ continue;
+ }
+ /* WARNING so far TGSI swizzle match R600 ones */
+ rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_X(desc->swizzle[0]);
+ rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Y(desc->swizzle[1]);
+ rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_Z(desc->swizzle[2]);
+ rshader->bcode[i] |= S_SQ_VTX_WORD1_DST_SEL_W(desc->swizzle[3]);
+ }
+ }
+ return 0;
+}
+
+int r600_shader_register(struct r600_shader *rshader)
+{
+ struct c_vector *v, *nv;
+ unsigned tid, cid, rid, i;
+
+ rshader->nvector = rshader->cshader.nvectors;
+ rshader->gpr = calloc(rshader->nvector, sizeof(void*));
+ if (rshader->gpr == NULL)
+ return -ENOMEM;
+ tid = 0;
+ cid = 0;
+ rid = 0;
+ /* alloc input first */
+ c_list_for_each(v, &rshader->cshader.files[C_FILE_INPUT].vectors) {
+ nv = c_vector_new();
+ if (nv == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(nv, v, sizeof(struct c_vector));
+ nv->id = tid++;
+ rshader->gpr[v->id] = nv;
+ }
+ for (i = 0; i < C_FILE_COUNT; i++) {
+ if (i == C_FILE_INPUT || i == C_FILE_IMMEDIATE)
+ continue;
+ c_list_for_each(v, &rshader->cshader.files[i].vectors) {
+ switch (v->file) {
+ case C_FILE_OUTPUT:
+ case C_FILE_TEMPORARY:
+ nv = c_vector_new();
+ if (nv == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(nv, v, sizeof(struct c_vector));
+ nv->id = tid++;
+ rshader->gpr[v->id] = nv;
+ break;
+ case C_FILE_CONSTANT:
+ nv = c_vector_new();
+ if (nv == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(nv, v, sizeof(struct c_vector));
+ nv->id = (cid++) + 256;
+ rshader->gpr[v->id] = nv;
+ break;
+ case C_FILE_RESOURCE:
+ nv = c_vector_new();
+ if (nv == NULL) {
+ return -ENOMEM;
+ }
+ memcpy(nv, v, sizeof(struct c_vector));
+ nv->id = (rid++);
+ rshader->gpr[v->id] = nv;
+ break;
+ default:
+ fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, v->file);
+ return -EINVAL;
+ }
+ }
+ }
+ rshader->ngpr = tid;
+ rshader->nconstant = cid;
+ rshader->nresource = rid;
+ return 0;
+}
+
+int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle,
+ struct r600_shader_operand *operand)
+{
+ struct c_vector *tmp;
+
+ /* Values [0,127] correspond to GPR[0..127].
+ * Values [256,511] correspond to cfile constants c[0..255].
+ * Other special values are shown in the list below.
+ * 248 SQ_ALU_SRC_0: special constant 0.0.
+ * 249 SQ_ALU_SRC_1: special constant 1.0 float.
+ * 250 SQ_ALU_SRC_1_INT: special constant 1 integer.
+ * 251 SQ_ALU_SRC_M_1_INT: special constant -1 integer.
+ * 252 SQ_ALU_SRC_0_5: special constant 0.5 float.
+ * 253 SQ_ALU_SRC_LITERAL: literal constant.
+ * 254 SQ_ALU_SRC_PV: previous vector result.
+ * 255 SQ_ALU_SRC_PS: previous scalar result.
+ */
+ operand->vector = v;
+ operand->sel = 248;
+ operand->chan = 0;
+ operand->neg = 0;
+ operand->abs = 0;
+ if (v == NULL)
+ return 0;
+ if (v->file == C_FILE_IMMEDIATE) {
+ operand->sel = 253;
+ } else {
+ tmp = rshader->gpr[v->id];
+ if (tmp == NULL) {
+ fprintf(stderr, "%s %d unknown register\n", __FILE__, __LINE__);
+ return -EINVAL;
+ }
+ operand->sel = tmp->id;
+ }
+ operand->chan = swizzle;
+ switch (swizzle) {
+ case C_SWIZZLE_X:
+ case C_SWIZZLE_Y:
+ case C_SWIZZLE_Z:
+ case C_SWIZZLE_W:
+ break;
+ case C_SWIZZLE_0:
+ operand->sel = 248;
+ operand->chan = 0;
+ break;
+ case C_SWIZZLE_1:
+ operand->sel = 249;
+ operand->chan = 0;
+ break;
+ default:
+ fprintf(stderr, "%s %d invalid swizzle %d\n", __FILE__, __LINE__, swizzle);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct r600_shader_node *r600_shader_new_node(struct r600_shader *rshader, struct c_node *node)
+{
+ struct r600_shader_node *rnode;
+
+ rnode = CALLOC_STRUCT(r600_shader_node);
+ if (rnode == NULL)
+ return NULL;
+ rnode->node = node;
+ c_list_init(&rnode->vfetch);
+ c_list_init(&rnode->alu);
+ c_list_add_tail(rnode, &rshader->nodes);
+ return rnode;
+}
+
+static int r600_shader_add_vfetch(struct r600_shader *rshader,
+ struct r600_shader_node *node,
+ struct c_instruction *instruction)
+{
+ struct r600_shader_vfetch *vfetch;
+ struct r600_shader_node *rnode;
+ int r;
+
+ if (instruction == NULL)
+ return 0;
+ if (instruction->opcode != C_OPCODE_VFETCH)
+ return 0;
+ if (!c_list_empty(&node->alu)) {
+ rnode = r600_shader_new_node(rshader, node->node);
+ if (rnode == NULL)
+ return -ENOMEM;
+ node = rnode;
+ }
+ vfetch = calloc(1, sizeof(struct r600_shader_vfetch));
+ if (vfetch == NULL)
+ return -ENOMEM;
+ r = r600_shader_find_gpr(rshader, instruction->output.vector, 0, &vfetch->dst[0]);
+ if (r)
+ return r;
+ r = r600_shader_find_gpr(rshader, instruction->input[0].vector, 0, &vfetch->src[0]);
+ if (r)
+ return r;
+ r = r600_shader_find_gpr(rshader, instruction->input[1].vector, 0, &vfetch->src[1]);
+ if (r)
+ return r;
+ vfetch->dst[0].chan = C_SWIZZLE_X;
+ vfetch->dst[1].chan = C_SWIZZLE_Y;
+ vfetch->dst[2].chan = C_SWIZZLE_Z;
+ vfetch->dst[3].chan = C_SWIZZLE_W;
+ c_list_add_tail(vfetch, &node->vfetch);
+ node->nslot += 2;
+ return 0;
+}
+
+static int r600_node_translate(struct r600_shader *rshader, struct c_node *node)
+{
+ struct c_instruction *instruction;
+ struct r600_shader_node *rnode;
+ int r;
+
+ rnode = r600_shader_new_node(rshader, node);
+ if (rnode == NULL)
+ return -ENOMEM;
+ c_list_for_each(instruction, &node->insts) {
+ switch (instruction->opcode) {
+ case C_OPCODE_VFETCH:
+ r = r600_shader_add_vfetch(rshader, rnode, instruction);
+ if (r) {
+ fprintf(stderr, "%s %d vfetch failed\n", __func__, __LINE__);
+ return r;
+ }
+ break;
+ default:
+ r = r600_shader_alu_translate(rshader, rnode, instruction);
+ if (r) {
+ fprintf(stderr, "%s %d alu failed\n", __func__, __LINE__);
+ return r;
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node)
+{
+ struct c_node_link *link;
+ int r;
+
+ if (node->opcode == C_OPCODE_END)
+ return 0;
+ r = r600_node_translate(rshader, node);
+ if (r)
+ return r;
+ c_list_for_each(link, &node->childs) {
+ r = r600_shader_translate_rec(rshader, link->node);
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+static struct r600_shader_alu *r600_shader_insert_alu(struct r600_shader *rshader, struct r600_shader_node *node)
+{
+ struct r600_shader_alu *alu;
+
+ alu = CALLOC_STRUCT(r600_shader_alu);
+ if (alu == NULL)
+ return NULL;
+ alu->alu[0].inst = INST_NOP;
+ alu->alu[1].inst = INST_NOP;
+ alu->alu[2].inst = INST_NOP;
+ alu->alu[3].inst = INST_NOP;
+ alu->alu[4].inst = INST_NOP;
+ alu->alu[0].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu->alu[1].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu->alu[2].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu->alu[3].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ alu->alu[4].opcode = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP;
+ c_list_add_tail(alu, &node->alu);
+ return alu;
+}
+
+static int r600_shader_node_add_alu(struct r600_shader *rshader,
+ struct r600_shader_node *node,
+ struct r600_shader_alu *alu,
+ unsigned instruction,
+ unsigned ninput,
+ struct r600_shader_operand *dst,
+ struct r600_shader_operand src[3])
+{
+ struct r600_shader_alu *nalu;
+ unsigned nconstant = 0, nliteral = 0, slot, i;
+
+ /* count number of constant & literal */
+ for (i = 0; i < ninput; i++) {
+ if (src[i].vector->file == C_FILE_IMMEDIATE) {
+ nliteral++;
+ nconstant++;
+ }
+ }
+
+ slot = dst->chan;
+ if (r600_instruction_info[instruction].is_trans) {
+ slot = 4;
+ }
+
+ /* allocate new alu group if necessary */
+ nalu = alu;
+ if (alu == NULL) {
+ nalu = r600_shader_insert_alu(rshader, node);
+ if (nalu == NULL)
+ return -ENOMEM;
+ alu = nalu;
+ }
+ if ((alu->alu[slot].inst != INST_NOP &&
+ alu->alu[4].inst != INST_NOP) ||
+ (alu->nconstant + nconstant) > 4 ||
+ (alu->nliteral + nliteral) > 4) {
+ /* neither trans neither dst slot are free need new alu */
+ nalu = r600_shader_insert_alu(rshader, node);
+ if (nalu == NULL)
+ return -ENOMEM;
+ alu = nalu;
+ }
+ if (alu->alu[slot].inst != INST_NOP) {
+ slot = 4;
+ }
+
+ alu->alu[slot].dst = *dst;
+ alu->alu[slot].inst = instruction;
+ alu->alu[slot].opcode = r600_instruction_info[instruction].opcode;
+ alu->alu[slot].is_op3 = r600_instruction_info[instruction].is_op3;
+ for (i = 0; i < ninput; i++) {
+ alu->alu[slot].src[i] = src[i];
+ if (src[i].vector->file == C_FILE_IMMEDIATE) {
+ alu->literal[alu->nliteral++] = src[i].vector->channel[0]->value;
+ alu->literal[alu->nliteral++] = src[i].vector->channel[1]->value;
+ alu->literal[alu->nliteral++] = src[i].vector->channel[2]->value;
+ alu->literal[alu->nliteral++] = src[i].vector->channel[3]->value;
+ }
+ }
+ return 0;
+}
+
+static int r600_shader_alu_translate(struct r600_shader *rshader,
+ struct r600_shader_node *node,
+ struct c_instruction *instruction)
+{
+ struct r600_alu_instruction *ainfo = &r600_alu_instruction[instruction->opcode];
+ struct r600_instruction_info *info;
+ struct r600_shader_alu *alu;
+ struct r600_shader_node *rnode;
+ int r, i, j;
+ struct r600_shader_operand dst;
+ struct r600_shader_operand src[3];
+
+ if (!c_list_empty(&node->vfetch)) {
+ rnode = r600_shader_new_node(rshader, node->node);
+ if (rnode == NULL) {
+ fprintf(stderr, "%s %d new node failed\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ node = rnode;
+ }
+ alu = r600_shader_insert_alu(rshader, node);
+ if (alu == NULL) {
+ fprintf(stderr, "%s %d instert alu node failed\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ for (i = 0; i < 4; i++) {
+ if (!(instruction->write_mask) || instruction->output.swizzle[i] == C_SWIZZLE_D)
+ continue;
+ if (ainfo->instruction == INST_NOP) {
+ fprintf(stderr, "%s:%d unsupported instruction %d\n", __FILE__, __LINE__, instruction->opcode);
+ continue;
+ }
+ info = &r600_instruction_info[ainfo->instruction];
+ r = r600_shader_find_gpr(rshader, instruction->output.vector,
+ instruction->output.swizzle[i], &dst);
+ if (r) {
+ fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
+ return r;
+ }
+ for (j = 0; j < instruction->ninput; j++) {
+ r = r600_shader_find_gpr(rshader, instruction->input[j].vector,
+ instruction->input[j].swizzle[i], &src[j]);
+ if (r) {
+ fprintf(stderr, "%s %d register failed\n", __FILE__, __LINE__);
+ return r;
+ }
+ }
+ r = r600_shader_node_add_alu(rshader, node, alu, ainfo->instruction,
+ instruction->ninput, &dst, src);
+ if (r) {
+ fprintf(stderr, "%s %d failed\n", __FILE__, __LINE__);
+ return r;
+ }
+ }
+ return 0;
+}
+
+void r600_shader_node_place(struct r600_shader *rshader)
+{
+ struct r600_shader_node *node, *nnode;
+ struct r600_shader_alu *alu, *nalu;
+ struct r600_shader_vfetch *vfetch, *nvfetch;
+ unsigned cf_id = 0, cf_addr = 0;
+
+ rshader->ncf = 0;
+ rshader->nslot = 0;
+ c_list_for_each_safe(node, nnode, &rshader->nodes) {
+ c_list_for_each_safe(alu, nalu, &node->alu) {
+ node->nslot += alu->nalu;
+ node->nslot += alu->nliteral >> 1;
+ }
+ node->nfetch = 0;
+ c_list_for_each_safe(vfetch, nvfetch, &node->vfetch) {
+ node->nslot += 2;
+ node->nfetch += 1;
+ }
+ if (!c_list_empty(&node->vfetch)) {
+ /* fetch node need to be 16 bytes aligned*/
+ cf_addr += 1;
+ cf_addr &= 0xFFFFFFFEUL;
+ }
+ node->cf_id = cf_id;
+ node->cf_addr = cf_addr;
+ cf_id += 2;
+ cf_addr += node->nslot * 2;
+ rshader->ncf++;
+ }
+ rshader->nslot = cf_addr;
+ c_list_for_each_safe(node, nnode, &rshader->nodes) {
+ node->cf_addr += cf_id * 2;
+ }
+ rshader->ncf += rshader->cshader.files[C_FILE_OUTPUT].nvectors;
+ rshader->ndw = rshader->ncf * 2 + rshader->nslot * 2;
+}
+
+int r600_shader_legalize(struct r600_shader *rshader)
+{
+ struct r600_shader_node *node, *nnode;
+ struct r600_shader_alu *alu, *nalu;
+
+ c_list_for_each_safe(node, nnode, &rshader->nodes) {
+ c_list_for_each_safe(alu, nalu, &node->alu) {
+ alu->nalu = 5;
+ alu->alu[4].last = 1;
+ }
+ }
+ return 0;
+}
+
+
+
+
+
+
+
+struct r600_instruction_info r600_instruction_info[] = {
+ {INST_ADD, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, 0, 0},
+ {INST_MUL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, 0, 0},
+ {INST_MUL_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE, 0, 0},
+ {INST_MAX, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX, 0, 0},
+ {INST_MIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN, 0, 0},
+ {INST_MAX_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10, 0, 0},
+ {INST_MIN_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10, 0, 0},
+ {INST_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE, 0, 0},
+ {INST_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT, 0, 0},
+ {INST_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE, 0, 0},
+ {INST_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE, 0, 0},
+ {INST_SETE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10, 0, 0},
+ {INST_SETGT_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10, 0, 0},
+ {INST_SETGE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10, 0, 0},
+ {INST_SETNE_DX10, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10, 0, 0},
+ {INST_FRACT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT, 0, 0},
+ {INST_TRUNC, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC, 0, 0},
+ {INST_CEIL, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL, 0, 0},
+ {INST_RNDNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE, 0, 0},
+ {INST_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR, 0, 0},
+ {INST_MOVA, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA, 0, 0},
+ {INST_MOVA_FLOOR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR, 0, 0},
+ {INST_MOVA_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT, 0, 0},
+ {INST_MOV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV, 0, 0},
+ {INST_NOP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, 0, 0},
+ {INST_PRED_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT, 0, 0},
+ {INST_PRED_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT, 0, 0},
+ {INST_PRED_SETE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE, 0, 0},
+ {INST_PRED_SETGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT, 0, 0},
+ {INST_PRED_SETGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE, 0, 0},
+ {INST_PRED_SETNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE, 0, 0},
+ {INST_PRED_SET_INV, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV, 0, 0},
+ {INST_PRED_SET_POP, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP, 0, 0},
+ {INST_PRED_SET_CLR, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR, 0, 0},
+ {INST_PRED_SET_RESTORE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE, 0, 0},
+ {INST_PRED_SETE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH, 0, 0},
+ {INST_PRED_SETGT_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH, 0, 0},
+ {INST_PRED_SETGE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH, 0, 0},
+ {INST_PRED_SETNE_PUSH, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH, 0, 0},
+ {INST_KILLE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE, 0, 0},
+ {INST_KILLGT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT, 0, 0},
+ {INST_KILLGE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE, 0, 0},
+ {INST_KILLNE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE, 0, 0},
+ {INST_AND_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT, 0, 0},
+ {INST_OR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT, 0, 0},
+ {INST_XOR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT, 0, 0},
+ {INST_NOT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT, 0, 0},
+ {INST_ADD_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT, 0, 0},
+ {INST_SUB_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT, 0, 0},
+ {INST_MAX_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT, 0, 0},
+ {INST_MIN_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT, 0, 0},
+ {INST_MAX_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT, 0, 0},
+ {INST_MIN_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT, 0, 0},
+ {INST_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT, 0, 0},
+ {INST_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT, 0, 0},
+ {INST_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT, 0, 0},
+ {INST_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT, 0, 0},
+ {INST_SETGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT, 0, 0},
+ {INST_SETGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT, 0, 0},
+ {INST_KILLGT_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT, 0, 0},
+ {INST_KILLGE_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT, 0, 0},
+ {INST_PRED_SETE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT, 0, 0},
+ {INST_PRED_SETGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT, 0, 0},
+ {INST_PRED_SETGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT, 0, 0},
+ {INST_PRED_SETNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT, 0, 0},
+ {INST_KILLE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT, 0, 0},
+ {INST_KILLGT_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT, 0, 0},
+ {INST_KILLGE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT, 0, 0},
+ {INST_KILLNE_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT, 0, 0},
+ {INST_PRED_SETE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT, 0, 0},
+ {INST_PRED_SETGT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT, 0, 0},
+ {INST_PRED_SETGE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT, 0, 0},
+ {INST_PRED_SETNE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT, 0, 0},
+ {INST_PRED_SETLT_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT, 0, 0},
+ {INST_PRED_SETLE_PUSH_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT, 0, 0},
+ {INST_DOT4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, 0, 0},
+ {INST_DOT4_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE, 0, 0},
+ {INST_CUBE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE, 0, 0},
+ {INST_MAX4, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4, 0, 0},
+ {INST_MOVA_GPR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT, 0, 0},
+ {INST_EXP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE, 1, 0},
+ {INST_LOG_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED, 1, 0},
+ {INST_LOG_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE, 1, 0},
+ {INST_RECIP_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED, 1, 0},
+ {INST_RECIP_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF, 1, 0},
+ {INST_RECIP_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, 1, 0},
+ {INST_RECIPSQRT_CLAMPED, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED, 1, 0},
+ {INST_RECIPSQRT_FF, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF, 1, 0},
+ {INST_RECIPSQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, 1, 0},
+ {INST_SQRT_IEEE, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE, 1, 0},
+ {INST_FLT_TO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT, 1, 0},
+ {INST_INT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT, 1, 0},
+ {INST_UINT_TO_FLT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT, 1, 0},
+ {INST_SIN, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN, 1, 0},
+ {INST_COS, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS, 1, 0},
+ {INST_ASHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT, 1, 0},
+ {INST_LSHR_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT, 1, 0},
+ {INST_LSHL_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT, 1, 0},
+ {INST_MULLO_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT, 1, 0},
+ {INST_MULHI_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT, 1, 0},
+ {INST_MULLO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT, 1, 0},
+ {INST_MULHI_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT, 1, 0},
+ {INST_RECIP_INT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT, 1, 0},
+ {INST_RECIP_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT, 1, 0},
+ {INST_FLT_TO_UINT, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT, 1, 0},
+ {INST_MUL_LIT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT, 1, 1},
+ {INST_MUL_LIT_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2, 1, 1},
+ {INST_MUL_LIT_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4, 1, 1},
+ {INST_MUL_LIT_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2, 1, 1},
+ {INST_MULADD, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD, 0, 1},
+ {INST_MULADD_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2, 0, 1},
+ {INST_MULADD_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4, 0, 1},
+ {INST_MULADD_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2, 0, 1},
+ {INST_MULADD_IEEE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE, 0, 1},
+ {INST_MULADD_IEEE_M2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2, 0, 1},
+ {INST_MULADD_IEEE_M4, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4, 0, 1},
+ {INST_MULADD_IEEE_D2, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2, 0, 1},
+ {INST_CNDE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE, 0, 1},
+ {INST_CNDGT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT, 0, 1},
+ {INST_CNDGE, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE, 0, 1},
+ {INST_CNDE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT, 0, 1},
+ {INST_CNDGT_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT, 0, 1},
+ {INST_CNDGE_INT, V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT, 0, 1},
+};
+
+struct r600_alu_instruction r600_alu_instruction[C_OPCODE_LAST] = {
+ {C_OPCODE_NOP, INST_NOP},
+ {C_OPCODE_MOV, INST_MOV},
+ {C_OPCODE_LIT, INST_NOP},
+ {C_OPCODE_RCP, INST_RECIP_IEEE},
+ {C_OPCODE_RSQ, INST_RECIPSQRT_IEEE},
+ {C_OPCODE_EXP, INST_EXP_IEEE},
+ {C_OPCODE_LOG, INST_LOG_IEEE},
+ {C_OPCODE_MUL, INST_MUL},
+ {C_OPCODE_ADD, INST_ADD},
+ {C_OPCODE_DP3, INST_DOT4},
+ {C_OPCODE_DP4, INST_DOT4},
+ {C_OPCODE_DST, INST_NOP},
+ {C_OPCODE_MIN, INST_MIN},
+ {C_OPCODE_MAX, INST_MAX},
+ {C_OPCODE_SLT, INST_NOP},
+ {C_OPCODE_SGE, INST_NOP},
+ {C_OPCODE_MAD, INST_MULADD},
+ {C_OPCODE_SUB, INST_COUNT},
+ {C_OPCODE_LRP, INST_NOP},
+ {C_OPCODE_CND, INST_NOP},
+ {20, INST_NOP},
+ {C_OPCODE_DP2A, INST_NOP},
+ {22, INST_NOP},
+ {23, INST_NOP},
+ {C_OPCODE_FRC, INST_NOP},
+ {C_OPCODE_CLAMP, INST_NOP},
+ {C_OPCODE_FLR, INST_NOP},
+ {C_OPCODE_ROUND, INST_NOP},
+ {C_OPCODE_EX2, INST_NOP},
+ {C_OPCODE_LG2, INST_NOP},
+ {C_OPCODE_POW, INST_NOP},
+ {C_OPCODE_XPD, INST_NOP},
+ {32, INST_NOP},
+ {C_OPCODE_ABS, INST_COUNT},
+ {C_OPCODE_RCC, INST_NOP},
+ {C_OPCODE_DPH, INST_NOP},
+ {C_OPCODE_COS, INST_COS},
+ {C_OPCODE_DDX, INST_NOP},
+ {C_OPCODE_DDY, INST_NOP},
+ {C_OPCODE_KILP, INST_NOP},
+ {C_OPCODE_PK2H, INST_NOP},
+ {C_OPCODE_PK2US, INST_NOP},
+ {C_OPCODE_PK4B, INST_NOP},
+ {C_OPCODE_PK4UB, INST_NOP},
+ {C_OPCODE_RFL, INST_NOP},
+ {C_OPCODE_SEQ, INST_NOP},
+ {C_OPCODE_SFL, INST_NOP},
+ {C_OPCODE_SGT, INST_NOP},
+ {C_OPCODE_SIN, INST_SIN},
+ {C_OPCODE_SLE, INST_NOP},
+ {C_OPCODE_SNE, INST_NOP},
+ {C_OPCODE_STR, INST_NOP},
+ {C_OPCODE_TEX, INST_NOP},
+ {C_OPCODE_TXD, INST_NOP},
+ {C_OPCODE_TXP, INST_NOP},
+ {C_OPCODE_UP2H, INST_NOP},
+ {C_OPCODE_UP2US, INST_NOP},
+ {C_OPCODE_UP4B, INST_NOP},
+ {C_OPCODE_UP4UB, INST_NOP},
+ {C_OPCODE_X2D, INST_NOP},
+ {C_OPCODE_ARA, INST_NOP},
+ {C_OPCODE_ARR, INST_NOP},
+ {C_OPCODE_BRA, INST_NOP},
+ {C_OPCODE_CAL, INST_NOP},
+ {C_OPCODE_RET, INST_NOP},
+ {C_OPCODE_SSG, INST_NOP},
+ {C_OPCODE_CMP, INST_NOP},
+ {C_OPCODE_SCS, INST_NOP},
+ {C_OPCODE_TXB, INST_NOP},
+ {C_OPCODE_NRM, INST_NOP},
+ {C_OPCODE_DIV, INST_NOP},
+ {C_OPCODE_DP2, INST_NOP},
+ {C_OPCODE_TXL, INST_NOP},
+ {C_OPCODE_BRK, INST_NOP},
+ {C_OPCODE_IF, INST_NOP},
+ {C_OPCODE_BGNFOR, INST_NOP},
+ {C_OPCODE_REP, INST_NOP},
+ {C_OPCODE_ELSE, INST_NOP},
+ {C_OPCODE_ENDIF, INST_NOP},
+ {C_OPCODE_ENDFOR, INST_NOP},
+ {C_OPCODE_ENDREP, INST_NOP},
+ {C_OPCODE_PUSHA, INST_NOP},
+ {C_OPCODE_POPA, INST_NOP},
+ {C_OPCODE_CEIL, INST_NOP},
+ {C_OPCODE_I2F, INST_NOP},
+ {C_OPCODE_NOT, INST_NOP},
+ {C_OPCODE_TRUNC, INST_NOP},
+ {C_OPCODE_SHL, INST_NOP},
+ {88, INST_NOP},
+ {C_OPCODE_AND, INST_NOP},
+ {C_OPCODE_OR, INST_NOP},
+ {C_OPCODE_MOD, INST_NOP},
+ {C_OPCODE_XOR, INST_NOP},
+ {C_OPCODE_SAD, INST_NOP},
+ {C_OPCODE_TXF, INST_NOP},
+ {C_OPCODE_TXQ, INST_NOP},
+ {C_OPCODE_CONT, INST_NOP},
+ {C_OPCODE_EMIT, INST_NOP},
+ {C_OPCODE_ENDPRIM, INST_NOP},
+ {C_OPCODE_BGNLOOP, INST_NOP},
+ {C_OPCODE_BGNSUB, INST_NOP},
+ {C_OPCODE_ENDLOOP, INST_NOP},
+ {C_OPCODE_ENDSUB, INST_NOP},
+ {103, INST_NOP},
+ {104, INST_NOP},
+ {105, INST_NOP},
+ {106, INST_NOP},
+ {107, INST_NOP},
+ {108, INST_NOP},
+ {109, INST_NOP},
+ {110, INST_NOP},
+ {111, INST_NOP},
+ {C_OPCODE_NRM4, INST_NOP},
+ {C_OPCODE_CALLNZ, INST_NOP},
+ {C_OPCODE_IFC, INST_NOP},
+ {C_OPCODE_BREAKC, INST_NOP},
+ {C_OPCODE_KIL, INST_NOP},
+ {C_OPCODE_END, INST_NOP},
+ {118, INST_NOP},
+ {C_OPCODE_F2I, INST_NOP},
+ {C_OPCODE_IDIV, INST_NOP},
+ {C_OPCODE_IMAX, INST_NOP},
+ {C_OPCODE_IMIN, INST_NOP},
+ {C_OPCODE_INEG, INST_NOP},
+ {C_OPCODE_ISGE, INST_NOP},
+ {C_OPCODE_ISHR, INST_NOP},
+ {C_OPCODE_ISLT, INST_NOP},
+ {C_OPCODE_F2U, INST_NOP},
+ {C_OPCODE_U2F, INST_NOP},
+ {C_OPCODE_UADD, INST_NOP},
+ {C_OPCODE_UDIV, INST_NOP},
+ {C_OPCODE_UMAD, INST_NOP},
+ {C_OPCODE_UMAX, INST_NOP},
+ {C_OPCODE_UMIN, INST_NOP},
+ {C_OPCODE_UMOD, INST_NOP},
+ {C_OPCODE_UMUL, INST_NOP},
+ {C_OPCODE_USEQ, INST_NOP},
+ {C_OPCODE_USGE, INST_NOP},
+ {C_OPCODE_USHR, INST_NOP},
+ {C_OPCODE_USLT, INST_NOP},
+ {C_OPCODE_USNE, INST_NOP},
+ {C_OPCODE_SWITCH, INST_NOP},
+ {C_OPCODE_CASE, INST_NOP},
+ {C_OPCODE_DEFAULT, INST_NOP},
+ {C_OPCODE_ENDSWITCH, INST_NOP},
+ {C_OPCODE_VFETCH, INST_NOP},
+ {C_OPCODE_ENTRY, INST_NOP},
+ {C_OPCODE_ARL, INST_NOP},
+};
diff --git a/src/gallium/drivers/r600/r600_compiler_r700.c b/src/gallium/drivers/r600/r600_compiler_r700.c
new file mode 100644
index 0000000000..809a57ae5c
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_compiler_r700.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include "r600_context.h"
+#include "r700_sq.h"
+
+static int r700_shader_cf_node_bytecode(struct r600_shader *rshader,
+ struct r600_shader_node *rnode,
+ unsigned *cid)
+{
+ unsigned id = *cid;
+
+ if (rnode->nfetch) {
+ rshader->bcode[id++] = S_SQ_CF_WORD0_ADDR(rnode->cf_addr >> 1);
+ rshader->bcode[id++] = S_SQ_CF_WORD1_CF_INST(V_SQ_CF_WORD1_SQ_CF_INST_VTX) |
+ S_SQ_CF_WORD1_BARRIER(1) |
+ S_SQ_CF_WORD1_COUNT(rnode->nfetch - 1);
+ } else {
+ rshader->bcode[id++] = S_SQ_CF_ALU_WORD0_ADDR(rnode->cf_addr >> 1);
+ rshader->bcode[id++] = S_SQ_CF_ALU_WORD1_CF_INST(V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU) |
+ S_SQ_CF_ALU_WORD1_BARRIER(1) |
+ S_SQ_CF_ALU_WORD1_COUNT(rnode->nslot - 1);
+ }
+ *cid = id;
+ return 0;
+}
+
+static int r700_shader_cf_output_bytecode(struct r600_shader *rshader,
+ struct c_vector *v,
+ unsigned *cid,
+ unsigned end)
+{
+ struct r600_shader_operand out;
+ unsigned id = *cid;
+ int r;
+
+ r = r600_shader_find_gpr(rshader, v, 0, &out);
+ if (r)
+ return r;
+ rshader->bcode[id + 0] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(out.sel) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(3);
+ rshader->bcode[id + 1] = S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(0) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(1) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(2) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(3) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(1) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE) |
+ S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end);
+ switch (v->name) {
+ case C_SEMANTIC_POSITION:
+ rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(60) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS);
+ break;
+ case C_SEMANTIC_COLOR:
+ if (rshader->cshader.type == C_PROGRAM_TYPE_VS) {
+ rshader->output[rshader->noutput].gpr = out.sel;
+ rshader->output[rshader->noutput].sid = v->sid;
+ rshader->output[rshader->noutput].name = v->name;
+ rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
+ } else {
+ rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(0) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL);
+ }
+ break;
+ case C_SEMANTIC_GENERIC:
+ rshader->output[rshader->noutput].gpr = out.sel;
+ rshader->output[rshader->noutput].sid = v->sid;
+ rshader->output[rshader->noutput].name = v->name;
+ rshader->bcode[id + 0] |= S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(rshader->noutput++) |
+ S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM);
+ break;
+ default:
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ *cid = id + 2;
+ return 0;
+}
+
+static int r700_shader_alu_bytecode(struct r600_shader *rshader,
+ struct r600_shader_node *rnode,
+ struct r600_shader_inst *alu,
+ unsigned *cid)
+{
+ unsigned id = *cid;
+
+ /* don't replace gpr by pv or ps for destination register */
+ if (alu->is_op3) {
+ rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |
+ S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |
+ S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |
+ S_SQ_ALU_WORD1_OP3_ALU_INST(alu->opcode) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+ } else {
+ rshader->bcode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |
+ S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |
+ S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |
+ S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |
+ S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |
+ S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |
+ S_SQ_ALU_WORD0_LAST(alu->last);
+ rshader->bcode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |
+ S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |
+ S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |
+ S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |
+ S_SQ_ALU_WORD1_OP2_WRITE_MASK(1) |
+ S_SQ_ALU_WORD1_OP2_ALU_INST(alu->opcode) |
+ S_SQ_ALU_WORD1_BANK_SWIZZLE(0);
+ }
+ *cid = id;
+ return 0;
+}
+
+int r700_shader_translate(struct r600_shader *rshader)
+{
+ struct c_shader *shader = &rshader->cshader;
+ struct r600_shader_node *rnode;
+ struct r600_shader_vfetch *vfetch;
+ struct r600_shader_alu *alu;
+ struct c_vector *v;
+ unsigned id, i, end;
+ int r;
+
+ r = r600_shader_register(rshader);
+ if (r) {
+ fprintf(stderr, "%s %d register allocation failed\n", __FILE__, __LINE__);
+ return r;
+ }
+ r = r600_shader_translate_rec(rshader, &shader->entry);
+ if (r) {
+ fprintf(stderr, "%s %d translation failed\n", __FILE__, __LINE__);
+ return r;
+ }
+ r = r600_shader_legalize(rshader);
+ if (r) {
+ fprintf(stderr, "%s %d legalize failed\n", __FILE__, __LINE__);
+ return r;
+ }
+ r600_shader_node_place(rshader);
+ rshader->bcode = malloc(rshader->ndw * 4);
+ if (rshader->bcode == NULL)
+ return -ENOMEM;
+ c_list_for_each(rnode, &rshader->nodes) {
+ id = rnode->cf_addr;
+ c_list_for_each(vfetch, &rnode->vfetch) {
+ r = r600_shader_vfetch_bytecode(rshader, rnode, vfetch, &id);
+ if (r)
+ return r;
+ }
+ c_list_for_each(alu, &rnode->alu) {
+ for (i = 0; i < alu->nalu; i++) {
+ r = r700_shader_alu_bytecode(rshader, rnode, &alu->alu[i], &id);
+ if (r)
+ return r;
+ }
+ for (i = 0; i < alu->nliteral; i++) {
+ rshader->bcode[id++] = alu->literal[i];
+ }
+ }
+ }
+ id = 0;
+ c_list_for_each(rnode, &rshader->nodes) {
+ r = r700_shader_cf_node_bytecode(rshader, rnode, &id);
+ if (r)
+ return r;
+ }
+ c_list_for_each(v, &rshader->cshader.files[C_FILE_OUTPUT].vectors) {
+ end = 0;
+ if (v->next == &rshader->cshader.files[C_FILE_OUTPUT].vectors)
+ end = 1;
+ r = r700_shader_cf_output_bytecode(rshader, v, &id, end);
+ if (r)
+ return r;
+ }
+ c_list_for_each(v, &rshader->cshader.files[C_FILE_INPUT].vectors) {
+ rshader->input[rshader->ninput].gpr = rshader->ninput;
+ rshader->input[rshader->ninput].sid = v->sid;
+ rshader->input[rshader->ninput].name = v->name;
+ rshader->ninput++;
+ }
+ return 0;
+}
diff --git a/src/gallium/drivers/r600/r600_compiler_tgsi.c b/src/gallium/drivers/r600/r600_compiler_tgsi.c
new file mode 100644
index 0000000000..563ca063af
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_compiler_tgsi.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+#include <tgsi/tgsi_parse.h>
+#include <tgsi/tgsi_scan.h>
+#include "r600_shader.h"
+#include "r600_context.h"
+
+struct tgsi_shader {
+ struct c_vector **v[TGSI_FILE_COUNT];
+ struct tgsi_shader_info info;
+ struct tgsi_parse_context parser;
+ const struct tgsi_token *tokens;
+ struct c_shader *shader;
+ struct c_node *node;
+};
+
+static unsigned tgsi_file_to_c_file(unsigned file);
+static unsigned tgsi_sname_to_c_sname(unsigned sname);
+static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode);
+
+static int tgsi_shader_init(struct tgsi_shader *ts,
+ const struct tgsi_token *tokens,
+ struct c_shader *shader)
+{
+ int i;
+
+ ts->shader = shader;
+ ts->tokens = tokens;
+ tgsi_scan_shader(ts->tokens, &ts->info);
+ tgsi_parse_init(&ts->parser, ts->tokens);
+ /* initialize to NULL in case of error */
+ for (i = 0; i < C_FILE_COUNT; i++) {
+ ts->v[i] = NULL;
+ }
+ for (i = 0; i < TGSI_FILE_COUNT; i++) {
+ if (ts->info.file_count[i] > 0) {
+ ts->v[i] = calloc(ts->info.file_count[i], sizeof(void*));
+ if (ts->v[i] == NULL) {
+ fprintf(stderr, "%s:%d unsupported %d %d\n", __func__, __LINE__, i, ts->info.file_count[i]);
+ return -ENOMEM;
+ }
+ }
+ }
+ return 0;
+}
+
+static void tgsi_shader_destroy(struct tgsi_shader *ts)
+{
+ int i;
+
+ for (i = 0; i < TGSI_FILE_COUNT; i++) {
+ free(ts->v[i]);
+ }
+ tgsi_parse_free(&ts->parser);
+}
+
+static int ntransform_declaration(struct tgsi_shader *ts)
+{
+ struct tgsi_full_declaration *fd = &ts->parser.FullToken.FullDeclaration;
+ struct c_vector *v;
+ unsigned file;
+ unsigned name;
+ int sid;
+ int i;
+
+ if (fd->Declaration.Dimension) {
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ for (i = fd->Range.First ; i <= fd->Range.Last; i++) {
+ sid = i;
+ name = C_SEMANTIC_GENERIC;
+ file = tgsi_file_to_c_file(fd->Declaration.File);
+ if (file == TGSI_FILE_NULL) {
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (fd->Declaration.Semantic) {
+ name = tgsi_sname_to_c_sname(fd->Semantic.Name);
+ sid = fd->Semantic.Index;
+ }
+ v = c_shader_vector_new(ts->shader, file, name, sid);
+ if (v == NULL) {
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ ts->v[fd->Declaration.File][i] = v;
+ }
+ return 0;
+}
+
+static int ntransform_immediate(struct tgsi_shader *ts)
+{
+ struct tgsi_full_immediate *fd = &ts->parser.FullToken.FullImmediate;
+ struct c_vector *v;
+ unsigned file;
+ unsigned name;
+
+ if (fd->Immediate.DataType != TGSI_IMM_FLOAT32) {
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ name = C_SEMANTIC_GENERIC;
+ file = C_FILE_IMMEDIATE;
+ v = c_shader_vector_new(ts->shader, file, name, 0);
+ if (v == NULL) {
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+ v->channel[0]->value = fd->u[0].Uint;
+ v->channel[1]->value = fd->u[1].Uint;
+ v->channel[2]->value = fd->u[2].Uint;
+ v->channel[3]->value = fd->u[3].Uint;
+ ts->v[TGSI_FILE_IMMEDIATE][0] = v;
+ return 0;
+}
+
+static int ntransform_instruction(struct tgsi_shader *ts)
+{
+ struct tgsi_full_instruction *fi = &ts->parser.FullToken.FullInstruction;
+ struct c_shader *shader = ts->shader;
+ struct c_instruction instruction;
+ unsigned opcode;
+ int i, r;
+
+ if (fi->Instruction.NumDstRegs > 1) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (fi->Instruction.Saturate) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (fi->Instruction.Predicate) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (fi->Instruction.Label) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (fi->Instruction.Texture) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
+ if (fi->Src[i].Register.Indirect ||
+ fi->Src[i].Register.Dimension ||
+ fi->Src[i].Register.Absolute) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ }
+ for (i = 0; i < fi->Instruction.NumDstRegs; i++) {
+ if (fi->Dst[i].Register.Indirect || fi->Dst[i].Register.Dimension) {
+ fprintf(stderr, "%s %d unsupported\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ }
+ r = tgsi_opcode_to_c_opcode(fi->Instruction.Opcode, &opcode);
+ if (r) {
+ fprintf(stderr, "%s:%d unsupported\n", __func__, __LINE__);
+ return r;
+ }
+ if (opcode == C_OPCODE_END) {
+ return c_node_cfg_link(ts->node, &shader->end);
+ }
+ /* FIXME add flow instruction handling */
+ memset(&instruction, 0, sizeof(struct c_instruction));
+ instruction.opcode = opcode;
+ instruction.ninput = fi->Instruction.NumSrcRegs;
+ instruction.write_mask = fi->Dst[0].Register.WriteMask;
+ for (i = 0; i < fi->Instruction.NumSrcRegs; i++) {
+ instruction.input[i].vector = ts->v[fi->Src[i].Register.File][fi->Src[i].Register.Index];
+ instruction.input[i].swizzle[0] = fi->Src[i].Register.SwizzleX;
+ instruction.input[i].swizzle[1] = fi->Src[i].Register.SwizzleY;
+ instruction.input[i].swizzle[2] = fi->Src[i].Register.SwizzleZ;
+ instruction.input[i].swizzle[3] = fi->Src[i].Register.SwizzleW;
+ }
+ instruction.output.vector = ts->v[fi->Dst[0].Register.File][fi->Dst[0].Register.Index];
+ instruction.output.swizzle[0] = (fi->Dst[0].Register.WriteMask & 0x1) ? C_SWIZZLE_X : C_SWIZZLE_D;
+ instruction.output.swizzle[1] = (fi->Dst[0].Register.WriteMask & 0x2) ? C_SWIZZLE_Y : C_SWIZZLE_D;
+ instruction.output.swizzle[2] = (fi->Dst[0].Register.WriteMask & 0x4) ? C_SWIZZLE_Z : C_SWIZZLE_D;
+ instruction.output.swizzle[3] = (fi->Dst[0].Register.WriteMask & 0x8) ? C_SWIZZLE_W : C_SWIZZLE_D;
+ return c_node_add_new_instruction(ts->node, &instruction);
+}
+
+int c_shader_from_tgsi(struct c_shader *shader, unsigned type,
+ const struct tgsi_token *tokens)
+{
+ struct tgsi_shader ts;
+ int r = 0;
+
+ c_shader_init(shader, type);
+ r = tgsi_shader_init(&ts, tokens, shader);
+ if (r)
+ goto out_err;
+ ts.shader = shader;
+ ts.node = &shader->entry;
+ while (!tgsi_parse_end_of_tokens(&ts.parser)) {
+ tgsi_parse_token(&ts.parser);
+ switch (ts.parser.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ r = ntransform_immediate(&ts);
+ if (r)
+ goto out_err;
+ break;
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ r = ntransform_declaration(&ts);
+ if (r)
+ goto out_err;
+ break;
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ r = ntransform_instruction(&ts);
+ if (r)
+ goto out_err;
+ break;
+ default:
+ r = -EINVAL;
+ goto out_err;
+ }
+ }
+ tgsi_shader_destroy(&ts);
+ return 0;
+out_err:
+ c_shader_destroy(shader);
+ tgsi_shader_destroy(&ts);
+ return r;
+}
+
+static unsigned tgsi_file_to_c_file(unsigned file)
+{
+ switch (file) {
+ case TGSI_FILE_CONSTANT:
+ return C_FILE_CONSTANT;
+ case TGSI_FILE_INPUT:
+ return C_FILE_INPUT;
+ case TGSI_FILE_OUTPUT:
+ return C_FILE_OUTPUT;
+ case TGSI_FILE_TEMPORARY:
+ return C_FILE_TEMPORARY;
+ case TGSI_FILE_SAMPLER:
+ return C_FILE_SAMPLER;
+ case TGSI_FILE_ADDRESS:
+ return C_FILE_ADDRESS;
+ case TGSI_FILE_IMMEDIATE:
+ return C_FILE_IMMEDIATE;
+ case TGSI_FILE_PREDICATE:
+ return C_FILE_PREDICATE;
+ case TGSI_FILE_SYSTEM_VALUE:
+ return C_FILE_SYSTEM_VALUE;
+ case TGSI_FILE_NULL:
+ return C_FILE_NULL;
+ default:
+ fprintf(stderr, "%s:%d unsupported file %d\n", __func__, __LINE__, file);
+ return C_FILE_NULL;
+ }
+}
+
+static unsigned tgsi_sname_to_c_sname(unsigned sname)
+{
+ switch (sname) {
+ case TGSI_SEMANTIC_POSITION:
+ return C_SEMANTIC_POSITION;
+ case TGSI_SEMANTIC_COLOR:
+ return C_SEMANTIC_COLOR;
+ case TGSI_SEMANTIC_BCOLOR:
+ return C_SEMANTIC_BCOLOR;
+ case TGSI_SEMANTIC_FOG:
+ return C_SEMANTIC_FOG;
+ case TGSI_SEMANTIC_PSIZE:
+ return C_SEMANTIC_PSIZE;
+ case TGSI_SEMANTIC_GENERIC:
+ return C_SEMANTIC_GENERIC;
+ case TGSI_SEMANTIC_NORMAL:
+ return C_SEMANTIC_NORMAL;
+ case TGSI_SEMANTIC_FACE:
+ return C_SEMANTIC_FACE;
+ case TGSI_SEMANTIC_EDGEFLAG:
+ return C_SEMANTIC_EDGEFLAG;
+ case TGSI_SEMANTIC_PRIMID:
+ return C_SEMANTIC_PRIMID;
+ case TGSI_SEMANTIC_INSTANCEID:
+ return C_SEMANTIC_INSTANCEID;
+ default:
+ return C_SEMANTIC_GENERIC;
+ }
+}
+
+static int tgsi_opcode_to_c_opcode(unsigned opcode, unsigned *copcode)
+{
+ switch (opcode) {
+ case TGSI_OPCODE_MOV:
+ *copcode = C_OPCODE_MOV;
+ return 0;
+ case TGSI_OPCODE_MUL:
+ *copcode = C_OPCODE_MUL;
+ return 0;
+ case TGSI_OPCODE_MAD:
+ *copcode = C_OPCODE_MAD;
+ return 0;
+ case TGSI_OPCODE_END:
+ *copcode = C_OPCODE_END;
+ return 0;
+ case TGSI_OPCODE_ARL:
+ *copcode = C_OPCODE_ARL;
+ return 0;
+ case TGSI_OPCODE_LIT:
+ *copcode = C_OPCODE_LIT;
+ return 0;
+ case TGSI_OPCODE_RCP:
+ *copcode = C_OPCODE_RCP;
+ return 0;
+ case TGSI_OPCODE_RSQ:
+ *copcode = C_OPCODE_RSQ;
+ return 0;
+ case TGSI_OPCODE_EXP:
+ *copcode = C_OPCODE_EXP;
+ return 0;
+ case TGSI_OPCODE_LOG:
+ *copcode = C_OPCODE_LOG;
+ return 0;
+ case TGSI_OPCODE_ADD:
+ *copcode = C_OPCODE_ADD;
+ return 0;
+ case TGSI_OPCODE_DP3:
+ *copcode = C_OPCODE_DP3;
+ return 0;
+ case TGSI_OPCODE_DP4:
+ *copcode = C_OPCODE_DP4;
+ return 0;
+ case TGSI_OPCODE_DST:
+ *copcode = C_OPCODE_DST;
+ return 0;
+ case TGSI_OPCODE_MIN:
+ *copcode = C_OPCODE_MIN;
+ return 0;
+ case TGSI_OPCODE_MAX:
+ *copcode = C_OPCODE_MAX;
+ return 0;
+ case TGSI_OPCODE_SLT:
+ *copcode = C_OPCODE_SLT;
+ return 0;
+ case TGSI_OPCODE_SGE:
+ *copcode = C_OPCODE_SGE;
+ return 0;
+ case TGSI_OPCODE_SUB:
+ *copcode = C_OPCODE_SUB;
+ return 0;
+ case TGSI_OPCODE_LRP:
+ *copcode = C_OPCODE_LRP;
+ return 0;
+ case TGSI_OPCODE_CND:
+ *copcode = C_OPCODE_CND;
+ return 0;
+ case TGSI_OPCODE_DP2A:
+ *copcode = C_OPCODE_DP2A;
+ return 0;
+ case TGSI_OPCODE_FRC:
+ *copcode = C_OPCODE_FRC;
+ return 0;
+ case TGSI_OPCODE_CLAMP:
+ *copcode = C_OPCODE_CLAMP;
+ return 0;
+ case TGSI_OPCODE_FLR:
+ *copcode = C_OPCODE_FLR;
+ return 0;
+ case TGSI_OPCODE_ROUND:
+ *copcode = C_OPCODE_ROUND;
+ return 0;
+ case TGSI_OPCODE_EX2:
+ *copcode = C_OPCODE_EX2;
+ return 0;
+ case TGSI_OPCODE_LG2:
+ *copcode = C_OPCODE_LG2;
+ return 0;
+ case TGSI_OPCODE_POW:
+ *copcode = C_OPCODE_POW;
+ return 0;
+ case TGSI_OPCODE_XPD:
+ *copcode = C_OPCODE_XPD;
+ return 0;
+ case TGSI_OPCODE_ABS:
+ *copcode = C_OPCODE_ABS;
+ return 0;
+ case TGSI_OPCODE_RCC:
+ *copcode = C_OPCODE_RCC;
+ return 0;
+ case TGSI_OPCODE_DPH:
+ *copcode = C_OPCODE_DPH;
+ return 0;
+ case TGSI_OPCODE_COS:
+ *copcode = C_OPCODE_COS;
+ return 0;
+ case TGSI_OPCODE_DDX:
+ *copcode = C_OPCODE_DDX;
+ return 0;
+ case TGSI_OPCODE_DDY:
+ *copcode = C_OPCODE_DDY;
+ return 0;
+ case TGSI_OPCODE_KILP:
+ *copcode = C_OPCODE_KILP;
+ return 0;
+ case TGSI_OPCODE_PK2H:
+ *copcode = C_OPCODE_PK2H;
+ return 0;
+ case TGSI_OPCODE_PK2US:
+ *copcode = C_OPCODE_PK2US;
+ return 0;
+ case TGSI_OPCODE_PK4B:
+ *copcode = C_OPCODE_PK4B;
+ return 0;
+ case TGSI_OPCODE_PK4UB:
+ *copcode = C_OPCODE_PK4UB;
+ return 0;
+ case TGSI_OPCODE_RFL:
+ *copcode = C_OPCODE_RFL;
+ return 0;
+ case TGSI_OPCODE_SEQ:
+ *copcode = C_OPCODE_SEQ;
+ return 0;
+ case TGSI_OPCODE_SFL:
+ *copcode = C_OPCODE_SFL;
+ return 0;
+ case TGSI_OPCODE_SGT:
+ *copcode = C_OPCODE_SGT;
+ return 0;
+ case TGSI_OPCODE_SIN:
+ *copcode = C_OPCODE_SIN;
+ return 0;
+ case TGSI_OPCODE_SLE:
+ *copcode = C_OPCODE_SLE;
+ return 0;
+ case TGSI_OPCODE_SNE:
+ *copcode = C_OPCODE_SNE;
+ return 0;
+ case TGSI_OPCODE_STR:
+ *copcode = C_OPCODE_STR;
+ return 0;
+ case TGSI_OPCODE_TEX:
+ *copcode = C_OPCODE_TEX;
+ return 0;
+ case TGSI_OPCODE_TXD:
+ *copcode = C_OPCODE_TXD;
+ return 0;
+ case TGSI_OPCODE_TXP:
+ *copcode = C_OPCODE_TXP;
+ return 0;
+ case TGSI_OPCODE_UP2H:
+ *copcode = C_OPCODE_UP2H;
+ return 0;
+ case TGSI_OPCODE_UP2US:
+ *copcode = C_OPCODE_UP2US;
+ return 0;
+ case TGSI_OPCODE_UP4B:
+ *copcode = C_OPCODE_UP4B;
+ return 0;
+ case TGSI_OPCODE_UP4UB:
+ *copcode = C_OPCODE_UP4UB;
+ return 0;
+ case TGSI_OPCODE_X2D:
+ *copcode = C_OPCODE_X2D;
+ return 0;
+ case TGSI_OPCODE_ARA:
+ *copcode = C_OPCODE_ARA;
+ return 0;
+ case TGSI_OPCODE_ARR:
+ *copcode = C_OPCODE_ARR;
+ return 0;
+ case TGSI_OPCODE_BRA:
+ *copcode = C_OPCODE_BRA;
+ return 0;
+ case TGSI_OPCODE_CAL:
+ *copcode = C_OPCODE_CAL;
+ return 0;
+ case TGSI_OPCODE_RET:
+ *copcode = C_OPCODE_RET;
+ return 0;
+ case TGSI_OPCODE_SSG:
+ *copcode = C_OPCODE_SSG;
+ return 0;
+ case TGSI_OPCODE_CMP:
+ *copcode = C_OPCODE_CMP;
+ return 0;
+ case TGSI_OPCODE_SCS:
+ *copcode = C_OPCODE_SCS;
+ return 0;
+ case TGSI_OPCODE_TXB:
+ *copcode = C_OPCODE_TXB;
+ return 0;
+ case TGSI_OPCODE_NRM:
+ *copcode = C_OPCODE_NRM;
+ return 0;
+ case TGSI_OPCODE_DIV:
+ *copcode = C_OPCODE_DIV;
+ return 0;
+ case TGSI_OPCODE_DP2:
+ *copcode = C_OPCODE_DP2;
+ return 0;
+ case TGSI_OPCODE_TXL:
+ *copcode = C_OPCODE_TXL;
+ return 0;
+ case TGSI_OPCODE_BRK:
+ *copcode = C_OPCODE_BRK;
+ return 0;
+ case TGSI_OPCODE_IF:
+ *copcode = C_OPCODE_IF;
+ return 0;
+ case TGSI_OPCODE_ELSE:
+ *copcode = C_OPCODE_ELSE;
+ return 0;
+ case TGSI_OPCODE_ENDIF:
+ *copcode = C_OPCODE_ENDIF;
+ return 0;
+ case TGSI_OPCODE_PUSHA:
+ *copcode = C_OPCODE_PUSHA;
+ return 0;
+ case TGSI_OPCODE_POPA:
+ *copcode = C_OPCODE_POPA;
+ return 0;
+ case TGSI_OPCODE_CEIL:
+ *copcode = C_OPCODE_CEIL;
+ return 0;
+ case TGSI_OPCODE_I2F:
+ *copcode = C_OPCODE_I2F;
+ return 0;
+ case TGSI_OPCODE_NOT:
+ *copcode = C_OPCODE_NOT;
+ return 0;
+ case TGSI_OPCODE_TRUNC:
+ *copcode = C_OPCODE_TRUNC;
+ return 0;
+ case TGSI_OPCODE_SHL:
+ *copcode = C_OPCODE_SHL;
+ return 0;
+ case TGSI_OPCODE_AND:
+ *copcode = C_OPCODE_AND;
+ return 0;
+ case TGSI_OPCODE_OR:
+ *copcode = C_OPCODE_OR;
+ return 0;
+ case TGSI_OPCODE_MOD:
+ *copcode = C_OPCODE_MOD;
+ return 0;
+ case TGSI_OPCODE_XOR:
+ *copcode = C_OPCODE_XOR;
+ return 0;
+ case TGSI_OPCODE_SAD:
+ *copcode = C_OPCODE_SAD;
+ return 0;
+ case TGSI_OPCODE_TXF:
+ *copcode = C_OPCODE_TXF;
+ return 0;
+ case TGSI_OPCODE_TXQ:
+ *copcode = C_OPCODE_TXQ;
+ return 0;
+ case TGSI_OPCODE_CONT:
+ *copcode = C_OPCODE_CONT;
+ return 0;
+ case TGSI_OPCODE_EMIT:
+ *copcode = C_OPCODE_EMIT;
+ return 0;
+ case TGSI_OPCODE_ENDPRIM:
+ *copcode = C_OPCODE_ENDPRIM;
+ return 0;
+ case TGSI_OPCODE_BGNLOOP:
+ *copcode = C_OPCODE_BGNLOOP;
+ return 0;
+ case TGSI_OPCODE_BGNSUB:
+ *copcode = C_OPCODE_BGNSUB;
+ return 0;
+ case TGSI_OPCODE_ENDLOOP:
+ *copcode = C_OPCODE_ENDLOOP;
+ return 0;
+ case TGSI_OPCODE_ENDSUB:
+ *copcode = C_OPCODE_ENDSUB;
+ return 0;
+ case TGSI_OPCODE_NOP:
+ *copcode = C_OPCODE_NOP;
+ return 0;
+ case TGSI_OPCODE_NRM4:
+ *copcode = C_OPCODE_NRM4;
+ return 0;
+ case TGSI_OPCODE_CALLNZ:
+ *copcode = C_OPCODE_CALLNZ;
+ return 0;
+ case TGSI_OPCODE_IFC:
+ *copcode = C_OPCODE_IFC;
+ return 0;
+ case TGSI_OPCODE_BREAKC:
+ *copcode = C_OPCODE_BREAKC;
+ return 0;
+ case TGSI_OPCODE_KIL:
+ *copcode = C_OPCODE_KIL;
+ return 0;
+ case TGSI_OPCODE_F2I:
+ *copcode = C_OPCODE_F2I;
+ return 0;
+ case TGSI_OPCODE_IDIV:
+ *copcode = C_OPCODE_IDIV;
+ return 0;
+ case TGSI_OPCODE_IMAX:
+ *copcode = C_OPCODE_IMAX;
+ return 0;
+ case TGSI_OPCODE_IMIN:
+ *copcode = C_OPCODE_IMIN;
+ return 0;
+ case TGSI_OPCODE_INEG:
+ *copcode = C_OPCODE_INEG;
+ return 0;
+ case TGSI_OPCODE_ISGE:
+ *copcode = C_OPCODE_ISGE;
+ return 0;
+ case TGSI_OPCODE_ISHR:
+ *copcode = C_OPCODE_ISHR;
+ return 0;
+ case TGSI_OPCODE_ISLT:
+ *copcode = C_OPCODE_ISLT;
+ return 0;
+ case TGSI_OPCODE_F2U:
+ *copcode = C_OPCODE_F2U;
+ return 0;
+ case TGSI_OPCODE_U2F:
+ *copcode = C_OPCODE_U2F;
+ return 0;
+ case TGSI_OPCODE_UADD:
+ *copcode = C_OPCODE_UADD;
+ return 0;
+ case TGSI_OPCODE_UDIV:
+ *copcode = C_OPCODE_UDIV;
+ return 0;
+ case TGSI_OPCODE_UMAD:
+ *copcode = C_OPCODE_UMAD;
+ return 0;
+ case TGSI_OPCODE_UMAX:
+ *copcode = C_OPCODE_UMAX;
+ return 0;
+ case TGSI_OPCODE_UMIN:
+ *copcode = C_OPCODE_UMIN;
+ return 0;
+ case TGSI_OPCODE_UMOD:
+ *copcode = C_OPCODE_UMOD;
+ return 0;
+ case TGSI_OPCODE_UMUL:
+ *copcode = C_OPCODE_UMUL;
+ return 0;
+ case TGSI_OPCODE_USEQ:
+ *copcode = C_OPCODE_USEQ;
+ return 0;
+ case TGSI_OPCODE_USGE:
+ *copcode = C_OPCODE_USGE;
+ return 0;
+ case TGSI_OPCODE_USHR:
+ *copcode = C_OPCODE_USHR;
+ return 0;
+ case TGSI_OPCODE_USLT:
+ *copcode = C_OPCODE_USLT;
+ return 0;
+ case TGSI_OPCODE_USNE:
+ *copcode = C_OPCODE_USNE;
+ return 0;
+ case TGSI_OPCODE_SWITCH:
+ *copcode = C_OPCODE_SWITCH;
+ return 0;
+ case TGSI_OPCODE_CASE:
+ *copcode = C_OPCODE_CASE;
+ return 0;
+ case TGSI_OPCODE_DEFAULT:
+ *copcode = C_OPCODE_DEFAULT;
+ return 0;
+ case TGSI_OPCODE_ENDSWITCH:
+ *copcode = C_OPCODE_ENDSWITCH;
+ return 0;
+ default:
+ fprintf(stderr, "%s:%d unsupported opcode %d\n", __func__, __LINE__, opcode);
+ return -EINVAL;
+ }
+}
diff --git a/src/gallium/drivers/r600/r600_context.c b/src/gallium/drivers/r600/r600_context.c
new file mode 100644
index 0000000000..d819c14148
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_context.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson
+ */
+#include <stdio.h>
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include <util/u_memory.h>
+#include <util/u_blitter.h>
+#include "r600_resource.h"
+#include "r600_screen.h"
+#include "r600_context.h"
+
+static void r600_destroy_context(struct pipe_context *context)
+{
+ struct r600_context *rctx = (struct r600_context*)context;
+
+ FREE(rctx);
+}
+
+static void r600_flush(struct pipe_context *ctx, unsigned flags,
+ struct pipe_fence_handle **fence)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ static int dc = 0;
+
+ if (radeon_ctx_pm4(rctx->ctx))
+ return;
+ /* FIXME dumping should be removed once shader support instructions
+ * without throwing bad code
+ */
+ if (!dc)
+ radeon_ctx_dump_bof(rctx->ctx, "gallium.bof");
+#if 0
+ radeon_ctx_submit(rctx->ctx);
+#endif
+ rctx->ctx = radeon_ctx_decref(rctx->ctx);
+ rctx->ctx = radeon_ctx(rscreen->rw);
+ dc++;
+}
+
+struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
+{
+ struct r600_context *rctx = CALLOC_STRUCT(r600_context);
+ struct r600_screen* rscreen = r600_screen(screen);
+
+ if (rctx == NULL)
+ return NULL;
+ rctx->context.winsys = rscreen->screen.winsys;
+ rctx->context.screen = screen;
+ rctx->context.priv = priv;
+ rctx->context.destroy = r600_destroy_context;
+ rctx->context.clear = r600_clear;
+ rctx->context.draw_arrays = r600_draw_arrays;
+ rctx->context.draw_elements = r600_draw_elements;
+ rctx->context.draw_range_elements = r600_draw_range_elements;
+ rctx->context.flush = r600_flush;
+ r600_init_query_functions(rctx);
+ r600_init_state_functions(rctx);
+ r600_init_context_resource_functions(rctx);
+
+ rctx->blitter = util_blitter_create(&rctx->context);
+ if (rctx->blitter == NULL) {
+ FREE(rctx);
+ return NULL;
+ }
+
+ rctx->cb_cntl = radeon_state(rscreen->rw, R600_CB_CNTL_TYPE, R600_CB_CNTL);
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_SHADER_MASK] = 0x0000000F;
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_TARGET_MASK] = 0x0000000F;
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_COLOR_CONTROL] = 0x00CC0000;
+ rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_CONFIG] = 0x00000000;
+ rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX] = 0x00000000;
+ rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX] = 0x00000000;
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_CONTROL] = 0x01000000;
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_SRC] = 0x00000000;
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_DST] = 0x000000FF;
+ rctx->cb_cntl->states[R600_CB_CNTL__CB_CLRCMP_MSK] = 0xFFFFFFFF;
+ rctx->cb_cntl->states[R600_CB_CNTL__PA_SC_AA_MASK] = 0xFFFFFFFF;
+ radeon_state_pm4(rctx->cb_cntl);
+
+ rctx->config = radeon_state(rscreen->rw, R600_CONFIG_TYPE, R600_CONFIG);
+ rctx->config->states[R600_CONFIG__SQ_CONFIG] = 0xE400000C;
+ rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1] = 0x403800C0;
+ rctx->config->states[R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_THREAD_RESOURCE_MGMT] = 0x00003090;
+ rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1] = 0x00800080;
+ rctx->config->states[R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ] = 0x00004000;
+ rctx->config->states[R600_CONFIG__TA_CNTL_AUX] = 0x07000002;
+ rctx->config->states[R600_CONFIG__VC_ENHANCE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__DB_DEBUG] = 0x00000000;
+ rctx->config->states[R600_CONFIG__DB_WATERMARKS] = 0x00420204;
+ rctx->config->states[R600_CONFIG__SX_MISC] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SPI_THREAD_GROUPING] = 0x00000001;
+ rctx->config->states[R600_CONFIG__CB_SHADER_CONTROL] = 0x00000003;
+ rctx->config->states[R600_CONFIG__SQ_ESGS_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_GSVS_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_FBUF_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_REDUC_RING_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__SQ_GS_VERT_ITEMSIZE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_OUTPUT_PATH_CNTL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_HOS_CNTL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_HOS_REUSE_DEPTH] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_PRIM_TYPE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_FIRST_DECR] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_DECR] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_CNTL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_CNTL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_GS_MODE] = 0x00000000;
+ rctx->config->states[R600_CONFIG__PA_SC_MODE_CNTL] = 0x00514000;
+ rctx->config->states[R600_CONFIG__VGT_STRMOUT_EN] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_REUSE_OFF] = 0x00000001;
+ rctx->config->states[R600_CONFIG__VGT_VTX_CNT_EN] = 0x00000000;
+ rctx->config->states[R600_CONFIG__VGT_STRMOUT_BUFFER_EN] = 0x00000000;
+ radeon_state_pm4(rctx->config);
+
+ rctx->ctx = radeon_ctx(rscreen->rw);
+ rctx->draw = radeon_draw(rscreen->rw);
+ return &rctx->context;
+}
diff --git a/src/gallium/drivers/r600/r600_context.h b/src/gallium/drivers/r600/r600_context.h
new file mode 100644
index 0000000000..8e996b7d20
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_context.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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 R600_CONTEXT_H
+#define R600_CONTEXT_H
+
+#include <pipe/p_state.h>
+#include <pipe/p_context.h>
+#include <tgsi/tgsi_scan.h>
+#include <tgsi/tgsi_parse.h>
+#include <tgsi/tgsi_util.h>
+#include <util/u_blitter.h>
+#include "radeon.h"
+#include "r600_shader.h"
+
+/* XXX move this to a more appropriate place */
+struct r600_vertex_elements_state
+{
+ unsigned count;
+ struct pipe_vertex_element elements[32];
+};
+
+struct r600_pipe_shader {
+ unsigned type;
+ struct r600_shader shader;
+ struct radeon_bo *bo;
+ struct radeon_state *state;
+};
+
+struct r600_context {
+ struct pipe_context context;
+ struct radeon_ctx *ctx;
+ struct radeon_state *cb_cntl;
+ struct radeon_state *db;
+ struct radeon_state *config;
+ struct r600_pipe_shader *ps_shader;
+ struct r600_pipe_shader *vs_shader;
+ unsigned flat_shade;
+ unsigned nvertex_buffer;
+ struct r600_vertex_elements_state *vertex_elements;
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct blitter_context *blitter;
+ struct pipe_stencil_ref stencil_ref;
+ struct pipe_framebuffer_state fb_state;
+ struct radeon_draw *draw;
+ struct pipe_viewport_state viewport;
+};
+
+void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
+ unsigned start, unsigned count);
+void r600_draw_elements(struct pipe_context *ctx,
+ struct pipe_resource *index_buffer,
+ unsigned index_size, int index_bias, unsigned mode,
+ unsigned start, unsigned count);
+void r600_draw_range_elements(struct pipe_context *ctx,
+ struct pipe_resource *index_buffer,
+ unsigned index_size, int index_bias, unsigned min_index,
+ unsigned max_index, unsigned mode,
+ unsigned start, unsigned count);
+
+void r600_init_state_functions(struct r600_context *rctx);
+void r600_init_query_functions(struct r600_context* rctx);
+struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv);
+
+void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
+struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx,
+ unsigned type,
+ const struct tgsi_token *tokens);
+int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader);
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_draw.c b/src/gallium/drivers/r600/r600_draw.c
new file mode 100644
index 0000000000..8b6a6d96aa
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_draw.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <pipe/p_screen.h>
+#include <util/u_format.h>
+#include <util/u_math.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include "r600_screen.h"
+#include "r600_context.h"
+#include "r600d.h"
+
+struct r600_draw {
+ struct pipe_context *ctx;
+ struct radeon_state *draw;
+ struct radeon_state *vgt;
+ unsigned mode;
+ unsigned start;
+ unsigned count;
+ unsigned index_size;
+ struct pipe_resource *index_buffer;
+};
+
+static int r600_draw_common(struct r600_draw *draw)
+{
+ struct r600_context *rctx = (struct r600_context*)draw->ctx;
+ struct r600_screen *rscreen = (struct r600_screen*)draw->ctx->screen;
+ struct radeon_state *vs_resource;
+ struct r600_buffer *rbuffer;
+ unsigned i, j, offset, format, prim;
+ u32 vgt_dma_index_type, vgt_draw_initiator;
+ int r;
+
+ switch (draw->index_size) {
+ case 2:
+ vgt_draw_initiator = 0;
+ vgt_dma_index_type = 0;
+ break;
+ case 4:
+ vgt_draw_initiator = 0;
+ vgt_dma_index_type = 1;
+ break;
+ case 0:
+ vgt_draw_initiator = 2;
+ vgt_dma_index_type = 0;
+ break;
+ default:
+ fprintf(stderr, "%s %d unsupported index size %d\n", __func__, __LINE__, draw->index_size);
+ return -EINVAL;
+ }
+ r = r600_conv_pipe_prim(draw->mode, &prim);
+ if (r)
+ return r;
+ /* rebuild vertex shader if input format changed */
+ r = r600_pipe_shader_update(draw->ctx, rctx->vs_shader);
+ if (r)
+ return r;
+ r = r600_pipe_shader_update(draw->ctx, rctx->ps_shader);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->vs_shader->state);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->ps_shader->state);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->cb_cntl);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->db);
+ if (r)
+ return r;
+ r = radeon_draw_set(rctx->draw, rctx->config);
+ if (r)
+ return r;
+
+ for (i = 0 ; i < rctx->vertex_elements->count; i++) {
+ j = rctx->vertex_elements->elements[i].vertex_buffer_index;
+ rbuffer = (struct r600_buffer*)rctx->vertex_buffer[j].buffer;
+ offset = rctx->vertex_elements->elements[i].src_offset + rctx->vertex_buffer[j].buffer_offset;
+ r = r600_conv_pipe_format(rctx->vertex_elements->elements[i].src_format, &format);
+ if (r)
+ return r;
+ vs_resource = radeon_state(rscreen->rw, R600_VS_RESOURCE_TYPE, R600_VS_RESOURCE + i);
+ if (vs_resource == NULL)
+ return -ENOMEM;
+ vs_resource->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ vs_resource->nbo = 1;
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD0] = offset;
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD1] = rbuffer->bo->size - offset;
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD2] = S_038008_STRIDE(rctx->vertex_buffer[j].stride) |
+ S_038008_DATA_FORMAT(format);
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD3] = 0x00000000;
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD4] = 0x00000000;
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD5] = 0x00000000;
+ vs_resource->states[R600_PS_RESOURCE__RESOURCE0_WORD6] = 0xC0000000;
+ vs_resource->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ vs_resource->placement[1] = RADEON_GEM_DOMAIN_GTT;
+ r = radeon_draw_set_new(rctx->draw, vs_resource);
+ if (r)
+ return r;
+ }
+ /* FIXME start need to change winsys */
+ draw->draw = radeon_state(rscreen->rw, R600_DRAW_TYPE, R600_DRAW);
+ if (draw->draw == NULL)
+ return -ENOMEM;
+ draw->draw->states[R600_DRAW__VGT_NUM_INDICES] = draw->count;
+ draw->draw->states[R600_DRAW__VGT_DRAW_INITIATOR] = vgt_draw_initiator;
+ if (draw->index_buffer) {
+ rbuffer = (struct r600_buffer*)draw->index_buffer;
+ draw->draw->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ draw->draw->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ draw->draw->placement[1] = RADEON_GEM_DOMAIN_GTT;
+ draw->draw->nbo = 1;
+ }
+ r = radeon_draw_set_new(rctx->draw, draw->draw);
+ if (r)
+ return r;
+ draw->vgt = radeon_state(rscreen->rw, R600_VGT_TYPE, R600_VGT);
+ if (draw->vgt == NULL)
+ return -ENOMEM;
+ draw->vgt->states[R600_VGT__VGT_PRIMITIVE_TYPE] = prim;
+ draw->vgt->states[R600_VGT__VGT_MAX_VTX_INDX] = 0x00FFFFFF;
+ draw->vgt->states[R600_VGT__VGT_MIN_VTX_INDX] = 0x00000000;
+ draw->vgt->states[R600_VGT__VGT_INDX_OFFSET] = draw->start;
+ draw->vgt->states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX] = 0x00000000;
+ draw->vgt->states[R600_VGT__VGT_DMA_INDEX_TYPE] = vgt_dma_index_type;
+ draw->vgt->states[R600_VGT__VGT_PRIMITIVEID_EN] = 0x00000000;
+ draw->vgt->states[R600_VGT__VGT_DMA_NUM_INSTANCES] = 0x00000001;
+ draw->vgt->states[R600_VGT__VGT_MULTI_PRIM_IB_RESET_EN] = 0x00000000;
+ draw->vgt->states[R600_VGT__VGT_INSTANCE_STEP_RATE_0] = 0x00000000;
+ draw->vgt->states[R600_VGT__VGT_INSTANCE_STEP_RATE_1] = 0x00000000;
+ r = radeon_draw_set_new(rctx->draw, draw->vgt);
+ if (r)
+ return r;
+ /* FIXME */
+ r = radeon_ctx_set_draw_new(rctx->ctx, rctx->draw);
+ if (r)
+ return r;
+ rctx->draw = radeon_draw_duplicate(rctx->draw);
+ return 0;
+}
+
+void r600_draw_range_elements(struct pipe_context *ctx,
+ struct pipe_resource *index_buffer,
+ unsigned index_size, int index_bias, unsigned min_index,
+ unsigned max_index, unsigned mode,
+ unsigned start, unsigned count)
+{
+ struct r600_draw draw;
+ assert(index_bias == 0);
+
+ draw.ctx = ctx;
+ draw.mode = mode;
+ draw.start = start;
+ draw.count = count;
+ draw.index_size = index_size;
+ draw.index_buffer = index_buffer;
+printf("index_size %d min %d max %d start %d count %d\n", index_size, min_index, max_index, start, count);
+ r600_draw_common(&draw);
+}
+
+void r600_draw_elements(struct pipe_context *ctx,
+ struct pipe_resource *index_buffer,
+ unsigned index_size, int index_bias, unsigned mode,
+ unsigned start, unsigned count)
+{
+ struct r600_draw draw;
+ assert(index_bias == 0);
+
+ draw.ctx = ctx;
+ draw.mode = mode;
+ draw.start = start;
+ draw.count = count;
+ draw.index_size = index_size;
+ draw.index_buffer = index_buffer;
+ r600_draw_common(&draw);
+}
+
+void r600_draw_arrays(struct pipe_context *ctx, unsigned mode,
+ unsigned start, unsigned count)
+{
+ struct r600_draw draw;
+
+ draw.ctx = ctx;
+ draw.mode = mode;
+ draw.start = start;
+ draw.count = count;
+ draw.index_size = 0;
+ draw.index_buffer = NULL;
+ r600_draw_common(&draw);
+}
diff --git a/src/gallium/drivers/r600/r600_helper.c b/src/gallium/drivers/r600/r600_helper.c
new file mode 100644
index 0000000000..9370a5355e
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_helper.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include "r600_screen.h"
+#include "r600d.h"
+
+int r600_conv_pipe_format(unsigned pformat, unsigned *format)
+{
+ switch (pformat) {
+ case PIPE_FORMAT_R32G32B32_FLOAT:
+ *format = 0x30;
+ return 0;
+ case PIPE_FORMAT_R32G32B32A32_FLOAT:
+ *format = V_0280A0_COLOR_32_32_32_32_FLOAT;
+ return 0;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_USCALED:
+ case PIPE_FORMAT_R8G8B8A8_SNORM:
+ case PIPE_FORMAT_R8G8B8A8_SSCALED:
+ *format = V_0280A0_COLOR_8_8_8_8;
+ return 0;
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_L16_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ case PIPE_FORMAT_R64_FLOAT:
+ case PIPE_FORMAT_R64G64_FLOAT:
+ case PIPE_FORMAT_R64G64B64_FLOAT:
+ case PIPE_FORMAT_R64G64B64A64_FLOAT:
+ case PIPE_FORMAT_R32_FLOAT:
+ case PIPE_FORMAT_R32G32_FLOAT:
+ case PIPE_FORMAT_R32_UNORM:
+ case PIPE_FORMAT_R32G32_UNORM:
+ case PIPE_FORMAT_R32G32B32_UNORM:
+ case PIPE_FORMAT_R32G32B32A32_UNORM:
+ case PIPE_FORMAT_R32_USCALED:
+ case PIPE_FORMAT_R32G32_USCALED:
+ case PIPE_FORMAT_R32G32B32_USCALED:
+ case PIPE_FORMAT_R32G32B32A32_USCALED:
+ case PIPE_FORMAT_R32_SNORM:
+ case PIPE_FORMAT_R32G32_SNORM:
+ case PIPE_FORMAT_R32G32B32_SNORM:
+ case PIPE_FORMAT_R32G32B32A32_SNORM:
+ case PIPE_FORMAT_R32_SSCALED:
+ case PIPE_FORMAT_R32G32_SSCALED:
+ case PIPE_FORMAT_R32G32B32_SSCALED:
+ case PIPE_FORMAT_R32G32B32A32_SSCALED:
+ case PIPE_FORMAT_R16_UNORM:
+ case PIPE_FORMAT_R16G16_UNORM:
+ case PIPE_FORMAT_R16G16B16_UNORM:
+ case PIPE_FORMAT_R16G16B16A16_UNORM:
+ case PIPE_FORMAT_R16_USCALED:
+ case PIPE_FORMAT_R16G16_USCALED:
+ case PIPE_FORMAT_R16G16B16_USCALED:
+ case PIPE_FORMAT_R16G16B16A16_USCALED:
+ case PIPE_FORMAT_R16_SNORM:
+ case PIPE_FORMAT_R16G16_SNORM:
+ case PIPE_FORMAT_R16G16B16_SNORM:
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ case PIPE_FORMAT_R16_SSCALED:
+ case PIPE_FORMAT_R16G16_SSCALED:
+ case PIPE_FORMAT_R16G16B16_SSCALED:
+ case PIPE_FORMAT_R16G16B16A16_SSCALED:
+ case PIPE_FORMAT_R8_UNORM:
+ case PIPE_FORMAT_R8G8_UNORM:
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ case PIPE_FORMAT_R8_USCALED:
+ case PIPE_FORMAT_R8G8_USCALED:
+ case PIPE_FORMAT_R8G8B8_USCALED:
+ case PIPE_FORMAT_R8_SNORM:
+ case PIPE_FORMAT_R8G8_SNORM:
+ case PIPE_FORMAT_R8G8B8_SNORM:
+ case PIPE_FORMAT_R8_SSCALED:
+ case PIPE_FORMAT_R8G8_SSCALED:
+ case PIPE_FORMAT_R8G8B8_SSCALED:
+ case PIPE_FORMAT_R32_FIXED:
+ case PIPE_FORMAT_R32G32_FIXED:
+ case PIPE_FORMAT_R32G32B32_FIXED:
+ case PIPE_FORMAT_R32G32B32A32_FIXED:
+ default:
+ fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pformat);
+ return -EINVAL;
+ }
+}
+
+int r600_conv_pipe_prim(unsigned pprim, unsigned *prim)
+{
+ switch (pprim) {
+ case PIPE_PRIM_POINTS:
+ *prim = V_008958_DI_PT_POINTLIST;
+ return 0;
+ case PIPE_PRIM_LINES:
+ *prim = V_008958_DI_PT_LINELIST;
+ return 0;
+ case PIPE_PRIM_LINE_STRIP:
+ *prim = V_008958_DI_PT_LINESTRIP;
+ return 0;
+ case PIPE_PRIM_LINE_LOOP:
+ *prim = V_008958_DI_PT_LINELOOP;
+ return 0;
+ case PIPE_PRIM_TRIANGLES:
+ *prim = V_008958_DI_PT_TRILIST;
+ return 0;
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ *prim = V_008958_DI_PT_TRISTRIP;
+ return 0;
+ case PIPE_PRIM_TRIANGLE_FAN:
+ *prim = V_008958_DI_PT_TRIFAN;
+ return 0;
+ case PIPE_PRIM_POLYGON:
+ *prim = V_008958_DI_PT_POLYGON;
+ return 0;
+ case PIPE_PRIM_QUADS:
+ *prim = V_008958_DI_PT_QUADLIST;
+ return 0;
+ case PIPE_PRIM_QUAD_STRIP:
+ *prim = V_008958_DI_PT_QUADSTRIP;
+ return 0;
+ default:
+ fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, pprim);
+ return -EINVAL;
+ }
+}
diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c
new file mode 100644
index 0000000000..24746e7877
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_query.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson
+ */
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include <util/u_memory.h>
+#include "r600_screen.h"
+#include "r600_context.h"
+
+static struct pipe_query *r600_create_query(struct pipe_context *pipe, unsigned query_type)
+{
+ return NULL;
+}
+
+static void r600_destroy_query(struct pipe_context *pipe, struct pipe_query *query)
+{
+ FREE(query);
+}
+
+static void r600_begin_query(struct pipe_context *pipe, struct pipe_query *query)
+{
+}
+
+static void r600_end_query(struct pipe_context *pipe, struct pipe_query *query)
+{
+}
+
+static boolean r600_get_query_result(struct pipe_context *pipe,
+ struct pipe_query *query,
+ boolean wait, uint64_t *result)
+{
+ return TRUE;
+}
+
+void r600_init_query_functions(struct r600_context* rctx)
+{
+ rctx->context.create_query = r600_create_query;
+ rctx->context.destroy_query = r600_destroy_query;
+ rctx->context.begin_query = r600_begin_query;
+ rctx->context.end_query = r600_end_query;
+ rctx->context.get_query_result = r600_get_query_result;
+}
diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c
new file mode 100644
index 0000000000..d9aa1df04f
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_resource.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@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.
+ */
+
+#include "r600_context.h"
+#include "r600_resource.h"
+#include "r600_screen.h"
+#include "r600_texture.h"
+
+static struct pipe_resource *
+r600_resource_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
+{
+ if (templ->target == PIPE_BUFFER)
+ return r600_buffer_create(screen, templ);
+ else
+ return r600_texture_create(screen, templ);
+}
+
+static struct pipe_resource *
+r600_resource_from_handle(struct pipe_screen * screen,
+ const struct pipe_resource *templ,
+ struct winsys_handle *whandle)
+{
+ if (templ->target == PIPE_BUFFER)
+ return NULL;
+ else
+ return r600_texture_from_handle(screen, templ, whandle);
+}
+
+void r600_init_context_resource_functions(struct r600_context *r600)
+{
+ r600->context.get_transfer = u_get_transfer_vtbl;
+ r600->context.transfer_map = u_transfer_map_vtbl;
+ r600->context.transfer_flush_region = u_transfer_flush_region_vtbl;
+ r600->context.transfer_unmap = u_transfer_unmap_vtbl;
+ r600->context.transfer_destroy = u_transfer_destroy_vtbl;
+ r600->context.transfer_inline_write = u_transfer_inline_write_vtbl;
+ r600->context.is_resource_referenced = u_is_resource_referenced_vtbl;
+}
+
+void r600_init_screen_resource_functions(struct r600_screen *r600screen)
+{
+ r600screen->screen.resource_create = r600_resource_create;
+ r600screen->screen.resource_from_handle = r600_resource_from_handle;
+ r600screen->screen.resource_get_handle = u_resource_get_handle_vtbl;
+ r600screen->screen.resource_destroy = u_resource_destroy_vtbl;
+ r600screen->screen.user_buffer_create = r600_user_buffer_create;
+}
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
new file mode 100644
index 0000000000..95084a371b
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Marek Olšák <maraeo@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 R600_RESOURCE_H
+#define R600_RESOURCE_H
+
+struct r600_context;
+struct r600_screen;
+
+void r600_init_context_resource_functions(struct r600_context *r600);
+void r600_init_screen_resource_functions(struct r600_screen *r600screen);
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_screen.c b/src/gallium/drivers/r600/r600_screen.c
new file mode 100644
index 0000000000..7d39184d90
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_screen.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson
+ */
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include <util/u_memory.h>
+#include "r600_resource.h"
+#include "r600_screen.h"
+#include "r600_texture.h"
+#include "r600_context.h"
+#include <stdio.h>
+
+static const char* r600_get_vendor(struct pipe_screen* pscreen)
+{
+ return "X.Org";
+}
+
+static const char* r600_get_name(struct pipe_screen* pscreen)
+{
+ return "R600/R700 (HD2XXX,HD3XXX,HD4XXX)";
+}
+
+static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ case PIPE_CAP_MAX_COMBINED_SAMPLERS:
+ return 16;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 1;
+ case PIPE_CAP_DUAL_SOURCE_BLEND:
+ return 1;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 1;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ /* FIXME some r6xx are buggy and can only do 4 */
+ return 8;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ /* FIXME not sure here */
+ return 13;
+ case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+ return 1;
+ case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+ return 1;
+ case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+ /* FIXME allow this once infrastructure is there */
+ return 0;
+ case PIPE_CAP_TGSI_CONT_SUPPORTED:
+ return 0;
+ case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ return 1;
+ case PIPE_CAP_SM3:
+ return 1;
+ case PIPE_CAP_INDEP_BLEND_ENABLE:
+ return 1;
+ case PIPE_CAP_INDEP_BLEND_FUNC:
+ /* FIXME allow this */
+ return 0;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
+ return 1;
+ case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
+ case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+ return 0;
+ default:
+ debug_printf("r600: unknown param %d\n", param);
+ return 0;
+ }
+}
+
+static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 8192.0f;
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 16.0f;
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0f;
+ default:
+ debug_printf("r600: unsupported paramf %d\n", param);
+ return 0.0f;
+ }
+}
+
+static boolean r600_is_format_supported(struct pipe_screen* screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned sample_count,
+ unsigned bindings,
+ unsigned geom_flags)
+{
+ if (target >= PIPE_MAX_TEXTURE_TYPES) {
+ debug_printf("r600: unsupported texture type %d\n", target);
+ return FALSE;
+ }
+ switch (format) {
+ case PIPE_FORMAT_B4G4R4A4_UNORM:
+ case PIPE_FORMAT_B5G6R5_UNORM:
+ case PIPE_FORMAT_B5G5R5A1_UNORM:
+ case PIPE_FORMAT_A8_UNORM:
+ case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ case PIPE_FORMAT_R8G8B8A8_SRGB:
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ case PIPE_FORMAT_UYVY:
+ case PIPE_FORMAT_L8_SRGB:
+ case PIPE_FORMAT_L8A8_SRGB:
+ case PIPE_FORMAT_L8A8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ case PIPE_FORMAT_R8G8B8X8_UNORM:
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_I8_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ return TRUE;
+ default:
+ /* Unknown format... */
+ break;
+ }
+ return FALSE;
+}
+
+struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box)
+{
+ struct r600_texture *rtex = (struct r600_texture*)texture;
+ struct r600_transfer *trans;
+
+ trans = CALLOC_STRUCT(r600_transfer);
+ if (trans == NULL)
+ return NULL;
+ pipe_resource_reference(&trans->transfer.resource, texture);
+ trans->transfer.sr = sr;
+ trans->transfer.usage = usage;
+ trans->transfer.box = *box;
+ trans->transfer.stride = rtex->stride[sr.level];
+ trans->offset = r600_texture_get_offset(rtex, sr.level, box->z, sr.face);
+ return &trans->transfer;
+}
+
+void r600_texture_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans)
+{
+ pipe_resource_reference(&trans->resource, NULL);
+ FREE(trans);
+}
+
+void* r600_texture_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer* transfer)
+{
+ struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+ struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
+ char *map;
+ enum pipe_format format = rtex->b.b.format;
+
+ map = pipe_buffer_map(ctx, rtex->buffer,
+ transfer->usage,
+ &rtransfer->buffer_transfer);
+
+ if (!map) {
+ return NULL;
+ }
+
+ return map + rtransfer->offset +
+ transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
+ transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
+}
+
+void r600_texture_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer* transfer)
+{
+ struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
+ struct r600_texture *rtex = (struct r600_texture*)transfer->resource;
+
+ pipe_buffer_unmap(ctx, rtex->buffer, rtransfer->buffer_transfer);
+}
+
+static void r600_destroy_screen(struct pipe_screen* pscreen)
+{
+ struct r600_screen* rscreen = r600_screen(pscreen);
+
+ if (rscreen == NULL)
+ return;
+ FREE(rscreen);
+}
+
+struct pipe_screen *radeon_create_screen(struct radeon *rw)
+{
+ struct r600_screen* rscreen;
+
+ rscreen = CALLOC_STRUCT(r600_screen);
+ if (rscreen == NULL) {
+ return NULL;
+ }
+ rscreen->rw = rw;
+ rscreen->screen.winsys = (struct pipe_winsys*)rw;
+ rscreen->screen.destroy = r600_destroy_screen;
+ rscreen->screen.get_name = r600_get_name;
+ rscreen->screen.get_vendor = r600_get_vendor;
+ rscreen->screen.get_param = r600_get_param;
+ rscreen->screen.get_paramf = r600_get_paramf;
+ rscreen->screen.is_format_supported = r600_is_format_supported;
+ rscreen->screen.context_create = r600_create_context;
+ r600_init_screen_texture_functions(&rscreen->screen);
+ r600_init_screen_resource_functions(rscreen);
+ return &rscreen->screen;
+}
diff --git a/src/gallium/drivers/r600/r600_screen.h b/src/gallium/drivers/r600/r600_screen.h
new file mode 100644
index 0000000000..4748021d07
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_screen.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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 R600_SCREEN_H
+#define R600_SCREEN_H
+
+#include <pipe/p_state.h>
+#include <pipe/p_screen.h>
+#include <pipebuffer/pb_buffer.h>
+#include <xf86drm.h>
+#include <radeon_drm.h>
+#include "radeon.h"
+#include "util/u_transfer.h"
+
+#define r600_screen(s) ((struct r600_screen*)s)
+
+/* Texture transfer. */
+struct r600_transfer {
+ /* Base class. */
+ struct pipe_transfer transfer;
+ /* Buffer transfer. */
+ struct pipe_transfer *buffer_transfer;
+ unsigned offset;
+};
+
+struct r600_buffer {
+ struct u_resource b;
+ struct radeon_bo *bo;
+ u32 domain;
+ u32 flink;
+ struct pb_buffer *pb;
+};
+
+struct r600_screen {
+ struct pipe_screen screen;
+ struct radeon *rw;
+};
+
+/* Buffer functions. */
+struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ);
+struct pipe_resource *r600_user_buffer_create(struct pipe_screen *screen,
+ void *ptr, unsigned bytes,
+ unsigned bind);
+unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context,
+ struct pipe_resource *buf,
+ unsigned face, unsigned level);
+struct pipe_resource *r600_buffer_from_handle(struct pipe_screen *screen,
+ struct winsys_handle *whandle);
+
+/* Texture transfer functions. */
+struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ struct pipe_subresource sr,
+ unsigned usage,
+ const struct pipe_box *box);
+void r600_texture_transfer_destroy(struct pipe_context *ctx,
+ struct pipe_transfer *trans);
+void* r600_texture_transfer_map(struct pipe_context *ctx,
+ struct pipe_transfer* transfer);
+void r600_texture_transfer_unmap(struct pipe_context *ctx,
+ struct pipe_transfer* transfer);
+
+
+/* Blit functions. */
+void r600_clear(struct pipe_context *ctx,
+ unsigned buffers,
+ const float *rgba,
+ double depth,
+ unsigned stencil);
+void r600_surface_copy(struct pipe_context *ctx,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height);
+void r600_surface_fill(struct pipe_context *ctx,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value);
+
+/* helpers */
+int r600_conv_pipe_format(unsigned pformat, unsigned *format);
+int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
+
+union r600_float_to_u32_u {
+ u32 u;
+ float f;
+};
+
+static inline u32 r600_float_to_u32(float f)
+{
+ union r600_float_to_u32_u c;
+
+ c.f = f;
+ return c.u;
+}
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
new file mode 100644
index 0000000000..6729fdd0e5
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include <util/u_memory.h>
+#include <tgsi/tgsi_dump.h>
+#include "r600_screen.h"
+#include "r600_context.h"
+#include "r600d.h"
+
+static int r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_shader *rshader = &rpshader->shader;
+ struct radeon_state *state;
+ unsigned i, tmp;
+
+ rpshader->state = radeon_state_decref(rpshader->state);
+ state = radeon_state(rscreen->rw, R600_VS_SHADER_TYPE, R600_VS_SHADER);
+ if (state == NULL)
+ return -ENOMEM;
+ for (i = 0; i < rshader->noutput; i += 4) {
+ tmp = rshader->output[i].sid;
+ tmp |= rshader->output[i + 1].sid << 8;
+ tmp |= rshader->output[i + 2].sid << 16;
+ tmp |= rshader->output[i + 3].sid << 24;
+ state->states[R600_VS_SHADER__SPI_VS_OUT_ID_0 + i / 4] = tmp;
+ }
+ state->states[R600_VS_SHADER__SPI_VS_OUT_CONFIG] = S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 1);
+ state->states[R600_VS_SHADER__SQ_PGM_RESOURCES_VS] = S_028868_NUM_GPRS(rshader->ngpr);
+ rpshader->state = state;
+ rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+ rpshader->state->bo[1] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+ rpshader->state->nbo = 2;
+ rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ return radeon_state_pm4(state);
+}
+
+static int r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_shader *rshader = &rpshader->shader;
+ struct radeon_state *state;
+ unsigned i, tmp;
+
+ rpshader->state = radeon_state_decref(rpshader->state);
+ state = radeon_state(rscreen->rw, R600_PS_SHADER_TYPE, R600_PS_SHADER);
+ if (state == NULL)
+ return -ENOMEM;
+ for (i = 0; i < rshader->ninput; i++) {
+ tmp = S_028644_SEMANTIC(rshader->input[i].sid);
+ tmp |= S_028644_SEL_CENTROID(1);
+ tmp |= S_028644_FLAT_SHADE(rshader->flat_shade);
+ state->states[R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 + i] = tmp;
+ }
+ state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_0] = S_0286CC_NUM_INTERP(rshader->ninput) |
+ S_0286CC_PERSP_GRADIENT_ENA(1);
+ state->states[R600_PS_SHADER__SPI_PS_IN_CONTROL_1] = 0x00000000;
+ state->states[R600_PS_SHADER__SQ_PGM_RESOURCES_PS] = S_028868_NUM_GPRS(rshader->ngpr);
+ state->states[R600_PS_SHADER__SQ_PGM_EXPORTS_PS] = 0x00000002;
+ rpshader->state = state;
+ rpshader->state->bo[0] = radeon_bo_incref(rscreen->rw, rpshader->bo);
+ rpshader->state->nbo = 1;
+ rpshader->state->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ return radeon_state_pm4(state);
+}
+
+static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct r600_shader *rshader = &rpshader->shader;
+ int r;
+
+ /* copy new shader */
+ radeon_bo_decref(rscreen->rw, rpshader->bo);
+ rpshader->bo = NULL;
+ rpshader->bo = radeon_bo(rscreen->rw, 0, rshader->ndw * 4,
+ 4096, NULL);
+ if (rpshader->bo == NULL) {
+ return -ENOMEM;
+ }
+ radeon_bo_map(rscreen->rw, rpshader->bo);
+ memcpy(rpshader->bo->data, rshader->bcode, rshader->ndw * 4);
+ radeon_bo_unmap(rscreen->rw, rpshader->bo);
+ /* build state */
+ rshader->flat_shade = rctx->flat_shade;
+ switch (rpshader->type) {
+ case C_PROGRAM_TYPE_VS:
+ r = r600_pipe_shader_vs(ctx, rpshader);
+ break;
+ case C_PROGRAM_TYPE_FS:
+ r = r600_pipe_shader_ps(ctx, rpshader);
+ break;
+ default:
+ r = -EINVAL;
+ break;
+ }
+ return r;
+}
+
+struct r600_pipe_shader *r600_pipe_shader_create(struct pipe_context *ctx, unsigned type, const struct tgsi_token *tokens)
+{
+ struct r600_pipe_shader *rpshader = CALLOC_STRUCT(r600_pipe_shader);
+ struct r600_shader *rshader = &rpshader->shader;
+ int r;
+
+ if (rpshader == NULL)
+ return NULL;
+ rpshader->type = type;
+ c_list_init(&rshader->nodes);
+ fprintf(stderr, "<<\n");
+ tgsi_dump(tokens, 0);
+ fprintf(stderr, "--------------------------------------------------------------\n");
+ r = c_shader_from_tgsi(&rshader->cshader, type, tokens);
+ if (r) {
+ r600_pipe_shader_destroy(ctx, rpshader);
+ fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
+ return NULL;
+ }
+ r = r600_shader_insert_fetch(&rshader->cshader);
+ if (r) {
+ r600_pipe_shader_destroy(ctx, rpshader);
+ fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
+ return NULL;
+ }
+ r = c_shader_build_dominator_tree(&rshader->cshader);
+ if (r) {
+ r600_pipe_shader_destroy(ctx, rpshader);
+ fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
+ return NULL;
+ }
+ c_shader_dump(&rshader->cshader);
+ r = r700_shader_translate(rshader);
+ if (r) {
+ r600_pipe_shader_destroy(ctx, rpshader);
+ fprintf(stderr, "ERROR(%s %d)>>\n\n", __func__, __LINE__);
+ return NULL;
+ }
+#if 1
+#if 0
+ fprintf(stderr, "--------------------------------------------------------------\n");
+ for (int i = 0; i < rshader->ndw; i++) {
+ fprintf(stderr, "0x%08X\n", rshader->bcode[i]);
+ }
+#endif
+ fprintf(stderr, ">>\n\n");
+#endif
+ return rpshader;
+}
+
+void r600_pipe_shader_destroy(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+
+ if (rpshader == NULL)
+ return;
+ radeon_bo_decref(rscreen->rw, rpshader->bo);
+ rpshader->bo = NULL;
+ r600_shader_cleanup(&rpshader->shader);
+ FREE(rpshader);
+}
+
+int r600_pipe_shader_update(struct pipe_context *ctx, struct r600_pipe_shader *rpshader)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct r600_shader *rshader;
+ enum pipe_format resource_format[160];
+ unsigned i, nresources = 0;
+ int r;
+
+ if (rpshader == NULL)
+ return -EINVAL;
+ rshader = &rpshader->shader;
+ switch (rpshader->type) {
+ case C_PROGRAM_TYPE_VS:
+ for (i = 0; i < rctx->vertex_elements->count; i++) {
+ resource_format[nresources++] = rctx->vertex_elements->elements[i].src_format;
+ }
+ break;
+ default:
+ break;
+ }
+ /* there should be enough input */
+ if (nresources < rshader->nresource)
+ return -EINVAL;
+ /* FIXME compare resources */
+ r = r600_shader_update(rshader, resource_format);
+ if (r)
+ return r;
+ return r600_pipe_shader(ctx, rpshader);
+}
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
new file mode 100644
index 0000000000..3b65b29553
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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 R600_SHADER_H
+#define R600_SHADER_H
+
+#include "r600_compiler.h"
+#include "radeon.h"
+
+struct r600_shader_operand {
+ struct c_vector *vector;
+ unsigned sel;
+ unsigned chan;
+ unsigned neg;
+ unsigned abs;
+};
+
+struct r600_shader_vfetch {
+ struct r600_shader_vfetch *next;
+ struct r600_shader_vfetch *prev;
+ unsigned cf_addr;
+ struct r600_shader_operand src[2];
+ struct r600_shader_operand dst[4];
+};
+
+struct r600_shader_inst {
+ unsigned is_op3;
+ unsigned opcode;
+ unsigned inst;
+ struct r600_shader_operand src[3];
+ struct r600_shader_operand dst;
+ unsigned last;
+};
+
+struct r600_shader_alu {
+ struct r600_shader_alu *next;
+ struct r600_shader_alu *prev;
+ unsigned nalu;
+ unsigned nliteral;
+ unsigned nconstant;
+ struct r600_shader_inst alu[5];
+ u32 literal[4];
+};
+
+struct r600_shader_node {
+ struct r600_shader_node *next;
+ struct r600_shader_node *prev;
+ unsigned cf_id; /**< cf index (in dw) in byte code */
+ unsigned cf_addr; /**< instructions index (in dw) in byte code */
+ unsigned nslot; /**< number of slot (2 dw) needed by this node */
+ unsigned nfetch;
+ struct c_node *node; /**< compiler node from which this node originate */
+ struct r600_shader_vfetch vfetch; /**< list of vfetch instructions */
+ struct r600_shader_alu alu; /**< list of alu instructions */
+};
+
+struct r600_shader_io {
+ unsigned name;
+ unsigned gpr;
+ int sid;
+};
+
+struct r600_shader {
+ unsigned stack_size; /**< stack size needed by this shader */
+ unsigned ngpr; /**< number of GPR needed by this shader */
+ unsigned nconstant; /**< number of constants used by this shader */
+ unsigned nresource; /**< number of resources used by this shader */
+ unsigned noutput;
+ unsigned ninput;
+ unsigned nvector;
+ unsigned ncf; /**< total number of cf clauses */
+ unsigned nslot; /**< total number of slots (2 dw) */
+ unsigned flat_shade; /**< are we flat shading */
+ struct r600_shader_node nodes; /**< list of node */
+ struct r600_shader_io input[32];
+ struct r600_shader_io output[32];
+ /* TODO replace GPR by some better register allocator */
+ struct c_vector **gpr;
+ unsigned ndw; /**< bytes code size in dw */
+ u32 *bcode; /**< bytes code */
+ enum pipe_format resource_format[160]; /**< format of resource */
+ struct c_shader cshader;
+};
+
+void r600_shader_cleanup(struct r600_shader *rshader);
+int r600_shader_register(struct r600_shader *rshader);
+int r600_shader_node(struct r600_shader *shader);
+void r600_shader_node_place(struct r600_shader *rshader);
+int r600_shader_find_gpr(struct r600_shader *rshader, struct c_vector *v, unsigned swizzle,
+ struct r600_shader_operand *operand);
+int r600_shader_vfetch_bytecode(struct r600_shader *rshader,
+ struct r600_shader_node *rnode,
+ struct r600_shader_vfetch *vfetch,
+ unsigned *cid);
+int r600_shader_update(struct r600_shader *rshader,
+ enum pipe_format *resource_format);
+int r600_shader_legalize(struct r600_shader *rshader);
+
+int r700_shader_translate(struct r600_shader *rshader);
+
+int c_shader_from_tgsi(struct c_shader *shader, unsigned type,
+ const struct tgsi_token *tokens);
+int r600_shader_register(struct r600_shader *rshader);
+int r600_shader_translate_rec(struct r600_shader *rshader, struct c_node *node);
+int r700_shader_translate(struct r600_shader *rshader);
+int r600_shader_insert_fetch(struct c_shader *shader);
+
+enum r600_instruction {
+ INST_ADD = 0,
+ INST_MUL = 1,
+ INST_MUL_IEEE = 2,
+ INST_MAX = 3,
+ INST_MIN = 4,
+ INST_MAX_DX10 = 5,
+ INST_MIN_DX10 = 6,
+ INST_SETE = 7,
+ INST_SETGT = 8,
+ INST_SETGE = 9,
+ INST_SETNE = 10,
+ INST_SETE_DX10 = 11,
+ INST_SETGT_DX10 = 12,
+ INST_SETGE_DX10 = 13,
+ INST_SETNE_DX10 = 14,
+ INST_FRACT = 15,
+ INST_TRUNC = 16,
+ INST_CEIL = 17,
+ INST_RNDNE = 18,
+ INST_FLOOR = 19,
+ INST_MOVA = 20,
+ INST_MOVA_FLOOR = 21,
+ INST_MOVA_INT = 22,
+ INST_MOV = 23,
+ INST_NOP = 24,
+ INST_PRED_SETGT_UINT = 25,
+ INST_PRED_SETGE_UINT = 26,
+ INST_PRED_SETE = 27,
+ INST_PRED_SETGT = 28,
+ INST_PRED_SETGE = 29,
+ INST_PRED_SETNE = 30,
+ INST_PRED_SET_INV = 31,
+ INST_PRED_SET_POP = 32,
+ INST_PRED_SET_CLR = 33,
+ INST_PRED_SET_RESTORE = 34,
+ INST_PRED_SETE_PUSH = 35,
+ INST_PRED_SETGT_PUSH = 36,
+ INST_PRED_SETGE_PUSH = 37,
+ INST_PRED_SETNE_PUSH = 38,
+ INST_KILLE = 39,
+ INST_KILLGT = 40,
+ INST_KILLGE = 41,
+ INST_KILLNE = 42,
+ INST_AND_INT = 43,
+ INST_OR_INT = 44,
+ INST_XOR_INT = 45,
+ INST_NOT_INT = 46,
+ INST_ADD_INT = 47,
+ INST_SUB_INT = 48,
+ INST_MAX_INT = 49,
+ INST_MIN_INT = 50,
+ INST_MAX_UINT = 51,
+ INST_MIN_UINT = 52,
+ INST_SETE_INT = 53,
+ INST_SETGT_INT = 54,
+ INST_SETGE_INT = 55,
+ INST_SETNE_INT = 56,
+ INST_SETGT_UINT = 57,
+ INST_SETGE_UINT = 58,
+ INST_KILLGT_UINT = 59,
+ INST_KILLGE_UINT = 60,
+ INST_PRED_SETE_INT = 61,
+ INST_PRED_SETGT_INT = 62,
+ INST_PRED_SETGE_INT = 63,
+ INST_PRED_SETNE_INT = 64,
+ INST_KILLE_INT = 65,
+ INST_KILLGT_INT = 66,
+ INST_KILLGE_INT = 67,
+ INST_KILLNE_INT = 68,
+ INST_PRED_SETE_PUSH_INT = 69,
+ INST_PRED_SETGT_PUSH_INT = 70,
+ INST_PRED_SETGE_PUSH_INT = 71,
+ INST_PRED_SETNE_PUSH_INT = 72,
+ INST_PRED_SETLT_PUSH_INT = 73,
+ INST_PRED_SETLE_PUSH_INT = 74,
+ INST_DOT4 = 75,
+ INST_DOT4_IEEE = 76,
+ INST_CUBE = 77,
+ INST_MAX4 = 78,
+ INST_MOVA_GPR_INT = 79,
+ INST_EXP_IEEE = 80,
+ INST_LOG_CLAMPED = 81,
+ INST_LOG_IEEE = 82,
+ INST_RECIP_CLAMPED = 83,
+ INST_RECIP_FF = 84,
+ INST_RECIP_IEEE = 85,
+ INST_RECIPSQRT_CLAMPED = 86,
+ INST_RECIPSQRT_FF = 87,
+ INST_RECIPSQRT_IEEE = 88,
+ INST_SQRT_IEEE = 89,
+ INST_FLT_TO_INT = 90,
+ INST_INT_TO_FLT = 91,
+ INST_UINT_TO_FLT = 92,
+ INST_SIN = 93,
+ INST_COS = 94,
+ INST_ASHR_INT = 95,
+ INST_LSHR_INT = 96,
+ INST_LSHL_INT = 97,
+ INST_MULLO_INT = 98,
+ INST_MULHI_INT = 99,
+ INST_MULLO_UINT = 100,
+ INST_MULHI_UINT = 101,
+ INST_RECIP_INT = 102,
+ INST_RECIP_UINT = 103,
+ INST_FLT_TO_UINT = 104,
+ INST_MUL_LIT = 105,
+ INST_MUL_LIT_M2 = 106,
+ INST_MUL_LIT_M4 = 107,
+ INST_MUL_LIT_D2 = 108,
+ INST_MULADD = 109,
+ INST_MULADD_M2 = 110,
+ INST_MULADD_M4 = 111,
+ INST_MULADD_D2 = 112,
+ INST_MULADD_IEEE = 113,
+ INST_MULADD_IEEE_M2 = 114,
+ INST_MULADD_IEEE_M4 = 115,
+ INST_MULADD_IEEE_D2 = 116,
+ INST_CNDE = 117,
+ INST_CNDGT = 118,
+ INST_CNDGE = 119,
+ INST_CNDE_INT = 120,
+ INST_CNDGT_INT = 121,
+ INST_CNDGE_INT = 122,
+ INST_COUNT
+};
+
+struct r600_instruction_info {
+ enum r600_instruction instruction;
+ unsigned opcode;
+ unsigned is_trans;
+ unsigned is_op3;
+};
+
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_sq.h b/src/gallium/drivers/r600/r600_sq.h
new file mode 100644
index 0000000000..71aa09719e
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_sq.h
@@ -0,0 +1,606 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef R600_SQ_H
+#define R600_SQ_H
+
+#define P_SQ_CF_WORD0
+#define S_SQ_CF_WORD0_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_SQ_CF_WORD0_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_SQ_CF_WORD0_ADDR 0x00000000
+#define P_SQ_CF_WORD1
+#define S_SQ_CF_WORD1_POP_COUNT(x) (((x) & 0x7) << 0)
+#define G_SQ_CF_WORD1_POP_COUNT(x) (((x) >> 0) & 0x7)
+#define C_SQ_CF_WORD1_POP_COUNT 0xFFFFFFF8
+#define S_SQ_CF_WORD1_CF_CONST(x) (((x) & 0x1F) << 3)
+#define G_SQ_CF_WORD1_CF_CONST(x) (((x) >> 3) & 0x1F)
+#define C_SQ_CF_WORD1_CF_CONST 0xFFFFFF07
+#define S_SQ_CF_WORD1_COND(x) (((x) & 0x3) << 8)
+#define G_SQ_CF_WORD1_COND(x) (((x) >> 8) & 0x3)
+#define C_SQ_CF_WORD1_COND 0xFFFFFCFF
+#define S_SQ_CF_WORD1_COUNT(x) (((x) & 0x7) << 10)
+#define G_SQ_CF_WORD1_COUNT(x) (((x) >> 10) & 0x7)
+#define C_SQ_CF_WORD1_COUNT 0xFFFFE3FF
+#define S_SQ_CF_WORD1_CALL_COUNT(x) (((x) & 0x3F) << 13)
+#define G_SQ_CF_WORD1_CALL_COUNT(x) (((x) >> 13) & 0x3F)
+#define C_SQ_CF_WORD1_CALL_COUNT 0xFFF81FFF
+#define S_SQ_CF_WORD1_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_SQ_CF_WORD1_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_SQ_CF_WORD1_END_OF_PROGRAM 0xFFDFFFFF
+#define S_SQ_CF_WORD1_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_SQ_CF_WORD1_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_SQ_CF_WORD1_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_SQ_CF_WORD1_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_SQ_CF_WORD1_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_SQ_CF_WORD1_CF_INST 0xC07FFFFF
+#define V_SQ_CF_WORD1_SQ_CF_INST_NOP 0x00000000
+#define V_SQ_CF_WORD1_SQ_CF_INST_TEX 0x00000001
+#define V_SQ_CF_WORD1_SQ_CF_INST_VTX 0x00000002
+#define V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC 0x00000003
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START 0x00000004
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END 0x00000005
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_DX10 0x00000006
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL 0x00000007
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE 0x00000008
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK 0x00000009
+#define V_SQ_CF_WORD1_SQ_CF_INST_JUMP 0x0000000A
+#define V_SQ_CF_WORD1_SQ_CF_INST_PUSH 0x0000000B
+#define V_SQ_CF_WORD1_SQ_CF_INST_PUSH_ELSE 0x0000000C
+#define V_SQ_CF_WORD1_SQ_CF_INST_ELSE 0x0000000D
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP 0x0000000E
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP_JUMP 0x0000000F
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP_PUSH 0x00000010
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP_PUSH_ELSE 0x00000011
+#define V_SQ_CF_WORD1_SQ_CF_INST_CALL 0x00000012
+#define V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS 0x00000013
+#define V_SQ_CF_WORD1_SQ_CF_INST_RETURN 0x00000014
+#define V_SQ_CF_WORD1_SQ_CF_INST_EMIT_VERTEX 0x00000015
+#define V_SQ_CF_WORD1_SQ_CF_INST_EMIT_CUT_VERTEX 0x00000016
+#define V_SQ_CF_WORD1_SQ_CF_INST_CUT_VERTEX 0x00000017
+#define V_SQ_CF_WORD1_SQ_CF_INST_KILL 0x00000018
+#define S_SQ_CF_WORD1_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_SQ_CF_WORD1_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_SQ_CF_WORD1_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_SQ_CF_WORD1_BARRIER(x) (((x) & 0x1) << 31)
+#define G_SQ_CF_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_SQ_CF_WORD1_BARRIER 0x7FFFFFFF
+#define P_SQ_CF_ALU_WORD0
+#define S_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0)
+#define G_SQ_CF_ALU_WORD0_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF)
+#define C_SQ_CF_ALU_WORD0_ALU_ADDR 0xFFC00000
+#define S_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) & 0xF) << 22)
+#define G_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) >> 22) & 0xF)
+#define C_SQ_CF_ALU_WORD0_KCACHE_BANK0 0xFC3FFFFF
+#define S_SQ_CF_ALU_WORD0_KCACHE_BANK1(x) (((x) & 0xF) << 26)
+#define G_SQ_CF_ALU_WORD0_KCACHE_BANK1(x) (((x) >> 26) & 0xF)
+#define C_SQ_CF_ALU_WORD0_KCACHE_BANK1 0xC3FFFFFF
+#define S_SQ_CF_ALU_WORD0_KCACHE_MODE0(x) (((x) & 0x3) << 30)
+#define G_SQ_CF_ALU_WORD0_KCACHE_MODE0(x) (((x) >> 30) & 0x3)
+#define C_SQ_CF_ALU_WORD0_KCACHE_MODE0 0x3FFFFFFF
+#define P_SQ_CF_ALU_WORD1
+#define S_SQ_CF_ALU_WORD1_KCACHE_MODE1(x) (((x) & 0x3) << 0)
+#define G_SQ_CF_ALU_WORD1_KCACHE_MODE1(x) (((x) >> 0) & 0x3)
+#define C_SQ_CF_ALU_WORD1_KCACHE_MODE1 0xFFFFFFFC
+#define S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(x) (((x) & 0xFF) << 2)
+#define G_SQ_CF_ALU_WORD1_KCACHE_ADDR0(x) (((x) >> 2) & 0xFF)
+#define C_SQ_CF_ALU_WORD1_KCACHE_ADDR0 0xFFFFFC03
+#define S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) & 0xFF) << 10)
+#define G_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF)
+#define C_SQ_CF_ALU_WORD1_KCACHE_ADDR1 0xFFFC03FF
+#define S_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) & 0x7F) << 18)
+#define G_SQ_CF_ALU_WORD1_ALU_COUNT(x) (((x) >> 18) & 0x7F)
+#define C_SQ_CF_ALU_WORD1_ALU_COUNT 0xFE03FFFF
+#define S_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) & 0x1) << 25)
+#define G_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) >> 25) & 0x1)
+#define C_SQ_CF_ALU_WORD1_USES_WATERFALL 0xFDFFFFFF
+#define S_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) & 0xF) << 26)
+#define G_SQ_CF_ALU_WORD1_CF_ALU_INST(x) (((x) >> 26) & 0xF)
+#define C_SQ_CF_ALU_WORD1_CF_ALU_INST 0xC3FFFFFF
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU 0x00000008
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER 0x0000000A
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER 0x0000000B
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_CONTINUE 0x0000000D
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_BREAK 0x0000000E
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_ELSE_AFTER 0x0000000F
+#define S_SQ_CF_ALU_WORD1_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_SQ_CF_ALU_WORD1_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_SQ_CF_ALU_WORD1_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_SQ_CF_ALU_WORD1_BARRIER(x) (((x) & 0x1) << 31)
+#define G_SQ_CF_ALU_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_SQ_CF_ALU_WORD1_BARRIER 0x7FFFFFFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD0
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(x) (((x) & 0x1FFF) << 0)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(x) (((x) >> 0) & 0x1FFF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE 0xFFFFE000
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(x) (((x) & 0x3) << 13)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(x) (((x) >> 13) & 0x3)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_TYPE 0xFFFF9FFF
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL 0x00000000
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS 0x00000001
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM 0x00000002
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_SX 0x00000003
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(x) (((x) & 0x7F) << 15)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(x) (((x) >> 15) & 0x7F)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR 0xFFC07FFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_RW_REL(x) (((x) & 0x1) << 22)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_RW_REL(x) (((x) >> 22) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_RW_REL 0xFFBFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR(x) (((x) & 0x7F) << 23)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR(x) (((x) >> 23) & 0x7F)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR 0xC07FFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(x) (((x) & 0x3) << 30)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(x) (((x) >> 30) & 0x3)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE 0x3FFFFFFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD1
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(x) (((x) & 0xF) << 17)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(x) (((x) >> 17) & 0xF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT 0xFFE1FFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM 0xFFDFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST 0xC07FFFFF
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0 0x00000020
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1 0x00000021
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2 0x00000022
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3 0x00000023
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_SCRATCH 0x00000024
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_REDUCTION 0x00000025
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_RING 0x00000026
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT 0x00000027
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE 0x00000028
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(x) (((x) & 0x1) << 31)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER 0x7FFFFFFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD1_BUF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(x) (((x) & 0xFFF) << 0)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(x) (((x) >> 0) & 0xFFF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE 0xFFFFF000
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(x) (((x) & 0xF) << 12)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(x) (((x) >> 12) & 0xF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK 0xFFFF0FFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(x) (((x) & 0x7) << 0)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(x) (((x) >> 0) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X 0xFFFFFFF8
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(x) (((x) & 0x7) << 3)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(x) (((x) >> 3) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y 0xFFFFFFC7
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(x) (((x) & 0x7) << 6)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(x) (((x) >> 6) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z 0xFFFFFE3F
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(x) (((x) & 0x7) << 9)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(x) (((x) >> 9) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W 0xFFFFF1FF
+#define P_SQ_ALU_WORD0
+#define S_SQ_ALU_WORD0_SRC0_SEL(x) (((x) & 0x1FF) << 0)
+#define G_SQ_ALU_WORD0_SRC0_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_SQ_ALU_WORD0_SRC0_SEL 0xFFFFFE00
+#define S_SQ_ALU_WORD0_SRC0_REL(x) (((x) & 0x1) << 9)
+#define G_SQ_ALU_WORD0_SRC0_REL(x) (((x) >> 9) & 0x1)
+#define C_SQ_ALU_WORD0_SRC0_REL 0xFFFFFDFF
+#define S_SQ_ALU_WORD0_SRC0_CHAN(x) (((x) & 0x3) << 10)
+#define G_SQ_ALU_WORD0_SRC0_CHAN(x) (((x) >> 10) & 0x3)
+#define C_SQ_ALU_WORD0_SRC0_CHAN 0xFFFFF3FF
+#define S_SQ_ALU_WORD0_SRC0_NEG(x) (((x) & 0x1) << 12)
+#define G_SQ_ALU_WORD0_SRC0_NEG(x) (((x) >> 12) & 0x1)
+#define C_SQ_ALU_WORD0_SRC0_NEG 0xFFFFEFFF
+#define S_SQ_ALU_WORD0_SRC1_SEL(x) (((x) & 0x1FF) << 13)
+#define G_SQ_ALU_WORD0_SRC1_SEL(x) (((x) >> 13) & 0x1FF)
+#define C_SQ_ALU_WORD0_SRC1_SEL 0xFFC01FFF
+#define S_SQ_ALU_WORD0_SRC1_REL(x) (((x) & 0x1) << 22)
+#define G_SQ_ALU_WORD0_SRC1_REL(x) (((x) >> 22) & 0x1)
+#define C_SQ_ALU_WORD0_SRC1_REL 0xFFBFFFFF
+#define S_SQ_ALU_WORD0_SRC1_CHAN(x) (((x) & 0x3) << 23)
+#define G_SQ_ALU_WORD0_SRC1_CHAN(x) (((x) >> 23) & 0x3)
+#define C_SQ_ALU_WORD0_SRC1_CHAN 0xFE7FFFFF
+#define S_SQ_ALU_WORD0_SRC1_NEG(x) (((x) & 0x1) << 25)
+#define G_SQ_ALU_WORD0_SRC1_NEG(x) (((x) >> 25) & 0x1)
+#define C_SQ_ALU_WORD0_SRC1_NEG 0xFDFFFFFF
+#define S_SQ_ALU_WORD0_INDEX_MODE(x) (((x) & 0x7) << 26)
+#define G_SQ_ALU_WORD0_INDEX_MODE(x) (((x) >> 26) & 0x7)
+#define C_SQ_ALU_WORD0_INDEX_MODE 0xE3FFFFFF
+#define S_SQ_ALU_WORD0_PRED_SEL(x) (((x) & 0x3) << 29)
+#define G_SQ_ALU_WORD0_PRED_SEL(x) (((x) >> 29) & 0x3)
+#define C_SQ_ALU_WORD0_PRED_SEL 0x9FFFFFFF
+#define S_SQ_ALU_WORD0_LAST(x) (((x) & 0x1) << 31)
+#define G_SQ_ALU_WORD0_LAST(x) (((x) >> 31) & 0x1)
+#define C_SQ_ALU_WORD0_LAST 0x7FFFFFFF
+#define P_SQ_ALU_WORD1
+#define S_SQ_ALU_WORD1_ENCODING(x) (((x) & 0x7) << 15)
+#define G_SQ_ALU_WORD1_ENCODING(x) (((x) >> 15) & 0x7)
+#define C_SQ_ALU_WORD1_ENCODING 0xFFFC7FFF
+#define S_SQ_ALU_WORD1_BANK_SWIZZLE(x) (((x) & 0x7) << 18)
+#define G_SQ_ALU_WORD1_BANK_SWIZZLE(x) (((x) >> 18) & 0x7)
+#define C_SQ_ALU_WORD1_BANK_SWIZZLE 0xFFE3FFFF
+#define S_SQ_ALU_WORD1_DST_GPR(x) (((x) & 0x7F) << 21)
+#define G_SQ_ALU_WORD1_DST_GPR(x) (((x) >> 21) & 0x7F)
+#define C_SQ_ALU_WORD1_DST_GPR 0xF01FFFFF
+#define S_SQ_ALU_WORD1_DST_REL(x) (((x) & 0x1) << 28)
+#define G_SQ_ALU_WORD1_DST_REL(x) (((x) >> 28) & 0x1)
+#define C_SQ_ALU_WORD1_DST_REL 0xEFFFFFFF
+#define S_SQ_ALU_WORD1_DST_CHAN(x) (((x) & 0x3) << 29)
+#define G_SQ_ALU_WORD1_DST_CHAN(x) (((x) >> 29) & 0x3)
+#define C_SQ_ALU_WORD1_DST_CHAN 0x9FFFFFFF
+#define S_SQ_ALU_WORD1_CLAMP(x) (((x) & 0x1) << 31)
+#define G_SQ_ALU_WORD1_CLAMP(x) (((x) >> 31) & 0x1)
+#define C_SQ_ALU_WORD1_CLAMP 0x7FFFFFFF
+#define P_SQ_ALU_WORD1_OP2
+#define S_SQ_ALU_WORD1_OP2_SRC0_ABS(x) (((x) & 0x1) << 0)
+#define G_SQ_ALU_WORD1_OP2_SRC0_ABS(x) (((x) >> 0) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_SRC0_ABS 0xFFFFFFFE
+#define S_SQ_ALU_WORD1_OP2_SRC1_ABS(x) (((x) & 0x1) << 1)
+#define G_SQ_ALU_WORD1_OP2_SRC1_ABS(x) (((x) >> 1) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_SRC1_ABS 0xFFFFFFFD
+#define S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(x) (((x) & 0x1) << 2)
+#define G_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(x) (((x) >> 2) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK 0xFFFFFFFB
+#define S_SQ_ALU_WORD1_OP2_UPDATE_PRED(x) (((x) & 0x1) << 3)
+#define G_SQ_ALU_WORD1_OP2_UPDATE_PRED(x) (((x) >> 3) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_UPDATE_PRED 0xFFFFFFF7
+#define S_SQ_ALU_WORD1_OP2_WRITE_MASK(x) (((x) & 0x1) << 4)
+#define G_SQ_ALU_WORD1_OP2_WRITE_MASK(x) (((x) >> 4) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_WRITE_MASK 0xFFFFFFEF
+#define S_SQ_ALU_WORD1_OP2_FOG_MERGE(x) (((x) & 0x1) << 5)
+#define G_SQ_ALU_WORD1_OP2_FOG_MERGE(x) (((x) >> 5) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_FOG_MERGE 0xFFFFFFDF
+#define S_SQ_ALU_WORD1_OP2_OMOD(x) (((x) & 0x3) << 6)
+#define G_SQ_ALU_WORD1_OP2_OMOD(x) (((x) >> 6) & 0x3)
+#define C_SQ_ALU_WORD1_OP2_OMOD 0xFFFFFF3F
+#define S_SQ_ALU_WORD1_OP2_ALU_INST(x) (((x) & 0x3FF) << 8)
+#define G_SQ_ALU_WORD1_OP2_ALU_INST(x) (((x) >> 8) & 0x3FF)
+#define C_SQ_ALU_WORD1_OP2_ALU_INST 0xFFFC00FF
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD 0x00000000
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL 0x00000001
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE 0x00000002
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX 0x00000003
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN 0x00000004
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10 0x00000005
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10 0x00000006
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE 0x00000008
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT 0x00000009
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE 0x0000000A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE 0x0000000B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10 0x0000000C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10 0x0000000D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10 0x0000000E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10 0x0000000F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT 0x00000010
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC 0x00000011
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL 0x00000012
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE 0x00000013
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR 0x00000014
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA 0x00000015
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR 0x00000016
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT 0x00000018
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV 0x00000019
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP 0x0000001A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT 0x0000001E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT 0x0000001F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE 0x00000020
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT 0x00000021
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE 0x00000022
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE 0x00000023
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV 0x00000024
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP 0x00000025
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR 0x00000026
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE 0x00000027
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH 0x00000028
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH 0x00000029
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH 0x0000002A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH 0x0000002B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE 0x0000002C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT 0x0000002D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE 0x0000002E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE 0x0000002F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT 0x00000030
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT 0x00000031
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT 0x00000032
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT 0x00000033
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT 0x00000034
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT 0x00000035
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT 0x00000036
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT 0x00000037
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT 0x00000038
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT 0x00000039
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT 0x0000003A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT 0x0000003B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT 0x0000003C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT 0x0000003D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT 0x0000003E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT 0x0000003F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT 0x00000040
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT 0x00000041
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT 0x00000042
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT 0x00000043
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT 0x00000044
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT 0x00000045
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT 0x00000046
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT 0x00000047
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT 0x00000048
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT 0x00000049
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT 0x0000004A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT 0x0000004B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT 0x0000004C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT 0x0000004D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT 0x0000004E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT 0x0000004F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 0x00000050
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE 0x00000051
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE 0x00000052
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4 0x00000053
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT 0x00000060
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE 0x00000061
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED 0x00000062
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE 0x00000063
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED 0x00000064
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF 0x00000065
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE 0x00000066
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED 0x00000067
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF 0x00000068
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE 0x00000069
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE 0x0000006A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT 0x0000006B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT 0x0000006C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT 0x0000006D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN 0x0000006E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS 0x0000006F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT 0x00000070
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT 0x00000071
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT 0x00000072
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT 0x00000073
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT 0x00000074
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT 0x00000075
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT 0x00000076
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT 0x00000077
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT 0x00000078
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT 0x00000079
+#define P_SQ_ALU_WORD1_OP3
+#define S_SQ_ALU_WORD1_OP3_SRC2_SEL(x) (((x) & 0x1FF) << 0)
+#define G_SQ_ALU_WORD1_OP3_SRC2_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_SQ_ALU_WORD1_OP3_SRC2_SEL 0xFFFFFE00
+#define S_SQ_ALU_WORD1_OP3_SRC2_REL(x) (((x) & 0x1) << 9)
+#define G_SQ_ALU_WORD1_OP3_SRC2_REL(x) (((x) >> 9) & 0x1)
+#define C_SQ_ALU_WORD1_OP3_SRC2_REL 0xFFFFFDFF
+#define S_SQ_ALU_WORD1_OP3_SRC2_CHAN(x) (((x) & 0x3) << 10)
+#define G_SQ_ALU_WORD1_OP3_SRC2_CHAN(x) (((x) >> 10) & 0x3)
+#define C_SQ_ALU_WORD1_OP3_SRC2_CHAN 0xFFFFF3FF
+#define S_SQ_ALU_WORD1_OP3_SRC2_NEG(x) (((x) & 0x1) << 12)
+#define G_SQ_ALU_WORD1_OP3_SRC2_NEG(x) (((x) >> 12) & 0x1)
+#define C_SQ_ALU_WORD1_OP3_SRC2_NEG 0xFFFFEFFF
+#define S_SQ_ALU_WORD1_OP3_ALU_INST(x) (((x) & 0x1F) << 13)
+#define G_SQ_ALU_WORD1_OP3_ALU_INST(x) (((x) >> 13) & 0x1F)
+#define C_SQ_ALU_WORD1_OP3_ALU_INST 0xFFFC1FFF
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT 0x0000000C
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 0x0000000D
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4 0x0000000E
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 0x0000000F
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD 0x00000010
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2 0x00000011
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4 0x00000012
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2 0x00000013
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE 0x00000014
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2 0x00000015
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4 0x00000016
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2 0x00000017
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE 0x00000018
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT 0x00000019
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE 0x0000001A
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT 0x0000001C
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT 0x0000001D
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT 0x0000001E
+#define P_SQ_VTX_WORD0
+#define S_SQ_VTX_WORD0_VTX_INST(x) (((x) & 0x1F) << 0)
+#define G_SQ_VTX_WORD0_VTX_INST(x) (((x) >> 0) & 0x1F)
+#define C_SQ_VTX_WORD0_VTX_INST 0xFFFFFFE0
+#define S_SQ_VTX_WORD0_FETCH_TYPE(x) (((x) & 0x3) << 5)
+#define G_SQ_VTX_WORD0_FETCH_TYPE(x) (((x) >> 5) & 0x3)
+#define C_SQ_VTX_WORD0_FETCH_TYPE 0xFFFFFF9F
+#define S_SQ_VTX_WORD0_FETCH_WHOLE_QUAD(x) (((x) & 0x1) << 7)
+#define G_SQ_VTX_WORD0_FETCH_WHOLE_QUAD(x) (((x) >> 7) & 0x1)
+#define C_SQ_VTX_WORD0_FETCH_WHOLE_QUAD 0xFFFFFF7F
+#define S_SQ_VTX_WORD0_BUFFER_ID(x) (((x) & 0xFF) << 8)
+#define G_SQ_VTX_WORD0_BUFFER_ID(x) (((x) >> 8) & 0xFF)
+#define C_SQ_VTX_WORD0_BUFFER_ID 0xFFFF00FF
+#define S_SQ_VTX_WORD0_SRC_GPR(x) (((x) & 0x7F) << 16)
+#define G_SQ_VTX_WORD0_SRC_GPR(x) (((x) >> 16) & 0x7F)
+#define C_SQ_VTX_WORD0_SRC_GPR 0xFF80FFFF
+#define S_SQ_VTX_WORD0_SRC_REL(x) (((x) & 0x1) << 23)
+#define G_SQ_VTX_WORD0_SRC_REL(x) (((x) >> 23) & 0x1)
+#define C_SQ_VTX_WORD0_SRC_REL 0xFF7FFFFF
+#define S_SQ_VTX_WORD0_SRC_SEL_X(x) (((x) & 0x3) << 24)
+#define G_SQ_VTX_WORD0_SRC_SEL_X(x) (((x) >> 24) & 0x3)
+#define C_SQ_VTX_WORD0_SRC_SEL_X 0xFCFFFFFF
+#define S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(x) (((x) & 0x3F) << 26)
+#define G_SQ_VTX_WORD0_MEGA_FETCH_COUNT(x) (((x) >> 26) & 0x3F)
+#define C_SQ_VTX_WORD0_MEGA_FETCH_COUNT 0x03FFFFFF
+#define P_SQ_VTX_WORD1
+#define S_SQ_VTX_WORD1_DST_SEL_X(x) (((x) & 0x7) << 9)
+#define G_SQ_VTX_WORD1_DST_SEL_X(x) (((x) >> 9) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_X 0xFFFFF1FF
+#define S_SQ_VTX_WORD1_DST_SEL_Y(x) (((x) & 0x7) << 12)
+#define G_SQ_VTX_WORD1_DST_SEL_Y(x) (((x) >> 12) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_Y 0xFFFF8FFF
+#define S_SQ_VTX_WORD1_DST_SEL_Z(x) (((x) & 0x7) << 15)
+#define G_SQ_VTX_WORD1_DST_SEL_Z(x) (((x) >> 15) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_Z 0xFFFC7FFF
+#define S_SQ_VTX_WORD1_DST_SEL_W(x) (((x) & 0x7) << 18)
+#define G_SQ_VTX_WORD1_DST_SEL_W(x) (((x) >> 18) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_W 0xFFE3FFFF
+#define S_SQ_VTX_WORD1_USE_CONST_FIELDS(x) (((x) & 0x1) << 21)
+#define G_SQ_VTX_WORD1_USE_CONST_FIELDS(x) (((x) >> 21) & 0x1)
+#define C_SQ_VTX_WORD1_USE_CONST_FIELDS 0xFFDFFFFF
+#define S_SQ_VTX_WORD1_DATA_FORMAT(x) (((x) & 0x3F) << 22)
+#define G_SQ_VTX_WORD1_DATA_FORMAT(x) (((x) >> 22) & 0x3F)
+#define C_SQ_VTX_WORD1_DATA_FORMAT 0xF03FFFFF
+#define S_SQ_VTX_WORD1_NUM_FORMAT_ALL(x) (((x) & 0x3) << 28)
+#define G_SQ_VTX_WORD1_NUM_FORMAT_ALL(x) (((x) >> 28) & 0x3)
+#define C_SQ_VTX_WORD1_NUM_FORMAT_ALL 0xCFFFFFFF
+#define S_SQ_VTX_WORD1_FORMAT_COMP_ALL(x) (((x) & 0x1) << 30)
+#define G_SQ_VTX_WORD1_FORMAT_COMP_ALL(x) (((x) >> 30) & 0x1)
+#define C_SQ_VTX_WORD1_FORMAT_COMP_ALL 0xBFFFFFFF
+#define S_SQ_VTX_WORD1_SRF_MODE_ALL(x) (((x) & 0x1) << 31)
+#define G_SQ_VTX_WORD1_SRF_MODE_ALL(x) (((x) >> 31) & 0x1)
+#define C_SQ_VTX_WORD1_SRF_MODE_ALL 0x7FFFFFFF
+#define P_SQ_VTX_WORD1_GPR
+#define S_SQ_VTX_WORD1_GPR_DST_GPR(x) (((x) & 0x7F) << 0)
+#define G_SQ_VTX_WORD1_GPR_DST_GPR(x) (((x) >> 0) & 0x7F)
+#define C_SQ_VTX_WORD1_GPR_DST_GPR 0xFFFFFF80
+#define S_SQ_VTX_WORD1_GPR_DST_REL(x) (((x) & 0x1) << 7)
+#define G_SQ_VTX_WORD1_GPR_DST_REL(x) (((x) >> 7) & 0x1)
+#define C_SQ_VTX_WORD1_GPR_DST_REL 0xFFFFFF7F
+#define P_SQ_VTX_WORD1_SEM
+#define S_SQ_VTX_WORD1_SEM_SEMANTIC_ID(x) (((x) & 0xFF) << 0)
+#define G_SQ_VTX_WORD1_SEM_SEMANTIC_ID(x) (((x) >> 0) & 0xFF)
+#define C_SQ_VTX_WORD1_SEM_SEMANTIC_ID 0xFFFFFF00
+#define P_SQ_VTX_WORD2
+#define S_SQ_VTX_WORD2_OFFSET(x) (((x) & 0xFFFF) << 0)
+#define G_SQ_VTX_WORD2_OFFSET(x) (((x) >> 0) & 0xFFFF)
+#define C_SQ_VTX_WORD2_OFFSET 0xFFFF0000
+#define S_SQ_VTX_WORD2_ENDIAN_SWAP(x) (((x) & 0x3) << 16)
+#define G_SQ_VTX_WORD2_ENDIAN_SWAP(x) (((x) >> 16) & 0x3)
+#define C_SQ_VTX_WORD2_ENDIAN_SWAP 0xFFFCFFFF
+#define S_SQ_VTX_WORD2_CONST_BUF_NO_STRIDE(x) (((x) & 0x1) << 18)
+#define G_SQ_VTX_WORD2_CONST_BUF_NO_STRIDE(x) (((x) >> 18) & 0x1)
+#define C_SQ_VTX_WORD2_CONST_BUF_NO_STRIDE 0xFFFBFFFF
+#define S_SQ_VTX_WORD2_MEGA_FETCH(x) (((x) & 0x1) << 19)
+#define G_SQ_VTX_WORD2_MEGA_FETCH(x) (((x) >> 19) & 0x1)
+#define C_SQ_VTX_WORD2_MEGA_FETCH 0xFFF7FFFF
+#define S_SQ_VTX_WORD2_ALT_CONST(x) (((x) & 0x1) << 20)
+#define G_SQ_VTX_WORD2_ALT_CONST(x) (((x) >> 20) & 0x1)
+#define C_SQ_VTX_WORD2_ALT_CONST 0xFFEFFFFF
+#define P_SQ_TEX_WORD0
+#define S_SQ_TEX_WORD0_TEX_INST(x) (((x) & 0x1F) << 0)
+#define G_SQ_TEX_WORD0_TEX_INST(x) (((x) >> 0) & 0x1F)
+#define C_SQ_TEX_WORD0_TEX_INST 0xFFFFFFE0
+#define S_SQ_TEX_WORD0_BC_FRAC_MODE(x) (((x) & 0x1) << 5)
+#define G_SQ_TEX_WORD0_BC_FRAC_MODE(x) (((x) >> 5) & 0x1)
+#define C_SQ_TEX_WORD0_BC_FRAC_MODE 0xFFFFFFDF
+#define S_SQ_TEX_WORD0_FETCH_WHOLE_QUAD(x) (((x) & 0x1) << 7)
+#define G_SQ_TEX_WORD0_FETCH_WHOLE_QUAD(x) (((x) >> 7) & 0x1)
+#define C_SQ_TEX_WORD0_FETCH_WHOLE_QUAD 0xFFFFFF7F
+#define S_SQ_TEX_WORD0_RESOURCE_ID(x) (((x) & 0xFF) << 8)
+#define G_SQ_TEX_WORD0_RESOURCE_ID(x) (((x) >> 8) & 0xFF)
+#define C_SQ_TEX_WORD0_RESOURCE_ID 0xFFFF00FF
+#define S_SQ_TEX_WORD0_SRC_GPR(x) (((x) & 0x7F) << 16)
+#define G_SQ_TEX_WORD0_SRC_GPR(x) (((x) >> 16) & 0x7F)
+#define C_SQ_TEX_WORD0_SRC_GPR 0xFF80FFFF
+#define S_SQ_TEX_WORD0_SRC_REL(x) (((x) & 0x1) << 23)
+#define G_SQ_TEX_WORD0_SRC_REL(x) (((x) >> 23) & 0x1)
+#define C_SQ_TEX_WORD0_SRC_REL 0xFF7FFFFF
+#define S_SQ_TEX_WORD0_ALT_CONST(x) (((x) & 0x1) << 24)
+#define G_SQ_TEX_WORD0_ALT_CONST(x) (((x) >> 24) & 0x1)
+#define C_SQ_TEX_WORD0_ALT_CONST 0xFEFFFFFF
+#define P_SQ_TEX_WORD1
+#define S_SQ_TEX_WORD1_DST_GPR(x) (((x) & 0x7F) << 0)
+#define G_SQ_TEX_WORD1_DST_GPR(x) (((x) >> 0) & 0x7F)
+#define C_SQ_TEX_WORD1_DST_GPR 0xFFFFFF80
+#define S_SQ_TEX_WORD1_DST_REL(x) (((x) & 0x1) << 7)
+#define G_SQ_TEX_WORD1_DST_REL(x) (((x) >> 7) & 0x1)
+#define C_SQ_TEX_WORD1_DST_REL 0xFFFFFF7F
+#define S_SQ_TEX_WORD1_DST_SEL_X(x) (((x) & 0x7) << 9)
+#define G_SQ_TEX_WORD1_DST_SEL_X(x) (((x) >> 9) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_X 0xFFFFF1FF
+#define S_SQ_TEX_WORD1_DST_SEL_Y(x) (((x) & 0x7) << 12)
+#define G_SQ_TEX_WORD1_DST_SEL_Y(x) (((x) >> 12) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_Y 0xFFFF8FFF
+#define S_SQ_TEX_WORD1_DST_SEL_Z(x) (((x) & 0x7) << 15)
+#define G_SQ_TEX_WORD1_DST_SEL_Z(x) (((x) >> 15) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_Z 0xFFFC7FFF
+#define S_SQ_TEX_WORD1_DST_SEL_W(x) (((x) & 0x7) << 18)
+#define G_SQ_TEX_WORD1_DST_SEL_W(x) (((x) >> 18) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_W 0xFFE3FFFF
+#define S_SQ_TEX_WORD1_LOD_BIAS(x) (((x) & 0x7F) << 21)
+#define G_SQ_TEX_WORD1_LOD_BIAS(x) (((x) >> 21) & 0x7F)
+#define C_SQ_TEX_WORD1_LOD_BIAS 0xF01FFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) & 0x1) << 28)
+#define G_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) >> 28) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_X 0xEFFFFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) & 0x1) << 29)
+#define G_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) >> 29) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_Y 0xDFFFFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_Z(x) (((x) & 0x1) << 30)
+#define G_SQ_TEX_WORD1_COORD_TYPE_Z(x) (((x) >> 30) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_Z 0xBFFFFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_W(x) (((x) & 0x1) << 31)
+#define G_SQ_TEX_WORD1_COORD_TYPE_W(x) (((x) >> 31) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_W 0x7FFFFFFF
+#define P_SQ_TEX_WORD2
+#define S_SQ_TEX_WORD2_OFFSET_X(x) (((x) & 0x1F) << 0)
+#define G_SQ_TEX_WORD2_OFFSET_X(x) (((x) >> 0) & 0x1F)
+#define C_SQ_TEX_WORD2_OFFSET_X 0xFFFFFFE0
+#define S_SQ_TEX_WORD2_OFFSET_Y(x) (((x) & 0x1F) << 5)
+#define G_SQ_TEX_WORD2_OFFSET_Y(x) (((x) >> 5) & 0x1F)
+#define C_SQ_TEX_WORD2_OFFSET_Y 0xFFFFFC1F
+#define S_SQ_TEX_WORD2_OFFSET_Z(x) (((x) & 0x1F) << 10)
+#define G_SQ_TEX_WORD2_OFFSET_Z(x) (((x) >> 10) & 0x1F)
+#define C_SQ_TEX_WORD2_OFFSET_Z 0xFFFF83FF
+#define S_SQ_TEX_WORD2_SAMPLER_ID(x) (((x) & 0x1F) << 15)
+#define G_SQ_TEX_WORD2_SAMPLER_ID(x) (((x) >> 15) & 0x1F)
+#define C_SQ_TEX_WORD2_SAMPLER_ID 0xFFF07FFF
+#define S_SQ_TEX_WORD2_SRC_SEL_X(x) (((x) & 0x7) << 20)
+#define G_SQ_TEX_WORD2_SRC_SEL_X(x) (((x) >> 20) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_X 0xFF8FFFFF
+#define S_SQ_TEX_WORD2_SRC_SEL_Y(x) (((x) & 0x7) << 23)
+#define G_SQ_TEX_WORD2_SRC_SEL_Y(x) (((x) >> 23) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_Y 0xFC7FFFFF
+#define S_SQ_TEX_WORD2_SRC_SEL_Z(x) (((x) & 0x7) << 26)
+#define G_SQ_TEX_WORD2_SRC_SEL_Z(x) (((x) >> 26) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_Z 0xE3FFFFFF
+#define S_SQ_TEX_WORD2_SRC_SEL_W(x) (((x) & 0x7) << 29)
+#define G_SQ_TEX_WORD2_SRC_SEL_W(x) (((x) >> 29) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_W 0x1FFFFFFF
+#define P_SQ_ALU_WORD1_OP2_V2
+#define S_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x) (((x) & 0x1) << 0)
+#define G_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x) (((x) >> 0) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_SRC0_ABS 0xFFFFFFFE
+#define S_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x) (((x) & 0x1) << 1)
+#define G_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x) (((x) >> 1) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_SRC1_ABS 0xFFFFFFFD
+#define S_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x) (((x) & 0x1) << 2)
+#define G_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x) (((x) >> 2) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK 0xFFFFFFFB
+#define S_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x) (((x) & 0x1) << 3)
+#define G_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x) (((x) >> 3) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED 0xFFFFFFF7
+#define S_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x) (((x) & 0x1) << 4)
+#define G_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x) (((x) >> 4) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_WRITE_MASK 0xFFFFFFEF
+#define S_SQ_ALU_WORD1_OP2_V2_OMOD(x) (((x) & 0x3) << 5)
+#define G_SQ_ALU_WORD1_OP2_V2_OMOD(x) (((x) >> 5) & 0x3)
+#define C_SQ_ALU_WORD1_OP2_V2_OMOD 0xFFFFFF9F
+#define S_SQ_ALU_WORD1_OP2_V2_ALU_INST(x) (((x) & 0x7FF) << 7)
+#define G_SQ_ALU_WORD1_OP2_V2_ALU_INST(x) (((x) >> 7) & 0x7FF)
+#define C_SQ_ALU_WORD1_OP2_V2_ALU_INST 0xFFFC007F
+
+#endif
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
new file mode 100644
index 0000000000..ff574b8285
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -0,0 +1,484 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include <util/u_memory.h>
+#include "r600_screen.h"
+#include "r600_texture.h"
+#include "r600_context.h"
+#include "r600d.h"
+
+
+static void r600_delete_state(struct pipe_context *ctx, void *state)
+{
+ struct radeon_state *rstate = state;
+
+ radeon_state_decref(rstate);
+}
+
+static void *r600_create_blend_state(struct pipe_context *ctx,
+ const struct pipe_blend_state *state)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct radeon_state *rstate;
+
+ rstate = radeon_state(rscreen->rw, R600_BLEND_TYPE, R600_BLEND);
+ if (rstate == NULL)
+ return NULL;
+ rstate->states[R600_BLEND__CB_BLEND_RED] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND_GREEN] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND_BLUE] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND_ALPHA] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND0_CONTROL] = 0x00010001;
+ rstate->states[R600_BLEND__CB_BLEND1_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND2_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND3_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND4_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND5_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND6_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND7_CONTROL] = 0x00000000;
+ rstate->states[R600_BLEND__CB_BLEND_CONTROL] = 0x00000000;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
+}
+
+static void r600_bind_blend_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ radeon_draw_set(rctx->draw, state);
+}
+
+static void r600_set_blend_color(struct pipe_context *ctx,
+ const struct pipe_blend_color *color)
+{
+}
+
+static void r600_set_clip_state(struct pipe_context *ctx,
+ const struct pipe_clip_state *state)
+{
+}
+
+static void r600_set_framebuffer_state(struct pipe_context *ctx,
+ const struct pipe_framebuffer_state *state)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct r600_texture *rtex;
+ struct r600_buffer *rbuffer;
+ struct radeon_state *rstate;
+ unsigned level = state->cbufs[0]->level;
+ unsigned pitch, slice;
+
+ rstate = radeon_state(rscreen->rw, R600_CB0_TYPE, R600_CB0);
+ if (rstate == NULL)
+ return;
+ rtex = (struct r600_texture*)state->cbufs[0]->texture;
+ rbuffer = (struct r600_buffer*)rtex->buffer;
+ rstate->bo[0] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ rstate->bo[1] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ rstate->bo[2] = radeon_bo_incref(rscreen->rw, rbuffer->bo);
+ rstate->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ rstate->placement[2] = RADEON_GEM_DOMAIN_GTT;
+ rstate->placement[4] = RADEON_GEM_DOMAIN_GTT;
+ rstate->nbo = 3;
+ pitch = rtex->pitch[level] / 8 - 1;
+ slice = rtex->pitch[level] * state->cbufs[0]->height / 64 - 1;
+ rstate->states[R600_CB0__CB_COLOR0_BASE] = 0x00000000;
+ rstate->states[R600_CB0__CB_COLOR0_INFO] = 0x08110068;
+ rstate->states[R600_CB0__CB_COLOR0_SIZE] = S_028060_PITCH_TILE_MAX(pitch) |
+ S_028060_SLICE_TILE_MAX(slice);
+ rstate->states[R600_CB0__CB_COLOR0_VIEW] = 0x00000000;
+ rstate->states[R600_CB0__CB_COLOR0_FRAG] = 0x00000000;
+ rstate->states[R600_CB0__CB_COLOR0_TILE] = 0x00000000;
+ rstate->states[R600_CB0__CB_COLOR0_MASK] = 0x00000000;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return;
+ }
+ radeon_draw_set_new(rctx->draw, rstate);
+ rctx->db = radeon_state_decref(rctx->db);
+ rctx->db = radeon_state(rscreen->rw, R600_DB_TYPE, R600_DB);
+ rctx->db->bo[0] = radeon_bo_incref(rscreen->rw, rstate->bo[0]);
+ rctx->db->nbo = 1;
+ rctx->db->placement[0] = RADEON_GEM_DOMAIN_GTT;
+ rctx->fb_state = *state;
+}
+
+static void *r600_create_fs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *shader)
+{
+ return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_FS, shader->tokens);
+}
+
+static void r600_bind_fs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+
+ rctx->ps_shader = state;
+}
+
+static void *r600_create_vs_state(struct pipe_context *ctx,
+ const struct pipe_shader_state *shader)
+{
+ return r600_pipe_shader_create(ctx, C_PROGRAM_TYPE_VS, shader->tokens);
+}
+
+static void r600_bind_vs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+
+ rctx->vs_shader = state;
+}
+
+static void r600_set_polygon_stipple(struct pipe_context *ctx,
+ const struct pipe_poly_stipple *state)
+{
+}
+
+static void *r600_create_rs_state(struct pipe_context *ctx,
+ const struct pipe_rasterizer_state *state)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct radeon_state *rstate;
+
+ rctx->flat_shade = state->flatshade;
+ rstate = radeon_state(rscreen->rw, R600_RASTERIZER_TYPE, R600_RASTERIZER);
+ if (rstate == NULL)
+ return NULL;
+ rstate->states[R600_RASTERIZER__SPI_INTERP_CONTROL_0] = 0x00000001;
+ rstate->states[R600_RASTERIZER__PA_CL_CLIP_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_SC_MODE_CNTL] = 0x00080000;
+ rstate->states[R600_RASTERIZER__PA_CL_VS_OUT_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_CL_NANINF_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POINT_SIZE] = 0x00080008;
+ rstate->states[R600_RASTERIZER__PA_SU_POINT_MINMAX] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_LINE_CNTL] = 0x00000008;
+ rstate->states[R600_RASTERIZER__PA_SC_LINE_STIPPLE] = 0x00000005;
+ rstate->states[R600_RASTERIZER__PA_SC_MPASS_PS_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SC_LINE_CNTL] = 0x00000400;
+ rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_CLIP_ADJ] = 0x3F800000;
+ rstate->states[R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ] = 0x3F800000;
+ rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ] = 0x3F800000;
+ rstate->states[R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ] = 0x3F800000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_CLAMP] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE] = 0x00000000;
+ rstate->states[R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET] = 0x00000000;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
+}
+
+static void r600_bind_rs_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ radeon_draw_set(rctx->draw, state);
+}
+
+static void *r600_create_sampler_state(struct pipe_context *ctx,
+ const struct pipe_sampler_state *state)
+{
+ return NULL;
+}
+
+static void r600_bind_sampler_states(struct pipe_context *ctx,
+ unsigned count, void **states)
+{
+}
+
+static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *ctx,
+ struct pipe_resource *texture,
+ const struct pipe_sampler_view *templ)
+{
+ struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view);
+
+ *view = *templ;
+ return view;
+}
+
+static void r600_sampler_view_destroy(struct pipe_context *ctx,
+ struct pipe_sampler_view *view)
+{
+ FREE(view);
+}
+
+static void r600_set_fragment_sampler_views(struct pipe_context *ctx,
+ unsigned count,
+ struct pipe_sampler_view **views)
+{
+}
+
+static void r600_set_vertex_sampler_views(struct pipe_context *ctx,
+ unsigned count,
+ struct pipe_sampler_view **views)
+{
+}
+
+static void r600_set_scissor_state(struct pipe_context *ctx,
+ const struct pipe_scissor_state *state)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct radeon_state *rstate;
+ u32 tl, br;
+
+ tl = S_028240_TL_X(state->minx) | S_028240_TL_Y(state->miny) | S_028240_WINDOW_OFFSET_DISABLE(1);
+ br = S_028244_BR_X(state->maxx) | S_028244_BR_Y(state->maxy);
+ rstate = radeon_state(rscreen->rw, R600_SCISSOR_TYPE, R600_SCISSOR);
+ if (rstate == NULL)
+ return;
+ rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_WINDOW_OFFSET] = 0x00000000;
+ rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_RULE] = 0x0000FFFF;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_0_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_1_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_2_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_CLIPRECT_3_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_EDGERULE] = 0xAAAAAAAA;
+ rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR] = br;
+ rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL] = tl;
+ rstate->states[R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR] = br;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return;
+ }
+ radeon_draw_set_new(rctx->draw, rstate);
+}
+
+static void r600_set_viewport_state(struct pipe_context *ctx,
+ const struct pipe_viewport_state *state)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct radeon_state *rstate;
+
+ rstate = radeon_state(rscreen->rw, R600_VIEWPORT_TYPE, R600_VIEWPORT);
+ if (rstate == NULL)
+ return;
+ rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMIN_0] = 0x00000000;
+ rstate->states[R600_VIEWPORT__PA_SC_VPORT_ZMAX_0] = 0x3F800000;
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_XSCALE_0] = r600_float_to_u32(state->scale[0]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_YSCALE_0] = r600_float_to_u32(state->scale[1]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0] = r600_float_to_u32(state->scale[2]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0] = r600_float_to_u32(state->translate[0]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0] = r600_float_to_u32(state->translate[1]);
+ rstate->states[R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0] = r600_float_to_u32(state->translate[2]);
+ rstate->states[R600_VIEWPORT__PA_CL_VTE_CNTL] = 0x0000043F;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return;
+ }
+ radeon_draw_set_new(rctx->draw, rstate);
+ rctx->viewport = *state;
+}
+
+static void r600_set_vertex_buffers(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+
+ memcpy(rctx->vertex_buffer, buffers, sizeof(struct pipe_vertex_buffer) * count);
+ rctx->nvertex_buffer = count;
+}
+
+
+static void *r600_create_vertex_elements_state(struct pipe_context *ctx,
+ unsigned count,
+ const struct pipe_vertex_element *elements)
+{
+ struct r600_vertex_elements_state *v = CALLOC_STRUCT(r600_vertex_elements_state);
+
+ assert(count < 32);
+ v->count = count;
+ memcpy(v->elements, elements, count * sizeof(struct pipe_vertex_element));
+ return v;
+}
+
+static void r600_bind_vertex_elements_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ struct r600_vertex_elements_state *v = (struct r600_vertex_elements_state*)state;
+
+ rctx->vertex_elements = v;
+}
+
+static void r600_delete_vertex_elements_state(struct pipe_context *ctx, void *state)
+{
+ FREE(state);
+}
+
+static void *r600_create_dsa_state(struct pipe_context *ctx,
+ const struct pipe_depth_stencil_alpha_state *state)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct radeon_state *rstate;
+
+ rstate = radeon_state(rscreen->rw, R600_DSA_TYPE, R600_DSA);
+ if (rstate == NULL)
+ return NULL;
+ rstate->states[R600_DSA__DB_STENCIL_CLEAR] = 0x00000000;
+ rstate->states[R600_DSA__DB_DEPTH_CLEAR] = 0x3F800000;
+ rstate->states[R600_DSA__SX_ALPHA_TEST_CONTROL] = 0x00000000;
+ rstate->states[R600_DSA__DB_STENCILREFMASK] = 0xFFFFFF00;
+ rstate->states[R600_DSA__DB_STENCILREFMASK_BF] = 0xFFFFFF00;
+ rstate->states[R600_DSA__SX_ALPHA_REF] = 0x00000000;
+ rstate->states[R600_DSA__SPI_FOG_FUNC_SCALE] = 0x00000000;
+ rstate->states[R600_DSA__SPI_FOG_FUNC_BIAS] = 0x00000000;
+ rstate->states[R600_DSA__SPI_FOG_CNTL] = 0x00000000;
+ rstate->states[R600_DSA__DB_DEPTH_CONTROL] = 0x00700700;
+ rstate->states[R600_DSA__DB_SHADER_CONTROL] = 0x00000210;
+ rstate->states[R600_DSA__DB_RENDER_CONTROL] = 0x00000060;
+ rstate->states[R600_DSA__DB_RENDER_OVERRIDE] = 0x0000002A;
+ rstate->states[R600_DSA__DB_SRESULTS_COMPARE_STATE1] = 0x00000000;
+ rstate->states[R600_DSA__DB_PRELOAD_CONTROL] = 0x00000000;
+ rstate->states[R600_DSA__DB_ALPHA_TO_MASK] = 0x0000AA00;
+ if (radeon_state_pm4(rstate)) {
+ radeon_state_decref(rstate);
+ return NULL;
+ }
+ return rstate;
+}
+
+static void r600_bind_dsa_state(struct pipe_context *ctx, void *state)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ radeon_draw_set(rctx->draw, state);
+}
+
+static void r600_set_constant_buffer(struct pipe_context *ctx,
+ uint shader, uint index,
+ struct pipe_resource *buffer)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)ctx->screen;
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ unsigned nconstant = 0, i, type, id;
+ struct radeon_state *rstate;
+ struct pipe_transfer *transfer;
+ u32 *ptr;
+
+ switch (shader) {
+ case PIPE_SHADER_VERTEX:
+ id = R600_VS_CONSTANT;
+ type = R600_VS_CONSTANT_TYPE;
+ break;
+ case PIPE_SHADER_FRAGMENT:
+ id = R600_PS_CONSTANT;
+ type = R600_PS_CONSTANT_TYPE;
+ break;
+ default:
+ fprintf(stderr, "%s:%d unsupported %d\n", __func__, __LINE__, shader);
+ return;
+ }
+ if (buffer && buffer->width0 > 0) {
+ nconstant = buffer->width0 / 16;
+ ptr = pipe_buffer_map(ctx, buffer, PIPE_TRANSFER_READ, &transfer);
+ if (ptr == NULL)
+ return;
+ for (i = 0; i < nconstant; i++) {
+ rstate = radeon_state(rscreen->rw, type, id + i);
+ if (rstate == NULL)
+ return;
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0] = ptr[i * 4 + 0];
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0] = ptr[i * 4 + 1];
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0] = ptr[i * 4 + 2];
+ rstate->states[R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0] = ptr[i * 4 + 3];
+ if (radeon_state_pm4(rstate))
+ return;
+ if (radeon_draw_set_new(rctx->draw, rstate))
+ return;
+ }
+ pipe_buffer_unmap(ctx, buffer, transfer);
+ }
+}
+
+static void r600_set_stencil_ref(struct pipe_context *ctx,
+ const struct pipe_stencil_ref *sr)
+{
+ struct r600_context *rctx = (struct r600_context*)ctx;
+ rctx->stencil_ref = *sr;
+}
+
+static void r600_set_sample_mask(struct pipe_context *pipe, unsigned sample_mask)
+{
+}
+
+void r600_init_state_functions(struct r600_context *rctx)
+{
+ rctx->context.set_sample_mask = r600_set_sample_mask;
+ rctx->context.create_blend_state = r600_create_blend_state;
+ rctx->context.bind_blend_state = r600_bind_blend_state;
+ rctx->context.delete_blend_state = r600_delete_state;
+ rctx->context.set_blend_color = r600_set_blend_color;
+ rctx->context.set_clip_state = r600_set_clip_state;
+ rctx->context.set_constant_buffer = r600_set_constant_buffer;
+ rctx->context.create_depth_stencil_alpha_state = r600_create_dsa_state;
+ rctx->context.bind_depth_stencil_alpha_state = r600_bind_dsa_state;
+ rctx->context.delete_depth_stencil_alpha_state = r600_delete_state;
+ rctx->context.set_framebuffer_state = r600_set_framebuffer_state;
+ rctx->context.create_fs_state = r600_create_fs_state;
+ rctx->context.bind_fs_state = r600_bind_fs_state;
+ rctx->context.delete_fs_state = r600_delete_state;
+ rctx->context.set_polygon_stipple = r600_set_polygon_stipple;
+ rctx->context.create_rasterizer_state = r600_create_rs_state;
+ rctx->context.bind_rasterizer_state = r600_bind_rs_state;
+ rctx->context.delete_rasterizer_state = r600_delete_state;
+ rctx->context.create_sampler_state = r600_create_sampler_state;
+ rctx->context.bind_fragment_sampler_states = r600_bind_sampler_states;
+ rctx->context.bind_vertex_sampler_states = r600_bind_sampler_states;
+ rctx->context.delete_sampler_state = r600_delete_state;
+ rctx->context.create_sampler_view = r600_create_sampler_view;
+ rctx->context.sampler_view_destroy = r600_sampler_view_destroy;
+ rctx->context.set_fragment_sampler_views = r600_set_fragment_sampler_views;
+ rctx->context.set_vertex_sampler_views = r600_set_vertex_sampler_views;
+ rctx->context.set_scissor_state = r600_set_scissor_state;
+ rctx->context.set_viewport_state = r600_set_viewport_state;
+ rctx->context.set_vertex_buffers = r600_set_vertex_buffers;
+ rctx->context.create_vertex_elements_state = r600_create_vertex_elements_state;
+ rctx->context.bind_vertex_elements_state = r600_bind_vertex_elements_state;
+ rctx->context.delete_vertex_elements_state = r600_delete_vertex_elements_state;
+ rctx->context.create_vs_state = r600_create_vs_state;
+ rctx->context.bind_vs_state = r600_bind_vs_state;
+ rctx->context.delete_vs_state = r600_delete_state;
+ rctx->context.set_stencil_ref = r600_set_stencil_ref;
+}
diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c
new file mode 100644
index 0000000000..7d94bbe510
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson
+ */
+#include <pipe/p_screen.h>
+#include <util/u_format.h>
+#include <util/u_math.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include "state_tracker/drm_api.h"
+#include "r600_screen.h"
+#include "r600_texture.h"
+
+extern struct u_resource_vtbl r600_texture_vtbl;
+
+unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face)
+{
+ unsigned long offset = rtex->offset[level];
+
+ switch (rtex->b.b.target) {
+ case PIPE_TEXTURE_3D:
+ assert(face == 0);
+ return offset + zslice * rtex->layer_size[level];
+ case PIPE_TEXTURE_CUBE:
+ assert(zslice == 0);
+ return offset + face * rtex->layer_size[level];
+ default:
+ assert(zslice == 0 && face == 0);
+ return offset;
+ }
+}
+
+static void r600_setup_miptree(struct r600_screen *rscreen, struct r600_texture *rtex)
+{
+ struct pipe_resource *ptex = &rtex->b.b;
+ unsigned long w, h, stride, size, layer_size, i, offset;
+
+ for (i = 0, offset = 0; i <= ptex->last_level; i++) {
+ w = u_minify(ptex->width0, i);
+ h = u_minify(ptex->height0, i);
+ stride = align(util_format_get_stride(ptex->format, w), 32);
+ layer_size = stride * h;
+ if (ptex->target == PIPE_TEXTURE_CUBE)
+ size = layer_size * 6;
+ else
+ size = layer_size * u_minify(ptex->depth0, i);
+ rtex->offset[i] = offset;
+ rtex->layer_size[i] = layer_size;
+ rtex->pitch[i] = stride / util_format_get_blocksize(ptex->format);
+ rtex->stride[i] = stride;
+ offset += align(size, 32);
+ }
+ rtex->size = offset;
+}
+
+struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
+{
+ struct r600_texture *rtex = CALLOC_STRUCT(r600_texture);
+ struct r600_screen *rscreen = r600_screen(screen);
+ struct pipe_resource templ_buf;
+
+ if (!rtex) {
+ return NULL;
+ }
+ rtex->b.b = *templ;
+ rtex->b.vtbl = &r600_texture_vtbl;
+ pipe_reference_init(&rtex->b.b.reference, 1);
+ rtex->b.b.screen = screen;
+ r600_setup_miptree(rscreen, rtex);
+
+ memset(&templ_buf, 0, sizeof(struct pipe_resource));
+ templ_buf.target = PIPE_BUFFER;
+ templ_buf.format = PIPE_FORMAT_R8_UNORM;
+ templ_buf.usage = templ->usage;
+ templ_buf.bind = templ->bind;
+ templ_buf.width0 = rtex->size;
+ templ_buf.height0 = 1;
+ templ_buf.depth0 = 1;
+
+ rtex->buffer = screen->resource_create(screen, &templ_buf);
+ if (!rtex->buffer) {
+ FREE(rtex);
+ return NULL;
+ }
+ return &rtex->b.b;
+}
+
+static void r600_texture_destroy(struct pipe_screen *screen,
+ struct pipe_resource *ptex)
+{
+ struct r600_texture *rtex = (struct r600_texture*)ptex;
+
+ FREE(rtex);
+}
+
+static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen,
+ struct pipe_resource *texture,
+ unsigned face, unsigned level,
+ unsigned zslice, unsigned flags)
+{
+ struct r600_texture *rtex = (struct r600_texture*)texture;
+ struct pipe_surface *surface = CALLOC_STRUCT(pipe_surface);
+ unsigned long offset;
+
+ if (surface == NULL)
+ return NULL;
+ offset = r600_texture_get_offset(rtex, level, zslice, face);
+ pipe_reference_init(&surface->reference, 1);
+ pipe_resource_reference(&surface->texture, texture);
+ surface->format = texture->format;
+ surface->width = u_minify(texture->width0, level);
+ surface->height = u_minify(texture->height0, level);
+ surface->offset = offset;
+ surface->usage = flags;
+ surface->zslice = zslice;
+ surface->texture = texture;
+ surface->face = face;
+ surface->level = level;
+ return surface;
+}
+
+static void r600_tex_surface_destroy(struct pipe_surface *surface)
+{
+ pipe_resource_reference(&surface->texture, NULL);
+ FREE(surface);
+}
+
+struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *base,
+ struct winsys_handle *whandle)
+{
+ struct pipe_resource *buffer;
+ struct r600_texture *rtex;
+
+ buffer = r600_buffer_from_handle(screen, whandle);
+ if (buffer == NULL) {
+ return NULL;
+ }
+
+ /* Support only 2D textures without mipmaps */
+ if (base->target != PIPE_TEXTURE_2D || base->depth0 != 1 || base->last_level != 0)
+ return NULL;
+
+ rtex = CALLOC_STRUCT(r600_texture);
+ if (rtex == NULL)
+ return NULL;
+
+ /* one ref already taken */
+ rtex->buffer = buffer;
+
+ rtex->b.b = *base;
+ rtex->b.vtbl = &r600_texture_vtbl;
+ pipe_reference_init(&rtex->b.b.reference, 1);
+ rtex->b.b.screen = screen;
+ rtex->stride_override = whandle->stride;
+ rtex->pitch[0] = whandle->stride / util_format_get_blocksize(base->format);
+ rtex->stride[0] = whandle->stride;
+ rtex->offset[0] = 0;
+ rtex->size = align(rtex->stride[0] * base->height0, 32);
+
+ return &rtex->b.b;
+}
+
+static boolean r600_texture_get_handle(struct pipe_screen* screen,
+ struct pipe_resource *texture,
+ struct winsys_handle *whandle)
+{
+ struct r600_screen *rscreen = r600_screen(screen);
+ struct r600_texture* rtex = (struct r600_texture*)texture;
+
+ if (!rtex) {
+ return FALSE;
+ }
+
+ whandle->stride = rtex->stride[0];
+
+ r600_buffer_get_handle(rscreen->rw, rtex->buffer, whandle);
+
+ return TRUE;
+}
+
+static unsigned int r600_texture_is_referenced(struct pipe_context *context,
+ struct pipe_resource *texture,
+ unsigned face, unsigned level)
+{
+ struct r600_texture *rtex = (struct r600_texture*)texture;
+
+ return r600_buffer_is_referenced_by_cs(context, rtex->buffer, face, level);
+}
+
+struct u_resource_vtbl r600_texture_vtbl =
+{
+ r600_texture_get_handle, /* get_handle */
+ r600_texture_destroy, /* resource_destroy */
+ r600_texture_is_referenced, /* is_resource_referenced */
+ r600_texture_get_transfer, /* get_transfer */
+ r600_texture_transfer_destroy, /* transfer_destroy */
+ r600_texture_transfer_map, /* transfer_map */
+ u_default_transfer_flush_region,/* transfer_flush_region */
+ r600_texture_transfer_unmap, /* transfer_unmap */
+ u_default_transfer_inline_write /* transfer_inline_write */
+};
+
+void r600_init_screen_texture_functions(struct pipe_screen *screen)
+{
+ screen->get_tex_surface = r600_get_tex_surface;
+ screen->tex_surface_destroy = r600_tex_surface_destroy;
+}
diff --git a/src/gallium/drivers/r600/r600_texture.h b/src/gallium/drivers/r600/r600_texture.h
new file mode 100644
index 0000000000..9bc08d6b04
--- /dev/null
+++ b/src/gallium/drivers/r600/r600_texture.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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 R600_TEXTURE_H
+#define R600_TEXTURE_H
+
+#include <pipe/p_state.h>
+
+struct r600_texture {
+ struct u_resource b;
+ unsigned long offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long pitch[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long stride[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long layer_size[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned long stride_override;
+ unsigned long size;
+ struct pipe_resource *buffer;
+};
+
+struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ);
+unsigned long r600_texture_get_offset(struct r600_texture *rtex, unsigned level, unsigned zslice, unsigned face);
+struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
+ const struct pipe_resource *base,
+ struct winsys_handle *whandle);
+void r600_init_screen_texture_functions(struct pipe_screen *screen);
+
+/* This should be implemented by winsys. */
+boolean r600_buffer_get_handle(struct radeon *rw,
+ struct pipe_resource *buf,
+ struct winsys_handle *whandle);
+
+
+#endif
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
new file mode 100644
index 0000000000..d2c7248ff2
--- /dev/null
+++ b/src/gallium/drivers/r600/r600d.h
@@ -0,0 +1,677 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef R600D_H
+#define R600D_H
+
+#define PKT3_NOP 0x10
+#define PKT3_INDIRECT_BUFFER_END 0x17
+#define PKT3_SET_PREDICATION 0x20
+#define PKT3_REG_RMW 0x21
+#define PKT3_COND_EXEC 0x22
+#define PKT3_PRED_EXEC 0x23
+#define PKT3_START_3D_CMDBUF 0x24
+#define PKT3_DRAW_INDEX_2 0x27
+#define PKT3_CONTEXT_CONTROL 0x28
+#define PKT3_DRAW_INDEX_IMMD_BE 0x29
+#define PKT3_INDEX_TYPE 0x2A
+#define PKT3_DRAW_INDEX 0x2B
+#define PKT3_DRAW_INDEX_AUTO 0x2D
+#define PKT3_DRAW_INDEX_IMMD 0x2E
+#define PKT3_NUM_INSTANCES 0x2F
+#define PKT3_STRMOUT_BUFFER_UPDATE 0x34
+#define PKT3_INDIRECT_BUFFER_MP 0x38
+#define PKT3_MEM_SEMAPHORE 0x39
+#define PKT3_MPEG_INDEX 0x3A
+#define PKT3_WAIT_REG_MEM 0x3C
+#define PKT3_MEM_WRITE 0x3D
+#define PKT3_INDIRECT_BUFFER 0x32
+#define PKT3_CP_INTERRUPT 0x40
+#define PKT3_SURFACE_SYNC 0x43
+#define PKT3_ME_INITIALIZE 0x44
+#define PKT3_COND_WRITE 0x45
+#define PKT3_EVENT_WRITE 0x46
+#define PKT3_EVENT_WRITE_EOP 0x47
+#define PKT3_ONE_REG_WRITE 0x57
+#define PKT3_SET_CONFIG_REG 0x68
+#define PKT3_SET_CONTEXT_REG 0x69
+#define PKT3_SET_ALU_CONST 0x6A
+#define PKT3_SET_BOOL_CONST 0x6B
+#define PKT3_SET_LOOP_CONST 0x6C
+#define PKT3_SET_RESOURCE 0x6D
+#define PKT3_SET_SAMPLER 0x6E
+#define PKT3_SET_CTL_CONST 0x6F
+#define PKT3_SURFACE_BASE_UPDATE 0x73
+
+#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
+#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
+#define PKT_TYPE_C 0x3FFFFFFF
+#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
+#define PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
+#define PKT_COUNT_C 0xC000FFFF
+#define PKT0_BASE_INDEX_S(x) (((x) & 0xFFFF) << 0)
+#define PKT0_BASE_INDEX_G(x) (((x) >> 0) & 0xFFFF)
+#define PKT0_BASE_INDEX_C 0xFFFF0000
+#define PKT3_IT_OPCODE_S(x) (((x) & 0xFF) << 8)
+#define PKT3_IT_OPCODE_G(x) (((x) >> 8) & 0xFF)
+#define PKT3_IT_OPCODE_C 0xFFFF00FF
+#define PKT0(index, count) (PKT_TYPE_S(0) | PKT0_BASE_INDEX_S(index) | PKT_COUNT_S(count))
+#define PKT3(op, count) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count))
+
+/* Registers */
+#define R_0280A0_CB_COLOR0_INFO 0x0280A0
+#define S_0280A0_ENDIAN(x) (((x) & 0x3) << 0)
+#define G_0280A0_ENDIAN(x) (((x) >> 0) & 0x3)
+#define C_0280A0_ENDIAN 0xFFFFFFFC
+#define S_0280A0_FORMAT(x) (((x) & 0x3F) << 2)
+#define G_0280A0_FORMAT(x) (((x) >> 2) & 0x3F)
+#define C_0280A0_FORMAT 0xFFFFFF03
+#define V_0280A0_COLOR_INVALID 0x00000000
+#define V_0280A0_COLOR_8 0x00000001
+#define V_0280A0_COLOR_4_4 0x00000002
+#define V_0280A0_COLOR_3_3_2 0x00000003
+#define V_0280A0_COLOR_16 0x00000005
+#define V_0280A0_COLOR_16_FLOAT 0x00000006
+#define V_0280A0_COLOR_8_8 0x00000007
+#define V_0280A0_COLOR_5_6_5 0x00000008
+#define V_0280A0_COLOR_6_5_5 0x00000009
+#define V_0280A0_COLOR_1_5_5_5 0x0000000A
+#define V_0280A0_COLOR_4_4_4_4 0x0000000B
+#define V_0280A0_COLOR_5_5_5_1 0x0000000C
+#define V_0280A0_COLOR_32 0x0000000D
+#define V_0280A0_COLOR_32_FLOAT 0x0000000E
+#define V_0280A0_COLOR_16_16 0x0000000F
+#define V_0280A0_COLOR_16_16_FLOAT 0x00000010
+#define V_0280A0_COLOR_8_24 0x00000011
+#define V_0280A0_COLOR_8_24_FLOAT 0x00000012
+#define V_0280A0_COLOR_24_8 0x00000013
+#define V_0280A0_COLOR_24_8_FLOAT 0x00000014
+#define V_0280A0_COLOR_10_11_11 0x00000015
+#define V_0280A0_COLOR_10_11_11_FLOAT 0x00000016
+#define V_0280A0_COLOR_11_11_10 0x00000017
+#define V_0280A0_COLOR_11_11_10_FLOAT 0x00000018
+#define V_0280A0_COLOR_2_10_10_10 0x00000019
+#define V_0280A0_COLOR_8_8_8_8 0x0000001A
+#define V_0280A0_COLOR_10_10_10_2 0x0000001B
+#define V_0280A0_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_0280A0_COLOR_32_32 0x0000001D
+#define V_0280A0_COLOR_32_32_FLOAT 0x0000001E
+#define V_0280A0_COLOR_16_16_16_16 0x0000001F
+#define V_0280A0_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_0280A0_COLOR_32_32_32_32 0x00000022
+#define V_0280A0_COLOR_32_32_32_32_FLOAT 0x00000023
+#define S_0280A0_ARRAY_MODE(x) (((x) & 0xF) << 8)
+#define G_0280A0_ARRAY_MODE(x) (((x) >> 8) & 0xF)
+#define C_0280A0_ARRAY_MODE 0xFFFFF0FF
+#define V_0280A0_ARRAY_LINEAR_GENERAL 0x00000000
+#define V_0280A0_ARRAY_LINEAR_ALIGNED 0x00000001
+#define V_0280A0_ARRAY_1D_TILED_THIN1 0x00000002
+#define V_0280A0_ARRAY_2D_TILED_THIN1 0x00000004
+#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12)
+#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
+#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF
+#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15)
+#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1)
+#define C_0280A0_READ_SIZE 0xFFFF7FFF
+#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16)
+#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3)
+#define C_0280A0_COMP_SWAP 0xFFFCFFFF
+#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18)
+#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3)
+#define C_0280A0_TILE_MODE 0xFFF3FFFF
+#define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20)
+#define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1)
+#define C_0280A0_BLEND_CLAMP 0xFFEFFFFF
+#define S_0280A0_CLEAR_COLOR(x) (((x) & 0x1) << 21)
+#define G_0280A0_CLEAR_COLOR(x) (((x) >> 21) & 0x1)
+#define C_0280A0_CLEAR_COLOR 0xFFDFFFFF
+#define S_0280A0_BLEND_BYPASS(x) (((x) & 0x1) << 22)
+#define G_0280A0_BLEND_BYPASS(x) (((x) >> 22) & 0x1)
+#define C_0280A0_BLEND_BYPASS 0xFFBFFFFF
+#define S_0280A0_BLEND_FLOAT32(x) (((x) & 0x1) << 23)
+#define G_0280A0_BLEND_FLOAT32(x) (((x) >> 23) & 0x1)
+#define C_0280A0_BLEND_FLOAT32 0xFF7FFFFF
+#define S_0280A0_SIMPLE_FLOAT(x) (((x) & 0x1) << 24)
+#define G_0280A0_SIMPLE_FLOAT(x) (((x) >> 24) & 0x1)
+#define C_0280A0_SIMPLE_FLOAT 0xFEFFFFFF
+#define S_0280A0_ROUND_MODE(x) (((x) & 0x1) << 25)
+#define G_0280A0_ROUND_MODE(x) (((x) >> 25) & 0x1)
+#define C_0280A0_ROUND_MODE 0xFDFFFFFF
+#define S_0280A0_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_0280A0_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_0280A0_TILE_COMPACT 0xFBFFFFFF
+#define S_0280A0_SOURCE_FORMAT(x) (((x) & 0x1) << 27)
+#define G_0280A0_SOURCE_FORMAT(x) (((x) >> 27) & 0x1)
+#define C_0280A0_SOURCE_FORMAT 0xF7FFFFFF
+#define R_028060_CB_COLOR0_SIZE 0x028060
+#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028060_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028060_SLICE_TILE_MAX 0xC00003FF
+#define R_028800_DB_DEPTH_CONTROL 0x028800
+#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028800_STENCIL_ENABLE 0xFFFFFFFE
+#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028800_Z_ENABLE 0xFFFFFFFD
+#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB
+#define S_028800_ZFUNC(x) (((x) & 0x7) << 4)
+#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7)
+#define C_028800_ZFUNC 0xFFFFFF8F
+#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7)
+#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1)
+#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F
+#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8)
+#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7)
+#define C_028800_STENCILFUNC 0xFFFFF8FF
+#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11)
+#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7)
+#define C_028800_STENCILFAIL 0xFFFFC7FF
+#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14)
+#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7)
+#define C_028800_STENCILZPASS 0xFFFE3FFF
+#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17)
+#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7)
+#define C_028800_STENCILZFAIL 0xFFF1FFFF
+#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20)
+#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7)
+#define C_028800_STENCILFUNC_BF 0xFF8FFFFF
+#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23)
+#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7)
+#define C_028800_STENCILFAIL_BF 0xFC7FFFFF
+#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26)
+#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7)
+#define C_028800_STENCILZPASS_BF 0xE3FFFFFF
+#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29)
+#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7)
+#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF
+#define R_028010_DB_DEPTH_INFO 0x028010
+#define S_028010_FORMAT(x) (((x) & 0x7) << 0)
+#define G_028010_FORMAT(x) (((x) >> 0) & 0x7)
+#define C_028010_FORMAT 0xFFFFFFF8
+#define V_028010_DEPTH_INVALID 0x00000000
+#define V_028010_DEPTH_16 0x00000001
+#define V_028010_DEPTH_X8_24 0x00000002
+#define V_028010_DEPTH_8_24 0x00000003
+#define V_028010_DEPTH_X8_24_FLOAT 0x00000004
+#define V_028010_DEPTH_8_24_FLOAT 0x00000005
+#define V_028010_DEPTH_32_FLOAT 0x00000006
+#define V_028010_DEPTH_X24_8_32_FLOAT 0x00000007
+#define S_028010_READ_SIZE(x) (((x) & 0x1) << 3)
+#define G_028010_READ_SIZE(x) (((x) >> 3) & 0x1)
+#define C_028010_READ_SIZE 0xFFFFFFF7
+#define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15)
+#define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF)
+#define C_028010_ARRAY_MODE 0xFFF87FFF
+#define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25)
+#define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1)
+#define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF
+#define S_028010_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_028010_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_028010_TILE_COMPACT 0xFBFFFFFF
+#define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31)
+#define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1)
+#define C_028010_ZRANGE_PRECISION 0x7FFFFFFF
+#define R_028000_DB_DEPTH_SIZE 0x028000
+#define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028000_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028000_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028000_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028000_SLICE_TILE_MAX 0xC00003FF
+#define R_028004_DB_DEPTH_VIEW 0x028004
+#define S_028004_SLICE_START(x) (((x) & 0x7FF) << 0)
+#define G_028004_SLICE_START(x) (((x) >> 0) & 0x7FF)
+#define C_028004_SLICE_START 0xFFFFF800
+#define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13)
+#define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
+#define C_028004_SLICE_MAX 0xFF001FFF
+#define R_028D24_DB_HTILE_SURFACE 0x028D24
+#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0)
+#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
+#define C_028D24_HTILE_WIDTH 0xFFFFFFFE
+#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
+#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
+#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD
+#define S_028D24_LINEAR(x) (((x) & 0x1) << 2)
+#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1)
+#define C_028D24_LINEAR 0xFFFFFFFB
+#define S_028D24_FULL_CACHE(x) (((x) & 0x1) << 3)
+#define G_028D24_FULL_CACHE(x) (((x) >> 3) & 0x1)
+#define C_028D24_FULL_CACHE 0xFFFFFFF7
+#define S_028D24_HTILE_USES_PRELOAD_WIN(x) (((x) & 0x1) << 4)
+#define G_028D24_HTILE_USES_PRELOAD_WIN(x) (((x) >> 4) & 0x1)
+#define C_028D24_HTILE_USES_PRELOAD_WIN 0xFFFFFFEF
+#define S_028D24_PRELOAD(x) (((x) & 0x1) << 5)
+#define G_028D24_PRELOAD(x) (((x) >> 5) & 0x1)
+#define C_028D24_PRELOAD 0xFFFFFFDF
+#define S_028D24_PREFETCH_WIDTH(x) (((x) & 0x3F) << 6)
+#define G_028D24_PREFETCH_WIDTH(x) (((x) >> 6) & 0x3F)
+#define C_028D24_PREFETCH_WIDTH 0xFFFFF03F
+#define S_028D24_PREFETCH_HEIGHT(x) (((x) & 0x3F) << 12)
+#define G_028D24_PREFETCH_HEIGHT(x) (((x) >> 12) & 0x3F)
+#define C_028D24_PREFETCH_HEIGHT 0xFFFC0FFF
+#define R_028D34_DB_PREFETCH_LIMIT 0x028D34
+#define S_028D34_DEPTH_HEIGHT_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028D34_DEPTH_HEIGHT_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028D34_DEPTH_HEIGHT_TILE_MAX 0xFFFFFC00
+#define R_028D10_DB_RENDER_OVERRIDE 0x028D10
+#define S_028D10_FORCE_HIZ_ENABLE(x) (((x) & 0x3) << 0)
+#define G_028D10_FORCE_HIZ_ENABLE(x) (((x) >> 0) & 0x3)
+#define C_028D10_FORCE_HIZ_ENABLE 0xFFFFFFFC
+#define S_028D10_FORCE_HIS_ENABLE0(x) (((x) & 0x3) << 2)
+#define G_028D10_FORCE_HIS_ENABLE0(x) (((x) >> 2) & 0x3)
+#define C_028D10_FORCE_HIS_ENABLE0 0xFFFFFFF3
+#define S_028D10_FORCE_HIS_ENABLE1(x) (((x) & 0x3) << 4)
+#define G_028D10_FORCE_HIS_ENABLE1(x) (((x) >> 4) & 0x3)
+#define C_028D10_FORCE_HIS_ENABLE1 0xFFFFFFCF
+#define S_028D10_FORCE_SHADER_Z_ORDER(x) (((x) & 0x1) << 6)
+#define G_028D10_FORCE_SHADER_Z_ORDER(x) (((x) >> 6) & 0x1)
+#define C_028D10_FORCE_SHADER_Z_ORDER 0xFFFFFFBF
+#define S_028D10_FAST_Z_DISABLE(x) (((x) & 0x1) << 7)
+#define G_028D10_FAST_Z_DISABLE(x) (((x) >> 7) & 0x1)
+#define C_028D10_FAST_Z_DISABLE 0xFFFFFF7F
+#define S_028D10_FAST_STENCIL_DISABLE(x) (((x) & 0x1) << 8)
+#define G_028D10_FAST_STENCIL_DISABLE(x) (((x) >> 8) & 0x1)
+#define C_028D10_FAST_STENCIL_DISABLE 0xFFFFFEFF
+#define S_028D10_NOOP_CULL_DISABLE(x) (((x) & 0x1) << 9)
+#define G_028D10_NOOP_CULL_DISABLE(x) (((x) >> 9) & 0x1)
+#define C_028D10_NOOP_CULL_DISABLE 0xFFFFFDFF
+#define S_028D10_FORCE_COLOR_KILL(x) (((x) & 0x1) << 10)
+#define G_028D10_FORCE_COLOR_KILL(x) (((x) >> 10) & 0x1)
+#define C_028D10_FORCE_COLOR_KILL 0xFFFFFBFF
+#define S_028D10_FORCE_Z_READ(x) (((x) & 0x1) << 11)
+#define G_028D10_FORCE_Z_READ(x) (((x) >> 11) & 0x1)
+#define C_028D10_FORCE_Z_READ 0xFFFFF7FF
+#define S_028D10_FORCE_STENCIL_READ(x) (((x) & 0x1) << 12)
+#define G_028D10_FORCE_STENCIL_READ(x) (((x) >> 12) & 0x1)
+#define C_028D10_FORCE_STENCIL_READ 0xFFFFEFFF
+#define S_028D10_FORCE_FULL_Z_RANGE(x) (((x) & 0x3) << 13)
+#define G_028D10_FORCE_FULL_Z_RANGE(x) (((x) >> 13) & 0x3)
+#define C_028D10_FORCE_FULL_Z_RANGE 0xFFFF9FFF
+#define S_028D10_FORCE_QC_SMASK_CONFLICT(x) (((x) & 0x1) << 15)
+#define G_028D10_FORCE_QC_SMASK_CONFLICT(x) (((x) >> 15) & 0x1)
+#define C_028D10_FORCE_QC_SMASK_CONFLICT 0xFFFF7FFF
+#define S_028D10_DISABLE_VIEWPORT_CLAMP(x) (((x) & 0x1) << 16)
+#define G_028D10_DISABLE_VIEWPORT_CLAMP(x) (((x) >> 16) & 0x1)
+#define C_028D10_DISABLE_VIEWPORT_CLAMP 0xFFFEFFFF
+#define S_028D10_IGNORE_SC_ZRANGE(x) (((x) & 0x1) << 17)
+#define G_028D10_IGNORE_SC_ZRANGE(x) (((x) >> 17) & 0x1)
+#define C_028D10_IGNORE_SC_ZRANGE 0xFFFDFFFF
+#define R_028A40_VGT_GS_MODE 0x028A40
+#define S_028A40_MODE(x) (((x) & 0x3) << 0)
+#define G_028A40_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A40_MODE 0xFFFFFFFC
+#define S_028A40_ES_PASSTHRU(x) (((x) & 0x1) << 2)
+#define G_028A40_ES_PASSTHRU(x) (((x) >> 2) & 0x1)
+#define C_028A40_ES_PASSTHRU 0xFFFFFFFB
+#define S_028A40_CUT_MODE(x) (((x) & 0x3) << 3)
+#define G_028A40_CUT_MODE(x) (((x) >> 3) & 0x3)
+#define C_028A40_CUT_MODE 0xFFFFFFE7
+#define R_008040_WAIT_UNTIL 0x008040
+#define S_008040_WAIT_CP_DMA_IDLE(x) (((x) & 0x1) << 8)
+#define G_008040_WAIT_CP_DMA_IDLE(x) (((x) >> 8) & 0x1)
+#define C_008040_WAIT_CP_DMA_IDLE 0xFFFFFEFF
+#define S_008040_WAIT_CMDFIFO(x) (((x) & 0x1) << 10)
+#define G_008040_WAIT_CMDFIFO(x) (((x) >> 10) & 0x1)
+#define C_008040_WAIT_CMDFIFO 0xFFFFFBFF
+#define S_008040_WAIT_2D_IDLE(x) (((x) & 0x1) << 14)
+#define G_008040_WAIT_2D_IDLE(x) (((x) >> 14) & 0x1)
+#define C_008040_WAIT_2D_IDLE 0xFFFFBFFF
+#define S_008040_WAIT_3D_IDLE(x) (((x) & 0x1) << 15)
+#define G_008040_WAIT_3D_IDLE(x) (((x) >> 15) & 0x1)
+#define C_008040_WAIT_3D_IDLE 0xFFFF7FFF
+#define S_008040_WAIT_2D_IDLECLEAN(x) (((x) & 0x1) << 16)
+#define G_008040_WAIT_2D_IDLECLEAN(x) (((x) >> 16) & 0x1)
+#define C_008040_WAIT_2D_IDLECLEAN 0xFFFEFFFF
+#define S_008040_WAIT_3D_IDLECLEAN(x) (((x) & 0x1) << 17)
+#define G_008040_WAIT_3D_IDLECLEAN(x) (((x) >> 17) & 0x1)
+#define C_008040_WAIT_3D_IDLECLEAN 0xFFFDFFFF
+#define S_008040_WAIT_EXTERN_SIG(x) (((x) & 0x1) << 19)
+#define G_008040_WAIT_EXTERN_SIG(x) (((x) >> 19) & 0x1)
+#define C_008040_WAIT_EXTERN_SIG 0xFFF7FFFF
+#define S_008040_CMDFIFO_ENTRIES(x) (((x) & 0x1F) << 20)
+#define G_008040_CMDFIFO_ENTRIES(x) (((x) >> 20) & 0x1F)
+#define C_008040_CMDFIFO_ENTRIES 0xFE0FFFFF
+#define R_0286CC_SPI_PS_IN_CONTROL_0 0x0286CC
+#define S_0286CC_NUM_INTERP(x) (((x) & 0x3F) << 0)
+#define G_0286CC_NUM_INTERP(x) (((x) >> 0) & 0x3F)
+#define C_0286CC_NUM_INTERP 0xFFFFFFC0
+#define S_0286CC_POSITION_ENA(x) (((x) & 0x1) << 8)
+#define G_0286CC_POSITION_ENA(x) (((x) >> 8) & 0x1)
+#define C_0286CC_POSITION_ENA 0xFFFFFEFF
+#define S_0286CC_POSITION_CENTROID(x) (((x) & 0x1) << 9)
+#define G_0286CC_POSITION_CENTROID(x) (((x) >> 9) & 0x1)
+#define C_0286CC_POSITION_CENTROID 0xFFFFFDFF
+#define S_0286CC_POSITION_ADDR(x) (((x) & 0x1F) << 10)
+#define G_0286CC_POSITION_ADDR(x) (((x) >> 10) & 0x1F)
+#define C_0286CC_POSITION_ADDR 0xFFFF83FF
+#define S_0286CC_PARAM_GEN(x) (((x) & 0xF) << 15)
+#define G_0286CC_PARAM_GEN(x) (((x) >> 15) & 0xF)
+#define C_0286CC_PARAM_GEN 0xFFF87FFF
+#define S_0286CC_PARAM_GEN_ADDR(x) (((x) & 0x7F) << 19)
+#define G_0286CC_PARAM_GEN_ADDR(x) (((x) >> 19) & 0x7F)
+#define C_0286CC_PARAM_GEN_ADDR 0xFC07FFFF
+#define S_0286CC_BARYC_SAMPLE_CNTL(x) (((x) & 0x3) << 26)
+#define G_0286CC_BARYC_SAMPLE_CNTL(x) (((x) >> 26) & 0x3)
+#define C_0286CC_BARYC_SAMPLE_CNTL 0xF3FFFFFF
+#define S_0286CC_PERSP_GRADIENT_ENA(x) (((x) & 0x1) << 28)
+#define G_0286CC_PERSP_GRADIENT_ENA(x) (((x) >> 28) & 0x1)
+#define C_0286CC_PERSP_GRADIENT_ENA 0xEFFFFFFF
+#define S_0286CC_LINEAR_GRADIENT_ENA(x) (((x) & 0x1) << 29)
+#define G_0286CC_LINEAR_GRADIENT_ENA(x) (((x) >> 29) & 0x1)
+#define C_0286CC_LINEAR_GRADIENT_ENA 0xDFFFFFFF
+#define S_0286CC_POSITION_SAMPLE(x) (((x) & 0x1) << 30)
+#define G_0286CC_POSITION_SAMPLE(x) (((x) >> 30) & 0x1)
+#define C_0286CC_POSITION_SAMPLE 0xBFFFFFFF
+#define S_0286CC_BARYC_AT_SAMPLE_ENA(x) (((x) & 0x1) << 31)
+#define G_0286CC_BARYC_AT_SAMPLE_ENA(x) (((x) >> 31) & 0x1)
+#define C_0286CC_BARYC_AT_SAMPLE_ENA 0x7FFFFFFF
+#define R_0286D0_SPI_PS_IN_CONTROL_1 0x0286D0
+#define S_0286D0_GEN_INDEX_PIX(x) (((x) & 0x1) << 0)
+#define G_0286D0_GEN_INDEX_PIX(x) (((x) >> 0) & 0x1)
+#define C_0286D0_GEN_INDEX_PIX 0xFFFFFFFE
+#define S_0286D0_GEN_INDEX_PIX_ADDR(x) (((x) & 0x7F) << 1)
+#define G_0286D0_GEN_INDEX_PIX_ADDR(x) (((x) >> 1) & 0x7F)
+#define C_0286D0_GEN_INDEX_PIX_ADDR 0xFFFFFF01
+#define S_0286D0_FRONT_FACE_ENA(x) (((x) & 0x1) << 8)
+#define G_0286D0_FRONT_FACE_ENA(x) (((x) >> 8) & 0x1)
+#define C_0286D0_FRONT_FACE_ENA 0xFFFFFEFF
+#define S_0286D0_FRONT_FACE_CHAN(x) (((x) & 0x3) << 9)
+#define G_0286D0_FRONT_FACE_CHAN(x) (((x) >> 9) & 0x3)
+#define C_0286D0_FRONT_FACE_CHAN 0xFFFFF9FF
+#define S_0286D0_FRONT_FACE_ALL_BITS(x) (((x) & 0x1) << 11)
+#define G_0286D0_FRONT_FACE_ALL_BITS(x) (((x) >> 11) & 0x1)
+#define C_0286D0_FRONT_FACE_ALL_BITS 0xFFFFF7FF
+#define S_0286D0_FRONT_FACE_ADDR(x) (((x) & 0x1F) << 12)
+#define G_0286D0_FRONT_FACE_ADDR(x) (((x) >> 12) & 0x1F)
+#define C_0286D0_FRONT_FACE_ADDR 0xFFFE0FFF
+#define S_0286D0_FOG_ADDR(x) (((x) & 0x7F) << 17)
+#define G_0286D0_FOG_ADDR(x) (((x) >> 17) & 0x7F)
+#define C_0286D0_FOG_ADDR 0xFF01FFFF
+#define S_0286D0_FIXED_PT_POSITION_ENA(x) (((x) & 0x1) << 24)
+#define G_0286D0_FIXED_PT_POSITION_ENA(x) (((x) >> 24) & 0x1)
+#define C_0286D0_FIXED_PT_POSITION_ENA 0xFEFFFFFF
+#define S_0286D0_FIXED_PT_POSITION_ADDR(x) (((x) & 0x1F) << 25)
+#define G_0286D0_FIXED_PT_POSITION_ADDR(x) (((x) >> 25) & 0x1F)
+#define C_0286D0_FIXED_PT_POSITION_ADDR 0xC1FFFFFF
+#define R_0286C4_SPI_VS_OUT_CONFIG 0x0286C4
+#define S_0286C4_VS_PER_COMPONENT(x) (((x) & 0x1) << 0)
+#define G_0286C4_VS_PER_COMPONENT(x) (((x) >> 0) & 0x1)
+#define C_0286C4_VS_PER_COMPONENT 0xFFFFFFFE
+#define S_0286C4_VS_EXPORT_COUNT(x) (((x) & 0x1F) << 1)
+#define G_0286C4_VS_EXPORT_COUNT(x) (((x) >> 1) & 0x1F)
+#define C_0286C4_VS_EXPORT_COUNT 0xFFFFFFC1
+#define S_0286C4_VS_EXPORTS_FOG(x) (((x) & 0x1) << 8)
+#define G_0286C4_VS_EXPORTS_FOG(x) (((x) >> 8) & 0x1)
+#define C_0286C4_VS_EXPORTS_FOG 0xFFFFFEFF
+#define S_0286C4_VS_OUT_FOG_VEC_ADDR(x) (((x) & 0x1F) << 9)
+#define G_0286C4_VS_OUT_FOG_VEC_ADDR(x) (((x) >> 9) & 0x1F)
+#define C_0286C4_VS_OUT_FOG_VEC_ADDR 0xFFFFC1FF
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define S_028240_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028240_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028240_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028244_PA_SC_GENERIC_SCISSOR_BR 0x028244
+#define S_028244_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028244_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028244_BR_X 0xFFFFC000
+#define S_028244_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028244_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028244_BR_Y 0xC000FFFF
+#define R_028030_PA_SC_SCREEN_SCISSOR_TL 0x028030
+#define S_028030_TL_X(x) (((x) & 0x7FFF) << 0)
+#define G_028030_TL_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028030_TL_X 0xFFFF8000
+#define S_028030_TL_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028030_TL_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028030_TL_Y 0x8000FFFF
+#define R_028034_PA_SC_SCREEN_SCISSOR_BR 0x028034
+#define S_028034_BR_X(x) (((x) & 0x7FFF) << 0)
+#define G_028034_BR_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028034_BR_X 0xFFFF8000
+#define S_028034_BR_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028034_BR_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028034_BR_Y 0x8000FFFF
+#define R_028204_PA_SC_WINDOW_SCISSOR_TL 0x028204
+#define S_028204_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028204_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028204_TL_X 0xFFFFC000
+#define S_028204_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028204_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028204_TL_Y 0xC000FFFF
+#define S_028204_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028204_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028204_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028208_PA_SC_WINDOW_SCISSOR_BR 0x028208
+#define S_028208_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028208_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028208_BR_X 0xFFFFC000
+#define S_028208_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028208_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028208_BR_Y 0xC000FFFF
+#define R_0287F0_VGT_DRAW_INITIATOR 0x0287F0
+#define S_0287F0_SOURCE_SELECT(x) (((x) & 0x3) << 0)
+#define G_0287F0_SOURCE_SELECT(x) (((x) >> 0) & 0x3)
+#define C_0287F0_SOURCE_SELECT 0xFFFFFFFC
+#define S_0287F0_MAJOR_MODE(x) (((x) & 0x3) << 2)
+#define G_0287F0_MAJOR_MODE(x) (((x) >> 2) & 0x3)
+#define C_0287F0_MAJOR_MODE 0xFFFFFFF3
+#define S_0287F0_SPRITE_EN(x) (((x) & 0x1) << 4)
+#define G_0287F0_SPRITE_EN(x) (((x) >> 4) & 0x1)
+#define C_0287F0_SPRITE_EN 0xFFFFFFEF
+#define S_0287F0_NOT_EOP(x) (((x) & 0x1) << 5)
+#define G_0287F0_NOT_EOP(x) (((x) >> 5) & 0x1)
+#define C_0287F0_NOT_EOP 0xFFFFFFDF
+#define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6)
+#define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1)
+#define C_0287F0_USE_OPAQUE 0xFFFFFFBF
+#define R_038008_SQ_VTX_CONSTANT_WORD2_0 0x038008
+#define S_038008_BASE_ADDRESS_HI(x) (((x) & 0xFF) << 0)
+#define G_038008_BASE_ADDRESS_HI(x) (((x) >> 0) & 0xFF)
+#define C_038008_BASE_ADDRESS_HI 0xFFFFFF00
+#define S_038008_STRIDE(x) (((x) & 0x7FF) << 8)
+#define G_038008_STRIDE(x) (((x) >> 8) & 0x7FF)
+#define C_038008_STRIDE 0xFFF800FF
+#define S_038008_CLAMP_X(x) (((x) & 0x1) << 19)
+#define G_038008_CLAMP_X(x) (((x) >> 19) & 0x1)
+#define C_038008_CLAMP_X 0xFFF7FFFF
+#define S_038008_DATA_FORMAT(x) (((x) & 0x3F) << 20)
+#define G_038008_DATA_FORMAT(x) (((x) >> 20) & 0x3F)
+#define C_038008_DATA_FORMAT 0xFC0FFFFF
+#define V_038008_COLOR_INVALID 0x00000000
+#define V_038008_COLOR_8 0x00000001
+#define V_038008_COLOR_4_4 0x00000002
+#define V_038008_COLOR_3_3_2 0x00000003
+#define V_038008_COLOR_16 0x00000005
+#define V_038008_COLOR_16_FLOAT 0x00000006
+#define V_038008_COLOR_8_8 0x00000007
+#define V_038008_COLOR_5_6_5 0x00000008
+#define V_038008_COLOR_6_5_5 0x00000009
+#define V_038008_COLOR_1_5_5_5 0x0000000A
+#define V_038008_COLOR_4_4_4_4 0x0000000B
+#define V_038008_COLOR_5_5_5_1 0x0000000C
+#define V_038008_COLOR_32 0x0000000D
+#define V_038008_COLOR_32_FLOAT 0x0000000E
+#define V_038008_COLOR_16_16 0x0000000F
+#define V_038008_COLOR_16_16_FLOAT 0x00000010
+#define V_038008_COLOR_8_24 0x00000011
+#define V_038008_COLOR_8_24_FLOAT 0x00000012
+#define V_038008_COLOR_24_8 0x00000013
+#define V_038008_COLOR_24_8_FLOAT 0x00000014
+#define V_038008_COLOR_10_11_11 0x00000015
+#define V_038008_COLOR_10_11_11_FLOAT 0x00000016
+#define V_038008_COLOR_11_11_10 0x00000017
+#define V_038008_COLOR_11_11_10_FLOAT 0x00000018
+#define V_038008_COLOR_2_10_10_10 0x00000019
+#define V_038008_COLOR_8_8_8_8 0x0000001A
+#define V_038008_COLOR_10_10_10_2 0x0000001B
+#define V_038008_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_038008_COLOR_32_32 0x0000001D
+#define V_038008_COLOR_32_32_FLOAT 0x0000001E
+#define V_038008_COLOR_16_16_16_16 0x0000001F
+#define V_038008_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_038008_COLOR_32_32_32_32 0x00000022
+#define V_038008_COLOR_32_32_32_32_FLOAT 0x00000023
+#define S_038008_NUM_FORMAT_ALL(x) (((x) & 0x3) << 26)
+#define G_038008_NUM_FORMAT_ALL(x) (((x) >> 26) & 0x3)
+#define C_038008_NUM_FORMAT_ALL 0xF3FFFFFF
+#define S_038008_FORMAT_COMP_ALL(x) (((x) & 0x1) << 28)
+#define G_038008_FORMAT_COMP_ALL(x) (((x) >> 28) & 0x1)
+#define C_038008_FORMAT_COMP_ALL 0xEFFFFFFF
+#define S_038008_SRF_MODE_ALL(x) (((x) & 0x1) << 29)
+#define G_038008_SRF_MODE_ALL(x) (((x) >> 29) & 0x1)
+#define C_038008_SRF_MODE_ALL 0xDFFFFFFF
+#define S_038008_ENDIAN_SWAP(x) (((x) & 0x3) << 30)
+#define G_038008_ENDIAN_SWAP(x) (((x) >> 30) & 0x3)
+#define C_038008_ENDIAN_SWAP 0x3FFFFFFF
+#define R_008958_VGT_PRIMITIVE_TYPE 0x008958
+#define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0)
+#define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F)
+#define C_008958_PRIM_TYPE 0xFFFFFFC0
+#define V_008958_DI_PT_NONE 0x00000000
+#define V_008958_DI_PT_POINTLIST 0x00000001
+#define V_008958_DI_PT_LINELIST 0x00000002
+#define V_008958_DI_PT_LINESTRIP 0x00000003
+#define V_008958_DI_PT_TRILIST 0x00000004
+#define V_008958_DI_PT_TRIFAN 0x00000005
+#define V_008958_DI_PT_TRISTRIP 0x00000006
+#define V_008958_DI_PT_UNUSED_0 0x00000007
+#define V_008958_DI_PT_UNUSED_1 0x00000008
+#define V_008958_DI_PT_UNUSED_2 0x00000009
+#define V_008958_DI_PT_LINELIST_ADJ 0x0000000A
+#define V_008958_DI_PT_LINESTRIP_ADJ 0x0000000B
+#define V_008958_DI_PT_TRILIST_ADJ 0x0000000C
+#define V_008958_DI_PT_TRISTRIP_ADJ 0x0000000D
+#define V_008958_DI_PT_UNUSED_3 0x0000000E
+#define V_008958_DI_PT_UNUSED_4 0x0000000F
+#define V_008958_DI_PT_TRI_WITH_WFLAGS 0x00000010
+#define V_008958_DI_PT_RECTLIST 0x00000011
+#define V_008958_DI_PT_LINELOOP 0x00000012
+#define V_008958_DI_PT_QUADLIST 0x00000013
+#define V_008958_DI_PT_QUADSTRIP 0x00000014
+#define V_008958_DI_PT_POLYGON 0x00000015
+#define V_008958_DI_PT_2D_COPY_RECT_LIST_V0 0x00000016
+#define V_008958_DI_PT_2D_COPY_RECT_LIST_V1 0x00000017
+#define V_008958_DI_PT_2D_COPY_RECT_LIST_V2 0x00000018
+#define V_008958_DI_PT_2D_COPY_RECT_LIST_V3 0x00000019
+#define V_008958_DI_PT_2D_FILL_RECT_LIST 0x0000001A
+#define V_008958_DI_PT_2D_LINE_STRIP 0x0000001B
+#define V_008958_DI_PT_2D_TRI_STRIP 0x0000001C
+#define R_028868_SQ_PGM_RESOURCES_VS 0x028868
+#define S_028868_NUM_GPRS(x) (((x) & 0xFF) << 0)
+#define G_028868_NUM_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_028868_NUM_GPRS 0xFFFFFF00
+#define S_028868_STACK_SIZE(x) (((x) & 0xFF) << 8)
+#define G_028868_STACK_SIZE(x) (((x) >> 8) & 0xFF)
+#define C_028868_STACK_SIZE 0xFFFF00FF
+#define S_028868_DX10_CLAMP(x) (((x) & 0x1) << 21)
+#define G_028868_DX10_CLAMP(x) (((x) >> 21) & 0x1)
+#define C_028868_DX10_CLAMP 0xFFDFFFFF
+#define S_028868_FETCH_CACHE_LINES(x) (((x) & 0x7) << 24)
+#define G_028868_FETCH_CACHE_LINES(x) (((x) >> 24) & 0x7)
+#define C_028868_FETCH_CACHE_LINES 0xF8FFFFFF
+#define S_028868_UNCACHED_FIRST_INST(x) (((x) & 0x1) << 28)
+#define G_028868_UNCACHED_FIRST_INST(x) (((x) >> 28) & 0x1)
+#define C_028868_UNCACHED_FIRST_INST 0xEFFFFFFF
+#define R_028850_SQ_PGM_RESOURCES_PS 0x028850
+#define S_028850_NUM_GPRS(x) (((x) & 0xFF) << 0)
+#define G_028850_NUM_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_028850_NUM_GPRS 0xFFFFFF00
+#define S_028850_STACK_SIZE(x) (((x) & 0xFF) << 8)
+#define G_028850_STACK_SIZE(x) (((x) >> 8) & 0xFF)
+#define C_028850_STACK_SIZE 0xFFFF00FF
+#define S_028850_DX10_CLAMP(x) (((x) & 0x1) << 21)
+#define G_028850_DX10_CLAMP(x) (((x) >> 21) & 0x1)
+#define C_028850_DX10_CLAMP 0xFFDFFFFF
+#define S_028850_FETCH_CACHE_LINES(x) (((x) & 0x7) << 24)
+#define G_028850_FETCH_CACHE_LINES(x) (((x) >> 24) & 0x7)
+#define C_028850_FETCH_CACHE_LINES 0xF8FFFFFF
+#define S_028850_UNCACHED_FIRST_INST(x) (((x) & 0x1) << 28)
+#define G_028850_UNCACHED_FIRST_INST(x) (((x) >> 28) & 0x1)
+#define C_028850_UNCACHED_FIRST_INST 0xEFFFFFFF
+#define S_028850_CLAMP_CONSTS(x) (((x) & 0x1) << 31)
+#define G_028850_CLAMP_CONSTS(x) (((x) >> 31) & 0x1)
+#define C_028850_CLAMP_CONSTS 0x7FFFFFFF
+#define R_028644_SPI_PS_INPUT_CNTL_0 0x028644
+#define S_028644_SEMANTIC(x) (((x) & 0xFF) << 0)
+#define G_028644_SEMANTIC(x) (((x) >> 0) & 0xFF)
+#define C_028644_SEMANTIC 0xFFFFFF00
+#define S_028644_DEFAULT_VAL(x) (((x) & 0x3) << 8)
+#define G_028644_DEFAULT_VAL(x) (((x) >> 8) & 0x3)
+#define C_028644_DEFAULT_VAL 0xFFFFFCFF
+#define S_028644_FLAT_SHADE(x) (((x) & 0x1) << 10)
+#define G_028644_FLAT_SHADE(x) (((x) >> 10) & 0x1)
+#define C_028644_FLAT_SHADE 0xFFFFFBFF
+#define S_028644_SEL_CENTROID(x) (((x) & 0x1) << 11)
+#define G_028644_SEL_CENTROID(x) (((x) >> 11) & 0x1)
+#define C_028644_SEL_CENTROID 0xFFFFF7FF
+#define S_028644_SEL_LINEAR(x) (((x) & 0x1) << 12)
+#define G_028644_SEL_LINEAR(x) (((x) >> 12) & 0x1)
+#define C_028644_SEL_LINEAR 0xFFFFEFFF
+#define S_028644_CYL_WRAP(x) (((x) & 0xF) << 13)
+#define G_028644_CYL_WRAP(x) (((x) >> 13) & 0xF)
+#define C_028644_CYL_WRAP 0xFFFE1FFF
+#define S_028644_PT_SPRITE_TEX(x) (((x) & 0x1) << 17)
+#define G_028644_PT_SPRITE_TEX(x) (((x) >> 17) & 0x1)
+#define C_028644_PT_SPRITE_TEX 0xFFFDFFFF
+#define S_028644_SEL_SAMPLE(x) (((x) & 0x1) << 18)
+#define G_028644_SEL_SAMPLE(x) (((x) >> 18) & 0x1)
+#define C_028644_SEL_SAMPLE 0xFFFBFFFF
+#define R_0286D4_SPI_INTERP_CONTROL_0 0x0286D4
+#define S_0286D4_FLAT_SHADE_ENA(x) (((x) & 0x1) << 0)
+#define G_0286D4_FLAT_SHADE_ENA(x) (((x) >> 0) & 0x1)
+#define C_0286D4_FLAT_SHADE_ENA 0xFFFFFFFE
+#define S_0286D4_PNT_SPRITE_ENA(x) (((x) & 0x1) << 1)
+#define G_0286D4_PNT_SPRITE_ENA(x) (((x) >> 1) & 0x1)
+#define C_0286D4_PNT_SPRITE_ENA 0xFFFFFFFD
+#define S_0286D4_PNT_SPRITE_OVRD_X(x) (((x) & 0x7) << 2)
+#define G_0286D4_PNT_SPRITE_OVRD_X(x) (((x) >> 2) & 0x7)
+#define C_0286D4_PNT_SPRITE_OVRD_X 0xFFFFFFE3
+#define S_0286D4_PNT_SPRITE_OVRD_Y(x) (((x) & 0x7) << 5)
+#define G_0286D4_PNT_SPRITE_OVRD_Y(x) (((x) >> 5) & 0x7)
+#define C_0286D4_PNT_SPRITE_OVRD_Y 0xFFFFFF1F
+#define S_0286D4_PNT_SPRITE_OVRD_Z(x) (((x) & 0x7) << 8)
+#define G_0286D4_PNT_SPRITE_OVRD_Z(x) (((x) >> 8) & 0x7)
+#define C_0286D4_PNT_SPRITE_OVRD_Z 0xFFFFF8FF
+#define S_0286D4_PNT_SPRITE_OVRD_W(x) (((x) & 0x7) << 11)
+#define G_0286D4_PNT_SPRITE_OVRD_W(x) (((x) >> 11) & 0x7)
+#define C_0286D4_PNT_SPRITE_OVRD_W 0xFFFFC7FF
+#define S_0286D4_PNT_SPRITE_TOP_1(x) (((x) & 0x1) << 14)
+#define G_0286D4_PNT_SPRITE_TOP_1(x) (((x) >> 14) & 0x1)
+#define C_0286D4_PNT_SPRITE_TOP_1 0xFFFFBFFF
+
+#endif
diff --git a/src/gallium/drivers/r600/r700_sq.h b/src/gallium/drivers/r600/r700_sq.h
new file mode 100644
index 0000000000..8266af6d1f
--- /dev/null
+++ b/src/gallium/drivers/r600/r700_sq.h
@@ -0,0 +1,609 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef R700_SQ_H
+#define R700_SQ_H
+
+#define P_SQ_CF_WORD0
+#define S_SQ_CF_WORD0_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_SQ_CF_WORD0_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_SQ_CF_WORD0_ADDR 0x00000000
+#define P_SQ_CF_WORD1
+#define S_SQ_CF_WORD1_POP_COUNT(x) (((x) & 0x7) << 0)
+#define G_SQ_CF_WORD1_POP_COUNT(x) (((x) >> 0) & 0x7)
+#define C_SQ_CF_WORD1_POP_COUNT 0xFFFFFFF8
+#define S_SQ_CF_WORD1_CF_CONST(x) (((x) & 0x1F) << 3)
+#define G_SQ_CF_WORD1_CF_CONST(x) (((x) >> 3) & 0x1F)
+#define C_SQ_CF_WORD1_CF_CONST 0xFFFFFF07
+#define S_SQ_CF_WORD1_COND(x) (((x) & 0x3) << 8)
+#define G_SQ_CF_WORD1_COND(x) (((x) >> 8) & 0x3)
+#define C_SQ_CF_WORD1_COND 0xFFFFFCFF
+#define S_SQ_CF_WORD1_COUNT(x) (((x) & 0x7) << 10)
+#define G_SQ_CF_WORD1_COUNT(x) (((x) >> 10) & 0x7)
+#define C_SQ_CF_WORD1_COUNT 0xFFFFE3FF
+#define S_SQ_CF_WORD1_CALL_COUNT(x) (((x) & 0x3F) << 13)
+#define G_SQ_CF_WORD1_CALL_COUNT(x) (((x) >> 13) & 0x3F)
+#define C_SQ_CF_WORD1_CALL_COUNT 0xFFF81FFF
+#define S_SQ_CF_WORD1_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_SQ_CF_WORD1_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_SQ_CF_WORD1_END_OF_PROGRAM 0xFFDFFFFF
+#define S_SQ_CF_WORD1_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_SQ_CF_WORD1_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_SQ_CF_WORD1_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_SQ_CF_WORD1_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_SQ_CF_WORD1_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_SQ_CF_WORD1_CF_INST 0xC07FFFFF
+#define V_SQ_CF_WORD1_SQ_CF_INST_NOP 0x00000000
+#define V_SQ_CF_WORD1_SQ_CF_INST_TEX 0x00000001
+#define V_SQ_CF_WORD1_SQ_CF_INST_VTX 0x00000002
+#define V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC 0x00000003
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START 0x00000004
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END 0x00000005
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_DX10 0x00000006
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL 0x00000007
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE 0x00000008
+#define V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK 0x00000009
+#define V_SQ_CF_WORD1_SQ_CF_INST_JUMP 0x0000000A
+#define V_SQ_CF_WORD1_SQ_CF_INST_PUSH 0x0000000B
+#define V_SQ_CF_WORD1_SQ_CF_INST_PUSH_ELSE 0x0000000C
+#define V_SQ_CF_WORD1_SQ_CF_INST_ELSE 0x0000000D
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP 0x0000000E
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP_JUMP 0x0000000F
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP_PUSH 0x00000010
+#define V_SQ_CF_WORD1_SQ_CF_INST_POP_PUSH_ELSE 0x00000011
+#define V_SQ_CF_WORD1_SQ_CF_INST_CALL 0x00000012
+#define V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS 0x00000013
+#define V_SQ_CF_WORD1_SQ_CF_INST_RETURN 0x00000014
+#define V_SQ_CF_WORD1_SQ_CF_INST_EMIT_VERTEX 0x00000015
+#define V_SQ_CF_WORD1_SQ_CF_INST_EMIT_CUT_VERTEX 0x00000016
+#define V_SQ_CF_WORD1_SQ_CF_INST_CUT_VERTEX 0x00000017
+#define V_SQ_CF_WORD1_SQ_CF_INST_KILL 0x00000018
+#define S_SQ_CF_WORD1_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_SQ_CF_WORD1_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_SQ_CF_WORD1_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_SQ_CF_WORD1_BARRIER(x) (((x) & 0x1) << 31)
+#define G_SQ_CF_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_SQ_CF_WORD1_BARRIER 0x7FFFFFFF
+#define S_SQ_CF_WORD1_COUNT_3(x) (((x) & 0x1) << 19)
+#define G_SQ_CF_WORD1_COUNT_3(x) (((x) >> 19) & 0x1)
+#define C_SQ_CF_WORD1_COUNT_3 0xFFF7FFFF
+#define P_SQ_CF_ALU_WORD0
+#define S_SQ_CF_ALU_WORD0_ADDR(x) (((x) & 0x3FFFFF) << 0)
+#define G_SQ_CF_ALU_WORD0_ADDR(x) (((x) >> 0) & 0x3FFFFF)
+#define C_SQ_CF_ALU_WORD0_ADDR 0xFFC00000
+#define S_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) & 0xF) << 22)
+#define G_SQ_CF_ALU_WORD0_KCACHE_BANK0(x) (((x) >> 22) & 0xF)
+#define C_SQ_CF_ALU_WORD0_KCACHE_BANK0 0xFC3FFFFF
+#define S_SQ_CF_ALU_WORD0_KCACHE_BANK1(x) (((x) & 0xF) << 26)
+#define G_SQ_CF_ALU_WORD0_KCACHE_BANK1(x) (((x) >> 26) & 0xF)
+#define C_SQ_CF_ALU_WORD0_KCACHE_BANK1 0xC3FFFFFF
+#define S_SQ_CF_ALU_WORD0_KCACHE_MODE0(x) (((x) & 0x3) << 30)
+#define G_SQ_CF_ALU_WORD0_KCACHE_MODE0(x) (((x) >> 30) & 0x3)
+#define C_SQ_CF_ALU_WORD0_KCACHE_MODE0 0x3FFFFFFF
+#define P_SQ_CF_ALU_WORD1
+#define S_SQ_CF_ALU_WORD1_KCACHE_MODE1(x) (((x) & 0x3) << 0)
+#define G_SQ_CF_ALU_WORD1_KCACHE_MODE1(x) (((x) >> 0) & 0x3)
+#define C_SQ_CF_ALU_WORD1_KCACHE_MODE1 0xFFFFFFFC
+#define S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(x) (((x) & 0xFF) << 2)
+#define G_SQ_CF_ALU_WORD1_KCACHE_ADDR0(x) (((x) >> 2) & 0xFF)
+#define C_SQ_CF_ALU_WORD1_KCACHE_ADDR0 0xFFFFFC03
+#define S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) & 0xFF) << 10)
+#define G_SQ_CF_ALU_WORD1_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF)
+#define C_SQ_CF_ALU_WORD1_KCACHE_ADDR1 0xFFFC03FF
+#define S_SQ_CF_ALU_WORD1_COUNT(x) (((x) & 0x7F) << 18)
+#define G_SQ_CF_ALU_WORD1_COUNT(x) (((x) >> 18) & 0x7F)
+#define C_SQ_CF_ALU_WORD1_COUNT 0xFE03FFFF
+#define S_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) & 0x1) << 25)
+#define G_SQ_CF_ALU_WORD1_USES_WATERFALL(x) (((x) >> 25) & 0x1)
+#define C_SQ_CF_ALU_WORD1_USES_WATERFALL 0xFDFFFFFF
+#define S_SQ_CF_ALU_WORD1_CF_INST(x) (((x) & 0xF) << 26)
+#define G_SQ_CF_ALU_WORD1_CF_INST(x) (((x) >> 26) & 0xF)
+#define C_SQ_CF_ALU_WORD1_CF_INST 0xC3FFFFFF
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU 0x00000008
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER 0x0000000A
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER 0x0000000B
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_CONTINUE 0x0000000D
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_BREAK 0x0000000E
+#define V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_ELSE_AFTER 0x0000000F
+#define S_SQ_CF_ALU_WORD1_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_SQ_CF_ALU_WORD1_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_SQ_CF_ALU_WORD1_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_SQ_CF_ALU_WORD1_BARRIER(x) (((x) & 0x1) << 31)
+#define G_SQ_CF_ALU_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_SQ_CF_ALU_WORD1_BARRIER 0x7FFFFFFF
+#define S_SQ_CF_ALU_WORD1_ALT_CONST(x) (((x) & 0x1) << 25)
+#define G_SQ_CF_ALU_WORD1_ALT_CONST(x) (((x) >> 25) & 0x1)
+#define C_SQ_CF_ALU_WORD1_ALT_CONST 0xFDFFFFFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD0
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(x) (((x) & 0x1FFF) << 0)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(x) (((x) >> 0) & 0x1FFF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE 0xFFFFE000
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(x) (((x) & 0x3) << 13)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_TYPE(x) (((x) >> 13) & 0x3)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_TYPE 0xFFFF9FFF
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL 0x00000000
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_POS 0x00000001
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM 0x00000002
+#define V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_SX 0x00000003
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(x) (((x) & 0x7F) << 15)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(x) (((x) >> 15) & 0x7F)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR 0xFFC07FFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_RW_REL(x) (((x) & 0x1) << 22)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_RW_REL(x) (((x) >> 22) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_RW_REL 0xFFBFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR(x) (((x) & 0x7F) << 23)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR(x) (((x) >> 23) & 0x7F)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_INDEX_GPR 0xC07FFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(x) (((x) & 0x3) << 30)
+#define G_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(x) (((x) >> 30) & 0x3)
+#define C_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE 0x3FFFFFFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD1
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(x) (((x) & 0xF) << 17)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT(x) (((x) >> 17) & 0xF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BURST_COUNT 0xFFE1FFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM 0xFFDFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST 0xC07FFFFF
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM0 0x00000020
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM1 0x00000021
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM2 0x00000022
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_STREAM3 0x00000023
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_SCRATCH 0x00000024
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_REDUCTION 0x00000025
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_MEM_RING 0x00000026
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT 0x00000027
+#define V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE 0x00000028
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(x) (((x) & 0x1) << 31)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER 0x7FFFFFFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD1_BUF
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(x) (((x) & 0xFFF) << 0)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE(x) (((x) >> 0) & 0xFFF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BUF_ARRAY_SIZE 0xFFFFF000
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(x) (((x) & 0xF) << 12)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK(x) (((x) >> 12) & 0xF)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_BUF_COMP_MASK 0xFFFF0FFF
+#define P_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(x) (((x) & 0x7) << 0)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X(x) (((x) >> 0) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_X 0xFFFFFFF8
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(x) (((x) & 0x7) << 3)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(x) (((x) >> 3) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y 0xFFFFFFC7
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(x) (((x) & 0x7) << 6)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(x) (((x) >> 6) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z 0xFFFFFE3F
+#define S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(x) (((x) & 0x7) << 9)
+#define G_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(x) (((x) >> 9) & 0x7)
+#define C_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W 0xFFFFF1FF
+#define P_SQ_ALU_WORD0
+#define S_SQ_ALU_WORD0_SRC0_SEL(x) (((x) & 0x1FF) << 0)
+#define G_SQ_ALU_WORD0_SRC0_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_SQ_ALU_WORD0_SRC0_SEL 0xFFFFFE00
+#define S_SQ_ALU_WORD0_SRC0_REL(x) (((x) & 0x1) << 9)
+#define G_SQ_ALU_WORD0_SRC0_REL(x) (((x) >> 9) & 0x1)
+#define C_SQ_ALU_WORD0_SRC0_REL 0xFFFFFDFF
+#define S_SQ_ALU_WORD0_SRC0_CHAN(x) (((x) & 0x3) << 10)
+#define G_SQ_ALU_WORD0_SRC0_CHAN(x) (((x) >> 10) & 0x3)
+#define C_SQ_ALU_WORD0_SRC0_CHAN 0xFFFFF3FF
+#define S_SQ_ALU_WORD0_SRC0_NEG(x) (((x) & 0x1) << 12)
+#define G_SQ_ALU_WORD0_SRC0_NEG(x) (((x) >> 12) & 0x1)
+#define C_SQ_ALU_WORD0_SRC0_NEG 0xFFFFEFFF
+#define S_SQ_ALU_WORD0_SRC1_SEL(x) (((x) & 0x1FF) << 13)
+#define G_SQ_ALU_WORD0_SRC1_SEL(x) (((x) >> 13) & 0x1FF)
+#define C_SQ_ALU_WORD0_SRC1_SEL 0xFFC01FFF
+#define S_SQ_ALU_WORD0_SRC1_REL(x) (((x) & 0x1) << 22)
+#define G_SQ_ALU_WORD0_SRC1_REL(x) (((x) >> 22) & 0x1)
+#define C_SQ_ALU_WORD0_SRC1_REL 0xFFBFFFFF
+#define S_SQ_ALU_WORD0_SRC1_CHAN(x) (((x) & 0x3) << 23)
+#define G_SQ_ALU_WORD0_SRC1_CHAN(x) (((x) >> 23) & 0x3)
+#define C_SQ_ALU_WORD0_SRC1_CHAN 0xFE7FFFFF
+#define S_SQ_ALU_WORD0_SRC1_NEG(x) (((x) & 0x1) << 25)
+#define G_SQ_ALU_WORD0_SRC1_NEG(x) (((x) >> 25) & 0x1)
+#define C_SQ_ALU_WORD0_SRC1_NEG 0xFDFFFFFF
+#define S_SQ_ALU_WORD0_INDEX_MODE(x) (((x) & 0x7) << 26)
+#define G_SQ_ALU_WORD0_INDEX_MODE(x) (((x) >> 26) & 0x7)
+#define C_SQ_ALU_WORD0_INDEX_MODE 0xE3FFFFFF
+#define S_SQ_ALU_WORD0_PRED_SEL(x) (((x) & 0x3) << 29)
+#define G_SQ_ALU_WORD0_PRED_SEL(x) (((x) >> 29) & 0x3)
+#define C_SQ_ALU_WORD0_PRED_SEL 0x9FFFFFFF
+#define S_SQ_ALU_WORD0_LAST(x) (((x) & 0x1) << 31)
+#define G_SQ_ALU_WORD0_LAST(x) (((x) >> 31) & 0x1)
+#define C_SQ_ALU_WORD0_LAST 0x7FFFFFFF
+#define P_SQ_ALU_WORD1
+#define S_SQ_ALU_WORD1_ENCODING(x) (((x) & 0x7) << 15)
+#define G_SQ_ALU_WORD1_ENCODING(x) (((x) >> 15) & 0x7)
+#define C_SQ_ALU_WORD1_ENCODING 0xFFFC7FFF
+#define S_SQ_ALU_WORD1_BANK_SWIZZLE(x) (((x) & 0x7) << 18)
+#define G_SQ_ALU_WORD1_BANK_SWIZZLE(x) (((x) >> 18) & 0x7)
+#define C_SQ_ALU_WORD1_BANK_SWIZZLE 0xFFE3FFFF
+#define S_SQ_ALU_WORD1_DST_GPR(x) (((x) & 0x7F) << 21)
+#define G_SQ_ALU_WORD1_DST_GPR(x) (((x) >> 21) & 0x7F)
+#define C_SQ_ALU_WORD1_DST_GPR 0xF01FFFFF
+#define S_SQ_ALU_WORD1_DST_REL(x) (((x) & 0x1) << 28)
+#define G_SQ_ALU_WORD1_DST_REL(x) (((x) >> 28) & 0x1)
+#define C_SQ_ALU_WORD1_DST_REL 0xEFFFFFFF
+#define S_SQ_ALU_WORD1_DST_CHAN(x) (((x) & 0x3) << 29)
+#define G_SQ_ALU_WORD1_DST_CHAN(x) (((x) >> 29) & 0x3)
+#define C_SQ_ALU_WORD1_DST_CHAN 0x9FFFFFFF
+#define S_SQ_ALU_WORD1_CLAMP(x) (((x) & 0x1) << 31)
+#define G_SQ_ALU_WORD1_CLAMP(x) (((x) >> 31) & 0x1)
+#define C_SQ_ALU_WORD1_CLAMP 0x7FFFFFFF
+#define P_SQ_ALU_WORD1_OP2
+#define S_SQ_ALU_WORD1_OP2_SRC0_ABS(x) (((x) & 0x1) << 0)
+#define G_SQ_ALU_WORD1_OP2_SRC0_ABS(x) (((x) >> 0) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_SRC0_ABS 0xFFFFFFFE
+#define S_SQ_ALU_WORD1_OP2_SRC1_ABS(x) (((x) & 0x1) << 1)
+#define G_SQ_ALU_WORD1_OP2_SRC1_ABS(x) (((x) >> 1) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_SRC1_ABS 0xFFFFFFFD
+#define S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(x) (((x) & 0x1) << 2)
+#define G_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(x) (((x) >> 2) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK 0xFFFFFFFB
+#define S_SQ_ALU_WORD1_OP2_UPDATE_PRED(x) (((x) & 0x1) << 3)
+#define G_SQ_ALU_WORD1_OP2_UPDATE_PRED(x) (((x) >> 3) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_UPDATE_PRED 0xFFFFFFF7
+#define S_SQ_ALU_WORD1_OP2_WRITE_MASK(x) (((x) & 0x1) << 4)
+#define G_SQ_ALU_WORD1_OP2_WRITE_MASK(x) (((x) >> 4) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_WRITE_MASK 0xFFFFFFEF
+#define S_SQ_ALU_WORD1_OP2_OMOD(x) (((x) & 0x3) << 5)
+#define G_SQ_ALU_WORD1_OP2_OMOD(x) (((x) >> 5) & 0x3)
+#define C_SQ_ALU_WORD1_OP2_OMOD 0xFFFFFF9F
+#define S_SQ_ALU_WORD1_OP2_ALU_INST(x) (((x) & 0x7FF) << 7)
+#define G_SQ_ALU_WORD1_OP2_ALU_INST(x) (((x) >> 7) & 0x7FF)
+#define C_SQ_ALU_WORD1_OP2_ALU_INST 0xFFFC007F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD 0x00000000
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL 0x00000001
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL_IEEE 0x00000002
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX 0x00000003
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN 0x00000004
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_DX10 0x00000005
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_DX10 0x00000006
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE 0x00000008
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT 0x00000009
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE 0x0000000A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE 0x0000000B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_DX10 0x0000000C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_DX10 0x0000000D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_DX10 0x0000000E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_DX10 0x0000000F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT 0x00000010
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC 0x00000011
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CEIL 0x00000012
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RNDNE 0x00000013
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR 0x00000014
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA 0x00000015
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR 0x00000016
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT 0x00000018
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV 0x00000019
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP 0x0000001A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT 0x0000001E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT 0x0000001F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE 0x00000020
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT 0x00000021
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE 0x00000022
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE 0x00000023
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV 0x00000024
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP 0x00000025
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR 0x00000026
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE 0x00000027
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH 0x00000028
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH 0x00000029
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH 0x0000002A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH 0x0000002B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE 0x0000002C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT 0x0000002D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE 0x0000002E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE 0x0000002F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_AND_INT 0x00000030
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_OR_INT 0x00000031
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_XOR_INT 0x00000032
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOT_INT 0x00000033
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD_INT 0x00000034
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SUB_INT 0x00000035
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_INT 0x00000036
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_INT 0x00000037
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX_UINT 0x00000038
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN_UINT 0x00000039
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE_INT 0x0000003A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_INT 0x0000003B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_INT 0x0000003C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE_INT 0x0000003D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT_UINT 0x0000003E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE_UINT 0x0000003F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT 0x00000040
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT 0x00000041
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT 0x00000042
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT 0x00000043
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT 0x00000044
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT 0x00000045
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT 0x00000046
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT 0x00000047
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT 0x00000048
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT 0x00000049
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT 0x0000004A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT 0x0000004B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT 0x0000004C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT 0x0000004D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT 0x0000004E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT 0x0000004F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 0x00000050
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE 0x00000051
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE 0x00000052
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4 0x00000053
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_GPR_INT 0x00000060
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE 0x00000061
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED 0x00000062
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE 0x00000063
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED 0x00000064
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF 0x00000065
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE 0x00000066
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED 0x00000067
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF 0x00000068
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE 0x00000069
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE 0x0000006A
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT 0x0000006B
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT 0x0000006C
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT 0x0000006D
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN 0x0000006E
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS 0x0000006F
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT 0x00000070
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT 0x00000071
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT 0x00000072
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT 0x00000073
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT 0x00000074
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT 0x00000075
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT 0x00000076
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT 0x00000077
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT 0x00000078
+#define V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_UINT 0x00000079
+#define P_SQ_ALU_WORD1_OP3
+#define S_SQ_ALU_WORD1_OP3_SRC2_SEL(x) (((x) & 0x1FF) << 0)
+#define G_SQ_ALU_WORD1_OP3_SRC2_SEL(x) (((x) >> 0) & 0x1FF)
+#define C_SQ_ALU_WORD1_OP3_SRC2_SEL 0xFFFFFE00
+#define S_SQ_ALU_WORD1_OP3_SRC2_REL(x) (((x) & 0x1) << 9)
+#define G_SQ_ALU_WORD1_OP3_SRC2_REL(x) (((x) >> 9) & 0x1)
+#define C_SQ_ALU_WORD1_OP3_SRC2_REL 0xFFFFFDFF
+#define S_SQ_ALU_WORD1_OP3_SRC2_CHAN(x) (((x) & 0x3) << 10)
+#define G_SQ_ALU_WORD1_OP3_SRC2_CHAN(x) (((x) >> 10) & 0x3)
+#define C_SQ_ALU_WORD1_OP3_SRC2_CHAN 0xFFFFF3FF
+#define S_SQ_ALU_WORD1_OP3_SRC2_NEG(x) (((x) & 0x1) << 12)
+#define G_SQ_ALU_WORD1_OP3_SRC2_NEG(x) (((x) >> 12) & 0x1)
+#define C_SQ_ALU_WORD1_OP3_SRC2_NEG 0xFFFFEFFF
+#define S_SQ_ALU_WORD1_OP3_ALU_INST(x) (((x) & 0x1F) << 13)
+#define G_SQ_ALU_WORD1_OP3_ALU_INST(x) (((x) >> 13) & 0x1F)
+#define C_SQ_ALU_WORD1_OP3_ALU_INST 0xFFFC1FFF
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT 0x0000000C
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 0x0000000D
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4 0x0000000E
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 0x0000000F
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD 0x00000010
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M2 0x00000011
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_M4 0x00000012
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_D2 0x00000013
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE 0x00000014
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M2 0x00000015
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_M4 0x00000016
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD_IEEE_D2 0x00000017
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE 0x00000018
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT 0x00000019
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE 0x0000001A
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDE_INT 0x0000001C
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGT_INT 0x0000001D
+#define V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_CNDGE_INT 0x0000001E
+#define P_SQ_VTX_WORD0
+#define S_SQ_VTX_WORD0_VTX_INST(x) (((x) & 0x1F) << 0)
+#define G_SQ_VTX_WORD0_VTX_INST(x) (((x) >> 0) & 0x1F)
+#define C_SQ_VTX_WORD0_VTX_INST 0xFFFFFFE0
+#define S_SQ_VTX_WORD0_FETCH_TYPE(x) (((x) & 0x3) << 5)
+#define G_SQ_VTX_WORD0_FETCH_TYPE(x) (((x) >> 5) & 0x3)
+#define C_SQ_VTX_WORD0_FETCH_TYPE 0xFFFFFF9F
+#define S_SQ_VTX_WORD0_FETCH_WHOLE_QUAD(x) (((x) & 0x1) << 7)
+#define G_SQ_VTX_WORD0_FETCH_WHOLE_QUAD(x) (((x) >> 7) & 0x1)
+#define C_SQ_VTX_WORD0_FETCH_WHOLE_QUAD 0xFFFFFF7F
+#define S_SQ_VTX_WORD0_BUFFER_ID(x) (((x) & 0xFF) << 8)
+#define G_SQ_VTX_WORD0_BUFFER_ID(x) (((x) >> 8) & 0xFF)
+#define C_SQ_VTX_WORD0_BUFFER_ID 0xFFFF00FF
+#define S_SQ_VTX_WORD0_SRC_GPR(x) (((x) & 0x7F) << 16)
+#define G_SQ_VTX_WORD0_SRC_GPR(x) (((x) >> 16) & 0x7F)
+#define C_SQ_VTX_WORD0_SRC_GPR 0xFF80FFFF
+#define S_SQ_VTX_WORD0_SRC_REL(x) (((x) & 0x1) << 23)
+#define G_SQ_VTX_WORD0_SRC_REL(x) (((x) >> 23) & 0x1)
+#define C_SQ_VTX_WORD0_SRC_REL 0xFF7FFFFF
+#define S_SQ_VTX_WORD0_SRC_SEL_X(x) (((x) & 0x3) << 24)
+#define G_SQ_VTX_WORD0_SRC_SEL_X(x) (((x) >> 24) & 0x3)
+#define C_SQ_VTX_WORD0_SRC_SEL_X 0xFCFFFFFF
+#define S_SQ_VTX_WORD0_MEGA_FETCH_COUNT(x) (((x) & 0x3F) << 26)
+#define G_SQ_VTX_WORD0_MEGA_FETCH_COUNT(x) (((x) >> 26) & 0x3F)
+#define C_SQ_VTX_WORD0_MEGA_FETCH_COUNT 0x03FFFFFF
+#define P_SQ_VTX_WORD1
+#define S_SQ_VTX_WORD1_DST_SEL_X(x) (((x) & 0x7) << 9)
+#define G_SQ_VTX_WORD1_DST_SEL_X(x) (((x) >> 9) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_X 0xFFFFF1FF
+#define S_SQ_VTX_WORD1_DST_SEL_Y(x) (((x) & 0x7) << 12)
+#define G_SQ_VTX_WORD1_DST_SEL_Y(x) (((x) >> 12) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_Y 0xFFFF8FFF
+#define S_SQ_VTX_WORD1_DST_SEL_Z(x) (((x) & 0x7) << 15)
+#define G_SQ_VTX_WORD1_DST_SEL_Z(x) (((x) >> 15) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_Z 0xFFFC7FFF
+#define S_SQ_VTX_WORD1_DST_SEL_W(x) (((x) & 0x7) << 18)
+#define G_SQ_VTX_WORD1_DST_SEL_W(x) (((x) >> 18) & 0x7)
+#define C_SQ_VTX_WORD1_DST_SEL_W 0xFFE3FFFF
+#define S_SQ_VTX_WORD1_USE_CONST_FIELDS(x) (((x) & 0x1) << 21)
+#define G_SQ_VTX_WORD1_USE_CONST_FIELDS(x) (((x) >> 21) & 0x1)
+#define C_SQ_VTX_WORD1_USE_CONST_FIELDS 0xFFDFFFFF
+#define S_SQ_VTX_WORD1_DATA_FORMAT(x) (((x) & 0x3F) << 22)
+#define G_SQ_VTX_WORD1_DATA_FORMAT(x) (((x) >> 22) & 0x3F)
+#define C_SQ_VTX_WORD1_DATA_FORMAT 0xF03FFFFF
+#define S_SQ_VTX_WORD1_NUM_FORMAT_ALL(x) (((x) & 0x3) << 28)
+#define G_SQ_VTX_WORD1_NUM_FORMAT_ALL(x) (((x) >> 28) & 0x3)
+#define C_SQ_VTX_WORD1_NUM_FORMAT_ALL 0xCFFFFFFF
+#define S_SQ_VTX_WORD1_FORMAT_COMP_ALL(x) (((x) & 0x1) << 30)
+#define G_SQ_VTX_WORD1_FORMAT_COMP_ALL(x) (((x) >> 30) & 0x1)
+#define C_SQ_VTX_WORD1_FORMAT_COMP_ALL 0xBFFFFFFF
+#define S_SQ_VTX_WORD1_SRF_MODE_ALL(x) (((x) & 0x1) << 31)
+#define G_SQ_VTX_WORD1_SRF_MODE_ALL(x) (((x) >> 31) & 0x1)
+#define C_SQ_VTX_WORD1_SRF_MODE_ALL 0x7FFFFFFF
+#define P_SQ_VTX_WORD1_GPR
+#define S_SQ_VTX_WORD1_GPR_DST_GPR(x) (((x) & 0x7F) << 0)
+#define G_SQ_VTX_WORD1_GPR_DST_GPR(x) (((x) >> 0) & 0x7F)
+#define C_SQ_VTX_WORD1_GPR_DST_GPR 0xFFFFFF80
+#define S_SQ_VTX_WORD1_GPR_DST_REL(x) (((x) & 0x1) << 7)
+#define G_SQ_VTX_WORD1_GPR_DST_REL(x) (((x) >> 7) & 0x1)
+#define C_SQ_VTX_WORD1_GPR_DST_REL 0xFFFFFF7F
+#define P_SQ_VTX_WORD1_SEM
+#define S_SQ_VTX_WORD1_SEM_SEMANTIC_ID(x) (((x) & 0xFF) << 0)
+#define G_SQ_VTX_WORD1_SEM_SEMANTIC_ID(x) (((x) >> 0) & 0xFF)
+#define C_SQ_VTX_WORD1_SEM_SEMANTIC_ID 0xFFFFFF00
+#define P_SQ_VTX_WORD2
+#define S_SQ_VTX_WORD2_OFFSET(x) (((x) & 0xFFFF) << 0)
+#define G_SQ_VTX_WORD2_OFFSET(x) (((x) >> 0) & 0xFFFF)
+#define C_SQ_VTX_WORD2_OFFSET 0xFFFF0000
+#define S_SQ_VTX_WORD2_ENDIAN_SWAP(x) (((x) & 0x3) << 16)
+#define G_SQ_VTX_WORD2_ENDIAN_SWAP(x) (((x) >> 16) & 0x3)
+#define C_SQ_VTX_WORD2_ENDIAN_SWAP 0xFFFCFFFF
+#define S_SQ_VTX_WORD2_CONST_BUF_NO_STRIDE(x) (((x) & 0x1) << 18)
+#define G_SQ_VTX_WORD2_CONST_BUF_NO_STRIDE(x) (((x) >> 18) & 0x1)
+#define C_SQ_VTX_WORD2_CONST_BUF_NO_STRIDE 0xFFFBFFFF
+#define S_SQ_VTX_WORD2_MEGA_FETCH(x) (((x) & 0x1) << 19)
+#define G_SQ_VTX_WORD2_MEGA_FETCH(x) (((x) >> 19) & 0x1)
+#define C_SQ_VTX_WORD2_MEGA_FETCH 0xFFF7FFFF
+#define S_SQ_VTX_WORD2_ALT_CONST(x) (((x) & 0x1) << 20)
+#define G_SQ_VTX_WORD2_ALT_CONST(x) (((x) >> 20) & 0x1)
+#define C_SQ_VTX_WORD2_ALT_CONST 0xFFEFFFFF
+#define P_SQ_TEX_WORD0
+#define S_SQ_TEX_WORD0_TEX_INST(x) (((x) & 0x1F) << 0)
+#define G_SQ_TEX_WORD0_TEX_INST(x) (((x) >> 0) & 0x1F)
+#define C_SQ_TEX_WORD0_TEX_INST 0xFFFFFFE0
+#define S_SQ_TEX_WORD0_BC_FRAC_MODE(x) (((x) & 0x1) << 5)
+#define G_SQ_TEX_WORD0_BC_FRAC_MODE(x) (((x) >> 5) & 0x1)
+#define C_SQ_TEX_WORD0_BC_FRAC_MODE 0xFFFFFFDF
+#define S_SQ_TEX_WORD0_FETCH_WHOLE_QUAD(x) (((x) & 0x1) << 7)
+#define G_SQ_TEX_WORD0_FETCH_WHOLE_QUAD(x) (((x) >> 7) & 0x1)
+#define C_SQ_TEX_WORD0_FETCH_WHOLE_QUAD 0xFFFFFF7F
+#define S_SQ_TEX_WORD0_RESOURCE_ID(x) (((x) & 0xFF) << 8)
+#define G_SQ_TEX_WORD0_RESOURCE_ID(x) (((x) >> 8) & 0xFF)
+#define C_SQ_TEX_WORD0_RESOURCE_ID 0xFFFF00FF
+#define S_SQ_TEX_WORD0_SRC_GPR(x) (((x) & 0x7F) << 16)
+#define G_SQ_TEX_WORD0_SRC_GPR(x) (((x) >> 16) & 0x7F)
+#define C_SQ_TEX_WORD0_SRC_GPR 0xFF80FFFF
+#define S_SQ_TEX_WORD0_SRC_REL(x) (((x) & 0x1) << 23)
+#define G_SQ_TEX_WORD0_SRC_REL(x) (((x) >> 23) & 0x1)
+#define C_SQ_TEX_WORD0_SRC_REL 0xFF7FFFFF
+#define S_SQ_TEX_WORD0_ALT_CONST(x) (((x) & 0x1) << 24)
+#define G_SQ_TEX_WORD0_ALT_CONST(x) (((x) >> 24) & 0x1)
+#define C_SQ_TEX_WORD0_ALT_CONST 0xFEFFFFFF
+#define P_SQ_TEX_WORD1
+#define S_SQ_TEX_WORD1_DST_GPR(x) (((x) & 0x7F) << 0)
+#define G_SQ_TEX_WORD1_DST_GPR(x) (((x) >> 0) & 0x7F)
+#define C_SQ_TEX_WORD1_DST_GPR 0xFFFFFF80
+#define S_SQ_TEX_WORD1_DST_REL(x) (((x) & 0x1) << 7)
+#define G_SQ_TEX_WORD1_DST_REL(x) (((x) >> 7) & 0x1)
+#define C_SQ_TEX_WORD1_DST_REL 0xFFFFFF7F
+#define S_SQ_TEX_WORD1_DST_SEL_X(x) (((x) & 0x7) << 9)
+#define G_SQ_TEX_WORD1_DST_SEL_X(x) (((x) >> 9) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_X 0xFFFFF1FF
+#define S_SQ_TEX_WORD1_DST_SEL_Y(x) (((x) & 0x7) << 12)
+#define G_SQ_TEX_WORD1_DST_SEL_Y(x) (((x) >> 12) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_Y 0xFFFF8FFF
+#define S_SQ_TEX_WORD1_DST_SEL_Z(x) (((x) & 0x7) << 15)
+#define G_SQ_TEX_WORD1_DST_SEL_Z(x) (((x) >> 15) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_Z 0xFFFC7FFF
+#define S_SQ_TEX_WORD1_DST_SEL_W(x) (((x) & 0x7) << 18)
+#define G_SQ_TEX_WORD1_DST_SEL_W(x) (((x) >> 18) & 0x7)
+#define C_SQ_TEX_WORD1_DST_SEL_W 0xFFE3FFFF
+#define S_SQ_TEX_WORD1_LOD_BIAS(x) (((x) & 0x7F) << 21)
+#define G_SQ_TEX_WORD1_LOD_BIAS(x) (((x) >> 21) & 0x7F)
+#define C_SQ_TEX_WORD1_LOD_BIAS 0xF01FFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) & 0x1) << 28)
+#define G_SQ_TEX_WORD1_COORD_TYPE_X(x) (((x) >> 28) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_X 0xEFFFFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) & 0x1) << 29)
+#define G_SQ_TEX_WORD1_COORD_TYPE_Y(x) (((x) >> 29) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_Y 0xDFFFFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_Z(x) (((x) & 0x1) << 30)
+#define G_SQ_TEX_WORD1_COORD_TYPE_Z(x) (((x) >> 30) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_Z 0xBFFFFFFF
+#define S_SQ_TEX_WORD1_COORD_TYPE_W(x) (((x) & 0x1) << 31)
+#define G_SQ_TEX_WORD1_COORD_TYPE_W(x) (((x) >> 31) & 0x1)
+#define C_SQ_TEX_WORD1_COORD_TYPE_W 0x7FFFFFFF
+#define P_SQ_TEX_WORD2
+#define S_SQ_TEX_WORD2_OFFSET_X(x) (((x) & 0x1F) << 0)
+#define G_SQ_TEX_WORD2_OFFSET_X(x) (((x) >> 0) & 0x1F)
+#define C_SQ_TEX_WORD2_OFFSET_X 0xFFFFFFE0
+#define S_SQ_TEX_WORD2_OFFSET_Y(x) (((x) & 0x1F) << 5)
+#define G_SQ_TEX_WORD2_OFFSET_Y(x) (((x) >> 5) & 0x1F)
+#define C_SQ_TEX_WORD2_OFFSET_Y 0xFFFFFC1F
+#define S_SQ_TEX_WORD2_OFFSET_Z(x) (((x) & 0x1F) << 10)
+#define G_SQ_TEX_WORD2_OFFSET_Z(x) (((x) >> 10) & 0x1F)
+#define C_SQ_TEX_WORD2_OFFSET_Z 0xFFFF83FF
+#define S_SQ_TEX_WORD2_SAMPLER_ID(x) (((x) & 0x1F) << 15)
+#define G_SQ_TEX_WORD2_SAMPLER_ID(x) (((x) >> 15) & 0x1F)
+#define C_SQ_TEX_WORD2_SAMPLER_ID 0xFFF07FFF
+#define S_SQ_TEX_WORD2_SRC_SEL_X(x) (((x) & 0x7) << 20)
+#define G_SQ_TEX_WORD2_SRC_SEL_X(x) (((x) >> 20) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_X 0xFF8FFFFF
+#define S_SQ_TEX_WORD2_SRC_SEL_Y(x) (((x) & 0x7) << 23)
+#define G_SQ_TEX_WORD2_SRC_SEL_Y(x) (((x) >> 23) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_Y 0xFC7FFFFF
+#define S_SQ_TEX_WORD2_SRC_SEL_Z(x) (((x) & 0x7) << 26)
+#define G_SQ_TEX_WORD2_SRC_SEL_Z(x) (((x) >> 26) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_Z 0xE3FFFFFF
+#define S_SQ_TEX_WORD2_SRC_SEL_W(x) (((x) & 0x7) << 29)
+#define G_SQ_TEX_WORD2_SRC_SEL_W(x) (((x) >> 29) & 0x7)
+#define C_SQ_TEX_WORD2_SRC_SEL_W 0x1FFFFFFF
+#define P_SQ_ALU_WORD1_OP2_V2
+#define S_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x) (((x) & 0x1) << 0)
+#define G_SQ_ALU_WORD1_OP2_V2_SRC0_ABS(x) (((x) >> 0) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_SRC0_ABS 0xFFFFFFFE
+#define S_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x) (((x) & 0x1) << 1)
+#define G_SQ_ALU_WORD1_OP2_V2_SRC1_ABS(x) (((x) >> 1) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_SRC1_ABS 0xFFFFFFFD
+#define S_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x) (((x) & 0x1) << 2)
+#define G_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK(x) (((x) >> 2) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_UPDATE_EXECUTE_MASK 0xFFFFFFFB
+#define S_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x) (((x) & 0x1) << 3)
+#define G_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED(x) (((x) >> 3) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_UPDATE_PRED 0xFFFFFFF7
+#define S_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x) (((x) & 0x1) << 4)
+#define G_SQ_ALU_WORD1_OP2_V2_WRITE_MASK(x) (((x) >> 4) & 0x1)
+#define C_SQ_ALU_WORD1_OP2_V2_WRITE_MASK 0xFFFFFFEF
+#define S_SQ_ALU_WORD1_OP2_V2_OMOD(x) (((x) & 0x3) << 5)
+#define G_SQ_ALU_WORD1_OP2_V2_OMOD(x) (((x) >> 5) & 0x3)
+#define C_SQ_ALU_WORD1_OP2_V2_OMOD 0xFFFFFF9F
+#define S_SQ_ALU_WORD1_OP2_V2_ALU_INST(x) (((x) & 0x7FF) << 7)
+#define G_SQ_ALU_WORD1_OP2_V2_ALU_INST(x) (((x) >> 7) & 0x7FF)
+#define C_SQ_ALU_WORD1_OP2_V2_ALU_INST 0xFFFC007F
+
+#endif
diff --git a/src/gallium/drivers/r600/radeon.h b/src/gallium/drivers/r600/radeon.h
new file mode 100644
index 0000000000..ec94b112d6
--- /dev/null
+++ b/src/gallium/drivers/r600/radeon.h
@@ -0,0 +1,602 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef RADEON_H
+#define RADEON_H
+
+#define RADEON_CTX_MAX_PM4 (64 * 1024 / 4)
+
+#include <stdint.h>
+
+typedef uint64_t u64;
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+
+struct radeon;
+
+struct pipe_screen *radeon_create_screen(struct radeon *rw);
+
+enum radeon_family {
+ CHIP_UNKNOWN,
+ CHIP_R100,
+ CHIP_RV100,
+ CHIP_RS100,
+ CHIP_RV200,
+ CHIP_RS200,
+ CHIP_R200,
+ CHIP_RV250,
+ CHIP_RS300,
+ CHIP_RV280,
+ CHIP_R300,
+ CHIP_R350,
+ CHIP_RV350,
+ CHIP_RV380,
+ CHIP_R420,
+ CHIP_R423,
+ CHIP_RV410,
+ CHIP_RS400,
+ CHIP_RS480,
+ CHIP_RS600,
+ CHIP_RS690,
+ CHIP_RS740,
+ CHIP_RV515,
+ CHIP_R520,
+ CHIP_RV530,
+ CHIP_RV560,
+ CHIP_RV570,
+ CHIP_R580,
+ CHIP_R600,
+ CHIP_RV610,
+ CHIP_RV630,
+ CHIP_RV670,
+ CHIP_RV620,
+ CHIP_RV635,
+ CHIP_RS780,
+ CHIP_RS880,
+ CHIP_RV770,
+ CHIP_RV730,
+ CHIP_RV710,
+ CHIP_RV740,
+ CHIP_CEDAR,
+ CHIP_REDWOOD,
+ CHIP_JUNIPER,
+ CHIP_CYPRESS,
+ CHIP_HEMLOCK,
+ CHIP_LAST,
+};
+
+/*
+ * radeon object functions
+ */
+struct radeon_bo {
+ unsigned refcount;
+ unsigned handle;
+ unsigned size;
+ unsigned alignment;
+ unsigned map_count;
+ void *data;
+};
+struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
+ unsigned size, unsigned alignment, void *ptr);
+int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo);
+void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo);
+struct radeon_bo *radeon_bo_incref(struct radeon *radeon, struct radeon_bo *bo);
+struct radeon_bo *radeon_bo_decref(struct radeon *radeon, struct radeon_bo *bo);
+int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo);
+
+/*
+ * states functions
+ */
+struct radeon_state {
+ struct radeon *radeon;
+ unsigned refcount;
+ unsigned type;
+ unsigned id;
+ unsigned nstates;
+ u32 *states;
+ unsigned npm4;
+ unsigned cpm4;
+ u32 pm4_crc;
+ u32 *pm4;
+ u32 nimmd;
+ u32 *immd;
+ unsigned nbo;
+ struct radeon_bo *bo[4];
+ unsigned nreloc;
+ unsigned reloc_pm4_id[8];
+ unsigned reloc_bo_id[8];
+ u32 placement[8];
+ unsigned bo_dirty[4];
+};
+
+struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id);
+struct radeon_state *radeon_state_incref(struct radeon_state *state);
+struct radeon_state *radeon_state_decref(struct radeon_state *state);
+int radeon_state_pm4(struct radeon_state *state);
+
+/*
+ * draw functions
+ */
+struct radeon_draw {
+ unsigned refcount;
+ struct radeon *radeon;
+ unsigned nstate;
+ struct radeon_state **state;
+ unsigned cpm4;
+};
+
+struct radeon_draw *radeon_draw(struct radeon *radeon);
+struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw);
+struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw);
+struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw);
+int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state);
+int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state);
+int radeon_draw_check(struct radeon_draw *draw);
+
+struct radeon_ctx *radeon_ctx(struct radeon *radeon);
+struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx);
+struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx);
+int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw);
+int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw);
+int radeon_ctx_pm4(struct radeon_ctx *ctx);
+int radeon_ctx_submit(struct radeon_ctx *ctx);
+void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file);
+
+/*
+ * R600/R700
+ */
+
+#define R600_NSTATE 1273
+#define R600_NTYPE 25
+
+#define R600_CONFIG 0
+#define R600_CONFIG_TYPE 0
+#define R600_CB_CNTL 1
+#define R600_CB_CNTL_TYPE 1
+#define R600_RASTERIZER 2
+#define R600_RASTERIZER_TYPE 2
+#define R600_VIEWPORT 3
+#define R600_VIEWPORT_TYPE 3
+#define R600_SCISSOR 4
+#define R600_SCISSOR_TYPE 4
+#define R600_BLEND 5
+#define R600_BLEND_TYPE 5
+#define R600_DSA 6
+#define R600_DSA_TYPE 6
+#define R600_VS_SHADER 7
+#define R600_VS_SHADER_TYPE 7
+#define R600_PS_SHADER 8
+#define R600_PS_SHADER_TYPE 8
+#define R600_PS_CONSTANT 9
+#define R600_PS_CONSTANT_TYPE 9
+#define R600_VS_CONSTANT 265
+#define R600_VS_CONSTANT_TYPE 10
+#define R600_PS_RESOURCE 521
+#define R600_PS_RESOURCE_TYPE 11
+#define R600_VS_RESOURCE 681
+#define R600_VS_RESOURCE_TYPE 12
+#define R600_FS_RESOURCE 841
+#define R600_FS_RESOURCE_TYPE 13
+#define R600_GS_RESOURCE 1001
+#define R600_GS_RESOURCE_TYPE 14
+#define R600_PS_SAMPLER 1161
+#define R600_PS_SAMPLER_TYPE 15
+#define R600_VS_SAMPLER 1179
+#define R600_VS_SAMPLER_TYPE 16
+#define R600_GS_SAMPLER 1197
+#define R600_GS_SAMPLER_TYPE 17
+#define R600_PS_SAMPLER_BORDER 1215
+#define R600_PS_SAMPLER_BORDER_TYPE 18
+#define R600_VS_SAMPLER_BORDER 1233
+#define R600_VS_SAMPLER_BORDER_TYPE 19
+#define R600_GS_SAMPLER_BORDER 1251
+#define R600_GS_SAMPLER_BORDER_TYPE 20
+#define R600_CB0 1269
+#define R600_CB0_TYPE 21
+#define R600_DB 1270
+#define R600_DB_TYPE 22
+#define R600_VGT 1271
+#define R600_VGT_TYPE 23
+#define R600_DRAW 1272
+#define R600_DRAW_TYPE 24
+/* R600_CONFIG */
+#define R600_CONFIG__SQ_CONFIG 0
+#define R600_CONFIG__SQ_GPR_RESOURCE_MGMT_1 1
+#define R600_CONFIG__SQ_GPR_RESOURCE_MGMT_2 2
+#define R600_CONFIG__SQ_THREAD_RESOURCE_MGMT 3
+#define R600_CONFIG__SQ_STACK_RESOURCE_MGMT_1 4
+#define R600_CONFIG__SQ_STACK_RESOURCE_MGMT_2 5
+#define R600_CONFIG__SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 6
+#define R600_CONFIG__TA_CNTL_AUX 7
+#define R600_CONFIG__VC_ENHANCE 8
+#define R600_CONFIG__DB_DEBUG 9
+#define R600_CONFIG__DB_WATERMARKS 10
+#define R600_CONFIG__SX_MISC 11
+#define R600_CONFIG__SPI_THREAD_GROUPING 12
+#define R600_CONFIG__CB_SHADER_CONTROL 13
+#define R600_CONFIG__SQ_ESGS_RING_ITEMSIZE 14
+#define R600_CONFIG__SQ_GSVS_RING_ITEMSIZE 15
+#define R600_CONFIG__SQ_ESTMP_RING_ITEMSIZE 16
+#define R600_CONFIG__SQ_GSTMP_RING_ITEMSIZE 17
+#define R600_CONFIG__SQ_VSTMP_RING_ITEMSIZE 18
+#define R600_CONFIG__SQ_PSTMP_RING_ITEMSIZE 19
+#define R600_CONFIG__SQ_FBUF_RING_ITEMSIZE 20
+#define R600_CONFIG__SQ_REDUC_RING_ITEMSIZE 21
+#define R600_CONFIG__SQ_GS_VERT_ITEMSIZE 22
+#define R600_CONFIG__VGT_OUTPUT_PATH_CNTL 23
+#define R600_CONFIG__VGT_HOS_CNTL 24
+#define R600_CONFIG__VGT_HOS_MAX_TESS_LEVEL 25
+#define R600_CONFIG__VGT_HOS_MIN_TESS_LEVEL 26
+#define R600_CONFIG__VGT_HOS_REUSE_DEPTH 27
+#define R600_CONFIG__VGT_GROUP_PRIM_TYPE 28
+#define R600_CONFIG__VGT_GROUP_FIRST_DECR 29
+#define R600_CONFIG__VGT_GROUP_DECR 30
+#define R600_CONFIG__VGT_GROUP_VECT_0_CNTL 31
+#define R600_CONFIG__VGT_GROUP_VECT_1_CNTL 32
+#define R600_CONFIG__VGT_GROUP_VECT_0_FMT_CNTL 33
+#define R600_CONFIG__VGT_GROUP_VECT_1_FMT_CNTL 34
+#define R600_CONFIG__VGT_GS_MODE 35
+#define R600_CONFIG__PA_SC_MODE_CNTL 36
+#define R600_CONFIG__VGT_STRMOUT_EN 37
+#define R600_CONFIG__VGT_REUSE_OFF 38
+#define R600_CONFIG__VGT_VTX_CNT_EN 39
+#define R600_CONFIG__VGT_STRMOUT_BUFFER_EN 40
+#define R600_CONFIG_SIZE 41
+#define R600_CONFIG_PM4 128
+/* R600_CB_CNTL */
+#define R600_CB_CNTL__CB_CLEAR_RED 0
+#define R600_CB_CNTL__CB_CLEAR_GREEN 1
+#define R600_CB_CNTL__CB_CLEAR_BLUE 2
+#define R600_CB_CNTL__CB_CLEAR_ALPHA 3
+#define R600_CB_CNTL__CB_SHADER_MASK 4
+#define R600_CB_CNTL__CB_TARGET_MASK 5
+#define R600_CB_CNTL__CB_FOG_RED 6
+#define R600_CB_CNTL__CB_FOG_GREEN 7
+#define R600_CB_CNTL__CB_FOG_BLUE 8
+#define R600_CB_CNTL__CB_COLOR_CONTROL 9
+#define R600_CB_CNTL__PA_SC_AA_CONFIG 10
+#define R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_MCTX 11
+#define R600_CB_CNTL__PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX 12
+#define R600_CB_CNTL__CB_CLRCMP_CONTROL 13
+#define R600_CB_CNTL__CB_CLRCMP_SRC 14
+#define R600_CB_CNTL__CB_CLRCMP_DST 15
+#define R600_CB_CNTL__CB_CLRCMP_MSK 16
+#define R600_CB_CNTL__PA_SC_AA_MASK 17
+#define R600_CB_CNTL_SIZE 18
+#define R600_CB_CNTL_PM4 128
+/* R600_RASTERIZER */
+#define R600_RASTERIZER__SPI_INTERP_CONTROL_0 0
+#define R600_RASTERIZER__PA_CL_CLIP_CNTL 1
+#define R600_RASTERIZER__PA_SU_SC_MODE_CNTL 2
+#define R600_RASTERIZER__PA_CL_VS_OUT_CNTL 3
+#define R600_RASTERIZER__PA_CL_NANINF_CNTL 4
+#define R600_RASTERIZER__PA_SU_POINT_SIZE 5
+#define R600_RASTERIZER__PA_SU_POINT_MINMAX 6
+#define R600_RASTERIZER__PA_SU_LINE_CNTL 7
+#define R600_RASTERIZER__PA_SC_LINE_STIPPLE 8
+#define R600_RASTERIZER__PA_SC_MPASS_PS_CNTL 9
+#define R600_RASTERIZER__PA_SC_LINE_CNTL 10
+#define R600_RASTERIZER__PA_CL_GB_VERT_CLIP_ADJ 11
+#define R600_RASTERIZER__PA_CL_GB_VERT_DISC_ADJ 12
+#define R600_RASTERIZER__PA_CL_GB_HORZ_CLIP_ADJ 13
+#define R600_RASTERIZER__PA_CL_GB_HORZ_DISC_ADJ 14
+#define R600_RASTERIZER__PA_SU_POLY_OFFSET_DB_FMT_CNTL 15
+#define R600_RASTERIZER__PA_SU_POLY_OFFSET_CLAMP 16
+#define R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_SCALE 17
+#define R600_RASTERIZER__PA_SU_POLY_OFFSET_FRONT_OFFSET 18
+#define R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_SCALE 19
+#define R600_RASTERIZER__PA_SU_POLY_OFFSET_BACK_OFFSET 20
+#define R600_RASTERIZER_SIZE 21
+#define R600_RASTERIZER_PM4 128
+/* R600_VIEWPORT */
+#define R600_VIEWPORT__PA_SC_VPORT_ZMIN_0 0
+#define R600_VIEWPORT__PA_SC_VPORT_ZMAX_0 1
+#define R600_VIEWPORT__PA_CL_VPORT_XSCALE_0 2
+#define R600_VIEWPORT__PA_CL_VPORT_YSCALE_0 3
+#define R600_VIEWPORT__PA_CL_VPORT_ZSCALE_0 4
+#define R600_VIEWPORT__PA_CL_VPORT_XOFFSET_0 5
+#define R600_VIEWPORT__PA_CL_VPORT_YOFFSET_0 6
+#define R600_VIEWPORT__PA_CL_VPORT_ZOFFSET_0 7
+#define R600_VIEWPORT__PA_CL_VTE_CNTL 8
+#define R600_VIEWPORT_SIZE 9
+#define R600_VIEWPORT_PM4 128
+/* R600_SCISSOR */
+#define R600_SCISSOR__PA_SC_SCREEN_SCISSOR_TL 0
+#define R600_SCISSOR__PA_SC_SCREEN_SCISSOR_BR 1
+#define R600_SCISSOR__PA_SC_WINDOW_OFFSET 2
+#define R600_SCISSOR__PA_SC_WINDOW_SCISSOR_TL 3
+#define R600_SCISSOR__PA_SC_WINDOW_SCISSOR_BR 4
+#define R600_SCISSOR__PA_SC_CLIPRECT_RULE 5
+#define R600_SCISSOR__PA_SC_CLIPRECT_0_TL 6
+#define R600_SCISSOR__PA_SC_CLIPRECT_0_BR 7
+#define R600_SCISSOR__PA_SC_CLIPRECT_1_TL 8
+#define R600_SCISSOR__PA_SC_CLIPRECT_1_BR 9
+#define R600_SCISSOR__PA_SC_CLIPRECT_2_TL 10
+#define R600_SCISSOR__PA_SC_CLIPRECT_2_BR 11
+#define R600_SCISSOR__PA_SC_CLIPRECT_3_TL 12
+#define R600_SCISSOR__PA_SC_CLIPRECT_3_BR 13
+#define R600_SCISSOR__PA_SC_EDGERULE 14
+#define R600_SCISSOR__PA_SC_GENERIC_SCISSOR_TL 15
+#define R600_SCISSOR__PA_SC_GENERIC_SCISSOR_BR 16
+#define R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_TL 17
+#define R600_SCISSOR__PA_SC_VPORT_SCISSOR_0_BR 18
+#define R600_SCISSOR_SIZE 19
+#define R600_SCISSOR_PM4 128
+/* R600_BLEND */
+#define R600_BLEND__CB_BLEND_RED 0
+#define R600_BLEND__CB_BLEND_GREEN 1
+#define R600_BLEND__CB_BLEND_BLUE 2
+#define R600_BLEND__CB_BLEND_ALPHA 3
+#define R600_BLEND__CB_BLEND0_CONTROL 4
+#define R600_BLEND__CB_BLEND1_CONTROL 5
+#define R600_BLEND__CB_BLEND2_CONTROL 6
+#define R600_BLEND__CB_BLEND3_CONTROL 7
+#define R600_BLEND__CB_BLEND4_CONTROL 8
+#define R600_BLEND__CB_BLEND5_CONTROL 9
+#define R600_BLEND__CB_BLEND6_CONTROL 10
+#define R600_BLEND__CB_BLEND7_CONTROL 11
+#define R600_BLEND__CB_BLEND_CONTROL 12
+#define R600_BLEND_SIZE 13
+#define R600_BLEND_PM4 128
+/* R600_DSA */
+#define R600_DSA__DB_STENCIL_CLEAR 0
+#define R600_DSA__DB_DEPTH_CLEAR 1
+#define R600_DSA__SX_ALPHA_TEST_CONTROL 2
+#define R600_DSA__DB_STENCILREFMASK 3
+#define R600_DSA__DB_STENCILREFMASK_BF 4
+#define R600_DSA__SX_ALPHA_REF 5
+#define R600_DSA__SPI_FOG_FUNC_SCALE 6
+#define R600_DSA__SPI_FOG_FUNC_BIAS 7
+#define R600_DSA__SPI_FOG_CNTL 8
+#define R600_DSA__DB_DEPTH_CONTROL 9
+#define R600_DSA__DB_SHADER_CONTROL 10
+#define R600_DSA__DB_RENDER_CONTROL 11
+#define R600_DSA__DB_RENDER_OVERRIDE 12
+#define R600_DSA__DB_SRESULTS_COMPARE_STATE1 13
+#define R600_DSA__DB_PRELOAD_CONTROL 14
+#define R600_DSA__DB_ALPHA_TO_MASK 15
+#define R600_DSA_SIZE 16
+#define R600_DSA_PM4 128
+/* R600_VS_SHADER */
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_0 0
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_1 1
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_2 2
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_3 3
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_4 4
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_5 5
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_6 6
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_7 7
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_8 8
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_9 9
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_10 10
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_11 11
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_12 12
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_13 13
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_14 14
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_15 15
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_16 16
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_17 17
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_18 18
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_19 19
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_20 20
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_21 21
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_22 22
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_23 23
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_24 24
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_25 25
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_26 26
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_27 27
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_28 28
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_29 29
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_30 30
+#define R600_VS_SHADER__SQ_VTX_SEMANTIC_31 31
+#define R600_VS_SHADER__SPI_VS_OUT_ID_0 32
+#define R600_VS_SHADER__SPI_VS_OUT_ID_1 33
+#define R600_VS_SHADER__SPI_VS_OUT_ID_2 34
+#define R600_VS_SHADER__SPI_VS_OUT_ID_3 35
+#define R600_VS_SHADER__SPI_VS_OUT_ID_4 36
+#define R600_VS_SHADER__SPI_VS_OUT_ID_5 37
+#define R600_VS_SHADER__SPI_VS_OUT_ID_6 38
+#define R600_VS_SHADER__SPI_VS_OUT_ID_7 39
+#define R600_VS_SHADER__SPI_VS_OUT_ID_8 40
+#define R600_VS_SHADER__SPI_VS_OUT_ID_9 41
+#define R600_VS_SHADER__SPI_VS_OUT_CONFIG 42
+#define R600_VS_SHADER__SQ_PGM_START_VS 43
+#define R600_VS_SHADER__SQ_PGM_RESOURCES_VS 44
+#define R600_VS_SHADER__SQ_PGM_START_FS 45
+#define R600_VS_SHADER__SQ_PGM_RESOURCES_FS 46
+#define R600_VS_SHADER__SQ_PGM_CF_OFFSET_VS 47
+#define R600_VS_SHADER__SQ_PGM_CF_OFFSET_FS 48
+#define R600_VS_SHADER_SIZE 49
+#define R600_VS_SHADER_PM4 128
+/* R600_PS_SHADER */
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_0 0
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_1 1
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_2 2
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_3 3
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_4 4
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_5 5
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_6 6
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_7 7
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_8 8
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_9 9
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_10 10
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_11 11
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_12 12
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_13 13
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_14 14
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_15 15
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_16 16
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_17 17
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_18 18
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_19 19
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_20 20
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_21 21
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_22 22
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_23 23
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_24 24
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_25 25
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_26 26
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_27 27
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_28 28
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_29 29
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_30 30
+#define R600_PS_SHADER__SPI_PS_INPUT_CNTL_31 31
+#define R600_PS_SHADER__SPI_PS_IN_CONTROL_0 32
+#define R600_PS_SHADER__SPI_PS_IN_CONTROL_1 33
+#define R600_PS_SHADER__SPI_INPUT_Z 34
+#define R600_PS_SHADER__SQ_PGM_START_PS 35
+#define R600_PS_SHADER__SQ_PGM_RESOURCES_PS 36
+#define R600_PS_SHADER__SQ_PGM_EXPORTS_PS 37
+#define R600_PS_SHADER__SQ_PGM_CF_OFFSET_PS 38
+#define R600_PS_SHADER_SIZE 39
+#define R600_PS_SHADER_PM4 128
+/* R600_PS_CONSTANT */
+#define R600_PS_CONSTANT__SQ_ALU_CONSTANT0_0 0
+#define R600_PS_CONSTANT__SQ_ALU_CONSTANT1_0 1
+#define R600_PS_CONSTANT__SQ_ALU_CONSTANT2_0 2
+#define R600_PS_CONSTANT__SQ_ALU_CONSTANT3_0 3
+#define R600_PS_CONSTANT_SIZE 4
+#define R600_PS_CONSTANT_PM4 128
+/* R600_VS_CONSTANT */
+#define R600_VS_CONSTANT__SQ_ALU_CONSTANT0_256 0
+#define R600_VS_CONSTANT__SQ_ALU_CONSTANT1_256 1
+#define R600_VS_CONSTANT__SQ_ALU_CONSTANT2_256 2
+#define R600_VS_CONSTANT__SQ_ALU_CONSTANT3_256 3
+#define R600_VS_CONSTANT_SIZE 4
+#define R600_VS_CONSTANT_PM4 128
+/* R600_PS_RESOURCE */
+#define R600_PS_RESOURCE__RESOURCE0_WORD0 0
+#define R600_PS_RESOURCE__RESOURCE0_WORD1 1
+#define R600_PS_RESOURCE__RESOURCE0_WORD2 2
+#define R600_PS_RESOURCE__RESOURCE0_WORD3 3
+#define R600_PS_RESOURCE__RESOURCE0_WORD4 4
+#define R600_PS_RESOURCE__RESOURCE0_WORD5 5
+#define R600_PS_RESOURCE__RESOURCE0_WORD6 6
+#define R600_PS_RESOURCE_SIZE 7
+#define R600_PS_RESOURCE_PM4 128
+/* R600_VS_RESOURCE */
+#define R600_VS_RESOURCE__RESOURCE160_WORD0 0
+#define R600_VS_RESOURCE__RESOURCE160_WORD1 1
+#define R600_VS_RESOURCE__RESOURCE160_WORD2 2
+#define R600_VS_RESOURCE__RESOURCE160_WORD3 3
+#define R600_VS_RESOURCE__RESOURCE160_WORD4 4
+#define R600_VS_RESOURCE__RESOURCE160_WORD5 5
+#define R600_VS_RESOURCE__RESOURCE160_WORD6 6
+#define R600_VS_RESOURCE_SIZE 7
+#define R600_VS_RESOURCE_PM4 128
+/* R600_FS_RESOURCE */
+#define R600_FS_RESOURCE__RESOURCE320_WORD0 0
+#define R600_FS_RESOURCE__RESOURCE320_WORD1 1
+#define R600_FS_RESOURCE__RESOURCE320_WORD2 2
+#define R600_FS_RESOURCE__RESOURCE320_WORD3 3
+#define R600_FS_RESOURCE__RESOURCE320_WORD4 4
+#define R600_FS_RESOURCE__RESOURCE320_WORD5 5
+#define R600_FS_RESOURCE__RESOURCE320_WORD6 6
+#define R600_FS_RESOURCE_SIZE 7
+#define R600_FS_RESOURCE_PM4 128
+/* R600_GS_RESOURCE */
+#define R600_GS_RESOURCE__RESOURCE336_WORD0 0
+#define R600_GS_RESOURCE__RESOURCE336_WORD1 1
+#define R600_GS_RESOURCE__RESOURCE336_WORD2 2
+#define R600_GS_RESOURCE__RESOURCE336_WORD3 3
+#define R600_GS_RESOURCE__RESOURCE336_WORD4 4
+#define R600_GS_RESOURCE__RESOURCE336_WORD5 5
+#define R600_GS_RESOURCE__RESOURCE336_WORD6 6
+#define R600_GS_RESOURCE_SIZE 7
+#define R600_GS_RESOURCE_PM4 128
+/* R600_PS_SAMPLER */
+#define R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD0_0 0
+#define R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD1_0 1
+#define R600_PS_SAMPLER__SQ_TEX_SAMPLER_WORD2_0 2
+#define R600_PS_SAMPLER_SIZE 3
+#define R600_PS_SAMPLER_PM4 128
+/* R600_VS_SAMPLER */
+#define R600_VS_SAMPLER__SQ_TEX_SAMPLER_WORD0_18 0
+#define R600_VS_SAMPLER__SQ_TEX_SAMPLER_WORD1_18 1
+#define R600_VS_SAMPLER__SQ_TEX_SAMPLER_WORD2_18 2
+#define R600_VS_SAMPLER_SIZE 3
+#define R600_VS_SAMPLER_PM4 128
+/* R600_GS_SAMPLER */
+#define R600_GS_SAMPLER__SQ_TEX_SAMPLER_WORD0_36 0
+#define R600_GS_SAMPLER__SQ_TEX_SAMPLER_WORD1_36 1
+#define R600_GS_SAMPLER__SQ_TEX_SAMPLER_WORD2_36 2
+#define R600_GS_SAMPLER_SIZE 3
+#define R600_GS_SAMPLER_PM4 128
+/* R600_PS_SAMPLER_BORDER */
+#define R600_PS_SAMPLER_BORDER__TD_PS_SAMPLER0_BORDER_RED 0
+#define R600_PS_SAMPLER_BORDER__TD_PS_SAMPLER0_BORDER_GREEN 1
+#define R600_PS_SAMPLER_BORDER__TD_PS_SAMPLER0_BORDER_BLUE 2
+#define R600_PS_SAMPLER_BORDER__TD_PS_SAMPLER0_BORDER_ALPHA 3
+#define R600_PS_SAMPLER_BORDER_SIZE 4
+#define R600_PS_SAMPLER_BORDER_PM4 128
+/* R600_VS_SAMPLER_BORDER */
+#define R600_VS_SAMPLER_BORDER__TD_VS_SAMPLER0_BORDER_RED 0
+#define R600_VS_SAMPLER_BORDER__TD_VS_SAMPLER0_BORDER_GREEN 1
+#define R600_VS_SAMPLER_BORDER__TD_VS_SAMPLER0_BORDER_BLUE 2
+#define R600_VS_SAMPLER_BORDER__TD_VS_SAMPLER0_BORDER_ALPHA 3
+#define R600_VS_SAMPLER_BORDER_SIZE 4
+#define R600_VS_SAMPLER_BORDER_PM4 128
+/* R600_GS_SAMPLER_BORDER */
+#define R600_GS_SAMPLER_BORDER__TD_GS_SAMPLER0_BORDER_RED 0
+#define R600_GS_SAMPLER_BORDER__TD_GS_SAMPLER0_BORDER_GREEN 1
+#define R600_GS_SAMPLER_BORDER__TD_GS_SAMPLER0_BORDER_BLUE 2
+#define R600_GS_SAMPLER_BORDER__TD_GS_SAMPLER0_BORDER_ALPHA 3
+#define R600_GS_SAMPLER_BORDER_SIZE 4
+#define R600_GS_SAMPLER_BORDER_PM4 128
+/* R600_CB0 */
+#define R600_CB0__CB_COLOR0_BASE 0
+#define R600_CB0__CB_COLOR0_INFO 1
+#define R600_CB0__CB_COLOR0_SIZE 2
+#define R600_CB0__CB_COLOR0_VIEW 3
+#define R600_CB0__CB_COLOR0_FRAG 4
+#define R600_CB0__CB_COLOR0_TILE 5
+#define R600_CB0__CB_COLOR0_MASK 6
+#define R600_CB0_SIZE 7
+#define R600_CB0_PM4 128
+/* R600_DB */
+#define R600_DB__DB_DEPTH_BASE 0
+#define R600_DB__DB_DEPTH_SIZE 1
+#define R600_DB__DB_DEPTH_VIEW 2
+#define R600_DB__DB_DEPTH_INFO 3
+#define R600_DB__DB_HTILE_SURFACE 4
+#define R600_DB__DB_PREFETCH_LIMIT 5
+#define R600_DB_SIZE 6
+#define R600_DB_PM4 128
+/* R600_VGT */
+#define R600_VGT__VGT_PRIMITIVE_TYPE 0
+#define R600_VGT__VGT_MAX_VTX_INDX 1
+#define R600_VGT__VGT_MIN_VTX_INDX 2
+#define R600_VGT__VGT_INDX_OFFSET 3
+#define R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX 4
+#define R600_VGT__VGT_DMA_INDEX_TYPE 5
+#define R600_VGT__VGT_PRIMITIVEID_EN 6
+#define R600_VGT__VGT_DMA_NUM_INSTANCES 7
+#define R600_VGT__VGT_MULTI_PRIM_IB_RESET_EN 8
+#define R600_VGT__VGT_INSTANCE_STEP_RATE_0 9
+#define R600_VGT__VGT_INSTANCE_STEP_RATE_1 10
+#define R600_VGT_SIZE 11
+#define R600_VGT_PM4 128
+/* R600_DRAW */
+#define R600_DRAW__VGT_NUM_INDICES 0
+#define R600_DRAW__VGT_DMA_BASE_HI 1
+#define R600_DRAW__VGT_DMA_BASE 2
+#define R600_DRAW__VGT_DRAW_INITIATOR 3
+#define R600_DRAW_SIZE 4
+#define R600_DRAW_PM4 128
+
+#endif
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 4e66468301..cb59040395 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -189,7 +189,8 @@ softpipe_is_format_supported( struct pipe_screen *screen,
struct sw_winsys *winsys = softpipe_screen(screen)->winsys;
const struct util_format_description *format_desc;
- assert(target == PIPE_TEXTURE_1D ||
+ assert(target == PIPE_BUFFER ||
+ target == PIPE_TEXTURE_1D ||
target == PIPE_TEXTURE_2D ||
target == PIPE_TEXTURE_3D ||
target == PIPE_TEXTURE_CUBE);
diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c
index 75d8afb2ea..3b30b9e341 100644
--- a/src/gallium/drivers/svga/svga_context.c
+++ b/src/gallium/drivers/svga/svga_context.c
@@ -239,3 +239,8 @@ void svga_hwtnl_flush_retry( struct svga_context *svga )
assert(ret == 0);
}
+struct svga_winsys_context *
+svga_winsys_context( struct pipe_context *pipe )
+{
+ return svga_context( pipe )->swc;
+}
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 099d8f91df..54d9faeb72 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -43,21 +43,21 @@
int SVGA_DEBUG = 0;
static const struct debug_named_value svga_debug_flags[] = {
- { "dma", DEBUG_DMA },
- { "tgsi", DEBUG_TGSI },
- { "pipe", DEBUG_PIPE },
- { "state", DEBUG_STATE },
- { "screen", DEBUG_SCREEN },
- { "tex", DEBUG_TEX },
- { "swtnl", DEBUG_SWTNL },
- { "const", DEBUG_CONSTS },
- { "viewport", DEBUG_VIEWPORT },
- { "views", DEBUG_VIEWS },
- { "perf", DEBUG_PERF },
- { "flush", DEBUG_FLUSH },
- { "sync", DEBUG_SYNC },
- { "cache", DEBUG_CACHE },
- {NULL, 0}
+ { "dma", DEBUG_DMA, NULL },
+ { "tgsi", DEBUG_TGSI, NULL },
+ { "pipe", DEBUG_PIPE, NULL },
+ { "state", DEBUG_STATE, NULL },
+ { "screen", DEBUG_SCREEN, NULL },
+ { "tex", DEBUG_TEX, NULL },
+ { "swtnl", DEBUG_SWTNL, NULL },
+ { "const", DEBUG_CONSTS, NULL },
+ { "viewport", DEBUG_VIEWPORT, NULL },
+ { "views", DEBUG_VIEWS, NULL },
+ { "perf", DEBUG_PERF, NULL },
+ { "flush", DEBUG_FLUSH, NULL },
+ { "sync", DEBUG_SYNC, NULL },
+ { "cache", DEBUG_CACHE, NULL },
+ DEBUG_NAMED_VALUE_END
};
#endif
diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h
index c155f5dae2..a2dcc84f7d 100644
--- a/src/gallium/drivers/svga/svga_winsys.h
+++ b/src/gallium/drivers/svga/svga_winsys.h
@@ -294,6 +294,9 @@ svga_screen_create(struct svga_winsys_screen *sws);
struct svga_winsys_screen *
svga_winsys_screen(struct pipe_screen *screen);
+struct svga_winsys_context *
+svga_winsys_context(struct pipe_context *context);
+
struct pipe_resource *
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
enum SVGA3dSurfaceFormat format,
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 7584b8d437..9ca916fe7b 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1407,9 +1407,9 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
static const struct debug_named_value rbug_blocker_flags[] = {
- {"before", 1},
- {"after", 2},
- {NULL, 0},
+ {"before", 1, NULL},
+ {"after", 2, NULL},
+ DEBUG_NAMED_VALUE_END
};
struct pipe_context *
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index 9b31555f1b..a14486a5fb 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -102,6 +102,8 @@ typedef unsigned char boolean;
#ifndef PUBLIC
# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define PUBLIC __attribute__((visibility("default")))
+# elif defined(_MSC_VER)
+# define PUBLIC __declspec(dllexport)
# else
# define PUBLIC
# endif
diff --git a/src/gallium/state_trackers/dri/common/dri_context.h b/src/gallium/state_trackers/dri/common/dri_context.h
index 54e56c6499..b29e853383 100644
--- a/src/gallium/state_trackers/dri/common/dri_context.h
+++ b/src/gallium/state_trackers/dri/common/dri_context.h
@@ -65,6 +65,8 @@ struct dri_context
static INLINE struct dri_context *
dri_context(__DRIcontext * driContextPriv)
{
+ if (!driContextPriv)
+ return NULL;
return (struct dri_context *)driContextPriv->driverPrivate;
}
diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript
index 965dc95760..0c279d2236 100644
--- a/src/gallium/state_trackers/dri/drm/SConscript
+++ b/src/gallium/state_trackers/dri/drm/SConscript
@@ -22,7 +22,6 @@ if env['dri']:
'dri_drawable.c',
'dri_screen.c',
'dri1_helper.c',
- 'dri1.c',
'dri2.c',
]
)
diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript
new file mode 100644
index 0000000000..c4d01d6b28
--- /dev/null
+++ b/src/gallium/state_trackers/egl/SConscript
@@ -0,0 +1,32 @@
+#######################################################################
+# SConscript for egl state_tracker
+
+Import('*')
+
+if 'egl' in env['statetrackers']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/egl/main',
+ '#/src/gallium/winsys/sw',
+ '.',
+ ])
+
+ common_sources = [
+ 'common/egl_g3d.c',
+ 'common/egl_g3d_api.c',
+ 'common/egl_g3d_image.c',
+ 'common/egl_g3d_st.c',
+ 'common/native_helper.c',
+ ]
+
+ gdi_sources = common_sources + [
+ 'gdi/native_gdi.c',
+ ]
+
+ st_egl_gdi = env.ConvenienceLibrary(
+ target = 'st_egl_gdi',
+ source = gdi_sources,
+ )
+ Export('st_egl_gdi')
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c
index d63b81a1c5..361cc7960b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.c
@@ -426,7 +426,7 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
}
static struct native_event_handler egl_g3d_native_event_handler = {
- .invalid_surface = egl_g3d_invalid_surface
+ egl_g3d_invalid_surface
};
static EGLBoolean
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h
index 5a3c80b968..d516d8fe03 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d.h
+++ b/src/gallium/state_trackers/egl/common/egl_g3d.h
@@ -75,6 +75,9 @@ struct egl_g3d_surface {
struct native_surface *native;
struct pipe_resource *render_texture;
+ EGLenum client_buffer_type;
+ EGLClientBuffer client_buffer;
+
unsigned int sequence_number;
};
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
index 4615a5829a..255a1fb730 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c
@@ -267,16 +267,16 @@ egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return egl_g3d_create_surface(drv, dpy, conf, &arg, attribs);
}
-static _EGLSurface *
-egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
- _EGLConfig *conf, const EGLint *attribs)
+static struct egl_g3d_surface *
+create_pbuffer_surface(_EGLDisplay *dpy, _EGLConfig *conf,
+ const EGLint *attribs, const char *func)
{
struct egl_g3d_config *gconf = egl_g3d_config(conf);
struct egl_g3d_surface *gsurf;
gsurf = CALLOC_STRUCT(egl_g3d_surface);
if (!gsurf) {
- _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ _eglError(EGL_BAD_ALLOC, func);
return NULL;
}
@@ -293,6 +293,96 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
return NULL;
}
+ return gsurf;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLConfig *conf, const EGLint *attribs)
+{
+ struct egl_g3d_surface *gsurf;
+ struct pipe_resource *ptex = NULL;
+
+ gsurf = create_pbuffer_surface(dpy, conf, attribs,
+ "eglCreatePbufferSurface");
+ if (!gsurf)
+ return NULL;
+
+ gsurf->client_buffer_type = EGL_NONE;
+
+ if (!gsurf->stfbi->validate(gsurf->stfbi,
+ &gsurf->stvis.render_buffer, 1, &ptex)) {
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+ FREE(gsurf);
+ return NULL;
+ }
+
+ return &gsurf->base;
+}
+
+static _EGLSurface *
+egl_g3d_create_pbuffer_from_client_buffer(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ _EGLConfig *conf,
+ const EGLint *attribs)
+{
+ struct egl_g3d_surface *gsurf;
+ struct pipe_resource *ptex = NULL;
+ EGLint pbuffer_attribs[32];
+ EGLint count, i;
+
+ switch (buftype) {
+ case EGL_OPENVG_IMAGE:
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
+ return NULL;
+ break;
+ }
+
+ /* parse the attributes first */
+ count = 0;
+ for (i = 0; attribs && attribs[i] != EGL_NONE; i++) {
+ EGLint attr = attribs[i++];
+ EGLint val = attribs[i];
+ EGLint err = EGL_SUCCESS;
+
+ switch (attr) {
+ case EGL_TEXTURE_FORMAT:
+ case EGL_TEXTURE_TARGET:
+ case EGL_MIPMAP_TEXTURE:
+ pbuffer_attribs[count++] = attr;
+ pbuffer_attribs[count++] = val;
+ break;
+ default:
+ err = EGL_BAD_ATTRIBUTE;
+ break;
+ }
+ /* bail out */
+ if (err != EGL_SUCCESS) {
+ _eglError(err, "eglCreatePbufferFromClientBuffer");
+ return NULL;
+ }
+ }
+
+ pbuffer_attribs[count++] = EGL_NONE;
+
+ gsurf = create_pbuffer_surface(dpy, conf, pbuffer_attribs,
+ "eglCreatePbufferFromClientBuffer");
+ if (!gsurf)
+ return NULL;
+
+ gsurf->client_buffer_type = buftype;
+ gsurf->client_buffer = buffer;
+
+ if (!gsurf->stfbi->validate(gsurf->stfbi,
+ &gsurf->stvis.render_buffer, 1, &ptex)) {
+ egl_g3d_destroy_st_framebuffer(gsurf->stfbi);
+ FREE(gsurf);
+ return NULL;
+ }
+
return &gsurf->base;
}
@@ -428,7 +518,6 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
_EGLContext *ctx = _eglGetCurrentContext();
struct egl_g3d_config *gconf;
struct native_surface *nsurf;
- struct pipe_screen *screen = gdpy->native->screen;
struct pipe_resource *ptex;
if (!gsurf->render_texture)
@@ -460,7 +549,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (ptex) {
- struct pipe_surface *psrc;
+ struct pipe_resource *psrc = gsurf->render_texture;
struct pipe_subresource subsrc, subdst;
subsrc.face = 0;
subsrc.level = 0;
@@ -704,6 +793,7 @@ egl_g3d_init_driver_api(_EGLDriver *drv)
drv->API.CreateWindowSurface = egl_g3d_create_window_surface;
drv->API.CreatePixmapSurface = egl_g3d_create_pixmap_surface;
drv->API.CreatePbufferSurface = egl_g3d_create_pbuffer_surface;
+ drv->API.CreatePbufferFromClientBuffer = egl_g3d_create_pbuffer_from_client_buffer;
drv->API.DestroySurface = egl_g3d_destroy_surface;
drv->API.MakeCurrent = egl_g3d_make_current;
drv->API.SwapBuffers = egl_g3d_swap_buffers;
diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
index cdf13140cb..e2217b3b2b 100644
--- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c
+++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c
@@ -29,6 +29,8 @@
#include "util/u_memory.h"
#include "util/u_string.h"
#include "util/u_inlines.h"
+#include "util/u_pointer.h"
+#include "util/u_format.h"
#include "util/u_dl.h"
#include "egldriver.h"
#include "eglimage.h"
@@ -62,6 +64,11 @@ egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data)
char path[1024];
int ret;
+ if (!len) {
+ stmod->lib = util_dl_open(stmod->filename);
+ return !(stmod->lib);
+ }
+
ret = util_snprintf(path, sizeof(path),
"%.*s/%s", len, dir, stmod->filename);
if (ret > 0 && ret < sizeof(path))
@@ -103,6 +110,12 @@ egl_g3d_load_st_module(struct egl_g3d_st_module *stmod,
}
}
+#ifdef PIPE_OS_WINDOWS
+#define ST_MODULE_SUFFIX ".dll"
+#else
+#define ST_MODULE_SUFFIX ".so"
+#endif
+
void
egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT])
{
@@ -121,24 +134,24 @@ egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT])
case ST_API_OPENGL:
skip_checks[api] = "glColor4d";
symbols[api] = ST_CREATE_OPENGL_SYMBOL;
- filenames[api][count++] = "api_GL.so";
+ filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
break;
case ST_API_OPENGL_ES1:
skip_checks[api] = "glColor4x";
symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL;
- filenames[api][count++] = "api_GLESv1_CM.so";
- filenames[api][count++] = "api_GL.so";
+ filenames[api][count++] = "api_GLESv1_CM" ST_MODULE_SUFFIX;
+ filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
break;
case ST_API_OPENGL_ES2:
skip_checks[api] = "glShaderBinary";
symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL;
- filenames[api][count++] = "api_GLESv2.so";
- filenames[api][count++] = "api_GL.so";
+ filenames[api][count++] = "api_GLESv2" ST_MODULE_SUFFIX;
+ filenames[api][count++] = "api_GL" ST_MODULE_SUFFIX;
break;
case ST_API_OPENVG:
skip_checks[api] = "vgClear";
symbols[api] = ST_CREATE_OPENVG_SYMBOL;
- filenames[api][count++]= "api_OpenVG.so";
+ filenames[api][count++]= "api_OpenVG" ST_MODULE_SUFFIX;
break;
default:
assert(!"Unknown API Type\n");
@@ -206,6 +219,7 @@ egl_g3d_destroy_st_apis(void)
static boolean
egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
+ struct st_context_iface *stctx,
void *egl_image,
struct st_egl_image *out)
{
@@ -275,7 +289,34 @@ egl_g3d_st_framebuffer_flush_front_pbuffer(struct st_framebuffer_iface *stfbi,
return TRUE;
}
-static boolean
+static void
+pbuffer_reference_openvg_image(struct egl_g3d_surface *gsurf)
+{
+ /* TODO */
+}
+
+static void
+pbuffer_allocate_render_texture(struct egl_g3d_surface *gsurf)
+{
+ struct egl_g3d_display *gdpy =
+ egl_g3d_display(gsurf->base.Resource.Display);
+ struct pipe_screen *screen = gdpy->native->screen;
+ struct pipe_resource templ, *ptex;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.last_level = 0;
+ templ.width0 = gsurf->base.Width;
+ templ.height0 = gsurf->base.Height;
+ templ.depth0 = 1;
+ templ.format = gsurf->stvis.color_format;
+ templ.bind = PIPE_BIND_RENDER_TARGET;
+
+ ptex = screen->resource_create(screen, &templ);
+ gsurf->render_texture = ptex;
+}
+
+static boolean
egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
const enum st_attachment_type *statts,
unsigned count,
@@ -283,7 +324,6 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
{
_EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private;
struct egl_g3d_surface *gsurf = egl_g3d_surface(surf);
- struct pipe_resource templ;
unsigned i;
for (i = 0; i < count; i++) {
@@ -293,20 +333,19 @@ egl_g3d_st_framebuffer_validate_pbuffer(struct st_framebuffer_iface *stfbi,
continue;
if (!gsurf->render_texture) {
- struct egl_g3d_display *gdpy =
- egl_g3d_display(gsurf->base.Resource.Display);
- struct pipe_screen *screen = gdpy->native->screen;
-
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.last_level = 0;
- templ.width0 = gsurf->base.Width;
- templ.height0 = gsurf->base.Height;
- templ.depth0 = 1;
- templ.format = gsurf->stvis.color_format;
- templ.bind = PIPE_BIND_RENDER_TARGET;
-
- gsurf->render_texture = screen->resource_create(screen, &templ);
+ switch (gsurf->client_buffer_type) {
+ case EGL_NONE:
+ pbuffer_allocate_render_texture(gsurf);
+ break;
+ case EGL_OPENVG_IMAGE:
+ pbuffer_reference_openvg_image(gsurf);
+ break;
+ default:
+ break;
+ }
+
+ if (!gsurf->render_texture)
+ return FALSE;
}
pipe_resource_reference(&out[i], gsurf->render_texture);
diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c
new file mode 100644
index 0000000000..7832b2b693
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_helper.c
@@ -0,0 +1,235 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+
+#include "native_helper.h"
+
+struct resource_surface {
+ struct pipe_screen *screen;
+ enum pipe_format format;
+ uint bind;
+
+ struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
+ struct pipe_surface *present_surfaces[NUM_NATIVE_ATTACHMENTS];
+ uint resource_mask;
+ uint width, height;
+};
+
+struct resource_surface *
+resource_surface_create(struct pipe_screen *screen,
+ enum pipe_format format, uint bind)
+{
+ struct resource_surface *rsurf = CALLOC_STRUCT(resource_surface);
+
+ if (rsurf) {
+ rsurf->screen = screen;
+ rsurf->format = format;
+ rsurf->bind = bind;
+ }
+
+ return rsurf;
+}
+
+static void
+resource_surface_free_resources(struct resource_surface *rsurf)
+{
+ if (rsurf->resource_mask) {
+ int i;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ if (rsurf->present_surfaces[i])
+ pipe_surface_reference(&rsurf->present_surfaces[i], NULL);
+ if (rsurf->resources[i])
+ pipe_resource_reference(&rsurf->resources[i], NULL);
+ }
+ rsurf->resource_mask = 0x0;
+ }
+}
+
+void
+resource_surface_destroy(struct resource_surface *rsurf)
+{
+ resource_surface_free_resources(rsurf);
+ FREE(rsurf);
+}
+
+boolean
+resource_surface_set_size(struct resource_surface *rsurf,
+ uint width, uint height)
+{
+ boolean changed = FALSE;
+
+ if (rsurf->width != width || rsurf->height != height) {
+ resource_surface_free_resources(rsurf);
+ rsurf->width = width;
+ rsurf->height = height;
+ changed = TRUE;
+ }
+
+ return changed;
+}
+
+void
+resource_surface_get_size(struct resource_surface *rsurf,
+ uint *width, uint *height)
+{
+ if (width)
+ *width = rsurf->width;
+ if (height)
+ *height = rsurf->height;
+}
+
+boolean
+resource_surface_add_resources(struct resource_surface *rsurf,
+ uint resource_mask)
+{
+ struct pipe_resource templ;
+ int i;
+
+ resource_mask &= ~rsurf->resource_mask;
+ if (!resource_mask)
+ return TRUE;
+
+ if (!rsurf->width || !rsurf->height)
+ return FALSE;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = rsurf->format;
+ templ.bind = rsurf->bind;
+ templ.width0 = rsurf->width;
+ templ.height0 = rsurf->height;
+ templ.depth0 = 1;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ if (resource_mask & (1 <<i)) {
+ assert(!rsurf->resources[i]);
+
+ rsurf->resources[i] =
+ rsurf->screen->resource_create(rsurf->screen, &templ);
+ if (rsurf->resources[i])
+ rsurf->resource_mask |= 1 << i;
+ }
+ }
+
+ return ((rsurf->resource_mask & resource_mask) == resource_mask);
+}
+
+
+void
+resource_surface_get_resources(struct resource_surface *rsurf,
+ struct pipe_resource **resources,
+ uint resource_mask)
+{
+ int i;
+
+ for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
+ if (resource_mask & (1 << i)) {
+ resources[i] = NULL;
+ pipe_resource_reference(&resources[i], rsurf->resources[i]);
+ }
+ }
+}
+
+struct pipe_resource *
+resource_surface_get_single_resource(struct resource_surface *rsurf,
+ enum native_attachment which)
+{
+ struct pipe_resource *pres = NULL;
+ pipe_resource_reference(&pres, rsurf->resources[which]);
+ return pres;
+}
+
+static INLINE void
+pointer_swap(const void **p1, const void **p2)
+{
+ const void *tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+}
+
+void
+resource_surface_swap_buffers(struct resource_surface *rsurf,
+ enum native_attachment buf1,
+ enum native_attachment buf2,
+ boolean only_if_exist)
+{
+ const uint buf1_bit = 1 << buf1;
+ const uint buf2_bit = 1 << buf2;
+ uint mask;
+
+ if (only_if_exist && !(rsurf->resources[buf1] && rsurf->resources[buf2]))
+ return;
+
+ pointer_swap((const void **) &rsurf->resources[buf1],
+ (const void **) &rsurf->resources[buf2]);
+ pointer_swap((const void **) &rsurf->present_surfaces[buf1],
+ (const void **) &rsurf->present_surfaces[buf2]);
+
+ /* swap mask bits */
+ mask = rsurf->resource_mask & ~(buf1_bit | buf2_bit);
+ if (rsurf->resource_mask & buf1_bit)
+ mask |= buf2_bit;
+ if (rsurf->resource_mask & buf2_bit)
+ mask |= buf1_bit;
+
+ rsurf->resource_mask = mask;
+}
+
+boolean
+resource_surface_present(struct resource_surface *rsurf,
+ enum native_attachment which,
+ void *winsys_drawable_handle)
+{
+ struct pipe_resource *pres = rsurf->resources[which];
+ struct pipe_surface *psurf = rsurf->present_surfaces[which];
+
+ if (!pres)
+ return TRUE;
+
+ if (!psurf) {
+ psurf = rsurf->screen->get_tex_surface(rsurf->screen,
+ pres, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
+ if (!psurf)
+ return FALSE;
+
+ rsurf->present_surfaces[which] = psurf;
+ }
+
+ assert(psurf->texture == pres);
+
+ rsurf->screen->flush_frontbuffer(rsurf->screen,
+ psurf, winsys_drawable_handle);
+
+ return TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/common/native_helper.h b/src/gallium/state_trackers/egl/common/native_helper.h
new file mode 100644
index 0000000000..62956d5220
--- /dev/null
+++ b/src/gallium/state_trackers/egl/common/native_helper.h
@@ -0,0 +1,70 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include "native.h"
+
+struct resource_surface;
+
+struct resource_surface *
+resource_surface_create(struct pipe_screen *screen,
+ enum pipe_format format, uint bind);
+
+void
+resource_surface_destroy(struct resource_surface *rsurf);
+
+boolean
+resource_surface_set_size(struct resource_surface *rsurf,
+ uint width, uint height);
+
+void
+resource_surface_get_size(struct resource_surface *rsurf,
+ uint *width, uint *height);
+
+boolean
+resource_surface_add_resources(struct resource_surface *rsurf,
+ uint resource_mask);
+
+void
+resource_surface_get_resources(struct resource_surface *rsurf,
+ struct pipe_resource **resources,
+ uint resource_mask);
+
+struct pipe_resource *
+resource_surface_get_single_resource(struct resource_surface *rsurf,
+ enum native_attachment which);
+
+void
+resource_surface_swap_buffers(struct resource_surface *rsurf,
+ enum native_attachment buf1,
+ enum native_attachment buf2,
+ boolean only_if_exist);
+
+boolean
+resource_surface_present(struct resource_surface *rsurf,
+ enum native_attachment which,
+ void *winsys_drawable_handle);
diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c
new file mode 100644
index 0000000000..29e89bcae8
--- /dev/null
+++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c
@@ -0,0 +1,427 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.9
+ *
+ * Copyright (C) 2010 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Chia-I Wu <olv@lunarg.com>
+ */
+
+#include <windows.h>
+
+#include "pipe/p_compiler.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "target-helpers/wrap_screen.h"
+#include "llvmpipe/lp_public.h"
+#include "softpipe/sp_public.h"
+#include "gdi/gdi_sw_winsys.h"
+
+#include "common/native_helper.h"
+#include "common/native.h"
+
+struct gdi_display {
+ struct native_display base;
+
+ HDC hDC;
+ struct native_event_handler *event_handler;
+
+ struct native_config *configs;
+ int num_configs;
+};
+
+struct gdi_surface {
+ struct native_surface base;
+
+ HWND hWnd;
+ enum pipe_format color_format;
+
+ struct gdi_display *gdpy;
+
+ unsigned int server_stamp;
+ unsigned int client_stamp;
+
+ struct resource_surface *rsurf;
+};
+
+static INLINE struct gdi_display *
+gdi_display(const struct native_display *ndpy)
+{
+ return (struct gdi_display *) ndpy;
+}
+
+static INLINE struct gdi_surface *
+gdi_surface(const struct native_surface *nsurf)
+{
+ return (struct gdi_surface *) nsurf;
+}
+
+/**
+ * Update the geometry of the surface. This is a slow functions.
+ */
+static void
+gdi_surface_update_geometry(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ RECT rect;
+ uint w, h;
+
+ GetClientRect(gsurf->hWnd, &rect);
+ w = rect.right - rect.left;
+ h = rect.bottom - rect.top;
+
+ if (resource_surface_set_size(gsurf->rsurf, w, h))
+ gsurf->server_stamp++;
+}
+
+/**
+ * Update the buffers of the surface.
+ */
+static boolean
+gdi_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+
+ if (gsurf->client_stamp != gsurf->server_stamp) {
+ gdi_surface_update_geometry(&gsurf->base);
+ gsurf->client_stamp = gsurf->server_stamp;
+ }
+
+ return resource_surface_add_resources(gsurf->rsurf, buffer_mask);
+}
+
+/**
+ * Emulate an invalidate event.
+ */
+static void
+gdi_surface_invalidate(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ struct gdi_display *gdpy = gsurf->gdpy;
+
+ gsurf->server_stamp++;
+ gdpy->event_handler->invalid_surface(&gdpy->base,
+ &gsurf->base, gsurf->server_stamp);
+}
+
+static boolean
+gdi_surface_flush_frontbuffer(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ HDC hDC;
+ boolean ret;
+
+ hDC = GetDC(gsurf->hWnd);
+ ret = resource_surface_present(gsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, (void *) hDC);
+ ReleaseDC(gsurf->hWnd, hDC);
+
+ /* force buffers to be updated in next validation call */
+ gdi_surface_invalidate(&gsurf->base);
+
+ return ret;
+}
+
+static boolean
+gdi_surface_swap_buffers(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ HDC hDC;
+ boolean ret;
+
+ hDC = GetDC(gsurf->hWnd);
+ ret = resource_surface_present(gsurf->rsurf,
+ NATIVE_ATTACHMENT_BACK_LEFT, (void *) hDC);
+ ReleaseDC(gsurf->hWnd, hDC);
+
+ resource_surface_swap_buffers(gsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
+ /* the front/back buffers have been swapped */
+ gdi_surface_invalidate(&gsurf->base);
+
+ return ret;
+}
+
+static boolean
+gdi_surface_validate(struct native_surface *nsurf, uint attachment_mask,
+ unsigned int *seq_num, struct pipe_resource **textures,
+ int *width, int *height)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+ uint w, h;
+
+ if (!gdi_surface_update_buffers(&gsurf->base, attachment_mask))
+ return FALSE;
+
+ if (seq_num)
+ *seq_num = gsurf->client_stamp;
+
+ if (textures)
+ resource_surface_get_resources(gsurf->rsurf, textures, attachment_mask);
+
+ resource_surface_get_size(gsurf->rsurf, &w, &h);
+ if (width)
+ *width = w;
+ if (height)
+ *height = h;
+
+ return TRUE;
+}
+
+static void
+gdi_surface_wait(struct native_surface *nsurf)
+{
+ /* no-op */
+}
+
+static void
+gdi_surface_destroy(struct native_surface *nsurf)
+{
+ struct gdi_surface *gsurf = gdi_surface(nsurf);
+
+ resource_surface_destroy(gsurf->rsurf);
+ FREE(gsurf);
+}
+
+static struct native_surface *
+gdi_display_create_window_surface(struct native_display *ndpy,
+ EGLNativeWindowType win,
+ const struct native_config *nconf)
+{
+ struct gdi_display *gdpy = gdi_display(ndpy);
+ struct gdi_surface *gsurf;
+
+ gsurf = CALLOC_STRUCT(gdi_surface);
+ if (!gsurf)
+ return NULL;
+
+ gsurf->gdpy = gdpy;
+ gsurf->color_format = nconf->color_format;
+ gsurf->hWnd = (HWND) win;
+
+ gsurf->rsurf = resource_surface_create(gdpy->base.screen,
+ gsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+ if (!gsurf->rsurf) {
+ FREE(gsurf);
+ return NULL;
+ }
+
+ /* initialize the geometry */
+ gdi_surface_update_geometry(&gsurf->base);
+
+ gsurf->base.destroy = gdi_surface_destroy;
+ gsurf->base.swap_buffers = gdi_surface_swap_buffers;
+ gsurf->base.flush_frontbuffer = gdi_surface_flush_frontbuffer;
+ gsurf->base.validate = gdi_surface_validate;
+ gsurf->base.wait = gdi_surface_wait;
+
+ return &gsurf->base;
+}
+
+static int
+fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8])
+{
+ struct pipe_screen *screen = ndpy->screen;
+ int i, count = 0;
+
+ enum pipe_format candidates[] = {
+ /* 32-bit */
+ PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_A8R8G8B8_UNORM,
+ /* 24-bit */
+ PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_X8R8G8B8_UNORM,
+ /* 16-bit */
+ PIPE_FORMAT_B5G6R5_UNORM
+ };
+
+ assert(Elements(candidates) <= 8);
+
+ for (i = 0; i < Elements(candidates); i++) {
+ if (screen->is_format_supported(screen, candidates[i],
+ PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0))
+ formats[count++] = candidates[i];
+ }
+
+ return count;
+}
+
+static const struct native_config **
+gdi_display_get_configs(struct native_display *ndpy, int *num_configs)
+{
+ struct gdi_display *gdpy = gdi_display(ndpy);
+ const struct native_config **configs;
+ int i;
+
+ /* first time */
+ if (!gdpy->configs) {
+ enum pipe_format formats[8];
+ int i, count;
+
+ count = fill_color_formats(&gdpy->base, formats);
+
+ gdpy->configs = CALLOC(count, sizeof(*gdpy->configs));
+ if (!gdpy->configs)
+ return NULL;
+
+ for (i = 0; i < count; i++) {
+ struct native_config *nconf = &gdpy->configs[i];
+
+ nconf->buffer_mask =
+ (1 << NATIVE_ATTACHMENT_FRONT_LEFT) |
+ (1 << NATIVE_ATTACHMENT_BACK_LEFT);
+ nconf->color_format = formats[i];
+
+ nconf->window_bit = TRUE;
+ nconf->slow_config = TRUE;
+ }
+
+ gdpy->num_configs = count;
+ }
+
+ configs = MALLOC(gdpy->num_configs * sizeof(*configs));
+ if (configs) {
+ for (i = 0; i < gdpy->num_configs; i++)
+ configs[i] = (const struct native_config *) &gdpy->configs[i];
+ if (num_configs)
+ *num_configs = gdpy->num_configs;
+ }
+ return configs;
+}
+
+static int
+gdi_display_get_param(struct native_display *ndpy,
+ enum native_param_type param)
+{
+ int val;
+
+ switch (param) {
+ case NATIVE_PARAM_USE_NATIVE_BUFFER:
+ /* private buffers are allocated */
+ val = FALSE;
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ return val;
+}
+
+static void
+gdi_display_destroy(struct native_display *ndpy)
+{
+ struct gdi_display *gdpy = gdi_display(ndpy);
+
+ if (gdpy->configs)
+ FREE(gdpy->configs);
+
+ gdpy->base.screen->destroy(gdpy->base.screen);
+
+ FREE(gdpy);
+}
+
+static struct native_display *
+gdi_create_display(HDC hDC, struct pipe_screen *screen,
+ struct native_event_handler *event_handler)
+{
+ struct gdi_display *gdpy;
+
+ gdpy = CALLOC_STRUCT(gdi_display);
+ if (!gdpy)
+ return NULL;
+
+ gdpy->hDC = hDC;
+ gdpy->event_handler = event_handler;
+
+ gdpy->base.screen = screen;
+
+ gdpy->base.destroy = gdi_display_destroy;
+ gdpy->base.get_param = gdi_display_get_param;
+
+ gdpy->base.get_configs = gdi_display_get_configs;
+ gdpy->base.create_window_surface = gdi_display_create_window_surface;
+
+ return &gdpy->base;
+}
+
+static struct pipe_screen *
+gdi_create_screen(void)
+{
+ struct sw_winsys *winsys;
+ struct pipe_screen *screen = NULL;
+
+ winsys = gdi_create_sw_winsys();
+ if (!winsys)
+ return NULL;
+
+#if defined(GALLIUM_LLVMPIPE)
+ if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
+ screen = llvmpipe_create_screen(winsys);
+#endif
+ if (!screen)
+ screen = softpipe_create_screen(winsys);
+
+ if (!screen) {
+ if (winsys->destroy)
+ winsys->destroy(winsys);
+ return NULL;
+ }
+
+ return gallium_wrap_screen(screen);
+}
+
+struct native_probe *
+native_create_probe(EGLNativeDisplayType dpy)
+{
+ return NULL;
+}
+
+enum native_probe_result
+native_get_probe_result(struct native_probe *nprobe)
+{
+ return NATIVE_PROBE_UNKNOWN;
+}
+
+const char *
+native_get_name(void)
+{
+ return "GDI";
+}
+
+struct native_display *
+native_create_display(EGLNativeDisplayType dpy,
+ struct native_event_handler *event_handler)
+{
+ struct pipe_screen *screen;
+
+ screen = gdi_create_screen();
+ if (!screen)
+ return NULL;
+
+ return gdi_create_display((HDC) dpy, screen, event_handler);
+}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.c b/src/gallium/state_trackers/egl/kms/native_kms.c
index d81178e559..bfb4a9d258 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.c
+++ b/src/gallium/state_trackers/egl/kms/native_kms.c
@@ -28,6 +28,7 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
+#include "util/u_pointer.h"
#include "util/u_string.h"
#include "egllog.h"
@@ -39,39 +40,11 @@ kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
int *width, int *height)
{
struct kms_surface *ksurf = kms_surface(nsurf);
- struct kms_display *kdpy = ksurf->kdpy;
- struct pipe_screen *screen = kdpy->base.screen;
- struct pipe_resource templ, *ptex;
- int att;
-
- if (attachment_mask) {
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.last_level = 0;
- templ.width0 = ksurf->width;
- templ.height0 = ksurf->height;
- templ.depth0 = 1;
- templ.format = ksurf->color_format;
- templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SCANOUT;
- }
-
- /* create textures */
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- /* delay the allocation */
- if (!native_attachment_mask_test(attachment_mask, att))
- continue;
-
- ptex = ksurf->textures[att];
- if (!ptex) {
- ptex = screen->resource_create(screen, &templ);
- ksurf->textures[att] = ptex;
- }
- if (textures) {
- textures[att] = NULL;
- pipe_resource_reference(&textures[att], ptex);
- }
- }
+ if (!resource_surface_add_resources(ksurf->rsurf, attachment_mask))
+ return FALSE;
+ if (textures)
+ resource_surface_get_resources(ksurf->rsurf, textures, attachment_mask);
if (seq_num)
*seq_num = ksurf->sequence_number;
@@ -111,11 +84,11 @@ kms_surface_init_framebuffers(struct native_surface *nsurf, boolean need_back)
if (!fb->texture) {
/* make sure the texture has been allocated */
- kms_surface_validate(&ksurf->base, 1 << natt, NULL, NULL, NULL, NULL);
- if (!ksurf->textures[natt])
+ resource_surface_add_resources(ksurf->rsurf, 1 << natt);
+ fb->texture =
+ resource_surface_get_single_resource(ksurf->rsurf, natt);
+ if (!fb->texture)
return FALSE;
-
- pipe_resource_reference(&fb->texture, ksurf->textures[natt]);
}
/* already initialized */
@@ -166,7 +139,6 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
struct kms_crtc *kcrtc = &ksurf->current_crtc;
struct kms_display *kdpy = ksurf->kdpy;
struct kms_framebuffer tmp_fb;
- struct pipe_resource *tmp_texture;
int err;
if (!ksurf->back_fb.buffer_id) {
@@ -187,11 +159,8 @@ kms_surface_swap_buffers(struct native_surface *nsurf)
ksurf->front_fb = ksurf->back_fb;
ksurf->back_fb = tmp_fb;
- tmp_texture = ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT];
- ksurf->textures[NATIVE_ATTACHMENT_FRONT_LEFT] =
- ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT];
- ksurf->textures[NATIVE_ATTACHMENT_BACK_LEFT] = tmp_texture;
-
+ resource_surface_swap_buffers(ksurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, FALSE);
/* the front/back textures are swapped */
ksurf->sequence_number++;
kdpy->event_handler->invalid_surface(&kdpy->base,
@@ -210,7 +179,6 @@ static void
kms_surface_destroy(struct native_surface *nsurf)
{
struct kms_surface *ksurf = kms_surface(nsurf);
- int i;
if (ksurf->current_crtc.crtc)
drmModeFreeCrtc(ksurf->current_crtc.crtc);
@@ -223,11 +191,7 @@ kms_surface_destroy(struct native_surface *nsurf)
drmModeRmFB(ksurf->kdpy->fd, ksurf->back_fb.buffer_id);
pipe_resource_reference(&ksurf->back_fb.texture, NULL);
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++) {
- struct pipe_resource *ptex = ksurf->textures[i];
- pipe_resource_reference(&ptex, NULL);
- }
-
+ resource_surface_destroy(ksurf->rsurf);
FREE(ksurf);
}
@@ -249,6 +213,19 @@ kms_display_create_surface(struct native_display *ndpy,
ksurf->width = width;
ksurf->height = height;
+ ksurf->rsurf = resource_surface_create(kdpy->base.screen,
+ ksurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+ if (!ksurf->rsurf) {
+ FREE(ksurf);
+ return NULL;
+ }
+
+ resource_surface_set_size(ksurf->rsurf, ksurf->width, ksurf->height);
+
ksurf->base.destroy = kms_surface_destroy;
ksurf->base.swap_buffers = kms_surface_swap_buffers;
ksurf->base.flush_frontbuffer = kms_surface_flush_frontbuffer;
@@ -694,7 +671,27 @@ kms_display_init_screen(struct native_display *ndpy)
struct kms_display *kdpy = kms_display(ndpy);
int fd;
- fd = drmOpen(kdpy->api->driver_name, NULL);
+ fd = kdpy->fd;
+ if (fd >= 0) {
+ drmVersionPtr version = drmGetVersion(fd);
+ if (!version || strcmp(version->name, kdpy->api->driver_name)) {
+ if (version) {
+ _eglLog(_EGL_WARNING, "unknown driver name %s", version->name);
+ drmFreeVersion(version);
+ }
+ else {
+ _eglLog(_EGL_WARNING, "invalid fd %d", fd);
+ }
+
+ return FALSE;
+ }
+
+ drmFreeVersion(version);
+ }
+ else {
+ fd = drmOpen(kdpy->api->driver_name, NULL);
+ }
+
if (fd < 0) {
_eglLog(_EGL_WARNING, "failed to open DRM device");
return FALSE;
@@ -707,7 +704,7 @@ kms_display_init_screen(struct native_display *ndpy)
}
#endif
- kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd, NULL);
+ kdpy->base.screen = kdpy->api->create_screen(kdpy->api, fd);
if (!kdpy->base.screen) {
_eglLog(_EGL_WARNING, "failed to create DRM screen");
drmClose(fd);
@@ -727,8 +724,7 @@ static struct native_display_modeset kms_display_modeset = {
};
static struct native_display *
-kms_create_display(EGLNativeDisplayType dpy,
- struct native_event_handler *event_handler,
+kms_create_display(int fd, struct native_event_handler *event_handler,
struct drm_api *api)
{
struct kms_display *kdpy;
@@ -746,7 +742,7 @@ kms_create_display(EGLNativeDisplayType dpy,
return NULL;
}
- kdpy->fd = -1;
+ kdpy->fd = fd;
if (!kms_display_init_screen(&kdpy->base)) {
kms_display_destroy(&kdpy->base);
return NULL;
@@ -818,12 +814,17 @@ native_create_display(EGLNativeDisplayType dpy,
struct native_event_handler *event_handler)
{
struct native_display *ndpy = NULL;
+ int fd;
if (!drm_api)
drm_api = drm_api_create();
- if (drm_api)
- ndpy = kms_create_display(dpy, event_handler, drm_api);
+ if (drm_api) {
+ /* well, this makes fd 0 being ignored */
+ fd = (dpy != EGL_DEFAULT_DISPLAY) ?
+ (int) pointer_to_intptr((void *) dpy) : -1;
+ ndpy = kms_create_display(fd, event_handler, drm_api);
+ }
return ndpy;
}
diff --git a/src/gallium/state_trackers/egl/kms/native_kms.h b/src/gallium/state_trackers/egl/kms/native_kms.h
index 3b08e930c5..d69c8d38c8 100644
--- a/src/gallium/state_trackers/egl/kms/native_kms.h
+++ b/src/gallium/state_trackers/egl/kms/native_kms.h
@@ -35,6 +35,7 @@
#include "state_tracker/drm_api.h"
#include "common/native.h"
+#include "common/native_helper.h"
struct kms_config;
struct kms_connector;
@@ -73,11 +74,12 @@ struct kms_framebuffer {
struct kms_surface {
struct native_surface base;
- enum pipe_format color_format;
struct kms_display *kdpy;
+
+ struct resource_surface *rsurf;
+ enum pipe_format color_format;
int width, height;
- struct pipe_resource *textures[NUM_NATIVE_ATTACHMENTS];
unsigned int sequence_number;
struct kms_framebuffer front_fb, back_fb;
diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c
index 47f5423b67..3388fc61e1 100644
--- a/src/gallium/state_trackers/egl/x11/native_ximage.c
+++ b/src/gallium/state_trackers/egl/x11/native_ximage.c
@@ -37,6 +37,7 @@
#include "llvmpipe/lp_public.h"
#include "egllog.h"
+#include "common/native_helper.h"
#include "native_x11.h"
#include "x11_screen.h"
@@ -59,11 +60,6 @@ struct ximage_display {
int num_configs;
};
-struct ximage_buffer {
- struct pipe_resource *texture;
- struct xlib_drawable xdraw;
-};
-
struct ximage_surface {
struct native_surface base;
Drawable drawable;
@@ -74,11 +70,9 @@ struct ximage_surface {
unsigned int server_stamp;
unsigned int client_stamp;
- int width, height;
- struct ximage_buffer buffers[NUM_NATIVE_ATTACHMENTS];
- uint valid_mask;
- struct pipe_surface *draw_surface;
+ struct resource_surface *rsurf;
+ struct xlib_drawable xdraw;
};
struct ximage_config {
@@ -104,68 +98,10 @@ ximage_config(const struct native_config *nconf)
return (struct ximage_config *) nconf;
}
-static void
-ximage_surface_free_buffer(struct native_surface *nsurf,
- enum native_attachment which)
-{
- struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_buffer *xbuf = &xsurf->buffers[which];
-
- pipe_resource_reference(&xbuf->texture, NULL);
-}
-
-static boolean
-ximage_surface_alloc_buffer(struct native_surface *nsurf,
- enum native_attachment which)
-{
- struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_buffer *xbuf = &xsurf->buffers[which];
- struct pipe_screen *screen = xsurf->xdpy->base.screen;
- struct pipe_resource templ;
-
- /* free old data */
- if (xbuf->texture)
- ximage_surface_free_buffer(&xsurf->base, which);
-
- memset(&templ, 0, sizeof(templ));
- templ.target = PIPE_TEXTURE_2D;
- templ.format = xsurf->color_format;
- templ.width0 = xsurf->width;
- templ.height0 = xsurf->height;
- templ.depth0 = 1;
- templ.bind = PIPE_BIND_RENDER_TARGET;
-
- switch (which) {
- case NATIVE_ATTACHMENT_FRONT_LEFT:
- case NATIVE_ATTACHMENT_FRONT_RIGHT:
- templ.bind |= PIPE_BIND_SCANOUT;
- break;
- case NATIVE_ATTACHMENT_BACK_LEFT:
- case NATIVE_ATTACHMENT_BACK_RIGHT:
- templ.bind |= PIPE_BIND_DISPLAY_TARGET;
- break;
- default:
- break;
- }
- xbuf->texture = screen->resource_create(screen, &templ);
- if (xbuf->texture) {
- xbuf->xdraw.visual = xsurf->visual.visual;
- xbuf->xdraw.depth = xsurf->visual.depth;
- xbuf->xdraw.drawable = xsurf->drawable;
- }
-
- /* clean up the buffer if allocation failed */
- if (!xbuf->texture)
- ximage_surface_free_buffer(&xsurf->base, which);
-
- return (xbuf->texture != NULL);
-}
-
/**
- * Update the geometry of the surface. Return TRUE if the geometry has changed
- * since last call.
+ * Update the geometry of the surface. This is a slow functions.
*/
-static boolean
+static void
ximage_surface_update_geometry(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
@@ -173,102 +109,41 @@ ximage_surface_update_geometry(struct native_surface *nsurf)
Window root;
int x, y;
unsigned int w, h, border, depth;
- boolean updated = FALSE;
ok = XGetGeometry(xsurf->xdpy->dpy, xsurf->drawable,
&root, &x, &y, &w, &h, &border, &depth);
- if (ok && (xsurf->width != w || xsurf->height != h)) {
- xsurf->width = w;
- xsurf->height = h;
-
+ if (ok && resource_surface_set_size(xsurf->rsurf, w, h))
xsurf->server_stamp++;
- updated = TRUE;
- }
-
- return updated;
-}
-
-static void
-ximage_surface_notify_invalid(struct native_surface *nsurf)
-{
- struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_display *xdpy = xsurf->xdpy;
-
- xdpy->event_handler->invalid_surface(&xdpy->base,
- &xsurf->base, xsurf->server_stamp);
}
/**
- * Update the buffers of the surface. It is a slow function due to the
- * round-trip to the server.
+ * Update the buffers of the surface.
*/
static boolean
ximage_surface_update_buffers(struct native_surface *nsurf, uint buffer_mask)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- boolean updated;
- uint new_valid;
- int att;
-
- updated = ximage_surface_update_geometry(&xsurf->base);
- if (updated) {
- /* all buffers become invalid */
- xsurf->valid_mask = 0x0;
- }
- else {
- buffer_mask &= ~xsurf->valid_mask;
- /* all requested buffers are valid */
- if (!buffer_mask) {
- xsurf->client_stamp = xsurf->server_stamp;
- return TRUE;
- }
- }
- new_valid = 0x0;
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- if (native_attachment_mask_test(buffer_mask, att)) {
- /* reallocate the texture */
- if (!ximage_surface_alloc_buffer(&xsurf->base, att))
- break;
-
- new_valid |= (1 << att);
- if (buffer_mask == new_valid)
- break;
- }
+ if (xsurf->client_stamp != xsurf->server_stamp) {
+ ximage_surface_update_geometry(&xsurf->base);
+ xsurf->client_stamp = xsurf->server_stamp;
}
- xsurf->valid_mask |= new_valid;
- xsurf->client_stamp = xsurf->server_stamp;
-
- return (new_valid == buffer_mask);
+ return resource_surface_add_resources(xsurf->rsurf, buffer_mask);
}
-static boolean
-ximage_surface_draw_buffer(struct native_surface *nsurf,
- enum native_attachment which)
+/**
+ * Emulate an invalidate event.
+ */
+static void
+ximage_surface_invalidate(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_buffer *xbuf = &xsurf->buffers[which];
- struct pipe_screen *screen = xsurf->xdpy->base.screen;
- struct pipe_surface *psurf;
-
- assert(xsurf->drawable && xbuf->texture);
-
- psurf = xsurf->draw_surface;
- if (!psurf || psurf->texture != xbuf->texture) {
- pipe_surface_reference(&xsurf->draw_surface, NULL);
-
- psurf = screen->get_tex_surface(screen,
- xbuf->texture, 0, 0, 0, PIPE_BIND_DISPLAY_TARGET);
- if (!psurf)
- return FALSE;
-
- xsurf->draw_surface = psurf;
- }
-
- screen->flush_frontbuffer(screen, psurf, &xbuf->xdraw);
+ struct ximage_display *xdpy = xsurf->xdpy;
- return TRUE;
+ xsurf->server_stamp++;
+ xdpy->event_handler->invalid_surface(&xdpy->base,
+ &xsurf->base, xsurf->server_stamp);
}
static boolean
@@ -277,11 +152,10 @@ ximage_surface_flush_frontbuffer(struct native_surface *nsurf)
struct ximage_surface *xsurf = ximage_surface(nsurf);
boolean ret;
- ret = ximage_surface_draw_buffer(&xsurf->base,
- NATIVE_ATTACHMENT_FRONT_LEFT);
+ ret = resource_surface_present(xsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, (void *) &xsurf->xdraw);
/* force buffers to be updated in next validation call */
- xsurf->server_stamp++;
- ximage_surface_notify_invalid(&xsurf->base);
+ ximage_surface_invalidate(&xsurf->base);
return ret;
}
@@ -290,25 +164,15 @@ static boolean
ximage_surface_swap_buffers(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- struct ximage_buffer *xfront, *xback, xtmp;
boolean ret;
- /* display the back buffer first */
- ret = ximage_surface_draw_buffer(&xsurf->base,
- NATIVE_ATTACHMENT_BACK_LEFT);
- /* force buffers to be updated in next validation call */
- xsurf->server_stamp++;
- ximage_surface_notify_invalid(&xsurf->base);
+ ret = resource_surface_present(xsurf->rsurf,
+ NATIVE_ATTACHMENT_BACK_LEFT, (void *) &xsurf->xdraw);
- xfront = &xsurf->buffers[NATIVE_ATTACHMENT_FRONT_LEFT];
- xback = &xsurf->buffers[NATIVE_ATTACHMENT_BACK_LEFT];
-
- /* skip swapping unless there is a front buffer */
- if (xfront->texture) {
- xtmp = *xfront;
- *xfront = *xback;
- *xback = xtmp;
- }
+ resource_surface_swap_buffers(xsurf->rsurf,
+ NATIVE_ATTACHMENT_FRONT_LEFT, NATIVE_ATTACHMENT_BACK_LEFT, TRUE);
+ /* the front/back buffers have been swapped */
+ ximage_surface_invalidate(&xsurf->base);
return ret;
}
@@ -319,32 +183,22 @@ ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask,
int *width, int *height)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
+ uint w, h;
- if (xsurf->client_stamp != xsurf->server_stamp ||
- (xsurf->valid_mask & attachment_mask) != attachment_mask) {
- if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
- return FALSE;
- }
+ if (!ximage_surface_update_buffers(&xsurf->base, attachment_mask))
+ return FALSE;
if (seq_num)
*seq_num = xsurf->client_stamp;
- if (textures) {
- int att;
- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) {
- if (native_attachment_mask_test(attachment_mask, att)) {
- struct ximage_buffer *xbuf = &xsurf->buffers[att];
-
- textures[att] = NULL;
- pipe_resource_reference(&textures[att], xbuf->texture);
- }
- }
- }
+ if (textures)
+ resource_surface_get_resources(xsurf->rsurf, textures, attachment_mask);
+ resource_surface_get_size(xsurf->rsurf, &w, &h);
if (width)
- *width = xsurf->width;
+ *width = w;
if (height)
- *height = xsurf->height;
+ *height = h;
return TRUE;
}
@@ -361,13 +215,8 @@ static void
ximage_surface_destroy(struct native_surface *nsurf)
{
struct ximage_surface *xsurf = ximage_surface(nsurf);
- int i;
-
- pipe_surface_reference(&xsurf->draw_surface, NULL);
-
- for (i = 0; i < NUM_NATIVE_ATTACHMENTS; i++)
- ximage_surface_free_buffer(&xsurf->base, i);
+ resource_surface_destroy(xsurf->rsurf);
FREE(xsurf);
}
@@ -390,10 +239,25 @@ ximage_display_create_surface(struct native_display *ndpy,
xsurf->color_format = xconf->base.color_format;
xsurf->drawable = drawable;
+ xsurf->rsurf = resource_surface_create(xdpy->base.screen,
+ xsurf->color_format,
+ PIPE_BIND_RENDER_TARGET |
+ PIPE_BIND_SAMPLER_VIEW |
+ PIPE_BIND_DISPLAY_TARGET |
+ PIPE_BIND_SCANOUT);
+ if (!xsurf->rsurf) {
+ FREE(xsurf);
+ return NULL;
+ }
+
xsurf->drawable = drawable;
xsurf->visual = *xconf->visual;
/* initialize the geometry */
- ximage_surface_update_buffers(&xsurf->base, 0x0);
+ ximage_surface_update_geometry(&xsurf->base);
+
+ xsurf->xdraw.visual = xsurf->visual.visual;
+ xsurf->xdraw.depth = xsurf->visual.depth;
+ xsurf->xdraw.drawable = xsurf->drawable;
xsurf->base.destroy = ximage_surface_destroy;
xsurf->base.swap_buffers = ximage_surface_swap_buffers;
diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i
index 0294e769a6..cf0144b5dc 100644
--- a/src/gallium/state_trackers/python/p_context.i
+++ b/src/gallium/state_trackers/python/p_context.i
@@ -414,39 +414,21 @@ error1:
* Surface functions
*/
- void surface_copy(struct st_surface *dst,
- unsigned destx, unsigned desty,
- struct st_surface *src,
- unsigned srcx, unsigned srcy,
- unsigned width, unsigned height)
+ void resource_copy_region(struct pipe_resource *dst,
+ struct pipe_subresource subdst,
+ unsigned dstx, unsigned dsty, unsigned dstz,
+ struct pipe_resource *src,
+ struct pipe_subresource subsrc,
+ unsigned srcx, unsigned srcy, unsigned srcz,
+ unsigned width, unsigned height)
{
-/* XXX
- struct pipe_surface *_dst = NULL;
- struct pipe_surface *_src = NULL;
-
- _dst = st_pipe_surface(dst, PIPE_BIND_BLIT_DESTINATION);
- if(!_dst)
- SWIG_exception(SWIG_ValueError, "couldn't acquire destination surface for writing");
-
- _src = st_pipe_surface(src, PIPE_BIND_BLIT_SOURCE);
- if(!_src)
- SWIG_exception(SWIG_ValueError, "couldn't acquire source surface for reading");
-
- $self->pipe->surface_copy($self->pipe, _dst, destx, desty, _src, srcx, srcy, width, height);
-
- fail:
- pipe_surface_reference(&_src, NULL);
- pipe_surface_reference(&_dst, NULL);
-*/
- struct pipe_subresource subdst, subsrc;
- subsrc.face = src->face;
- subsrc.level = src->level;
- subdst.face = dst->face;
- subdst.level = dst->level;
- $self->pipe->resource_copy_region($self->pipe, dst->texture, subdst, destx, desty, dst->zslice,
- src->texture, subsrc, srcx, srcy, src->zslice, width, height);
+ $self->pipe->resource_copy_region($self->pipe,
+ dst, subdst, dstx, dsty, dstz,
+ src, subsrc, srcx, srcy, srcz,
+ width, height);
}
+
void clear_render_target(struct st_surface *dst,
float *rgba,
unsigned x, unsigned y,
diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript
new file mode 100644
index 0000000000..548053eb64
--- /dev/null
+++ b/src/gallium/state_trackers/vega/SConscript
@@ -0,0 +1,51 @@
+#######################################################################
+# SConscript for vega state_tracker
+
+Import('*')
+
+if 'egl' in env['statetrackers']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mapi',
+ ])
+
+ vega_sources = [
+ 'api.c',
+ 'api_context.c',
+ 'api_filters.c',
+ 'api_images.c',
+ 'api_masks.c',
+ 'api_misc.c',
+ 'api_paint.c',
+ 'api_params.c',
+ 'api_path.c',
+ 'api_text.c',
+ 'api_transform.c',
+ 'vgu.c',
+ 'vg_context.c',
+ 'vg_manager.c',
+ 'vg_state.c',
+ 'vg_translate.c',
+ 'polygon.c',
+ 'bezier.c',
+ 'path.c',
+ 'paint.c',
+ 'arc.c',
+ 'image.c',
+ 'renderer.c',
+ 'stroker.c',
+ 'mask.c',
+ 'shader.c',
+ 'shaders_cache.c',
+ ]
+
+ # vgapi_header must be generated first
+ env.Depends(vega_sources, vgapi_header)
+
+ st_vega = env.ConvenienceLibrary(
+ target = 'st_vega',
+ source = vega_sources,
+ )
+ Export('st_vega')
diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c
index 144fb8f323..8ace985336 100644
--- a/src/gallium/state_trackers/vega/api_filters.c
+++ b/src/gallium/state_trackers/vega/api_filters.c
@@ -42,6 +42,7 @@
#include "util/u_format.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
+#include "util/u_string.h"
#include "asm_filters.h"
@@ -271,7 +272,7 @@ static struct vg_shader * setup_convolution(struct vg_context *ctx, void *user_d
VGint num_consts = (VGint)(long)(user_data);
struct vg_shader *shader;
- snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
+ util_snprintf(buffer, 1023, convolution_asm, num_consts, num_consts / 2 + 1);
shader = shader_create_from_text(ctx->pipe, buffer, 200,
PIPE_SHADER_FRAGMENT);
@@ -299,16 +300,16 @@ static struct vg_shader * setup_lookup_single(struct vg_context *ctx, void *user
switch(channel) {
case VG_RED:
- snprintf(buffer, 1023, lookup_single_asm, "xxxx");
+ util_snprintf(buffer, 1023, lookup_single_asm, "xxxx");
break;
case VG_GREEN:
- snprintf(buffer, 1023, lookup_single_asm, "yyyy");
+ util_snprintf(buffer, 1023, lookup_single_asm, "yyyy");
break;
case VG_BLUE:
- snprintf(buffer, 1023, lookup_single_asm, "zzzz");
+ util_snprintf(buffer, 1023, lookup_single_asm, "zzzz");
break;
case VG_ALPHA:
- snprintf(buffer, 1023, lookup_single_asm, "wwww");
+ util_snprintf(buffer, 1023, lookup_single_asm, "wwww");
break;
default:
debug_assert(!"Unknown color channel");
diff --git a/src/gallium/state_trackers/vega/arc.c b/src/gallium/state_trackers/vega/arc.c
index 2d12340870..65a985fbbb 100644
--- a/src/gallium/state_trackers/vega/arc.c
+++ b/src/gallium/state_trackers/vega/arc.c
@@ -33,8 +33,7 @@
#include "path.h"
#include "util/u_debug.h"
-
-#include <math.h>
+#include "util/u_math.h"
#ifndef M_PI
#define M_PI 3.14159265358979323846
diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c
index fe0f166e88..c40ea8675e 100644
--- a/src/gallium/state_trackers/vega/renderer.c
+++ b/src/gallium/state_trackers/vega/renderer.c
@@ -59,7 +59,8 @@ static void setup_shaders(struct renderer *ctx)
{
struct pipe_context *pipe = ctx->pipe;
/* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
+ ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D,
+ TGSI_INTERPOLATE_LINEAR);
}
static struct pipe_resource *
diff --git a/src/gallium/state_trackers/vega/stroker.c b/src/gallium/state_trackers/vega/stroker.c
index 68a52029db..d89b6cf25c 100644
--- a/src/gallium/state_trackers/vega/stroker.c
+++ b/src/gallium/state_trackers/vega/stroker.c
@@ -35,7 +35,7 @@
#include "path_utils.h"
#include "polygon.h"
-#include "math.h"
+#include "util/u_math.h"
#ifndef M_2PI
#define M_2PI 6.28318530717958647692528676655900576
@@ -870,7 +870,7 @@ static VGboolean vg_stroke_outline(struct stroke_iterator *it,
VGboolean cap_first,
VGfloat *start_tangent)
{
- const int MAX_OFFSET = 16;
+#define MAX_OFFSET 16
struct bezier offset_curves[MAX_OFFSET];
VGPathCommand first_element;
VGfloat start[2], prev[2];
@@ -1017,6 +1017,7 @@ static VGboolean vg_stroke_outline(struct stroke_iterator *it,
#endif
return VG_FALSE;
}
+#undef MAX_OFFSET
}
static void stroker_process_subpath(struct stroker *stroker)
diff --git a/src/gallium/state_trackers/vega/util_array.h b/src/gallium/state_trackers/vega/util_array.h
index 4343dfe36e..b2d22f476e 100644
--- a/src/gallium/state_trackers/vega/util_array.h
+++ b/src/gallium/state_trackers/vega/util_array.h
@@ -65,7 +65,7 @@ static INLINE void array_destroy(struct array *array)
{
if (array)
free(array->data);
- free(array);
+ FREE(array);
}
static INLINE void array_resize(struct array *array, int num)
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index f9022a9f93..f1a07bd863 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -146,6 +146,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
/* XXX: hockup */
}
+#if 0 /* Implement and enable to enable rotation and reflection. */
static void *
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
@@ -168,6 +169,8 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
/* ScrnInfoPtr pScrn = crtc->scrn; */
}
+#endif
+
/*
* Cursor functions
*/
@@ -362,9 +365,9 @@ static const xf86CrtcFuncsRec crtc_funcs = {
.hide_cursor = crtc_hide_cursor,
.load_cursor_argb = crtc_load_cursor_argb,
- .shadow_create = crtc_shadow_create,
- .shadow_allocate = crtc_shadow_allocate,
- .shadow_destroy = crtc_shadow_destroy,
+ .shadow_create = NULL,
+ .shadow_allocate = NULL,
+ .shadow_destroy = NULL,
.gamma_set = crtc_gamma_set,
.destroy = crtc_destroy,
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index e719644d34..4e01bd1030 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -299,6 +299,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
GCPtr gc;
RegionPtr copy_clip;
Bool save_accel;
+ CustomizerPtr cust = ms->cust;
/*
* In driCreateBuffers we dewrap windows into the
@@ -352,7 +353,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
ValidateGC(dst_draw, gc);
/* If this is a full buffer swap, throttle on the previous one */
- if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
+ if (ms->swapThrottling &&
+ dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
if (extents->x1 == 0 && extents->y1 == 0 &&
@@ -374,6 +376,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
DamageRegionAppend(src_draw, pRegion);
DamageRegionProcessPending(src_draw);
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP);
+
(*gc->ops->CopyArea)(src_draw, dst_draw, gc,
0, 0, pDraw->width, pDraw->height, 0, 0);
ms->exa->accel = save_accel;
@@ -381,8 +386,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
FreeScratchGC(gc);
ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
- pDestBuffer->attachment == DRI2BufferFrontLeft ?
+ (pDestBuffer->attachment == DRI2BufferFrontLeft
+ && ms->swapThrottling) ?
&dst_priv->fence : NULL);
+
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
+
}
Bool
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 84c0545b1b..6b6e2009fe 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -79,12 +79,16 @@ typedef enum
OPTION_SW_CURSOR,
OPTION_2D_ACCEL,
OPTION_DEBUG_FALLBACK,
+ OPTION_THROTTLE_SWAP,
+ OPTION_THROTTLE_DIRTY
} drv_option_enums;
static const OptionInfoRec drv_options[] = {
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
@@ -534,23 +538,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
if (ms->ctx) {
int j;
- ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
+ ms->dirtyThrottling ?
+ &ms->fence[XORG_NR_FENCES-1] :
+ NULL);
- if (ms->fence[0])
- ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
+ if (ms->dirtyThrottling) {
+ if (ms->fence[0])
+ ms->ctx->screen->fence_finish(ms->ctx->screen,
+ ms->fence[0], 0);
- /* The amount of rendering generated by a block handler can be
- * quite small. Let us get a fair way ahead of hardware before
- * throttling.
- */
- for (j = 0; j < XORG_NR_FENCES - 1; j++)
- ms->screen->fence_reference(ms->screen,
- &ms->fence[j],
- ms->fence[j+1]);
-
- ms->screen->fence_reference(ms->screen,
- &ms->fence[XORG_NR_FENCES-1],
- NULL);
+ /* The amount of rendering generated by a block handler can be
+ * quite small. Let us get a fair way ahead of hardware before
+ * throttling.
+ */
+ for (j = 0; j < XORG_NR_FENCES - 1; j++)
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[j],
+ ms->fence[j+1]);
+
+ ms->screen->fence_reference(ms->screen,
+ &ms->fence[XORG_NR_FENCES-1],
+ NULL);
+ }
}
@@ -634,6 +644,8 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
unsigned max_width, max_height;
VisualPtr visual;
CustomizerPtr cust = ms->cust;
+ MessageType from_st;
+ MessageType from_dt;
if (!drv_init_drm(pScrn)) {
FatalError("Could not init DRM");
@@ -720,6 +732,19 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
+ if (cust && cust->winsys_screen_init)
+ cust->winsys_screen_init(cust, ms->fd);
+
+ ms->swapThrottling = cust ? cust->swap_throttling : TRUE;
+ from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
+ &ms->swapThrottling) ?
+ X_CONFIG : X_DEFAULT;
+
+ ms->dirtyThrottling = cust ? cust->dirty_throttling : TRUE;
+ from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY,
+ &ms->dirtyThrottling) ?
+ X_CONFIG : X_DEFAULT;
+
if (ms->screen) {
ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
@@ -744,6 +769,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
#else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
#endif
+ xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n",
+ ms->swapThrottling ? "enabled" : "disabled");
+ xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n",
+ ms->dirtyThrottling ? "enabled" : "disabled");
+
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
miInitializeBackingStore(pScreen);
@@ -776,9 +806,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
- if (cust && cust->winsys_screen_init)
- cust->winsys_screen_init(cust, ms->fd);
-
return drv_enter_vt(scrnIndex, 1);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index ee40bc8ccb..bd84668300 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -46,7 +46,6 @@
#include "util/u_math.h"
#include "util/u_debug.h"
#include "util/u_format.h"
-#include "util/u_surface.h"
#define DEBUG_PRINT 0
#define ROUND_UP_TEXTURES 1
@@ -987,6 +986,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa;
ExaDriverPtr pExa;
+ CustomizerPtr cust = ms->cust;
exa = xcalloc(1, sizeof(struct exa_context));
if (!exa)
@@ -1048,6 +1048,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
/* Share context with DRI */
ms->ctx = exa->pipe;
+ if (cust && cust->winsys_context_throttle)
+ cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
exa->renderer = renderer_create(exa->pipe);
exa->accel = accel;
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index e5def3e2ed..92f1cc5065 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -8,7 +8,6 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sampler.h"
-#include "util/u_surface.h"
#include "util/u_inlines.h"
@@ -602,7 +601,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
void renderer_draw_yuv(struct xorg_renderer *r,
- int src_x, int src_y, int src_w, int src_h,
+ float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_resource **textures)
{
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.h b/src/gallium/state_trackers/xorg/xorg_renderer.h
index 0454a6513d..fb09fabe15 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.h
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.h
@@ -54,7 +54,7 @@ void renderer_set_constants(struct xorg_renderer *r,
void renderer_draw_yuv(struct xorg_renderer *r,
- int src_x, int src_y, int src_w, int src_h,
+ float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h,
struct pipe_resource **textures);
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index 65fbc3234b..25da9b1a3b 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -67,12 +67,22 @@ typedef struct
#define XORG_NR_FENCES 3
+enum xorg_throttling_reason {
+ THROTTLE_RENDER,
+ THROTTLE_SWAP
+};
+
typedef struct _CustomizerRec
{
+ Bool dirty_throttling;
+ Bool swap_throttling;
Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
+ void (*winsys_context_throttle)(struct _CustomizerRec *cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason);
} CustomizerRec, *CustomizerPtr;
typedef struct _modesettingRec
@@ -91,6 +101,8 @@ typedef struct _modesettingRec
Bool noAccel;
Bool SWCursor;
CursorPtr cursor;
+ Bool swapThrottling;
+ Bool dirtyThrottling;
CloseScreenProcPtr CloseScreen;
/* Broken-out options. */
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
index a221594454..f98bd93901 100644
--- a/src/gallium/state_trackers/xorg/xorg_xv.c
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -413,7 +413,7 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
static void
draw_yuv(struct xorg_xv_port_priv *port,
- int src_x, int src_y, int src_w, int src_h,
+ float src_x, float src_y, float src_w, float src_h,
int dst_x, int dst_y, int dst_w, int dst_h)
{
struct pipe_resource **textures = port->yuv[port->current_set];
@@ -562,10 +562,10 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
int box_y2 = pbox->y2;
float diff_x = (float)src_w / (float)dst_w;
float diff_y = (float)src_h / (float)dst_h;
- int offset_x = box_x1 - dstX + pPixmap->screen_x;
- int offset_y = box_y1 - dstY + pPixmap->screen_y;
- int offset_w;
- int offset_h;
+ float offset_x = box_x1 - dstX + pPixmap->screen_x;
+ float offset_y = box_y1 - dstY + pPixmap->screen_y;
+ float offset_w;
+ float offset_h;
x = box_x1;
y = box_y1;
@@ -576,8 +576,8 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
offset_h = dst_h - h;
draw_yuv(pPriv,
- src_x + offset_x*diff_x, src_y + offset_y*diff_y,
- src_w - offset_w*diff_x, src_h - offset_h*diff_y,
+ (float) src_x + offset_x*diff_x, (float) src_y + offset_y*diff_y,
+ (float) src_w - offset_w*diff_x, (float) src_h - offset_h*diff_y,
x, y, w, h);
pbox++;
diff --git a/src/gallium/targets/Makefile.dri b/src/gallium/targets/Makefile.dri
index 3eff07538f..de05f96d23 100644
--- a/src/gallium/targets/Makefile.dri
+++ b/src/gallium/targets/Makefile.dri
@@ -57,6 +57,8 @@ SHARED_INCLUDES = \
-I$(TOP)/src/egl/drivers/dri \
$(LIBDRM_CFLAGS)
+LIBNAME_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
+
##### RULES #####
@@ -69,7 +71,7 @@ SHARED_INCLUDES = \
##### TARGETS #####
-default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
+default: depend symlinks $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) Makefile \
$(TOP)/src/mesa/drivers/dri/Makefile.template $(TOP)/src/mesa/drivers/dri/common/dri_test.o
@@ -88,7 +90,7 @@ $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) Makefile \
$(TOP)/$(LIB_DIR)/gallium:
mkdir -p $@
-$(TOP)/$(LIB_DIR)/gallium/$(LIBNAME): $(LIBNAME) $(TOP)/$(LIB_DIR)/gallium
+$(LIBNAME_STAGING): $(LIBNAME)
$(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR)/gallium
depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
diff --git a/src/gallium/targets/Makefile.egl b/src/gallium/targets/Makefile.egl
index 4f8641e056..4fa13e85ce 100644
--- a/src/gallium/targets/Makefile.egl
+++ b/src/gallium/targets/Makefile.egl
@@ -33,10 +33,20 @@ endif
kms_ST = $(TOP)/src/gallium/state_trackers/egl/libeglkms.a
kms_LIBS = $(common_LIBS)
+### Include directories
+INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/winsys \
+ -I$(TOP)/src/egl/main \
+ $(LIBDRM_CFLAGS)
+
##### RULES #####
.c.o:
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(EGL_DRIVER_DEFINES) $< -o $@
##### TARGETS #####
diff --git a/src/gallium/targets/Makefile.xorg b/src/gallium/targets/Makefile.xorg
new file mode 100644
index 0000000000..f638fbe455
--- /dev/null
+++ b/src/gallium/targets/Makefile.xorg
@@ -0,0 +1,72 @@
+# src/gallium/targets/Makefile.xorg
+
+# Template makefile for gallium xorg drivers.
+#
+# Usage:
+# The minimum that the including makefile needs to define
+# is TOP, LIBNAME and one of of the *_SOURCES.
+#
+# Optional defines:
+# DRIVER_INCLUDES are appended to the list of includes directories.
+# DRIVER_DEFINES is not used for makedepend, but for compilation.
+# DRIVER_LINKS are flags given to the linker
+
+### Basic defines ###
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(CPP_SOURCES:.cpp=.o) \
+ $(ASM_SOURCES:.S=.o)
+
+INCLUDES = \
+ $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ $(DRIVER_INCLUDES)
+
+LIBNAME_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
+
+
+##### TARGETS #####
+
+default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING)
+
+$(LIBNAME): $(OBJECTS) Makefile $(LIBS)
+ $(MKLIB) -noprefix -o $@ $(OBJECTS) $(DRIVER_LINKS)
+
+depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(GENERATED_SOURCES) 2> /dev/null
+
+$(LIBNAME_STAGING): $(LIBNAME)
+ $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR)/gallium
+
+$(TOP)/$(LIB_DIR)/gallium:
+ mkdir -p $@
+
+clean:
+ rm -f $(OBJECTS) $(GENERATED_SOURCES) $(LIBNAME).a depend depend.bak
+
+install:
+ $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+
+
+##### RULES #####
+
+%.s: %.c
+ $(CC) -S $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+%.o: %.c
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+%.o: %.cpp
+ $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+%.o: %.S
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+sinclude depend
+
+.PHONY: default clean install
diff --git a/src/gallium/targets/SConscript b/src/gallium/targets/SConscript
index 9077cbf6a4..b61a4855af 100644
--- a/src/gallium/targets/SConscript
+++ b/src/gallium/targets/SConscript
@@ -3,15 +3,16 @@ Import('*')
# Compatibility with old build scripts:
#
-if 'xlib' in env['winsys']:
- SConscript([
- 'libgl-xlib/SConscript',
- ])
+if 'mesa' in env['statetrackers']:
+ if 'xlib' in env['winsys']:
+ SConscript([
+ 'libgl-xlib/SConscript',
+ ])
-if 'gdi' in env['winsys']:
- SConscript([
- 'libgl-gdi/SConscript',
- ])
+ if 'gdi' in env['winsys']:
+ SConscript([
+ 'libgl-gdi/SConscript',
+ ])
if not 'graw-xlib' in env['targets'] and not env['msvc']:
# XXX: disable until MSVC can link correctly
@@ -29,6 +30,12 @@ if 'xorg' in env['statetrackers']:
'xorg-vmwgfx/SConscript',
])
+if 'egl' in env['statetrackers']:
+ SConscript([
+ 'egl-swrast/SConscript',
+ 'egl-apis/SConscript',
+ ])
+
# Ideally all non-target directories would produce convenience
# libraries, and the actual shared libraries and other installables
# would be finally assembled in the targets subtree:
diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri
index 4bbb16c227..74b53e5023 100644
--- a/src/gallium/targets/SConscript.dri
+++ b/src/gallium/targets/SConscript.dri
@@ -99,3 +99,8 @@ if 'radeon' in env['winsys']:
SConscript([
'dri-radeong/SConscript',
])
+
+if 'r600' in env['winsys']:
+ SConscript([
+ 'dri-r600/SConscript',
+ ])
diff --git a/src/gallium/targets/dri-r600/Makefile b/src/gallium/targets/dri-r600/Makefile
new file mode 100644
index 0000000000..0213200fbc
--- /dev/null
+++ b/src/gallium/targets/dri-r600/Makefile
@@ -0,0 +1,22 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r600_dri.so
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/state_trackers/dri/drm/libdridrm.a \
+ $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
+ $(TOP)/src/gallium/drivers/rbug/librbug.a \
+ $(TOP)/src/gallium/drivers/r600/libr600.a
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+include ../Makefile.dri
+
+DRI_LIB_DEPS += -ldrm_radeon
+
+symlinks:
diff --git a/src/gallium/targets/dri-r600/SConscript b/src/gallium/targets/dri-r600/SConscript
new file mode 100644
index 0000000000..6c23c050eb
--- /dev/null
+++ b/src/gallium/targets/dri-r600/SConscript
@@ -0,0 +1,27 @@
+Import('*')
+
+if not 'r600' in env['drivers']:
+ print 'warning: r600 pipe driver not built skipping r600_dri.so'
+ Return()
+
+env = drienv.Clone()
+
+env.ParseConfig('pkg-config --cflags --libs libdrm_radeon')
+
+env.Prepend(LIBS = [
+ st_dri,
+ r600drm,
+ r600,
+ trace,
+ rbug,
+ mesa,
+ glsl,
+ gallium,
+ COMMON_DRI_DRM_OBJECTS
+])
+
+env.SharedLibrary(
+ target ='r600_dri.so',
+ source = 'dummy.c',
+ SHLIBPREFIX = '',
+)
diff --git a/src/gallium/targets/dri-r600/dummy.c b/src/gallium/targets/dri-r600/dummy.c
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/gallium/targets/dri-r600/dummy.c
diff --git a/src/gallium/targets/egl-apis/SConscript b/src/gallium/targets/egl-apis/SConscript
new file mode 100644
index 0000000000..0ca3d1fb9e
--- /dev/null
+++ b/src/gallium/targets/egl-apis/SConscript
@@ -0,0 +1,33 @@
+#######################################################################
+# SConscript for egl-apis target
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/gallium/state_trackers/vega',
+ ])
+
+ env.Append(LIBS = [
+ 'gdi32',
+ 'user32',
+ 'kernel32',
+ 'ws2_32',
+ ])
+
+ env['no_import_lib'] = 1
+
+ api_libs = {
+ 'OpenVG': vgapi + st_vega,
+ }
+
+ for name in api_libs.keys():
+ api = env.SharedLibrary(
+ target = 'api_' + name,
+ source = ['api_' + name + '.c'],
+ LIBS = api_libs[name] + gallium + env['LIBS'],
+ )
+ env.InstallSharedLibrary(api)
diff --git a/src/gallium/targets/egl-swrast/SConscript b/src/gallium/targets/egl-swrast/SConscript
new file mode 100644
index 0000000000..213e5b3e6c
--- /dev/null
+++ b/src/gallium/targets/egl-swrast/SConscript
@@ -0,0 +1,30 @@
+#######################################################################
+# SConscript for egl-swrast target
+
+Import('*')
+
+if env['platform'] == 'windows':
+
+ env = env.Clone()
+
+ env.Append(LIBS = [
+ 'gdi32',
+ 'user32',
+ 'kernel32',
+ 'ws2_32',
+ ])
+
+ drivers = [softpipe]
+ if env['llvm']:
+ drivers += [llvmpipe]
+ drivers += [identity, trace, rbug]
+
+ env['no_import_lib'] = 1
+
+ egl_gdi_swrast = env.SharedLibrary(
+ target ='egl_gdi_swrast',
+ source = 'swrast_glue.c',
+ LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'],
+ )
+
+ env.InstallSharedLibrary(egl_gdi_swrast)
diff --git a/src/gallium/targets/egl-swrast/swrast_glue.c b/src/gallium/targets/egl-swrast/swrast_glue.c
index 9db8089a66..defd11c687 100644
--- a/src/gallium/targets/egl-swrast/swrast_glue.c
+++ b/src/gallium/targets/egl-swrast/swrast_glue.c
@@ -1,14 +1,8 @@
#include "state_tracker/drm_api.h"
-static struct drm_api swrast_drm_api =
-{
- .name = "swrast",
-};
-
struct drm_api *
drm_api_create()
{
- (void) swrast_drm_api;
return NULL;
}
diff --git a/src/gallium/targets/xorg-vmwgfx/Makefile b/src/gallium/targets/xorg-vmwgfx/Makefile
index 01a10b6f19..c0ff999116 100644
--- a/src/gallium/targets/xorg-vmwgfx/Makefile
+++ b/src/gallium/targets/xorg-vmwgfx/Makefile
@@ -1,72 +1,30 @@
TOP = ../../../..
include $(TOP)/configs/current
-TARGET = vmwgfx_drv.so
+LIBNAME = vmwgfx_drv.so
-CFILES = \
+C_SOURCES = \
vmw_xorg.c \
vmw_video.c \
vmw_ioctl.c \
vmw_ctrl.c \
vmw_screen.c
-OBJECTS = $(patsubst %.c,%.o,$(CFILES))
-
-INCLUDES = \
- $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/auxiliary \
+DRIVER_INCLUDES = \
-I$(TOP)/src/gallium
-LIBS = \
+DRIVER_DEFINES = \
+ -std=gnu99 \
+ -DHAVE_CONFIG_H
+
+DRIVER_LINKS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
$(TOP)/src/gallium/winsys/svga/drm/libsvgadrm.a \
$(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/rbug/librbug.a \
$(TOP)/src/gallium/drivers/svga/libsvga.a \
- $(GALLIUM_AUXILIARIES)
-
-LINKS = \
+ $(GALLIUM_AUXILIARIES) \
$(shell pkg-config --libs --silence-errors libkms) \
$(shell pkg-config --libs libdrm)
-DRIVER_DEFINES = \
- -std=gnu99 \
- -DHAVE_CONFIG_H
-
-TARGET_STAGING = $(TOP)/$(LIB_DIR)/gallium/$(TARGET)
-
-#############################################
-
-
-
-all default: $(TARGET) $(TARGET_STAGING)
-
-$(TARGET): $(OBJECTS) Makefile $(LIBS)
- $(MKLIB) -noprefix -o $@ $(OBJECTS) $(LIBS) $(LINKS)
-
-$(TOP)/$(LIB_DIR)/gallium:
- mkdir -p $@
-
-$(TARGET_STAGING): $(TARGET) $(TOP)/$(LIB_DIR)/gallium
- $(INSTALL) $(TARGET) $(TOP)/$(LIB_DIR)/gallium
-
-clean:
- rm -rf $(OBJECTS) $(TARGET)
-
-install:
- $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
- $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
-
-
-##############################################
-
-
-.c.o:
- $(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
-
-
-##############################################
-
-.PHONY = all clean install
+include ../Makefile.xorg
diff --git a/src/gallium/targets/xorg-vmwgfx/vmw_screen.c b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
index 5e4ef41688..e0edf32adb 100644
--- a/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
+++ b/src/gallium/targets/xorg-vmwgfx/vmw_screen.c
@@ -32,9 +32,14 @@
#include "vmw_hook.h"
#include "vmw_driver.h"
+#include <pipe/p_context.h>
#include "cursorstr.h"
+void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us);
+
+
/* modified version of crtc functions */
xf86CrtcFuncsRec vmw_screen_crtc_funcs;
@@ -83,12 +88,51 @@ vmw_screen_cursor_close(struct vmw_customizer *vmw)
config->crtc[i]->funcs = vmw->cursor_priv;
}
+static void
+vmw_context_throttle(CustomizerPtr cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason)
+{
+ switch (reason) {
+ case THROTTLE_RENDER:
+ vmw_winsys_screen_set_throttling(pipe->screen, 20000);
+ break;
+ default:
+ vmw_winsys_screen_set_throttling(pipe->screen, 0);
+ }
+}
+
+static void
+vmw_context_no_throttle(CustomizerPtr cust,
+ struct pipe_context *pipe,
+ enum xorg_throttling_reason reason)
+{
+ vmw_winsys_screen_set_throttling(pipe->screen, 0);
+}
+
static Bool
vmw_screen_init(CustomizerPtr cust, int fd)
{
struct vmw_customizer *vmw = vmw_customizer(cust);
+ drmVersionPtr ver;
vmw->fd = fd;
+ ver = drmGetVersion(fd);
+ if (ver == NULL ||
+ (ver->version_major == 1 && ver->version_minor < 1)) {
+ cust->swap_throttling = TRUE;
+ cust->dirty_throttling = TRUE;
+ cust->winsys_context_throttle = vmw_context_no_throttle;
+ } else {
+ cust->swap_throttling = TRUE;
+ cust->dirty_throttling = FALSE;
+ cust->winsys_context_throttle = vmw_context_throttle;
+ debug_printf("%s: Enabling kernel throttling.\n", __func__);
+ }
+
+ if (ver)
+ drmFreeVersion(ver);
+
vmw_screen_cursor_init(vmw);
vmw_ctrl_ext_init(vmw);
diff --git a/src/gallium/tests/python/retrace/interpreter.py b/src/gallium/tests/python/retrace/interpreter.py
index 4599d68d7d..37d7fd6415 100755
--- a/src/gallium/tests/python/retrace/interpreter.py
+++ b/src/gallium/tests/python/retrace/interpreter.py
@@ -557,19 +557,15 @@ class Context(Object):
self.real.draw_range_elements(indexBuffer, indexSize, indexBias, minIndex, maxIndex, mode, start, count)
self._set_dirty()
- def surface_copy(self, dest, destx, desty, src, srcx, srcy, width, height):
- if dest is not None and src is not None:
+ def resource_copy_region(self, dst, subdst, dstx, dsty, dstz, src, subsrc, srcx, srcy, srcz, width, height):
+ if dst is not None and src is not None:
if self.interpreter.options.all:
- self.interpreter.present(self.real, src, 'surface_copy_src', srcx, srcy, width, height)
- self.real.surface_copy(dest, destx, desty, src, srcx, srcy, width, height)
- if dest in self.cbufs:
- self._set_dirty()
- flags = gallium.PIPE_FLUSH_FRAME
- else:
- flags = 0
+ self.interpreter.present(self.real, src, 'resource_copy_src', srcx, srcy, width, height)
+ self.real.resource_copy_region(dst, subdst, dstx, dsty, dstx, src, subsrc, srcx, srcy, srcz, width, height)
+ flags = 0
self.flush(flags)
if self.interpreter.options.all:
- self.interpreter.present(self.real, dest, 'surface_copy_dest', destx, desty, width, height)
+ self.interpreter.present(self.real, dst, 'resource_copy_dst', dstx, dsty, width, height)
def is_resource_referenced(self, texture, face, level):
#return self.real.is_resource_referenced(format, texture, face, level)
diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript
index 330b1ab834..907ac90bf0 100644
--- a/src/gallium/winsys/SConscript
+++ b/src/gallium/winsys/SConscript
@@ -40,3 +40,8 @@ if env['dri']:
SConscript([
'radeon/drm/SConscript',
])
+
+ if 'r600' in env['winsys']:
+ SConscript([
+ 'r600/drm/SConscript',
+ ])
diff --git a/src/gallium/winsys/i915/drm/Makefile b/src/gallium/winsys/i915/drm/Makefile
index a67b9e8a52..1977de1fb0 100644
--- a/src/gallium/winsys/i915/drm/Makefile
+++ b/src/gallium/winsys/i915/drm/Makefile
@@ -7,7 +7,7 @@ C_SOURCES = \
i915_drm_batchbuffer.c \
i915_drm_buffer.c \
i915_drm_fence.c \
- i915_drm_api.c
+ i915_drm_winsys.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
diff --git a/src/gallium/winsys/i915/drm/i915_drm_api.c b/src/gallium/winsys/i915/drm/i915_drm_winsys.c
index b95df40e86..5a6b45e6c9 100644
--- a/src/gallium/winsys/i915/drm/i915_drm_api.c
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.c
@@ -65,7 +65,7 @@ i915_drm_create_screen(struct drm_api *api, int drmFD)
i915_drm_winsys_init_fence_functions(idws);
idws->fd = drmFD;
- idws->id = deviceID;
+ idws->base.pci_id = deviceID;
idws->max_batch_size = 16 * 4096;
idws->base.destroy = i915_drm_winsys_destroy;
@@ -75,7 +75,7 @@ i915_drm_create_screen(struct drm_api *api, int drmFD)
idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
- return i915_create_screen(&idws->base, deviceID);
+ return i915_screen_create(&idws->base);
}
static struct drm_api i915_drm_api =
diff --git a/src/gallium/winsys/i915/drm/i915_drm_winsys.h b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
index 217c4a7eaf..99667bde4e 100644
--- a/src/gallium/winsys/i915/drm/i915_drm_winsys.h
+++ b/src/gallium/winsys/i915/drm/i915_drm_winsys.h
@@ -21,8 +21,6 @@ struct i915_drm_winsys
int fd; /**< Drm file discriptor */
- unsigned id;
-
size_t max_batch_size;
struct {
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.c b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
index a03875be5b..bb1c107c05 100644
--- a/src/gallium/winsys/i915/sw/i915_sw_winsys.c
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.c
@@ -46,11 +46,11 @@ i915_sw_create_screen()
isws->base.destroy = i915_sw_destroy;
- isws->id = deviceID;
+ isws->base.pci_id = deviceID;
isws->max_batch_size = 16 * 4096;
isws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
/* XXX so this will leak winsys:es */
- return i915_create_screen(&isws->base, deviceID);
+ return i915_screen_create(&isws->base);
}
diff --git a/src/gallium/winsys/i915/sw/i915_sw_winsys.h b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
index 92e7c36fd8..b8aa9ef4ac 100644
--- a/src/gallium/winsys/i915/sw/i915_sw_winsys.h
+++ b/src/gallium/winsys/i915/sw/i915_sw_winsys.h
@@ -16,8 +16,6 @@ struct i915_sw_winsys
boolean dump_cmd;
- unsigned id;
-
size_t max_batch_size;
};
diff --git a/src/gallium/winsys/r600/drm/Makefile b/src/gallium/winsys/r600/drm/Makefile
new file mode 100644
index 0000000000..e3b943c4d4
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/Makefile
@@ -0,0 +1,23 @@
+
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r600winsys
+
+C_SOURCES = \
+ bof.c \
+ r600_state.c \
+ radeon_ctx.c \
+ radeon_draw.c \
+ radeon_state.c \
+ radeon_bo.c \
+ radeon_pciid.c \
+ radeon.c \
+ r600_drm.c
+
+LIBRARY_INCLUDES = -I$(TOP)/src/gallium/drivers/r600 \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+include ../../../Makefile.template
+
+symlinks:
diff --git a/src/gallium/winsys/r600/drm/bof.c b/src/gallium/winsys/r600/drm/bof.c
new file mode 100644
index 0000000000..0598cc6bc0
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/bof.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include "bof.h"
+
+/*
+ * helpers
+ */
+static int bof_entry_grow(bof_t *bof)
+{
+ bof_t **array;
+
+ if (bof->array_size < bof->nentry)
+ return 0;
+ array = realloc(bof->array, (bof->nentry + 16) * sizeof(void*));
+ if (array == NULL)
+ return -ENOMEM;
+ bof->array = array;
+ bof->nentry += 16;
+ return 0;
+}
+
+/*
+ * object
+ */
+bof_t *bof_object(void)
+{
+ bof_t *object;
+
+ object = calloc(1, sizeof(bof_t));
+ if (object == NULL)
+ return NULL;
+ object->refcount = 1;
+ object->type = BOF_TYPE_OBJECT;
+ object->size = 12;
+ return object;
+}
+
+bof_t *bof_object_get(bof_t *object, const char *keyname)
+{
+ unsigned i;
+
+ for (i = 0; i < object->array_size; i += 2) {
+ if (!strcmp(object->array[i]->value, keyname)) {
+ return object->array[i + 1];
+ }
+ }
+ return NULL;
+}
+
+int bof_object_set(bof_t *object, const char *keyname, bof_t *value)
+{
+ bof_t *key;
+ int r;
+
+ if (object->type != BOF_TYPE_OBJECT)
+ return -EINVAL;
+ r = bof_entry_grow(object);
+ if (r)
+ return r;
+ key = bof_string(keyname);
+ if (key == NULL)
+ return -ENOMEM;
+ object->array[object->array_size++] = key;
+ object->array[object->array_size++] = value;
+ object->size += value->size;
+ object->size += key->size;
+ bof_incref(value);
+ return 0;
+}
+
+/*
+ * array
+ */
+bof_t *bof_array(void)
+{
+ bof_t *array = bof_object();
+
+ if (array == NULL)
+ return NULL;
+ array->type = BOF_TYPE_ARRAY;
+ array->size = 12;
+ return array;
+}
+
+int bof_array_append(bof_t *array, bof_t *value)
+{
+ int r;
+ if (array->type != BOF_TYPE_ARRAY)
+ return -EINVAL;
+ r = bof_entry_grow(array);
+ if (r)
+ return r;
+ array->array[array->array_size++] = value;
+ array->size += value->size;
+ bof_incref(value);
+ return 0;
+}
+
+bof_t *bof_array_get(bof_t *bof, unsigned i)
+{
+ if (!bof_is_array(bof) || i >= bof->array_size)
+ return NULL;
+ return bof->array[i];
+}
+
+unsigned bof_array_size(bof_t *bof)
+{
+ if (!bof_is_array(bof))
+ return 0;
+ return bof->array_size;
+}
+
+/*
+ * blob
+ */
+bof_t *bof_blob(unsigned size, void *value)
+{
+ bof_t *blob = bof_object();
+
+ if (blob == NULL)
+ return NULL;
+ blob->type = BOF_TYPE_BLOB;
+ blob->value = calloc(1, size);
+ if (blob->value == NULL) {
+ bof_decref(blob);
+ return NULL;
+ }
+ blob->size = size;
+ memcpy(blob->value, value, size);
+ blob->size += 12;
+ return blob;
+}
+
+unsigned bof_blob_size(bof_t *bof)
+{
+ if (!bof_is_blob(bof))
+ return 0;
+ return bof->size - 12;
+}
+
+void *bof_blob_value(bof_t *bof)
+{
+ if (!bof_is_blob(bof))
+ return NULL;
+ return bof->value;
+}
+
+/*
+ * string
+ */
+bof_t *bof_string(const char *value)
+{
+ bof_t *string = bof_object();
+
+ if (string == NULL)
+ return NULL;
+ string->type = BOF_TYPE_STRING;
+ string->size = strlen(value) + 1;
+ string->value = calloc(1, string->size);
+ if (string->value == NULL) {
+ bof_decref(string);
+ return NULL;
+ }
+ strcpy(string->value, value);
+ string->size += 12;
+ return string;
+}
+
+/*
+ * int32
+ */
+bof_t *bof_int32(int32_t value)
+{
+ bof_t *int32 = bof_object();
+
+ if (int32 == NULL)
+ return NULL;
+ int32->type = BOF_TYPE_INT32;
+ int32->size = 4;
+ int32->value = calloc(1, int32->size);
+ if (int32->value == NULL) {
+ bof_decref(int32);
+ return NULL;
+ }
+ memcpy(int32->value, &value, 4);
+ int32->size += 12;
+ return int32;
+}
+
+int32_t bof_int32_value(bof_t *bof)
+{
+ return *((uint32_t*)bof->value);
+}
+
+/*
+ * common
+ */
+static void bof_indent(int level)
+{
+ int i;
+
+ for (i = 0; i < level; i++)
+ fprintf(stderr, " ");
+}
+
+static void bof_print_bof(bof_t *bof, int level, int entry)
+{
+ bof_indent(level);
+ if (bof == NULL) {
+ fprintf(stderr, "--NULL-- for entry %d\n", entry);
+ return;
+ }
+ switch (bof->type) {
+ case BOF_TYPE_STRING:
+ fprintf(stderr, "%p string [%s %d]\n", bof, (char*)bof->value, bof->size);
+ break;
+ case BOF_TYPE_INT32:
+ fprintf(stderr, "%p int32 [%d %d]\n", bof, *(int*)bof->value, bof->size);
+ break;
+ case BOF_TYPE_BLOB:
+ fprintf(stderr, "%p blob [%d]\n", bof, bof->size);
+ break;
+ case BOF_TYPE_NULL:
+ fprintf(stderr, "%p null [%d]\n", bof, bof->size);
+ break;
+ case BOF_TYPE_OBJECT:
+ fprintf(stderr, "%p object [%d %d]\n", bof, bof->array_size / 2, bof->size);
+ break;
+ case BOF_TYPE_ARRAY:
+ fprintf(stderr, "%p array [%d %d]\n", bof, bof->array_size, bof->size);
+ break;
+ default:
+ fprintf(stderr, "%p unknown [%d]\n", bof, bof->type);
+ return;
+ }
+}
+
+static void bof_print_rec(bof_t *bof, int level, int entry)
+{
+ unsigned i;
+
+ bof_print_bof(bof, level, entry);
+ for (i = 0; i < bof->array_size; i++) {
+ bof_print_rec(bof->array[i], level + 2, i);
+ }
+}
+
+void bof_print(bof_t *bof)
+{
+ bof_print_rec(bof, 0, 0);
+}
+
+static int bof_read(bof_t *root, FILE *file, long end, int level)
+{
+ bof_t *bof = NULL;
+ int r;
+
+ if (ftell(file) >= end) {
+ return 0;
+ }
+ r = bof_entry_grow(root);
+ if (r)
+ return r;
+ bof = bof_object();
+ if (bof == NULL)
+ return -ENOMEM;
+ bof->offset = ftell(file);
+ r = fread(&bof->type, 4, 1, file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&bof->size, 4, 1, file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&bof->array_size, 4, 1, file);
+ if (r != 1)
+ goto out_err;
+ switch (bof->type) {
+ case BOF_TYPE_STRING:
+ case BOF_TYPE_INT32:
+ case BOF_TYPE_BLOB:
+ bof->value = calloc(1, bof->size - 12);
+ if (bof->value == NULL) {
+ goto out_err;
+ }
+ r = fread(bof->value, bof->size - 12, 1, file);
+ if (r != 1) {
+ fprintf(stderr, "error reading %d\n", bof->size - 12);
+ goto out_err;
+ }
+ break;
+ case BOF_TYPE_NULL:
+ return 0;
+ case BOF_TYPE_OBJECT:
+ case BOF_TYPE_ARRAY:
+ r = bof_read(bof, file, bof->offset + bof->size, level + 2);
+ if (r)
+ goto out_err;
+ break;
+ default:
+ fprintf(stderr, "invalid type %d\n", bof->type);
+ goto out_err;
+ }
+ root->array[root->centry++] = bof;
+ return bof_read(root, file, end, level);
+out_err:
+ bof_decref(bof);
+ return -EINVAL;
+}
+
+bof_t *bof_load_file(const char *filename)
+{
+ bof_t *root = bof_object();
+ int r;
+
+ if (root == NULL) {
+ fprintf(stderr, "%s failed to create root object\n", __func__);
+ return NULL;
+ }
+ root->file = fopen(filename, "r");
+ if (root->file == NULL)
+ goto out_err;
+ r = fseek(root->file, 0L, SEEK_SET);
+ if (r) {
+ fprintf(stderr, "%s failed to seek into file %s\n", __func__, filename);
+ goto out_err;
+ }
+ root->offset = ftell(root->file);
+ r = fread(&root->type, 4, 1, root->file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&root->size, 4, 1, root->file);
+ if (r != 1)
+ goto out_err;
+ r = fread(&root->array_size, 4, 1, root->file);
+ if (r != 1)
+ goto out_err;
+ r = bof_read(root, root->file, root->offset + root->size, 2);
+ if (r)
+ goto out_err;
+ return root;
+out_err:
+ bof_decref(root);
+ return NULL;
+}
+
+void bof_incref(bof_t *bof)
+{
+ bof->refcount++;
+}
+
+void bof_decref(bof_t *bof)
+{
+ unsigned i;
+
+ if (bof == NULL)
+ return;
+ if (--bof->refcount > 0)
+ return;
+ for (i = 0; i < bof->array_size; i++) {
+ bof_decref(bof->array[i]);
+ bof->array[i] = NULL;
+ }
+ bof->array_size = 0;
+ if (bof->file) {
+ fclose(bof->file);
+ bof->file = NULL;
+ }
+ free(bof->array);
+ free(bof->value);
+ free(bof);
+}
+
+static int bof_file_write(bof_t *bof, FILE *file)
+{
+ unsigned i;
+ int r;
+
+ r = fwrite(&bof->type, 4, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ r = fwrite(&bof->size, 4, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ r = fwrite(&bof->array_size, 4, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ switch (bof->type) {
+ case BOF_TYPE_NULL:
+ if (bof->size)
+ return -EINVAL;
+ break;
+ case BOF_TYPE_STRING:
+ case BOF_TYPE_INT32:
+ case BOF_TYPE_BLOB:
+ r = fwrite(bof->value, bof->size - 12, 1, file);
+ if (r != 1)
+ return -EINVAL;
+ break;
+ case BOF_TYPE_OBJECT:
+ case BOF_TYPE_ARRAY:
+ for (i = 0; i < bof->array_size; i++) {
+ r = bof_file_write(bof->array[i], file);
+ if (r)
+ return r;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int bof_dump_file(bof_t *bof, const char *filename)
+{
+ unsigned i;
+ int r = 0;
+
+ if (bof->file) {
+ fclose(bof->file);
+ bof->file = NULL;
+ }
+ bof->file = fopen(filename, "w");
+ if (bof->file == NULL) {
+ fprintf(stderr, "%s failed to open file %s\n", __func__, filename);
+ r = -EINVAL;
+ goto out_err;
+ }
+ r = fseek(bof->file, 0L, SEEK_SET);
+ if (r) {
+ fprintf(stderr, "%s failed to seek into file %s\n", __func__, filename);
+ goto out_err;
+ }
+ r = fwrite(&bof->type, 4, 1, bof->file);
+ if (r != 1)
+ goto out_err;
+ r = fwrite(&bof->size, 4, 1, bof->file);
+ if (r != 1)
+ goto out_err;
+ r = fwrite(&bof->array_size, 4, 1, bof->file);
+ if (r != 1)
+ goto out_err;
+ for (i = 0; i < bof->array_size; i++) {
+ r = bof_file_write(bof->array[i], bof->file);
+ if (r)
+ return r;
+ }
+out_err:
+ fclose(bof->file);
+ bof->file = NULL;
+ return r;
+}
diff --git a/src/gallium/winsys/r600/drm/bof.h b/src/gallium/winsys/r600/drm/bof.h
new file mode 100644
index 0000000000..014affb74f
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/bof.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef BOF_H
+#define BOF_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+#define BOF_TYPE_STRING 0
+#define BOF_TYPE_NULL 1
+#define BOF_TYPE_BLOB 2
+#define BOF_TYPE_OBJECT 3
+#define BOF_TYPE_ARRAY 4
+#define BOF_TYPE_INT32 5
+
+struct bof;
+
+typedef struct bof {
+ struct bof **array;
+ unsigned centry;
+ unsigned nentry;
+ unsigned refcount;
+ FILE *file;
+ uint32_t type;
+ uint32_t size;
+ uint32_t array_size;
+ void *value;
+ long offset;
+} bof_t;
+
+extern int bof_file_flush(bof_t *root);
+extern bof_t *bof_file_new(const char *filename);
+extern int bof_object_dump(bof_t *object, const char *filename);
+
+/* object */
+extern bof_t *bof_object(void);
+extern bof_t *bof_object_get(bof_t *object, const char *keyname);
+extern int bof_object_set(bof_t *object, const char *keyname, bof_t *value);
+/* array */
+extern bof_t *bof_array(void);
+extern int bof_array_append(bof_t *array, bof_t *value);
+extern bof_t *bof_array_get(bof_t *bof, unsigned i);
+extern unsigned bof_array_size(bof_t *bof);
+/* blob */
+extern bof_t *bof_blob(unsigned size, void *value);
+extern unsigned bof_blob_size(bof_t *bof);
+extern void *bof_blob_value(bof_t *bof);
+/* string */
+extern bof_t *bof_string(const char *value);
+/* int32 */
+extern bof_t *bof_int32(int32_t value);
+extern int32_t bof_int32_value(bof_t *bof);
+/* common functions */
+extern void bof_decref(bof_t *bof);
+extern void bof_incref(bof_t *bof);
+extern bof_t *bof_load_file(const char *filename);
+extern int bof_dump_file(bof_t *bof, const char *filename);
+extern void bof_print(bof_t *bof);
+
+static inline int bof_is_object(bof_t *bof){return (bof->type == BOF_TYPE_OBJECT);}
+static inline int bof_is_blob(bof_t *bof){return (bof->type == BOF_TYPE_BLOB);}
+static inline int bof_is_null(bof_t *bof){return (bof->type == BOF_TYPE_NULL);}
+static inline int bof_is_int32(bof_t *bof){return (bof->type == BOF_TYPE_INT32);}
+static inline int bof_is_array(bof_t *bof){return (bof->type == BOF_TYPE_ARRAY);}
+static inline int bof_is_string(bof_t *bof){return (bof->type == BOF_TYPE_STRING);}
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
new file mode 100644
index 0000000000..b772ff0dd9
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ * Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Joakim Sindholt <opensource@zhasha.com>
+ */
+#include <sys/ioctl.h>
+#include "trace/tr_drm.h"
+#include "util/u_inlines.h"
+#include "util/u_debug.h"
+#include "state_tracker/drm_api.h"
+#include "radeon_priv.h"
+#include "r600_screen.h"
+#include "r600_texture.h"
+
+static struct pipe_screen *r600_drm_create_screen(struct drm_api* api, int drmfd)
+{
+ struct radeon *rw = radeon_new(drmfd, 0);
+
+ if (rw == NULL)
+ return NULL;
+ return radeon_create_screen(rw);
+}
+
+boolean r600_buffer_get_handle(struct radeon *rw,
+ struct pipe_resource *buf,
+ struct winsys_handle *whandle)
+{
+ struct drm_gem_flink flink;
+ struct r600_buffer* rbuffer;
+ int r;
+
+ rbuffer = (struct r600_buffer*)buf;
+ if (!rbuffer->flink) {
+ flink.handle = rbuffer->bo->handle;
+ r = ioctl(rw->fd, DRM_IOCTL_GEM_FLINK, &flink);
+ if (r) {
+ return FALSE;
+ }
+ rbuffer->flink = flink.name;
+ }
+ whandle->handle = rbuffer->flink;
+ return TRUE;
+}
+
+static void r600_drm_api_destroy(struct drm_api *api)
+{
+ return;
+}
+
+struct drm_api drm_api_hooks = {
+ .name = "r600",
+ .driver_name = "r600",
+ .create_screen = r600_drm_create_screen,
+ .destroy = r600_drm_api_destroy,
+};
+
+struct drm_api* drm_api_create()
+{
+#ifdef DEBUG
+ return trace_drm_create(&drm_api_hooks);
+#else
+ return &drm_api_hooks;
+#endif
+}
diff --git a/src/gallium/winsys/r600/drm/r600_state.c b/src/gallium/winsys/r600/drm/r600_state.c
new file mode 100644
index 0000000000..d17d6e7954
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_state.c
@@ -0,0 +1,399 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon_priv.h"
+#include "r600d.h"
+
+static int r600_state_pm4_resource(struct radeon_state *state);
+static int r600_state_pm4_cb0(struct radeon_state *state);
+static int r600_state_pm4_vgt(struct radeon_state *state);
+static int r600_state_pm4_db(struct radeon_state *state);
+static int r600_state_pm4_shader(struct radeon_state *state);
+static int r600_state_pm4_draw(struct radeon_state *state);
+static int r600_state_pm4_config(struct radeon_state *state);
+static int r600_state_pm4_generic(struct radeon_state *state);
+static int r700_state_pm4_config(struct radeon_state *state);
+static int r700_state_pm4_cb0(struct radeon_state *state);
+static int r700_state_pm4_db(struct radeon_state *state);
+
+#include "r600_states.h"
+
+/*
+ * r600/r700 state functions
+ */
+static int r600_state_pm4_bytecode(struct radeon_state *state, unsigned offset, unsigned id, unsigned nreg)
+{
+ const struct radeon_register *regs = state->radeon->type[state->type].regs;
+ unsigned i;
+ int r;
+
+ if (!offset) {
+ fprintf(stderr, "%s invalid register for state %d %d\n",
+ __func__, state->type, id);
+ return -EINVAL;
+ }
+ if (offset >= R600_CONFIG_REG_OFFSET && offset < R600_CONFIG_REG_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_CONFIG_REG_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ for (i = 0; i < nreg; i++) {
+ if (regs[id + i].need_reloc) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
+ }
+ }
+ return 0;
+ }
+ if (offset >= R600_CONTEXT_REG_OFFSET && offset < R600_CONTEXT_REG_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONTEXT_REG, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_CONTEXT_REG_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ for (i = 0; i < nreg; i++) {
+ if (regs[id + i].need_reloc) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, regs[id + i].bo_id);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[regs[id + i].bo_id]->handle;
+ }
+ }
+ return 0;
+ }
+ if (offset >= R600_ALU_CONST_OFFSET && offset < R600_ALU_CONST_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_ALU_CONST, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_ALU_CONST_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ return 0;
+ }
+ if (offset >= R600_SAMPLER_OFFSET && offset < R600_SAMPLER_END) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_SAMPLER, nreg);
+ state->pm4[state->cpm4++] = (offset - R600_SAMPLER_OFFSET) >> 2;
+ for (i = 0; i < nreg; i++) {
+ state->pm4[state->cpm4++] = state->states[id + i];
+ }
+ return 0;
+ }
+ fprintf(stderr, "%s unsupported offset 0x%08X\n", __func__, offset);
+ return -EINVAL;
+}
+
+static int r600_state_pm4_generic(struct radeon_state *state)
+{
+ struct radeon *radeon = state->radeon;
+ unsigned i, offset, nreg, type, coffset, loffset, soffset;
+ unsigned start;
+ int r;
+
+ if (!state->nstates)
+ return 0;
+ type = state->type;
+ soffset = (state->id - radeon->type[type].id) * radeon->type[type].stride;
+ offset = loffset = radeon->type[type].regs[0].offset + soffset;
+ start = 0;
+ for (i = 1, nreg = 1; i < state->nstates; i++) {
+ coffset = radeon->type[type].regs[i].offset + soffset;
+ if (coffset == (loffset + 4)) {
+ nreg++;
+ loffset = coffset;
+ } else {
+ r = r600_state_pm4_bytecode(state, offset, start, nreg);
+ if (r) {
+ fprintf(stderr, "%s invalid 0x%08X %d\n", __func__, start, nreg);
+ return r;
+ }
+ offset = loffset = coffset;
+ nreg = 1;
+ start = i;
+ }
+ }
+ return r600_state_pm4_bytecode(state, offset, start, nreg);
+}
+
+static void r600_state_pm4_with_flush(struct radeon_state *state, u32 flags)
+{
+ unsigned i, j, add, size;
+
+ state->nreloc = 0;
+ for (i = 0; i < state->nbo; i++) {
+ for (j = 0, add = 1; j < state->nreloc; j++) {
+ if (state->bo[state->reloc_bo_id[j]] == state->bo[i]) {
+ add = 0;
+ break;
+ }
+ }
+ if (add) {
+ state->reloc_bo_id[state->nreloc++] = i;
+ }
+ }
+ for (i = 0; i < state->nreloc; i++) {
+ size = (state->bo[state->reloc_bo_id[i]]->size + 255) >> 8;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_SYNC, 3);
+ state->pm4[state->cpm4++] = flags;
+ state->pm4[state->cpm4++] = size;
+ state->pm4[state->cpm4++] = 0x00000000;
+ state->pm4[state->cpm4++] = 0x0000000A;
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ state->reloc_pm4_id[i] = state->cpm4;
+ state->pm4[state->cpm4++] = state->bo[state->reloc_bo_id[i]]->handle;
+ }
+}
+
+static int r600_state_pm4_cb0(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_CB_ACTION_ENA(1) |
+ S_0085F0_CB0_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
+ state->pm4[state->cpm4++] = 0x00000002;
+ return 0;
+}
+
+static int r700_state_pm4_cb0(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_CB_ACTION_ENA(1) |
+ S_0085F0_CB0_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int r600_state_pm4_db(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_DB_ACTION_ENA(1) |
+ S_0085F0_DB_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0);
+ state->pm4[state->cpm4++] = 0x00000001;
+ return 0;
+}
+
+static int r700_state_pm4_db(struct radeon_state *state)
+{
+ int r;
+
+ r600_state_pm4_with_flush(state, S_0085F0_DB_ACTION_ENA(1) |
+ S_0085F0_DB_DEST_BASE_ENA(1));
+ r = r600_state_pm4_generic(state);
+ if (r)
+ return r;
+ return 0;
+}
+
+static int r600_state_pm4_config(struct radeon_state *state)
+{
+ state->pm4[state->cpm4++] = PKT3(PKT3_START_3D_CMDBUF, 0);
+ state->pm4[state->cpm4++] = 0x00000000;
+ state->pm4[state->cpm4++] = PKT3(PKT3_CONTEXT_CONTROL, 1);
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
+ state->pm4[state->cpm4++] = 0x00000016;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, 1);
+ state->pm4[state->cpm4++] = 0x00000010;
+ state->pm4[state->cpm4++] = 0x00028000;
+ return r600_state_pm4_generic(state);
+}
+
+static int r700_state_pm4_config(struct radeon_state *state)
+{
+ state->pm4[state->cpm4++] = PKT3(PKT3_CONTEXT_CONTROL, 1);
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = 0x80000000;
+ state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
+ state->pm4[state->cpm4++] = 0x00000016;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_CONFIG_REG, 1);
+ state->pm4[state->cpm4++] = 0x00000010;
+ state->pm4[state->cpm4++] = 0x00028000;
+ return r600_state_pm4_generic(state);
+}
+
+static int r600_state_pm4_shader(struct radeon_state *state)
+{
+ r600_state_pm4_with_flush(state, S_0085F0_SH_ACTION_ENA(1));
+ return r600_state_pm4_generic(state);
+}
+
+static int r600_state_pm4_vgt(struct radeon_state *state)
+{
+ int r;
+
+ r = r600_state_pm4_bytecode(state, R_028400_VGT_MAX_VTX_INDX, R600_VGT__VGT_MAX_VTX_INDX, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_028404_VGT_MIN_VTX_INDX, R600_VGT__VGT_MIN_VTX_INDX, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_028408_VGT_INDX_OFFSET, R600_VGT__VGT_INDX_OFFSET, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, R600_VGT__VGT_MULTI_PRIM_IB_RESET_INDX, 1);
+ if (r)
+ return r;
+ r = r600_state_pm4_bytecode(state, R_008958_VGT_PRIMITIVE_TYPE, R600_VGT__VGT_PRIMITIVE_TYPE, 1);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = PKT3(PKT3_INDEX_TYPE, 0);
+ state->pm4[state->cpm4++] = state->states[R600_VGT__VGT_DMA_INDEX_TYPE];
+ state->pm4[state->cpm4++] = PKT3(PKT3_NUM_INSTANCES, 0);
+ state->pm4[state->cpm4++] = state->states[R600_VGT__VGT_DMA_NUM_INSTANCES];
+ return 0;
+}
+
+static int r600_state_pm4_draw(struct radeon_state *state)
+{
+ unsigned i;
+ int r;
+
+ if (state->nbo) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX, 3);
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DMA_BASE];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DMA_BASE_HI];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, 0);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[0]->handle;
+ } else if (state->nimmd) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_IMMD, state->nimmd + 1);
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
+ for (i = 0; i < state->nimmd; i++) {
+ state->pm4[state->cpm4++] = state->immd[i];
+ }
+ } else {
+ state->pm4[state->cpm4++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1);
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_NUM_INDICES];
+ state->pm4[state->cpm4++] = state->states[R600_DRAW__VGT_DRAW_INITIATOR];
+ }
+ state->pm4[state->cpm4++] = PKT3(PKT3_EVENT_WRITE, 0);
+ state->pm4[state->cpm4++] = 0x00000016;
+ return 0;
+}
+
+static int r600_state_pm4_resource(struct radeon_state *state)
+{
+ u32 flags, type, nbo, offset, soffset;
+ int r;
+
+ soffset = (state->id - state->radeon->type[state->type].id) * state->radeon->type[state->type].stride;
+ type = G_038018_TYPE(state->states[6]);
+ switch (type) {
+ case 2:
+ flags = S_0085F0_TC_ACTION_ENA(1);
+ nbo = 2;
+ break;
+ case 3:
+ flags = S_0085F0_VC_ACTION_ENA(1);
+ nbo = 1;
+ break;
+ default:
+ return 0;
+ }
+ if (state->nbo != nbo) {
+ fprintf(stderr, "%s need %d bo got %d\n", __func__, nbo, state->nbo);
+ return -EINVAL;
+ }
+ r600_state_pm4_with_flush(state, flags);
+ offset = state->radeon->type[state->type].regs[0].offset + soffset;
+ state->pm4[state->cpm4++] = PKT3(PKT3_SET_RESOURCE, 7);
+ state->pm4[state->cpm4++] = (offset - R_038000_SQ_TEX_RESOURCE_WORD0_0) >> 2;
+ state->pm4[state->cpm4++] = state->states[0];
+ state->pm4[state->cpm4++] = state->states[1];
+ state->pm4[state->cpm4++] = state->states[2];
+ state->pm4[state->cpm4++] = state->states[3];
+ state->pm4[state->cpm4++] = state->states[4];
+ state->pm4[state->cpm4++] = state->states[5];
+ state->pm4[state->cpm4++] = state->states[6];
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, 0);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[0]->handle;
+ if (type == 2) {
+ state->pm4[state->cpm4++] = PKT3(PKT3_NOP, 0);
+ r = radeon_state_reloc(state, state->cpm4, 1);
+ if (r)
+ return r;
+ state->pm4[state->cpm4++] = state->bo[1]->handle;
+ }
+ return 0;
+}
+
+int r600_init(struct radeon *radeon)
+{
+ switch (radeon->family) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ radeon->ntype = R600_NTYPE;
+ radeon->nstate = R600_NSTATE;
+ radeon->type = R600_types;
+ break;
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ radeon->ntype = R600_NTYPE;
+ radeon->nstate = R600_NSTATE;
+ radeon->type = R700_types;
+ break;
+ default:
+ fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+ __func__, radeon->device);
+ return -EINVAL;
+ }
+ return 0;
+}
diff --git a/src/gallium/winsys/r600/drm/r600_states.h b/src/gallium/winsys/r600/drm/r600_states.h
new file mode 100644
index 0000000000..5896df21b2
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600_states.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef R600_STATES_H
+#define R600_STATES_H
+
+static const struct radeon_register R600_CONFIG_names[] = {
+ {0x00008C00, 0, 0, "SQ_CONFIG"},
+ {0x00008C04, 0, 0, "SQ_GPR_RESOURCE_MGMT_1"},
+ {0x00008C08, 0, 0, "SQ_GPR_RESOURCE_MGMT_2"},
+ {0x00008C0C, 0, 0, "SQ_THREAD_RESOURCE_MGMT"},
+ {0x00008C10, 0, 0, "SQ_STACK_RESOURCE_MGMT_1"},
+ {0x00008C14, 0, 0, "SQ_STACK_RESOURCE_MGMT_2"},
+ {0x00008D8C, 0, 0, "SQ_DYN_GPR_CNTL_PS_FLUSH_REQ"},
+ {0x00009508, 0, 0, "TA_CNTL_AUX"},
+ {0x00009714, 0, 0, "VC_ENHANCE"},
+ {0x00009830, 0, 0, "DB_DEBUG"},
+ {0x00009838, 0, 0, "DB_WATERMARKS"},
+ {0x00028350, 0, 0, "SX_MISC"},
+ {0x000286C8, 0, 0, "SPI_THREAD_GROUPING"},
+ {0x000287A0, 0, 0, "CB_SHADER_CONTROL"},
+ {0x000288A8, 0, 0, "SQ_ESGS_RING_ITEMSIZE"},
+ {0x000288AC, 0, 0, "SQ_GSVS_RING_ITEMSIZE"},
+ {0x000288B0, 0, 0, "SQ_ESTMP_RING_ITEMSIZE"},
+ {0x000288B4, 0, 0, "SQ_GSTMP_RING_ITEMSIZE"},
+ {0x000288B8, 0, 0, "SQ_VSTMP_RING_ITEMSIZE"},
+ {0x000288BC, 0, 0, "SQ_PSTMP_RING_ITEMSIZE"},
+ {0x000288C0, 0, 0, "SQ_FBUF_RING_ITEMSIZE"},
+ {0x000288C4, 0, 0, "SQ_REDUC_RING_ITEMSIZE"},
+ {0x000288C8, 0, 0, "SQ_GS_VERT_ITEMSIZE"},
+ {0x00028A10, 0, 0, "VGT_OUTPUT_PATH_CNTL"},
+ {0x00028A14, 0, 0, "VGT_HOS_CNTL"},
+ {0x00028A18, 0, 0, "VGT_HOS_MAX_TESS_LEVEL"},
+ {0x00028A1C, 0, 0, "VGT_HOS_MIN_TESS_LEVEL"},
+ {0x00028A20, 0, 0, "VGT_HOS_REUSE_DEPTH"},
+ {0x00028A24, 0, 0, "VGT_GROUP_PRIM_TYPE"},
+ {0x00028A28, 0, 0, "VGT_GROUP_FIRST_DECR"},
+ {0x00028A2C, 0, 0, "VGT_GROUP_DECR"},
+ {0x00028A30, 0, 0, "VGT_GROUP_VECT_0_CNTL"},
+ {0x00028A34, 0, 0, "VGT_GROUP_VECT_1_CNTL"},
+ {0x00028A38, 0, 0, "VGT_GROUP_VECT_0_FMT_CNTL"},
+ {0x00028A3C, 0, 0, "VGT_GROUP_VECT_1_FMT_CNTL"},
+ {0x00028A40, 0, 0, "VGT_GS_MODE"},
+ {0x00028A4C, 0, 0, "PA_SC_MODE_CNTL"},
+ {0x00028AB0, 0, 0, "VGT_STRMOUT_EN"},
+ {0x00028AB4, 0, 0, "VGT_REUSE_OFF"},
+ {0x00028AB8, 0, 0, "VGT_VTX_CNT_EN"},
+ {0x00028B20, 0, 0, "VGT_STRMOUT_BUFFER_EN"},
+};
+
+static const struct radeon_register R600_CB_CNTL_names[] = {
+ {0x00028120, 0, 0, "CB_CLEAR_RED"},
+ {0x00028124, 0, 0, "CB_CLEAR_GREEN"},
+ {0x00028128, 0, 0, "CB_CLEAR_BLUE"},
+ {0x0002812C, 0, 0, "CB_CLEAR_ALPHA"},
+ {0x0002823C, 0, 0, "CB_SHADER_MASK"},
+ {0x00028238, 0, 0, "CB_TARGET_MASK"},
+ {0x00028424, 0, 0, "CB_FOG_RED"},
+ {0x00028428, 0, 0, "CB_FOG_GREEN"},
+ {0x0002842C, 0, 0, "CB_FOG_BLUE"},
+ {0x00028808, 0, 0, "CB_COLOR_CONTROL"},
+ {0x00028C04, 0, 0, "PA_SC_AA_CONFIG"},
+ {0x00028C1C, 0, 0, "PA_SC_AA_SAMPLE_LOCS_MCTX"},
+ {0x00028C20, 0, 0, "PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX"},
+ {0x00028C30, 0, 0, "CB_CLRCMP_CONTROL"},
+ {0x00028C34, 0, 0, "CB_CLRCMP_SRC"},
+ {0x00028C38, 0, 0, "CB_CLRCMP_DST"},
+ {0x00028C3C, 0, 0, "CB_CLRCMP_MSK"},
+ {0x00028C48, 0, 0, "PA_SC_AA_MASK"},
+};
+
+static const struct radeon_register R600_RASTERIZER_names[] = {
+ {0x000286D4, 0, 0, "SPI_INTERP_CONTROL_0"},
+ {0x00028810, 0, 0, "PA_CL_CLIP_CNTL"},
+ {0x00028814, 0, 0, "PA_SU_SC_MODE_CNTL"},
+ {0x0002881C, 0, 0, "PA_CL_VS_OUT_CNTL"},
+ {0x00028820, 0, 0, "PA_CL_NANINF_CNTL"},
+ {0x00028A00, 0, 0, "PA_SU_POINT_SIZE"},
+ {0x00028A04, 0, 0, "PA_SU_POINT_MINMAX"},
+ {0x00028A08, 0, 0, "PA_SU_LINE_CNTL"},
+ {0x00028A0C, 0, 0, "PA_SC_LINE_STIPPLE"},
+ {0x00028A48, 0, 0, "PA_SC_MPASS_PS_CNTL"},
+ {0x00028C00, 0, 0, "PA_SC_LINE_CNTL"},
+ {0x00028C0C, 0, 0, "PA_CL_GB_VERT_CLIP_ADJ"},
+ {0x00028C10, 0, 0, "PA_CL_GB_VERT_DISC_ADJ"},
+ {0x00028C14, 0, 0, "PA_CL_GB_HORZ_CLIP_ADJ"},
+ {0x00028C18, 0, 0, "PA_CL_GB_HORZ_DISC_ADJ"},
+ {0x00028DF8, 0, 0, "PA_SU_POLY_OFFSET_DB_FMT_CNTL"},
+ {0x00028DFC, 0, 0, "PA_SU_POLY_OFFSET_CLAMP"},
+ {0x00028E00, 0, 0, "PA_SU_POLY_OFFSET_FRONT_SCALE"},
+ {0x00028E04, 0, 0, "PA_SU_POLY_OFFSET_FRONT_OFFSET"},
+ {0x00028E08, 0, 0, "PA_SU_POLY_OFFSET_BACK_SCALE"},
+ {0x00028E0C, 0, 0, "PA_SU_POLY_OFFSET_BACK_OFFSET"},
+};
+
+static const struct radeon_register R600_VIEWPORT_names[] = {
+ {0x000282D0, 0, 0, "PA_SC_VPORT_ZMIN_0"},
+ {0x000282D4, 0, 0, "PA_SC_VPORT_ZMAX_0"},
+ {0x0002843C, 0, 0, "PA_CL_VPORT_XSCALE_0"},
+ {0x00028444, 0, 0, "PA_CL_VPORT_YSCALE_0"},
+ {0x0002844C, 0, 0, "PA_CL_VPORT_ZSCALE_0"},
+ {0x00028440, 0, 0, "PA_CL_VPORT_XOFFSET_0"},
+ {0x00028448, 0, 0, "PA_CL_VPORT_YOFFSET_0"},
+ {0x00028450, 0, 0, "PA_CL_VPORT_ZOFFSET_0"},
+ {0x00028818, 0, 0, "PA_CL_VTE_CNTL"},
+};
+
+static const struct radeon_register R600_SCISSOR_names[] = {
+ {0x00028030, 0, 0, "PA_SC_SCREEN_SCISSOR_TL"},
+ {0x00028034, 0, 0, "PA_SC_SCREEN_SCISSOR_BR"},
+ {0x00028200, 0, 0, "PA_SC_WINDOW_OFFSET"},
+ {0x00028204, 0, 0, "PA_SC_WINDOW_SCISSOR_TL"},
+ {0x00028208, 0, 0, "PA_SC_WINDOW_SCISSOR_BR"},
+ {0x0002820C, 0, 0, "PA_SC_CLIPRECT_RULE"},
+ {0x00028210, 0, 0, "PA_SC_CLIPRECT_0_TL"},
+ {0x00028214, 0, 0, "PA_SC_CLIPRECT_0_BR"},
+ {0x00028218, 0, 0, "PA_SC_CLIPRECT_1_TL"},
+ {0x0002821C, 0, 0, "PA_SC_CLIPRECT_1_BR"},
+ {0x00028220, 0, 0, "PA_SC_CLIPRECT_2_TL"},
+ {0x00028224, 0, 0, "PA_SC_CLIPRECT_2_BR"},
+ {0x00028228, 0, 0, "PA_SC_CLIPRECT_3_TL"},
+ {0x0002822C, 0, 0, "PA_SC_CLIPRECT_3_BR"},
+ {0x00028230, 0, 0, "PA_SC_EDGERULE"},
+ {0x00028240, 0, 0, "PA_SC_GENERIC_SCISSOR_TL"},
+ {0x00028244, 0, 0, "PA_SC_GENERIC_SCISSOR_BR"},
+ {0x00028250, 0, 0, "PA_SC_VPORT_SCISSOR_0_TL"},
+ {0x00028254, 0, 0, "PA_SC_VPORT_SCISSOR_0_BR"},
+};
+
+static const struct radeon_register R600_BLEND_names[] = {
+ {0x00028414, 0, 0, "CB_BLEND_RED"},
+ {0x00028418, 0, 0, "CB_BLEND_GREEN"},
+ {0x0002841C, 0, 0, "CB_BLEND_BLUE"},
+ {0x00028420, 0, 0, "CB_BLEND_ALPHA"},
+ {0x00028780, 0, 0, "CB_BLEND0_CONTROL"},
+ {0x00028784, 0, 0, "CB_BLEND1_CONTROL"},
+ {0x00028788, 0, 0, "CB_BLEND2_CONTROL"},
+ {0x0002878C, 0, 0, "CB_BLEND3_CONTROL"},
+ {0x00028790, 0, 0, "CB_BLEND4_CONTROL"},
+ {0x00028794, 0, 0, "CB_BLEND5_CONTROL"},
+ {0x00028798, 0, 0, "CB_BLEND6_CONTROL"},
+ {0x0002879C, 0, 0, "CB_BLEND7_CONTROL"},
+ {0x00028804, 0, 0, "CB_BLEND_CONTROL"},
+};
+
+static const struct radeon_register R600_DSA_names[] = {
+ {0x00028028, 0, 0, "DB_STENCIL_CLEAR"},
+ {0x0002802C, 0, 0, "DB_DEPTH_CLEAR"},
+ {0x00028410, 0, 0, "SX_ALPHA_TEST_CONTROL"},
+ {0x00028430, 0, 0, "DB_STENCILREFMASK"},
+ {0x00028434, 0, 0, "DB_STENCILREFMASK_BF"},
+ {0x00028438, 0, 0, "SX_ALPHA_REF"},
+ {0x000286E0, 0, 0, "SPI_FOG_FUNC_SCALE"},
+ {0x000286E4, 0, 0, "SPI_FOG_FUNC_BIAS"},
+ {0x000286DC, 0, 0, "SPI_FOG_CNTL"},
+ {0x00028800, 0, 0, "DB_DEPTH_CONTROL"},
+ {0x0002880C, 0, 0, "DB_SHADER_CONTROL"},
+ {0x00028D0C, 0, 0, "DB_RENDER_CONTROL"},
+ {0x00028D10, 0, 0, "DB_RENDER_OVERRIDE"},
+ {0x00028D2C, 0, 0, "DB_SRESULTS_COMPARE_STATE1"},
+ {0x00028D30, 0, 0, "DB_PRELOAD_CONTROL"},
+ {0x00028D44, 0, 0, "DB_ALPHA_TO_MASK"},
+};
+
+static const struct radeon_register R600_VS_SHADER_names[] = {
+ {0x00028380, 0, 0, "SQ_VTX_SEMANTIC_0"},
+ {0x00028384, 0, 0, "SQ_VTX_SEMANTIC_1"},
+ {0x00028388, 0, 0, "SQ_VTX_SEMANTIC_2"},
+ {0x0002838C, 0, 0, "SQ_VTX_SEMANTIC_3"},
+ {0x00028390, 0, 0, "SQ_VTX_SEMANTIC_4"},
+ {0x00028394, 0, 0, "SQ_VTX_SEMANTIC_5"},
+ {0x00028398, 0, 0, "SQ_VTX_SEMANTIC_6"},
+ {0x0002839C, 0, 0, "SQ_VTX_SEMANTIC_7"},
+ {0x000283A0, 0, 0, "SQ_VTX_SEMANTIC_8"},
+ {0x000283A4, 0, 0, "SQ_VTX_SEMANTIC_9"},
+ {0x000283A8, 0, 0, "SQ_VTX_SEMANTIC_10"},
+ {0x000283AC, 0, 0, "SQ_VTX_SEMANTIC_11"},
+ {0x000283B0, 0, 0, "SQ_VTX_SEMANTIC_12"},
+ {0x000283B4, 0, 0, "SQ_VTX_SEMANTIC_13"},
+ {0x000283B8, 0, 0, "SQ_VTX_SEMANTIC_14"},
+ {0x000283BC, 0, 0, "SQ_VTX_SEMANTIC_15"},
+ {0x000283C0, 0, 0, "SQ_VTX_SEMANTIC_16"},
+ {0x000283C4, 0, 0, "SQ_VTX_SEMANTIC_17"},
+ {0x000283C8, 0, 0, "SQ_VTX_SEMANTIC_18"},
+ {0x000283CC, 0, 0, "SQ_VTX_SEMANTIC_19"},
+ {0x000283D0, 0, 0, "SQ_VTX_SEMANTIC_20"},
+ {0x000283D4, 0, 0, "SQ_VTX_SEMANTIC_21"},
+ {0x000283D8, 0, 0, "SQ_VTX_SEMANTIC_22"},
+ {0x000283DC, 0, 0, "SQ_VTX_SEMANTIC_23"},
+ {0x000283E0, 0, 0, "SQ_VTX_SEMANTIC_24"},
+ {0x000283E4, 0, 0, "SQ_VTX_SEMANTIC_25"},
+ {0x000283E8, 0, 0, "SQ_VTX_SEMANTIC_26"},
+ {0x000283EC, 0, 0, "SQ_VTX_SEMANTIC_27"},
+ {0x000283F0, 0, 0, "SQ_VTX_SEMANTIC_28"},
+ {0x000283F4, 0, 0, "SQ_VTX_SEMANTIC_29"},
+ {0x000283F8, 0, 0, "SQ_VTX_SEMANTIC_30"},
+ {0x000283FC, 0, 0, "SQ_VTX_SEMANTIC_31"},
+ {0x00028614, 0, 0, "SPI_VS_OUT_ID_0"},
+ {0x00028618, 0, 0, "SPI_VS_OUT_ID_1"},
+ {0x0002861C, 0, 0, "SPI_VS_OUT_ID_2"},
+ {0x00028620, 0, 0, "SPI_VS_OUT_ID_3"},
+ {0x00028624, 0, 0, "SPI_VS_OUT_ID_4"},
+ {0x00028628, 0, 0, "SPI_VS_OUT_ID_5"},
+ {0x0002862C, 0, 0, "SPI_VS_OUT_ID_6"},
+ {0x00028630, 0, 0, "SPI_VS_OUT_ID_7"},
+ {0x00028634, 0, 0, "SPI_VS_OUT_ID_8"},
+ {0x00028638, 0, 0, "SPI_VS_OUT_ID_9"},
+ {0x000286C4, 0, 0, "SPI_VS_OUT_CONFIG"},
+ {0x00028858, 1, 0, "SQ_PGM_START_VS"},
+ {0x00028868, 0, 0, "SQ_PGM_RESOURCES_VS"},
+ {0x00028894, 1, 1, "SQ_PGM_START_FS"},
+ {0x000288A4, 0, 0, "SQ_PGM_RESOURCES_FS"},
+ {0x000288D0, 0, 0, "SQ_PGM_CF_OFFSET_VS"},
+ {0x000288DC, 0, 0, "SQ_PGM_CF_OFFSET_FS"},
+};
+
+static const struct radeon_register R600_PS_SHADER_names[] = {
+ {0x00028644, 0, 0, "SPI_PS_INPUT_CNTL_0"},
+ {0x00028648, 0, 0, "SPI_PS_INPUT_CNTL_1"},
+ {0x0002864C, 0, 0, "SPI_PS_INPUT_CNTL_2"},
+ {0x00028650, 0, 0, "SPI_PS_INPUT_CNTL_3"},
+ {0x00028654, 0, 0, "SPI_PS_INPUT_CNTL_4"},
+ {0x00028658, 0, 0, "SPI_PS_INPUT_CNTL_5"},
+ {0x0002865C, 0, 0, "SPI_PS_INPUT_CNTL_6"},
+ {0x00028660, 0, 0, "SPI_PS_INPUT_CNTL_7"},
+ {0x00028664, 0, 0, "SPI_PS_INPUT_CNTL_8"},
+ {0x00028668, 0, 0, "SPI_PS_INPUT_CNTL_9"},
+ {0x0002866C, 0, 0, "SPI_PS_INPUT_CNTL_10"},
+ {0x00028670, 0, 0, "SPI_PS_INPUT_CNTL_11"},
+ {0x00028674, 0, 0, "SPI_PS_INPUT_CNTL_12"},
+ {0x00028678, 0, 0, "SPI_PS_INPUT_CNTL_13"},
+ {0x0002867C, 0, 0, "SPI_PS_INPUT_CNTL_14"},
+ {0x00028680, 0, 0, "SPI_PS_INPUT_CNTL_15"},
+ {0x00028684, 0, 0, "SPI_PS_INPUT_CNTL_16"},
+ {0x00028688, 0, 0, "SPI_PS_INPUT_CNTL_17"},
+ {0x0002868C, 0, 0, "SPI_PS_INPUT_CNTL_18"},
+ {0x00028690, 0, 0, "SPI_PS_INPUT_CNTL_19"},
+ {0x00028694, 0, 0, "SPI_PS_INPUT_CNTL_20"},
+ {0x00028698, 0, 0, "SPI_PS_INPUT_CNTL_21"},
+ {0x0002869C, 0, 0, "SPI_PS_INPUT_CNTL_22"},
+ {0x000286A0, 0, 0, "SPI_PS_INPUT_CNTL_23"},
+ {0x000286A4, 0, 0, "SPI_PS_INPUT_CNTL_24"},
+ {0x000286A8, 0, 0, "SPI_PS_INPUT_CNTL_25"},
+ {0x000286AC, 0, 0, "SPI_PS_INPUT_CNTL_26"},
+ {0x000286B0, 0, 0, "SPI_PS_INPUT_CNTL_27"},
+ {0x000286B4, 0, 0, "SPI_PS_INPUT_CNTL_28"},
+ {0x000286B8, 0, 0, "SPI_PS_INPUT_CNTL_29"},
+ {0x000286BC, 0, 0, "SPI_PS_INPUT_CNTL_30"},
+ {0x000286C0, 0, 0, "SPI_PS_INPUT_CNTL_31"},
+ {0x000286CC, 0, 0, "SPI_PS_IN_CONTROL_0"},
+ {0x000286D0, 0, 0, "SPI_PS_IN_CONTROL_1"},
+ {0x000286D8, 0, 0, "SPI_INPUT_Z"},
+ {0x00028840, 1, 0, "SQ_PGM_START_PS"},
+ {0x00028850, 0, 0, "SQ_PGM_RESOURCES_PS"},
+ {0x00028854, 0, 0, "SQ_PGM_EXPORTS_PS"},
+ {0x000288CC, 0, 0, "SQ_PGM_CF_OFFSET_PS"},
+};
+
+static const struct radeon_register R600_PS_CONSTANT_names[] = {
+ {0x00030000, 0, 0, "SQ_ALU_CONSTANT0_0"},
+ {0x00030004, 0, 0, "SQ_ALU_CONSTANT1_0"},
+ {0x00030008, 0, 0, "SQ_ALU_CONSTANT2_0"},
+ {0x0003000C, 0, 0, "SQ_ALU_CONSTANT3_0"},
+};
+
+static const struct radeon_register R600_VS_CONSTANT_names[] = {
+ {0x00031000, 0, 0, "SQ_ALU_CONSTANT0_256"},
+ {0x00031004, 0, 0, "SQ_ALU_CONSTANT1_256"},
+ {0x00031008, 0, 0, "SQ_ALU_CONSTANT2_256"},
+ {0x0003100C, 0, 0, "SQ_ALU_CONSTANT3_256"},
+};
+
+static const struct radeon_register R600_PS_RESOURCE_names[] = {
+ {0x00038000, 0, 0, "RESOURCE0_WORD0"},
+ {0x00038004, 0, 0, "RESOURCE0_WORD1"},
+ {0x00038008, 0, 0, "RESOURCE0_WORD2"},
+ {0x0003800C, 0, 0, "RESOURCE0_WORD3"},
+ {0x00038010, 0, 0, "RESOURCE0_WORD4"},
+ {0x00038014, 0, 0, "RESOURCE0_WORD5"},
+ {0x00038018, 0, 0, "RESOURCE0_WORD6"},
+};
+
+static const struct radeon_register R600_VS_RESOURCE_names[] = {
+ {0x00039180, 0, 0, "RESOURCE160_WORD0"},
+ {0x00039184, 0, 0, "RESOURCE160_WORD1"},
+ {0x00039188, 0, 0, "RESOURCE160_WORD2"},
+ {0x0003918C, 0, 0, "RESOURCE160_WORD3"},
+ {0x00039190, 0, 0, "RESOURCE160_WORD4"},
+ {0x00039194, 0, 0, "RESOURCE160_WORD5"},
+ {0x00039198, 0, 0, "RESOURCE160_WORD6"},
+};
+
+static const struct radeon_register R600_FS_RESOURCE_names[] = {
+ {0x0003A300, 0, 0, "RESOURCE320_WORD0"},
+ {0x0003A304, 0, 0, "RESOURCE320_WORD1"},
+ {0x0003A308, 0, 0, "RESOURCE320_WORD2"},
+ {0x0003A30C, 0, 0, "RESOURCE320_WORD3"},
+ {0x0003A310, 0, 0, "RESOURCE320_WORD4"},
+ {0x0003A314, 0, 0, "RESOURCE320_WORD5"},
+ {0x0003A318, 0, 0, "RESOURCE320_WORD6"},
+};
+
+static const struct radeon_register R600_GS_RESOURCE_names[] = {
+ {0x0003A4C0, 0, 0, "RESOURCE336_WORD0"},
+ {0x0003A4C4, 0, 0, "RESOURCE336_WORD1"},
+ {0x0003A4C8, 0, 0, "RESOURCE336_WORD2"},
+ {0x0003A4CC, 0, 0, "RESOURCE336_WORD3"},
+ {0x0003A4D0, 0, 0, "RESOURCE336_WORD4"},
+ {0x0003A4D4, 0, 0, "RESOURCE336_WORD5"},
+ {0x0003A4D8, 0, 0, "RESOURCE336_WORD6"},
+};
+
+static const struct radeon_register R600_PS_SAMPLER_names[] = {
+ {0x0003C000, 0, 0, "SQ_TEX_SAMPLER_WORD0_0"},
+ {0x0003C004, 0, 0, "SQ_TEX_SAMPLER_WORD1_0"},
+ {0x0003C008, 0, 0, "SQ_TEX_SAMPLER_WORD2_0"},
+};
+
+static const struct radeon_register R600_VS_SAMPLER_names[] = {
+ {0x0003C0D8, 0, 0, "SQ_TEX_SAMPLER_WORD0_18"},
+ {0x0003C0DC, 0, 0, "SQ_TEX_SAMPLER_WORD1_18"},
+ {0x0003C0E0, 0, 0, "SQ_TEX_SAMPLER_WORD2_18"},
+};
+
+static const struct radeon_register R600_GS_SAMPLER_names[] = {
+ {0x0003C1B0, 0, 0, "SQ_TEX_SAMPLER_WORD0_36"},
+ {0x0003C1B4, 0, 0, "SQ_TEX_SAMPLER_WORD1_36"},
+ {0x0003C1B8, 0, 0, "SQ_TEX_SAMPLER_WORD2_36"},
+};
+
+static const struct radeon_register R600_PS_SAMPLER_BORDER_names[] = {
+ {0x0000A400, 0, 0, "TD_PS_SAMPLER0_BORDER_RED"},
+ {0x0000A404, 0, 0, "TD_PS_SAMPLER0_BORDER_GREEN"},
+ {0x0000A408, 0, 0, "TD_PS_SAMPLER0_BORDER_BLUE"},
+ {0x0000A40C, 0, 0, "TD_PS_SAMPLER0_BORDER_ALPHA"},
+};
+
+static const struct radeon_register R600_VS_SAMPLER_BORDER_names[] = {
+ {0x0000A600, 0, 0, "TD_VS_SAMPLER0_BORDER_RED"},
+ {0x0000A604, 0, 0, "TD_VS_SAMPLER0_BORDER_GREEN"},
+ {0x0000A608, 0, 0, "TD_VS_SAMPLER0_BORDER_BLUE"},
+ {0x0000A60C, 0, 0, "TD_VS_SAMPLER0_BORDER_ALPHA"},
+};
+
+static const struct radeon_register R600_GS_SAMPLER_BORDER_names[] = {
+ {0x0000A800, 0, 0, "TD_GS_SAMPLER0_BORDER_RED"},
+ {0x0000A804, 0, 0, "TD_GS_SAMPLER0_BORDER_GREEN"},
+ {0x0000A808, 0, 0, "TD_GS_SAMPLER0_BORDER_BLUE"},
+ {0x0000A80C, 0, 0, "TD_GS_SAMPLER0_BORDER_ALPHA"},
+};
+
+static const struct radeon_register R600_CB0_names[] = {
+ {0x00028040, 1, 0, "CB_COLOR0_BASE"},
+ {0x000280A0, 0, 0, "CB_COLOR0_INFO"},
+ {0x00028060, 0, 0, "CB_COLOR0_SIZE"},
+ {0x00028080, 0, 0, "CB_COLOR0_VIEW"},
+ {0x000280E0, 1, 1, "CB_COLOR0_FRAG"},
+ {0x000280C0, 1, 2, "CB_COLOR0_TILE"},
+ {0x00028100, 0, 0, "CB_COLOR0_MASK"},
+};
+
+static const struct radeon_register R600_DB_names[] = {
+ {0x0002800C, 1, 0, "DB_DEPTH_BASE"},
+ {0x00028000, 0, 0, "DB_DEPTH_SIZE"},
+ {0x00028004, 0, 0, "DB_DEPTH_VIEW"},
+ {0x00028010, 0, 0, "DB_DEPTH_INFO"},
+ {0x00028D24, 0, 0, "DB_HTILE_SURFACE"},
+ {0x00028D34, 0, 0, "DB_PREFETCH_LIMIT"},
+};
+
+static const struct radeon_register R600_VGT_names[] = {
+ {0x00008958, 0, 0, "VGT_PRIMITIVE_TYPE"},
+ {0x00028400, 0, 0, "VGT_MAX_VTX_INDX"},
+ {0x00028404, 0, 0, "VGT_MIN_VTX_INDX"},
+ {0x00028408, 0, 0, "VGT_INDX_OFFSET"},
+ {0x0002840C, 0, 0, "VGT_MULTI_PRIM_IB_RESET_INDX"},
+ {0x00028A7C, 0, 0, "VGT_DMA_INDEX_TYPE"},
+ {0x00028A84, 0, 0, "VGT_PRIMITIVEID_EN"},
+ {0x00028A88, 0, 0, "VGT_DMA_NUM_INSTANCES"},
+ {0x00028A94, 0, 0, "VGT_MULTI_PRIM_IB_RESET_EN"},
+ {0x00028AA0, 0, 0, "VGT_INSTANCE_STEP_RATE_0"},
+ {0x00028AA4, 0, 0, "VGT_INSTANCE_STEP_RATE_1"},
+};
+
+static const struct radeon_register R600_DRAW_names[] = {
+ {0x00008970, 0, 0, "VGT_NUM_INDICES"},
+ {0x000287E4, 0, 0, "VGT_DMA_BASE_HI"},
+ {0x000287E8, 1, 0, "VGT_DMA_BASE"},
+ {0x000287F0, 0, 0, "VGT_DRAW_INITIATOR"},
+};
+
+static struct radeon_type R600_types[] = {
+ { 128, 0, 0x00000000, 0x00000000, 0x0000, 0, "R600_CONFIG", 41, r600_state_pm4_config, R600_CONFIG_names},
+ { 128, 1, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB_CNTL", 18, r600_state_pm4_generic, R600_CB_CNTL_names},
+ { 128, 2, 0x00000000, 0x00000000, 0x0000, 0, "R600_RASTERIZER", 21, r600_state_pm4_generic, R600_RASTERIZER_names},
+ { 128, 3, 0x00000000, 0x00000000, 0x0000, 0, "R600_VIEWPORT", 9, r600_state_pm4_generic, R600_VIEWPORT_names},
+ { 128, 4, 0x00000000, 0x00000000, 0x0000, 0, "R600_SCISSOR", 19, r600_state_pm4_generic, R600_SCISSOR_names},
+ { 128, 5, 0x00000000, 0x00000000, 0x0000, 0, "R600_BLEND", 13, r600_state_pm4_generic, R600_BLEND_names},
+ { 128, 6, 0x00000000, 0x00000000, 0x0000, 0, "R600_DSA", 16, r600_state_pm4_generic, R600_DSA_names},
+ { 128, 7, 0x00000000, 0x00000000, 0x0000, 0, "R600_VS_SHADER", 49, r600_state_pm4_shader, R600_VS_SHADER_names},
+ { 128, 8, 0x00000000, 0x00000000, 0x0000, 0, "R600_PS_SHADER", 39, r600_state_pm4_shader, R600_PS_SHADER_names},
+ { 128, 9, 0x00030000, 0x00031000, 0x0010, 0, "R600_PS_CONSTANT", 4, r600_state_pm4_generic, R600_PS_CONSTANT_names},
+ { 128, 265, 0x00031000, 0x00032000, 0x0010, 0, "R600_VS_CONSTANT", 4, r600_state_pm4_generic, R600_VS_CONSTANT_names},
+ { 128, 521, 0x00038000, 0x00039180, 0x001C, 0, "R600_PS_RESOURCE", 7, r600_state_pm4_resource, R600_PS_RESOURCE_names},
+ { 128, 681, 0x00039180, 0x0003A300, 0x001C, 0, "R600_VS_RESOURCE", 7, r600_state_pm4_resource, R600_VS_RESOURCE_names},
+ { 128, 841, 0x00039180, 0x0003A300, 0x001C, 0, "R600_FS_RESOURCE", 7, r600_state_pm4_resource, R600_FS_RESOURCE_names},
+ { 128, 1001, 0x00039180, 0x0003A300, 0x001C, 0, "R600_GS_RESOURCE", 7, r600_state_pm4_resource, R600_GS_RESOURCE_names},
+ { 128, 1161, 0x0003C000, 0x0003C0D8, 0x000C, 0, "R600_PS_SAMPLER", 3, r600_state_pm4_generic, R600_PS_SAMPLER_names},
+ { 128, 1179, 0x0003C0D8, 0x0003C1B0, 0x000C, 0, "R600_VS_SAMPLER", 3, r600_state_pm4_generic, R600_VS_SAMPLER_names},
+ { 128, 1197, 0x0003C1B0, 0x0003C288, 0x000C, 0, "R600_GS_SAMPLER", 3, r600_state_pm4_generic, R600_GS_SAMPLER_names},
+ { 128, 1215, 0x0000A400, 0x0000A520, 0x0010, 0, "R600_PS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_PS_SAMPLER_BORDER_names},
+ { 128, 1233, 0x0000A600, 0x0000A720, 0x0010, 0, "R600_VS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_VS_SAMPLER_BORDER_names},
+ { 128, 1251, 0x0000A800, 0x0000A920, 0x0010, 0, "R600_GS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_GS_SAMPLER_BORDER_names},
+ { 128, 1269, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB0", 7, r600_state_pm4_cb0, R600_CB0_names},
+ { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r600_state_pm4_db, R600_DB_names},
+ { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names},
+ { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names},
+};
+
+static struct radeon_type R700_types[] = {
+ { 128, 0, 0x00000000, 0x00000000, 0x0000, 0, "R600_CONFIG", 41, r700_state_pm4_config, R600_CONFIG_names},
+ { 128, 1, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB_CNTL", 18, r600_state_pm4_generic, R600_CB_CNTL_names},
+ { 128, 2, 0x00000000, 0x00000000, 0x0000, 0, "R600_RASTERIZER", 21, r600_state_pm4_generic, R600_RASTERIZER_names},
+ { 128, 3, 0x00000000, 0x00000000, 0x0000, 0, "R600_VIEWPORT", 9, r600_state_pm4_generic, R600_VIEWPORT_names},
+ { 128, 4, 0x00000000, 0x00000000, 0x0000, 0, "R600_SCISSOR", 19, r600_state_pm4_generic, R600_SCISSOR_names},
+ { 128, 5, 0x00000000, 0x00000000, 0x0000, 0, "R600_BLEND", 13, r600_state_pm4_generic, R600_BLEND_names},
+ { 128, 6, 0x00000000, 0x00000000, 0x0000, 0, "R600_DSA", 16, r600_state_pm4_generic, R600_DSA_names},
+ { 128, 7, 0x00000000, 0x00000000, 0x0000, 0, "R600_VS_SHADER", 49, r600_state_pm4_shader, R600_VS_SHADER_names},
+ { 128, 8, 0x00000000, 0x00000000, 0x0000, 0, "R600_PS_SHADER", 39, r600_state_pm4_shader, R600_PS_SHADER_names},
+ { 128, 9, 0x00030000, 0x00031000, 0x0010, 0, "R600_PS_CONSTANT", 4, r600_state_pm4_generic, R600_PS_CONSTANT_names},
+ { 128, 265, 0x00031000, 0x00032000, 0x0010, 0, "R600_VS_CONSTANT", 4, r600_state_pm4_generic, R600_VS_CONSTANT_names},
+ { 128, 521, 0x00038000, 0x00039180, 0x001C, 0, "R600_PS_RESOURCE", 7, r600_state_pm4_resource, R600_PS_RESOURCE_names},
+ { 128, 681, 0x00039180, 0x0003A300, 0x001C, 0, "R600_VS_RESOURCE", 7, r600_state_pm4_resource, R600_VS_RESOURCE_names},
+ { 128, 841, 0x00039180, 0x0003A300, 0x001C, 0, "R600_FS_RESOURCE", 7, r600_state_pm4_resource, R600_FS_RESOURCE_names},
+ { 128, 1001, 0x00039180, 0x0003A300, 0x001C, 0, "R600_GS_RESOURCE", 7, r600_state_pm4_resource, R600_GS_RESOURCE_names},
+ { 128, 1161, 0x0003C000, 0x0003C0D8, 0x000C, 0, "R600_PS_SAMPLER", 3, r600_state_pm4_generic, R600_PS_SAMPLER_names},
+ { 128, 1179, 0x0003C0D8, 0x0003C1B0, 0x000C, 0, "R600_VS_SAMPLER", 3, r600_state_pm4_generic, R600_VS_SAMPLER_names},
+ { 128, 1197, 0x0003C1B0, 0x0003C288, 0x000C, 0, "R600_GS_SAMPLER", 3, r600_state_pm4_generic, R600_GS_SAMPLER_names},
+ { 128, 1215, 0x0000A400, 0x0000A520, 0x0010, 0, "R600_PS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_PS_SAMPLER_BORDER_names},
+ { 128, 1233, 0x0000A600, 0x0000A720, 0x0010, 0, "R600_VS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_VS_SAMPLER_BORDER_names},
+ { 128, 1251, 0x0000A800, 0x0000A920, 0x0010, 0, "R600_GS_SAMPLER_BORDER", 4, r600_state_pm4_generic, R600_GS_SAMPLER_BORDER_names},
+ { 128, 1269, 0x00000000, 0x00000000, 0x0000, 0, "R600_CB0", 7, r700_state_pm4_cb0, R600_CB0_names},
+ { 128, 1270, 0x00000000, 0x00000000, 0x0000, 0, "R600_DB", 6, r700_state_pm4_db, R600_DB_names},
+ { 128, 1271, 0x00000000, 0x00000000, 0x0000, 0, "R600_VGT", 11, r600_state_pm4_vgt, R600_VGT_names},
+ { 128, 1272, 0x00000000, 0x00000000, 0x0000, 0, "R600_DRAW", 4, r600_state_pm4_draw, R600_DRAW_names},
+};
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h
new file mode 100644
index 0000000000..5d13378627
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/r600d.h
@@ -0,0 +1,2122 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#ifndef R600D_H
+#define R600D_H
+
+#define R600_CONFIG_REG_OFFSET 0X00008000
+#define R600_CONFIG_REG_END 0X0000AC00
+#define R600_CONTEXT_REG_OFFSET 0X00028000
+#define R600_CONTEXT_REG_END 0X00029000
+#define R600_ALU_CONST_OFFSET 0X00030000
+#define R600_ALU_CONST_END 0X00032000
+#define R600_RESOURCE_OFFSET 0X00038000
+#define R600_RESOURCE_END 0X0003C000
+#define R600_SAMPLER_OFFSET 0X0003C000
+#define R600_SAMPLER_END 0X0003CFF0
+#define R600_CTL_CONST_OFFSET 0X0003CFF0
+#define R600_CTL_CONST_END 0X0003E200
+#define R600_LOOP_CONST_OFFSET 0X0003E200
+#define R600_LOOP_CONST_END 0X0003E380
+#define R600_BOOL_CONST_OFFSET 0X0003E380
+#define R600_BOOL_CONST_END 0X00040000
+
+#define PKT3_NOP 0x10
+#define PKT3_INDIRECT_BUFFER_END 0x17
+#define PKT3_SET_PREDICATION 0x20
+#define PKT3_REG_RMW 0x21
+#define PKT3_COND_EXEC 0x22
+#define PKT3_PRED_EXEC 0x23
+#define PKT3_START_3D_CMDBUF 0x24
+#define PKT3_DRAW_INDEX_2 0x27
+#define PKT3_CONTEXT_CONTROL 0x28
+#define PKT3_DRAW_INDEX_IMMD_BE 0x29
+#define PKT3_INDEX_TYPE 0x2A
+#define PKT3_DRAW_INDEX 0x2B
+#define PKT3_DRAW_INDEX_AUTO 0x2D
+#define PKT3_DRAW_INDEX_IMMD 0x2E
+#define PKT3_NUM_INSTANCES 0x2F
+#define PKT3_STRMOUT_BUFFER_UPDATE 0x34
+#define PKT3_INDIRECT_BUFFER_MP 0x38
+#define PKT3_MEM_SEMAPHORE 0x39
+#define PKT3_MPEG_INDEX 0x3A
+#define PKT3_WAIT_REG_MEM 0x3C
+#define PKT3_MEM_WRITE 0x3D
+#define PKT3_INDIRECT_BUFFER 0x32
+#define PKT3_CP_INTERRUPT 0x40
+#define PKT3_SURFACE_SYNC 0x43
+#define PKT3_ME_INITIALIZE 0x44
+#define PKT3_COND_WRITE 0x45
+#define PKT3_EVENT_WRITE 0x46
+#define PKT3_EVENT_WRITE_EOP 0x47
+#define PKT3_ONE_REG_WRITE 0x57
+#define PKT3_SET_CONFIG_REG 0x68
+#define PKT3_SET_CONTEXT_REG 0x69
+#define PKT3_SET_ALU_CONST 0x6A
+#define PKT3_SET_BOOL_CONST 0x6B
+#define PKT3_SET_LOOP_CONST 0x6C
+#define PKT3_SET_RESOURCE 0x6D
+#define PKT3_SET_SAMPLER 0x6E
+#define PKT3_SET_CTL_CONST 0x6F
+#define PKT3_SURFACE_BASE_UPDATE 0x73
+
+#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
+#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
+#define PKT_TYPE_C 0x3FFFFFFF
+#define PKT_COUNT_S(x) (((x) & 0x3FFF) << 16)
+#define PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
+#define PKT_COUNT_C 0xC000FFFF
+#define PKT0_BASE_INDEX_S(x) (((x) & 0xFFFF) << 0)
+#define PKT0_BASE_INDEX_G(x) (((x) >> 0) & 0xFFFF)
+#define PKT0_BASE_INDEX_C 0xFFFF0000
+#define PKT3_IT_OPCODE_S(x) (((x) & 0xFF) << 8)
+#define PKT3_IT_OPCODE_G(x) (((x) >> 8) & 0xFF)
+#define PKT3_IT_OPCODE_C 0xFFFF00FF
+#define PKT0(index, count) (PKT_TYPE_S(0) | PKT0_BASE_INDEX_S(index) | PKT_COUNT_S(count))
+#define PKT3(op, count) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count))
+
+/* Registers */
+#define R_0280A0_CB_COLOR0_INFO 0x0280A0
+#define S_0280A0_ENDIAN(x) (((x) & 0x3) << 0)
+#define G_0280A0_ENDIAN(x) (((x) >> 0) & 0x3)
+#define C_0280A0_ENDIAN 0xFFFFFFFC
+#define S_0280A0_FORMAT(x) (((x) & 0x3F) << 2)
+#define G_0280A0_FORMAT(x) (((x) >> 2) & 0x3F)
+#define C_0280A0_FORMAT 0xFFFFFF03
+#define V_0280A0_COLOR_INVALID 0x00000000
+#define V_0280A0_COLOR_8 0x00000001
+#define V_0280A0_COLOR_4_4 0x00000002
+#define V_0280A0_COLOR_3_3_2 0x00000003
+#define V_0280A0_COLOR_16 0x00000005
+#define V_0280A0_COLOR_16_FLOAT 0x00000006
+#define V_0280A0_COLOR_8_8 0x00000007
+#define V_0280A0_COLOR_5_6_5 0x00000008
+#define V_0280A0_COLOR_6_5_5 0x00000009
+#define V_0280A0_COLOR_1_5_5_5 0x0000000A
+#define V_0280A0_COLOR_4_4_4_4 0x0000000B
+#define V_0280A0_COLOR_5_5_5_1 0x0000000C
+#define V_0280A0_COLOR_32 0x0000000D
+#define V_0280A0_COLOR_32_FLOAT 0x0000000E
+#define V_0280A0_COLOR_16_16 0x0000000F
+#define V_0280A0_COLOR_16_16_FLOAT 0x00000010
+#define V_0280A0_COLOR_8_24 0x00000011
+#define V_0280A0_COLOR_8_24_FLOAT 0x00000012
+#define V_0280A0_COLOR_24_8 0x00000013
+#define V_0280A0_COLOR_24_8_FLOAT 0x00000014
+#define V_0280A0_COLOR_10_11_11 0x00000015
+#define V_0280A0_COLOR_10_11_11_FLOAT 0x00000016
+#define V_0280A0_COLOR_11_11_10 0x00000017
+#define V_0280A0_COLOR_11_11_10_FLOAT 0x00000018
+#define V_0280A0_COLOR_2_10_10_10 0x00000019
+#define V_0280A0_COLOR_8_8_8_8 0x0000001A
+#define V_0280A0_COLOR_10_10_10_2 0x0000001B
+#define V_0280A0_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_0280A0_COLOR_32_32 0x0000001D
+#define V_0280A0_COLOR_32_32_FLOAT 0x0000001E
+#define V_0280A0_COLOR_16_16_16_16 0x0000001F
+#define V_0280A0_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_0280A0_COLOR_32_32_32_32 0x00000022
+#define V_0280A0_COLOR_32_32_32_32_FLOAT 0x00000023
+#define S_0280A0_ARRAY_MODE(x) (((x) & 0xF) << 8)
+#define G_0280A0_ARRAY_MODE(x) (((x) >> 8) & 0xF)
+#define C_0280A0_ARRAY_MODE 0xFFFFF0FF
+#define V_0280A0_ARRAY_LINEAR_GENERAL 0x00000000
+#define V_0280A0_ARRAY_LINEAR_ALIGNED 0x00000001
+#define V_0280A0_ARRAY_1D_TILED_THIN1 0x00000002
+#define V_0280A0_ARRAY_2D_TILED_THIN1 0x00000004
+#define S_0280A0_NUMBER_TYPE(x) (((x) & 0x7) << 12)
+#define G_0280A0_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
+#define C_0280A0_NUMBER_TYPE 0xFFFF8FFF
+#define S_0280A0_READ_SIZE(x) (((x) & 0x1) << 15)
+#define G_0280A0_READ_SIZE(x) (((x) >> 15) & 0x1)
+#define C_0280A0_READ_SIZE 0xFFFF7FFF
+#define S_0280A0_COMP_SWAP(x) (((x) & 0x3) << 16)
+#define G_0280A0_COMP_SWAP(x) (((x) >> 16) & 0x3)
+#define C_0280A0_COMP_SWAP 0xFFFCFFFF
+#define S_0280A0_TILE_MODE(x) (((x) & 0x3) << 18)
+#define G_0280A0_TILE_MODE(x) (((x) >> 18) & 0x3)
+#define C_0280A0_TILE_MODE 0xFFF3FFFF
+#define S_0280A0_BLEND_CLAMP(x) (((x) & 0x1) << 20)
+#define G_0280A0_BLEND_CLAMP(x) (((x) >> 20) & 0x1)
+#define C_0280A0_BLEND_CLAMP 0xFFEFFFFF
+#define S_0280A0_CLEAR_COLOR(x) (((x) & 0x1) << 21)
+#define G_0280A0_CLEAR_COLOR(x) (((x) >> 21) & 0x1)
+#define C_0280A0_CLEAR_COLOR 0xFFDFFFFF
+#define S_0280A0_BLEND_BYPASS(x) (((x) & 0x1) << 22)
+#define G_0280A0_BLEND_BYPASS(x) (((x) >> 22) & 0x1)
+#define C_0280A0_BLEND_BYPASS 0xFFBFFFFF
+#define S_0280A0_BLEND_FLOAT32(x) (((x) & 0x1) << 23)
+#define G_0280A0_BLEND_FLOAT32(x) (((x) >> 23) & 0x1)
+#define C_0280A0_BLEND_FLOAT32 0xFF7FFFFF
+#define S_0280A0_SIMPLE_FLOAT(x) (((x) & 0x1) << 24)
+#define G_0280A0_SIMPLE_FLOAT(x) (((x) >> 24) & 0x1)
+#define C_0280A0_SIMPLE_FLOAT 0xFEFFFFFF
+#define S_0280A0_ROUND_MODE(x) (((x) & 0x1) << 25)
+#define G_0280A0_ROUND_MODE(x) (((x) >> 25) & 0x1)
+#define C_0280A0_ROUND_MODE 0xFDFFFFFF
+#define S_0280A0_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_0280A0_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_0280A0_TILE_COMPACT 0xFBFFFFFF
+#define S_0280A0_SOURCE_FORMAT(x) (((x) & 0x1) << 27)
+#define G_0280A0_SOURCE_FORMAT(x) (((x) >> 27) & 0x1)
+#define C_0280A0_SOURCE_FORMAT 0xF7FFFFFF
+#define R_028060_CB_COLOR0_SIZE 0x028060
+#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028060_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028060_SLICE_TILE_MAX 0xC00003FF
+#define R_028800_DB_DEPTH_CONTROL 0x028800
+#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028800_STENCIL_ENABLE 0xFFFFFFFE
+#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028800_Z_ENABLE 0xFFFFFFFD
+#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB
+#define S_028800_ZFUNC(x) (((x) & 0x7) << 4)
+#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7)
+#define C_028800_ZFUNC 0xFFFFFF8F
+#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7)
+#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1)
+#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F
+#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8)
+#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7)
+#define C_028800_STENCILFUNC 0xFFFFF8FF
+#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11)
+#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7)
+#define C_028800_STENCILFAIL 0xFFFFC7FF
+#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14)
+#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7)
+#define C_028800_STENCILZPASS 0xFFFE3FFF
+#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17)
+#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7)
+#define C_028800_STENCILZFAIL 0xFFF1FFFF
+#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20)
+#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7)
+#define C_028800_STENCILFUNC_BF 0xFF8FFFFF
+#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23)
+#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7)
+#define C_028800_STENCILFAIL_BF 0xFC7FFFFF
+#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26)
+#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7)
+#define C_028800_STENCILZPASS_BF 0xE3FFFFFF
+#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29)
+#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7)
+#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF
+#define R_028010_DB_DEPTH_INFO 0x028010
+#define S_028010_FORMAT(x) (((x) & 0x7) << 0)
+#define G_028010_FORMAT(x) (((x) >> 0) & 0x7)
+#define C_028010_FORMAT 0xFFFFFFF8
+#define V_028010_DEPTH_INVALID 0x00000000
+#define V_028010_DEPTH_16 0x00000001
+#define V_028010_DEPTH_X8_24 0x00000002
+#define V_028010_DEPTH_8_24 0x00000003
+#define V_028010_DEPTH_X8_24_FLOAT 0x00000004
+#define V_028010_DEPTH_8_24_FLOAT 0x00000005
+#define V_028010_DEPTH_32_FLOAT 0x00000006
+#define V_028010_DEPTH_X24_8_32_FLOAT 0x00000007
+#define S_028010_READ_SIZE(x) (((x) & 0x1) << 3)
+#define G_028010_READ_SIZE(x) (((x) >> 3) & 0x1)
+#define C_028010_READ_SIZE 0xFFFFFFF7
+#define S_028010_ARRAY_MODE(x) (((x) & 0xF) << 15)
+#define G_028010_ARRAY_MODE(x) (((x) >> 15) & 0xF)
+#define C_028010_ARRAY_MODE 0xFFF87FFF
+#define S_028010_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 25)
+#define G_028010_TILE_SURFACE_ENABLE(x) (((x) >> 25) & 0x1)
+#define C_028010_TILE_SURFACE_ENABLE 0xFDFFFFFF
+#define S_028010_TILE_COMPACT(x) (((x) & 0x1) << 26)
+#define G_028010_TILE_COMPACT(x) (((x) >> 26) & 0x1)
+#define C_028010_TILE_COMPACT 0xFBFFFFFF
+#define S_028010_ZRANGE_PRECISION(x) (((x) & 0x1) << 31)
+#define G_028010_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1)
+#define C_028010_ZRANGE_PRECISION 0x7FFFFFFF
+#define R_028000_DB_DEPTH_SIZE 0x028000
+#define S_028000_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028000_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028000_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028000_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028000_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028000_SLICE_TILE_MAX 0xC00003FF
+#define R_028004_DB_DEPTH_VIEW 0x028004
+#define S_028004_SLICE_START(x) (((x) & 0x7FF) << 0)
+#define G_028004_SLICE_START(x) (((x) >> 0) & 0x7FF)
+#define C_028004_SLICE_START 0xFFFFF800
+#define S_028004_SLICE_MAX(x) (((x) & 0x7FF) << 13)
+#define G_028004_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
+#define C_028004_SLICE_MAX 0xFF001FFF
+#define R_028D24_DB_HTILE_SURFACE 0x028D24
+#define S_028D24_HTILE_WIDTH(x) (((x) & 0x1) << 0)
+#define G_028D24_HTILE_WIDTH(x) (((x) >> 0) & 0x1)
+#define C_028D24_HTILE_WIDTH 0xFFFFFFFE
+#define S_028D24_HTILE_HEIGHT(x) (((x) & 0x1) << 1)
+#define G_028D24_HTILE_HEIGHT(x) (((x) >> 1) & 0x1)
+#define C_028D24_HTILE_HEIGHT 0xFFFFFFFD
+#define S_028D24_LINEAR(x) (((x) & 0x1) << 2)
+#define G_028D24_LINEAR(x) (((x) >> 2) & 0x1)
+#define C_028D24_LINEAR 0xFFFFFFFB
+#define S_028D24_FULL_CACHE(x) (((x) & 0x1) << 3)
+#define G_028D24_FULL_CACHE(x) (((x) >> 3) & 0x1)
+#define C_028D24_FULL_CACHE 0xFFFFFFF7
+#define S_028D24_HTILE_USES_PRELOAD_WIN(x) (((x) & 0x1) << 4)
+#define G_028D24_HTILE_USES_PRELOAD_WIN(x) (((x) >> 4) & 0x1)
+#define C_028D24_HTILE_USES_PRELOAD_WIN 0xFFFFFFEF
+#define S_028D24_PRELOAD(x) (((x) & 0x1) << 5)
+#define G_028D24_PRELOAD(x) (((x) >> 5) & 0x1)
+#define C_028D24_PRELOAD 0xFFFFFFDF
+#define S_028D24_PREFETCH_WIDTH(x) (((x) & 0x3F) << 6)
+#define G_028D24_PREFETCH_WIDTH(x) (((x) >> 6) & 0x3F)
+#define C_028D24_PREFETCH_WIDTH 0xFFFFF03F
+#define S_028D24_PREFETCH_HEIGHT(x) (((x) & 0x3F) << 12)
+#define G_028D24_PREFETCH_HEIGHT(x) (((x) >> 12) & 0x3F)
+#define C_028D24_PREFETCH_HEIGHT 0xFFFC0FFF
+#define R_028D34_DB_PREFETCH_LIMIT 0x028D34
+#define S_028D34_DEPTH_HEIGHT_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028D34_DEPTH_HEIGHT_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028D34_DEPTH_HEIGHT_TILE_MAX 0xFFFFFC00
+#define R_028D10_DB_RENDER_OVERRIDE 0x028D10
+#define S_028D10_FORCE_HIZ_ENABLE(x) (((x) & 0x3) << 0)
+#define G_028D10_FORCE_HIZ_ENABLE(x) (((x) >> 0) & 0x3)
+#define C_028D10_FORCE_HIZ_ENABLE 0xFFFFFFFC
+#define S_028D10_FORCE_HIS_ENABLE0(x) (((x) & 0x3) << 2)
+#define G_028D10_FORCE_HIS_ENABLE0(x) (((x) >> 2) & 0x3)
+#define C_028D10_FORCE_HIS_ENABLE0 0xFFFFFFF3
+#define S_028D10_FORCE_HIS_ENABLE1(x) (((x) & 0x3) << 4)
+#define G_028D10_FORCE_HIS_ENABLE1(x) (((x) >> 4) & 0x3)
+#define C_028D10_FORCE_HIS_ENABLE1 0xFFFFFFCF
+#define S_028D10_FORCE_SHADER_Z_ORDER(x) (((x) & 0x1) << 6)
+#define G_028D10_FORCE_SHADER_Z_ORDER(x) (((x) >> 6) & 0x1)
+#define C_028D10_FORCE_SHADER_Z_ORDER 0xFFFFFFBF
+#define S_028D10_FAST_Z_DISABLE(x) (((x) & 0x1) << 7)
+#define G_028D10_FAST_Z_DISABLE(x) (((x) >> 7) & 0x1)
+#define C_028D10_FAST_Z_DISABLE 0xFFFFFF7F
+#define S_028D10_FAST_STENCIL_DISABLE(x) (((x) & 0x1) << 8)
+#define G_028D10_FAST_STENCIL_DISABLE(x) (((x) >> 8) & 0x1)
+#define C_028D10_FAST_STENCIL_DISABLE 0xFFFFFEFF
+#define S_028D10_NOOP_CULL_DISABLE(x) (((x) & 0x1) << 9)
+#define G_028D10_NOOP_CULL_DISABLE(x) (((x) >> 9) & 0x1)
+#define C_028D10_NOOP_CULL_DISABLE 0xFFFFFDFF
+#define S_028D10_FORCE_COLOR_KILL(x) (((x) & 0x1) << 10)
+#define G_028D10_FORCE_COLOR_KILL(x) (((x) >> 10) & 0x1)
+#define C_028D10_FORCE_COLOR_KILL 0xFFFFFBFF
+#define S_028D10_FORCE_Z_READ(x) (((x) & 0x1) << 11)
+#define G_028D10_FORCE_Z_READ(x) (((x) >> 11) & 0x1)
+#define C_028D10_FORCE_Z_READ 0xFFFFF7FF
+#define S_028D10_FORCE_STENCIL_READ(x) (((x) & 0x1) << 12)
+#define G_028D10_FORCE_STENCIL_READ(x) (((x) >> 12) & 0x1)
+#define C_028D10_FORCE_STENCIL_READ 0xFFFFEFFF
+#define S_028D10_FORCE_FULL_Z_RANGE(x) (((x) & 0x3) << 13)
+#define G_028D10_FORCE_FULL_Z_RANGE(x) (((x) >> 13) & 0x3)
+#define C_028D10_FORCE_FULL_Z_RANGE 0xFFFF9FFF
+#define S_028D10_FORCE_QC_SMASK_CONFLICT(x) (((x) & 0x1) << 15)
+#define G_028D10_FORCE_QC_SMASK_CONFLICT(x) (((x) >> 15) & 0x1)
+#define C_028D10_FORCE_QC_SMASK_CONFLICT 0xFFFF7FFF
+#define S_028D10_DISABLE_VIEWPORT_CLAMP(x) (((x) & 0x1) << 16)
+#define G_028D10_DISABLE_VIEWPORT_CLAMP(x) (((x) >> 16) & 0x1)
+#define C_028D10_DISABLE_VIEWPORT_CLAMP 0xFFFEFFFF
+#define S_028D10_IGNORE_SC_ZRANGE(x) (((x) & 0x1) << 17)
+#define G_028D10_IGNORE_SC_ZRANGE(x) (((x) >> 17) & 0x1)
+#define C_028D10_IGNORE_SC_ZRANGE 0xFFFDFFFF
+#define R_028A40_VGT_GS_MODE 0x028A40
+#define S_028A40_MODE(x) (((x) & 0x3) << 0)
+#define G_028A40_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A40_MODE 0xFFFFFFFC
+#define S_028A40_ES_PASSTHRU(x) (((x) & 0x1) << 2)
+#define G_028A40_ES_PASSTHRU(x) (((x) >> 2) & 0x1)
+#define C_028A40_ES_PASSTHRU 0xFFFFFFFB
+#define S_028A40_CUT_MODE(x) (((x) & 0x3) << 3)
+#define G_028A40_CUT_MODE(x) (((x) >> 3) & 0x3)
+#define C_028A40_CUT_MODE 0xFFFFFFE7
+#define R_008DFC_SQ_CF_WORD0 0x008DFC
+#define S_008DFC_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_008DFC_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_008DFC_ADDR 0x00000000
+#define R_008DFC_SQ_CF_WORD1 0x008DFC
+#define S_008DFC_POP_COUNT(x) (((x) & 0x7) << 0)
+#define G_008DFC_POP_COUNT(x) (((x) >> 0) & 0x7)
+#define C_008DFC_POP_COUNT 0xFFFFFFF8
+#define S_008DFC_CF_CONST(x) (((x) & 0x1F) << 3)
+#define G_008DFC_CF_CONST(x) (((x) >> 3) & 0x1F)
+#define C_008DFC_CF_CONST 0xFFFFFF07
+#define S_008DFC_COND(x) (((x) & 0x3) << 8)
+#define G_008DFC_COND(x) (((x) >> 8) & 0x3)
+#define C_008DFC_COND 0xFFFFFCFF
+#define S_008DFC_COUNT(x) (((x) & 0x7) << 10)
+#define G_008DFC_COUNT(x) (((x) >> 10) & 0x7)
+#define C_008DFC_COUNT 0xFFFFE3FF
+#define S_008DFC_CALL_COUNT(x) (((x) & 0x3F) << 13)
+#define G_008DFC_CALL_COUNT(x) (((x) >> 13) & 0x3F)
+#define C_008DFC_CALL_COUNT 0xFFF81FFF
+#define S_008DFC_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_008DFC_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_008DFC_END_OF_PROGRAM 0xFFDFFFFF
+#define S_008DFC_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_008DFC_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_008DFC_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_008DFC_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_008DFC_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_CF_INST 0xC07FFFFF
+#define V_008DFC_SQ_CF_INST_NOP 0x00000000
+#define V_008DFC_SQ_CF_INST_TEX 0x00000001
+#define V_008DFC_SQ_CF_INST_VTX 0x00000002
+#define V_008DFC_SQ_CF_INST_VTX_TC 0x00000003
+#define V_008DFC_SQ_CF_INST_LOOP_START 0x00000004
+#define V_008DFC_SQ_CF_INST_LOOP_END 0x00000005
+#define V_008DFC_SQ_CF_INST_LOOP_START_DX10 0x00000006
+#define V_008DFC_SQ_CF_INST_LOOP_START_NO_AL 0x00000007
+#define V_008DFC_SQ_CF_INST_LOOP_CONTINUE 0x00000008
+#define V_008DFC_SQ_CF_INST_LOOP_BREAK 0x00000009
+#define V_008DFC_SQ_CF_INST_JUMP 0x0000000A
+#define V_008DFC_SQ_CF_INST_PUSH 0x0000000B
+#define V_008DFC_SQ_CF_INST_PUSH_ELSE 0x0000000C
+#define V_008DFC_SQ_CF_INST_ELSE 0x0000000D
+#define V_008DFC_SQ_CF_INST_POP 0x0000000E
+#define V_008DFC_SQ_CF_INST_POP_JUMP 0x0000000F
+#define V_008DFC_SQ_CF_INST_POP_PUSH 0x00000010
+#define V_008DFC_SQ_CF_INST_POP_PUSH_ELSE 0x00000011
+#define V_008DFC_SQ_CF_INST_CALL 0x00000012
+#define V_008DFC_SQ_CF_INST_CALL_FS 0x00000013
+#define V_008DFC_SQ_CF_INST_RETURN 0x00000014
+#define V_008DFC_SQ_CF_INST_EMIT_VERTEX 0x00000015
+#define V_008DFC_SQ_CF_INST_EMIT_CUT_VERTEX 0x00000016
+#define V_008DFC_SQ_CF_INST_CUT_VERTEX 0x00000017
+#define V_008DFC_SQ_CF_INST_KILL 0x00000018
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALU_WORD0 0x008DFC
+#define S_008DFC_ALU_ADDR(x) (((x) & 0x3FFFFF) << 0)
+#define G_008DFC_ALU_ADDR(x) (((x) >> 0) & 0x3FFFFF)
+#define C_008DFC_ALU_ADDR 0xFFC00000
+#define S_008DFC_KCACHE_BANK0(x) (((x) & 0xF) << 22)
+#define G_008DFC_KCACHE_BANK0(x) (((x) >> 22) & 0xF)
+#define C_008DFC_KCACHE_BANK0 0xFC3FFFFF
+#define S_008DFC_KCACHE_BANK1(x) (((x) & 0xF) << 26)
+#define G_008DFC_KCACHE_BANK1(x) (((x) >> 26) & 0xF)
+#define C_008DFC_KCACHE_BANK1 0xC3FFFFFF
+#define S_008DFC_KCACHE_MODE0(x) (((x) & 0x3) << 30)
+#define G_008DFC_KCACHE_MODE0(x) (((x) >> 30) & 0x3)
+#define C_008DFC_KCACHE_MODE0 0x3FFFFFFF
+#define R_008DFC_SQ_CF_ALU_WORD1 0x008DFC
+#define S_008DFC_KCACHE_MODE1(x) (((x) & 0x3) << 0)
+#define G_008DFC_KCACHE_MODE1(x) (((x) >> 0) & 0x3)
+#define C_008DFC_KCACHE_MODE1 0xFFFFFFFC
+#define S_008DFC_KCACHE_ADDR0(x) (((x) & 0xFF) << 2)
+#define G_008DFC_KCACHE_ADDR0(x) (((x) >> 2) & 0xFF)
+#define C_008DFC_KCACHE_ADDR0 0xFFFFFC03
+#define S_008DFC_KCACHE_ADDR1(x) (((x) & 0xFF) << 10)
+#define G_008DFC_KCACHE_ADDR1(x) (((x) >> 10) & 0xFF)
+#define C_008DFC_KCACHE_ADDR1 0xFFFC03FF
+#define S_008DFC_ALU_COUNT(x) (((x) & 0x7F) << 18)
+#define G_008DFC_ALU_COUNT(x) (((x) >> 18) & 0x7F)
+#define C_008DFC_ALU_COUNT 0xFE03FFFF
+#define S_008DFC_USES_WATERFALL(x) (((x) & 0x1) << 25)
+#define G_008DFC_USES_WATERFALL(x) (((x) >> 25) & 0x1)
+#define C_008DFC_USES_WATERFALL 0xFDFFFFFF
+#define S_008DFC_CF_ALU_INST(x) (((x) & 0xF) << 26)
+#define G_008DFC_CF_ALU_INST(x) (((x) >> 26) & 0xF)
+#define C_008DFC_CF_ALU_INST 0xC3FFFFFF
+#define V_008DFC_SQ_CF_INST_ALU 0x00000008
+#define V_008DFC_SQ_CF_INST_ALU_PUSH_BEFORE 0x00000009
+#define V_008DFC_SQ_CF_INST_ALU_POP_AFTER 0x0000000A
+#define V_008DFC_SQ_CF_INST_ALU_POP2_AFTER 0x0000000B
+#define V_008DFC_SQ_CF_INST_ALU_CONTINUE 0x0000000D
+#define V_008DFC_SQ_CF_INST_ALU_BREAK 0x0000000E
+#define V_008DFC_SQ_CF_INST_ALU_ELSE_AFTER 0x0000000F
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD0 0x008DFC
+#define S_008DFC_ARRAY_BASE(x) (((x) & 0x1FFF) << 0)
+#define G_008DFC_ARRAY_BASE(x) (((x) >> 0) & 0x1FFF)
+#define C_008DFC_ARRAY_BASE 0xFFFFE000
+#define S_008DFC_TYPE(x) (((x) & 0x3) << 13)
+#define G_008DFC_TYPE(x) (((x) >> 13) & 0x3)
+#define C_008DFC_TYPE 0xFFFF9FFF
+#define S_008DFC_RW_GPR(x) (((x) & 0x7F) << 15)
+#define G_008DFC_RW_GPR(x) (((x) >> 15) & 0x7F)
+#define C_008DFC_RW_GPR 0xFFC07FFF
+#define S_008DFC_RW_REL(x) (((x) & 0x1) << 22)
+#define G_008DFC_RW_REL(x) (((x) >> 22) & 0x1)
+#define C_008DFC_RW_REL 0xFFBFFFFF
+#define S_008DFC_INDEX_GPR(x) (((x) & 0x7F) << 23)
+#define G_008DFC_INDEX_GPR(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_INDEX_GPR 0xC07FFFFF
+#define S_008DFC_ELEM_SIZE(x) (((x) & 0x3) << 30)
+#define G_008DFC_ELEM_SIZE(x) (((x) >> 30) & 0x3)
+#define C_008DFC_ELEM_SIZE 0x3FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1 0x008DFC
+#define S_008DFC_BURST_COUNT(x) (((x) & 0xF) << 17)
+#define G_008DFC_BURST_COUNT(x) (((x) >> 17) & 0xF)
+#define C_008DFC_BURST_COUNT 0xFFE1FFFF
+#define S_008DFC_END_OF_PROGRAM(x) (((x) & 0x1) << 21)
+#define G_008DFC_END_OF_PROGRAM(x) (((x) >> 21) & 0x1)
+#define C_008DFC_END_OF_PROGRAM 0xFFDFFFFF
+#define S_008DFC_VALID_PIXEL_MODE(x) (((x) & 0x1) << 22)
+#define G_008DFC_VALID_PIXEL_MODE(x) (((x) >> 22) & 0x1)
+#define C_008DFC_VALID_PIXEL_MODE 0xFFBFFFFF
+#define S_008DFC_CF_INST(x) (((x) & 0x7F) << 23)
+#define G_008DFC_CF_INST(x) (((x) >> 23) & 0x7F)
+#define C_008DFC_CF_INST 0xC07FFFFF
+#define V_008DFC_SQ_CF_INST_MEM_STREAM0 0x00000020
+#define V_008DFC_SQ_CF_INST_MEM_STREAM1 0x00000021
+#define V_008DFC_SQ_CF_INST_MEM_STREAM2 0x00000022
+#define V_008DFC_SQ_CF_INST_MEM_STREAM3 0x00000023
+#define V_008DFC_SQ_CF_INST_MEM_SCRATCH 0x00000024
+#define V_008DFC_SQ_CF_INST_MEM_REDUCTION 0x00000025
+#define V_008DFC_SQ_CF_INST_MEM_RING 0x00000026
+#define V_008DFC_SQ_CF_INST_EXPORT 0x00000027
+#define V_008DFC_SQ_CF_INST_EXPORT_DONE 0x00000028
+#define S_008DFC_WHOLE_QUAD_MODE(x) (((x) & 0x1) << 30)
+#define G_008DFC_WHOLE_QUAD_MODE(x) (((x) >> 30) & 0x1)
+#define C_008DFC_WHOLE_QUAD_MODE 0xBFFFFFFF
+#define S_008DFC_BARRIER(x) (((x) & 0x1) << 31)
+#define G_008DFC_BARRIER(x) (((x) >> 31) & 0x1)
+#define C_008DFC_BARRIER 0x7FFFFFFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1_BUF 0x008DFC
+#define S_008DFC_ARRAY_SIZE(x) (((x) & 0xFFF) << 0)
+#define G_008DFC_ARRAY_SIZE(x) (((x) >> 0) & 0xFFF)
+#define C_008DFC_ARRAY_SIZE 0xFFFFF000
+#define S_008DFC_COMP_MASK(x) (((x) & 0xF) << 12)
+#define G_008DFC_COMP_MASK(x) (((x) >> 12) & 0xF)
+#define C_008DFC_COMP_MASK 0xFFFF0FFF
+#define R_008DFC_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ 0x008DFC
+#define S_008DFC_SEL_X(x) (((x) & 0x7) << 0)
+#define G_008DFC_SEL_X(x) (((x) >> 0) & 0x7)
+#define C_008DFC_SEL_X 0xFFFFFFF8
+#define S_008DFC_SEL_Y(x) (((x) & 0x7) << 3)
+#define G_008DFC_SEL_Y(x) (((x) >> 3) & 0x7)
+#define C_008DFC_SEL_Y 0xFFFFFFC7
+#define S_008DFC_SEL_Z(x) (((x) & 0x7) << 6)
+#define G_008DFC_SEL_Z(x) (((x) >> 6) & 0x7)
+#define C_008DFC_SEL_Z 0xFFFFFE3F
+#define S_008DFC_SEL_W(x) (((x) & 0x7) << 9)
+#define G_008DFC_SEL_W(x) (((x) >> 9) & 0x7)
+#define C_008DFC_SEL_W 0xFFFFF1FF
+#define R_008DFC_SQ_VTX_WORD0 0x008DFC
+#define S_008DFC_VTX_INST(x) (((x) & 0x1F) << 0)
+#define G_008DFC_VTX_INST(x) (((x) >> 0) & 0x1F)
+#define C_008DFC_VTX_INST 0xFFFFFFE0
+#define S_008DFC_FETCH_TYPE(x) (((x) & 0x3) << 5)
+#define G_008DFC_FETCH_TYPE(x) (((x) >> 5) & 0x3)
+#define C_008DFC_FETCH_TYPE 0xFFFFFF9F
+#define S_008DFC_FETCH_WHOLE_QUAD(x) (((x) & 0x1) << 7)
+#define G_008DFC_FETCH_WHOLE_QUAD(x) (((x) >> 7) & 0x1)
+#define C_008DFC_FETCH_WHOLE_QUAD 0xFFFFFF7F
+#define S_008DFC_BUFFER_ID(x) (((x) & 0xFF) << 8)
+#define G_008DFC_BUFFER_ID(x) (((x) >> 8) & 0xFF)
+#define C_008DFC_BUFFER_ID 0xFFFF00FF
+#define S_008DFC_SRC_GPR(x) (((x) & 0x7F) << 16)
+#define G_008DFC_SRC_GPR(x) (((x) >> 16) & 0x7F)
+#define C_008DFC_SRC_GPR 0xFF80FFFF
+#define S_008DFC_SRC_REL(x) (((x) & 0x1) << 23)
+#define G_008DFC_SRC_REL(x) (((x) >> 23) & 0x1)
+#define C_008DFC_SRC_REL 0xFF7FFFFF
+#define S_008DFC_SRC_SEL_X(x) (((x) & 0x3) << 24)
+#define G_008DFC_SRC_SEL_X(x) (((x) >> 24) & 0x3)
+#define C_008DFC_SRC_SEL_X 0xFCFFFFFF
+#define S_008DFC_MEGA_FETCH_COUNT(x) (((x) & 0x3F) << 26)
+#define G_008DFC_MEGA_FETCH_COUNT(x) (((x) >> 26) & 0x3F)
+#define C_008DFC_MEGA_FETCH_COUNT 0x03FFFFFF
+#define R_008DFC_SQ_VTX_WORD1 0x008DFC
+#define S_008DFC_DST_SEL_X(x) (((x) & 0x7) << 9)
+#define G_008DFC_DST_SEL_X(x) (((x) >> 9) & 0x7)
+#define C_008DFC_DST_SEL_X 0xFFFFF1FF
+#define S_008DFC_DST_SEL_Y(x) (((x) & 0x7) << 12)
+#define G_008DFC_DST_SEL_Y(x) (((x) >> 12) & 0x7)
+#define C_008DFC_DST_SEL_Y 0xFFFF8FFF
+#define S_008DFC_DST_SEL_Z(x) (((x) & 0x7) << 15)
+#define G_008DFC_DST_SEL_Z(x) (((x) >> 15) & 0x7)
+#define C_008DFC_DST_SEL_Z 0xFFFC7FFF
+#define S_008DFC_DST_SEL_W(x) (((x) & 0x7) << 18)
+#define G_008DFC_DST_SEL_W(x) (((x) >> 18) & 0x7)
+#define C_008DFC_DST_SEL_W 0xFFE3FFFF
+#define S_008DFC_USE_CONST_FIELDS(x) (((x) & 0x1) << 21)
+#define G_008DFC_USE_CONST_FIELDS(x) (((x) >> 21) & 0x1)
+#define C_008DFC_USE_CONST_FIELDS 0xFFDFFFFF
+#define S_008DFC_DATA_FORMAT(x) (((x) & 0x3F) << 22)
+#define G_008DFC_DATA_FORMAT(x) (((x) >> 22) & 0x3F)
+#define C_008DFC_DATA_FORMAT 0xF03FFFFF
+#define S_008DFC_NUM_FORMAT_ALL(x) (((x) & 0x3) << 28)
+#define G_008DFC_NUM_FORMAT_ALL(x) (((x) >> 28) & 0x3)
+#define C_008DFC_NUM_FORMAT_ALL 0xCFFFFFFF
+#define S_008DFC_FORMAT_COMP_ALL(x) (((x) & 0x1) << 30)
+#define G_008DFC_FORMAT_COMP_ALL(x) (((x) >> 30) & 0x1)
+#define C_008DFC_FORMAT_COMP_ALL 0xBFFFFFFF
+#define S_008DFC_SRF_MODE_ALL(x) (((x) & 0x1) << 31)
+#define G_008DFC_SRF_MODE_ALL(x) (((x) >> 31) & 0x1)
+#define C_008DFC_SRF_MODE_ALL 0x7FFFFFFF
+#define R_008DFC_SQ_VTX_WORD1_GPR 0x008DFC
+#define S_008DFC_DST_GPR(x) (((x) & 0x7F) << 0)
+#define G_008DFC_DST_GPR(x) (((x) >> 0) & 0x7F)
+#define C_008DFC_DST_GPR 0xFFFFFF80
+#define S_008DFC_DST_REL(x) (((x) & 0x1) << 7)
+#define G_008DFC_DST_REL(x) (((x) >> 7) & 0x1)
+#define C_008DFC_DST_REL 0xFFFFFF7F
+#define R_008DFC_SQ_VTX_WORD2 0x008DFC
+#define S_008DFC_OFFSET(x) (((x) & 0xFFFF) << 0)
+#define G_008DFC_OFFSET(x) (((x) >> 0) & 0xFFFF)
+#define C_008DFC_OFFSET 0xFFFF0000
+#define S_008DFC_ENDIAN_SWAP(x) (((x) & 0x3) << 16)
+#define G_008DFC_ENDIAN_SWAP(x) (((x) >> 16) & 0x3)
+#define C_008DFC_ENDIAN_SWAP 0xFFFCFFFF
+#define S_008DFC_CONST_BUF_NO_STRIDE(x) (((x) & 0x1) << 18)
+#define G_008DFC_CONST_BUF_NO_STRIDE(x) (((x) >> 18) & 0x1)
+#define C_008DFC_CONST_BUF_NO_STRIDE 0xFFFBFFFF
+#define S_008DFC_MEGA_FETCH(x) (((x) & 0x1) << 19)
+#define G_008DFC_MEGA_FETCH(x) (((x) >> 19) & 0x1)
+#define C_008DFC_MEGA_FETCH 0xFFF7FFFF
+#define S_008DFC_ALT_CONST(x) (((x) & 0x1) << 20)
+#define G_008DFC_ALT_CONST(x) (((x) >> 20) & 0x1)
+#define C_008DFC_ALT_CONST 0xFFEFFFFF
+#define R_008040_WAIT_UNTIL 0x008040
+#define S_008040_WAIT_CP_DMA_IDLE(x) (((x) & 0x1) << 8)
+#define G_008040_WAIT_CP_DMA_IDLE(x) (((x) >> 8) & 0x1)
+#define C_008040_WAIT_CP_DMA_IDLE 0xFFFFFEFF
+#define S_008040_WAIT_CMDFIFO(x) (((x) & 0x1) << 10)
+#define G_008040_WAIT_CMDFIFO(x) (((x) >> 10) & 0x1)
+#define C_008040_WAIT_CMDFIFO 0xFFFFFBFF
+#define S_008040_WAIT_2D_IDLE(x) (((x) & 0x1) << 14)
+#define G_008040_WAIT_2D_IDLE(x) (((x) >> 14) & 0x1)
+#define C_008040_WAIT_2D_IDLE 0xFFFFBFFF
+#define S_008040_WAIT_3D_IDLE(x) (((x) & 0x1) << 15)
+#define G_008040_WAIT_3D_IDLE(x) (((x) >> 15) & 0x1)
+#define C_008040_WAIT_3D_IDLE 0xFFFF7FFF
+#define S_008040_WAIT_2D_IDLECLEAN(x) (((x) & 0x1) << 16)
+#define G_008040_WAIT_2D_IDLECLEAN(x) (((x) >> 16) & 0x1)
+#define C_008040_WAIT_2D_IDLECLEAN 0xFFFEFFFF
+#define S_008040_WAIT_3D_IDLECLEAN(x) (((x) & 0x1) << 17)
+#define G_008040_WAIT_3D_IDLECLEAN(x) (((x) >> 17) & 0x1)
+#define C_008040_WAIT_3D_IDLECLEAN 0xFFFDFFFF
+#define S_008040_WAIT_EXTERN_SIG(x) (((x) & 0x1) << 19)
+#define G_008040_WAIT_EXTERN_SIG(x) (((x) >> 19) & 0x1)
+#define C_008040_WAIT_EXTERN_SIG 0xFFF7FFFF
+#define S_008040_CMDFIFO_ENTRIES(x) (((x) & 0x1F) << 20)
+#define G_008040_CMDFIFO_ENTRIES(x) (((x) >> 20) & 0x1F)
+#define C_008040_CMDFIFO_ENTRIES 0xFE0FFFFF
+#define R_0286CC_SPI_PS_IN_CONTROL_0 0x0286CC
+#define S_0286CC_NUM_INTERP(x) (((x) & 0x3F) << 0)
+#define G_0286CC_NUM_INTERP(x) (((x) >> 0) & 0x3F)
+#define C_0286CC_NUM_INTERP 0xFFFFFFC0
+#define S_0286CC_POSITION_ENA(x) (((x) & 0x1) << 8)
+#define G_0286CC_POSITION_ENA(x) (((x) >> 8) & 0x1)
+#define C_0286CC_POSITION_ENA 0xFFFFFEFF
+#define S_0286CC_POSITION_CENTROID(x) (((x) & 0x1) << 9)
+#define G_0286CC_POSITION_CENTROID(x) (((x) >> 9) & 0x1)
+#define C_0286CC_POSITION_CENTROID 0xFFFFFDFF
+#define S_0286CC_POSITION_ADDR(x) (((x) & 0x1F) << 10)
+#define G_0286CC_POSITION_ADDR(x) (((x) >> 10) & 0x1F)
+#define C_0286CC_POSITION_ADDR 0xFFFF83FF
+#define S_0286CC_PARAM_GEN(x) (((x) & 0xF) << 15)
+#define G_0286CC_PARAM_GEN(x) (((x) >> 15) & 0xF)
+#define C_0286CC_PARAM_GEN 0xFFF87FFF
+#define S_0286CC_PARAM_GEN_ADDR(x) (((x) & 0x7F) << 19)
+#define G_0286CC_PARAM_GEN_ADDR(x) (((x) >> 19) & 0x7F)
+#define C_0286CC_PARAM_GEN_ADDR 0xFC07FFFF
+#define S_0286CC_BARYC_SAMPLE_CNTL(x) (((x) & 0x3) << 26)
+#define G_0286CC_BARYC_SAMPLE_CNTL(x) (((x) >> 26) & 0x3)
+#define C_0286CC_BARYC_SAMPLE_CNTL 0xF3FFFFFF
+#define S_0286CC_PERSP_GRADIENT_ENA(x) (((x) & 0x1) << 28)
+#define G_0286CC_PERSP_GRADIENT_ENA(x) (((x) >> 28) & 0x1)
+#define C_0286CC_PERSP_GRADIENT_ENA 0xEFFFFFFF
+#define S_0286CC_LINEAR_GRADIENT_ENA(x) (((x) & 0x1) << 29)
+#define G_0286CC_LINEAR_GRADIENT_ENA(x) (((x) >> 29) & 0x1)
+#define C_0286CC_LINEAR_GRADIENT_ENA 0xDFFFFFFF
+#define S_0286CC_POSITION_SAMPLE(x) (((x) & 0x1) << 30)
+#define G_0286CC_POSITION_SAMPLE(x) (((x) >> 30) & 0x1)
+#define C_0286CC_POSITION_SAMPLE 0xBFFFFFFF
+#define S_0286CC_BARYC_AT_SAMPLE_ENA(x) (((x) & 0x1) << 31)
+#define G_0286CC_BARYC_AT_SAMPLE_ENA(x) (((x) >> 31) & 0x1)
+#define C_0286CC_BARYC_AT_SAMPLE_ENA 0x7FFFFFFF
+#define R_0286D0_SPI_PS_IN_CONTROL_1 0x0286D0
+#define S_0286D0_GEN_INDEX_PIX(x) (((x) & 0x1) << 0)
+#define G_0286D0_GEN_INDEX_PIX(x) (((x) >> 0) & 0x1)
+#define C_0286D0_GEN_INDEX_PIX 0xFFFFFFFE
+#define S_0286D0_GEN_INDEX_PIX_ADDR(x) (((x) & 0x7F) << 1)
+#define G_0286D0_GEN_INDEX_PIX_ADDR(x) (((x) >> 1) & 0x7F)
+#define C_0286D0_GEN_INDEX_PIX_ADDR 0xFFFFFF01
+#define S_0286D0_FRONT_FACE_ENA(x) (((x) & 0x1) << 8)
+#define G_0286D0_FRONT_FACE_ENA(x) (((x) >> 8) & 0x1)
+#define C_0286D0_FRONT_FACE_ENA 0xFFFFFEFF
+#define S_0286D0_FRONT_FACE_CHAN(x) (((x) & 0x3) << 9)
+#define G_0286D0_FRONT_FACE_CHAN(x) (((x) >> 9) & 0x3)
+#define C_0286D0_FRONT_FACE_CHAN 0xFFFFF9FF
+#define S_0286D0_FRONT_FACE_ALL_BITS(x) (((x) & 0x1) << 11)
+#define G_0286D0_FRONT_FACE_ALL_BITS(x) (((x) >> 11) & 0x1)
+#define C_0286D0_FRONT_FACE_ALL_BITS 0xFFFFF7FF
+#define S_0286D0_FRONT_FACE_ADDR(x) (((x) & 0x1F) << 12)
+#define G_0286D0_FRONT_FACE_ADDR(x) (((x) >> 12) & 0x1F)
+#define C_0286D0_FRONT_FACE_ADDR 0xFFFE0FFF
+#define S_0286D0_FOG_ADDR(x) (((x) & 0x7F) << 17)
+#define G_0286D0_FOG_ADDR(x) (((x) >> 17) & 0x7F)
+#define C_0286D0_FOG_ADDR 0xFF01FFFF
+#define S_0286D0_FIXED_PT_POSITION_ENA(x) (((x) & 0x1) << 24)
+#define G_0286D0_FIXED_PT_POSITION_ENA(x) (((x) >> 24) & 0x1)
+#define C_0286D0_FIXED_PT_POSITION_ENA 0xFEFFFFFF
+#define S_0286D0_FIXED_PT_POSITION_ADDR(x) (((x) & 0x1F) << 25)
+#define G_0286D0_FIXED_PT_POSITION_ADDR(x) (((x) >> 25) & 0x1F)
+#define C_0286D0_FIXED_PT_POSITION_ADDR 0xC1FFFFFF
+#define R_0286C4_SPI_VS_OUT_CONFIG 0x0286C4
+#define S_0286C4_VS_PER_COMPONENT(x) (((x) & 0x1) << 0)
+#define G_0286C4_VS_PER_COMPONENT(x) (((x) >> 0) & 0x1)
+#define C_0286C4_VS_PER_COMPONENT 0xFFFFFFFE
+#define S_0286C4_VS_EXPORT_COUNT(x) (((x) & 0x1F) << 1)
+#define G_0286C4_VS_EXPORT_COUNT(x) (((x) >> 1) & 0x1F)
+#define C_0286C4_VS_EXPORT_COUNT 0xFFFFFFC1
+#define S_0286C4_VS_EXPORTS_FOG(x) (((x) & 0x1) << 8)
+#define G_0286C4_VS_EXPORTS_FOG(x) (((x) >> 8) & 0x1)
+#define C_0286C4_VS_EXPORTS_FOG 0xFFFFFEFF
+#define S_0286C4_VS_OUT_FOG_VEC_ADDR(x) (((x) & 0x1F) << 9)
+#define G_0286C4_VS_OUT_FOG_VEC_ADDR(x) (((x) >> 9) & 0x1F)
+#define C_0286C4_VS_OUT_FOG_VEC_ADDR 0xFFFFC1FF
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define S_028240_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028240_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028240_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028244_PA_SC_GENERIC_SCISSOR_BR 0x028244
+#define S_028244_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028244_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028244_BR_X 0xFFFFC000
+#define S_028244_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028244_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028244_BR_Y 0xC000FFFF
+#define R_028030_PA_SC_SCREEN_SCISSOR_TL 0x028030
+#define S_028030_TL_X(x) (((x) & 0x7FFF) << 0)
+#define G_028030_TL_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028030_TL_X 0xFFFF8000
+#define S_028030_TL_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028030_TL_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028030_TL_Y 0x8000FFFF
+#define R_028034_PA_SC_SCREEN_SCISSOR_BR 0x028034
+#define S_028034_BR_X(x) (((x) & 0x7FFF) << 0)
+#define G_028034_BR_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028034_BR_X 0xFFFF8000
+#define S_028034_BR_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028034_BR_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028034_BR_Y 0x8000FFFF
+#define R_028204_PA_SC_WINDOW_SCISSOR_TL 0x028204
+#define S_028204_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028204_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028204_TL_X 0xFFFFC000
+#define S_028204_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028204_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028204_TL_Y 0xC000FFFF
+#define S_028204_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028204_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028204_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028208_PA_SC_WINDOW_SCISSOR_BR 0x028208
+#define S_028208_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028208_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028208_BR_X 0xFFFFC000
+#define S_028208_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028208_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028208_BR_Y 0xC000FFFF
+#define R_0287F0_VGT_DRAW_INITIATOR 0x0287F0
+#define S_0287F0_SOURCE_SELECT(x) (((x) & 0x3) << 0)
+#define G_0287F0_SOURCE_SELECT(x) (((x) >> 0) & 0x3)
+#define C_0287F0_SOURCE_SELECT 0xFFFFFFFC
+#define S_0287F0_MAJOR_MODE(x) (((x) & 0x3) << 2)
+#define G_0287F0_MAJOR_MODE(x) (((x) >> 2) & 0x3)
+#define C_0287F0_MAJOR_MODE 0xFFFFFFF3
+#define S_0287F0_SPRITE_EN(x) (((x) & 0x1) << 4)
+#define G_0287F0_SPRITE_EN(x) (((x) >> 4) & 0x1)
+#define C_0287F0_SPRITE_EN 0xFFFFFFEF
+#define S_0287F0_NOT_EOP(x) (((x) & 0x1) << 5)
+#define G_0287F0_NOT_EOP(x) (((x) >> 5) & 0x1)
+#define C_0287F0_NOT_EOP 0xFFFFFFDF
+#define S_0287F0_USE_OPAQUE(x) (((x) & 0x1) << 6)
+#define G_0287F0_USE_OPAQUE(x) (((x) >> 6) & 0x1)
+#define C_0287F0_USE_OPAQUE 0xFFFFFFBF
+#define R_0280A0_CB_COLOR0_INFO 0x0280A0
+#define R_0280A4_CB_COLOR1_INFO 0x0280A4
+#define R_0280A8_CB_COLOR2_INFO 0x0280A8
+#define R_0280AC_CB_COLOR3_INFO 0x0280AC
+#define R_0280B0_CB_COLOR4_INFO 0x0280B0
+#define R_0280B4_CB_COLOR5_INFO 0x0280B4
+#define R_0280B8_CB_COLOR6_INFO 0x0280B8
+#define R_0280BC_CB_COLOR7_INFO 0x0280BC
+#define R_02800C_DB_DEPTH_BASE 0x02800C
+#define R_028000_DB_DEPTH_SIZE 0x028000
+#define R_028004_DB_DEPTH_VIEW 0x028004
+#define R_028010_DB_DEPTH_INFO 0x028010
+#define R_028D24_DB_HTILE_SURFACE 0x028D24
+#define R_028D34_DB_PREFETCH_LIMIT 0x028D34
+#define R_0286D4_SPI_INTERP_CONTROL_0 0x0286D4
+#define R_028A48_PA_SC_MPASS_PS_CNTL 0x028A48
+#define R_028C00_PA_SC_LINE_CNTL 0x028C00
+#define R_028C04_PA_SC_AA_CONFIG 0x028C04
+#define R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX 0x028C1C
+#define R_028C48_PA_SC_AA_MASK 0x028C48
+#define R_028810_PA_CL_CLIP_CNTL 0x028810
+#define R_02881C_PA_CL_VS_OUT_CNTL 0x02881C
+#define R_028820_PA_CL_NANINF_CNTL 0x028820
+#define R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x028C0C
+#define R_028C10_PA_CL_GB_VERT_DISC_ADJ 0x028C10
+#define R_028C14_PA_CL_GB_HORZ_CLIP_ADJ 0x028C14
+#define R_028C18_PA_CL_GB_HORZ_DISC_ADJ 0x028C18
+#define R_028814_PA_SU_SC_MODE_CNTL 0x028814
+#define R_028A00_PA_SU_POINT_SIZE 0x028A00
+#define R_028A04_PA_SU_POINT_MINMAX 0x028A04
+#define R_028A08_PA_SU_LINE_CNTL 0x028A08
+#define R_028A0C_PA_SC_LINE_STIPPLE 0x028A0C
+#define R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL 0x028DF8
+#define R_028DFC_PA_SU_POLY_OFFSET_CLAMP 0x028DFC
+#define R_028E00_PA_SU_POLY_OFFSET_FRONT_SCALE 0x028E00
+#define R_028E04_PA_SU_POLY_OFFSET_FRONT_OFFSET 0x028E04
+#define R_028E08_PA_SU_POLY_OFFSET_BACK_SCALE 0x028E08
+#define R_028E0C_PA_SU_POLY_OFFSET_BACK_OFFSET 0x028E0C
+#define R_028818_PA_CL_VTE_CNTL 0x028818
+#define R_02843C_PA_CL_VPORT_XSCALE_0 0x02843C
+#define R_028444_PA_CL_VPORT_YSCALE_0 0x028444
+#define R_02844C_PA_CL_VPORT_ZSCALE_0 0x02844C
+#define R_028440_PA_CL_VPORT_XOFFSET_0 0x028440
+#define R_028448_PA_CL_VPORT_YOFFSET_0 0x028448
+#define R_028450_PA_CL_VPORT_ZOFFSET_0 0x028450
+#define R_028250_PA_SC_VPORT_SCISSOR_0_TL 0x028250
+#define R_028254_PA_SC_VPORT_SCISSOR_0_BR 0x028254
+#define R_028780_CB_BLEND0_CONTROL 0x028780
+#define R_028784_CB_BLEND1_CONTROL 0x028784
+#define R_028788_CB_BLEND2_CONTROL 0x028788
+#define R_02878C_CB_BLEND3_CONTROL 0x02878C
+#define R_028790_CB_BLEND4_CONTROL 0x028790
+#define R_028794_CB_BLEND5_CONTROL 0x028794
+#define R_028798_CB_BLEND6_CONTROL 0x028798
+#define R_02879C_CB_BLEND7_CONTROL 0x02879C
+#define R_028804_CB_BLEND_CONTROL 0x028804
+#define R_028028_DB_STENCIL_CLEAR 0x028028
+#define R_02802C_DB_DEPTH_CLEAR 0x02802C
+#define R_028430_DB_STENCILREFMASK 0x028430
+#define R_028434_DB_STENCILREFMASK_BF 0x028434
+#define R_028800_DB_DEPTH_CONTROL 0x028800
+#define R_02880C_DB_SHADER_CONTROL 0x02880C
+#define R_028D0C_DB_RENDER_CONTROL 0x028D0C
+#define R_028D10_DB_RENDER_OVERRIDE 0x028D10
+#define R_028D2C_DB_SRESULTS_COMPARE_STATE1 0x028D2C
+#define R_028D30_DB_PRELOAD_CONTROL 0x028D30
+#define R_028D44_DB_ALPHA_TO_MASK 0x028D44
+#define R_028868_SQ_PGM_RESOURCES_VS 0x028868
+#define R_0286CC_SPI_PS_IN_CONTROL_0 0x0286CC
+#define R_0286D0_SPI_PS_IN_CONTROL_1 0x0286D0
+#define R_028644_SPI_PS_INPUT_CNTL_0 0x028644
+#define R_028648_SPI_PS_INPUT_CNTL_1 0x028648
+#define R_02864C_SPI_PS_INPUT_CNTL_2 0x02864C
+#define R_028650_SPI_PS_INPUT_CNTL_3 0x028650
+#define R_028654_SPI_PS_INPUT_CNTL_4 0x028654
+#define R_028658_SPI_PS_INPUT_CNTL_5 0x028658
+#define R_02865C_SPI_PS_INPUT_CNTL_6 0x02865C
+#define R_028660_SPI_PS_INPUT_CNTL_7 0x028660
+#define R_028664_SPI_PS_INPUT_CNTL_8 0x028664
+#define R_028668_SPI_PS_INPUT_CNTL_9 0x028668
+#define R_02866C_SPI_PS_INPUT_CNTL_10 0x02866C
+#define R_028670_SPI_PS_INPUT_CNTL_11 0x028670
+#define R_028674_SPI_PS_INPUT_CNTL_12 0x028674
+#define R_028678_SPI_PS_INPUT_CNTL_13 0x028678
+#define R_02867C_SPI_PS_INPUT_CNTL_14 0x02867C
+#define R_028680_SPI_PS_INPUT_CNTL_15 0x028680
+#define R_028684_SPI_PS_INPUT_CNTL_16 0x028684
+#define R_028688_SPI_PS_INPUT_CNTL_17 0x028688
+#define R_02868C_SPI_PS_INPUT_CNTL_18 0x02868C
+#define R_028690_SPI_PS_INPUT_CNTL_19 0x028690
+#define R_028694_SPI_PS_INPUT_CNTL_20 0x028694
+#define R_028698_SPI_PS_INPUT_CNTL_21 0x028698
+#define R_02869C_SPI_PS_INPUT_CNTL_22 0x02869C
+#define R_0286A0_SPI_PS_INPUT_CNTL_23 0x0286A0
+#define R_0286A4_SPI_PS_INPUT_CNTL_24 0x0286A4
+#define R_0286A8_SPI_PS_INPUT_CNTL_25 0x0286A8
+#define R_0286AC_SPI_PS_INPUT_CNTL_26 0x0286AC
+#define R_0286B0_SPI_PS_INPUT_CNTL_27 0x0286B0
+#define R_0286B4_SPI_PS_INPUT_CNTL_28 0x0286B4
+#define R_0286B8_SPI_PS_INPUT_CNTL_29 0x0286B8
+#define R_0286BC_SPI_PS_INPUT_CNTL_30 0x0286BC
+#define R_0286C0_SPI_PS_INPUT_CNTL_31 0x0286C0
+#define R_028850_SQ_PGM_RESOURCES_PS 0x028850
+#define R_028854_SQ_PGM_EXPORTS_PS 0x028854
+#define R_008958_VGT_PRIMITIVE_TYPE 0x008958
+#define R_028A7C_VGT_DMA_INDEX_TYPE 0x028A7C
+#define R_028A88_VGT_DMA_NUM_INSTANCES 0x028A88
+#define R_008970_VGT_NUM_INDICES 0x008970
+#define R_0287F0_VGT_DRAW_INITIATOR 0x0287F0
+#define R_028238_CB_TARGET_MASK 0x028238
+#define R_02823C_CB_SHADER_MASK 0x02823C
+#define R_028060_CB_COLOR0_SIZE 0x028060
+#define S_028060_PITCH_TILE_MAX(x) (((x) & 0x3FF) << 0)
+#define G_028060_PITCH_TILE_MAX(x) (((x) >> 0) & 0x3FF)
+#define C_028060_PITCH_TILE_MAX 0xFFFFFC00
+#define S_028060_SLICE_TILE_MAX(x) (((x) & 0xFFFFF) << 10)
+#define G_028060_SLICE_TILE_MAX(x) (((x) >> 10) & 0xFFFFF)
+#define C_028060_SLICE_TILE_MAX 0xC00003FF
+#define R_028064_CB_COLOR1_SIZE 0x028064
+#define R_028068_CB_COLOR2_SIZE 0x028068
+#define R_02806C_CB_COLOR3_SIZE 0x02806C
+#define R_028070_CB_COLOR4_SIZE 0x028070
+#define R_028074_CB_COLOR5_SIZE 0x028074
+#define R_028078_CB_COLOR6_SIZE 0x028078
+#define R_02807C_CB_COLOR7_SIZE 0x02807C
+#define R_028040_CB_COLOR0_BASE 0x028040
+#define R_028044_CB_COLOR1_BASE 0x028044
+#define R_028048_CB_COLOR2_BASE 0x028048
+#define R_02804C_CB_COLOR3_BASE 0x02804C
+#define R_028050_CB_COLOR4_BASE 0x028050
+#define R_028054_CB_COLOR5_BASE 0x028054
+#define R_028058_CB_COLOR6_BASE 0x028058
+#define R_02805C_CB_COLOR7_BASE 0x02805C
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define R_028C04_PA_SC_AA_CONFIG 0x028C04
+#define S_028C04_MSAA_NUM_SAMPLES(x) (((x) & 0x3) << 0)
+#define G_028C04_MSAA_NUM_SAMPLES(x) (((x) >> 0) & 0x3)
+#define C_028C04_MSAA_NUM_SAMPLES 0xFFFFFFFC
+#define S_028C04_AA_MASK_CENTROID_DTMN(x) (((x) & 0x1) << 4)
+#define G_028C04_AA_MASK_CENTROID_DTMN(x) (((x) >> 4) & 0x1)
+#define C_028C04_AA_MASK_CENTROID_DTMN 0xFFFFFFEF
+#define S_028C04_MAX_SAMPLE_DIST(x) (((x) & 0xF) << 13)
+#define G_028C04_MAX_SAMPLE_DIST(x) (((x) >> 13) & 0xF)
+#define C_028C04_MAX_SAMPLE_DIST 0xFFFE1FFF
+#define R_0288CC_SQ_PGM_CF_OFFSET_PS 0x0288CC
+#define R_0288DC_SQ_PGM_CF_OFFSET_FS 0x0288DC
+#define R_0288D0_SQ_PGM_CF_OFFSET_VS 0x0288D0
+#define R_028840_SQ_PGM_START_PS 0x028840
+#define R_028894_SQ_PGM_START_FS 0x028894
+#define R_028858_SQ_PGM_START_VS 0x028858
+#define R_028080_CB_COLOR0_VIEW 0x028080
+#define S_028080_SLICE_START(x) (((x) & 0x7FF) << 0)
+#define G_028080_SLICE_START(x) (((x) >> 0) & 0x7FF)
+#define C_028080_SLICE_START 0xFFFFF800
+#define S_028080_SLICE_MAX(x) (((x) & 0x7FF) << 13)
+#define G_028080_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
+#define C_028080_SLICE_MAX 0xFF001FFF
+#define R_028100_CB_COLOR0_MASK 0x028100
+#define S_028100_CMASK_BLOCK_MAX(x) (((x) & 0xFFF) << 0)
+#define G_028100_CMASK_BLOCK_MAX(x) (((x) >> 0) & 0xFFF)
+#define C_028100_CMASK_BLOCK_MAX 0xFFFFF000
+#define S_028100_FMASK_TILE_MAX(x) (((x) & 0xFFFFF) << 12)
+#define G_028100_FMASK_TILE_MAX(x) (((x) >> 12) & 0xFFFFF)
+#define C_028100_FMASK_TILE_MAX 0x00000FFF
+#define R_028040_CB_COLOR0_BASE 0x028040
+#define S_028040_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028040_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028040_BASE_256B 0x00000000
+#define R_0280E0_CB_COLOR0_FRAG 0x0280E0
+#define S_0280E0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0280E0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0280E0_BASE_256B 0x00000000
+#define R_0280C0_CB_COLOR0_TILE 0x0280C0
+#define S_0280C0_BASE_256B(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0280C0_BASE_256B(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0280C0_BASE_256B 0x00000000
+#define R_028808_CB_COLOR_CONTROL 0x028808
+#define S_028808_FOG_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028808_FOG_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028808_FOG_ENABLE 0xFFFFFFFE
+#define S_028808_MULTIWRITE_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028808_MULTIWRITE_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028808_MULTIWRITE_ENABLE 0xFFFFFFFD
+#define S_028808_DITHER_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028808_DITHER_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028808_DITHER_ENABLE 0xFFFFFFFB
+#define S_028808_DEGAMMA_ENABLE(x) (((x) & 0x1) << 3)
+#define G_028808_DEGAMMA_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_028808_DEGAMMA_ENABLE 0xFFFFFFF7
+#define S_028808_SPECIAL_OP(x) (((x) & 0x7) << 4)
+#define G_028808_SPECIAL_OP(x) (((x) >> 4) & 0x7)
+#define C_028808_SPECIAL_OP 0xFFFFFF8F
+#define S_028808_PER_MRT_BLEND(x) (((x) & 0x1) << 7)
+#define G_028808_PER_MRT_BLEND(x) (((x) >> 7) & 0x1)
+#define C_028808_PER_MRT_BLEND 0xFFFFFF7F
+#define S_028808_TARGET_BLEND_ENABLE(x) (((x) & 0xFF) << 8)
+#define G_028808_TARGET_BLEND_ENABLE(x) (((x) >> 8) & 0xFF)
+#define C_028808_TARGET_BLEND_ENABLE 0xFFFF00FF
+#define S_028808_ROP3(x) (((x) & 0xFF) << 16)
+#define G_028808_ROP3(x) (((x) >> 16) & 0xFF)
+#define C_028808_ROP3 0xFF00FFFF
+#define R_028614_SPI_VS_OUT_ID_0 0x028614
+#define S_028614_SEMANTIC_0(x) (((x) & 0xFF) << 0)
+#define G_028614_SEMANTIC_0(x) (((x) >> 0) & 0xFF)
+#define C_028614_SEMANTIC_0 0xFFFFFF00
+#define S_028614_SEMANTIC_1(x) (((x) & 0xFF) << 8)
+#define G_028614_SEMANTIC_1(x) (((x) >> 8) & 0xFF)
+#define C_028614_SEMANTIC_1 0xFFFF00FF
+#define S_028614_SEMANTIC_2(x) (((x) & 0xFF) << 16)
+#define G_028614_SEMANTIC_2(x) (((x) >> 16) & 0xFF)
+#define C_028614_SEMANTIC_2 0xFF00FFFF
+#define S_028614_SEMANTIC_3(x) (((x) & 0xFF) << 24)
+#define G_028614_SEMANTIC_3(x) (((x) >> 24) & 0xFF)
+#define C_028614_SEMANTIC_3 0x00FFFFFF
+#define R_028618_SPI_VS_OUT_ID_1 0x028618
+#define R_02861C_SPI_VS_OUT_ID_2 0x02861C
+#define R_028620_SPI_VS_OUT_ID_3 0x028620
+#define R_028624_SPI_VS_OUT_ID_4 0x028624
+#define R_028628_SPI_VS_OUT_ID_5 0x028628
+#define R_02862C_SPI_VS_OUT_ID_6 0x02862C
+#define R_028630_SPI_VS_OUT_ID_7 0x028630
+#define R_028634_SPI_VS_OUT_ID_8 0x028634
+#define R_028638_SPI_VS_OUT_ID_9 0x028638
+#define R_038000_SQ_TEX_RESOURCE_WORD0_0 0x038000
+#define S_038000_DIM(x) (((x) & 0x7) << 0)
+#define G_038000_DIM(x) (((x) >> 0) & 0x7)
+#define C_038000_DIM 0xFFFFFFF8
+#define S_038000_TILE_MODE(x) (((x) & 0xF) << 3)
+#define G_038000_TILE_MODE(x) (((x) >> 3) & 0xF)
+#define C_038000_TILE_MODE 0xFFFFFF87
+#define S_038000_TILE_TYPE(x) (((x) & 0x1) << 7)
+#define G_038000_TILE_TYPE(x) (((x) >> 7) & 0x1)
+#define C_038000_TILE_TYPE 0xFFFFFF7F
+#define S_038000_PITCH(x) (((x) & 0x7FF) << 8)
+#define G_038000_PITCH(x) (((x) >> 8) & 0x7FF)
+#define C_038000_PITCH 0xFFF800FF
+#define S_038000_TEX_WIDTH(x) (((x) & 0x1FFF) << 19)
+#define G_038000_TEX_WIDTH(x) (((x) >> 19) & 0x1FFF)
+#define C_038000_TEX_WIDTH 0x0007FFFF
+#define R_038004_SQ_TEX_RESOURCE_WORD1_0 0x038004
+#define S_038004_TEX_HEIGHT(x) (((x) & 0x1FFF) << 0)
+#define G_038004_TEX_HEIGHT(x) (((x) >> 0) & 0x1FFF)
+#define C_038004_TEX_HEIGHT 0xFFFFE000
+#define S_038004_TEX_DEPTH(x) (((x) & 0x1FFF) << 13)
+#define G_038004_TEX_DEPTH(x) (((x) >> 13) & 0x1FFF)
+#define C_038004_TEX_DEPTH 0xFC001FFF
+#define S_038004_DATA_FORMAT(x) (((x) & 0x3F) << 26)
+#define G_038004_DATA_FORMAT(x) (((x) >> 26) & 0x3F)
+#define C_038004_DATA_FORMAT 0x03FFFFFF
+#define V_038004_COLOR_INVALID 0x00000000
+#define V_038004_COLOR_8 0x00000001
+#define V_038004_COLOR_4_4 0x00000002
+#define V_038004_COLOR_3_3_2 0x00000003
+#define V_038004_COLOR_16 0x00000005
+#define V_038004_COLOR_16_FLOAT 0x00000006
+#define V_038004_COLOR_8_8 0x00000007
+#define V_038004_COLOR_5_6_5 0x00000008
+#define V_038004_COLOR_6_5_5 0x00000009
+#define V_038004_COLOR_1_5_5_5 0x0000000A
+#define V_038004_COLOR_4_4_4_4 0x0000000B
+#define V_038004_COLOR_5_5_5_1 0x0000000C
+#define V_038004_COLOR_32 0x0000000D
+#define V_038004_COLOR_32_FLOAT 0x0000000E
+#define V_038004_COLOR_16_16 0x0000000F
+#define V_038004_COLOR_16_16_FLOAT 0x00000010
+#define V_038004_COLOR_8_24 0x00000011
+#define V_038004_COLOR_8_24_FLOAT 0x00000012
+#define V_038004_COLOR_24_8 0x00000013
+#define V_038004_COLOR_24_8_FLOAT 0x00000014
+#define V_038004_COLOR_10_11_11 0x00000015
+#define V_038004_COLOR_10_11_11_FLOAT 0x00000016
+#define V_038004_COLOR_11_11_10 0x00000017
+#define V_038004_COLOR_11_11_10_FLOAT 0x00000018
+#define V_038004_COLOR_2_10_10_10 0x00000019
+#define V_038004_COLOR_8_8_8_8 0x0000001A
+#define V_038004_COLOR_10_10_10_2 0x0000001B
+#define V_038004_COLOR_X24_8_32_FLOAT 0x0000001C
+#define V_038004_COLOR_32_32 0x0000001D
+#define V_038004_COLOR_32_32_FLOAT 0x0000001E
+#define V_038004_COLOR_16_16_16_16 0x0000001F
+#define V_038004_COLOR_16_16_16_16_FLOAT 0x00000020
+#define V_038004_COLOR_32_32_32_32 0x00000022
+#define V_038004_COLOR_32_32_32_32_FLOAT 0x00000023
+#define R_038008_SQ_TEX_RESOURCE_WORD2_0 0x038008
+#define S_038008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_038008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_038008_BASE_ADDRESS 0x00000000
+#define R_03800C_SQ_TEX_RESOURCE_WORD3_0 0x03800C
+#define S_03800C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_03800C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_03800C_MIP_ADDRESS 0x00000000
+#define R_038010_SQ_TEX_RESOURCE_WORD4_0 0x038010
+#define S_038010_FORMAT_COMP_X(x) (((x) & 0x3) << 0)
+#define G_038010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3)
+#define C_038010_FORMAT_COMP_X 0xFFFFFFFC
+#define S_038010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2)
+#define G_038010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3)
+#define C_038010_FORMAT_COMP_Y 0xFFFFFFF3
+#define S_038010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4)
+#define G_038010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3)
+#define C_038010_FORMAT_COMP_Z 0xFFFFFFCF
+#define S_038010_FORMAT_COMP_W(x) (((x) & 0x3) << 6)
+#define G_038010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3)
+#define C_038010_FORMAT_COMP_W 0xFFFFFF3F
+#define S_038010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8)
+#define G_038010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3)
+#define C_038010_NUM_FORMAT_ALL 0xFFFFFCFF
+#define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10)
+#define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1)
+#define C_038010_SRF_MODE_ALL 0xFFFFFBFF
+#define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11)
+#define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1)
+#define C_038010_FORCE_DEGAMMA 0xFFFFF7FF
+#define S_038010_ENDIAN_SWAP(x) (((x) & 0x3) << 12)
+#define G_038010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3)
+#define C_038010_ENDIAN_SWAP 0xFFFFCFFF
+#define S_038010_REQUEST_SIZE(x) (((x) & 0x3) << 14)
+#define G_038010_REQUEST_SIZE(x) (((x) >> 14) & 0x3)
+#define C_038010_REQUEST_SIZE 0xFFFF3FFF
+#define S_038010_DST_SEL_X(x) (((x) & 0x7) << 16)
+#define G_038010_DST_SEL_X(x) (((x) >> 16) & 0x7)
+#define C_038010_DST_SEL_X 0xFFF8FFFF
+#define S_038010_DST_SEL_Y(x) (((x) & 0x7) << 19)
+#define G_038010_DST_SEL_Y(x) (((x) >> 19) & 0x7)
+#define C_038010_DST_SEL_Y 0xFFC7FFFF
+#define S_038010_DST_SEL_Z(x) (((x) & 0x7) << 22)
+#define G_038010_DST_SEL_Z(x) (((x) >> 22) & 0x7)
+#define C_038010_DST_SEL_Z 0xFE3FFFFF
+#define S_038010_DST_SEL_W(x) (((x) & 0x7) << 25)
+#define G_038010_DST_SEL_W(x) (((x) >> 25) & 0x7)
+#define C_038010_DST_SEL_W 0xF1FFFFFF
+#define S_038010_BASE_LEVEL(x) (((x) & 0xF) << 28)
+#define G_038010_BASE_LEVEL(x) (((x) >> 28) & 0xF)
+#define C_038010_BASE_LEVEL 0x0FFFFFFF
+#define R_038014_SQ_TEX_RESOURCE_WORD5_0 0x038014
+#define S_038014_LAST_LEVEL(x) (((x) & 0xF) << 0)
+#define G_038014_LAST_LEVEL(x) (((x) >> 0) & 0xF)
+#define C_038014_LAST_LEVEL 0xFFFFFFF0
+#define S_038014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4)
+#define G_038014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF)
+#define C_038014_BASE_ARRAY 0xFFFE000F
+#define S_038014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17)
+#define G_038014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF)
+#define C_038014_LAST_ARRAY 0xC001FFFF
+#define R_038018_SQ_TEX_RESOURCE_WORD6_0 0x038018
+#define S_038018_MPEG_CLAMP(x) (((x) & 0x3) << 0)
+#define G_038018_MPEG_CLAMP(x) (((x) >> 0) & 0x3)
+#define C_038018_MPEG_CLAMP 0xFFFFFFFC
+#define S_038018_PERF_MODULATION(x) (((x) & 0x7) << 5)
+#define G_038018_PERF_MODULATION(x) (((x) >> 5) & 0x7)
+#define C_038018_PERF_MODULATION 0xFFFFFF1F
+#define S_038018_INTERLACED(x) (((x) & 0x1) << 8)
+#define G_038018_INTERLACED(x) (((x) >> 8) & 0x1)
+#define C_038018_INTERLACED 0xFFFFFEFF
+#define S_038018_TYPE(x) (((x) & 0x3) << 30)
+#define G_038018_TYPE(x) (((x) >> 30) & 0x3)
+#define C_038018_TYPE 0x3FFFFFFF
+#define R_008040_WAIT_UNTIL 0x008040
+#define S_008040_WAIT_CP_DMA_IDLE(x) (((x) & 0x1) << 8)
+#define G_008040_WAIT_CP_DMA_IDLE(x) (((x) >> 8) & 0x1)
+#define C_008040_WAIT_CP_DMA_IDLE 0xFFFFFEFF
+#define S_008040_WAIT_CMDFIFO(x) (((x) & 0x1) << 10)
+#define G_008040_WAIT_CMDFIFO(x) (((x) >> 10) & 0x1)
+#define C_008040_WAIT_CMDFIFO 0xFFFFFBFF
+#define S_008040_WAIT_2D_IDLE(x) (((x) & 0x1) << 14)
+#define G_008040_WAIT_2D_IDLE(x) (((x) >> 14) & 0x1)
+#define C_008040_WAIT_2D_IDLE 0xFFFFBFFF
+#define S_008040_WAIT_3D_IDLE(x) (((x) & 0x1) << 15)
+#define G_008040_WAIT_3D_IDLE(x) (((x) >> 15) & 0x1)
+#define C_008040_WAIT_3D_IDLE 0xFFFF7FFF
+#define S_008040_WAIT_2D_IDLECLEAN(x) (((x) & 0x1) << 16)
+#define G_008040_WAIT_2D_IDLECLEAN(x) (((x) >> 16) & 0x1)
+#define C_008040_WAIT_2D_IDLECLEAN 0xFFFEFFFF
+#define S_008040_WAIT_3D_IDLECLEAN(x) (((x) & 0x1) << 17)
+#define G_008040_WAIT_3D_IDLECLEAN(x) (((x) >> 17) & 0x1)
+#define C_008040_WAIT_3D_IDLECLEAN 0xFFFDFFFF
+#define S_008040_WAIT_EXTERN_SIG(x) (((x) & 0x1) << 19)
+#define G_008040_WAIT_EXTERN_SIG(x) (((x) >> 19) & 0x1)
+#define C_008040_WAIT_EXTERN_SIG 0xFFF7FFFF
+#define S_008040_CMDFIFO_ENTRIES(x) (((x) & 0x1F) << 20)
+#define G_008040_CMDFIFO_ENTRIES(x) (((x) >> 20) & 0x1F)
+#define C_008040_CMDFIFO_ENTRIES 0xFE0FFFFF
+#define R_008958_VGT_PRIMITIVE_TYPE 0x008958
+#define S_008958_PRIM_TYPE(x) (((x) & 0x3F) << 0)
+#define G_008958_PRIM_TYPE(x) (((x) >> 0) & 0x3F)
+#define C_008958_PRIM_TYPE 0xFFFFFFC0
+#define R_008C00_SQ_CONFIG 0x008C00
+#define S_008C00_VC_ENABLE(x) (((x) & 0x1) << 0)
+#define G_008C00_VC_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_008C00_VC_ENABLE 0xFFFFFFFE
+#define S_008C00_EXPORT_SRC_C(x) (((x) & 0x1) << 1)
+#define G_008C00_EXPORT_SRC_C(x) (((x) >> 1) & 0x1)
+#define C_008C00_EXPORT_SRC_C 0xFFFFFFFD
+#define S_008C00_DX9_CONSTS(x) (((x) & 0x1) << 2)
+#define G_008C00_DX9_CONSTS(x) (((x) >> 2) & 0x1)
+#define C_008C00_DX9_CONSTS 0xFFFFFFFB
+#define S_008C00_ALU_INST_PREFER_VECTOR(x) (((x) & 0x1) << 3)
+#define G_008C00_ALU_INST_PREFER_VECTOR(x) (((x) >> 3) & 0x1)
+#define C_008C00_ALU_INST_PREFER_VECTOR 0xFFFFFFF7
+#define S_008C00_DX10_CLAMP(x) (((x) & 0x1) << 4)
+#define G_008C00_DX10_CLAMP(x) (((x) >> 4) & 0x1)
+#define C_008C00_DX10_CLAMP 0xFFFFFFEF
+#define S_008C00_ALU_PREFER_ONE_WATERFALL(x) (((x) & 0x1) << 5)
+#define G_008C00_ALU_PREFER_ONE_WATERFALL(x) (((x) >> 5) & 0x1)
+#define C_008C00_ALU_PREFER_ONE_WATERFALL 0xFFFFFFDF
+#define S_008C00_ALU_MAX_ONE_WATERFALL(x) (((x) & 0x1) << 6)
+#define G_008C00_ALU_MAX_ONE_WATERFALL(x) (((x) >> 6) & 0x1)
+#define C_008C00_ALU_MAX_ONE_WATERFALL 0xFFFFFFBF
+#define S_008C00_CLAUSE_SEQ_PRIO(x) (((x) & 0x3) << 8)
+#define G_008C00_CLAUSE_SEQ_PRIO(x) (((x) >> 8) & 0x3)
+#define C_008C00_CLAUSE_SEQ_PRIO 0xFFFFFCFF
+#define S_008C00_PS_PRIO(x) (((x) & 0x3) << 24)
+#define G_008C00_PS_PRIO(x) (((x) >> 24) & 0x3)
+#define C_008C00_PS_PRIO 0xFCFFFFFF
+#define S_008C00_VS_PRIO(x) (((x) & 0x3) << 26)
+#define G_008C00_VS_PRIO(x) (((x) >> 26) & 0x3)
+#define C_008C00_VS_PRIO 0xF3FFFFFF
+#define S_008C00_GS_PRIO(x) (((x) & 0x3) << 28)
+#define G_008C00_GS_PRIO(x) (((x) >> 28) & 0x3)
+#define C_008C00_GS_PRIO 0xCFFFFFFF
+#define S_008C00_ES_PRIO(x) (((x) & 0x3) << 30)
+#define G_008C00_ES_PRIO(x) (((x) >> 30) & 0x3)
+#define C_008C00_ES_PRIO 0x3FFFFFFF
+#define R_008C04_SQ_GPR_RESOURCE_MGMT_1 0x008C04
+#define S_008C04_NUM_PS_GPRS(x) (((x) & 0xFF) << 0)
+#define G_008C04_NUM_PS_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_008C04_NUM_PS_GPRS 0xFFFFFF00
+#define S_008C04_NUM_VS_GPRS(x) (((x) & 0xFF) << 16)
+#define G_008C04_NUM_VS_GPRS(x) (((x) >> 16) & 0xFF)
+#define C_008C04_NUM_VS_GPRS 0xFF00FFFF
+#define S_008C04_NUM_CLAUSE_TEMP_GPRS(x) (((x) & 0xF) << 28)
+#define G_008C04_NUM_CLAUSE_TEMP_GPRS(x) (((x) >> 28) & 0xF)
+#define C_008C04_NUM_CLAUSE_TEMP_GPRS 0x0FFFFFFF
+#define R_008C08_SQ_GPR_RESOURCE_MGMT_2 0x008C08
+#define S_008C08_NUM_GS_GPRS(x) (((x) & 0xFF) << 0)
+#define G_008C08_NUM_GS_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_008C08_NUM_GS_GPRS 0xFFFFFF00
+#define S_008C08_NUM_ES_GPRS(x) (((x) & 0xFF) << 16)
+#define G_008C08_NUM_ES_GPRS(x) (((x) >> 16) & 0xFF)
+#define C_008C08_NUM_ES_GPRS 0xFF00FFFF
+#define R_008C0C_SQ_THREAD_RESOURCE_MGMT 0x008C0C
+#define S_008C0C_NUM_PS_THREADS(x) (((x) & 0xFF) << 0)
+#define G_008C0C_NUM_PS_THREADS(x) (((x) >> 0) & 0xFF)
+#define C_008C0C_NUM_PS_THREADS 0xFFFFFF00
+#define S_008C0C_NUM_VS_THREADS(x) (((x) & 0xFF) << 8)
+#define G_008C0C_NUM_VS_THREADS(x) (((x) >> 8) & 0xFF)
+#define C_008C0C_NUM_VS_THREADS 0xFFFF00FF
+#define S_008C0C_NUM_GS_THREADS(x) (((x) & 0xFF) << 16)
+#define G_008C0C_NUM_GS_THREADS(x) (((x) >> 16) & 0xFF)
+#define C_008C0C_NUM_GS_THREADS 0xFF00FFFF
+#define S_008C0C_NUM_ES_THREADS(x) (((x) & 0xFF) << 24)
+#define G_008C0C_NUM_ES_THREADS(x) (((x) >> 24) & 0xFF)
+#define C_008C0C_NUM_ES_THREADS 0x00FFFFFF
+#define R_008C10_SQ_STACK_RESOURCE_MGMT_1 0x008C10
+#define S_008C10_NUM_PS_STACK_ENTRIES(x) (((x) & 0xFFF) << 0)
+#define G_008C10_NUM_PS_STACK_ENTRIES(x) (((x) >> 0) & 0xFFF)
+#define C_008C10_NUM_PS_STACK_ENTRIES 0xFFFFF000
+#define S_008C10_NUM_VS_STACK_ENTRIES(x) (((x) & 0xFFF) << 16)
+#define G_008C10_NUM_VS_STACK_ENTRIES(x) (((x) >> 16) & 0xFFF)
+#define C_008C10_NUM_VS_STACK_ENTRIES 0xF000FFFF
+#define R_008C14_SQ_STACK_RESOURCE_MGMT_2 0x008C14
+#define S_008C14_NUM_GS_STACK_ENTRIES(x) (((x) & 0xFFF) << 0)
+#define G_008C14_NUM_GS_STACK_ENTRIES(x) (((x) >> 0) & 0xFFF)
+#define C_008C14_NUM_GS_STACK_ENTRIES 0xFFFFF000
+#define S_008C14_NUM_ES_STACK_ENTRIES(x) (((x) & 0xFFF) << 16)
+#define G_008C14_NUM_ES_STACK_ENTRIES(x) (((x) >> 16) & 0xFFF)
+#define C_008C14_NUM_ES_STACK_ENTRIES 0xF000FFFF
+#define R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 0x008D8C
+#define S_008D8C_RING0_OFFSET(x) (((x) & 0xFF) << 0)
+#define G_008D8C_RING0_OFFSET(x) (((x) >> 0) & 0xFF)
+#define C_008D8C_RING0_OFFSET 0xFFFFFF00
+#define S_008D8C_ISOLATE_ES_ENABLE(x) (((x) & 0x1) << 12)
+#define G_008D8C_ISOLATE_ES_ENABLE(x) (((x) >> 12) & 0x1)
+#define C_008D8C_ISOLATE_ES_ENABLE 0xFFFFEFFF
+#define S_008D8C_ISOLATE_GS_ENABLE(x) (((x) & 0x1) << 13)
+#define G_008D8C_ISOLATE_GS_ENABLE(x) (((x) >> 13) & 0x1)
+#define C_008D8C_ISOLATE_GS_ENABLE 0xFFFFDFFF
+#define S_008D8C_VS_PC_LIMIT_ENABLE(x) (((x) & 0x1) << 14)
+#define G_008D8C_VS_PC_LIMIT_ENABLE(x) (((x) >> 14) & 0x1)
+#define C_008D8C_VS_PC_LIMIT_ENABLE 0xFFFFBFFF
+#define R_009508_TA_CNTL_AUX 0x009508
+#define S_009508_DISABLE_CUBE_WRAP(x) (((x) & 0x1) << 0)
+#define G_009508_DISABLE_CUBE_WRAP(x) (((x) >> 0) & 0x1)
+#define C_009508_DISABLE_CUBE_WRAP 0xFFFFFFFE
+#define S_009508_SYNC_GRADIENT(x) (((x) & 0x1) << 24)
+#define G_009508_SYNC_GRADIENT(x) (((x) >> 24) & 0x1)
+#define C_009508_SYNC_GRADIENT 0xFEFFFFFF
+#define S_009508_SYNC_WALKER(x) (((x) & 0x1) << 25)
+#define G_009508_SYNC_WALKER(x) (((x) >> 25) & 0x1)
+#define C_009508_SYNC_WALKER 0xFDFFFFFF
+#define S_009508_SYNC_ALIGNER(x) (((x) & 0x1) << 26)
+#define G_009508_SYNC_ALIGNER(x) (((x) >> 26) & 0x1)
+#define C_009508_SYNC_ALIGNER 0xFBFFFFFF
+#define S_009508_BILINEAR_PRECISION(x) (((x) & 0x1) << 31)
+#define G_009508_BILINEAR_PRECISION(x) (((x) >> 31) & 0x1)
+#define C_009508_BILINEAR_PRECISION 0x7FFFFFFF
+#define R_009714_VC_ENHANCE 0x009714
+#define R_009830_DB_DEBUG 0x009830
+#define R_009838_DB_WATERMARKS 0x009838
+#define S_009838_DEPTH_FREE(x) (((x) & 0x1F) << 0)
+#define G_009838_DEPTH_FREE(x) (((x) >> 0) & 0x1F)
+#define C_009838_DEPTH_FREE 0xFFFFFFE0
+#define S_009838_DEPTH_FLUSH(x) (((x) & 0x3F) << 5)
+#define G_009838_DEPTH_FLUSH(x) (((x) >> 5) & 0x3F)
+#define C_009838_DEPTH_FLUSH 0xFFFFF81F
+#define S_009838_FORCE_SUMMARIZE(x) (((x) & 0xF) << 11)
+#define G_009838_FORCE_SUMMARIZE(x) (((x) >> 11) & 0xF)
+#define C_009838_FORCE_SUMMARIZE 0xFFFF87FF
+#define S_009838_DEPTH_PENDING_FREE(x) (((x) & 0x1F) << 15)
+#define G_009838_DEPTH_PENDING_FREE(x) (((x) >> 15) & 0x1F)
+#define C_009838_DEPTH_PENDING_FREE 0xFFF07FFF
+#define S_009838_DEPTH_CACHELINE_FREE(x) (((x) & 0x1F) << 20)
+#define G_009838_DEPTH_CACHELINE_FREE(x) (((x) >> 20) & 0x1F)
+#define C_009838_DEPTH_CACHELINE_FREE 0xFE0FFFFF
+#define S_009838_EARLY_Z_PANIC_DISABLE(x) (((x) & 0x1) << 25)
+#define G_009838_EARLY_Z_PANIC_DISABLE(x) (((x) >> 25) & 0x1)
+#define C_009838_EARLY_Z_PANIC_DISABLE 0xFDFFFFFF
+#define S_009838_LATE_Z_PANIC_DISABLE(x) (((x) & 0x1) << 26)
+#define G_009838_LATE_Z_PANIC_DISABLE(x) (((x) >> 26) & 0x1)
+#define C_009838_LATE_Z_PANIC_DISABLE 0xFBFFFFFF
+#define S_009838_RE_Z_PANIC_DISABLE(x) (((x) & 0x1) << 27)
+#define G_009838_RE_Z_PANIC_DISABLE(x) (((x) >> 27) & 0x1)
+#define C_009838_RE_Z_PANIC_DISABLE 0xF7FFFFFF
+#define S_009838_DB_EXTRA_DEBUG(x) (((x) & 0xF) << 28)
+#define G_009838_DB_EXTRA_DEBUG(x) (((x) >> 28) & 0xF)
+#define C_009838_DB_EXTRA_DEBUG 0x0FFFFFFF
+#define R_028030_PA_SC_SCREEN_SCISSOR_TL 0x028030
+#define S_028030_TL_X(x) (((x) & 0x7FFF) << 0)
+#define G_028030_TL_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028030_TL_X 0xFFFF8000
+#define S_028030_TL_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028030_TL_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028030_TL_Y 0x8000FFFF
+#define R_028034_PA_SC_SCREEN_SCISSOR_BR 0x028034
+#define S_028034_BR_X(x) (((x) & 0x7FFF) << 0)
+#define G_028034_BR_X(x) (((x) >> 0) & 0x7FFF)
+#define C_028034_BR_X 0xFFFF8000
+#define S_028034_BR_Y(x) (((x) & 0x7FFF) << 16)
+#define G_028034_BR_Y(x) (((x) >> 16) & 0x7FFF)
+#define C_028034_BR_Y 0x8000FFFF
+#define R_028200_PA_SC_WINDOW_OFFSET 0x028200
+#define S_028200_WINDOW_X_OFFSET(x) (((x) & 0x7FFF) << 0)
+#define G_028200_WINDOW_X_OFFSET(x) (((x) >> 0) & 0x7FFF)
+#define C_028200_WINDOW_X_OFFSET 0xFFFF8000
+#define S_028200_WINDOW_Y_OFFSET(x) (((x) & 0x7FFF) << 16)
+#define G_028200_WINDOW_Y_OFFSET(x) (((x) >> 16) & 0x7FFF)
+#define C_028200_WINDOW_Y_OFFSET 0x8000FFFF
+#define R_028204_PA_SC_WINDOW_SCISSOR_TL 0x028204
+#define S_028204_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028204_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028204_TL_X 0xFFFFC000
+#define S_028204_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028204_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028204_TL_Y 0xC000FFFF
+#define S_028204_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028204_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028204_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028208_PA_SC_WINDOW_SCISSOR_BR 0x028208
+#define S_028208_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028208_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028208_BR_X 0xFFFFC000
+#define S_028208_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028208_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028208_BR_Y 0xC000FFFF
+#define R_02820C_PA_SC_CLIPRECT_RULE 0x02820C
+#define S_02820C_CLIP_RULE(x) (((x) & 0xFFFF) << 0)
+#define G_02820C_CLIP_RULE(x) (((x) >> 0) & 0xFFFF)
+#define C_02820C_CLIP_RULE 0xFFFF0000
+#define R_028210_PA_SC_CLIPRECT_0_TL 0x028210
+#define S_028210_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028210_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028210_TL_X 0xFFFFC000
+#define S_028210_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028210_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028210_TL_Y 0xC000FFFF
+#define R_028214_PA_SC_CLIPRECT_0_BR 0x028214
+#define S_028214_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028214_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028214_BR_X 0xFFFFC000
+#define S_028214_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028214_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028214_BR_Y 0xC000FFFF
+#define R_028218_PA_SC_CLIPRECT_1_TL 0x028218
+#define R_02821C_PA_SC_CLIPRECT_1_BR 0x02821C
+#define R_028220_PA_SC_CLIPRECT_2_TL 0x028220
+#define R_028224_PA_SC_CLIPRECT_2_BR 0x028224
+#define R_028228_PA_SC_CLIPRECT_3_TL 0x028228
+#define R_02822C_PA_SC_CLIPRECT_3_BR 0x02822C
+#define R_028230_PA_SC_EDGERULE 0x028230
+#define R_028240_PA_SC_GENERIC_SCISSOR_TL 0x028240
+#define S_028240_TL_X(x) (((x) & 0x3FFF) << 0)
+#define G_028240_TL_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028240_TL_X 0xFFFFC000
+#define S_028240_TL_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028240_TL_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028240_TL_Y 0xC000FFFF
+#define S_028240_WINDOW_OFFSET_DISABLE(x) (((x) & 0x1) << 31)
+#define G_028240_WINDOW_OFFSET_DISABLE(x) (((x) >> 31) & 0x1)
+#define C_028240_WINDOW_OFFSET_DISABLE 0x7FFFFFFF
+#define R_028244_PA_SC_GENERIC_SCISSOR_BR 0x028244
+#define S_028244_BR_X(x) (((x) & 0x3FFF) << 0)
+#define G_028244_BR_X(x) (((x) >> 0) & 0x3FFF)
+#define C_028244_BR_X 0xFFFFC000
+#define S_028244_BR_Y(x) (((x) & 0x3FFF) << 16)
+#define G_028244_BR_Y(x) (((x) >> 16) & 0x3FFF)
+#define C_028244_BR_Y 0xC000FFFF
+#define R_0282D0_PA_SC_VPORT_ZMIN_0 0x0282D0
+#define S_0282D0_VPORT_ZMIN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0282D0_VPORT_ZMIN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0282D0_VPORT_ZMIN 0x00000000
+#define R_0282D4_PA_SC_VPORT_ZMAX_0 0x0282D4
+#define S_0282D4_VPORT_ZMAX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0282D4_VPORT_ZMAX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0282D4_VPORT_ZMAX 0x00000000
+#define R_028350_SX_MISC 0x028350
+#define S_028350_MULTIPASS(x) (((x) & 0x1) << 0)
+#define G_028350_MULTIPASS(x) (((x) >> 0) & 0x1)
+#define C_028350_MULTIPASS 0xFFFFFFFE
+#define R_028380_SQ_VTX_SEMANTIC_0 0x028380
+#define S_028380_SEMANTIC_ID(x) (((x) & 0xFF) << 0)
+#define G_028380_SEMANTIC_ID(x) (((x) >> 0) & 0xFF)
+#define C_028380_SEMANTIC_ID 0xFFFFFF00
+#define R_028384_SQ_VTX_SEMANTIC_1 0x028384
+#define R_028388_SQ_VTX_SEMANTIC_2 0x028388
+#define R_02838C_SQ_VTX_SEMANTIC_3 0x02838C
+#define R_028390_SQ_VTX_SEMANTIC_4 0x028390
+#define R_028394_SQ_VTX_SEMANTIC_5 0x028394
+#define R_028398_SQ_VTX_SEMANTIC_6 0x028398
+#define R_02839C_SQ_VTX_SEMANTIC_7 0x02839C
+#define R_0283A0_SQ_VTX_SEMANTIC_8 0x0283A0
+#define R_0283A4_SQ_VTX_SEMANTIC_9 0x0283A4
+#define R_0283A8_SQ_VTX_SEMANTIC_10 0x0283A8
+#define R_0283AC_SQ_VTX_SEMANTIC_11 0x0283AC
+#define R_0283B0_SQ_VTX_SEMANTIC_12 0x0283B0
+#define R_0283B4_SQ_VTX_SEMANTIC_13 0x0283B4
+#define R_0283B8_SQ_VTX_SEMANTIC_14 0x0283B8
+#define R_0283BC_SQ_VTX_SEMANTIC_15 0x0283BC
+#define R_0283C0_SQ_VTX_SEMANTIC_16 0x0283C0
+#define R_0283C4_SQ_VTX_SEMANTIC_17 0x0283C4
+#define R_0283C8_SQ_VTX_SEMANTIC_18 0x0283C8
+#define R_0283CC_SQ_VTX_SEMANTIC_19 0x0283CC
+#define R_0283D0_SQ_VTX_SEMANTIC_20 0x0283D0
+#define R_0283D4_SQ_VTX_SEMANTIC_21 0x0283D4
+#define R_0283D8_SQ_VTX_SEMANTIC_22 0x0283D8
+#define R_0283DC_SQ_VTX_SEMANTIC_23 0x0283DC
+#define R_0283E0_SQ_VTX_SEMANTIC_24 0x0283E0
+#define R_0283E4_SQ_VTX_SEMANTIC_25 0x0283E4
+#define R_0283E8_SQ_VTX_SEMANTIC_26 0x0283E8
+#define R_0283EC_SQ_VTX_SEMANTIC_27 0x0283EC
+#define R_0283F0_SQ_VTX_SEMANTIC_28 0x0283F0
+#define R_0283F4_SQ_VTX_SEMANTIC_29 0x0283F4
+#define R_0283F8_SQ_VTX_SEMANTIC_30 0x0283F8
+#define R_0283FC_SQ_VTX_SEMANTIC_31 0x0283FC
+#define R_028400_VGT_MAX_VTX_INDX 0x028400
+#define S_028400_MAX_INDX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028400_MAX_INDX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028400_MAX_INDX 0x00000000
+#define R_028404_VGT_MIN_VTX_INDX 0x028404
+#define S_028404_MIN_INDX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028404_MIN_INDX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028404_MIN_INDX 0x00000000
+#define R_028408_VGT_INDX_OFFSET 0x028408
+#define S_028408_INDX_OFFSET(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028408_INDX_OFFSET(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028408_INDX_OFFSET 0x00000000
+#define R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX 0x02840C
+#define S_02840C_RESET_INDX(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02840C_RESET_INDX(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02840C_RESET_INDX 0x00000000
+#define R_028410_SX_ALPHA_TEST_CONTROL 0x028410
+#define S_028410_ALPHA_FUNC(x) (((x) & 0x7) << 0)
+#define G_028410_ALPHA_FUNC(x) (((x) >> 0) & 0x7)
+#define C_028410_ALPHA_FUNC 0xFFFFFFF8
+#define S_028410_ALPHA_TEST_ENABLE(x) (((x) & 0x1) << 3)
+#define G_028410_ALPHA_TEST_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_028410_ALPHA_TEST_ENABLE 0xFFFFFFF7
+#define S_028410_ALPHA_TEST_BYPASS(x) (((x) & 0x1) << 8)
+#define G_028410_ALPHA_TEST_BYPASS(x) (((x) >> 8) & 0x1)
+#define C_028410_ALPHA_TEST_BYPASS 0xFFFFFEFF
+#define R_028414_CB_BLEND_RED 0x028414
+#define S_028414_BLEND_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028414_BLEND_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028414_BLEND_RED 0x00000000
+#define R_028418_CB_BLEND_GREEN 0x028418
+#define S_028418_BLEND_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028418_BLEND_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028418_BLEND_GREEN 0x00000000
+#define R_02841C_CB_BLEND_BLUE 0x02841C
+#define S_02841C_BLEND_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02841C_BLEND_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02841C_BLEND_BLUE 0x00000000
+#define R_028420_CB_BLEND_ALPHA 0x028420
+#define S_028420_BLEND_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028420_BLEND_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028420_BLEND_ALPHA 0x00000000
+#define R_028438_SX_ALPHA_REF 0x028438
+#define S_028438_ALPHA_REF(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028438_ALPHA_REF(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028438_ALPHA_REF 0x00000000
+#define R_0286C8_SPI_THREAD_GROUPING 0x0286C8
+#define S_0286C8_PS_GROUPING(x) (((x) & 0x1F) << 0)
+#define G_0286C8_PS_GROUPING(x) (((x) >> 0) & 0x1F)
+#define C_0286C8_PS_GROUPING 0xFFFFFFE0
+#define S_0286C8_VS_GROUPING(x) (((x) & 0x1F) << 8)
+#define G_0286C8_VS_GROUPING(x) (((x) >> 8) & 0x1F)
+#define C_0286C8_VS_GROUPING 0xFFFFE0FF
+#define S_0286C8_GS_GROUPING(x) (((x) & 0x1F) << 16)
+#define G_0286C8_GS_GROUPING(x) (((x) >> 16) & 0x1F)
+#define C_0286C8_GS_GROUPING 0xFFE0FFFF
+#define S_0286C8_ES_GROUPING(x) (((x) & 0x1F) << 24)
+#define G_0286C8_ES_GROUPING(x) (((x) >> 24) & 0x1F)
+#define C_0286C8_ES_GROUPING 0xE0FFFFFF
+#define R_0286D8_SPI_INPUT_Z 0x0286D8
+#define S_0286D8_PROVIDE_Z_TO_SPI(x) (((x) & 0x1) << 0)
+#define G_0286D8_PROVIDE_Z_TO_SPI(x) (((x) >> 0) & 0x1)
+#define C_0286D8_PROVIDE_Z_TO_SPI 0xFFFFFFFE
+#define R_0286DC_SPI_FOG_CNTL 0x0286DC
+#define S_0286DC_PASS_FOG_THROUGH_PS(x) (((x) & 0x1) << 0)
+#define G_0286DC_PASS_FOG_THROUGH_PS(x) (((x) >> 0) & 0x1)
+#define C_0286DC_PASS_FOG_THROUGH_PS 0xFFFFFFFE
+#define S_0286DC_PIXEL_FOG_FUNC(x) (((x) & 0x3) << 1)
+#define G_0286DC_PIXEL_FOG_FUNC(x) (((x) >> 1) & 0x3)
+#define C_0286DC_PIXEL_FOG_FUNC 0xFFFFFFF9
+#define S_0286DC_PIXEL_FOG_SRC_SEL(x) (((x) & 0x1) << 3)
+#define G_0286DC_PIXEL_FOG_SRC_SEL(x) (((x) >> 3) & 0x1)
+#define C_0286DC_PIXEL_FOG_SRC_SEL 0xFFFFFFF7
+#define S_0286DC_VS_FOG_CLAMP_DISABLE(x) (((x) & 0x1) << 4)
+#define G_0286DC_VS_FOG_CLAMP_DISABLE(x) (((x) >> 4) & 0x1)
+#define C_0286DC_VS_FOG_CLAMP_DISABLE 0xFFFFFFEF
+#define R_0286E0_SPI_FOG_FUNC_SCALE 0x0286E0
+#define S_0286E0_VALUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0286E0_VALUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0286E0_VALUE 0x00000000
+#define R_0286E4_SPI_FOG_FUNC_BIAS 0x0286E4
+#define S_0286E4_VALUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_0286E4_VALUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_0286E4_VALUE 0x00000000
+#define R_0287A0_CB_SHADER_CONTROL 0x0287A0
+#define S_0287A0_RT0_ENABLE(x) (((x) & 0x1) << 0)
+#define G_0287A0_RT0_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_0287A0_RT0_ENABLE 0xFFFFFFFE
+#define S_0287A0_RT1_ENABLE(x) (((x) & 0x1) << 1)
+#define G_0287A0_RT1_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_0287A0_RT1_ENABLE 0xFFFFFFFD
+#define S_0287A0_RT2_ENABLE(x) (((x) & 0x1) << 2)
+#define G_0287A0_RT2_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_0287A0_RT2_ENABLE 0xFFFFFFFB
+#define S_0287A0_RT3_ENABLE(x) (((x) & 0x1) << 3)
+#define G_0287A0_RT3_ENABLE(x) (((x) >> 3) & 0x1)
+#define C_0287A0_RT3_ENABLE 0xFFFFFFF7
+#define S_0287A0_RT4_ENABLE(x) (((x) & 0x1) << 4)
+#define G_0287A0_RT4_ENABLE(x) (((x) >> 4) & 0x1)
+#define C_0287A0_RT4_ENABLE 0xFFFFFFEF
+#define S_0287A0_RT5_ENABLE(x) (((x) & 0x1) << 5)
+#define G_0287A0_RT5_ENABLE(x) (((x) >> 5) & 0x1)
+#define C_0287A0_RT5_ENABLE 0xFFFFFFDF
+#define S_0287A0_RT6_ENABLE(x) (((x) & 0x1) << 6)
+#define G_0287A0_RT6_ENABLE(x) (((x) >> 6) & 0x1)
+#define C_0287A0_RT6_ENABLE 0xFFFFFFBF
+#define S_0287A0_RT7_ENABLE(x) (((x) & 0x1) << 7)
+#define G_0287A0_RT7_ENABLE(x) (((x) >> 7) & 0x1)
+#define C_0287A0_RT7_ENABLE 0xFFFFFF7F
+#define R_028894_SQ_PGM_START_FS 0x028894
+#define S_028894_PGM_START(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028894_PGM_START(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028894_PGM_START 0x00000000
+#define R_0288A4_SQ_PGM_RESOURCES_FS 0x0288A4
+#define S_0288A4_NUM_GPRS(x) (((x) & 0xFF) << 0)
+#define G_0288A4_NUM_GPRS(x) (((x) >> 0) & 0xFF)
+#define C_0288A4_NUM_GPRS 0xFFFFFF00
+#define S_0288A4_STACK_SIZE(x) (((x) & 0xFF) << 8)
+#define G_0288A4_STACK_SIZE(x) (((x) >> 8) & 0xFF)
+#define C_0288A4_STACK_SIZE 0xFFFF00FF
+#define S_0288A4_DX10_CLAMP(x) (((x) & 0x1) << 21)
+#define G_0288A4_DX10_CLAMP(x) (((x) >> 21) & 0x1)
+#define C_0288A4_DX10_CLAMP 0xFFDFFFFF
+#define R_0288A8_SQ_ESGS_RING_ITEMSIZE 0x0288A8
+#define S_0288A8_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288A8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288A8_ITEMSIZE 0xFFFF8000
+#define R_0288AC_SQ_GSVS_RING_ITEMSIZE 0x0288AC
+#define S_0288AC_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288AC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288AC_ITEMSIZE 0xFFFF8000
+#define R_0288B0_SQ_ESTMP_RING_ITEMSIZE 0x0288B0
+#define S_0288B0_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288B0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288B0_ITEMSIZE 0xFFFF8000
+#define R_0288B4_SQ_GSTMP_RING_ITEMSIZE 0x0288B4
+#define S_0288B4_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288B4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288B4_ITEMSIZE 0xFFFF8000
+#define R_0288B8_SQ_VSTMP_RING_ITEMSIZE 0x0288B8
+#define S_0288B8_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288B8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288B8_ITEMSIZE 0xFFFF8000
+#define R_0288BC_SQ_PSTMP_RING_ITEMSIZE 0x0288BC
+#define S_0288BC_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288BC_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288BC_ITEMSIZE 0xFFFF8000
+#define R_0288C0_SQ_FBUF_RING_ITEMSIZE 0x0288C0
+#define S_0288C0_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288C0_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288C0_ITEMSIZE 0xFFFF8000
+#define R_0288C4_SQ_REDUC_RING_ITEMSIZE 0x0288C4
+#define S_0288C4_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288C4_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288C4_ITEMSIZE 0xFFFF8000
+#define R_0288C8_SQ_GS_VERT_ITEMSIZE 0x0288C8
+#define S_0288C8_ITEMSIZE(x) (((x) & 0x7FFF) << 0)
+#define G_0288C8_ITEMSIZE(x) (((x) >> 0) & 0x7FFF)
+#define C_0288C8_ITEMSIZE 0xFFFF8000
+#define R_0288DC_SQ_PGM_CF_OFFSET_FS 0x0288DC
+#define S_0288DC_PGM_CF_OFFSET(x) (((x) & 0xFFFFF) << 0)
+#define G_0288DC_PGM_CF_OFFSET(x) (((x) >> 0) & 0xFFFFF)
+#define C_0288DC_PGM_CF_OFFSET 0xFFF00000
+#define R_028A10_VGT_OUTPUT_PATH_CNTL 0x028A10
+#define S_028A10_PATH_SELECT(x) (((x) & 0x3) << 0)
+#define G_028A10_PATH_SELECT(x) (((x) >> 0) & 0x3)
+#define C_028A10_PATH_SELECT 0xFFFFFFFC
+#define R_028A14_VGT_HOS_CNTL 0x028A14
+#define S_028A14_TESS_MODE(x) (((x) & 0x3) << 0)
+#define G_028A14_TESS_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A14_TESS_MODE 0xFFFFFFFC
+#define R_028A18_VGT_HOS_MAX_TESS_LEVEL 0x028A18
+#define S_028A18_MAX_TESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028A18_MAX_TESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028A18_MAX_TESS 0x00000000
+#define R_028A1C_VGT_HOS_MIN_TESS_LEVEL 0x028A1C
+#define S_028A1C_MIN_TESS(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028A1C_MIN_TESS(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028A1C_MIN_TESS 0x00000000
+#define R_028A20_VGT_HOS_REUSE_DEPTH 0x028A20
+#define S_028A20_REUSE_DEPTH(x) (((x) & 0xFF) << 0)
+#define G_028A20_REUSE_DEPTH(x) (((x) >> 0) & 0xFF)
+#define C_028A20_REUSE_DEPTH 0xFFFFFF00
+#define R_028A24_VGT_GROUP_PRIM_TYPE 0x028A24
+#define S_028A24_PRIM_TYPE(x) (((x) & 0x1F) << 0)
+#define G_028A24_PRIM_TYPE(x) (((x) >> 0) & 0x1F)
+#define C_028A24_PRIM_TYPE 0xFFFFFFE0
+#define S_028A24_RETAIN_ORDER(x) (((x) & 0x1) << 14)
+#define G_028A24_RETAIN_ORDER(x) (((x) >> 14) & 0x1)
+#define C_028A24_RETAIN_ORDER 0xFFFFBFFF
+#define S_028A24_RETAIN_QUADS(x) (((x) & 0x1) << 15)
+#define G_028A24_RETAIN_QUADS(x) (((x) >> 15) & 0x1)
+#define C_028A24_RETAIN_QUADS 0xFFFF7FFF
+#define S_028A24_PRIM_ORDER(x) (((x) & 0x7) << 16)
+#define G_028A24_PRIM_ORDER(x) (((x) >> 16) & 0x7)
+#define C_028A24_PRIM_ORDER 0xFFF8FFFF
+#define R_028A28_VGT_GROUP_FIRST_DECR 0x028A28
+#define S_028A28_FIRST_DECR(x) (((x) & 0xF) << 0)
+#define G_028A28_FIRST_DECR(x) (((x) >> 0) & 0xF)
+#define C_028A28_FIRST_DECR 0xFFFFFFF0
+#define R_028A2C_VGT_GROUP_DECR 0x028A2C
+#define S_028A2C_DECR(x) (((x) & 0xF) << 0)
+#define G_028A2C_DECR(x) (((x) >> 0) & 0xF)
+#define C_028A2C_DECR 0xFFFFFFF0
+#define R_028A30_VGT_GROUP_VECT_0_CNTL 0x028A30
+#define S_028A30_COMP_X_EN(x) (((x) & 0x1) << 0)
+#define G_028A30_COMP_X_EN(x) (((x) >> 0) & 0x1)
+#define C_028A30_COMP_X_EN 0xFFFFFFFE
+#define S_028A30_COMP_Y_EN(x) (((x) & 0x1) << 1)
+#define G_028A30_COMP_Y_EN(x) (((x) >> 1) & 0x1)
+#define C_028A30_COMP_Y_EN 0xFFFFFFFD
+#define S_028A30_COMP_Z_EN(x) (((x) & 0x1) << 2)
+#define G_028A30_COMP_Z_EN(x) (((x) >> 2) & 0x1)
+#define C_028A30_COMP_Z_EN 0xFFFFFFFB
+#define S_028A30_COMP_W_EN(x) (((x) & 0x1) << 3)
+#define G_028A30_COMP_W_EN(x) (((x) >> 3) & 0x1)
+#define C_028A30_COMP_W_EN 0xFFFFFFF7
+#define S_028A30_STRIDE(x) (((x) & 0xFF) << 8)
+#define G_028A30_STRIDE(x) (((x) >> 8) & 0xFF)
+#define C_028A30_STRIDE 0xFFFF00FF
+#define S_028A30_SHIFT(x) (((x) & 0xFF) << 16)
+#define G_028A30_SHIFT(x) (((x) >> 16) & 0xFF)
+#define C_028A30_SHIFT 0xFF00FFFF
+#define R_028A34_VGT_GROUP_VECT_1_CNTL 0x028A34
+#define S_028A34_COMP_X_EN(x) (((x) & 0x1) << 0)
+#define G_028A34_COMP_X_EN(x) (((x) >> 0) & 0x1)
+#define C_028A34_COMP_X_EN 0xFFFFFFFE
+#define S_028A34_COMP_Y_EN(x) (((x) & 0x1) << 1)
+#define G_028A34_COMP_Y_EN(x) (((x) >> 1) & 0x1)
+#define C_028A34_COMP_Y_EN 0xFFFFFFFD
+#define S_028A34_COMP_Z_EN(x) (((x) & 0x1) << 2)
+#define G_028A34_COMP_Z_EN(x) (((x) >> 2) & 0x1)
+#define C_028A34_COMP_Z_EN 0xFFFFFFFB
+#define S_028A34_COMP_W_EN(x) (((x) & 0x1) << 3)
+#define G_028A34_COMP_W_EN(x) (((x) >> 3) & 0x1)
+#define C_028A34_COMP_W_EN 0xFFFFFFF7
+#define S_028A34_STRIDE(x) (((x) & 0xFF) << 8)
+#define G_028A34_STRIDE(x) (((x) >> 8) & 0xFF)
+#define C_028A34_STRIDE 0xFFFF00FF
+#define S_028A34_SHIFT(x) (((x) & 0xFF) << 16)
+#define G_028A34_SHIFT(x) (((x) >> 16) & 0xFF)
+#define C_028A34_SHIFT 0xFF00FFFF
+#define R_028A38_VGT_GROUP_VECT_0_FMT_CNTL 0x028A38
+#define S_028A38_X_CONV(x) (((x) & 0xF) << 0)
+#define G_028A38_X_CONV(x) (((x) >> 0) & 0xF)
+#define C_028A38_X_CONV 0xFFFFFFF0
+#define S_028A38_X_OFFSET(x) (((x) & 0xF) << 4)
+#define G_028A38_X_OFFSET(x) (((x) >> 4) & 0xF)
+#define C_028A38_X_OFFSET 0xFFFFFF0F
+#define S_028A38_Y_CONV(x) (((x) & 0xF) << 8)
+#define G_028A38_Y_CONV(x) (((x) >> 8) & 0xF)
+#define C_028A38_Y_CONV 0xFFFFF0FF
+#define S_028A38_Y_OFFSET(x) (((x) & 0xF) << 12)
+#define G_028A38_Y_OFFSET(x) (((x) >> 12) & 0xF)
+#define C_028A38_Y_OFFSET 0xFFFF0FFF
+#define S_028A38_Z_CONV(x) (((x) & 0xF) << 16)
+#define G_028A38_Z_CONV(x) (((x) >> 16) & 0xF)
+#define C_028A38_Z_CONV 0xFFF0FFFF
+#define S_028A38_Z_OFFSET(x) (((x) & 0xF) << 20)
+#define G_028A38_Z_OFFSET(x) (((x) >> 20) & 0xF)
+#define C_028A38_Z_OFFSET 0xFF0FFFFF
+#define S_028A38_W_CONV(x) (((x) & 0xF) << 24)
+#define G_028A38_W_CONV(x) (((x) >> 24) & 0xF)
+#define C_028A38_W_CONV 0xF0FFFFFF
+#define S_028A38_W_OFFSET(x) (((x) & 0xF) << 28)
+#define G_028A38_W_OFFSET(x) (((x) >> 28) & 0xF)
+#define C_028A38_W_OFFSET 0x0FFFFFFF
+#define R_028A3C_VGT_GROUP_VECT_1_FMT_CNTL 0x028A3C
+#define S_028A3C_X_CONV(x) (((x) & 0xF) << 0)
+#define G_028A3C_X_CONV(x) (((x) >> 0) & 0xF)
+#define C_028A3C_X_CONV 0xFFFFFFF0
+#define S_028A3C_X_OFFSET(x) (((x) & 0xF) << 4)
+#define G_028A3C_X_OFFSET(x) (((x) >> 4) & 0xF)
+#define C_028A3C_X_OFFSET 0xFFFFFF0F
+#define S_028A3C_Y_CONV(x) (((x) & 0xF) << 8)
+#define G_028A3C_Y_CONV(x) (((x) >> 8) & 0xF)
+#define C_028A3C_Y_CONV 0xFFFFF0FF
+#define S_028A3C_Y_OFFSET(x) (((x) & 0xF) << 12)
+#define G_028A3C_Y_OFFSET(x) (((x) >> 12) & 0xF)
+#define C_028A3C_Y_OFFSET 0xFFFF0FFF
+#define S_028A3C_Z_CONV(x) (((x) & 0xF) << 16)
+#define G_028A3C_Z_CONV(x) (((x) >> 16) & 0xF)
+#define C_028A3C_Z_CONV 0xFFF0FFFF
+#define S_028A3C_Z_OFFSET(x) (((x) & 0xF) << 20)
+#define G_028A3C_Z_OFFSET(x) (((x) >> 20) & 0xF)
+#define C_028A3C_Z_OFFSET 0xFF0FFFFF
+#define S_028A3C_W_CONV(x) (((x) & 0xF) << 24)
+#define G_028A3C_W_CONV(x) (((x) >> 24) & 0xF)
+#define C_028A3C_W_CONV 0xF0FFFFFF
+#define S_028A3C_W_OFFSET(x) (((x) & 0xF) << 28)
+#define G_028A3C_W_OFFSET(x) (((x) >> 28) & 0xF)
+#define C_028A3C_W_OFFSET 0x0FFFFFFF
+#define R_028A40_VGT_GS_MODE 0x028A40
+#define S_028A40_MODE(x) (((x) & 0x3) << 0)
+#define G_028A40_MODE(x) (((x) >> 0) & 0x3)
+#define C_028A40_MODE 0xFFFFFFFC
+#define S_028A40_ES_PASSTHRU(x) (((x) & 0x1) << 2)
+#define G_028A40_ES_PASSTHRU(x) (((x) >> 2) & 0x1)
+#define C_028A40_ES_PASSTHRU 0xFFFFFFFB
+#define S_028A40_CUT_MODE(x) (((x) & 0x3) << 3)
+#define G_028A40_CUT_MODE(x) (((x) >> 3) & 0x3)
+#define C_028A40_CUT_MODE 0xFFFFFFE7
+#define R_028A4C_PA_SC_MODE_CNTL 0x028A4C
+#define S_028A4C_MSAA_ENABLE(x) (((x) & 0x1) << 0)
+#define G_028A4C_MSAA_ENABLE(x) (((x) >> 0) & 0x1)
+#define C_028A4C_MSAA_ENABLE 0xFFFFFFFE
+#define S_028A4C_CLIPRECT_ENABLE(x) (((x) & 0x1) << 1)
+#define G_028A4C_CLIPRECT_ENABLE(x) (((x) >> 1) & 0x1)
+#define C_028A4C_CLIPRECT_ENABLE 0xFFFFFFFD
+#define S_028A4C_LINE_STIPPLE_ENABLE(x) (((x) & 0x1) << 2)
+#define G_028A4C_LINE_STIPPLE_ENABLE(x) (((x) >> 2) & 0x1)
+#define C_028A4C_LINE_STIPPLE_ENABLE 0xFFFFFFFB
+#define S_028A4C_MULTI_CHIP_PRIM_DISCARD_ENAB(x) (((x) & 0x1) << 3)
+#define G_028A4C_MULTI_CHIP_PRIM_DISCARD_ENAB(x) (((x) >> 3) & 0x1)
+#define C_028A4C_MULTI_CHIP_PRIM_DISCARD_ENAB 0xFFFFFFF7
+#define S_028A4C_WALK_ORDER_ENABLE(x) (((x) & 0x1) << 4)
+#define G_028A4C_WALK_ORDER_ENABLE(x) (((x) >> 4) & 0x1)
+#define C_028A4C_WALK_ORDER_ENABLE 0xFFFFFFEF
+#define S_028A4C_HALVE_DETAIL_SAMPLE_PERF(x) (((x) & 0x1) << 5)
+#define G_028A4C_HALVE_DETAIL_SAMPLE_PERF(x) (((x) >> 5) & 0x1)
+#define C_028A4C_HALVE_DETAIL_SAMPLE_PERF 0xFFFFFFDF
+#define S_028A4C_WALK_SIZE(x) (((x) & 0x1) << 6)
+#define G_028A4C_WALK_SIZE(x) (((x) >> 6) & 0x1)
+#define C_028A4C_WALK_SIZE 0xFFFFFFBF
+#define S_028A4C_WALK_ALIGNMENT(x) (((x) & 0x1) << 7)
+#define G_028A4C_WALK_ALIGNMENT(x) (((x) >> 7) & 0x1)
+#define C_028A4C_WALK_ALIGNMENT 0xFFFFFF7F
+#define S_028A4C_WALK_ALIGN8_PRIM_FITS_ST(x) (((x) & 0x1) << 8)
+#define G_028A4C_WALK_ALIGN8_PRIM_FITS_ST(x) (((x) >> 8) & 0x1)
+#define C_028A4C_WALK_ALIGN8_PRIM_FITS_ST 0xFFFFFEFF
+#define S_028A4C_TILE_COVER_NO_SCISSOR(x) (((x) & 0x1) << 9)
+#define G_028A4C_TILE_COVER_NO_SCISSOR(x) (((x) >> 9) & 0x1)
+#define C_028A4C_TILE_COVER_NO_SCISSOR 0xFFFFFDFF
+#define S_028A4C_KILL_PIX_POST_HI_Z(x) (((x) & 0x1) << 10)
+#define G_028A4C_KILL_PIX_POST_HI_Z(x) (((x) >> 10) & 0x1)
+#define C_028A4C_KILL_PIX_POST_HI_Z 0xFFFFFBFF
+#define S_028A4C_KILL_PIX_POST_DETAIL_MASK(x) (((x) & 0x1) << 11)
+#define G_028A4C_KILL_PIX_POST_DETAIL_MASK(x) (((x) >> 11) & 0x1)
+#define C_028A4C_KILL_PIX_POST_DETAIL_MASK 0xFFFFF7FF
+#define S_028A4C_MULTI_CHIP_SUPERTILE_ENABLE(x) (((x) & 0x1) << 12)
+#define G_028A4C_MULTI_CHIP_SUPERTILE_ENABLE(x) (((x) >> 12) & 0x1)
+#define C_028A4C_MULTI_CHIP_SUPERTILE_ENABLE 0xFFFFEFFF
+#define S_028A4C_TILE_COVER_DISABLE(x) (((x) & 0x1) << 13)
+#define G_028A4C_TILE_COVER_DISABLE(x) (((x) >> 13) & 0x1)
+#define C_028A4C_TILE_COVER_DISABLE 0xFFFFDFFF
+#define S_028A4C_FORCE_EOV_CNTDWN_ENABLE(x) (((x) & 0x1) << 14)
+#define G_028A4C_FORCE_EOV_CNTDWN_ENABLE(x) (((x) >> 14) & 0x1)
+#define C_028A4C_FORCE_EOV_CNTDWN_ENABLE 0xFFFFBFFF
+#define S_028A4C_FORCE_EOV_TILE_ENABLE(x) (((x) & 0x1) << 15)
+#define G_028A4C_FORCE_EOV_TILE_ENABLE(x) (((x) >> 15) & 0x1)
+#define C_028A4C_FORCE_EOV_TILE_ENABLE 0xFFFF7FFF
+#define S_028A4C_FORCE_EOV_REZ_ENABLE(x) (((x) & 0x1) << 16)
+#define G_028A4C_FORCE_EOV_REZ_ENABLE(x) (((x) >> 16) & 0x1)
+#define C_028A4C_FORCE_EOV_REZ_ENABLE 0xFFFEFFFF
+#define S_028A4C_PS_ITER_SAMPLE(x) (((x) & 0x1) << 17)
+#define G_028A4C_PS_ITER_SAMPLE(x) (((x) >> 17) & 0x1)
+#define C_028A4C_PS_ITER_SAMPLE 0xFFFDFFFF
+#define R_028A84_VGT_PRIMITIVEID_EN 0x028A84
+#define S_028A84_PRIMITIVEID_EN(x) (((x) & 0x1) << 0)
+#define G_028A84_PRIMITIVEID_EN(x) (((x) >> 0) & 0x1)
+#define C_028A84_PRIMITIVEID_EN 0xFFFFFFFE
+#define R_028A94_VGT_MULTI_PRIM_IB_RESET_EN 0x028A94
+#define S_028A94_RESET_EN(x) (((x) & 0x1) << 0)
+#define G_028A94_RESET_EN(x) (((x) >> 0) & 0x1)
+#define C_028A94_RESET_EN 0xFFFFFFFE
+#define R_028AA0_VGT_INSTANCE_STEP_RATE_0 0x028AA0
+#define S_028AA0_STEP_RATE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028AA0_STEP_RATE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028AA0_STEP_RATE 0x00000000
+#define R_028AA4_VGT_INSTANCE_STEP_RATE_1 0x028AA4
+#define S_028AA4_STEP_RATE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028AA4_STEP_RATE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028AA4_STEP_RATE 0x00000000
+#define R_028AB0_VGT_STRMOUT_EN 0x028AB0
+#define S_028AB0_STREAMOUT(x) (((x) & 0x1) << 0)
+#define G_028AB0_STREAMOUT(x) (((x) >> 0) & 0x1)
+#define C_028AB0_STREAMOUT 0xFFFFFFFE
+#define R_028AB4_VGT_REUSE_OFF 0x028AB4
+#define S_028AB4_REUSE_OFF(x) (((x) & 0x1) << 0)
+#define G_028AB4_REUSE_OFF(x) (((x) >> 0) & 0x1)
+#define C_028AB4_REUSE_OFF 0xFFFFFFFE
+#define R_028AB8_VGT_VTX_CNT_EN 0x028AB8
+#define S_028AB8_VTX_CNT_EN(x) (((x) & 0x1) << 0)
+#define G_028AB8_VTX_CNT_EN(x) (((x) >> 0) & 0x1)
+#define C_028AB8_VTX_CNT_EN 0xFFFFFFFE
+#define R_028B20_VGT_STRMOUT_BUFFER_EN 0x028B20
+#define S_028B20_BUFFER_0_EN(x) (((x) & 0x1) << 0)
+#define G_028B20_BUFFER_0_EN(x) (((x) >> 0) & 0x1)
+#define C_028B20_BUFFER_0_EN 0xFFFFFFFE
+#define S_028B20_BUFFER_1_EN(x) (((x) & 0x1) << 1)
+#define G_028B20_BUFFER_1_EN(x) (((x) >> 1) & 0x1)
+#define C_028B20_BUFFER_1_EN 0xFFFFFFFD
+#define S_028B20_BUFFER_2_EN(x) (((x) & 0x1) << 2)
+#define G_028B20_BUFFER_2_EN(x) (((x) >> 2) & 0x1)
+#define C_028B20_BUFFER_2_EN 0xFFFFFFFB
+#define S_028B20_BUFFER_3_EN(x) (((x) & 0x1) << 3)
+#define G_028B20_BUFFER_3_EN(x) (((x) >> 3) & 0x1)
+#define C_028B20_BUFFER_3_EN 0xFFFFFFF7
+#define R_028C20_PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX 0x028C20
+#define S_028C20_S4_X(x) (((x) & 0xF) << 0)
+#define G_028C20_S4_X(x) (((x) >> 0) & 0xF)
+#define C_028C20_S4_X 0xFFFFFFF0
+#define S_028C20_S4_Y(x) (((x) & 0xF) << 4)
+#define G_028C20_S4_Y(x) (((x) >> 4) & 0xF)
+#define C_028C20_S4_Y 0xFFFFFF0F
+#define S_028C20_S5_X(x) (((x) & 0xF) << 8)
+#define G_028C20_S5_X(x) (((x) >> 8) & 0xF)
+#define C_028C20_S5_X 0xFFFFF0FF
+#define S_028C20_S5_Y(x) (((x) & 0xF) << 12)
+#define G_028C20_S5_Y(x) (((x) >> 12) & 0xF)
+#define C_028C20_S5_Y 0xFFFF0FFF
+#define S_028C20_S6_X(x) (((x) & 0xF) << 16)
+#define G_028C20_S6_X(x) (((x) >> 16) & 0xF)
+#define C_028C20_S6_X 0xFFF0FFFF
+#define S_028C20_S6_Y(x) (((x) & 0xF) << 20)
+#define G_028C20_S6_Y(x) (((x) >> 20) & 0xF)
+#define C_028C20_S6_Y 0xFF0FFFFF
+#define S_028C20_S7_X(x) (((x) & 0xF) << 24)
+#define G_028C20_S7_X(x) (((x) >> 24) & 0xF)
+#define C_028C20_S7_X 0xF0FFFFFF
+#define S_028C20_S7_Y(x) (((x) & 0xF) << 28)
+#define G_028C20_S7_Y(x) (((x) >> 28) & 0xF)
+#define C_028C20_S7_Y 0x0FFFFFFF
+#define R_028C30_CB_CLRCMP_CONTROL 0x028C30
+#define S_028C30_CLRCMP_FCN_SRC(x) (((x) & 0x7) << 0)
+#define G_028C30_CLRCMP_FCN_SRC(x) (((x) >> 0) & 0x7)
+#define C_028C30_CLRCMP_FCN_SRC 0xFFFFFFF8
+#define S_028C30_CLRCMP_FCN_DST(x) (((x) & 0x7) << 8)
+#define G_028C30_CLRCMP_FCN_DST(x) (((x) >> 8) & 0x7)
+#define C_028C30_CLRCMP_FCN_DST 0xFFFFF8FF
+#define S_028C30_CLRCMP_FCN_SEL(x) (((x) & 0x3) << 24)
+#define G_028C30_CLRCMP_FCN_SEL(x) (((x) >> 24) & 0x3)
+#define C_028C30_CLRCMP_FCN_SEL 0xFCFFFFFF
+#define R_028C34_CB_CLRCMP_SRC 0x028C34
+#define S_028C34_CLRCMP_SRC(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028C34_CLRCMP_SRC(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028C34_CLRCMP_SRC 0x00000000
+#define R_028C38_CB_CLRCMP_DST 0x028C38
+#define S_028C38_CLRCMP_DST(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028C38_CLRCMP_DST(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028C38_CLRCMP_DST 0x00000000
+#define R_028C3C_CB_CLRCMP_MSK 0x028C3C
+#define S_028C3C_CLRCMP_MSK(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028C3C_CLRCMP_MSK(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028C3C_CLRCMP_MSK 0x00000000
+#define R_0085F0_CP_COHER_CNTL 0x0085F0
+#define S_0085F0_DEST_BASE_0_ENA(x) (((x) & 0x1) << 0)
+#define G_0085F0_DEST_BASE_0_ENA(x) (((x) >> 0) & 0x1)
+#define C_0085F0_DEST_BASE_0_ENA 0xFFFFFFFE
+#define S_0085F0_DEST_BASE_1_ENA(x) (((x) & 0x1) << 1)
+#define G_0085F0_DEST_BASE_1_ENA(x) (((x) >> 1) & 0x1)
+#define C_0085F0_DEST_BASE_1_ENA 0xFFFFFFFD
+#define S_0085F0_SO0_DEST_BASE_ENA(x) (((x) & 0x1) << 2)
+#define G_0085F0_SO0_DEST_BASE_ENA(x) (((x) >> 2) & 0x1)
+#define C_0085F0_SO0_DEST_BASE_ENA 0xFFFFFFFB
+#define S_0085F0_SO1_DEST_BASE_ENA(x) (((x) & 0x1) << 3)
+#define G_0085F0_SO1_DEST_BASE_ENA(x) (((x) >> 3) & 0x1)
+#define C_0085F0_SO1_DEST_BASE_ENA 0xFFFFFFF7
+#define S_0085F0_SO2_DEST_BASE_ENA(x) (((x) & 0x1) << 4)
+#define G_0085F0_SO2_DEST_BASE_ENA(x) (((x) >> 4) & 0x1)
+#define C_0085F0_SO2_DEST_BASE_ENA 0xFFFFFFEF
+#define S_0085F0_SO3_DEST_BASE_ENA(x) (((x) & 0x1) << 5)
+#define G_0085F0_SO3_DEST_BASE_ENA(x) (((x) >> 5) & 0x1)
+#define C_0085F0_SO3_DEST_BASE_ENA 0xFFFFFFDF
+#define S_0085F0_CB0_DEST_BASE_ENA(x) (((x) & 0x1) << 6)
+#define G_0085F0_CB0_DEST_BASE_ENA(x) (((x) >> 6) & 0x1)
+#define C_0085F0_CB0_DEST_BASE_ENA 0xFFFFFFBF
+#define S_0085F0_CB1_DEST_BASE_ENA(x) (((x) & 0x1) << 7)
+#define G_0085F0_CB1_DEST_BASE_ENA(x) (((x) >> 7) & 0x1)
+#define C_0085F0_CB1_DEST_BASE_ENA 0xFFFFFF7F
+#define S_0085F0_CB2_DEST_BASE_ENA(x) (((x) & 0x1) << 8)
+#define G_0085F0_CB2_DEST_BASE_ENA(x) (((x) >> 8) & 0x1)
+#define C_0085F0_CB2_DEST_BASE_ENA 0xFFFFFEFF
+#define S_0085F0_CB3_DEST_BASE_ENA(x) (((x) & 0x1) << 9)
+#define G_0085F0_CB3_DEST_BASE_ENA(x) (((x) >> 9) & 0x1)
+#define C_0085F0_CB3_DEST_BASE_ENA 0xFFFFFDFF
+#define S_0085F0_CB4_DEST_BASE_ENA(x) (((x) & 0x1) << 10)
+#define G_0085F0_CB4_DEST_BASE_ENA(x) (((x) >> 10) & 0x1)
+#define C_0085F0_CB4_DEST_BASE_ENA 0xFFFFFBFF
+#define S_0085F0_CB5_DEST_BASE_ENA(x) (((x) & 0x1) << 11)
+#define G_0085F0_CB5_DEST_BASE_ENA(x) (((x) >> 11) & 0x1)
+#define C_0085F0_CB5_DEST_BASE_ENA 0xFFFFF7FF
+#define S_0085F0_CB6_DEST_BASE_ENA(x) (((x) & 0x1) << 12)
+#define G_0085F0_CB6_DEST_BASE_ENA(x) (((x) >> 12) & 0x1)
+#define C_0085F0_CB6_DEST_BASE_ENA 0xFFFFEFFF
+#define S_0085F0_CB7_DEST_BASE_ENA(x) (((x) & 0x1) << 13)
+#define G_0085F0_CB7_DEST_BASE_ENA(x) (((x) >> 13) & 0x1)
+#define C_0085F0_CB7_DEST_BASE_ENA 0xFFFFDFFF
+#define S_0085F0_DB_DEST_BASE_ENA(x) (((x) & 0x1) << 14)
+#define G_0085F0_DB_DEST_BASE_ENA(x) (((x) >> 14) & 0x1)
+#define C_0085F0_DB_DEST_BASE_ENA 0xFFFFBFFF
+#define S_0085F0_CR_DEST_BASE_ENA(x) (((x) & 0x1) << 15)
+#define G_0085F0_CR_DEST_BASE_ENA(x) (((x) >> 15) & 0x1)
+#define C_0085F0_CR_DEST_BASE_ENA 0xFFFF7FFF
+#define S_0085F0_TC_ACTION_ENA(x) (((x) & 0x1) << 23)
+#define G_0085F0_TC_ACTION_ENA(x) (((x) >> 23) & 0x1)
+#define C_0085F0_TC_ACTION_ENA 0xFF7FFFFF
+#define S_0085F0_VC_ACTION_ENA(x) (((x) & 0x1) << 24)
+#define G_0085F0_VC_ACTION_ENA(x) (((x) >> 24) & 0x1)
+#define C_0085F0_VC_ACTION_ENA 0xFEFFFFFF
+#define S_0085F0_CB_ACTION_ENA(x) (((x) & 0x1) << 25)
+#define G_0085F0_CB_ACTION_ENA(x) (((x) >> 25) & 0x1)
+#define C_0085F0_CB_ACTION_ENA 0xFDFFFFFF
+#define S_0085F0_DB_ACTION_ENA(x) (((x) & 0x1) << 26)
+#define G_0085F0_DB_ACTION_ENA(x) (((x) >> 26) & 0x1)
+#define C_0085F0_DB_ACTION_ENA 0xFBFFFFFF
+#define S_0085F0_SH_ACTION_ENA(x) (((x) & 0x1) << 27)
+#define G_0085F0_SH_ACTION_ENA(x) (((x) >> 27) & 0x1)
+#define C_0085F0_SH_ACTION_ENA 0xF7FFFFFF
+#define S_0085F0_SMX_ACTION_ENA(x) (((x) & 0x1) << 28)
+#define G_0085F0_SMX_ACTION_ENA(x) (((x) >> 28) & 0x1)
+#define C_0085F0_SMX_ACTION_ENA 0xEFFFFFFF
+#define S_0085F0_CR0_ACTION_ENA(x) (((x) & 0x1) << 29)
+#define G_0085F0_CR0_ACTION_ENA(x) (((x) >> 29) & 0x1)
+#define C_0085F0_CR0_ACTION_ENA 0xDFFFFFFF
+#define S_0085F0_CR1_ACTION_ENA(x) (((x) & 0x1) << 30)
+#define G_0085F0_CR1_ACTION_ENA(x) (((x) >> 30) & 0x1)
+#define C_0085F0_CR1_ACTION_ENA 0xBFFFFFFF
+#define S_0085F0_CR2_ACTION_ENA(x) (((x) & 0x1) << 31)
+#define G_0085F0_CR2_ACTION_ENA(x) (((x) >> 31) & 0x1)
+#define C_0085F0_CR2_ACTION_ENA 0x7FFFFFFF
+
+
+#define R_02812C_CB_CLEAR_ALPHA 0x02812C
+#define S_02812C_CLEAR_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02812C_CLEAR_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02812C_CLEAR_ALPHA 0x00000000
+#define R_028128_CB_CLEAR_BLUE 0x028128
+#define S_028128_CLEAR_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028128_CLEAR_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028128_CLEAR_BLUE 0x00000000
+#define R_028124_CB_CLEAR_GREEN 0x028124
+#define S_028124_CLEAR_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028124_CLEAR_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028124_CLEAR_GREEN 0x00000000
+#define R_028120_CB_CLEAR_RED 0x028120
+#define S_028120_CLEAR_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028120_CLEAR_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028120_CLEAR_RED 0x00000000
+#define R_02842C_CB_FOG_BLUE 0x02842C
+#define S_02842C_FOG_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_02842C_FOG_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_02842C_FOG_BLUE 0x00000000
+#define R_028428_CB_FOG_GREEN 0x028428
+#define S_028428_FOG_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028428_FOG_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028428_FOG_GREEN 0x00000000
+#define R_028424_CB_FOG_RED 0x028424
+#define S_028424_FOG_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_028424_FOG_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_028424_FOG_RED 0x00000000
+#define R_03C000_SQ_TEX_SAMPLER_WORD0_0 0x03C000
+#define S_03C000_CLAMP_X(x) (((x) & 0x7) << 0)
+#define G_03C000_CLAMP_X(x) (((x) >> 0) & 0x7)
+#define C_03C000_CLAMP_X 0xFFFFFFF8
+#define S_03C000_CLAMP_Y(x) (((x) & 0x7) << 3)
+#define G_03C000_CLAMP_Y(x) (((x) >> 3) & 0x7)
+#define C_03C000_CLAMP_Y 0xFFFFFFC7
+#define S_03C000_CLAMP_Z(x) (((x) & 0x7) << 6)
+#define G_03C000_CLAMP_Z(x) (((x) >> 6) & 0x7)
+#define C_03C000_CLAMP_Z 0xFFFFFE3F
+#define S_03C000_XY_MAG_FILTER(x) (((x) & 0x7) << 9)
+#define G_03C000_XY_MAG_FILTER(x) (((x) >> 9) & 0x7)
+#define C_03C000_XY_MAG_FILTER 0xFFFFF1FF
+#define S_03C000_XY_MIN_FILTER(x) (((x) & 0x7) << 12)
+#define G_03C000_XY_MIN_FILTER(x) (((x) >> 12) & 0x7)
+#define C_03C000_XY_MIN_FILTER 0xFFFF8FFF
+#define S_03C000_Z_FILTER(x) (((x) & 0x3) << 15)
+#define G_03C000_Z_FILTER(x) (((x) >> 15) & 0x3)
+#define C_03C000_Z_FILTER 0xFFFE7FFF
+#define S_03C000_MIP_FILTER(x) (((x) & 0x3) << 17)
+#define G_03C000_MIP_FILTER(x) (((x) >> 17) & 0x3)
+#define C_03C000_MIP_FILTER 0xFFF9FFFF
+#define S_03C000_BORDER_COLOR_TYPE(x) (((x) & 0x3) << 22)
+#define G_03C000_BORDER_COLOR_TYPE(x) (((x) >> 22) & 0x3)
+#define C_03C000_BORDER_COLOR_TYPE 0xFF3FFFFF
+#define S_03C000_POINT_SAMPLING_CLAMP(x) (((x) & 0x1) << 24)
+#define G_03C000_POINT_SAMPLING_CLAMP(x) (((x) >> 24) & 0x1)
+#define C_03C000_POINT_SAMPLING_CLAMP 0xFEFFFFFF
+#define S_03C000_TEX_ARRAY_OVERRIDE(x) (((x) & 0x1) << 25)
+#define G_03C000_TEX_ARRAY_OVERRIDE(x) (((x) >> 25) & 0x1)
+#define C_03C000_TEX_ARRAY_OVERRIDE 0xFDFFFFFF
+#define S_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) & 0x7) << 26)
+#define G_03C000_DEPTH_COMPARE_FUNCTION(x) (((x) >> 26) & 0x7)
+#define C_03C000_DEPTH_COMPARE_FUNCTION 0xE3FFFFFF
+#define S_03C000_CHROMA_KEY(x) (((x) & 0x3) << 29)
+#define G_03C000_CHROMA_KEY(x) (((x) >> 29) & 0x3)
+#define C_03C000_CHROMA_KEY 0x9FFFFFFF
+#define S_03C000_LOD_USES_MINOR_AXIS(x) (((x) & 0x1) << 31)
+#define G_03C000_LOD_USES_MINOR_AXIS(x) (((x) >> 31) & 0x1)
+#define C_03C000_LOD_USES_MINOR_AXIS 0x7FFFFFFF
+#define R_03C004_SQ_TEX_SAMPLER_WORD1_0 0x03C004
+#define S_03C004_MIN_LOD(x) (((x) & 0x3FF) << 0)
+#define G_03C004_MIN_LOD(x) (((x) >> 0) & 0x3FF)
+#define C_03C004_MIN_LOD 0xFFFFFC00
+#define S_03C004_MAX_LOD(x) (((x) & 0x3FF) << 10)
+#define G_03C004_MAX_LOD(x) (((x) >> 10) & 0x3FF)
+#define C_03C004_MAX_LOD 0xFFF003FF
+#define S_03C004_LOD_BIAS(x) (((x) & 0xFFF) << 20)
+#define G_03C004_LOD_BIAS(x) (((x) >> 20) & 0xFFF)
+#define C_03C004_LOD_BIAS 0x000FFFFF
+#define R_03C008_SQ_TEX_SAMPLER_WORD2_0 0x03C008
+#define S_03C008_LOD_BIAS_SEC(x) (((x) & 0xFFF) << 0)
+#define G_03C008_LOD_BIAS_SEC(x) (((x) >> 0) & 0xFFF)
+#define C_03C008_LOD_BIAS_SEC 0xFFFFF000
+#define S_03C008_MC_COORD_TRUNCATE(x) (((x) & 0x1) << 12)
+#define G_03C008_MC_COORD_TRUNCATE(x) (((x) >> 12) & 0x1)
+#define C_03C008_MC_COORD_TRUNCATE 0xFFFFEFFF
+#define S_03C008_FORCE_DEGAMMA(x) (((x) & 0x1) << 13)
+#define G_03C008_FORCE_DEGAMMA(x) (((x) >> 13) & 0x1)
+#define C_03C008_FORCE_DEGAMMA 0xFFFFDFFF
+#define S_03C008_HIGH_PRECISION_FILTER(x) (((x) & 0x1) << 14)
+#define G_03C008_HIGH_PRECISION_FILTER(x) (((x) >> 14) & 0x1)
+#define C_03C008_HIGH_PRECISION_FILTER 0xFFFFBFFF
+#define S_03C008_PERF_MIP(x) (((x) & 0x7) << 15)
+#define G_03C008_PERF_MIP(x) (((x) >> 15) & 0x7)
+#define C_03C008_PERF_MIP 0xFFFC7FFF
+#define S_03C008_PERF_Z(x) (((x) & 0x3) << 18)
+#define G_03C008_PERF_Z(x) (((x) >> 18) & 0x3)
+#define C_03C008_PERF_Z 0xFFF3FFFF
+#define S_03C008_FETCH_4(x) (((x) & 0x1) << 26)
+#define G_03C008_FETCH_4(x) (((x) >> 26) & 0x1)
+#define C_03C008_FETCH_4 0xFBFFFFFF
+#define S_03C008_SAMPLE_IS_PCF(x) (((x) & 0x1) << 27)
+#define G_03C008_SAMPLE_IS_PCF(x) (((x) >> 27) & 0x1)
+#define C_03C008_SAMPLE_IS_PCF 0xF7FFFFFF
+#define S_03C008_TYPE(x) (((x) & 0x1) << 31)
+#define G_03C008_TYPE(x) (((x) >> 31) & 0x1)
+#define C_03C008_TYPE 0x7FFFFFFF
+#define R_00A40C_TD_PS_SAMPLER0_BORDER_ALPHA 0x00A40C
+#define S_00A40C_BORDER_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A40C_BORDER_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A40C_BORDER_ALPHA 0x00000000
+#define R_00A408_TD_PS_SAMPLER0_BORDER_BLUE 0x00A408
+#define S_00A408_BORDER_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A408_BORDER_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A408_BORDER_BLUE 0x00000000
+#define R_00A404_TD_PS_SAMPLER0_BORDER_GREEN 0x00A404
+#define S_00A404_BORDER_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A404_BORDER_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A404_BORDER_GREEN 0x00000000
+#define R_00A400_TD_PS_SAMPLER0_BORDER_RED 0x00A400
+#define S_00A400_BORDER_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A400_BORDER_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A400_BORDER_RED 0x00000000
+#define R_00A60C_TD_VS_SAMPLER0_BORDER_ALPHA 0x00A60C
+#define S_00A60C_BORDER_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A60C_BORDER_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A60C_BORDER_ALPHA 0x00000000
+#define R_00A608_TD_VS_SAMPLER0_BORDER_BLUE 0x00A608
+#define S_00A608_BORDER_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A608_BORDER_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A608_BORDER_BLUE 0x00000000
+#define R_00A604_TD_VS_SAMPLER0_BORDER_GREEN 0x00A604
+#define S_00A604_BORDER_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A604_BORDER_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A604_BORDER_GREEN 0x00000000
+#define R_00A600_TD_VS_SAMPLER0_BORDER_RED 0x00A600
+#define S_00A600_BORDER_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A600_BORDER_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A600_BORDER_RED 0x00000000
+#define R_00A80C_TD_GS_SAMPLER0_BORDER_ALPHA 0x00A80C
+#define S_00A80C_BORDER_ALPHA(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A80C_BORDER_ALPHA(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A80C_BORDER_ALPHA 0x00000000
+#define R_00A808_TD_GS_SAMPLER0_BORDER_BLUE 0x00A808
+#define S_00A808_BORDER_BLUE(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A808_BORDER_BLUE(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A808_BORDER_BLUE 0x00000000
+#define R_00A804_TD_GS_SAMPLER0_BORDER_GREEN 0x00A804
+#define S_00A804_BORDER_GREEN(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A804_BORDER_GREEN(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A804_BORDER_GREEN 0x00000000
+#define R_00A800_TD_GS_SAMPLER0_BORDER_RED 0x00A800
+#define S_00A800_BORDER_RED(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_00A800_BORDER_RED(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_00A800_BORDER_RED 0x00000000
+#define R_030000_SQ_ALU_CONSTANT0_0 0x030000
+#define S_030000_X(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_030000_X(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_030000_X 0x00000000
+#define R_030004_SQ_ALU_CONSTANT1_0 0x030004
+#define S_030004_Y(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_030004_Y(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_030004_Y 0x00000000
+#define R_030008_SQ_ALU_CONSTANT2_0 0x030008
+#define S_030008_Z(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_030008_Z(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_030008_Z 0x00000000
+#define R_03000C_SQ_ALU_CONSTANT3_0 0x03000C
+#define S_03000C_W(x) (((x) & 0xFFFFFFFF) << 0)
+#define G_03000C_W(x) (((x) >> 0) & 0xFFFFFFFF)
+#define C_03000C_W 0x00000000
+#define R_0287E4_VGT_DMA_BASE_HI 0x0287E4
+#define R_0287E8_VGT_DMA_BASE 0x0287E8
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/radeon.c b/src/gallium/winsys/r600/drm/radeon.c
new file mode 100644
index 0000000000..f2113c5807
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "xf86drm.h"
+#include "radeon_priv.h"
+#include "radeon_drm.h"
+#include "r600d.h"
+
+static int radeon_get_device(struct radeon *radeon)
+{
+ struct drm_radeon_info info;
+ int r;
+
+ radeon->device = 0;
+ info.request = RADEON_INFO_DEVICE_ID;
+ info.value = (uintptr_t)&radeon->device;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+ sizeof(struct drm_radeon_info));
+ return r;
+}
+
+/* symbol missing drove me crazy hack to get symbol exported */
+static void fake(void)
+{
+ struct radeon_ctx *ctx;
+ struct radeon_draw *draw;
+
+ ctx = radeon_ctx(NULL);
+ draw = radeon_draw(NULL);
+}
+
+struct radeon *radeon_new(int fd, unsigned device)
+{
+ struct radeon *radeon;
+ int r;
+
+ radeon = calloc(1, sizeof(*radeon));
+ if (radeon == NULL) {
+ fake();
+ return NULL;
+ }
+ radeon->fd = fd;
+ radeon->device = device;
+ radeon->refcount = 1;
+ if (fd >= 0) {
+ r = radeon_get_device(radeon);
+ if (r) {
+ fprintf(stderr, "Failed to get device id\n");
+ return radeon_decref(radeon);
+ }
+ }
+ radeon->family = radeon_family_from_device(radeon->device);
+ if (radeon->family == CHIP_UNKNOWN) {
+ fprintf(stderr, "Unknown chipset 0x%04X\n", radeon->device);
+ return radeon_decref(radeon);
+ }
+ switch (radeon->family) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ if (r600_init(radeon)) {
+ return radeon_decref(radeon);
+ }
+ break;
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_RV350:
+ case CHIP_RV380:
+ case CHIP_R420:
+ case CHIP_R423:
+ case CHIP_RV410:
+ case CHIP_RS400:
+ case CHIP_RS480:
+ case CHIP_RS600:
+ case CHIP_RS690:
+ case CHIP_RS740:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ case CHIP_CEDAR:
+ case CHIP_REDWOOD:
+ case CHIP_JUNIPER:
+ case CHIP_CYPRESS:
+ case CHIP_HEMLOCK:
+ default:
+ fprintf(stderr, "%s unknown or unsupported chipset 0x%04X\n",
+ __func__, radeon->device);
+ break;
+ }
+ return radeon;
+}
+
+struct radeon *radeon_incref(struct radeon *radeon)
+{
+ if (radeon == NULL)
+ return NULL;
+ radeon->refcount++;
+ return radeon;
+}
+
+struct radeon *radeon_decref(struct radeon *radeon)
+{
+ if (radeon == NULL)
+ return NULL;
+ if (--radeon->refcount > 0) {
+ return NULL;
+ }
+ drmClose(radeon->fd);
+ free(radeon);
+ return NULL;
+}
+
+int radeon_reg_id(struct radeon *radeon, unsigned offset, unsigned *typeid, unsigned *stateid, unsigned *id)
+{
+ unsigned i, j;
+
+ for (i = 0; i < radeon->ntype; i++) {
+ if (radeon->type[i].range_start) {
+ if (offset >= radeon->type[i].range_start && offset < radeon->type[i].range_end) {
+ *typeid = i;
+ j = offset - radeon->type[i].range_start;
+ j /= radeon->type[i].stride;
+ *stateid = radeon->type[i].id + j;
+ *id = (offset - radeon->type[i].range_start - radeon->type[i].stride * j) / 4;
+ return 0;
+ }
+ } else {
+ for (j = 0; j < radeon->type[i].nstates; j++) {
+ if (radeon->type[i].regs[j].offset == offset) {
+ *typeid = i;
+ *stateid = radeon->type[i].id;
+ *id = j;
+ return 0;
+ }
+ }
+ }
+ }
+ fprintf(stderr, "%s unknown register 0x%08X\n", __func__, offset);
+ return -EINVAL;
+}
+
+unsigned radeon_type_from_id(struct radeon *radeon, unsigned id)
+{
+ unsigned i;
+
+ for (i = 0; i < radeon->ntype - 1; i++) {
+ if (radeon->type[i].id == id)
+ return i;
+ if (id > radeon->type[i].id && id < radeon->type[i + 1].id)
+ return i;
+ }
+ if (radeon->type[i].id == id)
+ return i;
+ return -1;
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c
new file mode 100644
index 0000000000..f259ae7fb5
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_bo.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#define _FILE_OFFSET_BITS 64
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include "radeon_priv.h"
+#include "xf86drm.h"
+#include "radeon_drm.h"
+
+struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle,
+ unsigned size, unsigned alignment, void *ptr)
+{
+ struct radeon_bo *bo;
+ int r;
+
+ bo = calloc(1, sizeof(*bo));
+ if (bo == NULL) {
+ return NULL;
+ }
+ bo->size = size;
+ bo->handle = handle;
+ bo->refcount = 1;
+ bo->alignment = alignment;
+
+ if (handle) {
+ struct drm_gem_open open_arg;
+
+ memset(&open_arg, 0, sizeof(open_arg));
+ open_arg.name = handle;
+ r = drmIoctl(radeon->fd, DRM_IOCTL_GEM_OPEN, &open_arg);
+ if (r != 0) {
+ free(bo);
+ return NULL;
+ }
+ bo->handle = open_arg.handle;
+ bo->size = open_arg.size;
+ } else {
+ struct drm_radeon_gem_create args;
+
+ args.size = size;
+ args.alignment = alignment;
+ args.initial_domain = RADEON_GEM_DOMAIN_CPU;
+ args.flags = 0;
+ args.handle = 0;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_CREATE,
+ &args, sizeof(args));
+ bo->handle = args.handle;
+ if (r) {
+ fprintf(stderr, "Failed to allocate :\n");
+ fprintf(stderr, " size : %d bytes\n", size);
+ fprintf(stderr, " alignment : %d bytes\n", alignment);
+ free(bo);
+ return NULL;
+ }
+ }
+ if (ptr) {
+ if (radeon_bo_map(radeon, bo)) {
+ fprintf(stderr, "%s failed to copy data into bo\n", __func__);
+ return radeon_bo_decref(radeon, bo);
+ }
+ memcpy(bo->data, ptr, size);
+ radeon_bo_unmap(radeon, bo);
+ }
+ return bo;
+}
+
+int radeon_bo_map(struct radeon *radeon, struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_mmap args;
+ void *ptr;
+ int r;
+
+ if (bo->map_count++ != 0) {
+ return 0;
+ }
+ /* Zero out args to make valgrind happy */
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+ args.offset = 0;
+ args.size = (uint64_t)bo->size;
+ r = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_MMAP,
+ &args, sizeof(args));
+ if (r) {
+ fprintf(stderr, "error mapping %p 0x%08X (error = %d)\n",
+ bo, bo->handle, r);
+ return r;
+ }
+ ptr = mmap(0, args.size, PROT_READ|PROT_WRITE, MAP_SHARED, radeon->fd, args.addr_ptr);
+ if (ptr == MAP_FAILED) {
+ fprintf(stderr, "%s failed to map bo\n", __func__);
+ return -errno;
+ }
+ bo->data = ptr;
+ return 0;
+}
+
+void radeon_bo_unmap(struct radeon *radeon, struct radeon_bo *bo)
+{
+ if (--bo->map_count > 0) {
+ return;
+ }
+ munmap(bo->data, bo->size);
+ bo->data = NULL;
+}
+
+struct radeon_bo *radeon_bo_incref(struct radeon *radeon, struct radeon_bo *bo)
+{
+ bo->refcount++;
+ return bo;
+}
+
+struct radeon_bo *radeon_bo_decref(struct radeon *radeon, struct radeon_bo *bo)
+{
+ struct drm_gem_close args;
+
+ if (bo == NULL)
+ return NULL;
+ if (--bo->refcount > 0) {
+ return NULL;
+ }
+
+ munmap(bo->data, bo->size);
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+ drmIoctl(radeon->fd, DRM_IOCTL_GEM_CLOSE, &args);
+ memset(bo, 0, sizeof(struct radeon_bo));
+ free(bo);
+ return NULL;
+}
+
+int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo)
+{
+ struct drm_radeon_gem_wait_idle args;
+ int ret;
+
+ /* Zero out args to make valgrind happy */
+ memset(&args, 0, sizeof(args));
+ args.handle = bo->handle;
+ do {
+ ret = drmCommandWriteRead(radeon->fd, DRM_RADEON_GEM_WAIT_IDLE,
+ &args, sizeof(args));
+ } while (ret == -EBUSY);
+ return ret;
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_ctx.c b/src/gallium/winsys/r600/drm/radeon_ctx.c
new file mode 100644
index 0000000000..6b0eba0b28
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_ctx.c
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "radeon_priv.h"
+#include "radeon_drm.h"
+#include "bof.h"
+
+int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo)
+{
+ void *ptr;
+
+ ptr = realloc(ctx->bo, sizeof(struct radeon_bo) * (ctx->nbo + 1));
+ if (ptr == NULL) {
+ return -ENOMEM;
+ }
+ ctx->bo = ptr;
+ ctx->bo[ctx->nbo] = bo;
+ ctx->nbo++;
+ return 0;
+}
+
+struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc)
+{
+ struct radeon_cs_reloc *greloc;
+ unsigned i;
+
+ greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4);
+ for (i = 0; i < ctx->nbo; i++) {
+ if (ctx->bo[i]->handle == greloc->handle) {
+ return radeon_bo_incref(ctx->radeon, ctx->bo[i]);
+ }
+ }
+ fprintf(stderr, "%s no bo for reloc[%d 0x%08X] %d\n", __func__, reloc, greloc->handle, ctx->nbo);
+ return NULL;
+}
+
+void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement)
+{
+ struct radeon_cs_reloc *greloc;
+ unsigned i;
+
+ placement[0] = 0;
+ placement[1] = 0;
+ greloc = (void *)(((u8 *)ctx->reloc) + reloc * 4);
+ for (i = 0; i < ctx->nbo; i++) {
+ if (ctx->bo[i]->handle == greloc->handle) {
+ placement[0] = greloc->read_domain | greloc->write_domain;
+ placement[1] = placement[0];
+ return;
+ }
+ }
+}
+
+struct radeon_ctx *radeon_ctx(struct radeon *radeon)
+{
+ struct radeon_ctx *ctx;
+
+ if (radeon == NULL)
+ return NULL;
+ ctx = calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ return NULL;
+ ctx->radeon = radeon_incref(radeon);
+ return ctx;
+}
+
+struct radeon_ctx *radeon_ctx_incref(struct radeon_ctx *ctx)
+{
+ ctx->refcount++;
+ return ctx;
+}
+
+struct radeon_ctx *radeon_ctx_decref(struct radeon_ctx *ctx)
+{
+ unsigned i;
+
+ if (ctx == NULL)
+ return NULL;
+ if (--ctx->refcount > 0) {
+ return NULL;
+ }
+
+ for (i = 0; i < ctx->ndraw; i++) {
+ ctx->draw[i] = radeon_draw_decref(ctx->draw[i]);
+ }
+ for (i = 0; i < ctx->nbo; i++) {
+ ctx->bo[i] = radeon_bo_decref(ctx->radeon, ctx->bo[i]);
+ }
+ ctx->radeon = radeon_decref(ctx->radeon);
+ free(ctx->draw);
+ free(ctx->bo);
+ free(ctx->pm4);
+ free(ctx->reloc);
+ memset(ctx, 0, sizeof(*ctx));
+ free(ctx);
+ return NULL;
+}
+
+static int radeon_ctx_state_bo(struct radeon_ctx *ctx, struct radeon_state *state)
+{
+ unsigned i, j;
+ int r;
+
+ if (state == NULL)
+ return 0;
+ for (i = 0; i < state->nbo; i++) {
+ for (j = 0; j < ctx->nbo; j++) {
+ if (state->bo[i] == ctx->bo[j])
+ break;
+ }
+ if (j == ctx->nbo) {
+ radeon_bo_incref(ctx->radeon, state->bo[i]);
+ r = radeon_ctx_set_bo_new(ctx, state->bo[i]);
+ if (r)
+ return r;
+ }
+ }
+ return 0;
+}
+
+
+int radeon_ctx_submit(struct radeon_ctx *ctx)
+{
+ struct drm_radeon_cs drmib;
+ struct drm_radeon_cs_chunk chunks[2];
+ uint64_t chunk_array[2];
+ int r = 0;
+
+#if 0
+ for (r = 0; r < ctx->cpm4; r++) {
+ fprintf(stderr, "0x%08X\n", ctx->pm4[r]);
+ }
+#endif
+ drmib.num_chunks = 2;
+ drmib.chunks = (uint64_t)(uintptr_t)chunk_array;
+ chunks[0].chunk_id = RADEON_CHUNK_ID_IB;
+ chunks[0].length_dw = ctx->cpm4;
+ chunks[0].chunk_data = (uint64_t)(uintptr_t)ctx->pm4;
+ chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
+ chunks[1].length_dw = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;
+ chunks[1].chunk_data = (uint64_t)(uintptr_t)ctx->reloc;
+ chunk_array[0] = (uint64_t)(uintptr_t)&chunks[0];
+ chunk_array[1] = (uint64_t)(uintptr_t)&chunks[1];
+#if 1
+ r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib,
+ sizeof(struct drm_radeon_cs));
+#endif
+ return r;
+}
+
+static int radeon_ctx_reloc(struct radeon_ctx *ctx, struct radeon_bo *bo,
+ unsigned id, unsigned *placement)
+{
+ unsigned i;
+ struct radeon_cs_reloc *ptr;
+
+ for (i = 0; i < ctx->nreloc; i++) {
+ if (ctx->reloc[i].handle == bo->handle) {
+ ctx->pm4[id] = i * sizeof(struct radeon_cs_reloc) / 4;
+ return 0;
+ }
+ }
+ ptr = realloc(ctx->reloc, sizeof(struct radeon_cs_reloc) * (ctx->nreloc + 1));
+ if (ptr == NULL)
+ return -ENOMEM;
+ ctx->reloc = ptr;
+ ptr[ctx->nreloc].handle = bo->handle;
+ ptr[ctx->nreloc].read_domain = placement[0] | placement [1];
+ ptr[ctx->nreloc].write_domain = placement[0] | placement [1];
+ ptr[ctx->nreloc].flags = 0;
+ ctx->pm4[id] = ctx->nreloc * sizeof(struct radeon_cs_reloc) / 4;
+ ctx->nreloc++;
+ return 0;
+}
+
+static int radeon_ctx_state_schedule(struct radeon_ctx *ctx, struct radeon_state *state)
+{
+ unsigned i, rid, bid, cid;
+ int r;
+
+ if (state == NULL)
+ return 0;
+ memcpy(&ctx->pm4[ctx->id], state->pm4, state->cpm4 * 4);
+ for (i = 0; i < state->nreloc; i++) {
+ rid = state->reloc_pm4_id[i];
+ bid = state->reloc_bo_id[i];
+ cid = ctx->id + rid;
+ r = radeon_ctx_reloc(ctx, state->bo[bid], cid,
+ &state->placement[bid * 2]);
+ if (r) {
+ fprintf(stderr, "%s state %d failed to reloc\n", __func__, state->type);
+ return r;
+ }
+ }
+ ctx->id += state->cpm4;
+ return 0;
+}
+
+int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw)
+{
+ struct radeon_draw *pdraw = NULL;
+ struct radeon_draw **ndraw;
+ struct radeon_state *nstate, *ostate;
+ unsigned cpm4, i, cstate;
+ void *tmp;
+ int r = 0;
+
+ ndraw = realloc(ctx->draw, sizeof(void*) * (ctx->ndraw + 1));
+ if (ndraw == NULL)
+ return -ENOMEM;
+ ctx->draw = ndraw;
+ for (i = 0; i < draw->nstate; i++) {
+ r = radeon_ctx_state_bo(ctx, draw->state[i]);
+ if (r)
+ return r;
+ }
+ r = radeon_draw_check(draw);
+ if (r)
+ return r;
+ if (draw->cpm4 >= RADEON_CTX_MAX_PM4) {
+ fprintf(stderr, "%s single draw too big %d, max %d\n",
+ __func__, draw->cpm4, RADEON_CTX_MAX_PM4);
+ return -EINVAL;
+ }
+ tmp = realloc(ctx->state, (ctx->nstate + draw->nstate) * sizeof(void*));
+ if (tmp == NULL)
+ return -ENOMEM;
+ ctx->state = tmp;
+ pdraw = ctx->cdraw;
+ for (i = 0, cpm4 = 0, cstate = ctx->nstate; i < draw->nstate - 1; i++) {
+ nstate = draw->state[i];
+ if (nstate) {
+ if (pdraw && pdraw->state[i]) {
+ ostate = pdraw->state[i];
+ if (ostate->pm4_crc != nstate->pm4_crc) {
+ ctx->state[cstate++] = nstate;
+ cpm4 += nstate->cpm4;
+ }
+ } else {
+ ctx->state[cstate++] = nstate;
+ cpm4 += nstate->cpm4;
+ }
+ }
+ }
+ /* The last state is the draw state always add it */
+ if (draw->state[i] == NULL) {
+ fprintf(stderr, "%s no draw command\n", __func__);
+ return -EINVAL;
+ }
+ ctx->state[cstate++] = draw->state[i];
+ cpm4 += draw->state[i]->cpm4;
+ if ((ctx->draw_cpm4 + cpm4) > RADEON_CTX_MAX_PM4) {
+ /* need to flush */
+ return -EBUSY;
+ }
+ ctx->draw_cpm4 += cpm4;
+ ctx->nstate = cstate;
+ ctx->draw[ctx->ndraw++] = draw;
+ ctx->cdraw = draw;
+ return 0;
+}
+
+int radeon_ctx_set_draw(struct radeon_ctx *ctx, struct radeon_draw *draw)
+{
+ int r;
+
+ radeon_draw_incref(draw);
+ r = radeon_ctx_set_draw_new(ctx, draw);
+ if (r)
+ radeon_draw_decref(draw);
+ return r;
+}
+
+int radeon_ctx_pm4(struct radeon_ctx *ctx)
+{
+ unsigned i;
+ int r;
+
+ free(ctx->pm4);
+ ctx->cpm4 = 0;
+ ctx->pm4 = malloc(ctx->draw_cpm4 * 4);
+ if (ctx->pm4 == NULL)
+ return -EINVAL;
+ for (i = 0, ctx->id = 0; i < ctx->nstate; i++) {
+ r = radeon_ctx_state_schedule(ctx, ctx->state[i]);
+ if (r)
+ return r;
+ }
+ if (ctx->id != ctx->draw_cpm4) {
+ fprintf(stderr, "%s miss predicted pm4 size %d for %d\n",
+ __func__, ctx->draw_cpm4, ctx->id);
+ return -EINVAL;
+ }
+ ctx->cpm4 = ctx->draw_cpm4;
+ return 0;
+}
+
+void radeon_ctx_dump_bof(struct radeon_ctx *ctx, const char *file)
+{
+ bof_t *bcs, *blob, *array, *bo, *size, *handle, *device_id, *root;
+ unsigned i;
+
+ root = device_id = bcs = blob = array = bo = size = handle = NULL;
+ root = bof_object();
+ if (root == NULL)
+ goto out_err;
+ device_id = bof_int32(ctx->radeon->device);
+ if (device_id == NULL)
+ return;
+ if (bof_object_set(root, "device_id", device_id))
+ goto out_err;
+ bof_decref(device_id);
+ device_id = NULL;
+ /* dump relocs */
+printf("%d relocs\n", ctx->nreloc);
+ blob = bof_blob(ctx->nreloc * 16, ctx->reloc);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "reloc", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump cs */
+printf("%d pm4\n", ctx->cpm4);
+ blob = bof_blob(ctx->cpm4 * 4, ctx->pm4);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(root, "pm4", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ /* dump bo */
+ array = bof_array();
+ if (array == NULL)
+ goto out_err;
+ for (i = 0; i < ctx->nbo; i++) {
+ bo = bof_object();
+ if (bo == NULL)
+ goto out_err;
+ size = bof_int32(ctx->bo[i]->size);
+printf("[%d] %d bo\n", i, size);
+ if (size == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "size", size))
+ goto out_err;
+ bof_decref(size);
+ size = NULL;
+ handle = bof_int32(ctx->bo[i]->handle);
+ if (handle == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "handle", handle))
+ goto out_err;
+ bof_decref(handle);
+ handle = NULL;
+ radeon_bo_map(ctx->radeon, ctx->bo[i]);
+ blob = bof_blob(ctx->bo[i]->size, ctx->bo[i]->data);
+ radeon_bo_unmap(ctx->radeon, ctx->bo[i]);
+ if (blob == NULL)
+ goto out_err;
+ if (bof_object_set(bo, "data", blob))
+ goto out_err;
+ bof_decref(blob);
+ blob = NULL;
+ if (bof_array_append(array, bo))
+ goto out_err;
+ bof_decref(bo);
+ bo = NULL;
+ }
+ if (bof_object_set(root, "bo", array))
+ goto out_err;
+ bof_dump_file(root, file);
+printf("done dump\n");
+out_err:
+ bof_decref(blob);
+ bof_decref(array);
+ bof_decref(bo);
+ bof_decref(size);
+ bof_decref(handle);
+ bof_decref(device_id);
+ bof_decref(root);
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_draw.c b/src/gallium/winsys/r600/drm/radeon_draw.c
new file mode 100644
index 0000000000..4413ed79fb
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_draw.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon_priv.h"
+
+/*
+ * draw functions
+ */
+struct radeon_draw *radeon_draw(struct radeon *radeon)
+{
+ struct radeon_draw *draw;
+
+ draw = calloc(1, sizeof(*draw));
+ if (draw == NULL)
+ return NULL;
+ draw->nstate = radeon->nstate;
+ draw->radeon = radeon;
+ draw->refcount = 1;
+ draw->state = calloc(1, sizeof(void*) * draw->nstate);
+ if (draw->state == NULL) {
+ free(draw);
+ return NULL;
+ }
+ return draw;
+}
+
+struct radeon_draw *radeon_draw_incref(struct radeon_draw *draw)
+{
+ draw->refcount++;
+ return draw;
+}
+
+struct radeon_draw *radeon_draw_decref(struct radeon_draw *draw)
+{
+ unsigned i;
+
+ if (draw == NULL)
+ return NULL;
+ if (--draw->refcount > 0)
+ return NULL;
+ for (i = 0; i < draw->nstate; i++) {
+ draw->state[i] = radeon_state_decref(draw->state[i]);
+ }
+ free(draw->state);
+ memset(draw, 0, sizeof(*draw));
+ free(draw);
+ return NULL;
+}
+
+int radeon_draw_set_new(struct radeon_draw *draw, struct radeon_state *state)
+{
+ if (state == NULL)
+ return 0;
+ if (state->type >= draw->radeon->ntype)
+ return -EINVAL;
+ draw->state[state->id] = radeon_state_decref(draw->state[state->id]);
+ draw->state[state->id] = state;
+ return 0;
+}
+
+int radeon_draw_set(struct radeon_draw *draw, struct radeon_state *state)
+{
+ if (state == NULL)
+ return 0;
+ radeon_state_incref(state);
+ return radeon_draw_set_new(draw, state);
+}
+
+int radeon_draw_check(struct radeon_draw *draw)
+{
+ unsigned i;
+ int r;
+
+ r = radeon_draw_pm4(draw);
+ if (r)
+ return r;
+ for (i = 0, draw->cpm4 = 0; i < draw->nstate; i++) {
+ if (draw->state[i]) {
+ draw->cpm4 += draw->state[i]->cpm4;
+ }
+ }
+ return 0;
+}
+
+struct radeon_draw *radeon_draw_duplicate(struct radeon_draw *draw)
+{
+ struct radeon_draw *ndraw;
+ unsigned i;
+
+ if (draw == NULL)
+ return NULL;
+ ndraw = radeon_draw(draw->radeon);
+ if (ndraw == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < draw->nstate; i++) {
+ if (radeon_draw_set(ndraw, draw->state[i])) {
+ radeon_draw_decref(ndraw);
+ return NULL;
+ }
+ }
+ return ndraw;
+}
+
+int radeon_draw_pm4(struct radeon_draw *draw)
+{
+ unsigned i;
+ int r;
+
+ for (i = 0; i < draw->nstate; i++) {
+ r = radeon_state_pm4(draw->state[i]);
+ if (r)
+ return r;
+ }
+ return 0;
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_pciid.c b/src/gallium/winsys/r600/drm/radeon_pciid.c
new file mode 100644
index 0000000000..dd6156d585
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_pciid.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdlib.h>
+#include "radeon_priv.h"
+
+struct pci_id {
+ unsigned vendor;
+ unsigned device;
+ unsigned family;
+};
+
+struct pci_id radeon_pci_id[] = {
+ {0x1002, 0x3150, CHIP_RV380},
+ {0x1002, 0x3152, CHIP_RV380},
+ {0x1002, 0x3154, CHIP_RV380},
+ {0x1002, 0x3E50, CHIP_RV380},
+ {0x1002, 0x3E54, CHIP_RV380},
+ {0x1002, 0x4136, CHIP_RS100},
+ {0x1002, 0x4137, CHIP_RS200},
+ {0x1002, 0x4144, CHIP_R300},
+ {0x1002, 0x4145, CHIP_R300},
+ {0x1002, 0x4146, CHIP_R300},
+ {0x1002, 0x4147, CHIP_R300},
+ {0x1002, 0x4148, CHIP_R350},
+ {0x1002, 0x4149, CHIP_R350},
+ {0x1002, 0x414A, CHIP_R350},
+ {0x1002, 0x414B, CHIP_R350},
+ {0x1002, 0x4150, CHIP_RV350},
+ {0x1002, 0x4151, CHIP_RV350},
+ {0x1002, 0x4152, CHIP_RV350},
+ {0x1002, 0x4153, CHIP_RV350},
+ {0x1002, 0x4154, CHIP_RV350},
+ {0x1002, 0x4155, CHIP_RV350},
+ {0x1002, 0x4156, CHIP_RV350},
+ {0x1002, 0x4237, CHIP_RS200},
+ {0x1002, 0x4242, CHIP_R200},
+ {0x1002, 0x4243, CHIP_R200},
+ {0x1002, 0x4336, CHIP_RS100},
+ {0x1002, 0x4337, CHIP_RS200},
+ {0x1002, 0x4437, CHIP_RS200},
+ {0x1002, 0x4966, CHIP_RV250},
+ {0x1002, 0x4967, CHIP_RV250},
+ {0x1002, 0x4A48, CHIP_R420},
+ {0x1002, 0x4A49, CHIP_R420},
+ {0x1002, 0x4A4A, CHIP_R420},
+ {0x1002, 0x4A4B, CHIP_R420},
+ {0x1002, 0x4A4C, CHIP_R420},
+ {0x1002, 0x4A4D, CHIP_R420},
+ {0x1002, 0x4A4E, CHIP_R420},
+ {0x1002, 0x4A4F, CHIP_R420},
+ {0x1002, 0x4A50, CHIP_R420},
+ {0x1002, 0x4A54, CHIP_R420},
+ {0x1002, 0x4B48, CHIP_R420},
+ {0x1002, 0x4B49, CHIP_R420},
+ {0x1002, 0x4B4A, CHIP_R420},
+ {0x1002, 0x4B4B, CHIP_R420},
+ {0x1002, 0x4B4C, CHIP_R420},
+ {0x1002, 0x4C57, CHIP_RV200},
+ {0x1002, 0x4C58, CHIP_RV200},
+ {0x1002, 0x4C59, CHIP_RV100},
+ {0x1002, 0x4C5A, CHIP_RV100},
+ {0x1002, 0x4C64, CHIP_RV250},
+ {0x1002, 0x4C66, CHIP_RV250},
+ {0x1002, 0x4C67, CHIP_RV250},
+ {0x1002, 0x4E44, CHIP_R300},
+ {0x1002, 0x4E45, CHIP_R300},
+ {0x1002, 0x4E46, CHIP_R300},
+ {0x1002, 0x4E47, CHIP_R300},
+ {0x1002, 0x4E48, CHIP_R350},
+ {0x1002, 0x4E49, CHIP_R350},
+ {0x1002, 0x4E4A, CHIP_R350},
+ {0x1002, 0x4E4B, CHIP_R350},
+ {0x1002, 0x4E50, CHIP_RV350},
+ {0x1002, 0x4E51, CHIP_RV350},
+ {0x1002, 0x4E52, CHIP_RV350},
+ {0x1002, 0x4E53, CHIP_RV350},
+ {0x1002, 0x4E54, CHIP_RV350},
+ {0x1002, 0x4E56, CHIP_RV350},
+ {0x1002, 0x5144, CHIP_R100},
+ {0x1002, 0x5145, CHIP_R100},
+ {0x1002, 0x5146, CHIP_R100},
+ {0x1002, 0x5147, CHIP_R100},
+ {0x1002, 0x5148, CHIP_R200},
+ {0x1002, 0x514C, CHIP_R200},
+ {0x1002, 0x514D, CHIP_R200},
+ {0x1002, 0x5157, CHIP_RV200},
+ {0x1002, 0x5158, CHIP_RV200},
+ {0x1002, 0x5159, CHIP_RV100},
+ {0x1002, 0x515A, CHIP_RV100},
+ {0x1002, 0x515E, CHIP_RV100},
+ {0x1002, 0x5460, CHIP_RV380},
+ {0x1002, 0x5462, CHIP_RV380},
+ {0x1002, 0x5464, CHIP_RV380},
+ {0x1002, 0x5657, CHIP_RV380},
+ {0x1002, 0x5548, CHIP_R423},
+ {0x1002, 0x5549, CHIP_R423},
+ {0x1002, 0x554A, CHIP_R423},
+ {0x1002, 0x554B, CHIP_R423},
+ {0x1002, 0x554C, CHIP_R423},
+ {0x1002, 0x554D, CHIP_R423},
+ {0x1002, 0x554E, CHIP_R423},
+ {0x1002, 0x554F, CHIP_R423},
+ {0x1002, 0x5550, CHIP_R423},
+ {0x1002, 0x5551, CHIP_R423},
+ {0x1002, 0x5552, CHIP_R423},
+ {0x1002, 0x5554, CHIP_R423},
+ {0x1002, 0x564A, CHIP_RV410},
+ {0x1002, 0x564B, CHIP_RV410},
+ {0x1002, 0x564F, CHIP_RV410},
+ {0x1002, 0x5652, CHIP_RV410},
+ {0x1002, 0x5653, CHIP_RV410},
+ {0x1002, 0x5834, CHIP_RS300},
+ {0x1002, 0x5835, CHIP_RS300},
+ {0x1002, 0x5954, CHIP_RS480},
+ {0x1002, 0x5955, CHIP_RS480},
+ {0x1002, 0x5974, CHIP_RS480},
+ {0x1002, 0x5975, CHIP_RS480},
+ {0x1002, 0x5960, CHIP_RV280},
+ {0x1002, 0x5961, CHIP_RV280},
+ {0x1002, 0x5962, CHIP_RV280},
+ {0x1002, 0x5964, CHIP_RV280},
+ {0x1002, 0x5965, CHIP_RV280},
+ {0x1002, 0x5969, CHIP_RV100},
+ {0x1002, 0x5a41, CHIP_RS400},
+ {0x1002, 0x5a42, CHIP_RS400},
+ {0x1002, 0x5a61, CHIP_RS400},
+ {0x1002, 0x5a62, CHIP_RS400},
+ {0x1002, 0x5b60, CHIP_RV380},
+ {0x1002, 0x5b62, CHIP_RV380},
+ {0x1002, 0x5b63, CHIP_RV380},
+ {0x1002, 0x5b64, CHIP_RV380},
+ {0x1002, 0x5b65, CHIP_RV380},
+ {0x1002, 0x5c61, CHIP_RV280},
+ {0x1002, 0x5c63, CHIP_RV280},
+ {0x1002, 0x5d48, CHIP_R423},
+ {0x1002, 0x5d49, CHIP_R423},
+ {0x1002, 0x5d4a, CHIP_R423},
+ {0x1002, 0x5d4c, CHIP_R423},
+ {0x1002, 0x5d4d, CHIP_R423},
+ {0x1002, 0x5d4e, CHIP_R423},
+ {0x1002, 0x5d4f, CHIP_R423},
+ {0x1002, 0x5d50, CHIP_R423},
+ {0x1002, 0x5d52, CHIP_R423},
+ {0x1002, 0x5d57, CHIP_R423},
+ {0x1002, 0x5e48, CHIP_RV410},
+ {0x1002, 0x5e4a, CHIP_RV410},
+ {0x1002, 0x5e4b, CHIP_RV410},
+ {0x1002, 0x5e4c, CHIP_RV410},
+ {0x1002, 0x5e4d, CHIP_RV410},
+ {0x1002, 0x5e4f, CHIP_RV410},
+ {0x1002, 0x6880, CHIP_CYPRESS},
+ {0x1002, 0x6888, CHIP_CYPRESS},
+ {0x1002, 0x6889, CHIP_CYPRESS},
+ {0x1002, 0x688A, CHIP_CYPRESS},
+ {0x1002, 0x6898, CHIP_CYPRESS},
+ {0x1002, 0x6899, CHIP_CYPRESS},
+ {0x1002, 0x689c, CHIP_HEMLOCK},
+ {0x1002, 0x689d, CHIP_HEMLOCK},
+ {0x1002, 0x689e, CHIP_CYPRESS},
+ {0x1002, 0x68a0, CHIP_JUNIPER},
+ {0x1002, 0x68a1, CHIP_JUNIPER},
+ {0x1002, 0x68a8, CHIP_JUNIPER},
+ {0x1002, 0x68a9, CHIP_JUNIPER},
+ {0x1002, 0x68b0, CHIP_JUNIPER},
+ {0x1002, 0x68b8, CHIP_JUNIPER},
+ {0x1002, 0x68b9, CHIP_JUNIPER},
+ {0x1002, 0x68be, CHIP_JUNIPER},
+ {0x1002, 0x68c0, CHIP_REDWOOD},
+ {0x1002, 0x68c1, CHIP_REDWOOD},
+ {0x1002, 0x68c8, CHIP_REDWOOD},
+ {0x1002, 0x68c9, CHIP_REDWOOD},
+ {0x1002, 0x68d8, CHIP_REDWOOD},
+ {0x1002, 0x68d9, CHIP_REDWOOD},
+ {0x1002, 0x68da, CHIP_REDWOOD},
+ {0x1002, 0x68de, CHIP_REDWOOD},
+ {0x1002, 0x68e0, CHIP_CEDAR},
+ {0x1002, 0x68e1, CHIP_CEDAR},
+ {0x1002, 0x68e4, CHIP_CEDAR},
+ {0x1002, 0x68e5, CHIP_CEDAR},
+ {0x1002, 0x68e8, CHIP_CEDAR},
+ {0x1002, 0x68e9, CHIP_CEDAR},
+ {0x1002, 0x68f1, CHIP_CEDAR},
+ {0x1002, 0x68f8, CHIP_CEDAR},
+ {0x1002, 0x68f9, CHIP_CEDAR},
+ {0x1002, 0x68fe, CHIP_CEDAR},
+ {0x1002, 0x7100, CHIP_R520},
+ {0x1002, 0x7101, CHIP_R520},
+ {0x1002, 0x7102, CHIP_R520},
+ {0x1002, 0x7103, CHIP_R520},
+ {0x1002, 0x7104, CHIP_R520},
+ {0x1002, 0x7105, CHIP_R520},
+ {0x1002, 0x7106, CHIP_R520},
+ {0x1002, 0x7108, CHIP_R520},
+ {0x1002, 0x7109, CHIP_R520},
+ {0x1002, 0x710A, CHIP_R520},
+ {0x1002, 0x710B, CHIP_R520},
+ {0x1002, 0x710C, CHIP_R520},
+ {0x1002, 0x710E, CHIP_R520},
+ {0x1002, 0x710F, CHIP_R520},
+ {0x1002, 0x7140, CHIP_RV515},
+ {0x1002, 0x7141, CHIP_RV515},
+ {0x1002, 0x7142, CHIP_RV515},
+ {0x1002, 0x7143, CHIP_RV515},
+ {0x1002, 0x7144, CHIP_RV515},
+ {0x1002, 0x7145, CHIP_RV515},
+ {0x1002, 0x7146, CHIP_RV515},
+ {0x1002, 0x7147, CHIP_RV515},
+ {0x1002, 0x7149, CHIP_RV515},
+ {0x1002, 0x714A, CHIP_RV515},
+ {0x1002, 0x714B, CHIP_RV515},
+ {0x1002, 0x714C, CHIP_RV515},
+ {0x1002, 0x714D, CHIP_RV515},
+ {0x1002, 0x714E, CHIP_RV515},
+ {0x1002, 0x714F, CHIP_RV515},
+ {0x1002, 0x7151, CHIP_RV515},
+ {0x1002, 0x7152, CHIP_RV515},
+ {0x1002, 0x7153, CHIP_RV515},
+ {0x1002, 0x715E, CHIP_RV515},
+ {0x1002, 0x715F, CHIP_RV515},
+ {0x1002, 0x7180, CHIP_RV515},
+ {0x1002, 0x7181, CHIP_RV515},
+ {0x1002, 0x7183, CHIP_RV515},
+ {0x1002, 0x7186, CHIP_RV515},
+ {0x1002, 0x7187, CHIP_RV515},
+ {0x1002, 0x7188, CHIP_RV515},
+ {0x1002, 0x718A, CHIP_RV515},
+ {0x1002, 0x718B, CHIP_RV515},
+ {0x1002, 0x718C, CHIP_RV515},
+ {0x1002, 0x718D, CHIP_RV515},
+ {0x1002, 0x718F, CHIP_RV515},
+ {0x1002, 0x7193, CHIP_RV515},
+ {0x1002, 0x7196, CHIP_RV515},
+ {0x1002, 0x719B, CHIP_RV515},
+ {0x1002, 0x719F, CHIP_RV515},
+ {0x1002, 0x71C0, CHIP_RV530},
+ {0x1002, 0x71C1, CHIP_RV530},
+ {0x1002, 0x71C2, CHIP_RV530},
+ {0x1002, 0x71C3, CHIP_RV530},
+ {0x1002, 0x71C4, CHIP_RV530},
+ {0x1002, 0x71C5, CHIP_RV530},
+ {0x1002, 0x71C6, CHIP_RV530},
+ {0x1002, 0x71C7, CHIP_RV530},
+ {0x1002, 0x71CD, CHIP_RV530},
+ {0x1002, 0x71CE, CHIP_RV530},
+ {0x1002, 0x71D2, CHIP_RV530},
+ {0x1002, 0x71D4, CHIP_RV530},
+ {0x1002, 0x71D5, CHIP_RV530},
+ {0x1002, 0x71D6, CHIP_RV530},
+ {0x1002, 0x71DA, CHIP_RV530},
+ {0x1002, 0x71DE, CHIP_RV530},
+ {0x1002, 0x7200, CHIP_RV515},
+ {0x1002, 0x7210, CHIP_RV515},
+ {0x1002, 0x7211, CHIP_RV515},
+ {0x1002, 0x7240, CHIP_R580},
+ {0x1002, 0x7243, CHIP_R580},
+ {0x1002, 0x7244, CHIP_R580},
+ {0x1002, 0x7245, CHIP_R580},
+ {0x1002, 0x7246, CHIP_R580},
+ {0x1002, 0x7247, CHIP_R580},
+ {0x1002, 0x7248, CHIP_R580},
+ {0x1002, 0x7249, CHIP_R580},
+ {0x1002, 0x724A, CHIP_R580},
+ {0x1002, 0x724B, CHIP_R580},
+ {0x1002, 0x724C, CHIP_R580},
+ {0x1002, 0x724D, CHIP_R580},
+ {0x1002, 0x724E, CHIP_R580},
+ {0x1002, 0x724F, CHIP_R580},
+ {0x1002, 0x7280, CHIP_RV570},
+ {0x1002, 0x7281, CHIP_RV560},
+ {0x1002, 0x7283, CHIP_RV560},
+ {0x1002, 0x7284, CHIP_R580},
+ {0x1002, 0x7287, CHIP_RV560},
+ {0x1002, 0x7288, CHIP_RV570},
+ {0x1002, 0x7289, CHIP_RV570},
+ {0x1002, 0x728B, CHIP_RV570},
+ {0x1002, 0x728C, CHIP_RV570},
+ {0x1002, 0x7290, CHIP_RV560},
+ {0x1002, 0x7291, CHIP_RV560},
+ {0x1002, 0x7293, CHIP_RV560},
+ {0x1002, 0x7297, CHIP_RV560},
+ {0x1002, 0x7834, CHIP_RS300},
+ {0x1002, 0x7835, CHIP_RS300},
+ {0x1002, 0x791e, CHIP_RS690},
+ {0x1002, 0x791f, CHIP_RS690},
+ {0x1002, 0x793f, CHIP_RS600},
+ {0x1002, 0x7941, CHIP_RS600},
+ {0x1002, 0x7942, CHIP_RS600},
+ {0x1002, 0x796c, CHIP_RS740},
+ {0x1002, 0x796d, CHIP_RS740},
+ {0x1002, 0x796e, CHIP_RS740},
+ {0x1002, 0x796f, CHIP_RS740},
+ {0x1002, 0x9400, CHIP_R600},
+ {0x1002, 0x9401, CHIP_R600},
+ {0x1002, 0x9402, CHIP_R600},
+ {0x1002, 0x9403, CHIP_R600},
+ {0x1002, 0x9405, CHIP_R600},
+ {0x1002, 0x940A, CHIP_R600},
+ {0x1002, 0x940B, CHIP_R600},
+ {0x1002, 0x940F, CHIP_R600},
+ {0x1002, 0x94A0, CHIP_RV740},
+ {0x1002, 0x94A1, CHIP_RV740},
+ {0x1002, 0x94A3, CHIP_RV740},
+ {0x1002, 0x94B1, CHIP_RV740},
+ {0x1002, 0x94B3, CHIP_RV740},
+ {0x1002, 0x94B4, CHIP_RV740},
+ {0x1002, 0x94B5, CHIP_RV740},
+ {0x1002, 0x94B9, CHIP_RV740},
+ {0x1002, 0x9440, CHIP_RV770},
+ {0x1002, 0x9441, CHIP_RV770},
+ {0x1002, 0x9442, CHIP_RV770},
+ {0x1002, 0x9443, CHIP_RV770},
+ {0x1002, 0x9444, CHIP_RV770},
+ {0x1002, 0x9446, CHIP_RV770},
+ {0x1002, 0x944A, CHIP_RV770},
+ {0x1002, 0x944B, CHIP_RV770},
+ {0x1002, 0x944C, CHIP_RV770},
+ {0x1002, 0x944E, CHIP_RV770},
+ {0x1002, 0x9450, CHIP_RV770},
+ {0x1002, 0x9452, CHIP_RV770},
+ {0x1002, 0x9456, CHIP_RV770},
+ {0x1002, 0x945A, CHIP_RV770},
+ {0x1002, 0x945B, CHIP_RV770},
+ {0x1002, 0x9460, CHIP_RV770},
+ {0x1002, 0x9462, CHIP_RV770},
+ {0x1002, 0x946A, CHIP_RV770},
+ {0x1002, 0x946B, CHIP_RV770},
+ {0x1002, 0x947A, CHIP_RV770},
+ {0x1002, 0x947B, CHIP_RV770},
+ {0x1002, 0x9480, CHIP_RV730},
+ {0x1002, 0x9487, CHIP_RV730},
+ {0x1002, 0x9488, CHIP_RV730},
+ {0x1002, 0x9489, CHIP_RV730},
+ {0x1002, 0x948F, CHIP_RV730},
+ {0x1002, 0x9490, CHIP_RV730},
+ {0x1002, 0x9491, CHIP_RV730},
+ {0x1002, 0x9495, CHIP_RV730},
+ {0x1002, 0x9498, CHIP_RV730},
+ {0x1002, 0x949C, CHIP_RV730},
+ {0x1002, 0x949E, CHIP_RV730},
+ {0x1002, 0x949F, CHIP_RV730},
+ {0x1002, 0x94C0, CHIP_RV610},
+ {0x1002, 0x94C1, CHIP_RV610},
+ {0x1002, 0x94C3, CHIP_RV610},
+ {0x1002, 0x94C4, CHIP_RV610},
+ {0x1002, 0x94C5, CHIP_RV610},
+ {0x1002, 0x94C6, CHIP_RV610},
+ {0x1002, 0x94C7, CHIP_RV610},
+ {0x1002, 0x94C8, CHIP_RV610},
+ {0x1002, 0x94C9, CHIP_RV610},
+ {0x1002, 0x94CB, CHIP_RV610},
+ {0x1002, 0x94CC, CHIP_RV610},
+ {0x1002, 0x94CD, CHIP_RV610},
+ {0x1002, 0x9500, CHIP_RV670},
+ {0x1002, 0x9501, CHIP_RV670},
+ {0x1002, 0x9504, CHIP_RV670},
+ {0x1002, 0x9505, CHIP_RV670},
+ {0x1002, 0x9506, CHIP_RV670},
+ {0x1002, 0x9507, CHIP_RV670},
+ {0x1002, 0x9508, CHIP_RV670},
+ {0x1002, 0x9509, CHIP_RV670},
+ {0x1002, 0x950F, CHIP_RV670},
+ {0x1002, 0x9511, CHIP_RV670},
+ {0x1002, 0x9515, CHIP_RV670},
+ {0x1002, 0x9517, CHIP_RV670},
+ {0x1002, 0x9519, CHIP_RV670},
+ {0x1002, 0x9540, CHIP_RV710},
+ {0x1002, 0x9541, CHIP_RV710},
+ {0x1002, 0x9542, CHIP_RV710},
+ {0x1002, 0x954E, CHIP_RV710},
+ {0x1002, 0x954F, CHIP_RV710},
+ {0x1002, 0x9552, CHIP_RV710},
+ {0x1002, 0x9553, CHIP_RV710},
+ {0x1002, 0x9555, CHIP_RV710},
+ {0x1002, 0x9557, CHIP_RV710},
+ {0x1002, 0x9580, CHIP_RV630},
+ {0x1002, 0x9581, CHIP_RV630},
+ {0x1002, 0x9583, CHIP_RV630},
+ {0x1002, 0x9586, CHIP_RV630},
+ {0x1002, 0x9587, CHIP_RV630},
+ {0x1002, 0x9588, CHIP_RV630},
+ {0x1002, 0x9589, CHIP_RV630},
+ {0x1002, 0x958A, CHIP_RV630},
+ {0x1002, 0x958B, CHIP_RV630},
+ {0x1002, 0x958C, CHIP_RV630},
+ {0x1002, 0x958D, CHIP_RV630},
+ {0x1002, 0x958E, CHIP_RV630},
+ {0x1002, 0x958F, CHIP_RV630},
+ {0x1002, 0x9590, CHIP_RV635},
+ {0x1002, 0x9591, CHIP_RV635},
+ {0x1002, 0x9593, CHIP_RV635},
+ {0x1002, 0x9595, CHIP_RV635},
+ {0x1002, 0x9596, CHIP_RV635},
+ {0x1002, 0x9597, CHIP_RV635},
+ {0x1002, 0x9598, CHIP_RV635},
+ {0x1002, 0x9599, CHIP_RV635},
+ {0x1002, 0x959B, CHIP_RV635},
+ {0x1002, 0x95C0, CHIP_RV620},
+ {0x1002, 0x95C2, CHIP_RV620},
+ {0x1002, 0x95C4, CHIP_RV620},
+ {0x1002, 0x95C5, CHIP_RV620},
+ {0x1002, 0x95C6, CHIP_RV620},
+ {0x1002, 0x95C7, CHIP_RV620},
+ {0x1002, 0x95C9, CHIP_RV620},
+ {0x1002, 0x95CC, CHIP_RV620},
+ {0x1002, 0x95CD, CHIP_RV620},
+ {0x1002, 0x95CE, CHIP_RV620},
+ {0x1002, 0x95CF, CHIP_RV620},
+ {0x1002, 0x9610, CHIP_RS780},
+ {0x1002, 0x9611, CHIP_RS780},
+ {0x1002, 0x9612, CHIP_RS780},
+ {0x1002, 0x9613, CHIP_RS780},
+ {0x1002, 0x9614, CHIP_RS780},
+ {0x1002, 0x9615, CHIP_RS780},
+ {0x1002, 0x9616, CHIP_RS780},
+ {0x1002, 0x9710, CHIP_RS880},
+ {0x1002, 0x9711, CHIP_RS880},
+ {0x1002, 0x9712, CHIP_RS880},
+ {0x1002, 0x9713, CHIP_RS880},
+ {0x1002, 0x9714, CHIP_RS880},
+ {0x1002, 0x9715, CHIP_RS880},
+ {0, 0},
+};
+
+unsigned radeon_family_from_device(unsigned device)
+{
+ unsigned i;
+
+ for (i = 0; ; i++) {
+ if (!radeon_pci_id[i].vendor)
+ return CHIP_UNKNOWN;
+ if (radeon_pci_id[i].device == device)
+ return radeon_pci_id[i].family;
+ }
+ return CHIP_UNKNOWN;
+}
+
+int radeon_is_family_compatible(unsigned family1, unsigned family2)
+{
+ switch (family1) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ switch (family2) {
+ case CHIP_R600:
+ case CHIP_RV610:
+ case CHIP_RV630:
+ case CHIP_RV670:
+ case CHIP_RV620:
+ case CHIP_RV635:
+ case CHIP_RS780:
+ case CHIP_RS880:
+ case CHIP_RV770:
+ case CHIP_RV730:
+ case CHIP_RV710:
+ case CHIP_RV740:
+ return 1;
+ default:
+ return 0;
+ }
+ break;
+ case CHIP_R100:
+ case CHIP_RV100:
+ case CHIP_RS100:
+ case CHIP_RV200:
+ case CHIP_RS200:
+ case CHIP_R200:
+ case CHIP_RV250:
+ case CHIP_RS300:
+ case CHIP_RV280:
+ case CHIP_R300:
+ case CHIP_R350:
+ case CHIP_RV350:
+ case CHIP_RV380:
+ case CHIP_R420:
+ case CHIP_R423:
+ case CHIP_RV410:
+ case CHIP_RS400:
+ case CHIP_RS480:
+ case CHIP_RS600:
+ case CHIP_RS690:
+ case CHIP_RS740:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ case CHIP_CEDAR:
+ case CHIP_REDWOOD:
+ case CHIP_JUNIPER:
+ case CHIP_CYPRESS:
+ case CHIP_HEMLOCK:
+ default:
+ return 0;
+ }
+}
diff --git a/src/gallium/winsys/r600/drm/radeon_priv.h b/src/gallium/winsys/r600/drm/radeon_priv.h
new file mode 100644
index 0000000000..b91421f438
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_priv.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright © 2009 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#ifndef RADEON_PRIV_H
+#define RADEON_PRIV_H
+
+#include <stdint.h>
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+#include <errno.h>
+#include "radeon.h"
+
+struct radeon;
+struct radeon_ctx;
+
+/*
+ * radeon functions
+ */
+typedef int (*radeon_state_pm4_t)(struct radeon_state *state);
+struct radeon_register {
+ unsigned offset;
+ unsigned need_reloc;
+ unsigned bo_id;
+ char name[64];
+};
+
+struct radeon_type {
+ unsigned npm4;
+ unsigned id;
+ unsigned range_start;
+ unsigned range_end;
+ unsigned stride;
+ unsigned immediate;
+ char name[64];
+ unsigned nstates;
+ radeon_state_pm4_t pm4;
+ const struct radeon_register *regs;
+};
+
+struct radeon {
+ int fd;
+ int refcount;
+ unsigned device;
+ unsigned family;
+ unsigned nstate;
+ unsigned ntype;
+ const struct radeon_type *type;
+};
+
+extern struct radeon *radeon_new(int fd, unsigned device);
+extern struct radeon *radeon_incref(struct radeon *radeon);
+extern struct radeon *radeon_decref(struct radeon *radeon);
+extern unsigned radeon_family_from_device(unsigned device);
+extern int radeon_is_family_compatible(unsigned family1, unsigned family2);
+extern int radeon_reg_id(struct radeon *radeon, unsigned offset, unsigned *typeid, unsigned *stateid, unsigned *id);
+extern unsigned radeon_type_from_id(struct radeon *radeon, unsigned id);
+
+/*
+ * radeon context functions
+ */
+#pragma pack(1)
+struct radeon_cs_reloc {
+ uint32_t handle;
+ uint32_t read_domain;
+ uint32_t write_domain;
+ uint32_t flags;
+};
+#pragma pack()
+
+struct radeon_ctx {
+ int refcount;
+ struct radeon *radeon;
+ u32 *pm4;
+ u32 cpm4;
+ u32 draw_cpm4;
+ unsigned id;
+ unsigned next_id;
+ unsigned nreloc;
+ struct radeon_cs_reloc *reloc;
+ unsigned nbo;
+ struct radeon_bo **bo;
+ unsigned ndraw;
+ struct radeon_draw *cdraw;
+ struct radeon_draw **draw;
+ unsigned nstate;
+ struct radeon_state **state;
+};
+
+int radeon_ctx_set_bo_new(struct radeon_ctx *ctx, struct radeon_bo *bo);
+struct radeon_bo *radeon_ctx_get_bo(struct radeon_ctx *ctx, unsigned reloc);
+void radeon_ctx_get_placement(struct radeon_ctx *ctx, unsigned reloc, u32 *placement);
+int radeon_ctx_set_draw_new(struct radeon_ctx *ctx, struct radeon_draw *draw);
+int radeon_ctx_draw(struct radeon_ctx *ctx);
+
+/*
+ * r600/r700 context functions
+ */
+extern int r600_init(struct radeon *radeon);
+extern int r600_ctx_draw(struct radeon_ctx *ctx);
+extern int r600_ctx_next_reloc(struct radeon_ctx *ctx, unsigned *reloc);
+
+/*
+ * radeon state functions
+ */
+extern u32 radeon_state_register_get(struct radeon_state *state, unsigned offset);
+extern int radeon_state_register_set(struct radeon_state *state, unsigned offset, u32 value);
+extern struct radeon_state *radeon_state_duplicate(struct radeon_state *state);
+extern int radeon_state_replace_always(struct radeon_state *ostate, struct radeon_state *nstate);
+extern int radeon_state_pm4_generic(struct radeon_state *state);
+extern int radeon_state_reloc(struct radeon_state *state, unsigned id, unsigned bo_id);
+
+/*
+ * radeon draw functions
+ */
+extern int radeon_draw_pm4(struct radeon_draw *draw);
+
+#endif
diff --git a/src/gallium/winsys/r600/drm/radeon_state.c b/src/gallium/winsys/r600/drm/radeon_state.c
new file mode 100644
index 0000000000..308288557a
--- /dev/null
+++ b/src/gallium/winsys/r600/drm/radeon_state.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2010 Jerome Glisse <glisse@freedesktop.org>
+ *
+ * Permission is hereby granted, free of charge, to 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.
+ *
+ * Authors:
+ * Jerome Glisse
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "radeon_priv.h"
+
+/*
+ * state core functions
+ */
+struct radeon_state *radeon_state(struct radeon *radeon, u32 type, u32 id)
+{
+ struct radeon_state *state;
+
+ if (type > radeon->ntype) {
+ fprintf(stderr, "%s invalid type %d\n", __func__, type);
+ return NULL;
+ }
+ if (id > radeon->nstate) {
+ fprintf(stderr, "%s invalid state id %d\n", __func__, id);
+ return NULL;
+ }
+ state = calloc(1, sizeof(*state));
+ if (state == NULL)
+ return NULL;
+ state->radeon = radeon;
+ state->type = type;
+ state->id = id;
+ state->refcount = 1;
+ state->npm4 = radeon->type[type].npm4;
+ state->nstates = radeon->type[type].nstates;
+ state->states = calloc(1, state->nstates * 4);
+ state->pm4 = calloc(1, radeon->type[type].npm4 * 4);
+ if (state->states == NULL || state->pm4 == NULL) {
+ radeon_state_decref(state);
+ return NULL;
+ }
+ return state;
+}
+
+struct radeon_state *radeon_state_duplicate(struct radeon_state *state)
+{
+ struct radeon_state *nstate = radeon_state(state->radeon, state->type, state->id);
+ unsigned i;
+
+ if (state == NULL)
+ return NULL;
+ nstate->cpm4 = state->cpm4;
+ nstate->nbo = state->nbo;
+ nstate->nreloc = state->nreloc;
+ memcpy(nstate->states, state->states, state->nstates * 4);
+ memcpy(nstate->pm4, state->pm4, state->npm4 * 4);
+ memcpy(nstate->placement, state->placement, 8 * 4);
+ memcpy(nstate->reloc_pm4_id, state->reloc_pm4_id, 8 * 4);
+ memcpy(nstate->reloc_bo_id, state->reloc_bo_id, 8 * 4);
+ memcpy(nstate->bo_dirty, state->bo_dirty, 4 * 4);
+ for (i = 0; i < state->nbo; i++) {
+ nstate->bo[i] = radeon_bo_incref(state->radeon, state->bo[i]);
+ }
+ return nstate;
+}
+
+struct radeon_state *radeon_state_incref(struct radeon_state *state)
+{
+ state->refcount++;
+ return state;
+}
+
+struct radeon_state *radeon_state_decref(struct radeon_state *state)
+{
+ unsigned i;
+
+ if (state == NULL)
+ return NULL;
+ if (--state->refcount > 0) {
+ return NULL;
+ }
+ for (i = 0; i < state->nbo; i++) {
+ state->bo[i] = radeon_bo_decref(state->radeon, state->bo[i]);
+ }
+ free(state->immd);
+ free(state->states);
+ free(state->pm4);
+ memset(state, 0, sizeof(*state));
+ free(state);
+ return NULL;
+}
+
+int radeon_state_replace_always(struct radeon_state *ostate,
+ struct radeon_state *nstate)
+{
+ return 1;
+}
+
+int radeon_state_pm4_generic(struct radeon_state *state)
+{
+ return -EINVAL;
+}
+
+static u32 crc32(void *d, size_t len)
+{
+ u16 *data = (uint16_t*)d;
+ u32 sum1 = 0xffff, sum2 = 0xffff;
+
+ len = len >> 1;
+ while (len) {
+ unsigned tlen = len > 360 ? 360 : len;
+ len -= tlen;
+ do {
+ sum1 += *data++;
+ sum2 += sum1;
+ } while (--tlen);
+ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+ }
+ /* Second reduction step to reduce sums to 16 bits */
+ sum1 = (sum1 & 0xffff) + (sum1 >> 16);
+ sum2 = (sum2 & 0xffff) + (sum2 >> 16);
+ return sum2 << 16 | sum1;
+}
+
+int radeon_state_pm4(struct radeon_state *state)
+{
+ int r;
+
+ if (state == NULL || state->cpm4)
+ return 0;
+ r = state->radeon->type[state->type].pm4(state);
+ if (r) {
+ fprintf(stderr, "%s failed to build PM4 for state(%d %d)\n",
+ __func__, state->type, state->id);
+ return r;
+ }
+ state->pm4_crc = crc32(state->pm4, state->cpm4 * 4);
+ return 0;
+}
+
+int radeon_state_reloc(struct radeon_state *state, unsigned id, unsigned bo_id)
+{
+ state->reloc_pm4_id[state->nreloc] = id;
+ state->reloc_bo_id[state->nreloc] = bo_id;
+ state->nreloc++;
+ return 0;
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
index b9ecf9ded0..73cb6a579b 100644
--- a/src/gallium/winsys/radeon/drm/radeon_buffer.h
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -43,6 +43,8 @@
#include "radeon_winsys.h"
+#define RADEON_USAGE_DOMAIN_GTT (1 << 29)
+#define RADEON_USAGE_DOMAIN_VRAM (1 << 30)
#define RADEON_MAX_BOS 24
@@ -62,11 +64,13 @@ struct pb_manager *
radeon_drm_bufmgr_create(struct radeon_libdrm_winsys *rws);
boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
- uint32_t rd, uint32_t wd);
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd);
void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
- uint32_t rd, uint32_t wd,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
uint32_t flags);
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index a05205da88..ee1b9ede25 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -145,31 +145,6 @@ const struct pb_vtbl radeon_drm_buffer_vtbl = {
radeon_drm_buffer_get_base_buffer,
};
-
-static uint32_t radeon_domain_from_usage(unsigned usage)
-{
- uint32_t domain = 0;
-
- if (usage & PIPE_BIND_RENDER_TARGET) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BIND_DEPTH_STENCIL) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- if (usage & PIPE_BIND_SAMPLER_VIEW) {
- domain |= RADEON_GEM_DOMAIN_VRAM;
- }
- /* also need BIND_BLIT_SOURCE/DESTINATION ? */
- if (usage & PIPE_BIND_VERTEX_BUFFER) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
- if (usage & PIPE_BIND_INDEX_BUFFER) {
- domain |= RADEON_GEM_DOMAIN_GTT;
- }
-
- return domain;
-}
-
struct pb_buffer *radeon_drm_bufmgr_create_buffer_from_handle(struct pb_manager *_mgr,
uint32_t handle)
{
@@ -225,7 +200,11 @@ radeon_drm_bufmgr_create_buffer(struct pb_manager *_mgr,
buf->mgr = mgr;
make_empty_list(buf);
- domain = radeon_domain_from_usage(desc->usage);
+
+ domain =
+ (desc->usage & RADEON_USAGE_DOMAIN_GTT ? RADEON_GEM_DOMAIN_GTT : 0) |
+ (desc->usage & RADEON_USAGE_DOMAIN_VRAM ? RADEON_GEM_DOMAIN_VRAM : 0);
+
buf->bo = radeon_bo_open(rws->bom, 0, size,
desc->alignment, domain, 0);
if (buf->bo == NULL)
@@ -360,27 +339,45 @@ void radeon_drm_bufmgr_set_tiling(struct pb_buffer *_buf,
}
}
+static uint32_t gem_domain(enum r300_buffer_domain dom)
+{
+ uint32_t res = 0;
+
+ if (dom & R300_DOMAIN_GTT)
+ res |= RADEON_GEM_DOMAIN_GTT;
+ if (dom & R300_DOMAIN_VRAM)
+ res |= RADEON_GEM_DOMAIN_VRAM;
+ return res;
+}
+
boolean radeon_drm_bufmgr_add_buffer(struct pb_buffer *_buf,
- uint32_t rd, uint32_t wd)
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
{
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+ uint32_t gem_rd = gem_domain(rd);
+ uint32_t gem_wd = gem_domain(wd);
+
radeon_cs_space_add_persistent_bo(buf->mgr->rws->cs, buf->bo,
- rd, wd);
+ gem_rd, gem_wd);
return TRUE;
}
void radeon_drm_bufmgr_write_reloc(struct pb_buffer *_buf,
- uint32_t rd, uint32_t wd,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
uint32_t flags)
{
struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
int retval;
+ uint32_t gem_rd = gem_domain(rd);
+ uint32_t gem_wd = gem_domain(wd);
retval = radeon_cs_write_reloc(buf->mgr->rws->cs,
- buf->bo, rd, wd, flags);
+ buf->bo, gem_rd, gem_wd, flags);
if (retval) {
debug_printf("radeon: Relocation of %p (%d, %d, %d) failed!\n",
- buf, rd, wd, flags);
+ buf, gem_rd, gem_wd, flags);
}
}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index e188f7e7cc..70ae01a694 100644
--- a/src/gallium/winsys/radeon/drm/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -31,6 +31,7 @@ static struct r300_winsys_buffer *
radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
unsigned alignment,
unsigned usage,
+ enum r300_buffer_domain domain,
unsigned size)
{
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
@@ -38,6 +39,14 @@ radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
struct pb_manager *provider;
struct pb_buffer *buffer;
+ /* XXX this is hackish, but it's the only way to pass these flags
+ * to the real create function. */
+ usage &= ~(RADEON_USAGE_DOMAIN_GTT | RADEON_USAGE_DOMAIN_VRAM);
+ if (domain & R300_DOMAIN_GTT)
+ usage |= RADEON_USAGE_DOMAIN_GTT;
+ if (domain & R300_DOMAIN_VRAM)
+ usage |= RADEON_USAGE_DOMAIN_VRAM;
+
memset(&desc, 0, sizeof(desc));
desc.alignment = alignment;
desc.usage = usage;
@@ -164,8 +173,8 @@ static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
struct r300_winsys_buffer *buf,
- uint32_t rd,
- uint32_t wd)
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd)
{
struct pb_buffer *_buf = radeon_pb_buffer(buf);
@@ -183,12 +192,15 @@ static boolean radeon_validate(struct r300_winsys_screen *rws)
return TRUE;
}
-static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size)
+static void radeon_get_cs_info(struct r300_winsys_screen *rws,
+ struct r300_cs_info *info)
{
struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
struct radeon_cs *cs = ws->cs;
- return cs->cdw + size <= cs->ndw;
+ info->capacity = cs->ndw;
+ info->used = cs->cdw;
+ info->free = cs->ndw - cs->cdw;
}
static void radeon_begin_cs(struct r300_winsys_screen *rws,
@@ -217,8 +229,8 @@ static void radeon_write_cs_table(struct r300_winsys_screen *rws,
static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
struct r300_winsys_buffer *buf,
- uint32_t rd,
- uint32_t wd,
+ enum r300_buffer_domain rd,
+ enum r300_buffer_domain wd,
uint32_t flags)
{
struct pb_buffer *_buf = radeon_pb_buffer(buf);
@@ -333,7 +345,7 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
ws->base.add_buffer = radeon_add_buffer;
ws->base.validate = radeon_validate;
ws->base.destroy = radeon_winsys_destroy;
- ws->base.check_cs = radeon_check_cs;
+ ws->base.get_cs_info = radeon_get_cs_info;
ws->base.begin_cs = radeon_begin_cs;
ws->base.write_cs_dword = radeon_write_cs_dword;
ws->base.write_cs_table = radeon_write_cs_table;
diff --git a/src/gallium/winsys/svga/drm/vmw_context.c b/src/gallium/winsys/svga/drm/vmw_context.c
index 104d03f273..11626ee637 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.c
+++ b/src/gallium/winsys/svga/drm/vmw_context.c
@@ -103,6 +103,9 @@ struct vmw_svga_winsys_context
* referred.
*/
boolean preemptive_flush;
+
+ boolean throttle_set;
+ uint32_t throttle_us;
};
@@ -135,6 +138,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
struct pipe_fence_handle *fence = NULL;
unsigned i;
enum pipe_error ret;
+ uint32_t throttle_us;
ret = pb_validate_validate(vswc->validate);
assert(ret == PIPE_OK);
@@ -153,8 +157,13 @@ vmw_swc_flush(struct svga_winsys_context *swc,
*reloc->where = ptr;
}
+ throttle_us = vswc->throttle_set ?
+ vswc->throttle_us : vswc->vws->default_throttle_us;
+
if (vswc->command.used)
vmw_ioctl_command(vswc->vws,
+ vswc->base.cid,
+ throttle_us,
vswc->command.buffer,
vswc->command.used,
&vswc->last_fence);
@@ -395,3 +404,13 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws)
}
+void
+vmw_svga_context_set_throttling(struct pipe_context *pipe,
+ uint32_t throttle_us)
+{
+ struct svga_winsys_context *swc = svga_winsys_context(pipe);
+ struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
+
+ vswc->throttle_us = throttle_us;
+ vswc->throttle_set = TRUE;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_context.h b/src/gallium/winsys/svga/drm/vmw_context.h
index d4884d24e9..aed8b93734 100644
--- a/src/gallium/winsys/svga/drm/vmw_context.h
+++ b/src/gallium/winsys/svga/drm/vmw_context.h
@@ -52,5 +52,8 @@ struct pipe_screen;
struct svga_winsys_context *
vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
+void
+vmw_svga_context_set_throttling(struct pipe_context *pipe,
+ uint32_t throttle_us);
#endif /* VMW_CONTEXT_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.c b/src/gallium/winsys/svga/drm/vmw_screen.c
index 6cc9b38293..51a4c55e5a 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen.c
@@ -75,3 +75,13 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws)
vmw_ioctl_cleanup(vws);
FREE(vws);
}
+
+void
+vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us)
+{
+ struct vmw_winsys_screen *vws =
+ vmw_winsys_screen(svga_winsys_screen(screen));
+
+ vws->default_throttle_us = throttle_us;
+}
diff --git a/src/gallium/winsys/svga/drm/vmw_screen.h b/src/gallium/winsys/svga/drm/vmw_screen.h
index d3f2c2c7f5..b3de72df88 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen.h
+++ b/src/gallium/winsys/svga/drm/vmw_screen.h
@@ -53,6 +53,7 @@ struct vmw_winsys_screen
struct svga_winsys_screen base;
boolean use_old_scanout_flag;
+ uint32_t default_throttle_us;
struct {
volatile uint32_t *fifo_map;
@@ -96,9 +97,11 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
void
vmw_ioctl_command(struct vmw_winsys_screen *vws,
- void *commands,
- uint32_t size,
- uint32_t *fence);
+ int32_t cid,
+ uint32_t throttle_us,
+ void *commands,
+ uint32_t size,
+ uint32_t *fence);
struct vmw_region *
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
@@ -135,6 +138,7 @@ void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
-
+void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
+ uint32_t throttle_us);
#endif /* VMW_SCREEN_H_ */
diff --git a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
index 5d81fa8c4a..d92ba389d3 100644
--- a/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
+++ b/src/gallium/winsys/svga/drm/vmw_screen_ioctl.c
@@ -241,8 +241,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
}
void
-vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
- uint32_t * pfence)
+vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
+ uint32_t throttle_us, void *commands, uint32_t size,
+ uint32_t *pfence)
{
struct drm_vmw_execbuf_arg arg;
struct drm_vmw_fence_rep rep;
@@ -275,6 +276,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
arg.fence_rep = (unsigned long)&rep;
arg.commands = (unsigned long)commands;
arg.command_size = size;
+ arg.throttle_us = throttle_us;
do {
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
diff --git a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
index 3d702ae08d..b78f537c12 100644
--- a/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
+++ b/src/gallium/winsys/sw/xlib/xlib_sw_winsys.c
@@ -255,7 +255,7 @@ xm_displaytarget_destroy(struct sw_winsys *ws,
}
else {
FREE(xm_dt->data);
- if (xm_dt->tempImage->data == xm_dt->data) {
+ if (xm_dt->tempImage && xm_dt->tempImage->data == xm_dt->data) {
xm_dt->tempImage->data = NULL;
}
xm_dt->data = NULL;
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index 0e148edf8e..69a7b29eb2 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -585,7 +585,8 @@ __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
break;
#endif
case GLX_USE_GL:
- if (fbconfig_style_tags) *bp++;
+ if (fbconfig_style_tags)
+ bp++;
break;
case None:
i = count;
@@ -598,9 +599,8 @@ __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
} else {
/* Ignore the unrecognized tag's value */
bp++;
- break;
}
- break;
+ break;
}
}
diff --git a/src/mapi/glapi/SConscript b/src/mapi/glapi/SConscript
index 15c08255c3..40db237fcb 100644
--- a/src/mapi/glapi/SConscript
+++ b/src/mapi/glapi/SConscript
@@ -1,5 +1,5 @@
#######################################################################
-# SConscript for Mesa
+# SConscript for glapi
Import('*')
@@ -12,6 +12,13 @@ if env['platform'] != 'winddk':
'MAPI_GLAPI_CURRENT',
])
+ if env['platform'] == 'windows':
+ env.Append(CPPDEFINES = [
+ '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers
+ 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers
+ 'WIN32_THREADS', # use Win32 thread API
+ ])
+
env.Append(CPPPATH = [
'#/src/mapi',
'#/src/mesa',
@@ -25,11 +32,14 @@ if env['platform'] != 'winddk':
'glthread.c',
]
- glapi_sources += [
- '../mapi/u_current.c',
- '../mapi/u_execmem.c',
- '../mapi/u_thread.c',
+ mapi_sources = [
+ 'u_current.c',
+ 'u_execmem.c',
+ 'u_thread.c',
]
+ for s in mapi_sources:
+ o = env.SharedObject(s[:-2], '../mapi/' + s)
+ glapi_sources.append(o)
#
# Assembly sources
diff --git a/src/mapi/mapi/u_compiler.h b/src/mapi/mapi/u_compiler.h
index cc9e2cd1e8..f1752d16f2 100644
--- a/src/mapi/mapi/u_compiler.h
+++ b/src/mapi/mapi/u_compiler.h
@@ -28,10 +28,10 @@
#ifndef PUBLIC
# if defined(__GNUC__) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
# define PUBLIC __attribute__((visibility("default")))
-# define HIDDEN __attribute__((visibility("hidden")))
+# elif defined(_MSC_VER)
+# define PUBLIC __declspec(dllexport)
# else
# define PUBLIC
-# define HIDDEN
# endif
#endif
diff --git a/src/mapi/vgapi/SConscript b/src/mapi/vgapi/SConscript
new file mode 100644
index 0000000000..bf51264ab9
--- /dev/null
+++ b/src/mapi/vgapi/SConscript
@@ -0,0 +1,55 @@
+#######################################################################
+# SConscript for vgapi
+
+from sys import executable as python_cmd
+
+Import('*')
+
+if env['platform'] != 'winddk':
+
+ env = env.Clone()
+
+ vgapi_header = env.CodeGenerate(
+ target = '#src/mapi/vgapi/vgapi_tmp.h',
+ script = '../mapi/mapi_abi.py',
+ source = 'vgapi.csv',
+ command = python_cmd + ' $SCRIPT -i vgapi/vgapi_defines.h $SOURCE > $TARGET'
+ )
+
+ env.Append(CPPDEFINES = [
+ 'MAPI_ABI_HEADER=\\"vgapi/vgapi_tmp.h\\"',
+ 'KHRONOS_DLL_EXPORTS',
+ ])
+
+ env.Append(CPPPATH = [
+ '#/include',
+ '#/src/mapi',
+ ])
+
+ mapi_sources = [
+ 'entry.c',
+ 'mapi.c',
+ 'stub.c',
+ 'table.c',
+ 'u_current.c',
+ 'u_execmem.c',
+ 'u_thread.c',
+ ]
+
+ vgapi_objects = []
+ for s in mapi_sources:
+ o = env.SharedObject(s[:-2], '../mapi/' + s)
+ vgapi_objects.append(o)
+
+ env.Depends(vgapi_objects, vgapi_header)
+
+ openvg = env.SharedLibrary(
+ target = 'libOpenVG',
+ source = vgapi_objects,
+ )
+
+ env.InstallSharedLibrary(openvg, version=(1, 0, 0))
+
+ vgapi = [env.FindIxes(openvg, 'LIBPREFIX', 'LIBSUFFIX')]
+
+ Export(['vgapi', 'vgapi_header'])
diff --git a/src/mesa/Makefile b/src/mesa/Makefile
index 3bb2f39475..4f81768924 100644
--- a/src/mesa/Makefile
+++ b/src/mesa/Makefile
@@ -17,8 +17,8 @@ ES1_OBJ_DIR := objs-es1
ES2_OBJ_DIR := objs-es2
MESA_CPPFLAGS := $(API_DEFINES)
-ES1_CPPFLAGS := -DFEATURE_ES1=1 -D__GL_EXPORTS
-ES2_CPPFLAGS := -DFEATURE_ES2=1 -D__GL_EXPORTS
+ES1_CPPFLAGS := -DFEATURE_ES1=1
+ES2_CPPFLAGS := -DFEATURE_ES2=1
include sources.mak
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index 3385bf6f39..34b7f4e8b7 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -217,6 +217,7 @@ if env['platform'] != 'winddk':
'shader/programopt.c',
'shader/symbol_table.c',
'shader/shader_api.c',
+ 'shader/uniforms.c',
]
slang_sources = [
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index c3d1f2c454..18b9035248 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -423,6 +423,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
return NULL;
}
+ pdp->driContextPriv = NULL;
pdp->loaderPrivate = data;
pdp->hHWDrawable = hwDrawable;
pdp->refcount = 1;
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 3b3cb5a0e9..35908ee7b6 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -182,6 +182,13 @@ static void upload_pipelined_state_pointers(struct brw_context *brw )
{
struct intel_context *intel = &brw->intel;
+ if (intel->gen == 5) {
+ /* Need to flush before changing clip max threads for errata. */
+ BEGIN_BATCH(1);
+ OUT_BATCH(MI_FLUSH);
+ ADVANCE_BATCH();
+ }
+
BEGIN_BATCH(7);
OUT_BATCH(CMD_PIPELINED_STATE_POINTERS << 16 | (7 - 2));
OUT_RELOC(brw->vs.state_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
@@ -519,11 +526,11 @@ static void upload_invarient_state( struct brw_context *brw )
BRW_BATCH_STRUCT(brw, &gdo);
}
- intel_batchbuffer_emit_mi_flush(intel->batch);
-
if (intel->gen >= 6) {
int i;
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+
BEGIN_BATCH(3);
OUT_BATCH(CMD_3D_MULTISAMPLE << 16 | (3 - 2));
OUT_BATCH(MS_PIXEL_LOCATION_CENTER |
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index 3f47a68049..7cb812b521 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -55,11 +55,15 @@ brw_queryobj_get_results(struct brw_query_object *query)
if (query->bo == NULL)
return;
- /* Map and count the pixels from the current query BO */
dri_bo_map(query->bo, GL_FALSE);
results = query->bo->virtual;
- for (i = query->first_index; i <= query->last_index; i++) {
- query->Base.Result += results[i * 2 + 1] - results[i * 2];
+ if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+ query->Base.Result += 1000 * ((results[1] >> 32) - (results[0] >> 32));
+ } else {
+ /* Map and count the pixels from the current query BO */
+ for (i = query->first_index; i <= query->last_index; i++) {
+ query->Base.Result += results[i * 2 + 1] - results[i * 2];
+ }
}
dri_bo_unmap(query->bo);
@@ -98,14 +102,31 @@ brw_begin_query(GLcontext *ctx, struct gl_query_object *q)
struct intel_context *intel = intel_context(ctx);
struct brw_query_object *query = (struct brw_query_object *)q;
- /* Reset our driver's tracking of query state. */
- dri_bo_unreference(query->bo);
- query->bo = NULL;
- query->first_index = -1;
- query->last_index = -1;
-
- brw->query.obj = query;
- intel->stats_wm++;
+ if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+ dri_bo_unreference(query->bo);
+ query->bo = drm_intel_bo_alloc(intel->bufmgr, "timer query",
+ 4096, 4096);
+
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+ PIPE_CONTROL_WRITE_TIMESTAMP);
+ OUT_RELOC(query->bo,
+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+ PIPE_CONTROL_GLOBAL_GTT_WRITE |
+ 0);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
+ } else {
+ /* Reset our driver's tracking of query state. */
+ dri_bo_unreference(query->bo);
+ query->bo = NULL;
+ query->first_index = -1;
+ query->last_index = -1;
+
+ brw->query.obj = query;
+ intel->stats_wm++;
+ }
}
/**
@@ -118,21 +139,36 @@ brw_end_query(GLcontext *ctx, struct gl_query_object *q)
struct intel_context *intel = intel_context(ctx);
struct brw_query_object *query = (struct brw_query_object *)q;
- /* Flush the batchbuffer in case it has writes to our query BO.
- * Have later queries write to a new query BO so that further rendering
- * doesn't delay the collection of our results.
- */
- if (query->bo) {
- brw_emit_query_end(brw);
- intel_batchbuffer_flush(intel->batch);
+ if (query->Base.Target == GL_TIME_ELAPSED_EXT) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL |
+ PIPE_CONTROL_WRITE_TIMESTAMP);
+ OUT_RELOC(query->bo,
+ I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
+ PIPE_CONTROL_GLOBAL_GTT_WRITE |
+ 8);
+ OUT_BATCH(0);
+ OUT_BATCH(0);
+ ADVANCE_BATCH();
- dri_bo_unreference(brw->query.bo);
- brw->query.bo = NULL;
+ intel_batchbuffer_flush(intel->batch);
+ } else {
+ /* Flush the batchbuffer in case it has writes to our query BO.
+ * Have later queries write to a new query BO so that further rendering
+ * doesn't delay the collection of our results.
+ */
+ if (query->bo) {
+ brw_emit_query_end(brw);
+ intel_batchbuffer_flush(intel->batch);
+
+ dri_bo_unreference(brw->query.bo);
+ brw->query.bo = NULL;
+ }
+
+ brw->query.obj = NULL;
+
+ intel->stats_wm--;
}
-
- brw->query.obj = NULL;
-
- intel->stats_wm--;
}
static void brw_wait_query(GLcontext *ctx, struct gl_query_object *q)
diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c
index c08cb45b75..c4431b5a32 100644
--- a/src/mesa/drivers/dri/i965/brw_state_cache.c
+++ b/src/mesa/drivers/dri/i965/brw_state_cache.c
@@ -386,11 +386,14 @@ brw_init_non_surface_cache(struct brw_context *brw)
brw_init_cache_id(cache, "CLIP_UNIT", BRW_CLIP_UNIT);
brw_init_cache_id(cache, "CLIP_PROG", BRW_CLIP_PROG);
+ brw_init_cache_id(cache, "CLIP_VP", BRW_CLIP_VP);
brw_init_cache_id(cache, "GS_UNIT", BRW_GS_UNIT);
brw_init_cache_id(cache, "GS_PROG", BRW_GS_PROG);
brw_init_cache_id(cache, "BLEND_STATE", BRW_BLEND_STATE);
+ brw_init_cache_id(cache, "COLOR_CALC_STATE", BRW_COLOR_CALC_STATE);
+ brw_init_cache_id(cache, "DEPTH_STENCIL_STATE", BRW_DEPTH_STENCIL_STATE);
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index e51a1a0e26..feaa2e1f40 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -519,13 +519,8 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
_mesa_problem(ctx, "Bad renderbuffer format: %d\n", irb->Base.Format);
}
key.tiling = region->tiling;
- if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
- key.width = rb->Width;
- key.height = rb->Height;
- } else {
- key.width = region->width;
- key.height = region->height;
- }
+ key.width = rb->Width;
+ key.height = rb->Height;
key.pitch = region->pitch;
key.cpp = region->cpp;
key.draw_x = region->draw_x;
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index ca8e344836..27bd4fe605 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -55,6 +55,7 @@ intel_batchbuffer_reset(struct intel_batchbuffer *batch)
}
batch->size = intel->maxBatchSize;
batch->ptr = batch->map;
+ batch->reserved_space = BATCH_RESERVED;
batch->dirty_state = ~0;
}
@@ -180,8 +181,6 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
/* Check that we didn't just wrap our batchbuffer at a bad time. */
assert(!intel->no_batch_wrap);
- batch->reserved_space = BATCH_RESERVED;
-
/* TODO: Just pass the relocation list and dma buffer up to the
* kernel.
*/
@@ -275,10 +274,18 @@ intel_batchbuffer_emit_mi_flush(struct intel_batchbuffer *batch)
{
struct intel_context *intel = batch->intel;
- if (intel->gen >= 4) {
+ if (intel->gen >= 6) {
+ BEGIN_BATCH(4);
+ OUT_BATCH(_3DSTATE_PIPE_CONTROL);
+ OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
+ PIPE_CONTROL_WRITE_FLUSH |
+ PIPE_CONTROL_NO_WRITE);
+ OUT_BATCH(0); /* write address */
+ OUT_BATCH(0); /* write data */
+ ADVANCE_BATCH();
+ } else if (intel->gen >= 4) {
BEGIN_BATCH(4);
OUT_BATCH(_3DSTATE_PIPE_CONTROL |
- PIPE_CONTROL_INSTRUCTION_FLUSH |
PIPE_CONTROL_WRITE_FLUSH |
PIPE_CONTROL_NO_WRITE);
OUT_BATCH(0); /* write address */
diff --git a/src/mesa/drivers/dri/intel/intel_decode.c b/src/mesa/drivers/dri/intel/intel_decode.c
index 5293482b35..650010ac9c 100644
--- a/src/mesa/drivers/dri/intel/intel_decode.c
+++ b/src/mesa/drivers/dri/intel/intel_decode.c
@@ -1407,6 +1407,7 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
{
unsigned int opcode, len;
int i;
+ char *desc1;
struct {
uint32_t opcode;
@@ -1622,6 +1623,32 @@ decode_3d_965(uint32_t *data, int count, uint32_t hw_offset, int *failures)
return len;
+ case 0x7a00:
+ len = (data[0] & 0xff) + 2;
+ if (len != 4)
+ fprintf(out, "Bad count in PIPE_CONTROL\n");
+ if (count < len)
+ BUFFER_FAIL(count, len, "PIPE_CONTROL");
+
+ switch ((data[0] >> 14) & 0x3) {
+ case 0: desc1 = "no write"; break;
+ case 1: desc1 = "qword write"; break;
+ case 2: desc1 = "PS_DEPTH_COUNT write"; break;
+ case 3: desc1 = "TIMESTAMP write"; break;
+ }
+ instr_out(data, hw_offset, 0,
+ "PIPE_CONTROL: %s, %sdepth stall, %sRC write flush, "
+ "%sinst flush, %stexture flush\n",
+ desc1,
+ data[0] & (1 << 13) ? "" : "no ",
+ data[0] & (1 << 12) ? "" : "no ",
+ data[0] & (1 << 11) ? "" : "no ",
+ data[0] & (1 << 9) ? "" : "no ");
+ instr_out(data, hw_offset, 1, "destination address\n");
+ instr_out(data, hw_offset, 2, "immediate dword low\n");
+ instr_out(data, hw_offset, 3, "immediate dword high\n");
+ return len;
+
case 0x7b00:
len = (data[0] & 0xff) + 2;
if (len != 6)
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 9c2083873a..edba1fc2f2 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -57,6 +57,7 @@
#define need_GL_EXT_provoking_vertex
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
+#define need_GL_EXT_timer_query
#define need_GL_APPLE_vertex_array_object
#define need_GL_APPLE_object_purgeable
#define need_GL_ATI_separate_stencil
@@ -182,6 +183,9 @@ static const struct dri_extension brw_extensions[] = {
{ NULL, NULL }
};
+static const struct dri_extension ironlake_extensions[] = {
+ { "GL_EXT_timer_query", GL_EXT_timer_query_functions },
+};
static const struct dri_extension arb_oq_extensions[] = {
{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
@@ -207,6 +211,9 @@ intelInitExtensions(GLcontext *ctx)
*/
driInitExtensions(ctx, card_extensions, GL_FALSE);
+ if (intel->gen >= 5)
+ driInitExtensions(ctx, ironlake_extensions, GL_FALSE);
+
if (intel->gen >= 4)
driInitExtensions(ctx, brw_extensions, GL_FALSE);
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 549a4acc7d..ddc2c337c8 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -74,6 +74,14 @@ get_teximage_source(struct intel_context *intel, GLenum internalFormat)
return NULL;
case GL_RGBA:
case GL_RGBA8:
+ irb = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);
+ /* We're required to set alpha to 1.0 in this case, but we can't
+ * do that with the blitter, so fall back. We could use the 3D
+ * engine or do two passes with the blitter, but it doesn't seem
+ * worth it for this case. */
+ if (irb->Base._BaseFormat == GL_RGB)
+ return NULL;
+ return irb->region;
case GL_RGB:
case GL_RGB8:
return intel_readbuf_region(intel);
diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
index ef56e62396..b27a683c39 100644
--- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
@@ -95,7 +95,7 @@ static unsigned int translate_rgb_opcode(struct r300_fragment_program_compiler *
case RC_OPCODE_DP4: return R300_ALU_OUTC_DP4;
case RC_OPCODE_FRC: return R300_ALU_OUTC_FRC;
default:
- error("translate_rgb_opcode(%i): Unknown opcode", opcode);
+ error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -116,7 +116,7 @@ static unsigned int translate_alpha_opcode(struct r300_fragment_program_compiler
case RC_OPCODE_FRC: return R300_ALU_OUTA_FRC;
case RC_OPCODE_LG2: return R300_ALU_OUTA_LG2;
default:
- error("translate_rgb_opcode(%i): Unknown opcode", opcode);
+ error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -302,7 +302,7 @@ static int emit_tex(struct r300_emit_state * emit, struct rc_instruction * inst)
case RC_OPCODE_TXB: opcode = R300_TEX_OP_TXB; break;
case RC_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break;
default:
- error("Unknown texture opcode %i", inst->U.I.Opcode);
+ error("Unknown texture opcode %s", rc_get_opcode_info(inst->U.I.Opcode)->Name);
return 0;
}
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 4a0b6c02ef..02bef5603f 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -375,7 +375,7 @@ static void translate_vertex_program(struct r300_vertex_program_compiler * compi
case RC_OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
case RC_OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
default:
- rc_error(&compiler->Base, "Unknown opcode %i\n", vpi->Opcode);
+ rc_error(&compiler->Base, "Unknown opcode %s\n", rc_get_opcode_info(vpi->Opcode)->Name);
return;
}
diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
index 10c5e2349e..fb2d8b5a9c 100644
--- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
@@ -82,7 +82,7 @@ static unsigned int translate_rgb_op(struct r300_fragment_program_compiler *c, r
case RC_OPCODE_DP4: return R500_ALU_RGBA_OP_DP4;
case RC_OPCODE_FRC: return R500_ALU_RGBA_OP_FRC;
default:
- error("translate_rgb_op(%d): unknown opcode\n", opcode);
+ error("translate_rgb_op: unknown opcode %s\n", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -106,7 +106,7 @@ static unsigned int translate_alpha_op(struct r300_fragment_program_compiler *c,
case RC_OPCODE_FRC: return R500_ALPHA_OP_FRC;
case RC_OPCODE_LG2: return R500_ALPHA_OP_LN2;
default:
- error("translate_alpha_op(%d): unknown opcode\n", opcode);
+ error("translate_alpha_op: unknown opcode %s\n", rc_get_opcode_info(opcode)->Name);
/* fall through */
case RC_OPCODE_NOP:
/* fall through */
@@ -332,7 +332,7 @@ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_inst
code->inst[ip].inst1 |= R500_TEX_INST_PROJ;
break;
default:
- error("emit_tex can't handle opcode %x\n", inst->Opcode);
+ error("emit_tex can't handle opcode %s\n", rc_get_opcode_info(inst->Opcode)->Name);
}
use_temporary(code, inst->SrcReg[0].Index);
@@ -432,7 +432,7 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst
s->CurrentBranchDepth--;
} else {
- rc_error(s->C, "%s: unknown opcode %i\n", __FUNCTION__, inst->U.I.Opcode);
+ rc_error(s->C, "%s: unknown opcode %s\n", __FUNCTION__, rc_get_opcode_info(inst->U.I.Opcode)->Name);
}
}
diff --git a/src/mesa/drivers/dri/r300/r300_blit.c b/src/mesa/drivers/dri/r300/r300_blit.c
index 6fd41b6f41..d2c25fb9cd 100644
--- a/src/mesa/drivers/dri/r300/r300_blit.c
+++ b/src/mesa/drivers/dri/r300/r300_blit.c
@@ -141,10 +141,11 @@ static void r300_emit_tx_setup(struct r300_context *r300,
unsigned height,
unsigned pitch)
{
+ int is_r500 = r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515;
BATCH_LOCALS(&r300->radeon);
- assert(width <= 2048);
- assert(height <= 2048);
+ assert(is_r500 ? width <= 4096 : width <= 2048);
+ assert(is_r500 ? height <= 4096 : height <= 2048);
assert(r300TranslateTexFormat(mesa_format) >= 0);
assert(offset % 32 == 0);
@@ -159,14 +160,17 @@ static void r300_emit_tx_setup(struct r300_context *r300,
(0 << 28));
OUT_BATCH_REGVAL(R300_TX_FILTER1_0, 0);
OUT_BATCH_REGVAL(R300_TX_SIZE_0,
- ((width-1) << R300_TX_WIDTHMASK_SHIFT) |
- ((height-1) << R300_TX_HEIGHTMASK_SHIFT) |
+ (((width - 1) & 0x7ff) << R300_TX_WIDTHMASK_SHIFT) |
+ (((height - 1) & 0x7ff) << R300_TX_HEIGHTMASK_SHIFT) |
(0 << R300_TX_DEPTHMASK_SHIFT) |
(0 << R300_TX_MAX_MIP_LEVEL_SHIFT) |
R300_TX_SIZE_TXPITCH_EN);
OUT_BATCH_REGVAL(R300_TX_FORMAT_0, r300TranslateTexFormat(mesa_format));
- OUT_BATCH_REGVAL(R300_TX_FORMAT2_0, pitch - 1);
+ OUT_BATCH_REGVAL(R300_TX_FORMAT2_0,
+ (pitch - 1) |
+ (is_r500 && width > 2048 ? R500_TXWIDTH_BIT11 : 0) |
+ (is_r500 && height > 2048 ? R500_TXHEIGHT_BIT11 : 0));
OUT_BATCH_REGSEQ(R300_TX_OFFSET_0, 1);
OUT_BATCH_RELOC(0, bo, offset, RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index 6398605835..517485091a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -506,9 +506,10 @@ radeon_render_texture(GLcontext * ctx,
ASSERT(newImage);
- if (newImage->Border != 0) {
- /* Fallback on drawing to a texture with a border, which won't have a
- * miptree.
+ radeon_image = (radeon_texture_image *)newImage;
+
+ if (!radeon_image->mt || newImage->Border != 0) {
+ /* Fallback on drawing to a texture without a miptree.
*/
_mesa_reference_renderbuffer(&att->Renderbuffer, NULL);
_mesa_render_texture(ctx, fb, att);
@@ -539,7 +540,6 @@ radeon_render_texture(GLcontext * ctx,
rrb->base.RefCount);
/* point the renderbufer's region to the texture image region */
- radeon_image = (radeon_texture_image *)newImage;
if (rrb->bo != radeon_image->mt->bo) {
if (rrb->bo)
radeon_bo_unref(rrb->bo);
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 2b655fbd95..bcac125baf 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -39,6 +39,7 @@
#include "main/texstore.h"
#include "main/teximage.h"
#include "main/texobj.h"
+#include "drivers/common/meta.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
@@ -294,9 +295,13 @@ void radeonGenerateMipmap(GLcontext* ctx, GLenum target, struct gl_texture_objec
radeon_firevertices(rmesa);
}
- radeon_teximage_map(baseimage, GL_FALSE);
- radeon_generate_mipmap(ctx, target, texObj);
- radeon_teximage_unmap(baseimage);
+ if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
+ radeon_teximage_map(baseimage, GL_FALSE);
+ radeon_generate_mipmap(ctx, target, texObj);
+ radeon_teximage_unmap(baseimage);
+ } else {
+ _mesa_meta_GenerateMipmap(ctx, target, texObj);
+ }
}
@@ -588,7 +593,12 @@ static int image_matches_texture_obj(struct gl_texture_object *texObj,
if (!baseImage)
return 0;
- if (level < texObj->BaseLevel || level > texObj->MaxLevel)
+ /* Check image level against object BaseLevel, but not MaxLevel. MaxLevel is not
+ * the highest level that can be assigned to the miptree.
+ */
+ const unsigned maxLevel = texObj->BaseLevel + baseImage->MaxLog2;
+ if (level < texObj->BaseLevel || level > maxLevel
+ || level > RADEON_MIPTREE_MAX_TEXTURE_LEVELS)
return 0;
const unsigned levelDiff = level - texObj->BaseLevel;
@@ -610,9 +620,7 @@ static void teximage_assign_miptree(radeonContextPtr rmesa,
radeonTexObj *t = radeon_tex_obj(texObj);
radeon_texture_image* image = get_radeon_texture_image(texImage);
- /* Since miptree holds only images for levels <BaseLevel..MaxLevel>
- * don't allocate the miptree if the teximage won't fit.
- */
+ /* check image for dimension and level compatibility with texture */
if (!image_matches_texture_obj(texObj, texImage, level))
return;
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index 7fa7e2192f..f3903c2e38 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -47,6 +47,11 @@
#include "drivers/common/meta.h"
#include "utils.h"
+#include "main/teximage.h"
+#include "main/texfetch.h"
+#include "main/texformat.h"
+#include "main/texstate.h"
+
#include "swrast_priv.h"
@@ -54,7 +59,59 @@
* Screen and config-related functions
*/
+static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint texture_format, __DRIdrawable *dPriv)
+{
+ struct dri_context *dri_ctx;
+ int x, y, w, h;
+ __DRIscreen *sPriv = dPriv->driScreenPriv;
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ uint32_t internalFormat;
+
+ dri_ctx = pDRICtx->driverPrivate;
+
+ internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
+
+ texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
+ texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
+ texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
+
+ _mesa_lock_texture(&dri_ctx->Base, texObj);
+
+ sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
+
+ _mesa_init_teximage_fields(&dri_ctx->Base, target, texImage,
+ w, h, 1, 0, internalFormat);
+
+ if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
+ texImage->TexFormat = MESA_FORMAT_XRGB8888;
+ else
+ texImage->TexFormat = MESA_FORMAT_ARGB8888;
+
+ _mesa_set_fetch_functions(texImage, 2);
+
+ sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)texImage->Data,
+ dPriv->loaderPrivate);
+
+ _mesa_unlock_texture(&dri_ctx->Base, texObj);
+}
+
+static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
+}
+
+static const __DRItexBufferExtension swrastTexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ swrastSetTexBuffer,
+ swrastSetTexBuffer2,
+};
+
static const __DRIextension *dri_screen_extensions[] = {
+ &swrastTexBufferExtension.base,
NULL
};
@@ -486,6 +543,16 @@ viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
swrast_check_and_update_window_size(ctx, read);
}
+static gl_format swrastChooseTextureFormat(GLcontext * ctx,
+ GLint internalFormat,
+ GLenum format,
+ GLenum type)
+{
+ if (internalFormat == GL_RGB)
+ return MESA_FORMAT_XRGB8888;
+ return _mesa_choose_tex_format(ctx, internalFormat, format, type);
+}
+
static void
swrast_init_driver_functions(struct dd_function_table *driver)
{
@@ -493,6 +560,7 @@ swrast_init_driver_functions(struct dd_function_table *driver)
driver->UpdateState = update_state;
driver->GetBufferSize = NULL;
driver->Viewport = viewport;
+ driver->ChooseTextureFormat = swrastChooseTextureFormat;
}
diff --git a/src/mesa/drivers/fbdev/glfbdev.c b/src/mesa/drivers/fbdev/glfbdev.c
index 0ea2796eaa..2ad52d89fc 100644
--- a/src/mesa/drivers/fbdev/glfbdev.c
+++ b/src/mesa/drivers/fbdev/glfbdev.c
@@ -41,8 +41,8 @@
#ifdef USE_GLFBDEV_DRIVER
-#include <linux/fb.h>
#include "GL/glfbdev.h"
+#include <linux/fb.h>
#include "main/glheader.h"
#include "main/buffers.h"
#include "main/context.h"
@@ -216,6 +216,10 @@ viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
DST[1] = VALUE[GCOMP]; \
DST[2] = VALUE[RCOMP]; \
DST[3] = VALUE[ACOMP]
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+ DST[0] = VALUE[BCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[2] = VALUE[RCOMP];
#define FETCH_PIXEL(DST, SRC) \
DST[RCOMP] = SRC[2]; \
DST[GCOMP] = SRC[1]; \
@@ -531,10 +535,12 @@ new_glfbdev_renderbuffer(void *bufferStart, const GLFBDevVisualPtr visual)
rb->Base.Width = visual->var.xres;
rb->Base.Height = visual->var.yres;
+ /*
rb->Base.RedBits = visual->var.red.length;
rb->Base.GreenBits = visual->var.green.length;
rb->Base.BlueBits = visual->var.blue.length;
rb->Base.AlphaBits = visual->var.transp.length;
+ */
rb->Base.InternalFormat = pixelFormat;
}
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index efd8057608..e0507ccf86 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -65,9 +65,7 @@ extern "C" {
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
-# ifndef __eglplatform_h_
- typedef __int32 int32_t;
-# endif
+ typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
diff --git a/src/mesa/main/es_generator.py b/src/mesa/main/es_generator.py
index a3e089ed58..9a8f5a6f5e 100644
--- a/src/mesa/main/es_generator.py
+++ b/src/mesa/main/es_generator.py
@@ -203,9 +203,6 @@ print """
typedef double GLdouble;
typedef double GLclampd;
-/* This type is normally in glext.h, but needed here */
-typedef char GLchar;
-
/* Mesa error handling requires these */
extern void *_mesa_get_current_context(void);
extern void _mesa_error(void *ctx, GLenum error, const char *fmtString, ... );
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index bf445d2b29..f33e027857 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -1015,9 +1015,10 @@ renderbuffer_storage(GLenum target, GLenum internalFormat,
*/
}
+
#if FEATURE_OES_EGL_image
void GLAPIENTRY
-_mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
+_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
struct gl_renderbuffer *rb;
GET_CURRENT_CONTEXT(ctx);
@@ -1030,13 +1031,15 @@ _mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
}
if (target != GL_RENDERBUFFER) {
- _mesa_error(ctx, GL_INVALID_ENUM, "EGLImageTargetRenderbufferStorageOES");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "EGLImageTargetRenderbufferStorageOES");
return;
}
rb = ctx->CurrentRenderbuffer;
if (!rb) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "EGLImageTargetRenderbufferStorageOES");
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "EGLImageTargetRenderbufferStorageOES");
return;
}
@@ -1046,6 +1049,7 @@ _mesa_EGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image)
}
#endif
+
/**
* Helper function for _mesa_GetRenderbufferParameterivEXT() and
* _mesa_GetFramebufferAttachmentParameterivEXT()
@@ -1113,6 +1117,10 @@ _mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
renderbuffer_storage(target, internalFormat, width, height, samples);
}
+
+/**
+ * OpenGL ES version of glRenderBufferStorage.
+ */
void GLAPIENTRY
_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
GLsizei width, GLsizei height)
@@ -1130,6 +1138,7 @@ _es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
renderbuffer_storage(target, internalFormat, width, height, 0);
}
+
void GLAPIENTRY
_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
{
@@ -1802,10 +1811,10 @@ _mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
rb = NULL;
}
- if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) {
+ if (attachment == GL_DEPTH_STENCIL_ATTACHMENT &&
+ rb && rb->Format != MESA_FORMAT_NONE) {
/* make sure the renderbuffer is a depth/stencil format */
- const GLenum baseFormat =
- _mesa_get_format_base_format(att->Renderbuffer->Format);
+ const GLenum baseFormat = _mesa_get_format_base_format(rb->Format);
if (baseFormat != GL_DEPTH_STENCIL) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glFramebufferRenderbufferEXT(renderbuffer"
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 1cb6cffb6a..03f2707f4f 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -674,14 +674,14 @@ static const struct value_desc values[] = {
#if FEATURE_ES2
/* Enums unique to OpenGL ES 2.0 */
- { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_OFFSET, NO_EXTRA },
+ { 0, 0, TYPE_API_MASK, API_OPENGLES2_BIT, NO_EXTRA },
{ GL_MAX_FRAGMENT_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT,
offsetof(GLcontext, Const.FragmentProgram.MaxUniformComponents), NO_EXTRA },
{ GL_MAX_VARYING_VECTORS, LOC_CUSTOM, TYPE_INT,
offsetof(GLcontext, Const.MaxVarying), NO_EXTRA },
{ GL_MAX_VERTEX_UNIFORM_VECTORS, LOC_CUSTOM, TYPE_INT,
offsetof(GLcontext, Const.VertexProgram.MaxUniformComponents), NO_EXTRA },
- { GL_SHADER_COMPILER, CONST(1), NO_EXTRA, NO_EXTRA },
+ { GL_SHADER_COMPILER, CONST(1), NO_EXTRA },
/* OES_get_program_binary */
{ GL_NUM_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
{ GL_SHADER_BINARY_FORMATS, CONST(0), NO_EXTRA },
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
index 917e295fe1..65f1ee3efb 100644
--- a/src/mesa/main/shaders.c
+++ b/src/mesa/main/shaders.c
@@ -49,7 +49,7 @@
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -57,7 +57,7 @@ _mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_AttachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -65,7 +65,7 @@ _mesa_AttachShader(GLuint program, GLuint shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
const GLcharARB *name)
{
@@ -74,7 +74,7 @@ _mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_CompileShaderARB(GLhandleARB shaderObj)
{
GET_CURRENT_CONTEXT(ctx);
@@ -82,7 +82,7 @@ _mesa_CompileShaderARB(GLhandleARB shaderObj)
}
-static GLuint GLAPIENTRY
+GLuint GLAPIENTRY
_mesa_CreateShader(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
@@ -90,7 +90,7 @@ _mesa_CreateShader(GLenum type)
}
-static GLhandleARB GLAPIENTRY
+GLhandleARB GLAPIENTRY
_mesa_CreateShaderObjectARB(GLenum type)
{
GET_CURRENT_CONTEXT(ctx);
@@ -98,7 +98,7 @@ _mesa_CreateShaderObjectARB(GLenum type)
}
-static GLuint GLAPIENTRY
+GLuint GLAPIENTRY
_mesa_CreateProgram(void)
{
GET_CURRENT_CONTEXT(ctx);
@@ -106,7 +106,7 @@ _mesa_CreateProgram(void)
}
-static GLhandleARB GLAPIENTRY
+GLhandleARB GLAPIENTRY
_mesa_CreateProgramObjectARB(void)
{
GET_CURRENT_CONTEXT(ctx);
@@ -114,7 +114,7 @@ _mesa_CreateProgramObjectARB(void)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteObjectARB(GLhandleARB obj)
{
if (obj) {
@@ -132,7 +132,7 @@ _mesa_DeleteObjectARB(GLhandleARB obj)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteProgram(GLuint name)
{
if (name) {
@@ -142,7 +142,7 @@ _mesa_DeleteProgram(GLuint name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DeleteShader(GLuint name)
{
if (name) {
@@ -152,7 +152,7 @@ _mesa_DeleteShader(GLuint name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -160,7 +160,7 @@ _mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_DetachShader(GLuint program, GLuint shader)
{
GET_CURRENT_CONTEXT(ctx);
@@ -168,7 +168,7 @@ _mesa_DetachShader(GLuint program, GLuint shader)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name)
@@ -179,7 +179,7 @@ _mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
GLsizei maxLength, GLsizei * length, GLint * size,
GLenum * type, GLcharARB * name)
@@ -190,7 +190,7 @@ _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
GLsizei * count, GLhandleARB * obj)
{
@@ -199,7 +199,7 @@ _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
GLsizei *count, GLuint *obj)
{
@@ -208,7 +208,7 @@ _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
}
-static GLint GLAPIENTRY
+GLint GLAPIENTRY
_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -216,7 +216,7 @@ _mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
GLcharARB * infoLog)
{
@@ -234,7 +234,7 @@ _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -261,7 +261,7 @@ _mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
GLfloat *params)
{
@@ -271,7 +271,7 @@ _mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -279,7 +279,7 @@ _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -287,7 +287,7 @@ _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
@@ -296,7 +296,7 @@ _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
GLsizei *length, GLchar *infoLog)
{
@@ -305,7 +305,7 @@ _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
GLsizei *length, GLcharARB *sourceOut)
{
@@ -314,7 +314,7 @@ _mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -322,7 +322,7 @@ _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -341,7 +341,7 @@ _mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
#endif
-static GLhandleARB GLAPIENTRY
+GLhandleARB GLAPIENTRY
_mesa_GetHandleARB(GLenum pname)
{
GET_CURRENT_CONTEXT(ctx);
@@ -349,7 +349,7 @@ _mesa_GetHandleARB(GLenum pname)
}
-static GLint GLAPIENTRY
+GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -357,7 +357,7 @@ _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
}
-static GLboolean GLAPIENTRY
+GLboolean GLAPIENTRY
_mesa_IsProgram(GLuint name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -365,7 +365,7 @@ _mesa_IsProgram(GLuint name)
}
-static GLboolean GLAPIENTRY
+GLboolean GLAPIENTRY
_mesa_IsShader(GLuint name)
{
GET_CURRENT_CONTEXT(ctx);
@@ -373,7 +373,7 @@ _mesa_IsShader(GLuint name)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_LinkProgramARB(GLhandleARB programObj)
{
GET_CURRENT_CONTEXT(ctx);
@@ -416,7 +416,7 @@ _mesa_read_shader(const char *fname)
* Basically, concatenate the source code strings into one long string
* and pass it to ctx->Driver.ShaderSource().
*/
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
const GLcharARB ** string, const GLint * length)
{
@@ -509,14 +509,14 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1fARB(GLint location, GLfloat v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
{
GET_CURRENT_CONTEXT(ctx);
@@ -526,7 +526,7 @@ _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -537,7 +537,7 @@ _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
GLfloat v3)
{
@@ -550,14 +550,14 @@ _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1iARB(GLint location, GLint v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
{
GET_CURRENT_CONTEXT(ctx);
@@ -567,7 +567,7 @@ _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -578,7 +578,7 @@ _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
{
GET_CURRENT_CONTEXT(ctx);
@@ -590,56 +590,56 @@ _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
{
GET_CURRENT_CONTEXT(ctx);
@@ -648,14 +648,14 @@ _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
/** OpenGL 3.0 GLuint-valued functions **/
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1ui(GLint location, GLuint v0)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, 1, &v0, GL_UNSIGNED_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
{
GET_CURRENT_CONTEXT(ctx);
@@ -665,7 +665,7 @@ _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
{
GET_CURRENT_CONTEXT(ctx);
@@ -676,7 +676,7 @@ _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
{
GET_CURRENT_CONTEXT(ctx);
@@ -688,28 +688,28 @@ _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
ctx->Driver.Uniform(ctx, location, 1, v, GL_UNSIGNED_INT_VEC4);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC2);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.Uniform(ctx, location, count, value, GL_UNSIGNED_INT_VEC3);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
{
GET_CURRENT_CONTEXT(ctx);
@@ -718,7 +718,7 @@ _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
@@ -726,7 +726,7 @@ _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 2, 2, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
@@ -734,7 +734,7 @@ _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 3, 3, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
const GLfloat * value)
{
@@ -746,7 +746,7 @@ _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
/**
* Non-square UniformMatrix are OpenGL 2.1
*/
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -754,7 +754,7 @@ _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 2, 3, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -762,7 +762,7 @@ _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 3, 2, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -770,7 +770,7 @@ _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 2, 4, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -778,7 +778,7 @@ _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 4, 2, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -786,7 +786,7 @@ _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
ctx->Driver.UniformMatrix(ctx, 3, 4, location, count, transpose, value);
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
const GLfloat *value)
{
@@ -804,16 +804,16 @@ _mesa_UseProgramObjectARB(GLhandleARB program)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ValidateProgramARB(GLhandleARB program)
{
GET_CURRENT_CONTEXT(ctx);
ctx->Driver.ValidateProgram(ctx, program);
}
-#ifdef FEATURE_ES2
+#if FEATURE_ES2
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
GLint* range, GLint* precision)
{
@@ -822,7 +822,7 @@ _mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ReleaseShaderCompiler(void)
{
GET_CURRENT_CONTEXT(ctx);
@@ -830,7 +830,7 @@ _mesa_ReleaseShaderCompiler(void)
}
-static void GLAPIENTRY
+void GLAPIENTRY
_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
const void* binary, GLint length)
{
@@ -847,6 +847,7 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
void
_mesa_init_shader_dispatch(struct _glapi_table *exec)
{
+#if FEATURE_GL
/* GL_ARB_vertex/fragment_shader */
SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB);
SET_GetHandleARB(exec, _mesa_GetHandleARB);
@@ -917,13 +918,6 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
#endif
-#ifdef FEATURE_ES2
- /* XXX finish dispatch */
- (void) _mesa_GetShaderPrecisionFormat;
- (void) _mesa_ReleaseShaderCompiler;
- (void) _mesa_ShaderBinary;
-#endif
-
/* OpenGL 3.0 */
/* XXX finish dispatch */
(void) _mesa_Uniform1ui;
@@ -934,4 +928,5 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec)
(void) _mesa_Uniform2uiv;
(void) _mesa_Uniform3uiv;
(void) _mesa_Uniform4uiv;
+#endif /* FEATURE_GL */
}
diff --git a/src/mesa/main/shaders.h b/src/mesa/main/shaders.h
index 24c381bd52..af65b2d01a 100644
--- a/src/mesa/main/shaders.h
+++ b/src/mesa/main/shaders.h
@@ -30,12 +30,245 @@
#include "glheader.h"
#include "mtypes.h"
+extern void
+_mesa_init_shader_dispatch(struct _glapi_table *exec);
extern void GLAPIENTRY
-_mesa_UseProgramObjectARB(GLhandleARB program);
+_mesa_DeleteObjectARB(GLhandleARB obj);
-extern void
-_mesa_init_shader_dispatch(struct _glapi_table *exec);
+extern GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname);
+
+extern void GLAPIENTRY
+_mesa_DetachObjectARB (GLhandleARB, GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB (GLenum);
+
+extern void GLAPIENTRY
+_mesa_ShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_CompileShaderARB (GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB (void);
+
+extern void GLAPIENTRY
+_mesa_AttachObjectARB (GLhandleARB, GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_LinkProgramARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_UseProgramObjectARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_ValidateProgramARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fARB (GLint, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fARB (GLint, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fARB (GLint, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform1iARB (GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform2iARB (GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform3iARB (GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform4iARB (GLint, GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ui(GLint location, GLuint v0);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+
+extern void GLAPIENTRY
+_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value);
+
+extern void GLAPIENTRY
+_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value);
+
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+extern void GLAPIENTRY
+_mesa_UniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterivARB (GLhandleARB, GLenum, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetUniformLocationARB (GLhandleARB, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformfvARB (GLhandleARB, GLint, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformivARB (GLhandleARB, GLint, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+#if FEATURE_ARB_vertex_shader
+
+extern void GLAPIENTRY
+_mesa_BindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
+
+#endif /* FEATURE_ARB_vertex_shader */
+
+
+/* 2.0 */
+extern void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateProgram(void);
+
+extern void GLAPIENTRY
+_mesa_DeleteProgram(GLuint program);
+
+extern void GLAPIENTRY
+_mesa_DeleteShader(GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+ GLsizei *count, GLuint *obj);
+
+extern void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+extern void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint program);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint shader);
+
+
+
+/* 2.1 */
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+/* GLES 2.0 */
+extern void GLAPIENTRY
+_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype,
+ GLint* range, GLint* precision);
+
+extern void GLAPIENTRY
+_mesa_ReleaseShaderCompiler(void);
+
+extern void GLAPIENTRY
+_mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat,
+ const void* binary, GLint length);
#endif /* SHADERS_H */
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index f66c240ce7..05aae83f0c 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -876,7 +876,7 @@ binary(GLbitfield64 val)
static char buf[80];
GLint i, len = 0;
for (i = 63; i >= 0; --i) {
- if (val & (1ULL << i))
+ if (val & (BITFIELD64_BIT(i)))
buf[len++] = '1';
else if (len > 0 || i == 0)
buf[len++] = '0';
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
index 99c4b2baa5..7da7226c32 100644
--- a/src/mesa/shader/program_parse.tab.c
+++ b/src/mesa/shader/program_parse.tab.c
@@ -3366,7 +3366,7 @@ yyreduce:
s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
- s->param_binding_swizzle = SWIZZLE_XYZW;
+ s->param_binding_swizzle = (yyvsp[(3) - (3)].temp_sym).param_binding_swizzle;
s->param_is_array = 0;
}
;}
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index 06c2db7a07..a2f34b863b 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -1219,7 +1219,7 @@ PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
s->param_binding_type = $3.param_binding_type;
s->param_binding_begin = $3.param_binding_begin;
s->param_binding_length = $3.param_binding_length;
- s->param_binding_swizzle = SWIZZLE_XYZW;
+ s->param_binding_swizzle = $3.param_binding_swizzle;
s->param_is_array = 0;
}
}
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index cebe899265..c414e89825 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -41,12 +41,11 @@
#include "main/hash.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
-#include "shader/prog_statevars.h"
#include "shader/prog_uniform.h"
#include "shader/shader_api.h"
+#include "shader/uniforms.h"
#include "shader/slang/slang_compile.h"
#include "shader/slang/slang_link.h"
-#include "main/dispatch.h"
/**
@@ -222,7 +221,7 @@ _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
/**
* As above, but record an error if program is not found.
*/
-static struct gl_shader_program *
+struct gl_shader_program *
_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
const char *caller)
{
@@ -840,77 +839,6 @@ _mesa_sizeof_glsl_type(GLenum type)
}
-static GLenum
-base_uniform_type(GLenum type)
-{
- switch (type) {
-#if 0 /* not needed, for now */
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- return GL_BOOL;
-#endif
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- return GL_FLOAT;
- case GL_UNSIGNED_INT:
- case GL_UNSIGNED_INT_VEC2:
- case GL_UNSIGNED_INT_VEC3:
- case GL_UNSIGNED_INT_VEC4:
- return GL_UNSIGNED_INT;
- case GL_INT:
- case GL_INT_VEC2:
- case GL_INT_VEC3:
- case GL_INT_VEC4:
- return GL_INT;
- default:
- _mesa_problem(NULL, "Invalid type in base_uniform_type()");
- return GL_FLOAT;
- }
-}
-
-
-static GLboolean
-is_boolean_type(GLenum type)
-{
- switch (type) {
- case GL_BOOL:
- case GL_BOOL_VEC2:
- case GL_BOOL_VEC3:
- case GL_BOOL_VEC4:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-static GLboolean
-is_sampler_type(GLenum type)
-{
- switch (type) {
- case GL_SAMPLER_1D:
- case GL_SAMPLER_2D:
- case GL_SAMPLER_3D:
- case GL_SAMPLER_CUBE:
- case GL_SAMPLER_1D_SHADOW:
- case GL_SAMPLER_2D_SHADOW:
- case GL_SAMPLER_2D_RECT_ARB:
- case GL_SAMPLER_2D_RECT_SHADOW_ARB:
- case GL_SAMPLER_1D_ARRAY_EXT:
- case GL_SAMPLER_2D_ARRAY_EXT:
- case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
- case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
static void
_mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
GLsizei maxLength, GLsizei *length, GLint *size,
@@ -943,93 +871,6 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
}
-static struct gl_program_parameter *
-get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
-{
- const struct gl_program *prog = NULL;
- GLint progPos;
-
- progPos = shProg->Uniforms->Uniforms[index].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[index].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- }
- }
-
- if (!prog || progPos < 0)
- return NULL; /* should never happen */
-
- return &prog->Parameters->Parameters[progPos];
-}
-
-
-/**
- * Called via ctx->Driver.GetActiveUniform().
- */
-static void
-_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
- GLsizei maxLength, GLsizei *length, GLint *size,
- GLenum *type, GLchar *nameOut)
-{
- const struct gl_shader_program *shProg;
- const struct gl_program *prog = NULL;
- const struct gl_program_parameter *param;
- GLint progPos;
-
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
- if (!shProg)
- return;
-
- if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
- return;
- }
-
- progPos = shProg->Uniforms->Uniforms[index].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[index].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- }
- }
-
- if (!prog || progPos < 0)
- return; /* should never happen */
-
- ASSERT(progPos < prog->Parameters->NumParameters);
- param = &prog->Parameters->Parameters[progPos];
-
- if (nameOut) {
- _mesa_copy_string(nameOut, maxLength, length, param->Name);
- }
-
- if (size) {
- GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
- if ((GLint) param->Size > typeSize) {
- /* This is an array.
- * Array elements are placed on vector[4] boundaries so they're
- * a multiple of four floats. We round typeSize up to next multiple
- * of four to get the right size below.
- */
- typeSize = (typeSize + 3) & ~3;
- }
- /* Note that the returned size is in units of the <type>, not bytes */
- *size = param->Size / typeSize;
- }
-
- if (type) {
- *type = param->DataType;
- }
-}
-
-
/**
* Called via ctx->Driver.GetAttachedShaders().
*/
@@ -1050,21 +891,28 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount,
}
+/** glGetHandleARB() - return ID/name of currently bound shader program */
static GLuint
_mesa_get_handle(GLcontext *ctx, GLenum pname)
{
- GLint handle = 0;
-
if (pname == GL_PROGRAM_OBJECT_ARB) {
- CALL_GetIntegerv(ctx->Exec, (GL_CURRENT_PROGRAM, &handle));
- } else {
+ if (ctx->Shader.CurrentProgram)
+ return ctx->Shader.CurrentProgram->Name;
+ else
+ return 0;
+ }
+ else {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
+ return 0;
}
-
- return handle;
}
+/**
+ * glGetProgramiv() - get shader program state.
+ * Note that this is for GLSL shader programs, not ARB vertex/fragment
+ * programs (see glGetProgramivARB).
+ */
static void
_mesa_get_programiv(GLcontext *ctx, GLuint program,
GLenum pname, GLint *params)
@@ -1134,6 +982,7 @@ _mesa_get_programiv(GLcontext *ctx, GLuint program,
}
+/** glGetShaderiv() - get GLSL shader state */
static void
_mesa_get_shaderiv(GLcontext *ctx, GLuint name, GLenum pname, GLint *params)
{
@@ -1209,282 +1058,6 @@ _mesa_get_shader_source(GLcontext *ctx, GLuint shader, GLsizei maxLength,
}
-static void
-get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
-{
- switch (type) {
- case GL_FLOAT_MAT2:
- *rows = *cols = 2;
- break;
- case GL_FLOAT_MAT2x3:
- *rows = 3;
- *cols = 2;
- break;
- case GL_FLOAT_MAT2x4:
- *rows = 4;
- *cols = 2;
- break;
- case GL_FLOAT_MAT3:
- *rows = 3;
- *cols = 3;
- break;
- case GL_FLOAT_MAT3x2:
- *rows = 2;
- *cols = 3;
- break;
- case GL_FLOAT_MAT3x4:
- *rows = 4;
- *cols = 3;
- break;
- case GL_FLOAT_MAT4:
- *rows = 4;
- *cols = 4;
- break;
- case GL_FLOAT_MAT4x2:
- *rows = 2;
- *cols = 4;
- break;
- case GL_FLOAT_MAT4x3:
- *rows = 3;
- *cols = 4;
- break;
- default:
- *rows = *cols = 0;
- }
-}
-
-
-/**
- * Determine the number of rows and columns occupied by a uniform
- * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
- * the number of rows = 1 and cols = number of elements in the vector.
- */
-static void
-get_uniform_rows_cols(const struct gl_program_parameter *p,
- GLint *rows, GLint *cols)
-{
- get_matrix_dims(p->DataType, rows, cols);
- if (*rows == 0 && *cols == 0) {
- /* not a matrix type, probably a float or vector */
- if (p->Size <= 4) {
- *rows = 1;
- *cols = p->Size;
- }
- else {
- *rows = p->Size / 4 + 1;
- if (p->Size % 4 == 0)
- *cols = 4;
- else
- *cols = p->Size % 4;
- }
- }
-}
-
-
-/**
- * Helper for get_uniform[fi]v() functions.
- * Given a shader program name and uniform location, return a pointer
- * to the shader program and return the program parameter position.
- */
-static void
-lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
- struct gl_program **progOut, GLint *paramPosOut)
-{
- struct gl_shader_program *shProg
- = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
- struct gl_program *prog = NULL;
- GLint progPos = -1;
-
- /* if shProg is NULL, we'll have already recorded an error */
-
- if (shProg) {
- if (!shProg->Uniforms ||
- location < 0 ||
- location >= (GLint) shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
- }
- else {
- /* OK, find the gl_program and program parameter location */
- progPos = shProg->Uniforms->Uniforms[location].VertPos;
- if (progPos >= 0) {
- prog = &shProg->VertexProgram->Base;
- }
- else {
- progPos = shProg->Uniforms->Uniforms[location].FragPos;
- if (progPos >= 0) {
- prog = &shProg->FragmentProgram->Base;
- }
- }
- }
- }
-
- *progOut = prog;
- *paramPosOut = progPos;
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformfv().
- */
-static void
-_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
- GLfloat *params)
-{
- struct gl_program *prog;
- GLint paramPos;
-
- lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
-
- if (prog) {
- const struct gl_program_parameter *p =
- &prog->Parameters->Parameters[paramPos];
- GLint rows, cols, i, j, k;
-
- get_uniform_rows_cols(p, &rows, &cols);
-
- k = 0;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++ ) {
- params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
- }
- }
- }
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformiv().
- * \sa _mesa_get_uniformfv, only difference is a cast.
- */
-static void
-_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
- GLint *params)
-{
- struct gl_program *prog;
- GLint paramPos;
-
- lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
-
- if (prog) {
- const struct gl_program_parameter *p =
- &prog->Parameters->Parameters[paramPos];
- GLint rows, cols, i, j, k;
-
- get_uniform_rows_cols(p, &rows, &cols);
-
- k = 0;
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++ ) {
- params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
- }
- }
- }
-}
-
-
-/**
- * The value returned by GetUniformLocation actually encodes two things:
- * 1. the index into the prog->Uniforms[] array for the uniform
- * 2. an offset in the prog->ParameterValues[] array for specifying array
- * elements or structure fields.
- * This function merges those two values.
- */
-static void
-merge_location_offset(GLint *location, GLint offset)
-{
- *location = *location | (offset << 16);
-}
-
-
-/**
- * Seperate the uniform location and parameter offset. See above.
- */
-static void
-split_location_offset(GLint *location, GLint *offset)
-{
- *offset = (*location >> 16);
- *location = *location & 0xffff;
-}
-
-
-/**
- * Called via ctx->Driver.GetUniformLocation().
- *
- * The return value will encode two values, the uniform location and an
- * offset (used for arrays, structs).
- */
-static GLint
-_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
-{
- GLint offset = 0, location = -1;
-
- struct gl_shader_program *shProg =
- _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
-
- if (!shProg)
- return -1;
-
- if (shProg->LinkStatus == GL_FALSE) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
- return -1;
- }
-
- /* XXX we should return -1 if the uniform was declared, but not
- * actually used.
- */
-
- /* XXX we need to be able to parse uniform names for structs and arrays
- * such as:
- * mymatrix[1]
- * mystruct.field1
- */
-
- {
- /* handle 1-dimension arrays here... */
- char *c = strchr(name, '[');
- if (c) {
- /* truncate name at [ */
- const GLint len = c - name;
- GLchar *newName = malloc(len + 1);
- if (!newName)
- return -1; /* out of mem */
- memcpy(newName, name, len);
- newName[len] = 0;
-
- location = _mesa_lookup_uniform(shProg->Uniforms, newName);
- if (location >= 0) {
- const GLint element = atoi(c + 1);
- if (element > 0) {
- /* get type of the uniform array element */
- struct gl_program_parameter *p;
- p = get_uniform_parameter(shProg, location);
- if (p) {
- GLint rows, cols;
- get_matrix_dims(p->DataType, &rows, &cols);
- if (rows < 1)
- rows = 1;
- offset = element * rows;
- }
- }
- }
-
- free(newName);
- }
- }
-
- if (location < 0) {
- location = _mesa_lookup_uniform(shProg->Uniforms, name);
- }
-
- if (location >= 0) {
- merge_location_offset(&location, offset);
- }
-
- return location;
-}
-
-
-
/**
* Called via ctx->Driver.ShaderSource()
*/
@@ -1692,422 +1265,6 @@ _mesa_update_shader_textures_used(struct gl_program *prog)
/**
- * Check if the type given by userType is allowed to set a uniform of the
- * target type. Generally, equivalence is required, but setting Boolean
- * uniforms can be done with glUniformiv or glUniformfv.
- */
-static GLboolean
-compatible_types(GLenum userType, GLenum targetType)
-{
- if (userType == targetType)
- return GL_TRUE;
-
- if (targetType == GL_BOOL && (userType == GL_FLOAT ||
- userType == GL_UNSIGNED_INT ||
- userType == GL_INT))
- return GL_TRUE;
-
- if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
- userType == GL_UNSIGNED_INT_VEC2 ||
- userType == GL_INT_VEC2))
- return GL_TRUE;
-
- if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
- userType == GL_UNSIGNED_INT_VEC3 ||
- userType == GL_INT_VEC3))
- return GL_TRUE;
-
- if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
- userType == GL_UNSIGNED_INT_VEC4 ||
- userType == GL_INT_VEC4))
- return GL_TRUE;
-
- if (is_sampler_type(targetType) && userType == GL_INT)
- return GL_TRUE;
-
- return GL_FALSE;
-}
-
-
-/**
- * Set the value of a program's uniform variable.
- * \param program the program whose uniform to update
- * \param index the index of the program parameter for the uniform
- * \param offset additional parameter slot offset (for arrays)
- * \param type the incoming datatype of 'values'
- * \param count the number of uniforms to set
- * \param elems number of elements per uniform (1, 2, 3 or 4)
- * \param values the new values, of datatype 'type'
- */
-static void
-set_program_uniform(GLcontext *ctx, struct gl_program *program,
- GLint index, GLint offset,
- GLenum type, GLsizei count, GLint elems,
- const void *values)
-{
- const struct gl_program_parameter *param =
- &program->Parameters->Parameters[index];
-
- assert(offset >= 0);
- assert(elems >= 1);
- assert(elems <= 4);
-
- if (!compatible_types(type, param->DataType)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
- return;
- }
-
- if (index + offset > (GLint) program->Parameters->Size) {
- /* out of bounds! */
- return;
- }
-
- if (param->Type == PROGRAM_SAMPLER) {
- /* This controls which texture unit which is used by a sampler */
- GLboolean changed = GL_FALSE;
- GLint i;
-
- /* this should have been caught by the compatible_types() check */
- ASSERT(type == GL_INT);
-
- /* loop over number of samplers to change */
- for (i = 0; i < count; i++) {
- GLuint sampler =
- (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
- GLuint texUnit = ((GLuint *) values)[i];
-
- /* check that the sampler (tex unit index) is legal */
- if (texUnit >= ctx->Const.MaxTextureImageUnits) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glUniform1(invalid sampler/tex unit index for '%s')",
- param->Name);
- return;
- }
-
- /* This maps a sampler to a texture unit: */
- if (sampler < MAX_SAMPLERS) {
-#if 0
- printf("Set program %p sampler %d '%s' to unit %u\n",
- program, sampler, param->Name, texUnit);
-#endif
- if (program->SamplerUnits[sampler] != texUnit) {
- program->SamplerUnits[sampler] = texUnit;
- changed = GL_TRUE;
- }
- }
- }
-
- if (changed) {
- /* When a sampler's value changes it usually requires rewriting
- * a GPU program's TEX instructions since there may not be a
- * sampler->texture lookup table. We signal this with the
- * ProgramStringNotify() callback.
- */
- FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
- _mesa_update_shader_textures_used(program);
- /* Do we need to care about the return value here?
- * This should not be the first time the driver was notified of
- * this program.
- */
- (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
- }
- }
- else {
- /* ordinary uniform variable */
- const GLboolean isUniformBool = is_boolean_type(param->DataType);
- const GLenum basicType = base_uniform_type(type);
- const GLint slots = (param->Size + 3) / 4;
- const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
- GLsizei k, i;
-
- if ((GLint) param->Size > typeSize) {
- /* an array */
- /* we'll ignore extra data below */
- }
- else {
- /* non-array: count must be at most one; count == 0 is handled by the loop below */
- if (count > 1) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniform(uniform '%s' is not an array)",
- param->Name);
- return;
- }
- }
-
- /* loop over number of array elements */
- for (k = 0; k < count; k++) {
- GLfloat *uniformVal;
-
- if (offset + k >= slots) {
- /* Extra array data is ignored */
- break;
- }
-
- /* uniformVal (the destination) is always float[4] */
- uniformVal = program->Parameters->ParameterValues[index + offset + k];
-
- if (basicType == GL_INT) {
- /* convert user's ints to floats */
- const GLint *iValues = ((const GLint *) values) + k * elems;
- for (i = 0; i < elems; i++) {
- uniformVal[i] = (GLfloat) iValues[i];
- }
- }
- else if (basicType == GL_UNSIGNED_INT) {
- /* convert user's uints to floats */
- const GLuint *iValues = ((const GLuint *) values) + k * elems;
- for (i = 0; i < elems; i++) {
- uniformVal[i] = (GLfloat) iValues[i];
- }
- }
- else {
- const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
- assert(basicType == GL_FLOAT);
- for (i = 0; i < elems; i++) {
- uniformVal[i] = fValues[i];
- }
- }
-
- /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
- if (isUniformBool) {
- for (i = 0; i < elems; i++) {
- uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
- }
- }
- }
- }
-}
-
-
-/**
- * Called via ctx->Driver.Uniform().
- */
-static void
-_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
- const GLvoid *values, GLenum type)
-{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- struct gl_uniform *uniform;
- GLint elems, offset;
-
- if (!shProg || !shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
- return;
- }
-
- if (location == -1)
- return; /* The standard specifies this as a no-op */
-
- if (location < -1) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
- location);
- return;
- }
-
- split_location_offset(&location, &offset);
-
- if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
- return;
- }
-
- if (count < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
- return;
- }
-
- elems = _mesa_sizeof_glsl_type(type);
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
- uniform = &shProg->Uniforms->Uniforms[location];
-
- if (ctx->Shader.Flags & GLSL_UNIFORMS) {
- const GLenum basicType = base_uniform_type(type);
- GLint i;
- printf("Mesa: set program %u uniform %s (loc %d) to: ",
- shProg->Name, uniform->Name, location);
- if (basicType == GL_INT) {
- const GLint *v = (const GLint *) values;
- for (i = 0; i < count * elems; i++) {
- printf("%d ", v[i]);
- }
- }
- else if (basicType == GL_UNSIGNED_INT) {
- const GLuint *v = (const GLuint *) values;
- for (i = 0; i < count * elems; i++) {
- printf("%u ", v[i]);
- }
- }
- else {
- const GLfloat *v = (const GLfloat *) values;
- assert(basicType == GL_FLOAT);
- for (i = 0; i < count * elems; i++) {
- printf("%g ", v[i]);
- }
- }
- printf("\n");
- }
-
- /* A uniform var may be used by both a vertex shader and a fragment
- * shader. We may need to update one or both shader's uniform here:
- */
- if (shProg->VertexProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->VertPos;
- if (index >= 0) {
- set_program_uniform(ctx, &shProg->VertexProgram->Base,
- index, offset, type, count, elems, values);
- }
- }
-
- if (shProg->FragmentProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->FragPos;
- if (index >= 0) {
- set_program_uniform(ctx, &shProg->FragmentProgram->Base,
- index, offset, type, count, elems, values);
- }
- }
-
- uniform->Initialized = GL_TRUE;
-}
-
-
-/**
- * Set a matrix-valued program parameter.
- */
-static void
-set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
- GLuint index, GLuint offset,
- GLuint count, GLuint rows, GLuint cols,
- GLboolean transpose, const GLfloat *values)
-{
- GLuint mat, row, col;
- GLuint src = 0;
- const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
- const GLuint slots = (param->Size + 3) / 4;
- const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
- GLint nr, nc;
-
- /* check that the number of rows, columns is correct */
- get_matrix_dims(param->DataType, &nr, &nc);
- if (rows != nr || cols != nc) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniformMatrix(matrix size mismatch)");
- return;
- }
-
- if ((GLint) param->Size <= typeSize) {
- /* non-array: count must be at most one; count == 0 is handled by the loop below */
- if (count > 1) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniformMatrix(uniform is not an array)");
- return;
- }
- }
-
- /*
- * Note: the _columns_ of a matrix are stored in program registers, not
- * the rows. So, the loops below look a little funny.
- * XXX could optimize this a bit...
- */
-
- /* loop over matrices */
- for (mat = 0; mat < count; mat++) {
-
- /* each matrix: */
- for (col = 0; col < cols; col++) {
- GLfloat *v;
- if (offset >= slots) {
- /* Ignore writes beyond the end of (the used part of) an array */
- return;
- }
- v = program->Parameters->ParameterValues[index + offset];
- for (row = 0; row < rows; row++) {
- if (transpose) {
- v[row] = values[src + row * cols + col];
- }
- else {
- v[row] = values[src + col * rows + row];
- }
- }
-
- offset++;
- }
-
- src += rows * cols; /* next matrix */
- }
-}
-
-
-/**
- * Called by ctx->Driver.UniformMatrix().
- * Note: cols=2, rows=4 ==> array[2] of vec4
- */
-static void
-_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
- GLint location, GLsizei count,
- GLboolean transpose, const GLfloat *values)
-{
- struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
- struct gl_uniform *uniform;
- GLint offset;
-
- if (!shProg || !shProg->LinkStatus) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniformMatrix(program not linked)");
- return;
- }
-
- if (location == -1)
- return; /* The standard specifies this as a no-op */
-
- if (location < -1) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
- return;
- }
-
- split_location_offset(&location, &offset);
-
- if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
- return;
- }
- if (values == NULL) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
- return;
- }
-
- FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
-
- uniform = &shProg->Uniforms->Uniforms[location];
-
- if (shProg->VertexProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->VertPos;
- if (index >= 0) {
- set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
- index, offset,
- count, rows, cols, transpose, values);
- }
- }
-
- if (shProg->FragmentProgram) {
- /* convert uniform location to program parameter index */
- GLint index = uniform->FragPos;
- if (index >= 0) {
- set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
- index, offset,
- count, rows, cols, transpose, values);
- }
- }
-
- uniform->Initialized = GL_TRUE;
-}
-
-
-/**
* Validate a program's samplers.
* Specifically, check that there aren't two samplers of different types
* pointing to the same texture unit.
@@ -2248,7 +1405,6 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
driver->DeleteShader = _mesa_delete_shader;
driver->DetachShader = _mesa_detach_shader;
driver->GetActiveAttrib = _mesa_get_active_attrib;
- driver->GetActiveUniform = _mesa_get_active_uniform;
driver->GetAttachedShaders = _mesa_get_attached_shaders;
driver->GetAttribLocation = _mesa_get_attrib_location;
driver->GetHandle = _mesa_get_handle;
@@ -2257,15 +1413,12 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver)
driver->GetShaderiv = _mesa_get_shaderiv;
driver->GetShaderInfoLog = _mesa_get_shader_info_log;
driver->GetShaderSource = _mesa_get_shader_source;
- driver->GetUniformfv = _mesa_get_uniformfv;
- driver->GetUniformiv = _mesa_get_uniformiv;
- driver->GetUniformLocation = _mesa_get_uniform_location;
driver->IsProgram = _mesa_is_program;
driver->IsShader = _mesa_is_shader;
driver->LinkProgram = _mesa_link_program;
driver->ShaderSource = _mesa_shader_source;
- driver->Uniform = _mesa_uniform;
- driver->UniformMatrix = _mesa_uniform_matrix;
driver->UseProgram = _mesa_use_program;
driver->ValidateProgram = _mesa_validate_program;
+
+ _mesa_init_uniform_functions(driver);
}
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
index 597f0b8e75..9743a23ce6 100644
--- a/src/mesa/shader/shader_api.h
+++ b/src/mesa/shader/shader_api.h
@@ -75,6 +75,10 @@ extern struct gl_shader_program *
_mesa_lookup_shader_program(GLcontext *ctx, GLuint name);
+extern struct gl_shader_program *
+_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name,
+ const char *caller);
+
extern struct gl_shader *
_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type);
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 974c4a3131..4d4c611dfe 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -366,7 +366,7 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
st0->File = PROGRAM_TEMPORARY;
}
#endif
- assert(st->File < PROGRAM_UNDEFINED);
+ assert(st->File < PROGRAM_FILE_MAX);
src->File = st->File;
assert(index >= 0);
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 3d4208ce4c..2d003ef9c3 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -591,6 +591,108 @@ _slang_count_temporaries(struct gl_program *prog)
/**
+ * If an input attribute is indexed with relative addressing we have
+ * to compute a gl_program::InputsRead bitmask which reflects the fact
+ * that any input may be referenced by array element. Ex: gl_TexCoord[i].
+ * This function computes the bitmask of potentially read inputs.
+ */
+static GLbitfield
+get_inputs_read_mask(GLenum target, GLuint index, GLboolean relAddr)
+{
+ GLbitfield mask;
+
+ mask = 1 << index;
+
+ if (relAddr) {
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ switch (index) {
+ case VERT_ATTRIB_TEX0:
+ mask = ((1U << (VERT_ATTRIB_TEX7 + 1)) - 1)
+ - ((1U << VERT_ATTRIB_TEX0) - 1);
+ break;
+ case VERT_ATTRIB_GENERIC0:
+ /* different code to avoid uint overflow */
+ mask = ~0x0U - ((1U << VERT_ATTRIB_GENERIC0) - 1);
+ break;
+ default:
+ ; /* a non-array input attribute */
+ }
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ switch (index) {
+ case FRAG_ATTRIB_TEX0:
+ mask = ((1U << (FRAG_ATTRIB_TEX7 + 1)) - 1)
+ - ((1U << FRAG_ATTRIB_TEX0) - 1);
+ break;
+ case FRAG_ATTRIB_VAR0:
+ mask = ((1U << (FRAG_ATTRIB_VAR0 + MAX_VARYING)) - 1)
+ - ((1U << FRAG_ATTRIB_VAR0) - 1);
+ break;
+ default:
+ ; /* a non-array input attribute */
+ }
+ }
+ else {
+ assert(0 && "bad program target");
+ }
+ }
+ else {
+ }
+
+ return mask;
+}
+
+
+/**
+ * If an output attribute is indexed with relative addressing we have
+ * to compute a gl_program::OutputsWritten bitmask which reflects the fact
+ * that any output may be referenced by array element. Ex: gl_TexCoord[i].
+ * This function computes the bitmask of potentially written outputs.
+ */
+static GLbitfield64
+get_outputs_written_mask(GLenum target, GLuint index, GLboolean relAddr)
+{
+ GLbitfield64 mask;
+
+ mask = BITFIELD64_BIT(index);
+
+ if (relAddr) {
+ if (target == GL_VERTEX_PROGRAM_ARB) {
+ switch (index) {
+ case VERT_RESULT_TEX0:
+ mask = BITFIELD64_RANGE(VERT_RESULT_TEX0,
+ (VERT_RESULT_TEX0
+ + MAX_TEXTURE_COORD_UNITS - 1));
+ break;
+ case VERT_RESULT_VAR0:
+ mask = BITFIELD64_RANGE(VERT_RESULT_VAR0,
+ (VERT_RESULT_VAR0 + MAX_VARYING - 1));
+ break;
+ default:
+ ; /* a non-array output attribute */
+ }
+ }
+ else if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ switch (index) {
+ case FRAG_RESULT_DATA0:
+ mask = BITFIELD64_RANGE(FRAG_RESULT_DATA0,
+ (FRAG_RESULT_DATA0
+ + MAX_DRAW_BUFFERS - 1));
+ break;
+ default:
+ ; /* a non-array output attribute */
+ }
+ }
+ else {
+ assert(0 && "bad program target");
+ }
+ }
+
+ return mask;
+}
+
+
+/**
* Scan program instructions to update the program's InputsRead and
* OutputsWritten fields.
*/
@@ -608,7 +710,9 @@ _slang_update_inputs_outputs(struct gl_program *prog)
const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
for (j = 0; j < numSrc; j++) {
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
- prog->InputsRead |= 1 << inst->SrcReg[j].Index;
+ prog->InputsRead |= get_inputs_read_mask(prog->Target,
+ inst->SrcReg[j].Index,
+ inst->SrcReg[j].RelAddr);
}
else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
@@ -616,34 +720,9 @@ _slang_update_inputs_outputs(struct gl_program *prog)
}
if (inst->DstReg.File == PROGRAM_OUTPUT) {
- prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index);
- if (inst->DstReg.RelAddr) {
- /* If the output attribute is indexed with relative addressing
- * we know that it must be a varying or texcoord such as
- * gl_TexCoord[i] = v; In this case, mark all the texcoords
- * or varying outputs as being written. It's not an error if
- * a vertex shader writes varying vars that aren't used by the
- * fragment shader. But it is an error for a fragment shader
- * to use varyings that are not written by the vertex shader.
- */
- if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
- if (inst->DstReg.Index == VERT_RESULT_TEX0) {
- /* mark all texcoord outputs as written */
- const GLbitfield64 mask =
- BITFIELD64_RANGE(VERT_RESULT_TEX0,
- (VERT_RESULT_TEX0
- + MAX_TEXTURE_COORD_UNITS - 1));
- prog->OutputsWritten |= mask;
- }
- else if (inst->DstReg.Index == VERT_RESULT_VAR0) {
- /* mark all generic varying outputs as written */
- const GLbitfield64 mask =
- BITFIELD64_RANGE(VERT_RESULT_VAR0,
- (VERT_RESULT_VAR0 + MAX_VARYING - 1));
- prog->OutputsWritten |= mask;
- }
- }
- }
+ prog->OutputsWritten |= get_outputs_written_mask(prog->Target,
+ inst->DstReg.Index,
+ inst->DstReg.RelAddr);
}
else if (inst->DstReg.File == PROGRAM_ADDRESS) {
maxAddrReg = MAX2(maxAddrReg, inst->DstReg.Index + 1);
diff --git a/src/mesa/shader/uniforms.c b/src/mesa/shader/uniforms.c
new file mode 100644
index 0000000000..b1fb90d020
--- /dev/null
+++ b/src/mesa/shader/uniforms.c
@@ -0,0 +1,937 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009-2010 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, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file uniforms.c
+ * Functions related to GLSL uniform variables.
+ * \author Brian Paul
+ */
+
+/**
+ * XXX things to do:
+ * 1. Check that the right error code is generated for all _mesa_error() calls.
+ * 2. Insert FLUSH_VERTICES calls in various places
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_statevars.h"
+#include "shader/prog_uniform.h"
+#include "shader/shader_api.h"
+#include "uniforms.h"
+
+
+
+static GLenum
+base_uniform_type(GLenum type)
+{
+ switch (type) {
+#if 0 /* not needed, for now */
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return GL_BOOL;
+#endif
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ return GL_FLOAT;
+ case GL_UNSIGNED_INT:
+ case GL_UNSIGNED_INT_VEC2:
+ case GL_UNSIGNED_INT_VEC3:
+ case GL_UNSIGNED_INT_VEC4:
+ return GL_UNSIGNED_INT;
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ return GL_INT;
+ default:
+ _mesa_problem(NULL, "Invalid type in base_uniform_type()");
+ return GL_FLOAT;
+ }
+}
+
+
+static GLboolean
+is_boolean_type(GLenum type)
+{
+ switch (type) {
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+static GLboolean
+is_sampler_type(GLenum type)
+{
+ switch (type) {
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_1D_SHADOW:
+ case GL_SAMPLER_2D_SHADOW:
+ case GL_SAMPLER_2D_RECT_ARB:
+ case GL_SAMPLER_2D_RECT_SHADOW_ARB:
+ case GL_SAMPLER_1D_ARRAY_EXT:
+ case GL_SAMPLER_2D_ARRAY_EXT:
+ case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
+ case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+static struct gl_program_parameter *
+get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
+{
+ const struct gl_program *prog = NULL;
+ GLint progPos;
+
+ progPos = shProg->Uniforms->Uniforms[index].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[index].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
+ }
+
+ if (!prog || progPos < 0)
+ return NULL; /* should never happen */
+
+ return &prog->Parameters->Parameters[progPos];
+}
+
+
+/**
+ * Called via ctx->Driver.GetActiveUniform().
+ */
+static void
+_mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
+ GLsizei maxLength, GLsizei *length, GLint *size,
+ GLenum *type, GLchar *nameOut)
+{
+ const struct gl_shader_program *shProg;
+ const struct gl_program *prog = NULL;
+ const struct gl_program_parameter *param;
+ GLint progPos;
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
+ if (!shProg)
+ return;
+
+ if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
+ return;
+ }
+
+ progPos = shProg->Uniforms->Uniforms[index].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[index].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
+ }
+
+ if (!prog || progPos < 0)
+ return; /* should never happen */
+
+ ASSERT(progPos < prog->Parameters->NumParameters);
+ param = &prog->Parameters->Parameters[progPos];
+
+ if (nameOut) {
+ _mesa_copy_string(nameOut, maxLength, length, param->Name);
+ }
+
+ if (size) {
+ GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+ if ((GLint) param->Size > typeSize) {
+ /* This is an array.
+ * Array elements are placed on vector[4] boundaries so they're
+ * a multiple of four floats. We round typeSize up to next multiple
+ * of four to get the right size below.
+ */
+ typeSize = (typeSize + 3) & ~3;
+ }
+ /* Note that the returned size is in units of the <type>, not bytes */
+ *size = param->Size / typeSize;
+ }
+
+ if (type) {
+ *type = param->DataType;
+ }
+}
+
+
+
+static void
+get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
+{
+ switch (type) {
+ case GL_FLOAT_MAT2:
+ *rows = *cols = 2;
+ break;
+ case GL_FLOAT_MAT2x3:
+ *rows = 3;
+ *cols = 2;
+ break;
+ case GL_FLOAT_MAT2x4:
+ *rows = 4;
+ *cols = 2;
+ break;
+ case GL_FLOAT_MAT3:
+ *rows = 3;
+ *cols = 3;
+ break;
+ case GL_FLOAT_MAT3x2:
+ *rows = 2;
+ *cols = 3;
+ break;
+ case GL_FLOAT_MAT3x4:
+ *rows = 4;
+ *cols = 3;
+ break;
+ case GL_FLOAT_MAT4:
+ *rows = 4;
+ *cols = 4;
+ break;
+ case GL_FLOAT_MAT4x2:
+ *rows = 2;
+ *cols = 4;
+ break;
+ case GL_FLOAT_MAT4x3:
+ *rows = 3;
+ *cols = 4;
+ break;
+ default:
+ *rows = *cols = 0;
+ }
+}
+
+
+/**
+ * Determine the number of rows and columns occupied by a uniform
+ * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
+ * the number of rows = 1 and cols = number of elements in the vector.
+ */
+static void
+get_uniform_rows_cols(const struct gl_program_parameter *p,
+ GLint *rows, GLint *cols)
+{
+ get_matrix_dims(p->DataType, rows, cols);
+ if (*rows == 0 && *cols == 0) {
+ /* not a matrix type, probably a float or vector */
+ if (p->Size <= 4) {
+ *rows = 1;
+ *cols = p->Size;
+ }
+ else {
+ *rows = p->Size / 4 + 1;
+ if (p->Size % 4 == 0)
+ *cols = 4;
+ else
+ *cols = p->Size % 4;
+ }
+ }
+}
+
+
+/**
+ * Helper for get_uniform[fi]v() functions.
+ * Given a shader program name and uniform location, return a pointer
+ * to the shader program and return the program parameter position.
+ */
+static void
+lookup_uniform_parameter(GLcontext *ctx, GLuint program, GLint location,
+ struct gl_program **progOut, GLint *paramPosOut)
+{
+ struct gl_shader_program *shProg
+ = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
+ struct gl_program *prog = NULL;
+ GLint progPos = -1;
+
+ /* if shProg is NULL, we'll have already recorded an error */
+
+ if (shProg) {
+ if (!shProg->Uniforms ||
+ location < 0 ||
+ location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
+ }
+ else {
+ /* OK, find the gl_program and program parameter location */
+ progPos = shProg->Uniforms->Uniforms[location].VertPos;
+ if (progPos >= 0) {
+ prog = &shProg->VertexProgram->Base;
+ }
+ else {
+ progPos = shProg->Uniforms->Uniforms[location].FragPos;
+ if (progPos >= 0) {
+ prog = &shProg->FragmentProgram->Base;
+ }
+ }
+ }
+ }
+
+ *progOut = prog;
+ *paramPosOut = progPos;
+}
+
+
+/**
+ * GLGL uniform arrays and structs require special handling.
+ *
+ * The GL_ARB_shader_objects spec says that if you use
+ * glGetUniformLocation to get the location of an array, you CANNOT
+ * access other elements of the array by adding an offset to the
+ * returned location. For example, you must call
+ * glGetUniformLocation("foo[16]") if you want to set the 16th element
+ * of the array with glUniform().
+ *
+ * HOWEVER, some other OpenGL drivers allow accessing array elements
+ * by adding an offset to the returned array location. And some apps
+ * seem to depend on that behaviour.
+ *
+ * Mesa's gl_uniform_list doesn't directly support this since each
+ * entry in the list describes one uniform variable, not one uniform
+ * element. We could insert dummy entries in the list for each array
+ * element after [0] but that causes complications elsewhere.
+ *
+ * We solve this problem by encoding two values in the location that's
+ * returned by glGetUniformLocation():
+ * a) index into gl_uniform_list::Uniforms[] for the uniform
+ * b) an array/field offset (0 for simple types)
+ *
+ * These two values are encoded in the high and low halves of a GLint.
+ * By putting the uniform number in the high part and the offset in the
+ * low part, we can support the unofficial ability to index into arrays
+ * by adding offsets to the location value.
+ */
+static void
+merge_location_offset(GLint *location, GLint offset)
+{
+ *location = (*location << 16) | offset;
+}
+
+
+/**
+ * Separate the uniform location and parameter offset. See above.
+ */
+static void
+split_location_offset(GLint *location, GLint *offset)
+{
+ *offset = *location & 0xffff;
+ *location = *location >> 16;
+}
+
+
+
+/**
+ * Called via ctx->Driver.GetUniformfv().
+ */
+static void
+_mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location,
+ GLfloat *params)
+{
+ struct gl_program *prog;
+ GLint paramPos;
+ GLint offset;
+
+ split_location_offset(&location, &offset);
+
+ lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+ if (prog) {
+ const struct gl_program_parameter *p =
+ &prog->Parameters->Parameters[paramPos];
+ GLint rows, cols, i, j, k;
+
+ get_uniform_rows_cols(p, &rows, &cols);
+
+ k = 0;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++ ) {
+ params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformiv().
+ * \sa _mesa_get_uniformfv, only difference is a cast.
+ */
+static void
+_mesa_get_uniformiv(GLcontext *ctx, GLuint program, GLint location,
+ GLint *params)
+{
+ struct gl_program *prog;
+ GLint paramPos;
+ GLint offset;
+
+ split_location_offset(&location, &offset);
+
+ lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
+
+ if (prog) {
+ const struct gl_program_parameter *p =
+ &prog->Parameters->Parameters[paramPos];
+ GLint rows, cols, i, j, k;
+
+ get_uniform_rows_cols(p, &rows, &cols);
+
+ k = 0;
+ for (i = 0; i < rows; i++) {
+ for (j = 0; j < cols; j++ ) {
+ params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.GetUniformLocation().
+ *
+ * The return value will encode two values, the uniform location and an
+ * offset (used for arrays, structs).
+ */
+static GLint
+_mesa_get_uniform_location(GLcontext *ctx, GLuint program, const GLchar *name)
+{
+ GLint offset = 0, location = -1;
+
+ struct gl_shader_program *shProg =
+ _mesa_lookup_shader_program_err(ctx, program, "glGetUniformLocation");
+
+ if (!shProg)
+ return -1;
+
+ if (shProg->LinkStatus == GL_FALSE) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
+ return -1;
+ }
+
+ /* XXX we should return -1 if the uniform was declared, but not
+ * actually used.
+ */
+
+ /* XXX we need to be able to parse uniform names for structs and arrays
+ * such as:
+ * mymatrix[1]
+ * mystruct.field1
+ */
+
+ {
+ /* handle 1-dimension arrays here... */
+ char *c = strchr(name, '[');
+ if (c) {
+ /* truncate name at [ */
+ const GLint len = c - name;
+ GLchar *newName = malloc(len + 1);
+ if (!newName)
+ return -1; /* out of mem */
+ memcpy(newName, name, len);
+ newName[len] = 0;
+
+ location = _mesa_lookup_uniform(shProg->Uniforms, newName);
+ if (location >= 0) {
+ const GLint element = atoi(c + 1);
+ if (element > 0) {
+ /* get type of the uniform array element */
+ struct gl_program_parameter *p;
+ p = get_uniform_parameter(shProg, location);
+ if (p) {
+ GLint rows, cols;
+ get_matrix_dims(p->DataType, &rows, &cols);
+ if (rows < 1)
+ rows = 1;
+ offset = element * rows;
+ }
+ }
+ }
+
+ free(newName);
+ }
+ }
+
+ if (location < 0) {
+ location = _mesa_lookup_uniform(shProg->Uniforms, name);
+ }
+
+ if (location >= 0) {
+ merge_location_offset(&location, offset);
+ }
+
+ return location;
+}
+
+
+/**
+ * Check if the type given by userType is allowed to set a uniform of the
+ * target type. Generally, equivalence is required, but setting Boolean
+ * uniforms can be done with glUniformiv or glUniformfv.
+ */
+static GLboolean
+compatible_types(GLenum userType, GLenum targetType)
+{
+ if (userType == targetType)
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL && (userType == GL_FLOAT ||
+ userType == GL_UNSIGNED_INT ||
+ userType == GL_INT))
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
+ userType == GL_UNSIGNED_INT_VEC2 ||
+ userType == GL_INT_VEC2))
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
+ userType == GL_UNSIGNED_INT_VEC3 ||
+ userType == GL_INT_VEC3))
+ return GL_TRUE;
+
+ if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
+ userType == GL_UNSIGNED_INT_VEC4 ||
+ userType == GL_INT_VEC4))
+ return GL_TRUE;
+
+ if (is_sampler_type(targetType) && userType == GL_INT)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Set the value of a program's uniform variable.
+ * \param program the program whose uniform to update
+ * \param index the index of the program parameter for the uniform
+ * \param offset additional parameter slot offset (for arrays)
+ * \param type the incoming datatype of 'values'
+ * \param count the number of uniforms to set
+ * \param elems number of elements per uniform (1, 2, 3 or 4)
+ * \param values the new values, of datatype 'type'
+ */
+static void
+set_program_uniform(GLcontext *ctx, struct gl_program *program,
+ GLint index, GLint offset,
+ GLenum type, GLsizei count, GLint elems,
+ const void *values)
+{
+ const struct gl_program_parameter *param =
+ &program->Parameters->Parameters[index];
+
+ assert(offset >= 0);
+ assert(elems >= 1);
+ assert(elems <= 4);
+
+ if (!compatible_types(type, param->DataType)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
+ return;
+ }
+
+ if (index + offset > (GLint) program->Parameters->Size) {
+ /* out of bounds! */
+ return;
+ }
+
+ if (param->Type == PROGRAM_SAMPLER) {
+ /* This controls which texture unit which is used by a sampler */
+ GLboolean changed = GL_FALSE;
+ GLint i;
+
+ /* this should have been caught by the compatible_types() check */
+ ASSERT(type == GL_INT);
+
+ /* loop over number of samplers to change */
+ for (i = 0; i < count; i++) {
+ GLuint sampler =
+ (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
+ GLuint texUnit = ((GLuint *) values)[i];
+
+ /* check that the sampler (tex unit index) is legal */
+ if (texUnit >= ctx->Const.MaxTextureImageUnits) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glUniform1(invalid sampler/tex unit index for '%s')",
+ param->Name);
+ return;
+ }
+
+ /* This maps a sampler to a texture unit: */
+ if (sampler < MAX_SAMPLERS) {
+#if 0
+ printf("Set program %p sampler %d '%s' to unit %u\n",
+ program, sampler, param->Name, texUnit);
+#endif
+ if (program->SamplerUnits[sampler] != texUnit) {
+ program->SamplerUnits[sampler] = texUnit;
+ changed = GL_TRUE;
+ }
+ }
+ }
+
+ if (changed) {
+ /* When a sampler's value changes it usually requires rewriting
+ * a GPU program's TEX instructions since there may not be a
+ * sampler->texture lookup table. We signal this with the
+ * ProgramStringNotify() callback.
+ */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
+ _mesa_update_shader_textures_used(program);
+ /* Do we need to care about the return value here?
+ * This should not be the first time the driver was notified of
+ * this program.
+ */
+ (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+ }
+ }
+ else {
+ /* ordinary uniform variable */
+ const GLboolean isUniformBool = is_boolean_type(param->DataType);
+ const GLenum basicType = base_uniform_type(type);
+ const GLint slots = (param->Size + 3) / 4;
+ const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+ GLsizei k, i;
+
+ if ((GLint) param->Size > typeSize) {
+ /* an array */
+ /* we'll ignore extra data below */
+ }
+ else {
+ /* non-array: count must be at most one; count == 0 is handled by the loop below */
+ if (count > 1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniform(uniform '%s' is not an array)",
+ param->Name);
+ return;
+ }
+ }
+
+ /* loop over number of array elements */
+ for (k = 0; k < count; k++) {
+ GLfloat *uniformVal;
+
+ if (offset + k >= slots) {
+ /* Extra array data is ignored */
+ break;
+ }
+
+ /* uniformVal (the destination) is always float[4] */
+ uniformVal = program->Parameters->ParameterValues[index + offset + k];
+
+ if (basicType == GL_INT) {
+ /* convert user's ints to floats */
+ const GLint *iValues = ((const GLint *) values) + k * elems;
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = (GLfloat) iValues[i];
+ }
+ }
+ else if (basicType == GL_UNSIGNED_INT) {
+ /* convert user's uints to floats */
+ const GLuint *iValues = ((const GLuint *) values) + k * elems;
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = (GLfloat) iValues[i];
+ }
+ }
+ else {
+ const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
+ assert(basicType == GL_FLOAT);
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = fValues[i];
+ }
+ }
+
+ /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
+ if (isUniformBool) {
+ for (i = 0; i < elems; i++) {
+ uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Called via ctx->Driver.Uniform().
+ */
+static void
+_mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
+ const GLvoid *values, GLenum type)
+{
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ struct gl_uniform *uniform;
+ GLint elems, offset;
+
+ if (!shProg || !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
+ return;
+ }
+
+ if (location == -1)
+ return; /* The standard specifies this as a no-op */
+
+ if (location < -1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
+ location);
+ return;
+ }
+
+ split_location_offset(&location, &offset);
+
+ if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
+ return;
+ }
+
+ if (count < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
+ return;
+ }
+
+ elems = _mesa_sizeof_glsl_type(type);
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+ uniform = &shProg->Uniforms->Uniforms[location];
+
+ if (ctx->Shader.Flags & GLSL_UNIFORMS) {
+ const GLenum basicType = base_uniform_type(type);
+ GLint i;
+ printf("Mesa: set program %u uniform %s (loc %d) to: ",
+ shProg->Name, uniform->Name, location);
+ if (basicType == GL_INT) {
+ const GLint *v = (const GLint *) values;
+ for (i = 0; i < count * elems; i++) {
+ printf("%d ", v[i]);
+ }
+ }
+ else if (basicType == GL_UNSIGNED_INT) {
+ const GLuint *v = (const GLuint *) values;
+ for (i = 0; i < count * elems; i++) {
+ printf("%u ", v[i]);
+ }
+ }
+ else {
+ const GLfloat *v = (const GLfloat *) values;
+ assert(basicType == GL_FLOAT);
+ for (i = 0; i < count * elems; i++) {
+ printf("%g ", v[i]);
+ }
+ }
+ printf("\n");
+ }
+
+ /* A uniform var may be used by both a vertex shader and a fragment
+ * shader. We may need to update one or both shader's uniform here:
+ */
+ if (shProg->VertexProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->VertPos;
+ if (index >= 0) {
+ set_program_uniform(ctx, &shProg->VertexProgram->Base,
+ index, offset, type, count, elems, values);
+ }
+ }
+
+ if (shProg->FragmentProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->FragPos;
+ if (index >= 0) {
+ set_program_uniform(ctx, &shProg->FragmentProgram->Base,
+ index, offset, type, count, elems, values);
+ }
+ }
+
+ uniform->Initialized = GL_TRUE;
+}
+
+
+/**
+ * Set a matrix-valued program parameter.
+ */
+static void
+set_program_uniform_matrix(GLcontext *ctx, struct gl_program *program,
+ GLuint index, GLuint offset,
+ GLuint count, GLuint rows, GLuint cols,
+ GLboolean transpose, const GLfloat *values)
+{
+ GLuint mat, row, col;
+ GLuint src = 0;
+ const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
+ const GLuint slots = (param->Size + 3) / 4;
+ const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
+ GLint nr, nc;
+
+ /* check that the number of rows, columns is correct */
+ get_matrix_dims(param->DataType, &nr, &nc);
+ if (rows != nr || cols != nc) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformMatrix(matrix size mismatch)");
+ return;
+ }
+
+ if ((GLint) param->Size <= typeSize) {
+ /* non-array: count must be at most one; count == 0 is handled by the loop below */
+ if (count > 1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformMatrix(uniform is not an array)");
+ return;
+ }
+ }
+
+ /*
+ * Note: the _columns_ of a matrix are stored in program registers, not
+ * the rows. So, the loops below look a little funny.
+ * XXX could optimize this a bit...
+ */
+
+ /* loop over matrices */
+ for (mat = 0; mat < count; mat++) {
+
+ /* each matrix: */
+ for (col = 0; col < cols; col++) {
+ GLfloat *v;
+ if (offset >= slots) {
+ /* Ignore writes beyond the end of (the used part of) an array */
+ return;
+ }
+ v = program->Parameters->ParameterValues[index + offset];
+ for (row = 0; row < rows; row++) {
+ if (transpose) {
+ v[row] = values[src + row * cols + col];
+ }
+ else {
+ v[row] = values[src + col * rows + row];
+ }
+ }
+
+ offset++;
+ }
+
+ src += rows * cols; /* next matrix */
+ }
+}
+
+
+/**
+ * Called by ctx->Driver.UniformMatrix().
+ * Note: cols=2, rows=4 ==> array[2] of vec4
+ */
+static void
+_mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
+ GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *values)
+{
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ struct gl_uniform *uniform;
+ GLint offset;
+
+ if (!shProg || !shProg->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glUniformMatrix(program not linked)");
+ return;
+ }
+
+ if (location == -1)
+ return; /* The standard specifies this as a no-op */
+
+ if (location < -1) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
+ return;
+ }
+
+ split_location_offset(&location, &offset);
+
+ if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
+ return;
+ }
+ if (values == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
+ return;
+ }
+
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
+
+ uniform = &shProg->Uniforms->Uniforms[location];
+
+ if (shProg->VertexProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->VertPos;
+ if (index >= 0) {
+ set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
+ index, offset,
+ count, rows, cols, transpose, values);
+ }
+ }
+
+ if (shProg->FragmentProgram) {
+ /* convert uniform location to program parameter index */
+ GLint index = uniform->FragPos;
+ if (index >= 0) {
+ set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
+ index, offset,
+ count, rows, cols, transpose, values);
+ }
+ }
+
+ uniform->Initialized = GL_TRUE;
+}
+
+
+
+void
+_mesa_init_uniform_functions(struct dd_function_table *driver)
+{
+ driver->GetActiveUniform = _mesa_get_active_uniform;
+ driver->GetUniformfv = _mesa_get_uniformfv;
+ driver->GetUniformiv = _mesa_get_uniformiv;
+ driver->GetUniformLocation = _mesa_get_uniform_location;
+ driver->Uniform = _mesa_uniform;
+ driver->UniformMatrix = _mesa_uniform_matrix;
+}
diff --git a/src/mesa/shader/uniforms.h b/src/mesa/shader/uniforms.h
new file mode 100644
index 0000000000..52984dedad
--- /dev/null
+++ b/src/mesa/shader/uniforms.h
@@ -0,0 +1,33 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2010 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, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION 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 UNIFORMS_H
+#define UNIFORMS_H
+
+
+extern void
+_mesa_init_uniform_functions(struct dd_function_table *driver);
+
+
+#endif /* UNIFORMS_H */
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index c9d8620e35..ddd63cea0b 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -247,7 +247,8 @@ SHADER_SOURCES = \
shader/prog_uniform.c \
shader/programopt.c \
shader/symbol_table.c \
- shader/shader_api.c
+ shader/shader_api.c \
+ shader/uniforms.c
SLANG_SOURCES = \
shader/slang/slang_builtin.c \
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index d7c086f569..1f73f503f6 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -33,7 +33,6 @@
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
-#include "shader/program.h"
#include "st_context.h"
#include "st_texture.h"
@@ -41,7 +40,6 @@
#include "st_cb_fbo.h"
#include "util/u_blit.h"
-#include "util/u_inlines.h"
void
diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/mesa/state_tracker/st_cb_viewport.c
index d10b0b2531..a1fe45cac4 100644
--- a/src/mesa/state_tracker/st_cb_viewport.c
+++ b/src/mesa/state_tracker/st_cb_viewport.c
@@ -29,11 +29,9 @@
#include "st_context.h"
#include "st_cb_viewport.h"
-#include "pipe/p_context.h"
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "util/u_atomic.h"
-#include "util/u_debug.h"
/**
* Cast wrapper to convert a GLframebuffer to an st_framebuffer.
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index 605a337b55..0bf030e987 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -59,8 +59,6 @@
#include "st_program.h"
#include "pipe/p_context.h"
#include "util/u_inlines.h"
-#include "util/u_rect.h"
-#include "util/u_surface.h"
#include "cso_cache/cso_context.h"
diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c
index 2da27fc4bd..0b3768341e 100644
--- a/src/mesa/state_tracker/st_debug.c
+++ b/src/mesa/state_tracker/st_debug.c
@@ -45,15 +45,15 @@
int ST_DEBUG = 0;
static const struct debug_named_value st_debug_flags[] = {
- { "mesa", DEBUG_MESA },
- { "tgsi", DEBUG_TGSI },
- { "constants",DEBUG_CONSTANTS },
- { "pipe", DEBUG_PIPE },
- { "tex", DEBUG_TEX },
- { "fallback", DEBUG_FALLBACK },
- { "screen", DEBUG_SCREEN },
- { "query", DEBUG_QUERY },
- {NULL, 0}
+ { "mesa", DEBUG_MESA, NULL },
+ { "tgsi", DEBUG_TGSI, NULL },
+ { "constants",DEBUG_CONSTANTS, NULL },
+ { "pipe", DEBUG_PIPE, NULL },
+ { "tex", DEBUG_TEX, NULL },
+ { "fallback", DEBUG_FALLBACK, NULL },
+ { "screen", DEBUG_SCREEN, NULL },
+ { "query", DEBUG_QUERY, NULL },
+ DEBUG_NAMED_VALUE_END
};
#endif
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 810a0635b5..4093eedde9 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -373,6 +373,13 @@ void st_init_extensions(struct st_context *st)
ctx->Extensions.EXT_draw_buffers2 = GL_TRUE;
}
+ /* GL_ARB_half_float_vertex */
+ if (screen->is_format_supported(screen, PIPE_FORMAT_R16G16B16A16_FLOAT,
+ PIPE_BUFFER, 0,
+ PIPE_BIND_VERTEX_BUFFER, 0)) {
+ ctx->Extensions.ARB_half_float_vertex = GL_TRUE;
+ }
+
#if 0 /* not yet */
if (screen->get_param(screen, PIPE_CAP_INDEP_BLEND_FUNC)) {
ctx->Extensions.ARB_draw_buffers_blend = GL_TRUE;
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 6df6cdfe03..35016d80e6 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -319,10 +319,15 @@ translate_src( struct st_translate *t,
if (SrcReg->RelAddr) {
src = ureg_src_indirect( src, ureg_src(t->address[0]));
- /* If SrcReg->Index was negative, it was set to zero in
- * src_register(). Reassign it now.
- */
- src.Index = SrcReg->Index;
+ if (SrcReg->File != PROGRAM_INPUT &&
+ SrcReg->File != PROGRAM_OUTPUT) {
+ /* If SrcReg->Index was negative, it was set to zero in
+ * src_register(). Reassign it now. But don't do this
+ * for input/output regs since they get remapped while
+ * const buffers don't.
+ */
+ src.Index = SrcReg->Index;
+ }
}
return src;
diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c
index a057befed0..046fa8105b 100644
--- a/src/mesa/vbo/vbo_exec.c
+++ b/src/mesa/vbo/vbo_exec.c
@@ -30,9 +30,10 @@
#include "main/glheader.h"
#include "main/mtypes.h"
#include "main/vtxfmt.h"
-
#include "vbo_context.h"
+
+
void vbo_exec_init( GLcontext *ctx )
{
struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
@@ -74,7 +75,9 @@ void vbo_exec_destroy( GLcontext *ctx )
vbo_exec_array_destroy( exec );
}
-/* Really want to install these callbacks to a central facility to be
+
+/**
+ * Really want to install these callbacks to a central facility to be
* invoked according to the state flags. That will have to wait for a
* mesa rework:
*/
@@ -87,8 +90,3 @@ void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state )
_ae_invalidate_state(ctx, new_state);
}
-
-
-
-
-
diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h
index 98c1f363d9..33494f0cea 100644
--- a/src/mesa/vbo/vbo_exec.h
+++ b/src/mesa/vbo/vbo_exec.h
@@ -195,7 +195,4 @@ void vbo_exec_do_EvalCoord2f( struct vbo_exec_context *exec,
void vbo_exec_do_EvalCoord1f( struct vbo_exec_context *exec,
GLfloat u);
-extern GLboolean
-vbo_validate_shaders(GLcontext *ctx);
-
#endif
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index d4dbc8d256..c32a504443 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -30,7 +30,6 @@
#include "main/context.h"
#include "main/state.h"
#include "main/api_validate.h"
-#include "main/api_noop.h"
#include "main/varray.h"
#include "main/bufferobj.h"
#include "main/enums.h"
@@ -40,7 +39,8 @@
/**
- * Compute min and max elements for glDraw[Range]Elements() calls.
+ * Compute min and max elements by scanning the index buffer for
+ * glDraw[Range]Elements() calls.
*/
void
vbo_get_minmax_index(GLcontext *ctx,
@@ -112,6 +112,7 @@ vbo_get_minmax_index(GLcontext *ctx,
/**
* Check that element 'j' of the array has reasonable data.
* Map VBO if needed.
+ * For debugging purposes; not normally used.
*/
static void
check_array_data(GLcontext *ctx, struct gl_client_array *array,
@@ -172,6 +173,7 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
/**
* Examine the array's data for NaNs, etc.
+ * For debug purposes; not normally used.
*/
static void
check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
@@ -249,7 +251,7 @@ check_draw_arrays_data(GLcontext *ctx, GLint start, GLsizei count)
/**
- * Print info/data for glDrawArrays().
+ * Print info/data for glDrawArrays(), for debugging.
*/
static void
print_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec,
@@ -295,6 +297,9 @@ print_draw_arrays(GLcontext *ctx, struct vbo_exec_context *exec,
/**
+ * Bind the VBO executor to the current vertex array object prior
+ * to drawing.
+ *
* Just translate the arrayobj into a sane layout.
*/
static void
@@ -334,6 +339,14 @@ bind_array_obj(GLcontext *ctx)
}
+/**
+ * Set the vbo->exec->inputs[] pointers to point to the enabled
+ * vertex arrays. This depends on the current vertex program/shader
+ * being executed because of whether or not generic vertex arrays
+ * alias the conventional vertex arrays.
+ * For arrays that aren't enabled, we set the input[attrib] pointer
+ * to point at a zero-stride current value "array".
+ */
static void
recalculate_input_bindings(GLcontext *ctx)
{
@@ -453,27 +466,15 @@ recalculate_input_bindings(GLcontext *ctx)
static void
bind_arrays(GLcontext *ctx)
{
-#if 0
- if (ctx->Array.ArrayObj.Name != exec->array.array_obj) {
- bind_array_obj(ctx);
- recalculate_input_bindings(ctx);
- }
- else if (exec->array.program_mode != get_program_mode(ctx) ||
- exec->array.enabled_flags != ctx->Array.ArrayObj->_Enabled) {
- recalculate_input_bindings(ctx);
- }
-#else
bind_array_obj(ctx);
recalculate_input_bindings(ctx);
-#endif
}
-/***********************************************************************
- * API functions.
+/**
+ * Called from glDrawArrays when in immediate mode (not display list mode).
*/
-
static void GLAPIENTRY
vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
@@ -533,6 +534,10 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
}
+/**
+ * Called from glDrawArraysInstanced when in immediate mode (not
+ * display list mode).
+ */
static void GLAPIENTRY
vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
GLsizei primcount)
@@ -591,6 +596,7 @@ vbo_exec_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count,
/**
* Map GL_ELEMENT_ARRAY_BUFFER and print contents.
+ * For debugging.
*/
static void
dump_element_buffer(GLcontext *ctx, GLenum type)
@@ -645,7 +651,11 @@ dump_element_buffer(GLcontext *ctx, GLenum type)
}
-/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+/**
+ * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements.
+ * Do the rendering for a glDrawElements or glDrawRangeElements call after
+ * we've validated buffer bounds, etc.
+ */
static void
vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
GLboolean index_bounds_valid,
@@ -722,6 +732,10 @@ vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
index_bounds_valid, start, end );
}
+
+/**
+ * Called by glDrawRangeElementsBaseVertex() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
GLuint start, GLuint end,
@@ -831,6 +845,9 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
}
+/**
+ * Called by glDrawRangeElements() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
GLsizei count, GLenum type, const GLvoid *indices)
@@ -848,6 +865,9 @@ vbo_exec_DrawRangeElements(GLenum mode, GLuint start, GLuint end,
}
+/**
+ * Called by glDrawElements() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
@@ -867,6 +887,9 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
}
+/**
+ * Called by glDrawElementsBaseVertex() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLint basevertex)
@@ -887,6 +910,9 @@ vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
}
+/**
+ * Called by glDrawElementsInstanced() in immediate mode.
+ */
static void GLAPIENTRY
vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLsizei primcount)
@@ -907,7 +933,11 @@ vbo_exec_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
}
-/** Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+/**
+ * Inner support for both _mesa_MultiDrawElements() and
+ * _mesa_MultiDrawRangeElements().
+ * This does the actual rendering after we've checked array indexes, etc.
+ */
static void
vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
const GLsizei *count, GLenum type,
@@ -939,7 +969,8 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
}
/* Decide if we can do this all as one set of primitives sharing the
- * same index buffer, or if we have to reset the index pointer per primitive.
+ * same index buffer, or if we have to reset the index pointer per
+ * primitive.
*/
bind_arrays( ctx );
@@ -1089,14 +1120,13 @@ vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
}
-/***********************************************************************
- * Initialization
+/**
+ * Plug in the immediate-mode vertex array drawing commands into the
+ * givven vbo_exec_context object.
*/
-
void
vbo_exec_array_init( struct vbo_exec_context *exec )
{
-#if 1
exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
@@ -1106,15 +1136,6 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
exec->vtxfmt.DrawArraysInstanced = vbo_exec_DrawArraysInstanced;
exec->vtxfmt.DrawElementsInstanced = vbo_exec_DrawElementsInstanced;
-#else
- exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
- exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
- exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;
- exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
- exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
- exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
- exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
-#endif
}
@@ -1125,7 +1146,13 @@ vbo_exec_array_destroy( struct vbo_exec_context *exec )
}
-/* This API entrypoint is not ordinarily used */
+
+/**
+ * The following functions are only used for OpenGL ES 1/2 support.
+ * And some aren't even supported (yet) in ES 1/2.
+ */
+
+
void GLAPIENTRY
_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
{
@@ -1133,7 +1160,6 @@ _mesa_DrawArrays(GLenum mode, GLint first, GLsizei count)
}
-/* This API entrypoint is not ordinarily used */
void GLAPIENTRY
_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
@@ -1141,6 +1167,7 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
vbo_exec_DrawElements(mode, count, type, indices);
}
+
void GLAPIENTRY
_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices, GLint basevertex)
@@ -1149,7 +1176,6 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
}
-/* This API entrypoint is not ordinarily used */
void GLAPIENTRY
_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
GLenum type, const GLvoid *indices)
@@ -1168,7 +1194,6 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
}
-/* GL_EXT_multi_draw_arrays */
void GLAPIENTRY
_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
const GLvoid **indices, GLsizei primcount)