Merge remote branch 'origin/master' into pipe-video

This commit is contained in:
Christian König 2011-03-03 00:59:12 +01:00
commit 0eccb1038a
260 changed files with 4644 additions and 29326 deletions

View file

@ -209,7 +209,6 @@ MAIN_FILES = \
$(DIRECTORY)/docs/README.* \
$(DIRECTORY)/docs/RELNOTES* \
$(DIRECTORY)/docs/*.spec \
$(DIRECTORY)/include/GL/internal/glcore.h \
$(DIRECTORY)/include/GL/gl.h \
$(DIRECTORY)/include/GL/glext.h \
$(DIRECTORY)/include/GL/gl_mangle.h \
@ -308,8 +307,7 @@ MAPI_FILES = \
$(DIRECTORY)/src/mapi/mapi/*.[ch] \
$(DIRECTORY)/src/mapi/vgapi/Makefile \
$(DIRECTORY)/src/mapi/vgapi/vgapi.csv \
$(DIRECTORY)/src/mapi/vgapi/vg.pc.in \
$(DIRECTORY)/src/mapi/vgapi/*.h
$(DIRECTORY)/src/mapi/vgapi/vg.pc.in
EGL_FILES = \
$(DIRECTORY)/include/KHR/*.h \
@ -422,10 +420,22 @@ LIB_FILES = \
$(GLW_FILES)
# Everything for new a Mesa release:
tarballs: rm_depend configure aclocal.m4 lib_gz glut_gz \
lib_bz2 glut_bz2 lib_zip glut_zip md5
parsers: configure
-@touch $(TOP)/configs/current
$(MAKE) -C src/glsl glsl_parser.cpp glsl_parser.h glsl_lexer.cpp
$(MAKE) -C src/glsl/glcpp glcpp-lex.c glcpp-parse.c glcpp-parse.h
$(MAKE) -C src/mesa/program lex.yy.c program_parse.tab.c program_parse.tab.h
# Everything for new a Mesa release:
ARCHIVES = $(LIB_NAME).tar.gz \
$(LIB_NAME).tar.bz2 \
$(LIB_NAME).zip \
$(GLUT_NAME).tar.gz \
$(GLUT_NAME).tar.bz2 \
$(GLUT_NAME).zip
tarballs: md5
rm -f ../$(LIB_NAME).tar
# Helper for autoconf builds
ACLOCAL = aclocal
@ -434,7 +444,7 @@ AUTOCONF = autoconf
AC_FLAGS =
aclocal.m4: configure.ac acinclude.m4
$(ACLOCAL) $(ACLOCAL_FLAGS)
configure: configure.ac aclocal.m4 acinclude.m4
configure: rm_depend configure.ac aclocal.m4 acinclude.m4
$(AUTOCONF) $(AC_FLAGS)
rm_depend:
@ -443,47 +453,41 @@ rm_depend:
touch $$dep ; \
done
rm_config:
rm_config: parsers
rm -f configs/current
rm -f configs/autoconf
lib_gz: rm_config
cd .. ; \
tar -cf $(LIB_NAME).tar $(LIB_FILES) ; \
gzip $(LIB_NAME).tar ; \
mv $(LIB_NAME).tar.gz $(DIRECTORY)
$(LIB_NAME).tar: rm_config
cd .. ; tar -cf $(DIRECTORY)/$(LIB_NAME).tar $(LIB_FILES)
glut_gz:
cd .. ; \
tar -cf $(GLUT_NAME).tar $(GLUT_FILES) ; \
gzip $(GLUT_NAME).tar ; \
mv $(GLUT_NAME).tar.gz $(DIRECTORY)
$(LIB_NAME).tar.gz: $(LIB_NAME).tar
gzip --stdout --best $(LIB_NAME).tar > $(LIB_NAME).tar.gz
lib_bz2: rm_config
cd .. ; \
tar -cf $(LIB_NAME).tar $(LIB_FILES) ; \
bzip2 $(LIB_NAME).tar ; \
mv $(LIB_NAME).tar.bz2 $(DIRECTORY)
$(GLUT_NAME).tar: rm_depend
cd .. ; tar -cf $(DIRECTORY)/$(GLUT_NAME).tar $(GLUT_FILES)
glut_bz2:
cd .. ; \
tar -cf $(GLUT_NAME).tar $(GLUT_FILES) ; \
bzip2 $(GLUT_NAME).tar ; \
mv $(GLUT_NAME).tar.bz2 $(DIRECTORY)
$(GLUT_NAME).tar.gz: $(GLUT_NAME).tar
gzip --stdout --best $(GLUT_NAME).tar > $(GLUT_NAME).tar.gz
lib_zip: rm_config
$(LIB_NAME).tar.bz2: $(LIB_NAME).tar
bzip2 --stdout --best $(LIB_NAME).tar > $(LIB_NAME).tar.bz2
$(GLUT_NAME).tar.bz2: $(GLUT_NAME).tar
bzip2 --stdout --best $(GLUT_NAME).tar > $(GLUT_NAME).tar.bz2
$(LIB_NAME).zip: rm_config
rm -f $(LIB_NAME).zip ; \
cd .. ; \
zip -qr $(LIB_NAME).zip $(LIB_FILES) ; \
mv $(LIB_NAME).zip $(DIRECTORY)
glut_zip:
$(GLUT_NAME).zip:
rm -f $(GLUT_NAME).zip ; \
cd .. ; \
zip -qr $(GLUT_NAME).zip $(GLUT_FILES) ; \
mv $(GLUT_NAME).zip $(DIRECTORY)
md5:
md5: $(ARCHIVES)
@-md5sum $(LIB_NAME).tar.gz
@-md5sum $(LIB_NAME).tar.bz2
@-md5sum $(LIB_NAME).zip
@ -491,7 +495,4 @@ md5:
@-md5sum $(GLUT_NAME).tar.bz2
@-md5sum $(GLUT_NAME).zip
.PHONY: tarballs rm_depend rm_config md5 \
lib_gz glut_gz \
lib_bz2 glut_bz2 \
lib_zip glut_zip
.PHONY: tarballs rm_depend rm_config md5

View file

@ -18,12 +18,12 @@ AC_CONFIG_AUX_DIR([bin])
AC_CANONICAL_HOST
dnl Versions for external dependencies
LIBDRM_REQUIRED=2.4.23
LIBDRM_RADEON_REQUIRED=2.4.23
LIBDRM_INTEL_REQUIRED=2.4.23
LIBDRM_REQUIRED=2.4.24
LIBDRM_RADEON_REQUIRED=2.4.24
LIBDRM_INTEL_REQUIRED=2.4.24
DRI2PROTO_REQUIRED=2.1
GLPROTO_REQUIRED=1.4.11
LIBDRM_XORG_REQUIRED=2.4.23
LIBDRM_XORG_REQUIRED=2.4.24
LIBKMS_XORG_REQUIRED=1.0.0
dnl Check for progs
@ -1162,6 +1162,9 @@ if test "x$enable_egl" = xyes; then
if test "$have_libudev" = yes; then
DEFINES="$DEFINES -DHAVE_LIBUDEV"
fi
# workaround a bug in xcb-dri2 generated by xcb-proto 1.6
AC_CHECK_LIB(xcb-dri2, xcb_dri2_connect_alignment_pad, [],
[DEFINES="$DEFINES -DXCB_DRI2_CONNECT_DEVICE_NAME_BROKEN"])
fi
fi
@ -1608,7 +1611,7 @@ yes)
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/fbdev"
fi
if test "$plat" = "wayland"; then
PKG_CHECK_MODULES([WAYLAND], [wayland-client],, \
PKG_CHECK_MODULES([WAYLAND], [wayland-client wayland-server],, \
[AC_MSG_ERROR([cannot find libwayland-client])])
WAYLAND_EGL_LIB_DEPS="$WAYLAND_LIBS $LIBDRM_LIBS"
fi

View file

@ -0,0 +1,92 @@
Name
WL_bind_wayland_display
Name Strings
EGL_WL_bind_wayland_display
Contact
Kristian Høgsberg <krh@bitplanet.net>
Benjamin Franzke <benjaminfranzke@googlemail.com>
Status
Proposal
Version
Version 1, March 1, 2011
Number
EGL Extension #not assigned
Dependencies
Reguires EGL 1.4 or later. This extension is written against the
wording of the EGL 1.4 specification.
EGL_KHR_base_image is required.
Overview
This extension provides entry points for binding and unbinding the
wl_display of a Wayland compositor to an EGLDisplay. Binding a
wl_display means that the EGL implementation should provide one or
more interfaces in the Wayland protocol to allow clients to create
wl_buffer objects. On the server side, this extension also
provides a new target for eglCreateImageKHR, to create an EGLImage
from a wl_buffer
Adding a implementation specific wayland interface, allows the
EGL implementation to define specific wayland requests and events,
needed for buffer sharing in a EGL wayland platform.
IP Status
Open-source; freely implementable.
New Procedures and Functions
EGLBoolean eglBindWaylandDisplayWL(EGLDisplay dpy,
struct wl_display *display);
EGLBoolean eglUnbindWaylandDisplayWL(EGLDisplay dpy,
struct wl_display *display);
New Tokens
Accepted as <target> in eglCreateImageKHR
EGL_WAYLAND_BUFFER_WL 0x31D5
Additions to the EGL 1.4 Specification:
To bind a server side wl_display to an EGLDisplay, call
EGLBoolean eglBindWaylandDisplayWL(EGLDisplay dpy,
struct wl_display *display);
To unbind a server side wl_display from an EGLDisplay, call
EGLBoolean eglUnbindWaylandDisplayWL(EGLDisplay dpy,
struct wl_display *display);
eglBindWaylandDisplayWL returns EGL_FALSE when there is already a
wl_display bound to EGLDisplay otherwise EGL_TRUE.
eglUnbindWaylandDisplayWL returns EGL_FALSE when there is no
wl_display bound to the EGLDisplay currently otherwise EGL_TRUE.
Import a wl_buffer by calling eglCreateImageKHR with
wl_buffer as EGLClientBuffer, EGL_WAYLAND_BUFFER_WL as the target,
and an empty attribute_list.
Issues
Revision History
Version 1, March 1, 2011
Initial draft (Benjamin Franzke)

View file

@ -11,6 +11,15 @@
<H1>News</H1>
<h2>March 2, 2011</h2>
<p>
<a href="relnotes-7.9.2.html">Mesa 7.9.2</a> and
<a href="relnotes-7.10.1.html">Mesa 7.10.1</a> are released. These are
stable releases containing bug fixes since the 7.9.1 and 7.10 releases.
</p>
<h2>October 4, 2010</h2>
<p>

380
docs/relnotes-7.10.1.html Normal file
View file

@ -0,0 +1,380 @@
<HTML>
<head>
<TITLE>Mesa Release Notes</TITLE>
<link rel="stylesheet" type="text/css" href="mesa.css">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<BODY>
<body bgcolor="#eeeeee">
<H1>Mesa 7.10.1 Release Notes / TBD</H1>
<p>
Mesa 7.10.1 is a bug fix release which fixes bugs found since the 7.10 release.
</p>
<p>
Mesa 7.10.1 implements the OpenGL 2.1 API, but the version reported by
glGetString(GL_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 2.1.
</p>
<p>
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
for DRI hardware acceleration.
</p>
<h2>MD5 checksums</h2>
<pre>
4b4cee19f3bf16eb78bd4cc278ccf812 MesaLib-7.10.1.tar.gz
efe8da4d80c2a5d32a800770b8ce5dfa MesaLib-7.10.1.tar.bz2
0fd2b1a025934de3f8cecf9fb9b57f4c MesaLib-7.10.1.zip
42beb0f5188d544476c19496f725fa67 MesaGLUT-7.10.1.tar.gz
637bb8a20fdad89f7382b4ea83f896e3 MesaGLUT-7.10.1.tar.bz2
bdbf3ffb2606d6aa8afabb6c6243b91b MesaGLUT-7.10.1.zip
</pre>
<h2>New features</h2>
<p>None.</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li>Fix an off-by-one bug in a vsplit assertion.</li>
<li>Fix incorrect handling of <tt>layout</tt> qualifier
with <tt>in</tt>, <tt>out</tt>, <tt>attribute</tt>, and <tt>varying</tt>.</li>
<li>Fix an i965 shader bug where the negative absolute value was generated instead of the absolute value of a negation.</li>
<li>Fix numerous issues handling precision qualifiers in GLSL ES.</li>
<li>Fixed a few GLX protocol encoder bugs (Julien Cristau)</li>
<li>Assorted Gallium llvmpipe driver bug fixes</li>
<li>Assorted Mesa/Gallium state tracker bug fixes</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=26795">Bug 26795</a> - gl_FragCoord off by one in Gallium drivers.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29164">Bug 29164</a> - [GLSL 1.20] invariant variable shouldn't be used before declaration</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29823">Bug 29823</a> - GetUniform[if]v busted</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29927">Bug 29927</a> - [glsl2] fail to compile shader with constructor for array of struct type</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=30156">Bug 30156</a> - [i965] After updating to Mesa 7.9, Civilization IV starts to show garbage</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=31923">Bug 31923</a> - [GLSL 1.20] allowing inconsistent centroid declaration between two vertex shaders</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=31925">Bug 31925</a> - [GLSL 1.20] "#pragma STDGL invariant(all)" fail</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32214">Bug 32214</a> - [gles2]no link error happens when missing vertex shader or frag shader</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32375">Bug 32375</a> - [gl gles2] Not able to get the attribute by function glGetVertexAttribfv</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32541">Bug 32541</a> - Segmentation Fault while running an HDR (high dynamic range) rendering demo</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32569">Bug 32569</a> - [gles2] glGetShaderPrecisionFormat not implemented yet</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32695">Bug 32695</a> - [glsl] SIGSEGV glcpp/glcpp-parse.y:833</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32831">Bug 32831</a> - [glsl] division by zero crashes GLSL compiler</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32910">Bug 32910</a> - Keywords 'in' and 'out' not handled properly for GLSL 1.20 shaders</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33219">Bug 33219</a> -[GLSL bisected] implicit sized array triggers segfault in ir_to_mesa_visitor::copy_propagate</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33306">Bug 33306</a> - GLSL integer division by zero crashes GLSL compiler</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33308">Bug 33308</a> -[glsl] ast_to_hir.cpp:3016: virtual ir_rvalue* ast_jump_statement::hir(exec_list*, _mesa_glsl_parse_state*): Assertion `ret != __null' failed.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33316">Bug 33316</a> - uniform array will be allocate one line more and initialize it when it was freed will abort</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33386">Bug 33386</a> - Dubious assembler in read_rgba_span_x86.S</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33388">Bug 33388</a> - Dubious assembler in xform4.S</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33433">Bug 33433</a> - Error in x86-64 API dispatch code.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33507">Bug 33507</a> - [glsl] GLSL preprocessor modulus by zero crash</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33508">Bug 33508</a> - [glsl] GLSL compiler modulus by zero crash</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33916">Bug 33916</a> - Compiler accepts reserved operators % and %=</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34030">Bug 34030</a> - [bisected] Starcraft 2: some effects are corrupted or too big</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34047">Bug 34047</a> - Assert in _tnl_import_array() when using GLfixed vertex datatypes with GLESv2</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34114">Bug 34114</a> - Sun Studio build fails due to standard library functions not being in global namespace</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34179">Bug 34179</a> - Nouveau 3D driver: nv50_pc_emit.c:863 assertion error kills Compiz</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34198">Bug 34198</a> - [GLSL] implicit sized array with index 0 used gets assertion</li>
<li><a href="https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/691653">Ubuntu bug 691653</a> - compiz crashes when using alt-tab (the radeon driver kills it) </li>
<li><a href="https://bugs.meego.com/show_bug.cgi?id=13005">Meego bug 13005</a> - Graphics GLSL issue lead to camera preview fail on Pinetrail</li>
<!-- <li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=">Bug </a> - </li> -->
</ul>
<h2>Changes</h2>
<p>The full set of changes can be viewed by using the following GIT command:</p>
<pre>
git log mesa-7.10..mesa-7.10.1
</pre>
<p>Alberto Milone (1):
<ul>
<li>r600c: add evergreen ARL support.</li>
</ul></p>
<p>Brian Paul (21):
<ul>
<li>draw: Fix an off-by-one bug in a vsplit assertion.</li>
<li>docs: add links to 7.9.1 and 7.10 release notes</li>
<li>docs: added news item for 7.9.1 and 7.10 release</li>
<li>gallivm: work around LLVM 2.6 bug when calling C functions</li>
<li>gallivm: fix copy&amp;paste error from previous commit</li>
<li>mesa: fix a few format table mistakes, assertions</li>
<li>mesa: fix num_draw_buffers==0 in fixed-function fragment program generation</li>
<li>mesa: don't assert in GetIntegerIndexed, etc</li>
<li>mesa: check for dummy renderbuffer in _mesa_FramebufferRenderbufferEXT()</li>
<li>llvmpipe: make sure binning is active when we begin/end a query</li>
<li>st/mesa: fix incorrect fragcoord.x translation</li>
<li>softpipe: fix off-by-one error in setup_fragcoord_coeff()</li>
<li>cso: fix loop bound in cso_set_vertex_samplers()</li>
<li>st/mesa: fix incorrect glCopyPixels position on fallback path</li>
<li>st/mesa: set renderbuffer _BaseFormat in a few places</li>
<li>st/mesa: fix the default case in st_format_datatype()</li>
<li>st/mesa: need to translate clear color according to surface's base format</li>
<li>docs: update 7.9.2 release notes with Brian's cherry-picks</li>
<li>docs: add link to 7.10.1 release notes</li>
<li>mesa: implement glGetShaderPrecisionFormat()</li>
<li>docs: updated environment variable list</li>
</ul></p>
<p>Bryce Harrington (1):
<ul>
<li>r300g: Null pointer check for buffer deref in gallium winsys</li>
</ul></p>
<p>Chad Versace (20):
<ul>
<li>glsl: At link-time, check that globals have matching centroid qualifiers</li>
<li>glcpp: Fix segfault when validating macro redefinitions</li>
<li>glsl: Fix parser rule for type_specifier</li>
<li>glsl: Change default value of ast_type_specifier::precision</li>
<li>glsl: Add semantic checks for precision qualifiers</li>
<li>glsl: Add support for default precision statements</li>
<li>glsl: Remove redundant semantic check in parser</li>
<li>glsl: Fix semantic checks on precision qualifiers</li>
<li>glsl: Fix segfault due to missing printf argument</li>
<li>glsl: Mark 'in' variables at global scope as read-only</li>
<li>mesa: Refactor handling of extension strings</li>
<li>mesa: Add/remove extensions in extension string</li>
<li>mesa: Change dependencies of some OES extension strings</li>
<li>mesa: Change OES_point_sprite to depend on ARB_point_sprite</li>
<li>mesa: Change OES_standard_derivatives to be stand-alone extension</li>
<li>i915: Disable extension OES_standard_derivatives</li>
<li>glcpp: Raise error when modulus is zero</li>
<li>glsl: Set operators '%' and '%=' to be reserved when GLSL &lt 1.30</li>
<li>glsl: Reinstate constant-folding for division by zero</li>
<li>tnl: Add support for datatype GL_FIXED in vertex arrays</li>
</ul></p>
<p>Chia-I Wu (1):
<ul>
<li>mesa: Add glDepthRangef and glClearDepthf to APIspec.xml.</li>
</ul></p>
<p>Christoph Bumiller (1):
<ul>
<li>nv50,nvc0: do not forget to apply sign mode to saved TGSI inputs</li>
</ul></p>
<p>Cyril Brulebois (1):
<ul>
<li>Point to bugs.freedesktop.org rather than bugzilla.freedesktop.org</li>
</ul></p>
<p>Dave Airlie (3):
<ul>
<li>radeon/r200: fix fbo-clearmipmap + gen-teximage</li>
<li>radeon: calculate complete texture state inside TFP function</li>
<li>radeon: avoid segfault on 3D textures.</li>
</ul></p>
<p>Dimitry Andric (4):
<ul>
<li>mesa: s/movzx/movzbl/</li>
<li>mesa: s/movzxw/movzwl/ in read_rgba_span_x86.S</li>
<li>glapi: adding @ char before type specifier in glapi_x86.S</li>
<li>glapi: add @GOTPCREL relocation type</li>
</ul></p>
<p>Eric Anholt (16):
<ul>
<li>glsl: Fix the lowering of variable array indexing to not lose write_masks.</li>
<li>i965/fs: When producing ir_unop_abs of an operand, strip negate.</li>
<li>i965/vs: When MOVing to produce ABS, strip negate of the operand.</li>
<li>i965/fs: Do flat shading when appropriate.</li>
<li>i965: Avoid double-negation of immediate values in the VS.</li>
<li>intel: Make renderbuffer tiling choice match texture tiling choice.</li>
<li>i965: Fix dead pointers to fp-&gt;Parameters-&gt;ParameterValues[] after realloc.</li>
<li>docs: Add a relnote for the Civ IV on i965.</li>
<li>glapi: Add entrypoints and enums for GL_ARB_ES2_compatibility.</li>
<li>mesa: Add extension enable bit for GL_ARB_ES2_compatibility.</li>
<li>mesa: Add actual support for glReleaseShaderCompiler from ES2.</li>
<li>mesa: Add support for glDepthRangef and glClearDepthf.</li>
<li>mesa: Add getters for ARB_ES2_compatibility MAX_*_VECTORS.</li>
<li>mesa: Add getter for GL_SHADER_COMPILER with ARB_ES2_compatibility.</li>
<li>i965: Fix a bug in i965 compute-to-MRF.</li>
<li>i965/fs: Add a helper function for detecting math opcodes.</li>
</ul></p>
<p>Fredrik Höglund (1):
<ul>
<li>st/mesa: fix a regression from cae2bb76</li>
</ul></p>
<p>Ian Romanick (42):
<ul>
<li>docs: Add 7.10 md5sums</li>
<li>glsl: Support the 'invariant(all)' pragma</li>
<li>glcpp: Generate an error for division by zero</li>
<li>glsl: Add version_string containing properly formatted GLSL version</li>
<li>glsl &amp; glcpp: Refresh autogenerated lexer and parser files.</li>
<li>glsl: Disallow 'in' and 'out' on globals in GLSL 1.20</li>
<li>glsl: Track variable usage, use that to enforce semantics</li>
<li>glsl: Allow 'in' and 'out' when 'layout' is also available</li>
<li>docs: Initial bits of 7.10.1 release notes</li>
<li>mesa: bump version to 7.10.1-devel</li>
<li>doc: Update 7.10.1 release notes</li>
<li>glsl: Emit errors or warnings when 'layout' is used with 'attribute' or 'varying'</li>
<li>docs: Update 7.10.1 release notes</li>
<li>glsl: Refresh autogenerated lexer and parser files.</li>
<li>glsl: Don't assert when the value returned by a function has no rvalue</li>
<li>linker: Set sizes for non-global arrays as well</li>
<li>linker: Propagate max_array_access while linking functions</li>
<li>docs: Update 7.10.1 release notes</li>
<li>mesa: glGetUniform only returns a single element of an array</li>
<li>linker: Generate link errors when ES shaders are missing stages</li>
<li>mesa: Fix error checks in GetVertexAttrib functions</li>
<li>Use C-style system headers in C++ code to avoid issues with std:: namespace</li>
<li>docs: Update 7.10.1 release notes</li>
<li>glapi: Regenerate for GL_ARB_ES2_compatibility.</li>
<li>mesa: Connect glGetShaderPrecisionFormat into the dispatch table</li>
<li>i965: Set correct values for range/precision of fragment shader types</li>
<li>i915: Set correct values for range/precision of fragment shader types</li>
<li>intel: Fix typeos from 3d028024 and 790ff232</li>
<li>glsl: Ensure that all GLSL versions are supported in the stand-alone compiler</li>
<li>glsl: Reject shader versions not supported by the implementation</li>
<li>mesa: Initial size for secondary color array is 3</li>
<li>glsl: Finish out the reduce/reduce error fixes</li>
<li>glsl: Regenerate compiler and glcpp files from cherry picks</li>
<li>linker: Fix off-by-one error implicit array sizing</li>
<li>docs: update 7.10.1 release notes with Ian's recent cherry picks</li>
<li>i915: Only mark a register as available if all components are written</li>
<li>i915: Calculate partial result to temp register first</li>
<li>i915: Force lowering of all types of indirect array accesses in the FS</li>
<li>docs: Update 7.10.1 with (hopefully) the last of the cherry picks</li>
<li>docs: Clean up bug fixes list</li>
<li>intel: Remove driver date and related bits from renderer string</li>
<li>mesa: set version string to 7.10.1 (final)</li>
</ul></p>
<p>Jian Zhao (1):
<ul>
<li>mesa: fix an error in uniform arrays in row calculating.</li>
</ul></p>
<p>Julien Cristau (3):
<ul>
<li>glx: fix request lengths</li>
<li>glx: fix GLXChangeDrawableAttributesSGIX request</li>
<li>glx: fix length of GLXGetFBConfigsSGIX</li>
</ul></p>
<p>Keith Packard (1):
<ul>
<li>glsl: Eliminate reduce/reduce conflicts in glsl grammar</li>
</ul></p>
<p>Kenneth Graunke (20):
<ul>
<li>glsl: Expose a public glsl_type::void_type const pointer.</li>
<li>glsl: Don't bother unsetting a destructor that was never set.</li>
<li>glsl, i965: Remove unnecessary talloc includes.</li>
<li>glcpp: Remove use of talloc reference counting.</li>
<li>ralloc: Add a fake implementation of ralloc based on talloc.</li>
<li>Convert everything from the talloc API to the ralloc API.</li>
<li>ralloc: a new MIT-licensed recursive memory allocator.</li>
<li>Remove talloc from the make and automake build systems.</li>
<li>Remove talloc from the SCons build system.</li>
<li>Remove the talloc sources from the Mesa repository.</li>
<li>glsl: Fix use of uninitialized values in _mesa_glsl_parse_state ctor.</li>
<li>i965/fs: Apply source modifier workarounds to POW as well.</li>
<li>i965: Fix shaders that write to gl_PointSize on Sandybridge.</li>
<li>i965/fs: Avoid register coalescing away gen6 MATH workarounds.</li>
<li>i965/fs: Correctly set up gl_FragCoord.w on Sandybridge.</li>
<li>i965: Increase Sandybridge point size clamp.</li>
<li>i965/fs: Refactor control flow stack handling.</li>
<li>i965: Increase Sandybridge point size clamp in the clip state.</li>
<li>glsl: Use reralloc instead of plain realloc.</li>
<li>Revert "i965/fs: Correctly set up gl_FragCoord.w on Sandybridge."</li>
</ul></p>
<p>Marek Olšák (4):
<ul>
<li>docs: fix messed up names with special characters in relnotes-7.10</li>
<li>docs: fix messed up names with special characters in relnotes-7.9.1</li>
<li>mesa: fix texture3D mipmap generation for UNSIGNED_BYTE_3_3_2</li>
<li>st/dri: Track drawable context bindings</li>
</ul></p>
<p>Paulo Zanoni (1):
<ul>
<li>dri_util: fail driCreateNewScreen if InitScreen is NULL</li>
</ul></p>
<p>Sam Hocevar (2):
<ul>
<li>docs: add glsl info</li>
<li>docs: fix glsl_compiler name</li>
</ul></p>
<p>Tom Fogal (1):
<ul>
<li>Regenerate gl_mangle.h.</li>
</ul></p>
<p>Tom Stellard (2):
<ul>
<li>r300/compiler: Disable register rename pass on r500</li>
<li>r300/compiler: Don't erase sources when converting RGB-&gt;Alpha</li>
</ul></p>
<p>Vinson Lee (3):
<ul>
<li>ralloc: Add missing va_end following va_copy.</li>
<li>mesa: Move declaration before code in extensions.c.</li>
<li>mesa: Move loop variable declarations outside for loop in extensions.c.</li>
</ul></p>
<p>nobled (1):
<ul>
<li>glx: Put null check before use</li>
</ul></p>
</p>
</body>
</html>

View file

@ -53,6 +53,8 @@ tbd
<ul>
<li>The Windows MSVC project files have been removed. They haven't been maintained
in quite a while. Building with SCons is an alterantive.
<li>Removed GL_SGI_texture_color_table support from swrast driver - the only
driver that implemented it.
</ul>

336
docs/relnotes-7.9.2.html Normal file
View file

@ -0,0 +1,336 @@
<HTML>
<head>
<TITLE>Mesa Release Notes</TITLE>
<link rel="stylesheet" type="text/css" href="mesa.css">
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<BODY>
<body bgcolor="#eeeeee">
<H1>Mesa 7.9.2 Release Notes / TBD</H1>
<p>
Mesa 7.9.2 is a bug fix release which fixes bugs found since the 7.9.1 release.
</p>
<p>
Mesa 7.9.2 implements the OpenGL 2.1 API, but the version reported by
glGetString(GL_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 2.1.
</p>
<p>
See the <a href="install.html">Compiling/Installing page</a> for prerequisites
for DRI hardware acceleration.
</p>
<h2>MD5 checksums</h2>
<pre>
eb4ab8c1a03386def3ea34b1358e9cda MesaLib-7.9.2.tar.gz
8f6d1474912787ce13bd35f3bae9938a MesaLib-7.9.2.tar.bz2
427a81dd43ac97603768dc5c6af3df26 MesaLib-7.9.2.zip
aacb8f4db997e346db40c6066942140a MesaGLUT-7.9.2.tar.gz
18abe6cff4fad8ad4752c7b7ab548e5d MesaGLUT-7.9.2.tar.bz2
3189e5732d636c71baf3d8bc23ce7b11 MesaGLUT-7.9.2.zip
</pre>
<h2>New features</h2>
<p>None.</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li>Fix an off-by-one bug in a vsplit assertion.</li>
<li>Fix incorrect handling of <tt>layout</tt> qualifier
with <tt>in</tt>, <tt>out</tt>, <tt>attribute</tt>, and <tt>varying</tt>.</li>
<li>Fix an i965 GPU hang in GLSL shaders that contain an unconditional <tt>discard</tt> statement.</li>
<li>Fix an i965 shader bug where the negative absolute value was generated instead of the absolute value of a negation.</li>
<li>Fix numerous issues handling precision qualifiers in GLSL ES.</li>
<li>Fixed a few GLX protocol encoder bugs (Julien Cristau)</li>
<li>Assorted Gallium llvmpipe driver bug fixes</li>
<li>Assorted Mesa/Gallium state tracker bug fixes</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=26795">Bug 26795</a> - gl_FragCoord off by one in Gallium drivers.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29164">Bug 29164</a> - [GLSL 1.20] invariant variable shouldn't be used before declaration</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29823">Bug 29823</a> - GetUniform[if]v busted</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=29927">Bug 29927</a> - [glsl2] fail to compile shader with constructor for array of struct type</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=30156">Bug 30156</a> - [i965] After updating to Mesa 7.9, Civilization IV starts to show garbage</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=31923">Bug 31923</a> - [GLSL 1.20] allowing inconsistent centroid declaration between two vertex shaders</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=31925">Bug 31925</a> - [GLSL 1.20] "#pragma STDGL invariant(all)" fail</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32214">Bug 32214</a> - [gles2]no link error happens when missing vertex shader or frag shader</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32375">Bug 32375</a> - [gl gles2] Not able to get the attribute by function glGetVertexAttribfv</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32541">Bug 32541</a> - Segmentation Fault while running an HDR (high dynamic range) rendering demo</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32569">Bug 32569</a> - [gles2] glGetShaderPrecisionFormat not implemented yet</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32695">Bug 32695</a> - [glsl] SIGSEGV glcpp/glcpp-parse.y:833</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32831">Bug 32831</a> - [glsl] division by zero crashes GLSL compiler</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=32910">Bug 32910</a> - Keywords 'in' and 'out' not handled properly for GLSL 1.20 shaders</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33219">Bug 33219</a> -[GLSL bisected] implicit sized array triggers segfault in ir_to_mesa_visitor::copy_propagate</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33306">Bug 33306</a> - GLSL integer division by zero crashes GLSL compiler</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33308">Bug 33308</a> -[glsl] ast_to_hir.cpp:3016: virtual ir_rvalue* ast_jump_statement::hir(exec_list*, _mesa_glsl_parse_state*): Assertion `ret != __null' failed.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33316">Bug 33316</a> - uniform array will be allocate one line more and initialize it when it was freed will abort</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33386">Bug 33386</a> - Dubious assembler in read_rgba_span_x86.S</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33388">Bug 33388</a> - Dubious assembler in xform4.S</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33433">Bug 33433</a> - Error in x86-64 API dispatch code.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33507">Bug 33507</a> - [glsl] GLSL preprocessor modulus by zero crash</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33508">Bug 33508</a> - [glsl] GLSL compiler modulus by zero crash</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=33916">Bug 33916</a> - Compiler accepts reserved operators % and %=</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34047">Bug 34047</a> - Assert in _tnl_import_array() when using GLfixed vertex datatypes with GLESv2</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34114">Bug 34114</a> - Sun Studio build fails due to standard library functions not being in global namespace</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=34198">Bug 34198</a> - [GLSL] implicit sized array with index 0 used gets assertion</li>
<li><a href="https://bugs.launchpad.net/ubuntu/+source/mesa/+bug/691653">Ubuntu bug 691653</a> - compiz crashes when using alt-tab (the radeon driver kills it) </li>
<li><a href="https://bugs.meego.com/show_bug.cgi?id=13005">Meego bug 13005</a> - Graphics GLSL issue lead to camera preview fail on Pinetrail</li>
<!-- <li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=">Bug </a> - </li> -->
</ul>
<h2>Changes</h2>
<p>The full set of changes can be viewed by using the following GIT command:</p>
<pre>
git log mesa-7.9.1..mesa-7.9.2
</pre>
<p>Alberto Milone (1):
<ul>
<li>r600c: add evergreen ARL support.</li>
</ul></p>
<p>Brian Paul (19):
<ul>
<li>draw: Fix an off-by-one bug in a vsplit assertion.</li>
<li>mesa: fix a few format table mistakes, assertions</li>
<li>mesa: fix num_draw_buffers==0 in fixed-function fragment program generation</li>
<li>mesa: don't assert in GetIntegerIndexed, etc</li>
<li>mesa: check for dummy renderbuffer in _mesa_FramebufferRenderbufferEXT()</li>
<li>llvmpipe: make sure binning is active when we begin/end a query</li>
<li>st/mesa: fix incorrect fragcoord.x translation</li>
<li>softpipe: fix off-by-one error in setup_fragcoord_coeff()</li>
<li>cso: fix loop bound in cso_set_vertex_samplers()</li>
<li>st/mesa: set renderbuffer _BaseFormat in a few places</li>
<li>st/mesa: fix the default case in st_format_datatype()</li>
<li>st/mesa: need to translate clear color according to surface's base format</li>
<li>docs: update 7.9.2 release notes with Brian's cherry-picks</li>
<li>docs: add links to 7.9.1 and 7.9.2 release notes</li>
<li>mesa: include compiler.h for ASSERT macro</li>
<li>glsl: add ir_shader case in switch stmt to silence warning</li>
<li>glsl2: fix signed/unsigned comparison warning</li>
<li>mesa: implement glGetShaderPrecisionFormat()</li>
<li>docs: updated environment variable list</li>
</ul></p>
<p>Bryce Harrington (1):
<ul>
<li>r300g: Null pointer check for buffer deref in gallium winsys</li>
</ul></p>
<p>Chad Versace (14):
<ul>
<li>glsl: At link-time, check that globals have matching centroid qualifiers</li>
<li>glcpp: Fix segfault when validating macro redefinitions</li>
<li>glsl: Fix parser rule for type_specifier</li>
<li>glsl: Change default value of ast_type_specifier::precision</li>
<li>glsl: Add semantic checks for precision qualifiers</li>
<li>glsl: Add support for default precision statements</li>
<li>glsl: Remove redundant semantic check in parser</li>
<li>glsl: Fix semantic checks on precision qualifiers</li>
<li>glsl: Fix segfault due to missing printf argument</li>
<li>glsl: Mark 'in' variables at global scope as read-only</li>
<li>glcpp: Raise error when modulus is zero</li>
<li>glsl: Set operators '%' and '%=' to be reserved when GLSL &lt 1.30</li>
<li>glsl: Reinstate constant-folding for division by zero</li>
<li>tnl: Add support for datatype GL_FIXED in vertex arrays</li>
</ul></p>
<p>Chia-I Wu (1):
<ul>
<li>mesa: Add glDepthRangef and glClearDepthf to APIspec.xml.</li>
</ul></p>
<p>Chris Wilson (1):
<ul>
<li>intel: Check for unsupported texture when finishing using as a render target</li>
</ul></p>
<p>Cyril Brulebois (1):
<ul>
<li>Point to bugs.freedesktop.org rather than bugzilla.freedesktop.org</li>
</ul></p>
<p>Dave Airlie (2):
<ul>
<li>radeon/r200: fix fbo-clearmipmap + gen-teximage</li>
<li>radeon: avoid segfault on 3D textures.</li>
</ul></p>
<p>Dimitry Andric (4):
<ul>
<li>mesa: s/movzx/movzbl/</li>
<li>mesa: s/movzxw/movzwl/ in read_rgba_span_x86.S</li>
<li>glapi: adding @ char before type specifier in glapi_x86.S</li>
<li>glapi: add @GOTPCREL relocation type</li>
</ul></p>
<p>Eric Anholt (11):
<ul>
<li>i965: Avoid double-negation of immediate values in the VS.</li>
<li>docs: Add a relnote for the Civ IV on i965.</li>
<li>i965/vs: When MOVing to produce ABS, strip negate of the operand.</li>
<li>glsl: Fix the lowering of variable array indexing to not lose write_masks.</li>
<li>intel: Make renderbuffer tiling choice match texture tiling choice.</li>
<li>glapi: Add entrypoints and enums for GL_ARB_ES2_compatibility.</li>
<li>mesa: Add extension enable bit for GL_ARB_ES2_compatibility.</li>
<li>mesa: Add actual support for glReleaseShaderCompiler from ES2.</li>
<li>mesa: Add support for glDepthRangef and glClearDepthf.</li>
<li>mesa: Add getters for ARB_ES2_compatibility MAX_*_VECTORS.</li>
<li>mesa: Add getter for GL_SHADER_COMPILER with ARB_ES2_compatibility.</li>
</ul></p>
<p>Ian Romanick (42):
<ul>
<li>docs: Add 7.9.1 md5sums</li>
<li>glsl: Support the 'invariant(all)' pragma</li>
<li>glcpp: Generate an error for division by zero</li>
<li>glsl: Add version_string containing properly formatted GLSL version</li>
<li>glsl &amp; glcpp: Refresh autogenerated lexer and parser files.</li>
<li>glsl: Disallow 'in' and 'out' on globals in GLSL 1.20</li>
<li>glsl: Track variable usage, use that to enforce semantics</li>
<li>glsl: Allow 'in' and 'out' when 'layout' is also available</li>
<li>docs: Initial set of release notes for 7.9.2</li>
<li>mesa: bump version to 7.9.2-devel</li>
<li>docs: Update 7.9.2 release notes</li>
<li>i965: Make OPCODE_KIL_NV do its work in a temp, not the null reg!</li>
<li>glsl: Refresh autogenerated lexer and parser files.</li>
<li>glsl: Don't assert when the value returned by a function has no rvalue</li>
<li>linker: Set sizes for non-global arrays as well</li>
<li>linker: Propagate max_array_access while linking functions</li>
<li>docs: Update 7.9.2 release notes</li>
<li>Use C-style system headers in C++ code to avoid issues with std:: namespace</li>
<li>mesa: glGetUniform only returns a single element of an array</li>
<li>linker: Generate link errors when ES shaders are missing stages</li>
<li>mesa: Fix error checks in GetVertexAttrib functions</li>
<li>docs: Update 7.9.2 release notes</li>
<li>mesa: Remove unsupported OES extensions</li>
<li>glapi: Regenerate for GL_ARB_ES2_compatibility.</li>
<li>mesa: Connect glGetShaderPrecisionFormat into the dispatch table</li>
<li>i965: Set correct values for range/precision of fragment shader types</li>
<li>i915: Set correct values for range/precision of fragment shader types</li>
<li>intel: Fix typeos from 3d028024 and 790ff232</li>
<li>glsl: Ensure that all GLSL versions are supported in the stand-alone compiler</li>
<li>glsl: Reject shader versions not supported by the implementation</li>
<li>mesa: Initial size for secondary color array is 3</li>
<li>glcpp: Regenerate files from recent cherry picks</li>
<li>glsl: Finish out the reduce/reduce error fixes</li>
<li>glsl: Regenerate compiler files from cherry picks</li>
<li>linker: Fix off-by-one error implicit array sizing</li>
<li>i915: Only mark a register as available if all components are written</li>
<li>i915: Calculate partial result to temp register first</li>
<li>i915: Force lowering of all types of indirect array accesses in the FS</li>
<li>docs: Update 7.9.2 release notes for recent cherry picks</li>
<li>docs: Clean up bug fixes list</li>
<li>intel: Remove driver date and related bits from renderer string</li>
<li>mesa: set version string to 7.9.2 (final)</li>
</ul></p>
<p>Jian Zhao (1):
<ul>
<li>mesa: fix an error in uniform arrays in row calculating.</li>
</ul></p>
<p>Julien Cristau (3):
<ul>
<li>glx: fix request lengths</li>
<li>glx: fix GLXChangeDrawableAttributesSGIX request</li>
<li>glx: fix length of GLXGetFBConfigsSGIX</li>
</ul></p>
<p>Keith Packard (1):
<ul>
<li>glsl: Eliminate reduce/reduce conflicts in glsl grammar</li>
</ul></p>
<p>Kenneth Graunke (12):
<ul>
<li>glsl: Expose a public glsl_type::void_type const pointer.</li>
<li>glsl: Don't bother unsetting a destructor that was never set.</li>
<li>glsl, i965: Remove unnecessary talloc includes.</li>
<li>glcpp: Remove use of talloc reference counting.</li>
<li>ralloc: Add a fake implementation of ralloc based on talloc.</li>
<li>Convert everything from the talloc API to the ralloc API.</li>
<li>ralloc: a new MIT-licensed recursive memory allocator.</li>
<li>Remove talloc from the make and automake build systems.</li>
<li>Remove talloc from the SCons build system.</li>
<li>Remove the talloc sources from the Mesa repository.</li>
<li>glsl: Fix use of uninitialized values in _mesa_glsl_parse_state ctor.</li>
<li>glsl: Use reralloc instead of plain realloc.</li>
</ul></p>
<p>Marek Olšák (3):
<ul>
<li>docs: fix messed up names with special characters in relnotes-7.9.1</li>
<li>mesa: fix texture3D mipmap generation for UNSIGNED_BYTE_3_3_2</li>
<li>st/dri: Track drawable context bindings</li>
</ul></p>
<p>Paulo Zanoni (1):
<ul>
<li>dri_util: fail driCreateNewScreen if InitScreen is NULL</li>
</ul></p>
<p>Sam Hocevar (2):
<ul>
<li>docs: add glsl info</li>
<li>docs: fix glsl_compiler name</li>
</ul></p>
<p>Vinson Lee (1):
<ul>
<li>ralloc: Add missing va_end following va_copy.</li>
</ul></p>
<p>nobled (1):
<ul>
<li>glx: Put null check before use</li>
</ul></p>
</p>
</body>
</html>

View file

@ -14,7 +14,9 @@ The release notes summarize what's new or changed in each Mesa release.
<UL>
<LI><A HREF="relnotes-7.11.html">7.11 release notes</A>
<LI><A HREF="relnotes-7.10.1.html">7.10.1 release notes</A>
<LI><A HREF="relnotes-7.10.html">7.10 release notes</A>
<LI><A HREF="relnotes-7.9.2.html">7.9.2 release notes</A>
<LI><A HREF="relnotes-7.9.1.html">7.9.1 release notes</A>
<LI><A HREF="relnotes-7.9.html">7.9 release notes</A>
<LI><A HREF="relnotes-7.8.3.html">7.8.3 release notes</A>

View file

@ -143,6 +143,20 @@ typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESA) (EGLDisplay dpy, con
typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESA) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride);
#endif
#ifndef EGL_WL_bind_wayland_display
#define EGL_WL_bind_wayland_display 1
#define EGL_WAYLAND_BUFFER_WL 0x31D5 /* eglCreateImageKHR target */
struct wl_display;
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
EGLAPI EGLBoolean EGLAPIENTRY eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display);
#else
typedef EGLBoolean (EGLAPIENTRY PFNEGLBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
typedef EGLBoolean (EGLAPIENTRY PFNEGLUNBINDWAYLANDDISPLAYWL) (EGLDisplay dpy, struct wl_display *display);
#endif
#endif
#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */
#ifndef EGL_KHR_reusable_sync
#define EGL_KHR_reusable_sync 1

View file

@ -3,12 +3,13 @@
TOP = ../..
include $(TOP)/configs/current
SUBDIRS = drivers main
SUBDIRS =
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
SUBDIRS += wayland
endif
SUBDIRS += drivers main
default: subdirs

View file

@ -27,8 +27,10 @@ endif
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
EGL_SOURCES += platform_wayland.c
EGL_INCLUDES += -DHAVE_WAYLAND_PLATFORM $(WAYLAND_CFLAGS) \
-I$(TOP)/src/egl/wayland
EGL_LIBS += $(WAYLAND_LIBS)
-I$(TOP)/src/egl/wayland \
-I$(TOP)/src/egl/wayland/wayland-drm
EGL_LIBS += $(WAYLAND_LIBS) \
$(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
endif
include ../Makefile.template

View file

@ -915,6 +915,51 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return &dri2_img->base;
}
static EGLBoolean
dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
EGLint *name, EGLint *handle, EGLint *stride);
static _EGLImage *
dri2_reference_drm_image(_EGLDisplay *disp, _EGLContext *ctx,
_EGLImage *image, EGLint width, EGLint height)
{
EGLint attr_list[] = {
EGL_WIDTH, 0,
EGL_HEIGHT, 0,
EGL_DRM_BUFFER_STRIDE_MESA, 0,
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
EGL_NONE
};
EGLint name, stride;
dri2_export_drm_image_mesa(disp->Driver, disp, image,
&name, NULL, &stride);
attr_list[1] = width;
attr_list[3] = height;
attr_list[5] = stride / 4;
return dri2_create_image_mesa_drm_buffer(disp, ctx,
(EGLClientBuffer)(intptr_t) name,
attr_list);
}
#ifdef HAVE_WAYLAND_PLATFORM
static _EGLImage *
dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
EGLClientBuffer buffer,
const EGLint *attr_list)
{
struct wl_drm_buffer *wl_drm_buffer = (struct wl_drm_buffer *) buffer;
(void) attr_list;
return dri2_reference_drm_image(disp, ctx, wl_drm_buffer->image,
wl_drm_buffer->buffer.width,
wl_drm_buffer->buffer.height);
}
#endif
_EGLImage *
dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,
@ -927,6 +972,10 @@ dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
return dri2_create_image_khr_renderbuffer(disp, ctx, buffer, attr_list);
case EGL_DRM_BUFFER_MESA:
return dri2_create_image_mesa_drm_buffer(disp, ctx, buffer, attr_list);
#ifdef HAVE_WAYLAND_PLATFORM
case EGL_WAYLAND_BUFFER_WL:
return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
#endif
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
@ -1055,6 +1104,47 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img,
return EGL_TRUE;
}
#ifdef HAVE_WAYLAND_PLATFORM
static EGLBoolean
dri2_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
struct wl_display *wl_dpy)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
(void) drv;
if (dri2_dpy->wl_server_drm)
return EGL_FALSE;
dri2_dpy->wl_server_drm =
wayland_drm_init(wl_dpy, disp,
dri2_dpy->authenticate,
dri2_dpy->device_name);
if (!dri2_dpy->wl_server_drm)
return EGL_FALSE;
return EGL_TRUE;
}
static EGLBoolean
dri2_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *disp,
struct wl_display *wl_dpy)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
(void) drv;
if (!dri2_dpy->wl_server_drm)
return EGL_FALSE;
wayland_drm_destroy(dri2_dpy->wl_server_drm);
dri2_dpy->wl_server_drm = NULL;
return EGL_TRUE;
}
#endif
static void
dri2_unload(_EGLDriver *drv)
{
@ -1140,6 +1230,10 @@ _EGL_MAIN(const char *args)
dri2_drv->base.API.DestroyImageKHR = dri2_destroy_image_khr;
dri2_drv->base.API.CreateDRMImageMESA = dri2_create_drm_image_mesa;
dri2_drv->base.API.ExportDRMImageMESA = dri2_export_drm_image_mesa;
#ifdef HAVE_WAYLAND_PLATFORM
dri2_drv->base.API.BindWaylandDisplayWL = dri2_bind_wayland_display_wl;
dri2_drv->base.API.UnbindWaylandDisplayWL = dri2_unbind_wayland_display_wl;
#endif
dri2_drv->base.Name = "DRI2";
dri2_drv->base.Unload = dri2_unload;

View file

@ -35,6 +35,7 @@
#ifdef HAVE_WAYLAND_PLATFORM
#include <wayland-client.h>
#include "wayland-drm.h"
#include "wayland-egl-priv.h"
#endif
@ -85,7 +86,10 @@ struct dri2_egl_display
const __DRIextension *extensions[3];
#ifdef HAVE_WAYLAND_PLATFORM
struct wl_egl_display *wl_dpy;
struct wl_drm *wl_server_drm;
#endif
int (*authenticate) (struct dri2_egl_display *dri_dpy, uint32_t id);
};
struct dri2_egl_context

View file

@ -568,6 +568,39 @@ const struct dri2_driver_map driver_map[] = {
{ 0x10de, "nouveau", NULL, -1 },
};
static char *
dri2_get_device_name(int fd)
{
struct udev *udev;
struct udev_device *device;
struct stat buf;
char *device_name;
udev = udev_new();
if (fstat(fd, &buf) < 0) {
_eglLog(_EGL_WARNING, "EGL-DRI2: failed to stat fd %d", fd);
goto out;
}
device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
if (device == NULL) {
_eglLog(_EGL_WARNING,
"EGL-DRI2: could not create udev device for fd %d", fd);
goto out;
}
device_name = udev_device_get_devnode(device);
if (!device_name)
goto out;
device_name = strdup(device_name);
out:
udev_device_unref(device);
udev_unref(udev);
return device_name;
}
char *
dri2_get_driver_for_fd(int fd)
{
@ -629,6 +662,14 @@ dri2_get_driver_for_fd(int fd)
return driver;
}
static int
dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
return drmAuthMagic(dri2_dpy->fd, id);
}
EGLBoolean
dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
{
@ -648,8 +689,14 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
if (dri2_dpy->driver_name == NULL)
return _eglError(EGL_BAD_ALLOC, "DRI2: failed to get driver name");
if (!dri2_load_driver(disp))
dri2_dpy->device_name = dri2_get_device_name(dri2_dpy->fd);
if (dri2_dpy->device_name == NULL) {
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name");
goto cleanup_driver_name;
}
if (!dri2_load_driver(disp))
goto cleanup_device_name;
dri2_dpy->extensions[0] = &image_lookup_extension.base;
dri2_dpy->extensions[1] = &use_invalidate.base;
@ -666,6 +713,11 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif
dri2_dpy->authenticate = dri2_drm_authenticate;
/* we're supporting EGL 1.4 */
disp->VersionMajor = 1;
disp->VersionMinor = 4;
@ -674,6 +726,8 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
cleanup_driver:
dlclose(dri2_dpy->driver);
cleanup_device_name:
free(dri2_dpy->device_name);
cleanup_driver_name:
free(dri2_dpy->driver_name);

View file

@ -35,6 +35,9 @@
#include "egl_dri2.h"
#include <wayland-client.h>
#include "wayland-drm-client-protocol.h"
static void
sync_callback(void *data)
{
@ -561,6 +564,26 @@ dri2_wayland_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
}
}
static int
dri2_wayland_authenticate(_EGLDisplay *disp, uint32_t id)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
int ret = 0;
dri2_dpy->wl_dpy->authenticated = false;
wl_drm_authenticate(dri2_dpy->wl_dpy->drm, id);
force_roundtrip(dri2_dpy->wl_dpy->display);
if (!dri2_dpy->wl_dpy->authenticated)
ret = -1;
/* reset authenticated */
dri2_dpy->wl_dpy->authenticated = true;
return ret;
}
/**
* Called via eglTerminate(), drv->API.Terminate().
*/
@ -626,8 +649,14 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
goto cleanup_fd;
}
if (!dri2_load_driver(disp))
dri2_dpy->device_name = strdup(dri2_dpy->wl_dpy->device_name);
if (dri2_dpy->device_name == NULL) {
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get device name");
goto cleanup_driver_name;
}
if (!dri2_load_driver(disp))
goto cleanup_device_name;
dri2_dpy->dri2_loader_extension.base.name = __DRI_DRI2_LOADER;
dri2_dpy->dri2_loader_extension.base.version = 3;
@ -654,6 +683,9 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
dri2_dpy->authenticate = dri2_wayland_authenticate;
/* we're supporting EGL 1.4 */
disp->VersionMajor = 1;
disp->VersionMinor = 4;
@ -662,6 +694,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp)
cleanup_driver:
dlclose(dri2_dpy->driver);
cleanup_device_name:
free(dri2_dpy->device_name);
cleanup_driver_name:
free(dri2_dpy->driver_name);
cleanup_fd:

View file

@ -478,6 +478,7 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
xcb_dri2_connect_cookie_t connect_cookie;
xcb_generic_error_t *error;
xcb_screen_iterator_t s;
char *driver_name, *device_name;
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_xfixes_id);
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri2_id);
@ -524,14 +525,21 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
return EGL_FALSE;
}
dri2_dpy->device_name =
dri2_strndup(xcb_dri2_connect_device_name (connect),
xcb_dri2_connect_device_name_length (connect));
driver_name = xcb_dri2_connect_driver_name (connect);
dri2_dpy->driver_name =
dri2_strndup(xcb_dri2_connect_driver_name (connect),
dri2_strndup(driver_name,
xcb_dri2_connect_driver_name_length (connect));
#if XCB_DRI2_CONNECT_DEVICE_NAME_BROKEN
device_name = driver_name + ((connect->driver_name_length + 3) & ~3);
#else
device_name = xcb_dri2_connect_device_name (connect);
#endif
dri2_dpy->device_name =
dri2_strndup(device_name,
xcb_dri2_connect_device_name_length (connect));
if (dri2_dpy->device_name == NULL || dri2_dpy->driver_name == NULL) {
free(dri2_dpy->device_name);
free(dri2_dpy->driver_name);
@ -543,32 +551,46 @@ dri2_connect(struct dri2_egl_display *dri2_dpy)
return EGL_TRUE;
}
static EGLBoolean
dri2_authenticate(struct dri2_egl_display *dri2_dpy)
static int
dri2_x11_authenticate(_EGLDisplay *disp, uint32_t id)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
xcb_dri2_authenticate_reply_t *authenticate;
xcb_dri2_authenticate_cookie_t authenticate_cookie;
xcb_screen_iterator_t s;
int ret = 0;
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
authenticate_cookie =
xcb_dri2_authenticate_unchecked(dri2_dpy->conn, s.data->root, id);
authenticate =
xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
if (authenticate == NULL || !authenticate->authenticated)
ret = -1;
if (authenticate)
free(authenticate);
return ret;
}
static EGLBoolean
dri2_authenticate(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
drm_magic_t magic;
if (drmGetMagic(dri2_dpy->fd, &magic)) {
_eglLog(_EGL_WARNING, "DRI2: failed to get drm magic");
return EGL_FALSE;
}
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
authenticate_cookie =
xcb_dri2_authenticate_unchecked(dri2_dpy->conn, s.data->root, magic);
authenticate =
xcb_dri2_authenticate_reply(dri2_dpy->conn, authenticate_cookie, NULL);
if (authenticate == NULL || !authenticate->authenticated) {
if (dri2_x11_authenticate(disp, magic) < 0) {
_eglLog(_EGL_WARNING, "DRI2: failed to authenticate");
free(authenticate);
return EGL_FALSE;
}
free(authenticate);
return EGL_TRUE;
}
@ -977,7 +999,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
}
if (dri2_dpy->conn) {
if (!dri2_authenticate(dri2_dpy))
if (!dri2_authenticate(disp))
goto cleanup_fd;
}
@ -1016,6 +1038,11 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.NOK_swap_region = EGL_TRUE;
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif
dri2_dpy->authenticate = dri2_x11_authenticate;
/* we're supporting EGL 1.4 */
disp->VersionMajor = 1;
disp->VersionMinor = 4;

View file

@ -58,6 +58,9 @@ LOCAL_LIBS =
ifeq ($(filter dri2, $(EGL_DRIVERS_DIRS)),dri2)
LOCAL_CFLAGS += -D_EGL_BUILT_IN_DRIVER_DRI2
LOCAL_LIBS += $(TOP)/src/egl/drivers/dri2/libegl_dri2.a
ifneq ($(findstring wayland, $(EGL_PLATFORMS)),)
LOCAL_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a
endif
EGL_LIB_DEPS += $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) $(WAYLAND_LIBS)
endif
ifeq ($(filter glx, $(EGL_DRIVERS_DIRS)),glx)

View file

@ -913,6 +913,10 @@ eglGetProcAddress(const char *procname)
#ifdef EGL_MESA_drm_image
{ "eglCreateDRMImageMESA", (_EGLProc) eglCreateDRMImageMESA },
{ "eglExportDRMImageMESA", (_EGLProc) eglExportDRMImageMESA },
#endif
#ifdef EGL_WL_bind_display
{ "eglBindWaylandDisplayWL", (_EGLProc) eglBindWaylandDisplayWL },
{ "eglUnbindWaylandDisplayWL", (_EGLProc) eglUnbindWaylandDisplayWL },
#endif
{ NULL, NULL }
};
@ -1491,3 +1495,43 @@ eglExportDRMImageMESA(EGLDisplay dpy, EGLImageKHR image,
}
#endif
#ifdef EGL_WL_bind_wayland_display
struct wl_display;
EGLBoolean EGLAPIENTRY
eglBindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLDriver *drv;
EGLBoolean ret;
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
if (!display)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
ret = drv->API.BindWaylandDisplayWL(drv, disp, display);
RETURN_EGL_EVAL(disp, ret);
}
EGLBoolean EGLAPIENTRY
eglUnbindWaylandDisplayWL(EGLDisplay dpy, struct wl_display *display)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
_EGLDriver *drv;
EGLBoolean ret;
_EGL_CHECK_DISPLAY(disp, EGL_FALSE, drv);
assert(disp->Extensions.WL_bind_wayland_display);
if (!display)
RETURN_EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE);
ret = drv->API.UnbindWaylandDisplayWL(drv, disp, display);
RETURN_EGL_EVAL(disp, ret);
}
#endif

View file

@ -95,6 +95,12 @@ typedef _EGLImage *(*CreateDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, c
typedef EGLBoolean (*ExportDRMImageMESA_t)(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, EGLint *name, EGLint *handle, EGLint *stride);
#endif
#ifdef EGL_WL_bind_wayland_display
struct wl_display;
typedef EGLBoolean (*BindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
typedef EGLBoolean (*UnbindWaylandDisplayWL_t)(_EGLDriver *drv, _EGLDisplay *disp, struct wl_display *display);
#endif
/**
* The API dispatcher jumps through these functions
*/
@ -169,6 +175,11 @@ struct _egl_api
CreateDRMImageMESA_t CreateDRMImageMESA;
ExportDRMImageMESA_t ExportDRMImageMESA;
#endif
#ifdef EGL_WL_bind_wayland_display
BindWaylandDisplayWL_t BindWaylandDisplayWL;
UnbindWaylandDisplayWL_t UnbindWaylandDisplayWL;
#endif
};
#endif /* EGLAPI_INCLUDED */

View file

@ -58,6 +58,8 @@ struct _egl_extensions
EGLBoolean MESA_drm_display;
EGLBoolean MESA_drm_image;
EGLBoolean WL_bind_wayland_display;
EGLBoolean KHR_image_base;
EGLBoolean KHR_image_pixmap;
EGLBoolean KHR_vg_parent_image;

View file

@ -89,6 +89,8 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
_EGL_CHECK_EXTENSION(MESA_drm_display);
_EGL_CHECK_EXTENSION(MESA_drm_image);
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
_EGL_CHECK_EXTENSION(KHR_image_base);
_EGL_CHECK_EXTENSION(KHR_image_pixmap);
if (dpy->Extensions.KHR_image_base && dpy->Extensions.KHR_image_pixmap)

View file

@ -1,4 +1,4 @@
# src/egl/main/Makefile
# src/egl/wayland/Makefile
TOP = ../../..
include $(TOP)/configs/current
@ -10,14 +10,20 @@ SOURCES = wayland-egl.c
OBJECTS = $(SOURCES:.c=.o)
LOCAL_CFLAGS = -I$(TOP)/include/EGL $(LIBDRM_CFLAGS) $(WAYLAND_CFLAGS)
LOCAL_CFLAGS = -I$(TOP)/include/EGL \
-I$(TOP)/src/egl/wayland/wayland-drm \
$(LIBDRM_CFLAGS) \
$(WAYLAND_CFLAGS)
LOCAL_LIBS =
SUBDIRS = wayland-drm
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
default: depend library
default: subdirs depend library
# wayland-egl Library
library: $(TOP)/$(LIB_DIR)/$(WAYLAND_EGL_LIB_NAME)
@ -54,6 +60,12 @@ clean:
-rm -f *.o
-rm -f depend depend.bak
subdirs:
@for dir in $(SUBDIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE)) || exit 1 ; \
fi \
done
depend: $(SOURCES) $(HEADERS)
@ echo "running $(MKDEP)"

View file

@ -0,0 +1,3 @@
wayland-drm-client-protocol.h
wayland-drm-server-protocol.h
wayland-drm-protocol.c

View file

@ -0,0 +1,45 @@
# src/egl/wayland/wayland-drm/Makefile
TOP = ../../../..
include $(TOP)/configs/current
GEN_SOURCES = wayland-drm-protocol.c
GEN_HEADERS = wayland-drm-client-protocol.h wayland-drm-server-protocol.h
wayland_drm_SOURCES = wayland-drm.c $(GEN_SOURCES)
wayland_drm_OBJECTS = $(wayland_drm_SOURCES:.c=.o)
wayland_drm_INCLUDES = \
$(WAYLAND_CFLAGS) \
-I$(TOP)/src/egl/main
# Generate protocol sources
prefix=$(shell pkg-config --variable=prefix wayland-server)
exec_prefx=$(shell pkg-config --variable=exec_prefix wayland-server)
wayland_protocoldir = $(PWD)/protocol
wayland_scanner=$(exec_prefix)/bin/wayland-scanner
default: depend libwayland-drm.a $(GEN_SOURCES) $(GEN_HEADERS)
libwayland-drm.a: $(wayland_drm_OBJECTS) Makefile
$(MKLIB) -o wayland-drm -static $(wayland_drm_OBJECTS)
depend:
rm -f depend
touch depend
$(MKDEP) $(MKDEP_OPTIONS) $(wayland_drm_INCLUDES) $(wayland_drm_SOURCES) 2> /dev/null
clean:
rm -rf libwayland-drm.a $(wayland_drm_OBJECTS) \
$(GEN_SOURCES) $(GEN_HEADERS)
install:
@echo -n ""
$(wayland_drm_OBJECTS): %.o: %.c $(GEN_HEADERS)
$(CC) -c $(wayland_drm_INCLUDES) $(CFLAGS) $< -o $@
include $(prefix)/share/aclocal/wayland-scanner.mk
sinclude depend

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="drm">
<!-- drm support. This object is created by the server and published
using the display's global event. -->
<interface name="drm" version="1">
<!-- Call this request with the magic received from drmGetMagic().
It will be passed on to the drmAuthMagic() or
DRIAuthConnection() call. This authentication must be
completed before create_buffer could be used. -->
<request name="authenticate">
<arg name="id" type="uint"/>
</request>
<!-- Create a wayland buffer for the named DRM buffer. The DRM
surface must have a name using the flink ioctl -->
<request name="create_buffer">
<arg name="id" type="new_id" interface="buffer"/>
<arg name="name" type="uint"/>
<arg name="width" type="int"/>
<arg name="height" type="int"/>
<arg name="stride" type="uint"/>
<arg name="visual" type="object" interface="visual"/>
</request>
<!-- Notification of the path of the drm device which is used by
the server. The client should use this device for creating
local buffers. Only buffers created from this device should
be be passed to the server using this drm object's
create_buffer request. -->
<event name="device">
<arg name="name" type="string"/>
</event>
<!-- Raised if the authenticate request succeeded -->
<event name="authenticated"/>
</interface>
</protocol>

View file

@ -0,0 +1,203 @@
/*
* Copyright © 2011 Kristian Høgsberg
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE 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:
* Kristian Høgsberg <krh@bitplanet.net>
* Benjamin Franzke <benjaminfranzke@googlemail.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <wayland-server.h>
#include "wayland-drm.h"
#include "wayland-drm-server-protocol.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglimage.h"
#include "egltypedefs.h"
struct wl_drm {
struct wl_object object;
struct wl_display *display;
_EGLDisplay *edisp;
char *device_name;
authenticate_t authenticate;
};
static void
drm_buffer_damage(struct wl_buffer *buffer_base,
struct wl_surface *surface,
int32_t x, int32_t y, int32_t width, int32_t height)
{
}
static void
destroy_buffer(struct wl_resource *resource, struct wl_client *client)
{
struct wl_drm_buffer *buffer = (struct wl_drm_buffer *) resource;
_EGLDriver *drv = buffer->drm->edisp->Driver;
drv->API.DestroyImageKHR(drv, buffer->drm->edisp, buffer->image);
free(buffer);
}
static void
buffer_destroy(struct wl_client *client, struct wl_buffer *buffer)
{
wl_resource_destroy(&buffer->resource, client);
}
const static struct wl_buffer_interface buffer_interface = {
buffer_destroy
};
static void
drm_create_buffer(struct wl_client *client, struct wl_drm *drm,
uint32_t id, uint32_t name, int32_t width, int32_t height,
uint32_t stride, struct wl_visual *visual)
{
struct wl_drm_buffer *buffer;
EGLint attribs[] = {
EGL_WIDTH, 0,
EGL_HEIGHT, 0,
EGL_DRM_BUFFER_STRIDE_MESA, 0,
EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA,
EGL_NONE
};
_EGLDriver *drv = drm->edisp->Driver;
buffer = malloc(sizeof *buffer);
if (buffer == NULL) {
wl_client_post_no_memory(client);
return;
}
buffer->drm = drm;
buffer->buffer.compositor = NULL;
buffer->buffer.width = width;
buffer->buffer.height = height;
buffer->buffer.visual = visual;
buffer->buffer.attach = NULL;
buffer->buffer.damage = drm_buffer_damage;
if (visual->object.interface != &wl_visual_interface) {
/* FIXME: Define a real exception event instead of
* abusing this one */
wl_client_post_event(client,
(struct wl_object *) drm->display,
WL_DISPLAY_INVALID_OBJECT, 0);
fprintf(stderr, "invalid visual in create_buffer\n");
return;
}
attribs[1] = width;
attribs[3] = height;
attribs[5] = stride / 4;
buffer->image = drv->API.CreateImageKHR(drv, drm->edisp,
EGL_NO_CONTEXT,
EGL_DRM_BUFFER_MESA,
(EGLClientBuffer) (intptr_t) name,
attribs);
if (buffer->image == NULL) {
/* FIXME: Define a real exception event instead of
* abusing this one */
wl_client_post_event(client,
(struct wl_object *) drm->display,
WL_DISPLAY_INVALID_OBJECT, 0);
fprintf(stderr, "failed to create image for name %d\n", name);
return;
}
buffer->buffer.resource.object.id = id;
buffer->buffer.resource.object.interface = &wl_buffer_interface;
buffer->buffer.resource.object.implementation = (void (**)(void))
&buffer_interface;
buffer->buffer.resource.destroy = destroy_buffer;
wl_client_add_resource(client, &buffer->buffer.resource);
}
static void
drm_authenticate(struct wl_client *client,
struct wl_drm *drm, uint32_t id)
{
if (drm->authenticate(drm->edisp, id) < 0)
wl_client_post_event(client,
(struct wl_object *) drm->display,
WL_DISPLAY_INVALID_OBJECT, 0);
else
wl_client_post_event(client, &drm->object,
WL_DRM_AUTHENTICATED);
}
const static struct wl_drm_interface drm_interface = {
drm_authenticate,
drm_create_buffer
};
static void
post_drm_device(struct wl_client *client, struct wl_object *global)
{
struct wl_drm *drm = (struct wl_drm *) global;
wl_client_post_event(client, global, WL_DRM_DEVICE, drm->device_name);
}
struct wl_drm *
wayland_drm_init(struct wl_display *display, _EGLDisplay *disp,
authenticate_t authenticate, char *device_name)
{
struct wl_drm *drm;
drm = malloc(sizeof *drm);
drm->display = display;
drm->edisp = disp;
drm->authenticate = authenticate;
drm->device_name = strdup(device_name);
drm->object.interface = &wl_drm_interface;
drm->object.implementation = (void (**)(void)) &drm_interface;
wl_display_add_object(display, &drm->object);
wl_display_add_global(display, &drm->object, post_drm_device);
return drm;
}
void
wayland_drm_destroy(struct wl_drm *drm)
{
free(drm->device_name);
/* FIXME: need wl_display_del_{object,global} */
free(drm);
}

View file

@ -0,0 +1,26 @@
#ifndef WAYLAND_DRM_H
#define WAYLAND_DRM_H
#include "egldisplay.h"
#include "eglimage.h"
#include <wayland-server.h>
struct wl_drm;
typedef int (*authenticate_t) (_EGLDisplay *disp, uint32_t id);
struct wl_drm_buffer {
struct wl_buffer buffer;
struct wl_drm *drm;
_EGLImage *image;
};
struct wl_drm *
wayland_drm_init(struct wl_display *display, _EGLDisplay *disp,
authenticate_t authenticate, char *device_name);
void
wayland_drm_destroy(struct wl_drm *drm);
#endif

View file

@ -12,10 +12,10 @@
#include <dlfcn.h>
#include <wayland-client.h>
#include <xf86drm.h>
#include "wayland-egl.h"
#include "wayland-egl-priv.h"
#include "wayland-drm-client-protocol.h"
#include <xf86drm.h>
static void
drm_handle_device(void *data, struct wl_drm *drm, const char *device)

View file

@ -111,6 +111,7 @@ C_SOURCES = \
util/u_format.c \
util/u_format_other.c \
util/u_format_s3tc.c \
util/u_format_rgtc.c \
util/u_format_srgb.c \
util/u_format_table.c \
util/u_format_tests.c \

View file

@ -158,6 +158,7 @@ source = [
'util/u_format.c',
'util/u_format_other.c',
'util/u_format_s3tc.c',
'util/u_format_rgtc.c',
'util/u_format_srgb.c',
'util/u_format_table.c',
'util/u_format_tests.c',

View file

@ -874,6 +874,8 @@ draw_install_aapoint_stage(struct draw_context *draw,
{
struct aapoint_stage *aapoint;
pipe->draw = (void *) draw;
/*
* Create / install AA point drawing / prim stage
*/

View file

@ -672,6 +672,31 @@ tgsi_exec_machine_bind_shader(
mach->Processor = parse.FullHeader.Processor.Processor;
mach->ImmLimit = 0;
if (mach->Processor == TGSI_PROCESSOR_GEOMETRY &&
!mach->UsedGeometryShader) {
struct tgsi_exec_vector *inputs =
align_malloc(sizeof(struct tgsi_exec_vector) *
TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS,
16);
struct tgsi_exec_vector *outputs =
align_malloc(sizeof(struct tgsi_exec_vector) *
TGSI_MAX_TOTAL_VERTICES, 16);
if (!inputs)
return;
if (!outputs) {
align_free(inputs);
return;
}
align_free(mach->Inputs);
align_free(mach->Outputs);
mach->Inputs = inputs;
mach->Outputs = outputs;
mach->UsedGeometryShader = TRUE;
}
declarations = (struct tgsi_full_declaration *)
MALLOC( maxDeclarations * sizeof(struct tgsi_full_declaration) );
@ -801,6 +826,11 @@ tgsi_exec_machine_create( void )
mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES;
mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0];
mach->Inputs = align_malloc(sizeof(struct tgsi_exec_vector) * PIPE_MAX_ATTRIBS, 16);
mach->Outputs = align_malloc(sizeof(struct tgsi_exec_vector) * PIPE_MAX_ATTRIBS, 16);
if (!mach->Inputs || !mach->Outputs)
goto fail;
/* Setup constants needed by the SSE2 executor. */
for( i = 0; i < 4; i++ ) {
mach->Temps[TGSI_EXEC_TEMP_00000000_I].xyzw[TGSI_EXEC_TEMP_00000000_C].u[i] = 0x00000000;
@ -824,7 +854,11 @@ tgsi_exec_machine_create( void )
return mach;
fail:
align_free(mach);
if (mach) {
align_free(mach->Inputs);
align_free(mach->Outputs);
align_free(mach);
}
return NULL;
}
@ -836,10 +870,13 @@ tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach)
if (mach->Instructions)
FREE(mach->Instructions);
if (mach->Declarations)
FREE(mach->Declarations);
}
FREE(mach->Declarations);
align_free(mach);
align_free(mach->Inputs);
align_free(mach->Outputs);
align_free(mach);
}
}
static void

View file

@ -228,8 +228,8 @@ struct tgsi_exec_machine
float ImmArray[TGSI_EXEC_NUM_IMMEDIATES][4];
struct tgsi_exec_vector Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS];
struct tgsi_exec_vector Outputs[TGSI_MAX_TOTAL_VERTICES];
struct tgsi_exec_vector *Inputs;
struct tgsi_exec_vector *Outputs;
/* System values */
unsigned SysSemanticToIndex[TGSI_SEMANTIC_COUNT];
@ -309,6 +309,8 @@ struct tgsi_exec_machine
uint NumDeclarations;
struct tgsi_declaration_resource Resources[PIPE_MAX_SHADER_RESOURCES];
boolean UsedGeometryShader;
};
struct tgsi_exec_machine *

View file

@ -632,7 +632,7 @@ def generate_format_fetch(format, dst_channel, dst_native_type, dst_suffix):
def is_format_hand_written(format):
return format.layout in ('s3tc', 'subsampled', 'other') or format.colorspace == ZS
return format.layout in ('s3tc', 'rgtc', 'subsampled', 'other') or format.colorspace == ZS
def generate(formats):

View file

@ -0,0 +1,452 @@
/**************************************************************************
*
* Copyright (C) 2011 Red Hat 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
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <stdio.h>
#include "u_math.h"
#include "u_format.h"
#include "u_format_rgtc.h"
static void u_format_unsigned_encode_rgtc_chan(uint8_t *blkaddr, uint8_t srccolors[4][4],
int numxpixels, int numypixels);
static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata,
unsigned i, unsigned j, uint8_t *value, unsigned comps);
static void u_format_signed_encode_rgtc_chan(int8_t *blkaddr, int8_t srccolors[4][4],
int numxpixels, int numypixels);
static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata,
unsigned i, unsigned j, int8_t *value, unsigned comps);
void
util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
{
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
}
void
util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, comps = 4;
unsigned x, y, i, j;
unsigned block_size = 8;
for(y = 0; y < height; y += bh) {
const uint8_t *src = src_row;
for(x = 0; x < width; x += bw) {
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1);
}
}
src += block_size;
}
src_row += src_stride;
}
}
void
util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row,
unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 8;
unsigned x, y, i, j;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += bw) {
uint8_t tmp[4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
}
}
u_format_unsigned_encode_rgtc_chan(dst, tmp, 4, 4);
dst += bytes_per_block;
}
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
unsigned x, y, i, j;
int block_size = 8;
for(y = 0; y < height; y += 4) {
const uint8_t *src = src_row;
for(x = 0; x < width; x += 4) {
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
uint8_t tmp_r;
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
dst[0] = ubyte_to_float(tmp_r);
dst[1] = 0.0;
dst[2] = 0.0;
dst[3] = 1.0;
}
}
src += block_size;
}
src_row += src_stride;
}
}
void
util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 8;
unsigned x, y, i, j;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += bw) {
uint8_t tmp[4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
}
}
u_format_unsigned_encode_rgtc_chan(dst, tmp, 4, 4);
dst += bytes_per_block;
}
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
{
uint8_t tmp_r;
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
dst[0] = ubyte_to_float(tmp_r);
dst[1] = 0.0;
dst[2] = 0.0;
dst[3] = 1.0;
}
void
util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
{
fprintf(stderr,"%s\n", __func__);
}
void
util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
fprintf(stderr,"%s\n", __func__);
}
void
util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
fprintf(stderr,"%s\n", __func__);
}
void
util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 8;
unsigned x, y, i, j;
for(y = 0; y < height; y += bh) {
int8_t *dst = (int8_t *)dst_row;
for(x = 0; x < width; x += bw) {
int8_t tmp[4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
}
}
u_format_signed_encode_rgtc_chan(dst, tmp, 4, 4);
dst += bytes_per_block;
}
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
unsigned x, y, i, j;
int block_size = 8;
for(y = 0; y < height; y += 4) {
const int8_t *src = (int8_t *)src_row;
for(x = 0; x < width; x += 4) {
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
int8_t tmp_r;
u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1);
dst[0] = byte_to_float_tex(tmp_r);
dst[1] = 0.0;
dst[2] = 0.0;
dst[3] = 1.0;
}
}
src += block_size;
}
src_row += src_stride;
}
}
void
util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
{
int8_t tmp_r;
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1);
dst[0] = byte_to_float_tex(tmp_r);
dst[1] = 0.0;
dst[2] = 0.0;
dst[3] = 1.0;
}
void
util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
{
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
}
void
util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, comps = 4;
unsigned x, y, i, j;
unsigned block_size = 16;
for(y = 0; y < height; y += bh) {
const uint8_t *src = src_row;
for(x = 0; x < width; x += bw) {
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2);
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2);
}
}
src += block_size;
}
src_row += src_stride;
}
}
void
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += bw) {
uint8_t tmp_r[4][4]; /* [bh][bw] */
uint8_t tmp_g[4][4]; /* [bh][bw] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4];
tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1];
}
}
u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4);
u_format_unsigned_encode_rgtc_chan(dst + 8, tmp_g, 4, 4);
dst += bytes_per_block;
}
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += bw) {
uint8_t tmp_r[4][4]; /* [bh][bw][comps] */
uint8_t tmp_g[4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]);
}
}
u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4);
u_format_unsigned_encode_rgtc_chan(dst + 8, tmp_g, 4, 4);
dst += bytes_per_block;
}
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
unsigned x, y, i, j;
int block_size = 16;
for(y = 0; y < height; y += 4) {
const uint8_t *src = src_row;
for(x = 0; x < width; x += 4) {
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
uint8_t tmp_r, tmp_g;
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
dst[0] = ubyte_to_float(tmp_r);
dst[1] = ubyte_to_float(tmp_g);
dst[2] = 0.0;
dst[3] = 1.0;
}
}
src += block_size;
}
src_row += src_stride;
}
}
void
util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
{
uint8_t tmp_r, tmp_g;
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
dst[0] = ubyte_to_float(tmp_r);
dst[1] = ubyte_to_float(tmp_g);
dst[2] = 0.0;
dst[3] = 1.0;
}
void
util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j)
{
fprintf(stderr,"%s\n", __func__);
}
void
util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
fprintf(stderr,"%s\n", __func__);
}
void
util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
fprintf(stderr,"%s\n", __func__);
}
void
util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)
{
unsigned x, y, i, j;
int block_size = 16;
for(y = 0; y < height; y += 4) {
const int8_t *src = (int8_t *)src_row;
for(x = 0; x < width; x += 4) {
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
int8_t tmp_r, tmp_g;
u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2);
u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2);
dst[0] = byte_to_float_tex(tmp_r);
dst[1] = byte_to_float_tex(tmp_g);
dst[2] = 0.0;
dst[3] = 1.0;
}
}
src += block_size;
}
src_row += src_stride;
}
}
void
util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 16;
unsigned x, y, i, j;
for(y = 0; y < height; y += bh) {
int8_t *dst = (int8_t *)dst_row;
for(x = 0; x < width; x += bw) {
int8_t tmp_r[4][4]; /* [bh][bw][comps] */
int8_t tmp_g[4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]);
tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]);
}
}
u_format_signed_encode_rgtc_chan(dst, tmp_r, 4, 4);
u_format_signed_encode_rgtc_chan(dst + 8, tmp_g, 4, 4);
dst += bytes_per_block;
}
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j)
{
int8_t tmp_r, tmp_g;
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2);
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2);
dst[0] = byte_to_float_tex(tmp_r);
dst[1] = byte_to_float_tex(tmp_g);
dst[2] = 0.0;
dst[3] = 1.0;
}
#define TAG(x) u_format_unsigned_##x
#define TYPE uint8_t
#define T_MIN 0
#define T_MAX 255
#include "../../../mesa/main/texcompress_rgtc_tmp.h"
#undef TYPE
#undef TAG
#undef T_MIN
#undef T_MAX
#define TAG(x) u_format_signed_##x
#define TYPE int8_t
#define T_MIN (int8_t)-128
#define T_MAX (int8_t)127
#include "../../../mesa/main/texcompress_rgtc_tmp.h"
#undef TYPE
#undef TAG
#undef T_MIN
#undef T_MAX

View file

@ -0,0 +1,108 @@
/**************************************************************************
*
* Copyright 2011 Red Hat 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 U_FORMAT_RGTC_H_
#define U_FORMAT_RGTC_H_
void
util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j);
void
util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height);
void
util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
#endif

View file

@ -87,6 +87,7 @@ def write_format_table(formats):
print
print '#include "u_format.h"'
print '#include "u_format_s3tc.h"'
print '#include "u_format_rgtc.h"'
print
u_format_pack.generate(formats)
@ -132,7 +133,7 @@ def write_format_table(formats):
if format.colorspace != ZS:
print " &util_format_%s_unpack_rgba_8unorm," % format.short_name()
print " &util_format_%s_pack_rgba_8unorm," % format.short_name()
if format.layout == 's3tc':
if format.layout == 's3tc' or format.layout == 'rgtc':
print " &util_format_%s_fetch_rgba_8unorm," % format.short_name()
else:
print " NULL, /* fetch_rgba_8unorm */"

View file

@ -475,6 +475,17 @@ float_to_ubyte(float f)
}
}
static INLINE float
byte_to_float_tex(int8_t b)
{
return (b == -128) ? -1.0F : b * 1.0F / 127.0F;
}
static INLINE int8_t
float_to_byte_tex(float f)
{
return (int8_t) (127.0F * f);
}
/**
* Calc log base 2

View file

@ -515,6 +515,7 @@ void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
int min_index, int max_index,
unsigned instance_count,
boolean *upload_flushed)
{
int i, nr = mgr->ve->count;
@ -530,10 +531,12 @@ static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
!uploaded[index]) {
unsigned first, size;
boolean flushed;
unsigned instance_div = mgr->ve->ve[i].instance_divisor;
if (mgr->ve->ve[i].instance_divisor) {
if (instance_div) {
first = 0;
size = vb->buffer->width0;
size = vb->stride *
((instance_count + instance_div - 1) / instance_div);
} else if (vb->stride) {
first = vb->stride * min_index;
size = vb->stride * count;
@ -581,7 +584,8 @@ void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
/* Upload user buffers. */
if (mgr->any_user_vbs) {
u_vbuf_upload_buffers(mgr, min_index, max_index, &upload_flushed);
u_vbuf_upload_buffers(mgr, min_index, max_index, info->instance_count,
&upload_flushed);
bufs_updated = TRUE;
}

View file

@ -31,8 +31,8 @@
#include "i915_batchbuffer.h"
#define BEGIN_BATCH(dwords, relocs) \
(i915_winsys_batchbuffer_check(i915->batch, dwords, relocs))
#define BEGIN_BATCH(dwords) \
(i915_winsys_batchbuffer_check(i915->batch, dwords))
#define OUT_BATCH(dword) \
i915_winsys_batchbuffer_dword(i915->batch, dword)

View file

@ -41,11 +41,9 @@ i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch)
static INLINE boolean
i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch,
size_t dwords,
size_t relocs)
size_t dwords)
{
return dwords * 4 <= i915_winsys_batchbuffer_space(batch) &&
relocs <= (batch->max_relocs - batch->relocs);
return dwords * 4 <= i915_winsys_batchbuffer_space(batch);
}
static INLINE void
@ -71,7 +69,7 @@ i915_winsys_batchbuffer_write(struct i915_winsys_batchbuffer *batch,
{
assert (i915_winsys_batchbuffer_space(batch) >= size);
memcpy(data, batch->ptr, size);
memcpy(batch->ptr, data, size);
batch->ptr += size;
}

View file

@ -71,9 +71,9 @@ i915_fill_blit(struct i915_context *i915,
return;
}
if (!BEGIN_BATCH(6, 1)) {
if (!BEGIN_BATCH(6)) {
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(6, 1));
assert(BEGIN_BATCH(6));
}
OUT_BATCH(CMD);
OUT_BATCH(BR13);
@ -143,9 +143,9 @@ i915_copy_blit(struct i915_context *i915,
*/
assert (dst_pitch > 0 && src_pitch > 0);
if (!BEGIN_BATCH(8, 2)) {
if (!BEGIN_BATCH(8)) {
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(8, 2));
assert(BEGIN_BATCH(8));
}
OUT_BATCH(CMD);
OUT_BATCH(BR13);

View file

@ -39,7 +39,7 @@
#include "pipe/p_screen.h"
DEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE);
DEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE)
/*

View file

@ -59,9 +59,9 @@ static void i915_flush_pipe( struct pipe_context *pipe,
if (flags & PIPE_FLUSH_TEXTURE_CACHE)
flush |= FLUSH_MAP_CACHE;
if (!BEGIN_BATCH(1, 0)) {
if (!BEGIN_BATCH(1)) {
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(1, 0));
assert(BEGIN_BATCH(1));
}
OUT_BATCH( flush );
}

View file

@ -144,7 +144,7 @@ emit_prim( struct draw_stage *stage,
vertex_size = i915->current.vertex_info.size * 4; /* in bytes */
assert(vertex_size >= 12); /* never smaller than 12 bytes */
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
@ -152,7 +152,7 @@ emit_prim( struct draw_stage *stage,
i915_update_derived( i915 );
i915_emit_hardware_state( i915 );
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4, 0 )) {
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) {
assert(0);
return;
}

View file

@ -465,7 +465,7 @@ draw_arrays_fallback(struct vbuf_render *render,
if (i915->hardware_dirty)
i915_emit_hardware_state(i915);
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
@ -474,7 +474,7 @@ draw_arrays_fallback(struct vbuf_render *render,
i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
assert(0);
goto out;
}
@ -514,7 +514,7 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
if (i915->hardware_dirty)
i915_emit_hardware_state(i915);
if (!BEGIN_BATCH(2, 0)) {
if (!BEGIN_BATCH(2)) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
@ -523,7 +523,7 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render,
i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
if (!BEGIN_BATCH(2, 0)) {
if (!BEGIN_BATCH(2)) {
assert(0);
goto out;
}
@ -635,7 +635,7 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render,
if (i915->hardware_dirty)
i915_emit_hardware_state(i915);
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
@ -644,7 +644,7 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render,
i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) {
assert(0);
goto out;
}

View file

@ -40,12 +40,18 @@
struct i915_tracked_hw_state {
const char *name;
void (*validate)(struct i915_context *);
void (*validate)(struct i915_context *, unsigned *batch_space);
void (*emit)(struct i915_context *);
unsigned dirty, batch_space;
};
static void
validate_flush(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = i915->flush_dirty ? 1 : 0;
}
static void
emit_flush(struct i915_context *i915)
{
@ -61,109 +67,343 @@ emit_flush(struct i915_context *i915)
OUT_BATCH(MI_FLUSH | INHIBIT_FLUSH_RENDER_CACHE);
}
uint32_t invariant_state[] = {
_3DSTATE_AA_CMD | AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 |
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0,
_3DSTATE_DFLT_DIFFUSE_CMD, 0,
_3DSTATE_DFLT_SPEC_CMD, 0,
_3DSTATE_DFLT_Z_CMD, 0,
_3DSTATE_COORD_SET_BINDINGS |
CSB_TCB(0, 0) |
CSB_TCB(1, 1) |
CSB_TCB(2, 2) |
CSB_TCB(3, 3) |
CSB_TCB(4, 4) |
CSB_TCB(5, 5) |
CSB_TCB(6, 6) |
CSB_TCB(7, 7),
_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE |
ENABLE_LINE_STRIP_PROVOKE_VRTX |
ENABLE_TRI_FAN_PROVOKE_VRTX |
LINE_STRIP_PROVOKE_VRTX(1) |
TRI_FAN_PROVOKE_VRTX(2) |
ENABLE_TEXKILL_3D_4D |
TEXKILL_4D,
_3DSTATE_DEPTH_SUBRECT_DISABLE,
/* disable indirect state for now
*/
_3DSTATE_LOAD_INDIRECT | 0, 0};
static void
validate_immediate(struct i915_context *i915)
emit_invariant(struct i915_context *i915)
{
i915_winsys_batchbuffer_write(i915->batch, invariant_state,
Elements(invariant_state)*sizeof(uint32_t));
}
static void
validate_immediate(struct i915_context *i915, unsigned *batch_space)
{
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 |
1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) &
i915->immediate_dirty;
if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0))
i915->validation_buffers[i915->num_validation_buffers++] = i915->vbo;
*batch_space = 1 + util_bitcount(dirty);
}
static void
validate_static(struct i915_context *i915)
emit_immediate(struct i915_context *i915)
{
if (i915->current.cbuf_bo)
/* remove unwatned bits and S7 */
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 |
1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) &
i915->immediate_dirty;
int i, num = util_bitcount(dirty);
assert(num && num <= I915_MAX_IMMEDIATE);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
dirty << 4 | (num - 1));
if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0)) {
if (i915->vbo)
OUT_RELOC(i915->vbo, I915_USAGE_VERTEX,
i915->current.immediate[I915_IMMEDIATE_S0]);
else
OUT_BATCH(0);
}
for (i = 1; i < I915_MAX_IMMEDIATE; i++) {
if (dirty & (1 << i))
OUT_BATCH(i915->current.immediate[i]);
}
}
static void
validate_dynamic(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = util_bitcount(i915->dynamic_dirty & ((1 << I915_MAX_DYNAMIC) - 1));
}
static void
emit_dynamic(struct i915_context *i915)
{
int i;
for (i = 0; i < I915_MAX_DYNAMIC; i++) {
if (i915->dynamic_dirty & (1 << i))
OUT_BATCH(i915->current.dynamic[i]);
}
}
static void
validate_static(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = 2 + 5; /* including DRAW_RECT */
if (i915->current.cbuf_bo) {
i915->validation_buffers[i915->num_validation_buffers++]
= i915->current.cbuf_bo;
*batch_space += 3;
}
if (i915->current.depth_bo)
if (i915->current.depth_bo) {
i915->validation_buffers[i915->num_validation_buffers++]
= i915->current.depth_bo;
*batch_space += 3;
}
}
static void
validate_map(struct i915_context *i915)
emit_static(struct i915_context *i915)
{
if (i915->current.cbuf_bo) {
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(i915->current.cbuf_flags);
OUT_RELOC(i915->current.cbuf_bo,
I915_USAGE_RENDER,
0);
}
/* What happens if no zbuf??
*/
if (i915->current.depth_bo) {
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(i915->current.depth_flags);
OUT_RELOC(i915->current.depth_bo,
I915_USAGE_RENDER,
0);
}
{
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
OUT_BATCH(i915->current.dst_buf_vars);
}
}
static void
validate_map(struct i915_context *i915, unsigned *batch_space)
{
const uint enabled = i915->current.sampler_enable_flags;
uint unit;
struct i915_texture *tex;
*batch_space = i915->current.sampler_enable_nr ?
2 + 3*i915->current.sampler_enable_nr : 0;
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
tex = i915_texture(i915->fragment_sampler_views[unit]->texture);
i915->validation_buffers[i915->num_validation_buffers++] = tex->buffer;
tex = i915_texture(i915->fragment_sampler_views[unit]->texture);
i915->validation_buffers[i915->num_validation_buffers++] = tex->buffer;
}
}
}
const static struct i915_tracked_hw_state hw_atoms[] = {
{ "flush", NULL, emit_flush, I915_HW_FLUSH, 1 },
{ "immediate", validate_immediate, NULL, I915_HW_IMMEDIATE },
{ "static", validate_static, NULL, I915_HW_STATIC },
{ "map", validate_map, NULL, I915_HW_MAP }
};
static void
emit_map(struct i915_context *i915)
{
const uint nr = i915->current.sampler_enable_nr;
if (nr) {
const uint enabled = i915->current.sampler_enable_flags;
uint unit;
uint count = 0;
OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture);
struct i915_winsys_buffer *buf = texture->buffer;
assert(buf);
count++;
OUT_RELOC(buf, I915_USAGE_SAMPLER, 0);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
}
}
assert(count == nr);
}
}
static void
validate_sampler(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = i915->current.sampler_enable_nr ?
2 + 3*i915->current.sampler_enable_nr : 0;
}
static void
emit_sampler(struct i915_context *i915)
{
if (i915->current.sampler_enable_nr) {
int i;
OUT_BATCH( _3DSTATE_SAMPLER_STATE |
(3 * i915->current.sampler_enable_nr) );
OUT_BATCH( i915->current.sampler_enable_flags );
for (i = 0; i < I915_TEX_UNITS; i++) {
if (i915->current.sampler_enable_flags & (1<<i)) {
OUT_BATCH( i915->current.sampler[i][0] );
OUT_BATCH( i915->current.sampler[i][1] );
OUT_BATCH( i915->current.sampler[i][2] );
}
}
}
}
static void
validate_constants(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = i915->fs->num_constants ?
2 + 4*i915->fs->num_constants : 0;
}
static void
emit_constants(struct i915_context *i915)
{
/* Collate the user-defined constants with the fragment shader's
* immediates according to the constant_flags[] array.
*/
const uint nr = i915->fs->num_constants;
if (nr) {
uint i;
OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) );
OUT_BATCH((1 << nr) - 1);
for (i = 0; i < nr; i++) {
const uint *c;
if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) {
/* grab user-defined constant */
c = (uint *) i915_buffer(i915->constants[PIPE_SHADER_FRAGMENT])->data;
c += 4 * i;
}
else {
/* emit program constant */
c = (uint *) i915->fs->constants[i];
}
#if 0 /* debug */
{
float *f = (float *) c;
printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3],
(i915->fs->constant_flags[i] == I915_CONSTFLAG_USER
? "user" : "immediate"));
}
#endif
OUT_BATCH(*c++);
OUT_BATCH(*c++);
OUT_BATCH(*c++);
OUT_BATCH(*c++);
}
}
}
static void
validate_program(struct i915_context *i915, unsigned *batch_space)
{
*batch_space = i915->fs->program_len;
}
static void
emit_program(struct i915_context *i915)
{
uint i;
/* we should always have, at least, a pass-through program */
assert(i915->fs->program_len > 0);
for (i = 0; i < i915->fs->program_len; i++) {
OUT_BATCH(i915->fs->program[i]);
}
}
static void
emit_draw_rect(struct i915_context *i915)
{
OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS);
OUT_BATCH(i915->current.draw_offset);
OUT_BATCH(i915->current.draw_size);
OUT_BATCH(i915->current.draw_offset);
}
static boolean
i915_validate_state(struct i915_context *i915, unsigned *batch_space)
{
int i;
unsigned tmp;
i915->num_validation_buffers = 0;
*batch_space = 0;
if (i915->hardware_dirty & I915_HW_INVARIANT)
*batch_space = Elements(invariant_state);
else
*batch_space = 0;
for (i = 0; i < Elements(hw_atoms); i++)
if ((i915->hardware_dirty & hw_atoms[i].dirty) && hw_atoms[i].validate) {
hw_atoms[i].validate(i915);
*batch_space += hw_atoms[i].batch_space;
}
#define VALIDATE_ATOM(atom, hw_dirty) \
if (i915->hardware_dirty & hw_dirty) { \
validate_##atom(i915, &tmp); \
*batch_space += tmp; }
VALIDATE_ATOM(flush, I915_HW_FLUSH);
VALIDATE_ATOM(immediate, I915_HW_IMMEDIATE);
VALIDATE_ATOM(dynamic, I915_HW_DYNAMIC);
VALIDATE_ATOM(static, I915_HW_STATIC);
VALIDATE_ATOM(map, I915_HW_MAP);
VALIDATE_ATOM(sampler, I915_HW_SAMPLER);
VALIDATE_ATOM(constants, I915_HW_CONSTANTS);
VALIDATE_ATOM(program, I915_HW_PROGRAM);
#undef VALIDATE_ATOM
if (i915->num_validation_buffers == 0)
return TRUE;
if (!i915_winsys_validate_buffers(i915->batch, i915->validation_buffers,
i915->num_validation_buffers))
i915->num_validation_buffers))
return FALSE;
return TRUE;
}
static void
emit_state(struct i915_context *i915)
{
int i;
for (i = 0; i < Elements(hw_atoms); i++)
if ((i915->hardware_dirty & hw_atoms[i].dirty) && hw_atoms[i].emit)
hw_atoms[i].emit(i915);
}
/* Push the state into the sarea and/or texture memory.
*/
void
i915_emit_hardware_state(struct i915_context *i915 )
{
unsigned batch_space;
/* XXX: there must be an easier way */
const unsigned dwords = ( 14 +
7 +
I915_MAX_DYNAMIC +
8 +
2 + I915_TEX_UNITS*3 +
2 + I915_TEX_UNITS*3 +
2 + I915_MAX_CONSTANT*4 +
#if 0
i915->current.program_len +
#else
i915->fs->program_len +
#endif
6
) * 3/2; /* plus 50% margin */
const unsigned relocs = ( I915_TEX_UNITS +
3
) * 3/2; /* plus 50% margin */
uintptr_t save_ptr;
size_t save_relocs;
if (I915_DBG_ON(DBG_ATOMS))
i915_dump_hardware_dirty(i915, __FUNCTION__);
@ -173,262 +413,36 @@ i915_emit_hardware_state(struct i915_context *i915 )
assert(i915_validate_state(i915, &batch_space));
}
if(!BEGIN_BATCH(batch_space + dwords, relocs)) {
if(!BEGIN_BATCH(batch_space)) {
FLUSH_BATCH(NULL);
assert(i915_validate_state(i915, &batch_space));
assert(BEGIN_BATCH(batch_space + dwords, relocs));
assert(BEGIN_BATCH(batch_space));
}
save_ptr = (uintptr_t)i915->batch->ptr;
save_relocs = i915->batch->relocs;
emit_state(i915);
/* 14 dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_INVARIANT)
{
OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
AA_LINE_ECAAR_WIDTH_1_0 |
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
#define EMIT_ATOM(atom, hw_dirty) \
if (i915->hardware_dirty & hw_dirty) \
emit_##atom(i915);
EMIT_ATOM(flush, I915_HW_FLUSH);
EMIT_ATOM(invariant, I915_HW_INVARIANT);
EMIT_ATOM(immediate, I915_HW_IMMEDIATE);
EMIT_ATOM(dynamic, I915_HW_DYNAMIC);
EMIT_ATOM(static, I915_HW_STATIC);
EMIT_ATOM(map, I915_HW_MAP);
EMIT_ATOM(sampler, I915_HW_SAMPLER);
EMIT_ATOM(constants, I915_HW_CONSTANTS);
EMIT_ATOM(program, I915_HW_PROGRAM);
EMIT_ATOM(draw_rect, I915_HW_STATIC);
#undef EMIT_ATOM
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DFLT_SPEC_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_DFLT_Z_CMD);
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
CSB_TCB(0, 0) |
CSB_TCB(1, 1) |
CSB_TCB(2, 2) |
CSB_TCB(3, 3) |
CSB_TCB(4, 4) |
CSB_TCB(5, 5) |
CSB_TCB(6, 6) |
CSB_TCB(7, 7));
OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
ENABLE_POINT_RASTER_RULE |
OGL_POINT_RASTER_RULE |
ENABLE_LINE_STRIP_PROVOKE_VRTX |
ENABLE_TRI_FAN_PROVOKE_VRTX |
LINE_STRIP_PROVOKE_VRTX(1) |
TRI_FAN_PROVOKE_VRTX(2) |
ENABLE_TEXKILL_3D_4D |
TEXKILL_4D);
OUT_BATCH(_3DSTATE_DEPTH_SUBRECT_DISABLE);
/* disable indirect state for now
*/
OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0);
OUT_BATCH(0);
}
/* 7 dwords, 1 relocs */
if (i915->hardware_dirty & I915_HW_IMMEDIATE)
{
/* remove unwatned bits and S7 */
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 |
1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) &
i915->immediate_dirty;
int i, num = util_bitcount(dirty);
assert(num && num <= I915_MAX_IMMEDIATE);
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
dirty << 4 | (num - 1));
if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0)) {
if (i915->vbo)
OUT_RELOC(i915->vbo, I915_USAGE_VERTEX,
i915->current.immediate[I915_IMMEDIATE_S0]);
else
OUT_BATCH(0);
}
for (i = 1; i < I915_MAX_IMMEDIATE; i++) {
if (dirty & (1 << i))
OUT_BATCH(i915->current.immediate[i]);
}
}
#if 01
/* I915_MAX_DYNAMIC dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_DYNAMIC)
{
int i;
for (i = 0; i < I915_MAX_DYNAMIC; i++) {
if (i915->dynamic_dirty & (1 << i))
OUT_BATCH(i915->current.dynamic[i]);
}
}
#endif
#if 01
/* 8 dwords, 2 relocs */
if (i915->hardware_dirty & I915_HW_STATIC)
{
if (i915->current.cbuf_bo) {
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(i915->current.cbuf_flags);
OUT_RELOC(i915->current.cbuf_bo,
I915_USAGE_RENDER,
0);
}
/* What happens if no zbuf??
*/
if (i915->current.depth_bo) {
OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
OUT_BATCH(i915->current.depth_flags);
OUT_RELOC(i915->current.depth_bo,
I915_USAGE_RENDER,
0);
}
{
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
OUT_BATCH(i915->current.dst_buf_vars);
}
}
#endif
#if 01
/* texture images */
/* 2 + I915_TEX_UNITS*3 dwords, I915_TEX_UNITS relocs */
if (i915->hardware_dirty & (I915_HW_MAP | I915_HW_SAMPLER))
{
const uint nr = i915->current.sampler_enable_nr;
if (nr) {
const uint enabled = i915->current.sampler_enable_flags;
uint unit;
uint count = 0;
OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr));
OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture);
struct i915_winsys_buffer *buf = texture->buffer;
assert(buf);
count++;
OUT_RELOC(buf, I915_USAGE_SAMPLER, 0);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
}
}
assert(count == nr);
}
}
#endif
#if 01
/* samplers */
/* 2 + I915_TEX_UNITS*3 dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_SAMPLER)
{
if (i915->current.sampler_enable_nr) {
int i;
OUT_BATCH( _3DSTATE_SAMPLER_STATE |
(3 * i915->current.sampler_enable_nr) );
OUT_BATCH( i915->current.sampler_enable_flags );
for (i = 0; i < I915_TEX_UNITS; i++) {
if (i915->current.sampler_enable_flags & (1<<i)) {
OUT_BATCH( i915->current.sampler[i][0] );
OUT_BATCH( i915->current.sampler[i][1] );
OUT_BATCH( i915->current.sampler[i][2] );
}
}
}
}
#endif
#if 01
/* constants */
/* 2 + I915_MAX_CONSTANT*4 dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_CONSTANTS)
{
/* Collate the user-defined constants with the fragment shader's
* immediates according to the constant_flags[] array.
*/
const uint nr = i915->fs->num_constants;
if (nr) {
uint i;
OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) );
OUT_BATCH((1 << nr) - 1);
for (i = 0; i < nr; i++) {
const uint *c;
if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) {
/* grab user-defined constant */
c = (uint *) i915_buffer(i915->constants[PIPE_SHADER_FRAGMENT])->data;
c += 4 * i;
}
else {
/* emit program constant */
c = (uint *) i915->fs->constants[i];
}
#if 0 /* debug */
{
float *f = (float *) c;
printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3],
(i915->fs->constant_flags[i] == I915_CONSTFLAG_USER
? "user" : "immediate"));
}
#endif
OUT_BATCH(*c++);
OUT_BATCH(*c++);
OUT_BATCH(*c++);
OUT_BATCH(*c++);
}
}
}
#endif
#if 01
/* Fragment program */
/* i915->current.program_len dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_PROGRAM)
{
uint i;
/* we should always have, at least, a pass-through program */
assert(i915->fs->program_len > 0);
for (i = 0; i < i915->fs->program_len; i++) {
OUT_BATCH(i915->fs->program[i]);
}
}
#endif
#if 01
/* drawing surface size */
/* 6 dwords, 0 relocs */
if (i915->hardware_dirty & I915_HW_STATIC)
{
/* XXX flush only required when the draw_offset changes! */
OUT_BATCH(MI_FLUSH | INHIBIT_FLUSH_RENDER_CACHE);
OUT_BATCH(_3DSTATE_DRAW_RECT_CMD);
OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS);
OUT_BATCH(i915->current.draw_offset);
OUT_BATCH(i915->current.draw_size);
OUT_BATCH(i915->current.draw_offset);
}
#endif
I915_DBG(DBG_EMIT, "%s: used %d dwords, %d relocs\n", __FUNCTION__,
I915_DBG(DBG_EMIT, "%s: used %d dwords, %d dwords reserved\n", __FUNCTION__,
((uintptr_t)i915->batch->ptr - save_ptr) / 4,
i915->batch->relocs - save_relocs);
batch_space);
assert(((uintptr_t)i915->batch->ptr - save_ptr) / 4 == batch_space);
i915->hardware_dirty = 0;
i915->immediate_dirty = 0;
i915->dynamic_dirty = 0;
i915->flush_dirty = 0;
}

View file

@ -164,7 +164,7 @@ static void update_framebuffer(struct i915_context *i915)
assert(ret);
if (i915->current.draw_offset != draw_offset) {
i915->current.draw_offset = draw_offset;
/* XXX: only emit flush on change and not always in emit */
i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH);
}
i915->current.draw_size = (w - 1 + x) | ((h - 1 + y) << 16);

View file

@ -76,7 +76,6 @@ struct i915_winsys_batchbuffer {
size_t size;
size_t relocs;
size_t max_relocs;
/*@}*/
};

View file

@ -22,7 +22,6 @@
#include "r300_context.h"
#include "r300_emit.h"
#include "r300_hyperz.h"
#include "r300_texture.h"
#include "r300_winsys.h"
@ -117,6 +116,14 @@ static boolean r300_fast_zclear_allowed(struct r300_context *r300)
return r300_resource(fb->zsbuf->texture)->tex.zmask_dwords[fb->zsbuf->u.tex.level];
}
static boolean r300_hiz_clear_allowed(struct r300_context *r300)
{
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
return r300_resource(fb->zsbuf->texture)->tex.hiz_dwords[fb->zsbuf->u.tex.level];
}
static uint32_t r300_depth_clear_value(enum pipe_format format,
double depth, unsigned stencil)
{
@ -134,6 +141,13 @@ static uint32_t r300_depth_clear_value(enum pipe_format format,
}
}
static uint32_t r300_hiz_clear_value(double depth)
{
uint32_t r = (uint32_t)(CLAMP(depth, 0, 1) * 255.5);
assert(r <= 255);
return r | (r << 8) | (r << 16) | (r << 24);
}
/* Clear currently bound buffers. */
static void r300_clear(struct pipe_context* pipe,
unsigned buffers,
@ -190,8 +204,6 @@ static void r300_clear(struct pipe_context* pipe,
(struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_hyperz_state *hyperz =
(struct r300_hyperz_state*)r300->hyperz_state.state;
struct r300_resource *zstex =
fb->zsbuf ? r300_resource(fb->zsbuf->texture) : NULL;
uint32_t width = fb->width;
uint32_t height = fb->height;
boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
@ -200,20 +212,18 @@ static void r300_clear(struct pipe_context* pipe,
/* Enable fast Z clear.
* The zbuffer must be in micro-tiled mode, otherwise it locks up. */
if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) {
hyperz_dcv = hyperz->zb_depthclearvalue =
r300_depth_clear_value(fb->zsbuf->format, depth, stencil);
if (r300_fast_zclear_allowed(r300)) {
hyperz_dcv = hyperz->zb_depthclearvalue =
r300_depth_clear_value(fb->zsbuf->format, depth, stencil);
r300_mark_atom_dirty(r300, &r300->zmask_clear);
buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
}
if (zstex->hiz_mem[fb->zsbuf->u.tex.level])
if (r300_hiz_clear_allowed(r300)) {
r300->hiz_clear_value = r300_hiz_clear_value(depth);
r300_mark_atom_dirty(r300, &r300->hiz_clear);
/* XXX Change this to r300_mark_atom_dirty(r300, &r300->hyperz_state);
* once hiz offset is constant. */
r300_mark_fb_state_dirty(r300, R300_CHANGED_HYPERZ_FLAG);
}
}
/* Enable CBZB clear. */
@ -240,14 +250,14 @@ static void r300_clear(struct pipe_context* pipe,
fb->nr_cbufs,
buffers, rgba, depth, stencil);
r300_blitter_end(r300);
} else if (r300->zmask_clear.dirty) {
} else if (r300->zmask_clear.dirty || r300->hiz_clear.dirty) {
/* Just clear zmask and hiz now, this does not use the standard draw
* procedure. */
unsigned dwords;
/* Calculate zmask_clear and hiz_clear atom sizes. */
r300_update_hyperz_state(r300);
dwords = r300->zmask_clear.size +
dwords = (r300->zmask_clear.dirty ? r300->zmask_clear.size : 0) +
(r300->hiz_clear.dirty ? r300->hiz_clear.size : 0) +
r300_get_num_cs_end_dwords(r300);
@ -257,9 +267,11 @@ static void r300_clear(struct pipe_context* pipe,
}
/* Emit clear packets. */
r300_emit_zmask_clear(r300, r300->zmask_clear.size,
r300->zmask_clear.state);
r300->zmask_clear.dirty = FALSE;
if (r300->zmask_clear.dirty) {
r300_emit_zmask_clear(r300, r300->zmask_clear.size,
r300->zmask_clear.state);
r300->zmask_clear.dirty = FALSE;
}
if (r300->hiz_clear.dirty) {
r300_emit_hiz_clear(r300, r300->hiz_clear.size,
r300->hiz_clear.state);
@ -279,9 +291,8 @@ static void r300_clear(struct pipe_context* pipe,
/* Enable fastfill and/or hiz.
*
* If we cleared zmask/hiz, it's in use now. The Hyper-Z state update
* looks if zmask/hiz is in use and enables fastfill accordingly. */
if (r300->zmask_in_use ||
(zstex && zstex->hiz_in_use[fb->zsbuf->u.tex.level])) {
* looks if zmask/hiz is in use and programs hardware accordingly. */
if (r300->zmask_in_use || r300->hiz_in_use) {
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}
@ -295,7 +306,7 @@ static void r300_clear_render_target(struct pipe_context *pipe,
{
struct r300_context *r300 = r300_context(pipe);
r300->zmask_locked = TRUE;
r300->hyperz_locked = TRUE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
r300_blitter_begin(r300, R300_CLEAR_SURFACE);
@ -303,7 +314,7 @@ static void r300_clear_render_target(struct pipe_context *pipe,
dstx, dsty, width, height);
r300_blitter_end(r300);
r300->zmask_locked = FALSE;
r300->hyperz_locked = FALSE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
@ -320,11 +331,11 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe,
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
if (r300->zmask_in_use && !r300->zmask_locked) {
if (r300->zmask_in_use && !r300->hyperz_locked) {
if (fb->zsbuf->texture == dst->texture) {
r300_decompress_zmask(r300);
} else {
r300->zmask_locked = TRUE;
r300->hyperz_locked = TRUE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}
@ -334,8 +345,8 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe,
dstx, dsty, width, height);
r300_blitter_end(r300);
if (r300->zmask_locked) {
r300->zmask_locked = FALSE;
if (r300->hyperz_locked) {
r300->hyperz_locked = FALSE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}
@ -345,7 +356,7 @@ void r300_decompress_zmask(struct r300_context *r300)
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
if (!r300->zmask_in_use || r300->zmask_locked)
if (!r300->zmask_in_use || r300->hyperz_locked)
return;
r300->zmask_decompress = TRUE;
@ -420,12 +431,12 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
util_format_description(dst->format);
struct pipe_box box;
if (r300->zmask_in_use && !r300->zmask_locked) {
if (r300->zmask_in_use && !r300->hyperz_locked) {
if (fb->zsbuf->texture == src ||
fb->zsbuf->texture == dst) {
r300_decompress_zmask(r300);
} else {
r300->zmask_locked = TRUE;
r300->hyperz_locked = TRUE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}
@ -463,7 +474,8 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
}
/* Handle compressed formats. */
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC ||
desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
switch (util_format_get_blocksize(old_dst.format)) {
case 8:
/* 1 pixel = 4 bits,
@ -502,8 +514,8 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
if (old_dst.format != new_dst.format)
r300_resource_set_properties(pipe->screen, dst, 0, &old_dst);
if (r300->zmask_locked) {
r300->zmask_locked = FALSE;
if (r300->hyperz_locked) {
r300->hyperz_locked = FALSE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
}

View file

@ -90,8 +90,6 @@ struct r300_capabilities {
boolean high_second_pipe;
/* DXTC texture swizzling. */
boolean dxtc_swizzle;
/* Index bias (AKA index offset). */
boolean index_bias_supported;
};
/* Enumerations for legibility and telling which card we're running on. */

View file

@ -30,7 +30,6 @@
#include "r300_cb.h"
#include "r300_context.h"
#include "r300_emit.h"
#include "r300_hyperz.h"
#include "r300_screen.h"
#include "r300_screen_buffer.h"
#include "r300_winsys.h"
@ -170,7 +169,6 @@ static boolean r300_setup_atoms(struct r300_context* r300)
boolean is_rv350 = r300->screen->caps.is_rv350;
boolean is_r500 = r300->screen->caps.is_r500;
boolean has_tcl = r300->screen->caps.has_tcl;
boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0);
boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0;
@ -203,11 +201,11 @@ static boolean r300_setup_atoms(struct r300_context* r300)
/* SC. */
R300_INIT_ATOM(scissor_state, 3);
/* GB, FG, GA, SU, SC, RB3D. */
R300_INIT_ATOM(invariant_state, 18 + (is_rv350 ? 4 : 0));
R300_INIT_ATOM(invariant_state, 18 + (is_rv350 ? 4 : 0) + (is_r500 ? 4 : 0));
/* VAP. */
R300_INIT_ATOM(viewport_state, 9);
R300_INIT_ATOM(pvs_flush, 2);
R300_INIT_ATOM(vap_invariant_state, 9);
R300_INIT_ATOM(vap_invariant_state, is_r500 ? 11 : 9);
R300_INIT_ATOM(vertex_stream_state, 0);
R300_INIT_ATOM(vs_state, 0);
R300_INIT_ATOM(vs_constants, 0);
@ -216,7 +214,7 @@ static boolean r300_setup_atoms(struct r300_context* r300)
R300_INIT_ATOM(rs_block_state, 0);
R300_INIT_ATOM(rs_state, 0);
/* SC, US. */
R300_INIT_ATOM(fb_state_pipelined, 5 + (drm_2_3_0 ? 3 : 0));
R300_INIT_ATOM(fb_state_pipelined, 8);
/* US. */
R300_INIT_ATOM(fs, 0);
R300_INIT_ATOM(fs_rc_constant_state, 0);
@ -227,7 +225,7 @@ static boolean r300_setup_atoms(struct r300_context* r300)
if (can_hyperz) {
/* HiZ Clear */
if (has_hiz_ram)
R300_INIT_ATOM(hiz_clear, 0);
R300_INIT_ATOM(hiz_clear, 4);
/* zmask clear */
R300_INIT_ATOM(zmask_clear, 4);
}
@ -331,7 +329,7 @@ static void r300_init_states(struct pipe_context *pipe)
/* Initialize the VAP invariant state. */
{
BEGIN_CB(vap_invariant->cb, 9);
BEGIN_CB(vap_invariant->cb, r300->vap_invariant_state.size);
OUT_CB_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xffff);
OUT_CB_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4);
OUT_CB_32F(1.0);
@ -339,6 +337,10 @@ static void r300_init_states(struct pipe_context *pipe)
OUT_CB_32F(1.0);
OUT_CB_32F(1.0);
OUT_CB_REG(R300_VAP_PSC_SGN_NORM_CNTL, R300_SGN_NORM_NO_ZERO);
if (r300->screen->caps.is_r500) {
OUT_CB_REG(R500_VAP_TEX_TO_COLOR_CNTL, 0);
}
END_CB;
}
@ -359,6 +361,11 @@ static void r300_init_states(struct pipe_context *pipe)
OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x01010101);
OUT_CB_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFEFEFEFE);
}
if (r300->screen->caps.is_r500) {
OUT_CB_REG(R500_GA_COLOR_CONTROL_PS3, 0);
OUT_CB_REG(R500_SU_TEX_WRAP_PS3, 0);
}
END_CB;
}
@ -447,16 +454,10 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
/* Render functions must be initialized after blitter. */
r300_init_render_functions(r300);
r300_init_states(&r300->context);
rws->cs_set_flush(r300->cs, r300_flush_cb, r300);
/* setup hyper-z mm */
if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
if (!r300_hyperz_init_mm(r300))
goto fail;
r300_init_states(&r300->context);
/* The KIL opcode needs the first texture unit to be enabled
* on r3xx-r4xx. In order to calm down the CS checker, we bind this
* dummy texture there. */
@ -507,10 +508,10 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
}
/* Print driver info. */
#ifdef NDEBUG
if (DBG_ON(r300, DBG_INFO)) {
#else
#ifdef DEBUG
{
#else
if (DBG_ON(r300, DBG_INFO)) {
#endif
fprintf(stderr,
"r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n"
@ -526,7 +527,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
rws->get_value(rws, R300_VID_GART_SIZE) >> 20,
rws->get_value(rws, R300_VID_VRAM_SIZE) >> 20,
rws->get_value(rws, R300_CAN_AACOMPRESS) ? "YES" : "NO",
rws->get_value(rws, R300_CAN_HYPERZ) ? "YES" : "NO",
rws->get_value(rws, R300_CAN_HYPERZ) &&
r300->screen->caps.zmask_ram ? "YES" : "NO",
rws->get_value(rws, R300_CAN_HYPERZ) &&
r300->screen->caps.hiz_ram ? "YES" : "NO");
}

View file

@ -102,7 +102,6 @@ struct r300_dsa_state {
};
struct r300_hyperz_state {
int current_func; /* -1 after a clear before first op */
int flush;
/* This is actually a command buffer with named dwords. */
uint32_t cb_flush_begin;
@ -220,11 +219,11 @@ struct r300_vertex_stream_state {
};
struct r300_invariant_state {
uint32_t cb[22];
uint32_t cb[26];
};
struct r300_vap_invariant_state {
uint32_t cb[9];
uint32_t cb[11];
};
struct r300_viewport_state {
@ -295,6 +294,8 @@ struct r300_surface {
uint32_t offset; /* COLOROFFSET or DEPTHOFFSET. */
uint32_t pitch; /* COLORPITCH or DEPTHPITCH. */
uint32_t pitch_zmask; /* ZMASK_PITCH */
uint32_t pitch_hiz; /* HIZ_PITCH */
uint32_t format; /* US_OUT_FMT or ZB_FORMAT. */
/* Parameters dedicated to the CBZB clear. */
@ -363,8 +364,12 @@ struct r300_texture_desc {
/* Zbuffer compression info for each miplevel. */
boolean zcomp8x8[R300_MAX_TEXTURE_LEVELS];
/* If zero, then disable compression. */
/* If zero, then disable Z compression/HiZ. */
unsigned zmask_dwords[R300_MAX_TEXTURE_LEVELS];
unsigned hiz_dwords[R300_MAX_TEXTURE_LEVELS];
/* Zmask/HiZ strides for each miplevel. */
unsigned zmask_stride_in_pixels[R300_MAX_TEXTURE_LEVELS];
unsigned hiz_stride_in_pixels[R300_MAX_TEXTURE_LEVELS];
};
struct r300_resource
@ -390,10 +395,6 @@ struct r300_resource
/* Where the texture starts in the buffer. */
unsigned tex_offset;
/* HiZ memory allocations. */
struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS];
boolean hiz_in_use[R300_MAX_TEXTURE_LEVELS];
/* This is the level tiling flags were last time set for.
* It's used to prevent redundant tiling-flags changes from happening.*/
unsigned surface_level;
@ -412,6 +413,21 @@ struct r300_vertex_element_state {
struct r300_vertex_stream_state vertex_stream;
};
enum r300_hiz_func {
HIZ_FUNC_NONE,
/* The function, when determined, is set in stone
* until the next HiZ clear. */
/* MAX is written to the HiZ buffer.
* Used for LESS, LEQUAL. */
HIZ_FUNC_MAX,
/* MIN is written to the HiZ buffer.
* Used for GREATER, GEQUAL. */
HIZ_FUNC_MIN,
};
struct r300_context {
/* Parent class */
struct pipe_context context;
@ -545,22 +561,25 @@ struct r300_context {
int sprite_coord_enable;
/* Whether two-sided color selection is enabled (AKA light_twoside). */
boolean two_sided_color;
/* Whether fast color clear is enabled. */
boolean cbzb_clear;
/* Whether ZMASK is enabled. */
boolean zmask_in_use;
/* Whether ZMASK is being decompressed. */
boolean zmask_decompress;
/* Whether ZMASK is locked, i.e. should be disabled and cannot be taken over. */
boolean zmask_locked;
/* Whether ZMASK/HIZ is locked, i.e. should be disabled and cannot be taken over. */
boolean hyperz_locked;
/* The zbuffer the ZMASK of which is locked. */
struct pipe_surface *locked_zbuffer;
/* Whether HIZ is enabled. */
boolean hiz_in_use;
/* HiZ function. Can be either MIN or MAX. */
enum r300_hiz_func hiz_func;
/* HiZ clear value. */
uint32_t hiz_clear_value;
void *dsa_decompress_zmask;
/* two mem block managers for hiz/zmask ram space */
struct mem_block *hiz_mm;
struct u_vbuf_mgr *vbuf_mgr;
struct util_slab_mempool pool_transfers;
@ -644,6 +663,9 @@ void r300_decompress_zmask(struct r300_context *r300);
void r300_decompress_zmask_locked_unsafe(struct r300_context *r300);
void r300_decompress_zmask_locked(struct r300_context *r300);
/* r300_hyperz.c */
void r300_update_hyperz_state(struct r300_context* r300);
/* r300_query.c */
void r300_resume_query(struct r300_context *r300,
struct r300_query *query);

View file

@ -425,27 +425,12 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
OUT_CS_RELOC(surf);
if (can_hyperz) {
uint32_t surf_pitch;
struct r300_resource *tex;
int level = surf->base.u.tex.level;
tex = r300_resource(surf->base.texture);
surf_pitch = surf->pitch & R300_DEPTHPITCH_MASK;
/* HiZ RAM. */
if (r300->screen->caps.hiz_ram) {
if (tex->hiz_mem[level]) {
OUT_CS_REG(R300_ZB_HIZ_OFFSET, tex->hiz_mem[level]->ofs << 2);
OUT_CS_REG(R300_ZB_HIZ_PITCH, surf_pitch);
} else {
OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0);
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0);
}
}
OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0);
OUT_CS_REG(R300_ZB_HIZ_PITCH, surf->pitch_hiz);
/* Z Mask RAM. (compressed zbuffer) */
OUT_CS_REG(R300_ZB_ZMASK_OFFSET, 0);
OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf_pitch);
OUT_CS_REG(R300_ZB_ZMASK_PITCH, surf->pitch_zmask);
}
}
@ -484,6 +469,7 @@ void r300_emit_fb_state_pipelined(struct r300_context *r300,
struct pipe_framebuffer_state* fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
unsigned i, num_cbufs = fb->nr_cbufs;
unsigned mspos0, mspos1;
CS_LOCALS(r300);
/* If we use the multiwrite feature, the colorbuffers 2,3,4 must be
@ -507,38 +493,36 @@ void r300_emit_fb_state_pipelined(struct r300_context *r300,
/* Multisampling. Depends on framebuffer sample count.
* These are pipelined regs and as such cannot be moved
* to the AA state. */
if (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
unsigned mspos0 = 0x66666666;
unsigned mspos1 = 0x6666666;
mspos0 = 0x66666666;
mspos1 = 0x6666666;
if (fb->nr_cbufs && fb->cbufs[0]->texture->nr_samples > 1) {
/* Subsample placement. These may not be optimal. */
switch (fb->cbufs[0]->texture->nr_samples) {
case 2:
mspos0 = 0x33996633;
mspos1 = 0x6666663;
break;
case 3:
mspos0 = 0x33936933;
mspos1 = 0x6666663;
break;
case 4:
mspos0 = 0x33939933;
mspos1 = 0x3966663;
break;
case 6:
mspos0 = 0x22a2aa22;
mspos1 = 0x2a65672;
break;
default:
debug_printf("r300: Bad number of multisamples!\n");
}
if (fb->nr_cbufs && fb->cbufs[0]->texture->nr_samples > 1) {
/* Subsample placement. These may not be optimal. */
switch (fb->cbufs[0]->texture->nr_samples) {
case 2:
mspos0 = 0x33996633;
mspos1 = 0x6666663;
break;
case 3:
mspos0 = 0x33936933;
mspos1 = 0x6666663;
break;
case 4:
mspos0 = 0x33939933;
mspos1 = 0x3966663;
break;
case 6:
mspos0 = 0x22a2aa22;
mspos1 = 0x2a65672;
break;
default:
debug_printf("r300: Bad number of multisamples!\n");
}
OUT_CS_REG_SEQ(R300_GB_MSPOS0, 2);
OUT_CS(mspos0);
OUT_CS(mspos1);
}
OUT_CS_REG_SEQ(R300_GB_MSPOS0, 2);
OUT_CS(mspos0);
OUT_CS(mspos1);
END_CS;
}
@ -1039,56 +1023,26 @@ void r300_emit_viewport_state(struct r300_context* r300,
END_CS;
}
static void r300_emit_hiz_line_clear(struct r300_context *r300, int start, uint16_t count, uint32_t val)
{
CS_LOCALS(r300);
BEGIN_CS(4);
OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2);
OUT_CS(start);
OUT_CS(count);
OUT_CS(val);
END_CS;
}
#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
{
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_hyperz_state *z =
(struct r300_hyperz_state*)r300->hyperz_state.state;
struct r300_screen* r300screen = r300->screen;
uint32_t stride, offset = 0, height, offset_shift;
struct r300_resource* tex;
int i;
CS_LOCALS(r300);
tex = r300_resource(fb->zsbuf->texture);
offset = tex->hiz_mem[fb->zsbuf->u.tex.level]->ofs;
stride = tex->tex.stride_in_pixels[fb->zsbuf->u.tex.level];
/* convert from pixels to 4x4 blocks */
stride = ALIGN_DIVUP(stride, 4);
stride = ALIGN_DIVUP(stride, r300screen->caps.num_frag_pipes);
/* there are 4 blocks per dwords */
stride = ALIGN_DIVUP(stride, 4);
height = ALIGN_DIVUP(fb->zsbuf->height, 4);
offset_shift = 2;
offset_shift += (r300screen->caps.num_frag_pipes / 2);
for (i = 0; i < height; i++) {
offset = i * stride;
offset <<= offset_shift;
r300_emit_hiz_line_clear(r300, offset, stride, 0xffffffff);
}
z->current_func = -1;
BEGIN_CS(size);
OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2);
OUT_CS(0);
OUT_CS(tex->tex.hiz_dwords[fb->zsbuf->u.tex.level]);
OUT_CS(r300->hiz_clear_value);
END_CS;
/* Mark the current zbuffer's hiz ram as in use. */
tex->hiz_in_use[fb->zsbuf->u.tex.level] = TRUE;
r300->hiz_in_use = TRUE;
r300->hiz_func = HIZ_FUNC_NONE;
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state)
@ -1236,7 +1190,7 @@ unsigned r300_get_num_cs_end_dwords(struct r300_context *r300)
/* Emitted in flush. */
dwords += 26; /* emit_query_end */
dwords += r300->hyperz_state.size + 2; /* emit_hyperz_end + zcache flush */
if (r300->screen->caps.index_bias_supported)
if (r300->screen->caps.is_r500)
dwords += 2;
return dwords;

View file

@ -57,7 +57,7 @@ static void r300_flush(struct pipe_context* pipe,
if (r300->dirty_hw) {
r300_emit_hyperz_end(r300);
r300_emit_query_end(r300);
if (r300->screen->caps.index_bias_supported)
if (r300->screen->caps.is_r500)
r500_emit_index_bias(r300, 0);
r300->flush_counter++;

View file

@ -22,7 +22,6 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "r300_context.h"
#include "r300_hyperz.h"
#include "r300_reg.h"
#include "r300_fs.h"
#include "r300_winsys.h"
@ -41,58 +40,74 @@
/* The HyperZ setup */
/*****************************************************************************/
static bool r300_get_sc_hz_max(struct r300_context *r300)
static enum r300_hiz_func r300_get_hiz_func(struct r300_context *r300)
{
struct r300_dsa_state *dsa_state = r300->dsa_state.state;
int func = dsa_state->z_stencil_control & R300_ZS_MASK;
int ret = R300_SC_HYPERZ_MIN;
struct r300_dsa_state *dsa = r300->dsa_state.state;
if (func >= R300_ZS_GEQUAL && func <= R300_ZS_ALWAYS)
ret = R300_SC_HYPERZ_MAX;
return ret;
if (!dsa->dsa.depth.enabled || !dsa->dsa.depth.writemask)
return HIZ_FUNC_NONE;
switch (dsa->dsa.depth.func) {
case PIPE_FUNC_NEVER:
case PIPE_FUNC_EQUAL:
case PIPE_FUNC_NOTEQUAL:
case PIPE_FUNC_ALWAYS:
return HIZ_FUNC_NONE;
case PIPE_FUNC_LESS:
case PIPE_FUNC_LEQUAL:
return HIZ_FUNC_MAX;
case PIPE_FUNC_GREATER:
case PIPE_FUNC_GEQUAL:
return HIZ_FUNC_MIN;
default:
assert(0);
return HIZ_FUNC_NONE;
}
}
static bool r300_zfunc_same_direction(int func1, int func2)
/* Return what's used for the depth test (either minimum or maximum). */
static unsigned r300_get_sc_hz_max(struct r300_context *r300)
{
struct r300_dsa_state *dsa = r300->dsa_state.state;
unsigned func = dsa->dsa.depth.func;
return func >= PIPE_FUNC_GREATER ? R300_SC_HYPERZ_MAX : R300_SC_HYPERZ_MIN;
}
static boolean r300_is_hiz_func_valid(struct r300_context *r300)
{
struct r300_dsa_state *dsa = r300->dsa_state.state;
unsigned func = dsa->dsa.depth.func;
if (r300->hiz_func == HIZ_FUNC_NONE)
return TRUE;
/* func1 is less/lessthan */
if ((func1 == R300_ZS_LESS || func1 == R300_ZS_LEQUAL) &&
(func2 == R300_ZS_EQUAL || func2 == R300_ZS_GEQUAL ||
func2 == R300_ZS_GREATER))
return FALSE;
if (r300->hiz_func == HIZ_FUNC_MAX &&
(func == PIPE_FUNC_GEQUAL || func == PIPE_FUNC_GREATER))
return FALSE;
/* func1 is greater/greaterthan */
if ((func1 == R300_ZS_GEQUAL || func1 == R300_ZS_GREATER) &&
(func2 == R300_ZS_LESS || func2 == R300_ZS_LEQUAL))
return FALSE;
if (r300->hiz_func == HIZ_FUNC_MIN &&
(func == PIPE_FUNC_LESS || func == PIPE_FUNC_LEQUAL))
return FALSE;
return TRUE;
}
static int r300_get_hiz_min(struct r300_context *r300)
{
struct r300_dsa_state *dsa_state = r300->dsa_state.state;
int func = dsa_state->z_stencil_control & R300_ZS_MASK;
int ret = R300_HIZ_MIN;
if (func == R300_ZS_LESS || func == R300_ZS_LEQUAL)
ret = R300_HIZ_MAX;
return ret;
}
static boolean r300_dsa_stencil_op_not_keep(struct pipe_stencil_state *s)
{
if (s->enabled && (s->fail_op != PIPE_STENCIL_OP_KEEP ||
s->zfail_op != PIPE_STENCIL_OP_KEEP))
return TRUE;
return FALSE;
return s->enabled && (s->fail_op != PIPE_STENCIL_OP_KEEP ||
s->zfail_op != PIPE_STENCIL_OP_KEEP);
}
static boolean r300_can_hiz(struct r300_context *r300)
{
struct r300_dsa_state *dsa_state = r300->dsa_state.state;
struct pipe_depth_stencil_alpha_state *dsa = &dsa_state->dsa;
struct r300_screen* r300screen = r300->screen;
struct r300_hyperz_state *z = r300->hyperz_state.state;
struct r300_dsa_state *dsa = r300->dsa_state.state;
struct r300_screen *r300screen = r300->screen;
/* shader writes depth - no HiZ */
if (r300_fragment_shader_writes_depth(r300_fs(r300))) /* (5) */
@ -100,34 +115,21 @@ static boolean r300_can_hiz(struct r300_context *r300)
if (r300->query_current)
return FALSE;
/* if stencil fail/zfail op is not KEEP */
if (r300_dsa_stencil_op_not_keep(&dsa->stencil[0]) ||
r300_dsa_stencil_op_not_keep(&dsa->stencil[1]))
if (r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[0]) ||
r300_dsa_stencil_op_not_keep(&dsa->dsa.stencil[1]))
return FALSE;
if (dsa->depth.enabled) {
if (dsa->dsa.depth.enabled) {
/* if depth func is EQUAL pre-r500 */
if (dsa->depth.func == PIPE_FUNC_EQUAL && !r300screen->caps.is_r500)
if (dsa->dsa.depth.func == PIPE_FUNC_EQUAL && !r300screen->caps.is_r500)
return FALSE;
/* if depth func is NOTEQUAL */
if (dsa->depth.func == PIPE_FUNC_NOTEQUAL)
if (dsa->dsa.depth.func == PIPE_FUNC_NOTEQUAL)
return FALSE;
}
/* depth comparison function - if just cleared save and return okay */
if (z->current_func == -1) {
int func = dsa_state->z_stencil_control & R300_ZS_MASK;
if (func != 0 && func != 7)
z->current_func = dsa_state->z_stencil_control & R300_ZS_MASK;
} else {
/* simple don't change */
if (!r300_zfunc_same_direction(z->current_func,
(dsa_state->z_stencil_control & R300_ZS_MASK))) {
DBG(r300, DBG_HYPERZ,
"z func changed direction - disabling hyper-z %d -> %d\n",
z->current_func, dsa_state->z_stencil_control);
return FALSE;
}
}
return TRUE;
}
@ -139,7 +141,6 @@ static void r300_update_hyperz(struct r300_context* r300)
(struct pipe_framebuffer_state*)r300->fb_state.state;
struct r300_resource *zstex =
fb->zsbuf ? r300_resource(fb->zsbuf->texture) : NULL;
boolean hiz_in_use = FALSE;
z->gb_z_peq_config = 0;
z->zb_bw_cntl = 0;
@ -151,16 +152,12 @@ static void r300_update_hyperz(struct r300_context* r300)
return;
}
if (!zstex)
if (!zstex ||
!r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
return;
if (!r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
return;
hiz_in_use = zstex->hiz_in_use[fb->zsbuf->u.tex.level];
/* Zbuffer compression. */
if (r300->zmask_in_use && !r300->zmask_locked) {
if (r300->zmask_in_use && !r300->hyperz_locked) {
z->zb_bw_cntl |= R300_FAST_FILL_ENABLE |
/*R300_FORCE_COMPRESSED_STENCIL_VALUE_ENABLE |*/
R300_RD_COMP_ENABLE;
@ -174,16 +171,28 @@ static void r300_update_hyperz(struct r300_context* r300)
z->gb_z_peq_config |= R300_GB_Z_PEQ_CONFIG_Z_PEQ_SIZE_8_8;
}
if (hiz_in_use && r300_can_hiz(r300)) {
z->zb_bw_cntl |= R300_HIZ_ENABLE |
r300_get_hiz_min(r300);
/* HiZ. */
if (r300->hiz_in_use && !r300->hyperz_locked) {
/* Set the HiZ function if needed. */
if (r300->hiz_func == HIZ_FUNC_NONE) {
r300->hiz_func = r300_get_hiz_func(r300);
}
z->sc_hyperz |= R300_SC_HYPERZ_ENABLE |
r300_get_sc_hz_max(r300);
/* If the depth function is inverted, HiZ must be disabled. */
if (!r300_is_hiz_func_valid(r300)) {
r300->hiz_in_use = FALSE;
} else if (r300_can_hiz(r300)) {
/* Setup the HiZ bits. */
z->zb_bw_cntl |=
R300_HIZ_ENABLE |
(r300->hiz_func == HIZ_FUNC_MIN ? R300_HIZ_MIN : R300_HIZ_MAX);
if (r300->screen->caps.is_r500) {
z->zb_bw_cntl |= R500_HIZ_FP_EXP_BITS_3 |
R500_HIZ_EQUAL_REJECT_ENABLE;
z->sc_hyperz |= R300_SC_HYPERZ_ENABLE |
r300_get_sc_hz_max(r300);
if (r300->screen->caps.is_r500) {
z->zb_bw_cntl |= R500_HIZ_EQUAL_REJECT_ENABLE;
}
}
}
@ -282,18 +291,6 @@ static void r300_update_ztop(struct r300_context* r300)
r300_mark_atom_dirty(r300, &r300->ztop_state);
}
#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
static void r300_update_hiz_clear(struct r300_context *r300)
{
struct pipe_framebuffer_state *fb =
(struct pipe_framebuffer_state*)r300->fb_state.state;
uint32_t height;
height = ALIGN_DIVUP(fb->zsbuf->height, 4);
r300->hiz_clear.size = height * 4;
}
void r300_update_hyperz_state(struct r300_context* r300)
{
r300_update_ztop(r300);
@ -301,51 +298,4 @@ void r300_update_hyperz_state(struct r300_context* r300)
if (r300->hyperz_state.dirty) {
r300_update_hyperz(r300);
}
if (r300->hiz_clear.dirty) {
r300_update_hiz_clear(r300);
}
}
void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf)
{
struct r300_resource *tex;
uint32_t zsize, ndw;
int level = surf->base.u.tex.level;
tex = r300_resource(surf->base.texture);
if (tex->hiz_mem[level])
return;
zsize = tex->tex.layer_size_in_bytes[level];
zsize /= util_format_get_blocksize(tex->b.b.b.format);
ndw = ALIGN_DIVUP(zsize, 64);
tex->hiz_mem[level] = u_mmAllocMem(r300->hiz_mm, ndw, 0, 0);
}
boolean r300_hyperz_init_mm(struct r300_context *r300)
{
struct r300_screen* r300screen = r300->screen;
int frag_pipes = r300screen->caps.num_frag_pipes;
if (r300screen->caps.hiz_ram) {
r300->hiz_mm = u_mmInit(0, r300screen->caps.hiz_ram * frag_pipes);
if (!r300->hiz_mm) {
return FALSE;
}
}
return TRUE;
}
void r300_hyperz_destroy_mm(struct r300_context *r300)
{
struct r300_screen* r300screen = r300->screen;
if (r300screen->caps.hiz_ram) {
u_mmDestroy(r300->hiz_mm);
r300->hiz_mm = NULL;
}
}

View file

@ -1,35 +0,0 @@
/*
* 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 R300_HYPERZ_H
#define R300_HYPERZ_H
struct r300_context;
void r300_update_hyperz_state(struct r300_context* r300);
void r300_hiz_alloc_block(struct r300_context *r300, struct r300_surface *surf);
boolean r300_hyperz_init_mm(struct r300_context *r300);
void r300_hyperz_destroy_mm(struct r300_context *r300);
#endif

View file

@ -467,6 +467,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* See bug #9871. http://bugs.freedesktop.org/attachment.cgi?id=10672&action=view
*/
#define R500_VAP_TEX_TO_COLOR_CNTL 0x2218
#define R300_VAP_CLIP_CNTL 0x221C
# define R300_VAP_UCP_ENABLE_0 (1 << 0)
# define R300_VAP_UCP_ENABLE_1 (1 << 1)
@ -857,6 +859,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R500_TX_DIRECTION_HORIZONTAL (0<<27)
# define R500_TX_DIRECTION_VERITCAL (1<<27)
#define R500_SU_TEX_WRAP_PS3 0x4114
/* S Texture Coordinate of Vertex 0 for Point texture stuffing (LLC) */
#define R300_GA_POINT_S0 0x4200

View file

@ -205,7 +205,7 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300,
if (first_draw) {
cs_dwords += r300_get_num_dirty_dwords(r300);
if (r300->screen->caps.index_bias_supported)
if (r300->screen->caps.is_r500)
cs_dwords += 2; /* emit_index_offset */
if (emit_vertex_arrays)
@ -257,7 +257,7 @@ static boolean r300_emit_states(struct r300_context *r300,
}
r300_emit_dirty_state(r300);
if (r300->screen->caps.index_bias_supported) {
if (r300->screen->caps.is_r500) {
if (r300->screen->caps.has_tcl)
r500_emit_index_bias(r300, index_bias);
else
@ -557,7 +557,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300_translate_primitive(mode));
if (indexBias && !r300->screen->caps.index_bias_supported) {
if (indexBias && !r300->screen->caps.is_r500) {
for (i = 0; i < count-1; i += 2)
OUT_CS(((ptr1[i+1] + indexBias) << 16) |
(ptr1[i] + indexBias));
@ -581,7 +581,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300_translate_primitive(mode));
if (indexBias && !r300->screen->caps.index_bias_supported) {
if (indexBias && !r300->screen->caps.is_r500) {
for (i = 0; i < count-1; i += 2)
OUT_CS(((ptr2[i+1] + indexBias) << 16) |
(ptr2[i] + indexBias));
@ -601,7 +601,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
r300_translate_primitive(mode));
if (indexBias && !r300->screen->caps.index_bias_supported) {
if (indexBias && !r300->screen->caps.is_r500) {
for (i = 0; i < count; i++)
OUT_CS(ptr4[i] + indexBias);
} else {
@ -620,13 +620,12 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias,
unsigned indexSize = r300->index_buffer.index_size;
struct pipe_resource* orgIndexBuffer = indexBuffer;
boolean alt_num_verts = r300->screen->caps.is_r500 &&
count > 65536 &&
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
count > 65536;
unsigned short_count;
int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
uint16_t indices3[3];
if (indexBias && !r300->screen->caps.index_bias_supported) {
if (indexBias && !r300->screen->caps.is_r500) {
r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset);
}
@ -702,8 +701,7 @@ static void r300_draw_arrays(struct r300_context *r300, unsigned mode,
unsigned start, unsigned count)
{
boolean alt_num_verts = r300->screen->caps.is_r500 &&
count > 65536 &&
r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0);
count > 65536;
unsigned short_count;
/* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */
@ -748,6 +746,8 @@ static void r300_draw_vbo(struct pipe_context* pipe,
return;
}
r300_update_derived_state(r300);
/* Start the vbuf manager and update buffers if needed. */
u_vbuf_mgr_draw_begin(r300->vbuf_mgr, info,
&buffers_updated, &uploader_flushed);
@ -756,8 +756,6 @@ static void r300_draw_vbo(struct pipe_context* pipe,
}
/* Draw. */
r300_update_derived_state(r300);
if (indexed) {
if (count <= 8 &&
r300_resource(r300->index_buffer.buffer)->b.user_ptr) {

View file

@ -456,10 +456,6 @@ struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws)
if (SCREEN_DBG_ON(r300screen, DBG_NO_HIZ))
r300screen->caps.hiz_ram = 0;
r300screen->caps.index_bias_supported =
r300screen->caps.is_r500 &&
rws->get_value(rws, R300_VID_DRM_2_3_0);
pipe_mutex_init(r300screen->num_contexts_mutex);
util_slab_create(&r300screen->pool_buffers,

View file

@ -45,7 +45,6 @@
#include "r300_texture.h"
#include "r300_vs.h"
#include "r300_winsys.h"
#include "r300_hyperz.h"
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@ -707,7 +706,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
else if (state->zsbuf) {
r300->fb_state.size += 10;
if (can_hyperz)
r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4;
r300->fb_state.size += 8;
}
/* The size of the rest of atoms stays the same. */
@ -720,7 +719,6 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
struct pipe_framebuffer_state *old_state = r300->fb_state.state;
boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
unsigned max_width, max_height, i;
uint32_t zbuffer_bpp = 0;
@ -738,28 +736,30 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
return;
}
if (old_state->zsbuf && r300->zmask_in_use && !r300->zmask_locked) {
if (old_state->zsbuf && r300->zmask_in_use && !r300->hyperz_locked) {
/* There is a zmask in use, what are we gonna do? */
if (state->zsbuf) {
if (!pipe_surface_equal(old_state->zsbuf, state->zsbuf)) {
/* Decompress the currently bound zbuffer before we bind another one. */
r300_decompress_zmask(r300);
r300->hiz_in_use = FALSE;
}
} else {
/* We don't bind another zbuffer, so lock the current one. */
r300->zmask_locked = TRUE;
r300->hyperz_locked = TRUE;
pipe_surface_reference(&r300->locked_zbuffer, old_state->zsbuf);
}
} else if (r300->zmask_locked && r300->locked_zbuffer) {
} else if (r300->hyperz_locked && r300->locked_zbuffer) {
/* We have a locked zbuffer now, what are we gonna do? */
if (state->zsbuf) {
if (!pipe_surface_equal(r300->locked_zbuffer, state->zsbuf)) {
/* We are binding some other zbuffer, so decompress the locked one,
* it gets unlocked automatically. */
r300_decompress_zmask_locked_unsafe(r300);
r300->hiz_in_use = FALSE;
} else {
/* We are binding the locked zbuffer again, so unlock it. */
r300->zmask_locked = FALSE;
r300->hyperz_locked = FALSE;
}
}
}
@ -778,7 +778,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
util_copy_framebuffer_state(r300->fb_state.state, state);
if (!r300->zmask_locked) {
if (!r300->hyperz_locked) {
pipe_surface_reference(&r300->locked_zbuffer, NULL);
}
@ -794,20 +794,6 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
break;
}
/* Setup Hyper-Z. */
if (can_hyperz) {
struct r300_surface *zs_surf = r300_surface(state->zsbuf);
struct r300_resource *tex = r300_resource(zs_surf->base.texture);
int level = zs_surf->base.u.tex.level;
/* work out whether we can support hiz on this buffer */
r300_hiz_alloc_block(r300, zs_surf);
DBG(r300, DBG_HYPERZ,
"hyper-z features: hiz: %d @ %08x\n", tex->hiz_mem[level] ? 1 : 0,
tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef);
}
/* Polygon offset depends on the zbuffer bit depth. */
if (r300->zbuffer_bpp != zbuffer_bpp) {
r300->zbuffer_bpp = zbuffer_bpp;
@ -818,27 +804,25 @@ r300_set_framebuffer_state(struct pipe_context* pipe,
}
/* Set up AA config. */
if (r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0)) {
if (state->nr_cbufs && state->cbufs[0]->texture->nr_samples > 1) {
aa->aa_config = R300_GB_AA_CONFIG_AA_ENABLE;
if (state->nr_cbufs && state->cbufs[0]->texture->nr_samples > 1) {
aa->aa_config = R300_GB_AA_CONFIG_AA_ENABLE;
switch (state->cbufs[0]->texture->nr_samples) {
case 2:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2;
break;
case 3:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3;
break;
case 4:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4;
break;
case 6:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6;
break;
}
} else {
aa->aa_config = 0;
switch (state->cbufs[0]->texture->nr_samples) {
case 2:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_2;
break;
case 3:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_3;
break;
case 4:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_4;
break;
case 6:
aa->aa_config |= R300_GB_AA_CONFIG_NUM_AA_SUBSAMPLES_6;
break;
}
} else {
aa->aa_config = 0;
}
if (DBG_ON(r300, DBG_FB)) {

View file

@ -29,7 +29,6 @@
#include "r300_context.h"
#include "r300_fs.h"
#include "r300_hyperz.h"
#include "r300_screen.h"
#include "r300_shader_semantics.h"
#include "r300_state_inlines.h"
@ -642,8 +641,25 @@ static uint32_t r300_get_border_color(enum pipe_format format,
/* Compressed formats. */
if (util_format_is_compressed(format)) {
util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
return uc.ui;
switch (format) {
case PIPE_FORMAT_RGTC1_SNORM:
case PIPE_FORMAT_RGTC1_UNORM:
/* Add 1/32 to round the border color instead of truncating. */
/* The Y component is used for the border color. */
border_swizzled[1] = border_swizzled[2] + 1.0f/32;
util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc);
return uc.ui;
case PIPE_FORMAT_RGTC2_SNORM:
border_swizzled[0] = border_swizzled[2];
util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc);
return uc.ui;
case PIPE_FORMAT_RGTC2_UNORM:
util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
return uc.ui;
default:
util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
return uc.ui;
}
}
switch (desc->channel[0].size) {
@ -937,7 +953,7 @@ static void r300_decompress_depth_textures(struct r300_context *r300)
state->sampler_state_count);
unsigned i;
if (!r300->zmask_locked || !r300->locked_zbuffer) {
if (!r300->hyperz_locked || !r300->locked_zbuffer) {
return;
}

View file

@ -171,8 +171,16 @@ uint32_t r300_translate_texformat(enum pipe_format format,
}
}
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
util_format_is_compressed(format) && dxtc_swizzle);
if (util_format_is_compressed(format) &&
dxtc_swizzle &&
format != PIPE_FORMAT_RGTC2_UNORM &&
format != PIPE_FORMAT_RGTC2_SNORM) {
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
dxtc_swizzle);
} else {
result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view,
FALSE);
}
/* S3TC formats. */
if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
@ -197,10 +205,19 @@ uint32_t r300_translate_texformat(enum pipe_format format,
}
}
/* Add sign. */
for (i = 0; i < desc->nr_channels; i++) {
if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
result |= sign_bit[i];
/* RGTC formats. */
if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
switch (format) {
case PIPE_FORMAT_RGTC1_SNORM:
result |= sign_bit[1];
case PIPE_FORMAT_RGTC1_UNORM:
return R500_TX_FORMAT_ATI1N | result;
case PIPE_FORMAT_RGTC2_SNORM:
result |= sign_bit[2] | sign_bit[3];
case PIPE_FORMAT_RGTC2_UNORM:
return R400_TX_FORMAT_ATI2N | result;
default:
return ~0; /* Unsupported/unknown. */
}
}
@ -211,24 +228,10 @@ uint32_t r300_translate_texformat(enum pipe_format format,
return R300_TX_FORMAT_CxV8U8 | result;
}
/* RGTC formats. */
if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
switch (format) {
case PIPE_FORMAT_RGTC1_SNORM:
result |= sign_bit[0];
case PIPE_FORMAT_RGTC1_UNORM:
result &= ~(0xfff << 9); /* mask off swizzle */
result |= R300_TX_FORMAT_Y << R300_TX_FORMAT_R_SHIFT;
return R500_TX_FORMAT_ATI1N | result;
case PIPE_FORMAT_RGTC2_SNORM:
result |= sign_bit[0] | sign_bit[1];
case PIPE_FORMAT_RGTC2_UNORM:
result &= ~(0xfff << 9); /* mask off swizzle */
result |= R300_TX_FORMAT_Y << R300_TX_FORMAT_R_SHIFT |
R300_TX_FORMAT_X << R300_TX_FORMAT_G_SHIFT;
return R400_TX_FORMAT_ATI2N | result;
default:
return ~0; /* Unsupported/unknown. */
/* Add sign. */
for (i = 0; i < desc->nr_channels; i++) {
if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) {
result |= sign_bit[i];
}
}
@ -676,6 +679,8 @@ static void r300_texture_setup_fb_state(struct r300_surface *surf)
R300_DEPTHMACROTILE(tex->tex.macrotile[level]) |
R300_DEPTHMICROTILE(tex->tex.microtile);
surf->format = r300_translate_zsformat(surf->base.format);
surf->pitch_zmask = tex->tex.zmask_stride_in_pixels[level];
surf->pitch_hiz = tex->tex.hiz_stride_in_pixels[level];
} else {
surf->pitch =
tex->tex.stride_in_pixels[level] |
@ -713,14 +718,8 @@ static void r300_texture_destroy(struct pipe_screen *screen,
struct pipe_resource* texture)
{
struct r300_resource* tex = (struct r300_resource*)texture;
int i;
r300_winsys_bo_reference(&tex->buf, NULL);
for (i = 0; i < R300_MAX_TEXTURE_LEVELS; i++) {
if (tex->hiz_mem[i])
u_mmFreeMem(tex->hiz_mem[i]);
}
FREE(tex);
}
@ -868,8 +867,7 @@ struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
break;
case 2:
if (rws->get_value(rws, R300_VID_DRM_2_1_0))
microtile = R300_BUFFER_SQUARETILED;
microtile = R300_BUFFER_SQUARETILED;
break;
}
}

View file

@ -207,29 +207,6 @@ static unsigned r300_texture_get_nblocksy(struct r300_resource *tex,
return util_format_get_nblocksy(tex->b.b.b.format, height);
}
static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
struct r300_resource *tex)
{
/* The kernels <= 2.6.34-rc4 compute the size of mipmapped 3D textures
* incorrectly. This is a workaround to prevent CS from being rejected. */
unsigned i, size;
if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
tex->b.b.b.target == PIPE_TEXTURE_3D &&
tex->b.b.b.last_level > 0) {
size = 0;
for (i = 0; i <= tex->b.b.b.last_level; i++) {
size += tex->tex.stride_in_bytes[i] *
r300_texture_get_nblocksy(tex, i, FALSE);
}
size *= tex->tex.depth0;
tex->tex.size_in_bytes = size;
}
}
/* Get a width in pixels from a stride in bytes. */
static unsigned stride_to_width(enum pipe_format format,
unsigned stride_in_bytes)
@ -334,12 +311,17 @@ static void r300_setup_cbzb_flags(struct r300_screen *rscreen,
tex->tex.cbzb_allowed[i] = first_level_valid && tex->tex.macrotile[i];
}
#define ALIGN_DIVUP(x, y) (((x) + (y) - 1) / (y))
static void r300_setup_zmask_flags(struct r300_screen *screen,
struct r300_resource *tex)
static unsigned r300_pixels_to_dwords(unsigned stride,
unsigned height,
unsigned xblock, unsigned yblock)
{
/* The tile size of 1 DWORD is:
return (align(stride, xblock) * align(height, yblock)) / (xblock * yblock);
}
static void r300_setup_hyperz_properties(struct r300_screen *screen,
struct r300_resource *tex)
{
/* The tile size of 1 DWORD in ZMASK RAM is:
*
* GPU Pipes 4x4 mode 8x8 mode
* ------------------------------------------
@ -348,8 +330,31 @@ static void r300_setup_zmask_flags(struct r300_screen *screen,
* RV530 1P/2Z 32x16 64x32
* 1P/1Z 16x16 32x32
*/
static unsigned num_blocks_x_per_dw[4] = {4, 8, 12, 8};
static unsigned num_blocks_y_per_dw[4] = {4, 4, 4, 8};
static unsigned zmask_blocks_x_per_dw[4] = {4, 8, 12, 8};
static unsigned zmask_blocks_y_per_dw[4] = {4, 4, 4, 8};
/* In HIZ RAM, one dword is always 8x8 pixels (each byte is 4x4 pixels),
* but the blocks have very weird ordering.
*
* With 2 pipes and an image of size 8xY, where Y >= 1,
* clearing 4 dwords clears blocks like this:
*
* 01012323
*
* where numbers correspond to dword indices. The blocks are interleaved
* in the X direction, so the alignment must be 4x1 blocks (32x8 pixels).
*
* With 4 pipes and an image of size 8xY, where Y >= 4,
* clearing 8 dwords clears blocks like this:
* 01012323
* 45456767
* 01012323
* 45456767
* where numbers correspond to dword indices. The blocks are interleaved
* in both directions, so the alignment must be 4x4 blocks (32x32 pixels)
*/
static unsigned hiz_align_x[4] = {8, 32, 48, 32};
static unsigned hiz_align_y[4] = {8, 8, 8, 32};
if (util_format_is_depth_or_stencil(tex->b.b.b.format) &&
util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
@ -363,30 +368,49 @@ static void r300_setup_zmask_flags(struct r300_screen *screen,
}
for (i = 0; i <= tex->b.b.b.last_level; i++) {
unsigned numdw, compsize;
unsigned zcomp_numdw, zcompsize, hiz_numdw, stride, height;
stride = align(tex->tex.stride_in_pixels[i], 16);
height = u_minify(tex->b.b.b.height0, i);
/* The 8x8 compression mode needs macrotiling. */
compsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
zcompsize = screen->caps.z_compress == R300_ZCOMP_8X8 &&
tex->tex.macrotile[i] &&
tex->b.b.b.nr_samples <= 1 ? 8 : 4;
/* Get the zbuffer size (with the aligned width and height). */
numdw = align(tex->tex.stride_in_pixels[i],
num_blocks_x_per_dw[pipes-1] * compsize) *
align(u_minify(tex->b.b.b.height0, i),
num_blocks_y_per_dw[pipes-1] * compsize);
/* Get the ZMASK buffer size in dwords. */
zcomp_numdw = r300_pixels_to_dwords(stride, height,
zmask_blocks_x_per_dw[pipes-1] * zcompsize,
zmask_blocks_y_per_dw[pipes-1] * zcompsize);
/* Convert pixels -> dwords. */
numdw = ALIGN_DIVUP(numdw, num_blocks_x_per_dw[pipes-1] * compsize *
num_blocks_y_per_dw[pipes-1] * compsize);
/* Check whether we have enough ZMASK memory. */
if (util_format_get_blocksizebits(tex->b.b.b.format) == 32 &&
zcomp_numdw <= screen->caps.zmask_ram * pipes) {
tex->tex.zmask_dwords[i] = zcomp_numdw;
tex->tex.zcomp8x8[i] = zcompsize == 8;
/* Check that we have enough ZMASK memory. */
if (numdw <= screen->caps.zmask_ram * pipes) {
tex->tex.zmask_dwords[i] = numdw;
tex->tex.zcomp8x8[i] = compsize == 8;
tex->tex.zmask_stride_in_pixels[i] =
align(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize);
} else {
tex->tex.zmask_dwords[i] = 0;
tex->tex.zcomp8x8[i] = FALSE;
tex->tex.zmask_stride_in_pixels[i] = 0;
}
/* Now setup HIZ. */
stride = align(stride, hiz_align_x[pipes-1]);
height = align(height, hiz_align_y[pipes-1]);
/* Get the HIZ buffer size in dwords. */
hiz_numdw = (stride * height) / (8*8 * pipes);
/* Check whether we have enough HIZ memory. */
if (hiz_numdw <= screen->caps.hiz_ram * pipes) {
tex->tex.hiz_dwords[i] = hiz_numdw;
tex->tex.hiz_stride_in_pixels[i] = stride;
} else {
tex->tex.hiz_dwords[i] = 0;
tex->tex.hiz_stride_in_pixels[i] = 0;
}
}
}
@ -395,7 +419,6 @@ static void r300_setup_zmask_flags(struct r300_screen *screen,
static void r300_setup_tiling(struct r300_screen *screen,
struct r300_resource *tex)
{
struct r300_winsys_screen *rws = screen->rws;
enum pipe_format format = tex->b.b.b.format;
boolean rv350_mode = screen->caps.family >= CHIP_FAMILY_R350;
boolean is_zb = util_format_is_depth_or_stencil(format);
@ -422,9 +445,7 @@ static void r300_setup_tiling(struct r300_screen *screen,
break;
case 2:
if (rws->get_value(rws, R300_VID_DRM_2_1_0)) {
tex->tex.microtile = R300_BUFFER_SQUARETILED;
}
tex->tex.microtile = R300_BUFFER_SQUARETILED;
break;
}
@ -494,8 +515,7 @@ boolean r300_texture_desc_init(struct r300_screen *rscreen,
r300_setup_miptree(rscreen, tex, FALSE);
}
r300_texture_3d_fix_mipmapping(rscreen, tex);
r300_setup_zmask_flags(rscreen, tex);
r300_setup_hyperz_properties(rscreen, tex);
if (tex->buf_size) {
/* Make sure the buffer we got is large enough. */

View file

@ -60,10 +60,8 @@ enum r300_value_id {
R300_VID_DRM_PATCHLEVEL,
/* These should probably go away: */
R300_VID_DRM_2_1_0, /* Square tiling. */
R300_VID_DRM_2_3_0, /* R500 VAP regs, MSPOS regs, fixed tex3D size checking */
R300_VID_DRM_2_6_0, /* Hyper-Z, GB_Z_PEQ_CONFIG on rv350->r4xx, R500 FG_ALPHA_VALUE */
R300_VID_DRM_2_8_0, /* R500 US_FORMAT regs, R500 ARGB2101010 colorbuffer, CMask */
R300_VID_DRM_2_8_0, /* R500 US_FORMAT regs, R500 ARGB2101010 colorbuffer, CMask, R16F/RG16F */
R300_CAN_HYPERZ, /* ZMask + HiZ */
R300_CAN_AACOMPRESS, /* CMask */

View file

@ -503,9 +503,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
}
}
static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format)
static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
{
return r600_translate_texformat(format, NULL, NULL, NULL) != ~0;
return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0;
}
static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)

View file

@ -305,11 +305,16 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
{
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
union util_color uc;
uint32_t coord_trunc = 0;
if (rstate == NULL) {
return NULL;
}
if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) ||
(state->min_img_filter == PIPE_TEX_FILTER_NEAREST))
coord_trunc = 1;
rstate->id = R600_PIPE_STATE_SAMPLER;
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@ -328,6 +333,7 @@ static void *evergreen_create_sampler_state(struct pipe_context *ctx,
0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0,
S_03C008_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 8)) |
S_03C008_MC_COORD_TRUNCATE(coord_trunc) |
S_03C008_TYPE(1),
0xFFFFFFFF, NULL);
@ -370,7 +376,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
swizzle[1] = state->swizzle_g;
swizzle[2] = state->swizzle_b;
swizzle[3] = state->swizzle_a;
format = r600_translate_texformat(state->format,
format = r600_translate_texformat(ctx->screen, state->format,
swizzle,
&word4, &yuv_format);
if (format == ~0) {

View file

@ -108,8 +108,9 @@
#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 PKT3_PREDICATE(x) (((x) >> 0) & 0x1)
#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))
#define PKT3(op, count, predicate) (PKT_TYPE_S(3) | PKT3_IT_OPCODE_S(op) | PKT_COUNT_S(count) | PKT3_PREDICATE(predicate))
/* Registers */
#define R_008C00_SQ_CONFIG 0x00008C00

View file

@ -114,6 +114,8 @@ enum radeon_family r600_get_family(struct radeon *rw);
enum chip_class r600_get_family_class(struct radeon *radeon);
struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon);
unsigned r600_get_clock_crystal_freq(struct radeon *radeon);
unsigned r600_get_minor_version(struct radeon *radeon);
unsigned r600_get_num_backends(struct radeon *radeon);
/* r600_bo.c */
struct r600_bo;
@ -251,6 +253,7 @@ struct r600_context {
unsigned num_query_running;
struct list_head fenced_bo;
unsigned max_db; /* for OQ */
boolean predicate_drawing;
};
struct r600_draw {
@ -283,6 +286,8 @@ void r600_query_begin(struct r600_context *ctx, struct r600_query *query);
void r600_query_end(struct r600_context *ctx, struct r600_query *query);
void r600_context_queries_suspend(struct r600_context *ctx);
void r600_context_queries_resume(struct r600_context *ctx);
void r600_query_predication(struct r600_context *ctx, struct r600_query *query, int operation,
int flag_wait);
int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon);
void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *draw);

View file

@ -3061,7 +3061,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
vtx.fetch_type = elements[i].instance_divisor ? 1 : 0;
vtx.src_gpr = elements[i].instance_divisor > 1 ? i + 1 : 0;
vtx.src_sel_x = elements[i].instance_divisor ? 3 : 0;
vtx.mega_fetch_count = 16;
vtx.mega_fetch_count = 0x1F;
vtx.dst_gpr = i + 1;
vtx.dst_sel_x = desc->swizzle[0];
vtx.dst_sel_y = desc->swizzle[1];

View file

@ -431,7 +431,7 @@ static boolean r600_is_format_supported(struct pipe_screen* screen,
return FALSE;
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
r600_is_sampler_format_supported(format)) {
r600_is_sampler_format_supported(screen, format)) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}

View file

@ -227,7 +227,7 @@ int r600_conv_pipe_prim(unsigned pprim, unsigned *prim);
/* r600_texture.c */
void r600_init_screen_texture_functions(struct pipe_screen *screen);
void r600_init_surface_functions(struct r600_pipe_context *r600);
uint32_t r600_translate_texformat(enum pipe_format format,
uint32_t r600_translate_texformat(struct pipe_screen *screen, enum pipe_format format,
const unsigned char *swizzle_view,
uint32_t *word4_p, uint32_t *yuv_format_p);
unsigned r600_texture_get_offset(struct r600_resource_texture *rtex,

View file

@ -21,6 +21,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "r600_pipe.h"
#include "r600d.h"
static struct pipe_query *r600_create_query(struct pipe_context *ctx, unsigned query_type)
{
@ -66,6 +67,30 @@ static boolean r600_get_query_result(struct pipe_context *ctx,
return r600_context_query_result(&rctx->ctx, (struct r600_query *)query, wait, vresult);
}
static void r600_render_condition(struct pipe_context *ctx,
struct pipe_query *query,
uint mode)
{
struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
struct r600_query *rquery = (struct r600_query *)query;
int wait_flag = 0;
if (!query) {
rctx->ctx.predicate_drawing = false;
r600_query_predication(&rctx->ctx, NULL, PREDICATION_OP_CLEAR, 1);
return;
}
if (mode == PIPE_RENDER_COND_WAIT ||
mode == PIPE_RENDER_COND_BY_REGION_WAIT) {
wait_flag = 1;
}
rctx->ctx.predicate_drawing = true;
r600_query_predication(&rctx->ctx, rquery, PREDICATION_OP_ZPASS, wait_flag);
}
void r600_init_query_functions(struct r600_pipe_context *rctx)
{
rctx->context.create_query = r600_create_query;
@ -73,4 +98,7 @@ void r600_init_query_functions(struct r600_pipe_context *rctx)
rctx->context.begin_query = r600_begin_query;
rctx->context.end_query = r600_end_query;
rctx->context.get_query_result = r600_get_query_result;
if (r600_get_num_backends(rctx->screen->radeon) > 0)
rctx->context.render_condition = r600_render_condition;
}

View file

@ -358,11 +358,16 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
{
struct r600_pipe_state *rstate = CALLOC_STRUCT(r600_pipe_state);
union util_color uc;
uint32_t coord_trunc = 0;
if (rstate == NULL) {
return NULL;
}
if ((state->mag_img_filter == PIPE_TEX_FILTER_NEAREST) ||
(state->min_img_filter == PIPE_TEX_FILTER_NEAREST))
coord_trunc = 1;
rstate->id = R600_PIPE_STATE_SAMPLER;
util_pack_color(state->border_color, PIPE_FORMAT_B8G8R8A8_UNORM, &uc);
r600_pipe_state_add_reg(rstate, R_03C000_SQ_TEX_SAMPLER_WORD0_0,
@ -379,7 +384,9 @@ static void *r600_create_sampler_state(struct pipe_context *ctx,
S_03C004_MIN_LOD(S_FIXED(CLAMP(state->min_lod, 0, 15), 6)) |
S_03C004_MAX_LOD(S_FIXED(CLAMP(state->max_lod, 0, 15), 6)) |
S_03C004_LOD_BIAS(S_FIXED(CLAMP(state->lod_bias, -16, 16), 6)), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0, S_03C008_TYPE(1), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_03C008_SQ_TEX_SAMPLER_WORD2_0,
S_03C008_MC_COORD_TRUNCATE(coord_trunc) |
S_03C008_TYPE(1), 0xFFFFFFFF, NULL);
if (uc.ui) {
r600_pipe_state_add_reg(rstate, R_00A400_TD_PS_SAMPLER0_BORDER_RED, fui(state->border_color[0]), 0xFFFFFFFF, NULL);
r600_pipe_state_add_reg(rstate, R_00A404_TD_PS_SAMPLER0_BORDER_GREEN, fui(state->border_color[1]), 0xFFFFFFFF, NULL);
@ -420,7 +427,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c
swizzle[1] = state->swizzle_g;
swizzle[2] = state->swizzle_b;
swizzle[3] = state->swizzle_a;
format = r600_translate_texformat(state->format,
format = r600_translate_texformat(ctx->screen, state->format,
swizzle,
&word4, &yuv_format);
if (format == ~0) {

View file

@ -500,9 +500,9 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
}
}
static INLINE boolean r600_is_sampler_format_supported(enum pipe_format format)
static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
{
return r600_translate_texformat(format, NULL, NULL, NULL) != ~0;
return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0;
}
static INLINE boolean r600_is_colorbuffer_format_supported(enum pipe_format format)

View file

@ -226,7 +226,7 @@ static void r600_texture_set_array_mode(struct pipe_screen *screen,
w = mip_minify(ptex->width0, level);
h = mip_minify(ptex->height0, level);
if (w < tile_width || h < tile_height)
if (w <= tile_width || h <= tile_height)
rtex->array_mode[level] = V_0280A0_ARRAY_1D_TILED_THIN1;
else
rtex->array_mode[level] = array_mode;
@ -422,8 +422,13 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
/* Would like some magic "get_bool_option_once" routine.
*/
if (force_tiling == -1)
force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE);
if (force_tiling == -1) {
struct r600_screen *rscreen = (struct r600_screen *)screen;
if (r600_get_minor_version(rscreen->radeon) >= 9)
force_tiling = debug_get_bool_option("R600_TILING", TRUE);
else
force_tiling = debug_get_bool_option("R600_TILING", FALSE);
}
if (force_tiling && permit_hardware_blit(screen, templ)) {
if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
@ -813,7 +818,8 @@ static unsigned r600_get_swizzle_combined(const unsigned char *swizzle_format,
}
/* texture format translate */
uint32_t r600_translate_texformat(enum pipe_format format,
uint32_t r600_translate_texformat(struct pipe_screen *screen,
enum pipe_format format,
const unsigned char *swizzle_view,
uint32_t *word4_p, uint32_t *yuv_format_p)
{
@ -879,8 +885,13 @@ uint32_t r600_translate_texformat(enum pipe_format format,
break;
}
if (r600_enable_s3tc == -1)
r600_enable_s3tc = debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
if (r600_enable_s3tc == -1) {
struct r600_screen *rscreen = (struct r600_screen *)screen;
if (r600_get_minor_version(rscreen->radeon) >= 9)
r600_enable_s3tc = 1;
else
r600_enable_s3tc = debug_get_bool_option("R600_ENABLE_S3TC", FALSE);
}
if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
if (!r600_enable_s3tc)

View file

@ -67,6 +67,10 @@
#define PKT3_SET_CTL_CONST 0x6F
#define PKT3_SURFACE_BASE_UPDATE 0x73
#define PREDICATION_OP_CLEAR 0x0
#define PREDICATION_OP_ZPASS 0x1
#define PREDICATION_OP_PRIMCOUNT 0x2
#define PKT_TYPE_S(x) (((x) & 0x3) << 30)
#define PKT_TYPE_G(x) (((x) >> 30) & 0x3)
#define PKT_TYPE_C 0x3FFFFFFF

View file

@ -249,11 +249,6 @@ softpipe_is_format_supported( struct pipe_screen *screen,
return util_format_s3tc_enabled;
}
/* u_format doesn't implement RGTC yet */
if (format_desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
return FALSE;
}
/*
* Everything else should be supported by u_format.
*/

View file

@ -91,8 +91,6 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
draw_flush(softpipe->draw);
if (softpipe->fs == fs)
return;

View file

@ -40,7 +40,7 @@
#include "svga_debug.h"
#define MAX_DMA_SIZE (8 * 1024 * 1024)
#define MAX_DMA_SIZE (4 * 1024 * 1024)
/**

View file

@ -40,9 +40,12 @@
/* Convert from PIPE_SHADER_* to SVGA3D_SHADERTYPE_*
*/
static int svga_shader_type( int unit )
static int svga_shader_type( int shader )
{
return unit + 1;
assert(PIPE_SHADER_VERTEX + 1 == SVGA3D_SHADERTYPE_VS);
assert(PIPE_SHADER_FRAGMENT + 1 == SVGA3D_SHADERTYPE_PS);
assert(shader <= PIPE_SHADER_FRAGMENT);
return shader + 1;
}

View file

@ -317,6 +317,7 @@ dri2_allocate_buffer(__DRIscreen *sPriv,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
buffer->resource =
screen->base.screen->resource_create(screen->base.screen, &templ);
@ -510,6 +511,7 @@ dri2_create_image(__DRIscreen *_screen,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
templ.array_size = 1;
img->texture = screen->base.screen->resource_create(screen->base.screen, &templ);
if (!img->texture) {

View file

@ -26,6 +26,7 @@ x11_OBJECTS = $(x11_SOURCES:.c=.o)
wayland_INCLUDES = \
-I$(TOP)/src/gallium/winsys \
-I$(TOP)/src/egl/wayland \
-I$(TOP)/src/egl/wayland/wayland-drm \
$(shell pkg-config --cflags-only-I libdrm wayland-client)
wayland_SOURCES = $(wildcard wayland/*.c)

View file

@ -455,9 +455,6 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
_eglReleaseDisplayResources(drv, dpy);
if (gdpy->pipe)
gdpy->pipe->destroy(gdpy->pipe);
if (dpy->Configs) {
_eglDestroyArray(dpy->Configs, egl_g3d_free_config);
dpy->Configs = NULL;

View file

@ -56,7 +56,6 @@ struct egl_g3d_display {
const struct egl_g3d_loader *loader;
struct st_manager *smapi;
struct pipe_context *pipe;
};
struct egl_g3d_context {

View file

@ -640,6 +640,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
_EGLContext *ctx = _eglGetCurrentContext();
struct native_surface *nsurf;
struct pipe_resource *ptex;
struct pipe_context *pipe;
if (!gsurf->render_texture)
return EGL_TRUE;
@ -655,22 +656,18 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
}
/* create a pipe context to copy surfaces */
if (!gdpy->pipe) {
gdpy->pipe =
gdpy->native->screen->context_create(gdpy->native->screen, NULL);
if (!gdpy->pipe)
return EGL_FALSE;
}
pipe = ndpy_get_copy_context(gdpy->native);
if (!pipe)
return EGL_FALSE;
ptex = get_pipe_resource(gdpy->native, nsurf, NATIVE_ATTACHMENT_FRONT_LEFT);
if (ptex) {
struct pipe_box src_box;
u_box_origin_2d(ptex->width0, ptex->height0, &src_box);
gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, 0, 0, 0, 0,
pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0,
gsurf->render_texture, 0, &src_box);
gdpy->pipe->flush(gdpy->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0);
pipe_resource_reference(&ptex, NULL);

View file

@ -111,6 +111,7 @@ egl_g3d_create_drm_buffer(_EGLDisplay *dpy, _EGLImage *img,
templ.width0 = attrs.Width;
templ.height0 = attrs.Height;
templ.depth0 = 1;
templ.array_size = 1;
/*
* XXX fix apps (e.g. wayland) and pipe drivers (e.g. i915) and remove the

View file

@ -141,6 +141,11 @@ struct native_display {
*/
struct pipe_screen *screen;
/**
* Context used for copy operations.
*/
struct pipe_context *pipe;
/**
* Available for caller's use.
*/
@ -223,6 +228,29 @@ native_attachment_mask_test(uint mask, enum native_attachment att)
return !!(mask & (1 << att));
}
/**
* Get the display copy context
*/
static INLINE struct pipe_context *
ndpy_get_copy_context(struct native_display *ndpy)
{
if (!ndpy->pipe)
ndpy->pipe = ndpy->screen->context_create(ndpy->screen, NULL);
return ndpy->pipe;
}
/**
* Free display screen and context resources
*/
static INLINE void
ndpy_uninit(struct native_display *ndpy)
{
if (ndpy->pipe)
ndpy->pipe->destroy(ndpy->pipe);
if (ndpy->screen)
ndpy->screen->destroy(ndpy->screen);
}
struct native_platform {
const char *name;

View file

@ -3,6 +3,7 @@
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
* Copyright (C) 2011 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"),
@ -24,6 +25,7 @@
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
#include "util/u_inlines.h"
@ -34,6 +36,14 @@
#include "native_helper.h"
/**
* Number of swap fences and mask
*/
#define EGL_SWAP_FENCES_MAX 4
#define EGL_SWAP_FENCES_MASK 3
#define EGL_SWAP_FENCES_DEFAULT 1
struct resource_surface {
struct pipe_screen *screen;
enum pipe_format format;
@ -42,6 +52,15 @@ struct resource_surface {
struct pipe_resource *resources[NUM_NATIVE_ATTACHMENTS];
uint resource_mask;
uint width, height;
/**
* Swap fences.
*/
struct pipe_fence_handle *swap_fences[EGL_SWAP_FENCES_MAX];
unsigned int cur_fences;
unsigned int head;
unsigned int tail;
unsigned int desired_fences;
};
struct resource_surface *
@ -49,11 +68,16 @@ resource_surface_create(struct pipe_screen *screen,
enum pipe_format format, uint bind)
{
struct resource_surface *rsurf = CALLOC_STRUCT(resource_surface);
char *swap_fences = getenv("EGL_THROTTLE_FENCES");
if (rsurf) {
rsurf->screen = screen;
rsurf->format = format;
rsurf->bind = bind;
rsurf->desired_fences = (swap_fences) ? atoi(swap_fences) :
EGL_SWAP_FENCES_DEFAULT;
if (rsurf->desired_fences > EGL_SWAP_FENCES_MAX)
rsurf->desired_fences = EGL_SWAP_FENCES_MAX;
}
return rsurf;
@ -225,3 +249,121 @@ resource_surface_present(struct resource_surface *rsurf,
return TRUE;
}
/**
* Schedule a copy swap from the back to the front buffer using the
* native display's copy context.
*/
boolean
resource_surface_copy_swap(struct resource_surface *rsurf,
struct native_display *ndpy)
{
struct pipe_resource *ftex;
struct pipe_resource *btex;
struct pipe_context *pipe;
struct pipe_box src_box;
boolean ret = FALSE;
pipe = ndpy_get_copy_context(ndpy);
if (!pipe)
return FALSE;
ftex = resource_surface_get_single_resource(rsurf,
NATIVE_ATTACHMENT_FRONT_LEFT);
if (!ftex)
goto out_no_ftex;
btex = resource_surface_get_single_resource(rsurf,
NATIVE_ATTACHMENT_BACK_LEFT);
if (!btex)
goto out_no_btex;
u_box_origin_2d(ftex->width0, ftex->height0, &src_box);
pipe->resource_copy_region(pipe, ftex, 0, 0, 0, 0,
btex, 0, &src_box);
ret = TRUE;
out_no_ftex:
pipe_resource_reference(&btex, NULL);
out_no_btex:
pipe_resource_reference(&ftex, NULL);
return ret;
}
static struct pipe_fence_handle *
swap_fences_pop_front(struct resource_surface *rsurf)
{
struct pipe_screen *screen = rsurf->screen;
struct pipe_fence_handle *fence = NULL;
if (rsurf->desired_fences == 0)
return NULL;
if (rsurf->cur_fences >= rsurf->desired_fences) {
screen->fence_reference(screen, &fence, rsurf->swap_fences[rsurf->tail]);
screen->fence_reference(screen, &rsurf->swap_fences[rsurf->tail++], NULL);
rsurf->tail &= EGL_SWAP_FENCES_MASK;
--rsurf->cur_fences;
}
return fence;
}
static void
swap_fences_push_back(struct resource_surface *rsurf,
struct pipe_fence_handle *fence)
{
struct pipe_screen *screen = rsurf->screen;
if (!fence || rsurf->desired_fences == 0)
return;
while(rsurf->cur_fences == rsurf->desired_fences)
swap_fences_pop_front(rsurf);
rsurf->cur_fences++;
screen->fence_reference(screen, &rsurf->swap_fences[rsurf->head++],
fence);
rsurf->head &= EGL_SWAP_FENCES_MASK;
}
boolean
resource_surface_throttle(struct resource_surface *rsurf)
{
struct pipe_screen *screen = rsurf->screen;
struct pipe_fence_handle *fence = swap_fences_pop_front(rsurf);
if (fence) {
(void) screen->fence_finish(screen, fence, 0);
screen->fence_reference(screen, &fence, NULL);
return TRUE;
}
return FALSE;
}
boolean
resource_surface_flush(struct resource_surface *rsurf,
struct native_display *ndpy)
{
struct pipe_fence_handle *fence = NULL;
struct pipe_screen *screen = rsurf->screen;
struct pipe_context *pipe= ndpy_get_copy_context(ndpy);
if (!pipe)
return FALSE;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &fence);
if (fence == NULL)
return FALSE;
swap_fences_push_back(rsurf, fence);
screen->fence_reference(screen, &fence, NULL);
return TRUE;
}
void
resource_surface_wait(struct resource_surface *rsurf)
{
while (resource_surface_throttle(rsurf));
}

View file

@ -3,6 +3,7 @@
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
* Copyright (C) 2011 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"),
@ -24,6 +25,7 @@
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
#include "native.h"
@ -74,3 +76,32 @@ boolean
resource_surface_present(struct resource_surface *rsurf,
enum native_attachment which,
void *winsys_drawable_handle);
/**
* Perform a gallium copy blit between the back left and front left
* surfaces. Needs to be followed by a call to resource_surface_flush.
*/
boolean
resource_surface_copy_swap(struct resource_surface *rsurf,
struct native_display *ndpy);
/**
* Throttle on outstanding rendering using the copy context. For example
* copy swaps.
*/
boolean
resource_surface_throttle(struct resource_surface *rsurf);
/**
* Flush pending rendering using the copy context. This function saves a
* marker for upcoming throttles.
*/
boolean
resource_surface_flush(struct resource_surface *rsurf,
struct native_display *ndpy);
/**
* Wait for all rendering using the copy context to be complete. Frees all
* throttle markers saved using resource_surface_flush.
*/
void
resource_surface_wait(struct resource_surface *rsurf);

View file

@ -3,6 +3,7 @@
* Version: 7.9
*
* Copyright (C) 2010 LunarG Inc.
* Copyright (C) 2011 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"),
@ -24,6 +25,7 @@
*
* Authors:
* Chia-I Wu <olv@lunarg.com>
* Thomas Hellstrom <thellstrom@vmware.com>
*/
#include "util/u_memory.h"
@ -130,6 +132,25 @@ drm_surface_flush_frontbuffer(struct native_surface *nsurf)
return TRUE;
}
static boolean
drm_surface_copy_swap(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
struct drm_display *drmdpy = drmsurf->drmdpy;
(void) resource_surface_throttle(drmsurf->rsurf);
if (!resource_surface_copy_swap(drmsurf->rsurf, &drmdpy->base))
return FALSE;
(void) resource_surface_flush(drmsurf->rsurf, &drmdpy->base);
if (!drm_surface_flush_frontbuffer(nsurf))
return FALSE;
drmsurf->sequence_number++;
return TRUE;
}
static boolean
drm_surface_swap_buffers(struct native_surface *nsurf)
{
@ -139,17 +160,21 @@ drm_surface_swap_buffers(struct native_surface *nsurf)
struct drm_framebuffer tmp_fb;
int err;
if (!drmsurf->have_pageflip)
return drm_surface_copy_swap(nsurf);
if (!drmsurf->back_fb.buffer_id) {
if (!drm_surface_init_framebuffers(&drmsurf->base, TRUE))
return FALSE;
}
if (drmsurf->is_shown && drmcrtc->crtc) {
err = drmModeSetCrtc(drmdpy->fd, drmcrtc->crtc->crtc_id,
drmsurf->back_fb.buffer_id, drmcrtc->crtc->x, drmcrtc->crtc->y,
drmcrtc->connectors, drmcrtc->num_connectors, &drmcrtc->crtc->mode);
if (err)
return FALSE;
err = drmModePageFlip(drmdpy->fd, drmcrtc->crtc->crtc_id,
drmsurf->back_fb.buffer_id, 0, NULL);
if (err) {
drmsurf->have_pageflip = FALSE;
return drm_surface_copy_swap(nsurf);
}
}
/* swap the buffers */
@ -175,7 +200,7 @@ drm_surface_present(struct native_surface *nsurf,
{
boolean ret;
if (preserve || swap_interval)
if (swap_interval)
return FALSE;
switch (natt) {
@ -183,7 +208,10 @@ drm_surface_present(struct native_surface *nsurf,
ret = drm_surface_flush_frontbuffer(nsurf);
break;
case NATIVE_ATTACHMENT_BACK_LEFT:
ret = drm_surface_swap_buffers(nsurf);
if (preserve)
ret = drm_surface_copy_swap(nsurf);
else
ret = drm_surface_swap_buffers(nsurf);
break;
default:
ret = FALSE;
@ -196,7 +224,9 @@ drm_surface_present(struct native_surface *nsurf,
static void
drm_surface_wait(struct native_surface *nsurf)
{
/* no-op */
struct drm_surface *drmsurf = drm_surface(nsurf);
resource_surface_wait(drmsurf->rsurf);
}
static void
@ -204,6 +234,7 @@ drm_surface_destroy(struct native_surface *nsurf)
{
struct drm_surface *drmsurf = drm_surface(nsurf);
resource_surface_wait(drmsurf->rsurf);
if (drmsurf->current_crtc.crtc)
drmModeFreeCrtc(drmsurf->current_crtc.crtc);
@ -236,6 +267,7 @@ drm_display_create_surface(struct native_display *ndpy,
drmsurf->color_format = drmconf->base.color_format;
drmsurf->width = width;
drmsurf->height = height;
drmsurf->have_pageflip = TRUE;
drmsurf->rsurf = resource_surface_create(drmdpy->base.screen,
drmsurf->color_format,

View file

@ -124,8 +124,7 @@ drm_display_destroy(struct native_display *ndpy)
drm_display_fini_modeset(&drmdpy->base);
if (drmdpy->base.screen)
drmdpy->base.screen->destroy(drmdpy->base.screen);
ndpy_uninit(ndpy);
if (drmdpy->fd >= 0)
close(drmdpy->fd);

View file

@ -91,6 +91,8 @@ struct drm_surface {
boolean is_shown;
struct drm_crtc current_crtc;
boolean have_pageflip;
};
struct drm_connector {

View file

@ -320,7 +320,7 @@ fbdev_display_destroy(struct native_display *ndpy)
{
struct fbdev_display *fbdpy = fbdev_display(ndpy);
fbdpy->base.screen->destroy(fbdpy->base.screen);
ndpy_uninit(&fbdpy->base);
close(fbdpy->fd);
FREE(fbdpy);
}

View file

@ -363,7 +363,7 @@ gdi_display_destroy(struct native_display *ndpy)
if (gdpy->configs)
FREE(gdpy->configs);
gdpy->base.screen->destroy(gdpy->base.screen);
ndpy_uninit(ndpy);
FREE(gdpy);
}

View file

@ -41,6 +41,7 @@
#include "radeon/drm/radeon_drm_public.h"
#include <wayland-client.h>
#include "wayland-drm-client-protocol.h"
#include "wayland-egl-priv.h"
#include <xf86drm.h>
@ -137,8 +138,7 @@ wayland_display_destroy(struct native_display *ndpy)
if (display->config)
FREE(display->config);
if (display->base.screen)
display->base.screen->destroy(display->base.screen);
ndpy_uninit(ndpy);
FREE(display);
}

View file

@ -476,7 +476,7 @@ ximage_display_destroy(struct native_display *ndpy)
if (xdpy->configs)
FREE(xdpy->configs);
xdpy->base.screen->destroy(xdpy->base.screen);
ndpy_uninit(ndpy);
x11_screen_destroy(xdpy->xscr);
if (xdpy->own_dpy)

View file

@ -63,7 +63,6 @@ i915_drm_batchbuffer_create(struct i915_winsys *iws)
batch->base.size = 0;
batch->base.relocs = 0;
batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
batch->base.iws = iws;
@ -104,8 +103,6 @@ i915_drm_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
unsigned offset;
int ret = 0;
assert(batch->base.relocs < batch->base.max_relocs);
switch (usage) {
case I915_USAGE_SAMPLER:
write_domain = 0;

View file

@ -49,7 +49,6 @@ i915_sw_batchbuffer_create(struct i915_winsys *iws)
batch->base.size = 0;
batch->base.relocs = 0;
batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
batch->base.iws = iws;
@ -75,8 +74,6 @@ i915_sw_batchbuffer_reloc(struct i915_winsys_batchbuffer *ibatch,
struct i915_sw_batchbuffer *batch = i915_sw_batchbuffer(ibatch);
int ret = 0;
assert(batch->base.relocs < batch->base.max_relocs);
if (usage == I915_USAGE_SAMPLER) {
} else if (usage == I915_USAGE_RENDER) {

View file

@ -834,25 +834,25 @@ void evergreen_context_draw(struct r600_context *ctx, const struct r600_draw *dr
}
/* draw packet */
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0);
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type;
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0);
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NUM_INSTANCES, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_instances;
if (draw->indices) {
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3);
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX, 3, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->indices_bo_offset + r600_bo_offset(draw->indices);
ctx->pm4[ctx->pm4_cdwords++] = 0;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0);
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_NOP, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = 0;
r600_context_bo_reloc(ctx, &ctx->pm4[ctx->pm4_cdwords - 1], draw->indices);
} else {
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1);
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_DRAW_INDEX_AUTO, 1, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_num_indices;
ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_draw_initiator;
}
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0);
ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, ctx->predicate_drawing);
ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0);
/* flush color buffer */

Some files were not shown because too many files have changed in this diff Show more