Merge branch 'master' of ../mesa into vulkan

This commit is contained in:
Kristian Høgsberg Kristensen
2015-09-29 17:10:50 -07:00
648 changed files with 46609 additions and 12619 deletions
+2 -1
View File
@@ -42,6 +42,7 @@ LOCAL_CFLAGS += \
-DANDROID_VERSION=0x0$(MESA_ANDROID_MAJOR_VERSION)0$(MESA_ANDROID_MINOR_VERSION)
LOCAL_CFLAGS += \
-D__STDC_LIMIT_MACROS \
-DHAVE___BUILTIN_EXPECT \
-DHAVE___BUILTIN_FFS \
-DHAVE___BUILTIN_FFSLL \
@@ -70,7 +71,7 @@ endif
ifeq ($(MESA_ENABLE_LLVM),true)
LOCAL_CFLAGS += \
-DHAVE_LLVM=0x0305 -DLLVM_VERSION_PATCH=2 \
-DHAVE_LLVM=0x0305 -DMESA_LLVM_VERSION_PATCH=2 \
-D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS \
-D__STDC_LIMIT_MACROS
+46 -13
View File
@@ -74,7 +74,7 @@ LIBDRM_AMDGPU_REQUIRED=2.4.63
LIBDRM_INTEL_REQUIRED=2.4.61
LIBDRM_NVVIEUX_REQUIRED=2.4.33
LIBDRM_NOUVEAU_REQUIRED=2.4.62
LIBDRM_FREEDRENO_REQUIRED=2.4.64
LIBDRM_FREEDRENO_REQUIRED=2.4.65
DRI2PROTO_REQUIRED=2.6
DRI3PROTO_REQUIRED=1.0
PRESENTPROTO_REQUIRED=1.0
@@ -534,15 +534,32 @@ AM_CONDITIONAL(HAVE_COMPAT_SYMLINKS, test "x$HAVE_COMPAT_SYMLINKS" = xyes)
dnl
dnl library names
dnl
dnl Unfortunately we need to do a few things that libtool can't help us with,
dnl so we need some knowledge of shared library filenames:
dnl
dnl LIB_EXT is the extension used when creating symlinks for alternate
dnl filenames for a shared library which will be dynamically loaded
dnl
dnl IMP_LIB_EXT is the extension used when checking for the presence of a
dnl the file for a shared library we wish to link with
dnl
case "$host_os" in
darwin* )
LIB_EXT='dylib' ;;
LIB_EXT='dylib'
IMP_LIB_EXT=$LIB_EXT
;;
cygwin* )
LIB_EXT='dll' ;;
LIB_EXT='dll'
IMP_LIB_EXT='dll.a'
;;
aix* )
LIB_EXT='a' ;;
LIB_EXT='a'
IMP_LIB_EXT=$LIB_EXT
;;
* )
LIB_EXT='so' ;;
LIB_EXT='so'
IMP_LIB_EXT=$LIB_EXT
;;
esac
AC_SUBST([LIB_EXT])
@@ -1111,6 +1128,11 @@ AC_MSG_RESULT([$with_sha1])
AC_SUBST(SHA1_LIBS)
AC_SUBST(SHA1_CFLAGS)
# Enable a define for SHA1
if test "x$with_sha1" != "x"; then
DEFINES="$DEFINES -DHAVE_SHA1"
fi
# Allow user to configure out the shader-cache feature
AC_ARG_ENABLE([shader-cache],
AS_HELP_STRING([--disable-shader-cache], [Disable binary shader cache]),
@@ -1290,6 +1312,16 @@ AC_SUBST(GLX_TLS, ${GLX_USE_TLS})
AS_IF([test "x$GLX_USE_TLS" = xyes -a "x$ax_pthread_ok" = xyes],
[DEFINES="${DEFINES} -DGLX_USE_TLS"])
dnl Read-only text section on x86 hardened platforms
AC_ARG_ENABLE([glx-read-only-text],
[AS_HELP_STRING([--enable-glx-read-only-text],
[Disable writable .text section on x86 (decreases performance) @<:@default=disabled@:>@])],
[enable_glx_read_only_text="$enableval"],
[enable_glx_read_only_text=no])
if test "x$enable_glx_read_only_text" = xyes; then
DEFINES="$DEFINES -DGLX_X86_READONLY_TEXT"
fi
dnl
dnl More DRI setup
dnl
@@ -2058,7 +2090,7 @@ radeon_llvm_check() {
if test "x$enable_gallium_llvm" != "xyes"; then
AC_MSG_ERROR([--enable-gallium-llvm is required when building $1])
fi
llvm_check_version_for "3" "4" "2" $1
llvm_check_version_for "3" "5" "0" $1
if test true && $LLVM_CONFIG --targets-built | grep -iqvw $amdgpu_llvm_target_name ; then
AC_MSG_ERROR([LLVM $amdgpu_llvm_target_name not enabled in your LLVM build.])
fi
@@ -2146,11 +2178,8 @@ if test -n "$with_gallium_drivers"; then
gallium_require_drm "vc4"
gallium_require_drm_loader
case "$host_cpu" in
i?86 | x86_64 | amd64)
USE_VC4_SIMULATOR=yes
;;
esac
PKG_CHECK_MODULES([SIMPENROSE], [simpenrose],
[USE_VC4_SIMULATOR=yes], [USE_VC4_SIMULATOR=no])
;;
*)
AC_MSG_ERROR([Unknown Gallium driver: $driver])
@@ -2170,10 +2199,14 @@ if test "x$MESA_LLVM" != x0; then
LLVM_LIBS="`$LLVM_CONFIG --libs ${LLVM_COMPONENTS}`"
dnl llvm-config may not give the right answer when llvm is a built as a
dnl single shared library, so we must work the library name out for
dnl ourselves.
dnl (See https://llvm.org/bugs/show_bug.cgi?id=6823)
if test "x$enable_llvm_shared_libs" = xyes; then
dnl We can't use $LLVM_VERSION because it has 'svn' stripped out,
LLVM_SO_NAME=LLVM-`$LLVM_CONFIG --version`
AS_IF([test -f "$LLVM_LIBDIR/lib$LLVM_SO_NAME.so"], [llvm_have_one_so=yes])
AS_IF([test -f "$LLVM_LIBDIR/lib$LLVM_SO_NAME.$IMP_LIB_EXT"], [llvm_have_one_so=yes])
if test "x$llvm_have_one_so" = xyes; then
dnl LLVM was built using auto*, so there is only one shared object.
@@ -2181,7 +2214,7 @@ if test "x$MESA_LLVM" != x0; then
else
dnl If LLVM was built with CMake, there will be one shared object per
dnl component.
AS_IF([test ! -f "$LLVM_LIBDIR/libLLVMTarget.so"],
AS_IF([test ! -f "$LLVM_LIBDIR/libLLVMTarget.$IMP_LIB_EXT"],
[AC_MSG_ERROR([Could not find llvm shared libraries:
Please make sure you have built llvm with the --enable-shared option
and that your llvm libraries are installed in $LLVM_LIBDIR
+36 -11
View File
@@ -109,14 +109,14 @@ GL 4.0, GLSL 4.00 --- all DONE: nvc0, radeonsi
- Enhanced per-sample shading DONE (r600)
- Interpolation functions DONE (r600)
- New overload resolution rules DONE
GL_ARB_gpu_shader_fp64 DONE (llvmpipe, softpipe)
GL_ARB_gpu_shader_fp64 DONE (r600, llvmpipe, softpipe)
GL_ARB_sample_shading DONE (i965, nv50, r600)
GL_ARB_shader_subroutine DONE (i965, nv50, r600, llvmpipe, softpipe)
GL_ARB_tessellation_shader DONE ()
GL_ARB_texture_buffer_object_rgb32 DONE (i965, r600, llvmpipe, softpipe)
GL_ARB_texture_cube_map_array DONE (i965, nv50, r600, llvmpipe, softpipe)
GL_ARB_texture_gather DONE (i965, nv50, r600, llvmpipe, softpipe)
GL_ARB_texture_query_lod DONE (i965, nv50, r600)
GL_ARB_texture_query_lod DONE (i965, nv50, r600, softpipe)
GL_ARB_transform_feedback2 DONE (i965, nv50, r600, llvmpipe, softpipe)
GL_ARB_transform_feedback3 DONE (i965, nv50, r600, llvmpipe, softpipe)
@@ -127,7 +127,7 @@ GL 4.1, GLSL 4.10 --- all DONE: nvc0, radeonsi
GL_ARB_get_program_binary DONE (0 binary formats)
GL_ARB_separate_shader_objects DONE (all drivers)
GL_ARB_shader_precision DONE (all drivers that support GLSL 4.10)
GL_ARB_vertex_attrib_64bit DONE (llvmpipe, softpipe)
GL_ARB_vertex_attrib_64bit DONE (r600, llvmpipe, softpipe)
GL_ARB_viewport_array DONE (i965, nv50, r600, llvmpipe)
@@ -164,7 +164,7 @@ GL 4.3, GLSL 4.30:
GL_ARB_program_interface_query DONE (all drivers)
GL_ARB_robust_buffer_access_behavior not started
GL_ARB_shader_image_size DONE (i965)
GL_ARB_shader_storage_buffer_object in progress (Iago Toral, Samuel Iglesias)
GL_ARB_shader_storage_buffer_object DONE (i965)
GL_ARB_stencil_texturing DONE (i965/gen8+, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
GL_ARB_texture_buffer_range DONE (nv50, nvc0, i965, r600, radeonsi, llvmpipe)
GL_ARB_texture_query_levels DONE (all drivers that support GLSL 1.30)
@@ -194,8 +194,8 @@ GL 4.5, GLSL 4.50:
GL_ARB_derivative_control DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_direct_state_access DONE (all drivers)
GL_ARB_get_texture_sub_image DONE (all drivers)
GL_ARB_shader_texture_image_samples not started
GL_ARB_texture_barrier DONE (nv50, nvc0, r600, radeonsi)
GL_ARB_shader_texture_image_samples DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_texture_barrier DONE (i965, nv50, nvc0, r600, radeonsi)
GL_KHR_context_flush_control DONE (all - but needs GLX/EGL extension to be useful)
GL_KHR_robust_buffer_access_behavior not started
GL_KHR_robustness 90% done (the ARB variant)
@@ -212,7 +212,7 @@ GLES3.1, GLSL ES 3.1
GL_ARB_shader_atomic_counters DONE (i965)
GL_ARB_shader_image_load_store DONE (i965)
GL_ARB_shader_image_size DONE (i965)
GL_ARB_shader_storage_buffer_object in progress (Iago Toral, Samuel Iglesias)
GL_ARB_shader_storage_buffer_object DONE (i965)
GL_ARB_shading_language_packing DONE (all drivers)
GL_ARB_separate_shader_objects DONE (all drivers)
GL_ARB_stencil_texturing DONE (i965/gen8+, nv50, nvc0, r600, radeonsi, llvmpipe, softpipe)
@@ -223,10 +223,35 @@ GLES3.1, GLSL ES 3.1
GS5 Packing/bitfield/conversion functions DONE (i965, nvc0, r600, radeonsi)
GL_EXT_shader_integer_mix DONE (all drivers that support GLSL)
Additional functions not covered above:
glMemoryBarrierByRegion
glGetTexLevelParameter[fi]v - needs updates to restrict to GLES enums
glGetBooleani_v - needs updates to restrict to GLES enums
Additional functionality not covered above:
glMemoryBarrierByRegion DONE
glGetTexLevelParameter[fi]v - needs updates DONE
glGetBooleani_v - restrict to GLES enums
gl_HelperInvocation support
GLES3.2, GLSL ES 3.2
GL_EXT_color_buffer_float DONE (all drivers)
GL_KHR_blend_equation_advanced not started
GL_KHR_debug DONE (all drivers)
GL_KHR_robustness 90% done (the ARB variant)
GL_KHR_texture_compression_astc_ldr DONE (i965/gen9+)
GL_OES_copy_image not started (based on GL_ARB_copy_image, which is done for some drivers)
GL_OES_draw_buffers_indexed not started
GL_OES_draw_elements_base_vertex not started (based on GL_ARB_draw_elements_base_vertex, which is done for all drivers)
GL_OES_geometry_shader not started (based on GL_ARB_geometry_shader4, which is done for all drivers)
GL_OES_gpu_shader5 not started (based on parts of GL_ARB_gpu_shader5, which is done for some drivers)
GL_OES_primitive_bounding box not started
GL_OES_sample_shading not started (based on parts of GL_ARB_sample_shading, which is done for some drivers)
GL_OES_sample_variables not started (based on parts of GL_ARB_sample_shading, which is done for some drivers)
GL_OES_shader_image_atomic not started (based on parts of GL_ARB_shader_image_load_store, which is done for some drivers)
GL_OES_shader_io_blocks not started (based on parts of GLSL 1.50, which is done)
GL_OES_shader_multisample_interpolation not started (based on parts of GL_ARB_gpu_shader5, which is done)
GL_OES_tessellation_shader not started (based on GL_ARB_tessellation_shader, which is done for some drivers)
GL_OES_texture_border_clamp not started (based on GL_ARB_texture_border_clamp, which is done)
GL_OES_texture_buffer not started (based on GL_ARB_texture_buffer_object, GL_ARB_texture_buffer_range, and GL_ARB_texture_buffer_object_rgb32 that are all done)
GL_OES_texture_cube_map_array not started (based on GL_ARB_texture_cube_map_array, which is done for all drivers)
GL_OES_texture_stencil8 not started (based on GL_ARB_texture_stencil8, which is done for some drivers)
GL_OES_texture_storage_multisample_2d_array DONE (all drivers that support GL_ARB_texture_multisample)
More info about these features and the work involved can be found at
http://dri.freedesktop.org/wiki/MissingFunctionality
+8 -1
View File
@@ -87,6 +87,13 @@ created in a <code>lib64</code> directory at the top of the Mesa source
tree.</p>
</dd>
<dt><code>--sysconfdir=DIR</code></dt>
<dd><p>This option specifies the directory where the configuration
files will be installed. The default is <code>${prefix}/etc</code>.
Currently there's only one config file provided when dri drivers are
enabled - it's <code>drirc</code>.</p>
</dd>
<dt><code>--enable-static, --disable-shared</code></dt>
<dd><p>By default, Mesa
will build shared libraries. Either of these options will force static
@@ -217,7 +224,7 @@ GLX.
<dt><code>--with-expat=DIR</code>
<dd><p><strong>DEPRECATED</strong>, use <code>PKG_CONFIG_PATH</code> instead.</p>
<p>The DRI-enabled libGL uses expat to
parse the DRI configuration files in <code>/etc/drirc</code> and
parse the DRI configuration files in <code>${sysconfdir}/drirc</code> and
<code>~/.drirc</code>. This option allows a specific expat installation
to be used. For example, <code>--with-expat=/usr/local</code> will
search for expat headers and libraries in <code>/usr/local/include</code>
+1
View File
@@ -153,6 +153,7 @@ See the <a href="xlibdriver.html">Xlib software driver page</a> for details.
<li>no16 - suppress generation of 16-wide fragment shaders. useful for debugging broken shaders</li>
<li>blorp - emit messages about the blorp operations (blits &amp; clears)</li>
<li>nodualobj - suppress generation of dual-object geometry shader code</li>
<li>optimizer - dump shader assembly to files at each optimization pass and iteration that make progress</li>
</ul>
</ul>
+41 -4
View File
@@ -16,25 +16,62 @@
<h1>News</h1>
<h2>August 22 2015</h2>
<h2>September 28, 2015</h2>
<p>
<a href="relnotes/11.0.2.html">Mesa 11.0.2</a> is released.
This is a bug-fix release.
</p>
<h2>September 26, 2015</h2>
<p>
<a href="relnotes/11.0.1.html">Mesa 11.0.1</a> is released.
This is a bug-fix release.
</p>
<h2>September 20, 2015</h2>
<p>
<a href="relnotes/10.6.8.html">Mesa 10.6.8</a> is released.
This is a bug-fix release.
</p>
<h2>September 12, 2015</h2>
<p>
<a href="relnotes/11.0.0.html">Mesa 11.0.0</a> is released. This is a new
development release. See the release notes for more information about
the release.
</p>
<h2>September 10, 2015</h2>
<p>
<a href="relnotes/10.6.7.html">Mesa 10.6.7</a> is released.
This is a bug-fix release.
</p>
<h2>September 4, 2015</h2>
<p>
<a href="relnotes/10.6.6.html">Mesa 10.6.6</a> is released.
This is a bug-fix release.
</p>
<h2>August 22, 2015</h2>
<p>
<a href="relnotes/10.6.5.html">Mesa 10.6.5</a> is released.
This is a bug-fix release.
</p>
<h2>August 11 2015</h2>
<h2>August 11, 2015</h2>
<p>
<a href="relnotes/10.6.4.html">Mesa 10.6.4</a> is released.
This is a bug-fix release.
</p>
<h2>July 26 2015</h2>
<h2>July 26, 2015</h2>
<p>
<a href="relnotes/10.6.3.html">Mesa 10.6.3</a> is released.
This is a bug-fix release.
</p>
<h2>July 11 2015</h2>
<h2>July 11, 2015</h2>
<p>
<a href="relnotes/10.6.2.html">Mesa 10.6.2</a> is released.
This is a bug-fix release.
+6
View File
@@ -21,6 +21,12 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<ul>
<li><a href="relnotes/11.0.2.html">11.0.2 release notes</a>
<li><a href="relnotes/11.0.1.html">11.0.1 release notes</a>
<li><a href="relnotes/10.6.8.html">10.6.8 release notes</a>
<li><a href="relnotes/11.0.0.html">11.0.0 release notes</a>
<li><a href="relnotes/10.6.7.html">10.6.7 release notes</a>
<li><a href="relnotes/10.6.6.html">10.6.6 release notes</a>
<li><a href="relnotes/10.6.5.html">10.6.5 release notes</a>
<li><a href="relnotes/10.6.4.html">10.6.4 release notes</a>
<li><a href="relnotes/10.6.3.html">10.6.3 release notes</a>
+164
View File
@@ -0,0 +1,164 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 10.6.6 Release Notes / September 04, 2015</h1>
<p>
Mesa 10.6.6 is a bug fix release which fixes bugs found since the 10.6.5 release.
</p>
<p>
Mesa 10.6.6 implements the OpenGL 3.3 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 3.3. OpenGL
3.3 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
416517aa9df4791f97d34451a9e4da33c966afcd18c115c5769b92b15b018ef5 mesa-10.6.6.tar.gz
570f2154b7340ff5db61ff103bc6e85165b8958798b78a50fa2df488e98e5778 mesa-10.6.6.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84677">Bug 84677</a> - Triangle disappears with glPolygonMode GL_LINE</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90734">Bug 90734</a> - glBufferSubData is corrupting data when buffer is &gt; 32k</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90748">Bug 90748</a> - [BDW Bisected]dEQP-GLES3.functional.fbo.completeness.renderable.texture.depth.rg_half_float_oes fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90902">Bug 90902</a> - [bsw][regression] dEQP: &quot;Found invalid pixel values&quot;</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90925">Bug 90925</a> - &quot;high fidelity&quot;: Segfault in _mesa_program_resource_find_name</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91254">Bug 91254</a> - (regresion) video using VA-API on Intel slow and freeze system with mesa 10.6 or 10.6.1</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91292">Bug 91292</a> - [BDW+] glVertexAttribDivisor not working in combination with glPolygonMode</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91673">Bug 91673</a> - Segfault when calling glTexSubImage2D on storage texture to bound FBO</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91726">Bug 91726</a> - R600 asserts in tgsi_cmp/make_src_for_op3</li>
</ul>
<h2>Changes</h2>
<p>Chris Wilson (2):</p>
<ul>
<li>i965: Prevent coordinate overflow in intel_emit_linear_blit</li>
<li>i965: Always re-emit the pipeline select during invariant state emission</li>
</ul>
<p>Daniel Scharrer (1):</p>
<ul>
<li>mesa: add missing queries for ARB_direct_state_access</li>
</ul>
<p>Dave Airlie (8):</p>
<ul>
<li>mesa/arb_gpu_shader_fp64: add support for glGetUniformdv</li>
<li>mesa/texgetimage: fix missing stencil check</li>
<li>st/readpixels: fix accel path for skipimages.</li>
<li>texcompress_s3tc/fxt1: fix stride checks (v1.1)</li>
<li>mesa/readpixels: check strides are equal before skipping conversion</li>
<li>mesa: enable texture stencil8 for multisample</li>
<li>r600/sb: update last_cf for finalize if.</li>
<li>r600g: fix calculation for gpr allocation</li>
</ul>
<p>David Heidelberg (1):</p>
<ul>
<li>st/nine: Require gcc &gt;= 4.6</li>
</ul>
<p>Emil Velikov (2):</p>
<ul>
<li>docs: add sha256 checksums for 10.6.5</li>
<li>get-pick-list.sh: Require explicit "10.6" for nominating stable patches</li>
</ul>
<p>Glenn Kennard (4):</p>
<ul>
<li>r600g: Fix assert in tgsi_cmp</li>
<li>r600g/sb: Handle undef in read port tracker</li>
<li>r600g/sb: Don't read junk after EOP</li>
<li>r600g/sb: Don't crash on empty if jump target</li>
</ul>
<p>Ilia Mirkin (5):</p>
<ul>
<li>st/mesa: fix assignments with 4-operand arguments (i.e. BFI)</li>
<li>st/mesa: pass through 4th opcode argument in bitmap/pixel visitors</li>
<li>nv50,nvc0: disable depth bounds test on blit</li>
<li>nv50: fix 2d engine blits for 64- and 128-bit formats</li>
<li>mesa: only copy the requested teximage faces</li>
</ul>
<p>Jason Ekstrand (1):</p>
<ul>
<li>i965/fs: Split VGRFs after lowering pull constants</li>
</ul>
<p>Kenneth Graunke (3):</p>
<ul>
<li>i965: Fix copy propagation type changes.</li>
<li>Revert "i965: Advertise a line width of 40.0 on Cherryview and Skylake."</li>
<li>i965: Momentarily pretend to support ARB_texture_stencil8 for blits.</li>
</ul>
<p>Marek Olšák (3):</p>
<ul>
<li>gallium/radeon: fix the ADDRESS_HI mask for EVENT_WRITE CIK packets</li>
<li>mesa: create multisample fallback textures like normal textures</li>
<li>radeonsi: fix a Unigine Heaven hang when drirc is missing</li>
</ul>
<p>Matt Turner (1):</p>
<ul>
<li>i965/fs: Handle MRF destinations in lower_integer_multiplication().</li>
</ul>
<p>Neil Roberts (2):</p>
<ul>
<li>i965: Swap the order of the vertex ID and edge flag attributes</li>
<li>i965/bdw: Fix 3DSTATE_VF_INSTANCING when the edge flag is used</li>
</ul>
<p>Tapani Pälli (5):</p>
<ul>
<li>mesa: update fbo state in glTexStorage</li>
<li>glsl: build stageref mask using IR, not symbol table</li>
<li>glsl: expose build_program_resource_list function</li>
<li>glsl: create program resource list after LinkShader</li>
<li>mesa: add GL_RED, GL_RG support for floating point textures</li>
</ul>
</div>
</body>
</html>
+75
View File
@@ -0,0 +1,75 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 10.6.7 Release Notes / September 10, 2015</h1>
<p>
Mesa 10.6.7 is a bug fix release which fixes bugs found since the 10.6.6 release.
</p>
<p>
Mesa 10.6.7 implements the OpenGL 3.3 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 3.3. OpenGL
3.3 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
4ba10c59abee30d72476543a57afd2f33803dabf4620dc333b335d47966ff842 mesa-10.6.7.tar.gz
feb1f640b915dada88a7c793dfaff0ae23580f8903f87a6b76469253de0d28d8 mesa-10.6.7.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90751">Bug 90751</a> - [BDW Bisected]dEQP-GLES3.functional.fbo.completeness.renderable.texture.stencil.stencil_index8 fails</li>
</ul>
<h2>Changes</h2>
<p>Dave Airlie (1):</p>
<ul>
<li>mesa/teximage: use correct extension for accept stencil texture.</li>
</ul>
<p>Emil Velikov (3):</p>
<ul>
<li>docs: add sha256 checksums for 10.6.6</li>
<li>Revert "i965: Momentarily pretend to support ARB_texture_stencil8 for blits."</li>
<li>Update version to 10.6.7</li>
</ul>
<p>Kenneth Graunke (1):</p>
<ul>
<li>glsl: Handle attribute aliasing in attribute storage limit check.</li>
</ul>
</div>
</body>
</html>
+136
View File
@@ -0,0 +1,136 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 10.6.8 Release Notes / September 20, 2015</h1>
<p>
Mesa 10.6.8 is a bug fix release which fixes bugs found since the 10.6.7 release.
</p>
<p>
Mesa 10.6.8 implements the OpenGL 3.3 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 3.3. OpenGL
3.3 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
1f34dba2a8059782e3e4e0f18b9628004e253b2c69085f735b846d2e63c9e250 mesa-10.6.8.tar.gz
e36ee5ceeadb3966fb5ce5b4cf18322dbb76a4f075558ae49c3bba94f57d58fd mesa-10.6.8.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90621">Bug 90621</a> - Mesa fail to build from git</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91526">Bug 91526</a> - World of Warcraft (on Wine) has UI corruption with nouveau</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91719">Bug 91719</a> - [SNB,HSW,BYT] dEQP regressions associated with using NIR for vertex shaders</li>
</ul>
<h2>Changes</h2>
<p>Alejandro Piñeiro (1):</p>
<ul>
<li>i965/vec4: fill src_reg type using the constructor type parameter</li>
</ul>
<p>Antia Puentes (1):</p>
<ul>
<li>i965/vec4: Fix saturation errors when coalescing registers</li>
</ul>
<p>Emil Velikov (2):</p>
<ul>
<li>docs: add sha256 checksums for 10.6.7</li>
<li>cherry-ignore: add commit non applicable for 10.6</li>
</ul>
<p>Hans de Goede (4):</p>
<ul>
<li>nv30: Fix creation of scanout buffers</li>
<li>nv30: Implement color resolve for msaa</li>
<li>nv30: Fix max width / height checks in nv30 sifm code</li>
<li>nv30: Disable msaa unless requested from the env by NV30_MAX_MSAA</li>
</ul>
<p>Ian Romanick (2):</p>
<ul>
<li>mesa: Pass the type to _mesa_uniform_matrix as a glsl_base_type</li>
<li>mesa: Don't allow wrong type setters for matrix uniforms</li>
</ul>
<p>Ilia Mirkin (5):</p>
<ul>
<li>st/mesa: don't fall back to 16F when 32F is requested</li>
<li>nvc0: always emit a full shader colormask</li>
<li>nvc0: remove BGRA4 format support</li>
<li>st/mesa: avoid integer overflows with buffers &gt;= 512MB</li>
<li>nv50, nvc0: fix max texture buffer size to 128M elements</li>
</ul>
<p>Jason Ekstrand (1):</p>
<ul>
<li>i965/vec4: Don't reswizzle hardware registers</li>
</ul>
<p>Jose Fonseca (1):</p>
<ul>
<li>gallivm: Workaround LLVM PR23628.</li>
</ul>
<p>Kenneth Graunke (1):</p>
<ul>
<li>i965: Momentarily pretend to support ARB_texture_stencil8 for blits.</li>
</ul>
<p>Oded Gabbay (1):</p>
<ul>
<li>llvmpipe: convert double to long long instead of unsigned long long</li>
</ul>
<p>Ray Strode (1):</p>
<ul>
<li>gbm: convert gbm bo format to fourcc format on dma-buf import</li>
</ul>
<p>Ulrich Weigand (1):</p>
<ul>
<li>mesa: Fix texture compression on big-endian systems</li>
</ul>
<p>Vinson Lee (1):</p>
<ul>
<li>gallivm: Do not use NoFramePointerElim with LLVM 3.7.</li>
</ul>
</div>
</body>
</html>
+167 -4
View File
@@ -14,7 +14,7 @@
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.0.0 Release Notes / TBD</h1>
<h1>Mesa 11.0.0 Release Notes / September 12, 2015</h1>
<p>
Mesa 11.0.0 is a new development release.
@@ -33,7 +33,8 @@ because compatibility contexts are not supported.
<h2>SHA256 checksums</h2>
<pre>
TBD.
7d7e4ddffa3b162506efa01e2cc41e329caa4995336b92e5cc21f2e1fb36c1b3 mesa-11.0.0.tar.gz
e095a3eb2eca9dfde7efca8946527c8ae20a0cc938a8c78debc7f158ad44af32 mesa-11.0.0.tar.xz
</pre>
@@ -83,13 +84,175 @@ Note: some of the new features are only available with certain drivers.
<li>EGL 1.5 on r600, radeonsi, nv50, nvc0</li>
</ul>
<h2>Bug fixes</h2>
TBD.
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=51658">Bug 51658</a> - r200 (&amp; possibly radeon) DRI fixes for gnome shell on Mesa 8.0.3</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=65525">Bug 65525</a> - [llvmpipe] lp_scene.h:210:lp_scene_alloc: Assertion `size &lt;= (64 * 1024)' failed.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66346">Bug 66346</a> - shader_query.cpp:49: error: invalid conversion from 'void*' to 'GLuint'</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=73512">Bug 73512</a> - [clover] mesa.icd. should contain full path</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=73528">Bug 73528</a> - Deferred lighting in Second Life causes system hiccups and screen flickering</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=74329">Bug 74329</a> - Please expose OES_texture_float and OES_texture_half_float on the ES3 context</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80500">Bug 80500</a> - Flickering shadows in unreleased title trace</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82186">Bug 82186</a> - [r600g] BARTS GPU lockup with minecraft shaders</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84225">Bug 84225</a> - Allow constant-index-expression sampler array indexing with GLSL-ES &lt; 300</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84677">Bug 84677</a> - Triangle disappears with glPolygonMode GL_LINE</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=85252">Bug 85252</a> - Segfault in compiler while processing ternary operator with void arguments</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=89131">Bug 89131</a> - [Bisected] Graphical corruption in Weston, shows old framebuffer pieces</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90000">Bug 90000</a> - [i965 Bisected NIR] Piglit/gglean_fragprog1-z-write_test fail</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90073">Bug 90073</a> - Leaks in xcb_dri3_open_reply_fds() and get_render_node_from_id_path_tag</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90249">Bug 90249</a> - Fails to build egl_dri2 on osx</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90310">Bug 90310</a> - Fails to build gallium_dri.so at linking stage with clang because of multiple redefinitions</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90347">Bug 90347</a> - [NVE0+] Failure to insert texbar under some circumstances (causing bad colors in Terasology)</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90466">Bug 90466</a> - arm: linker error ndefined reference to `nir_metadata_preserve'</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90520">Bug 90520</a> - Register spilling clobbers registers used elsewhere in the shader</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90537">Bug 90537</a> - radeonsi bo/va conflict on RADEON_GEM_VA (rscreen-&gt;ws-&gt;buffer_from_handle returns NULL)</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90547">Bug 90547</a> - [BDW/BSW/SKL Bisected]Piglit/glean&#64;vertprog1-rsq_test_2_(reciprocal_square_root_of_negative_value) fais</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90580">Bug 90580</a> - [HSW bisected] integer multiplication bug</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90600">Bug 90600</a> - IOError: [Errno 2] No such file or directory: 'gl_API.xml'</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90621">Bug 90621</a> - Mesa fail to build from git</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90629">Bug 90629</a> - [i965] SIMD16 dual_source_blend assertion `src[i].file != GRF || src[i].width == dst.width' failed</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90691">Bug 90691</a> - [BSW]Piglit/spec/nv_conditional_render/dlist fails intermittently</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90728">Bug 90728</a> - dvd playback with vlc and vdpau causes segmentation fault</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90734">Bug 90734</a> - glBufferSubData is corrupting data when buffer is &gt; 32k</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90748">Bug 90748</a> - [BDW Bisected]dEQP-GLES3.functional.fbo.completeness.renderable.texture.depth.rg_half_float_oes fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90749">Bug 90749</a> - [BDW Bisected]dEQP-GLES3.functional.rasterization.fbo.rbo_multisample_max.primitives.lines_wide fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90751">Bug 90751</a> - [BDW Bisected]dEQP-GLES3.functional.fbo.completeness.renderable.texture.stencil.stencil_index8 fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90797">Bug 90797</a> - [ALL bisected] Mesa change cause performance case manhattan fail.</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90817">Bug 90817</a> - swrast fails to load with certain remote X servers</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90830">Bug 90830</a> - [bsw bisected regression] GPU hang for spec.arb_gpu_shader5.execution.sampler_array_indexing.vs-nonzero-base</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90839">Bug 90839</a> - [10.5.5/10.6 regression, bisected] PBO glDrawPixels no longer using blit fastpath</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90873">Bug 90873</a> - Kernel hang, TearFree On, Mate desktop environment</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90887">Bug 90887</a> - PhiMovesPass in register allocator broken</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90895">Bug 90895</a> - [IVB/HSW/BDW/BSW Bisected] GLB2.7 Egypt, GfxBench3.0 T-Rex &amp; ALU and many SynMark cases performance reduced by 10-23%</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90902">Bug 90902</a> - [bsw][regression] dEQP: &quot;Found invalid pixel values&quot;</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90903">Bug 90903</a> - egl_dri2.c:dri2_load fails to load libglapi on osx</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90904">Bug 90904</a> - OSX: EXC_BAD_ACCESS when using translate_sse + gallium + softpipe/llvmpipe</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90905">Bug 90905</a> - mesa: Finish subdir-objects transition</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90925">Bug 90925</a> - &quot;high fidelity&quot;: Segfault in _mesa_program_resource_find_name</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91022">Bug 91022</a> - [g45 g965 bisected] assertions generated from textureGrad cube samplers fix</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91047">Bug 91047</a> - [SNB Bisected] Messed up Fog in Super Smash Bros. Melee in Dolphin</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91056">Bug 91056</a> - The Bard's Tale (2005, native) has rendering issues</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91077">Bug 91077</a> - dri2_glx.c:1186: undefined reference to `loader_open_device'</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91099">Bug 91099</a> - [llvmpipe] piglit glsl-max-varyings &gt;max_varying_components regression</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91101">Bug 91101</a> - [softpipe] piglit glsl-1.50&#64;execution&#64;geometry&#64;max-input-components regression</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91117">Bug 91117</a> - Nimbus (running in wine) has rendering issues, objects are semi-transparent</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91124">Bug 91124</a> - Civilization V (in Wine) has rendering issues: text missing, menu bar corrupted</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91173">Bug 91173</a> - Oddworld: Stranger's Wrath HD: disfigured models in wrong colors</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91193">Bug 91193</a> - [290x] Dota2 reborn ingame rendering breaks with git-af4b9c7</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91222">Bug 91222</a> - lp_test_format regression on CentOS 7</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91226">Bug 91226</a> - Crash in glLinkProgram (NEW)</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91231">Bug 91231</a> - [NV92] Psychonauts (native) segfaults on start when DRI3 enabled</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91254">Bug 91254</a> - (regresion) video using VA-API on Intel slow and freeze system with mesa 10.6 or 10.6.1</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91290">Bug 91290</a> - SIGSEGV glcpp/glcpp-parse.y:1077</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91292">Bug 91292</a> - [BDW+] glVertexAttribDivisor not working in combination with glPolygonMode</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91337">Bug 91337</a> - OSMesaGetProcAdress(&quot;OSMesaPixelStore&quot;) returns nil</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91418">Bug 91418</a> - Visual Studio 2015 vsnprintf build error</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91425">Bug 91425</a> - [regression, bisected] Piglit spec/ext_packed_float/ getteximage-invalid-format-for-packed-type fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91441">Bug 91441</a> - make check DispatchSanity_test.GL30 regression</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91444">Bug 91444</a> - regression bisected radeonsi: don't change pipe_resource in resource_copy_region</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91461">Bug 91461</a> - gl_TessLevel* writes have no effect for all but the last TCS invocation</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91513">Bug 91513</a> - [IVB/HSW/BDW/SKL Bisected] Lightsmark performance reduced by 7%-10%</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91526">Bug 91526</a> - World of Warcraft (on Wine) has UI corruption with nouveau</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91544">Bug 91544</a> - [i965, regression, bisected] regression of several tests in 93977d3a151675946c03e</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91551">Bug 91551</a> - DXTn compressed normal maps produce severe artifacts on all NV5x and NVDx chipsets</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91570">Bug 91570</a> - Upgrading mesa to 10.6 causes segfault in OpenGL applications with GeForce4 MX 440 / AGP 8X</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91591">Bug 91591</a> - rounding.h:102:2: error: #error &quot;Unsupported or undefined LONG_BIT&quot;</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91610">Bug 91610</a> - [BSW] GPU hang for spec.shaders.point-vertex-id gl_instanceid divisor</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91673">Bug 91673</a> - Segfault when calling glTexSubImage2D on storage texture to bound FBO</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91726">Bug 91726</a> - R600 asserts in tgsi_cmp/make_src_for_op3</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91847">Bug 91847</a> - glGenerateTextureMipmap not working (no errors) unless glActiveTexture(GL_TEXTURE1) is called before</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91857">Bug 91857</a> - Mesa 10.6.3 linker is slow</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91881">Bug 91881</a> - regression: GPU lockups since mesa-11.0.0_rc1 on RV620 (r600) driver</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91890">Bug 91890</a> - [nve7] witcher2: blurry image &amp; DATA_ERRORs (class 0xa097 mthd 0x2380/0x238c)</li>
</ul>
<h2>Changes</h2>
TBD.
<li>Removed the EGL loader from the Linux SCons build.</li>
</div>
</body>
+134
View File
@@ -0,0 +1,134 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.0.1 Release Notes / September 26, 2015</h1>
<p>
Mesa 11.0.1 is a bug fix release which fixes bugs found since the 11.0.0 release.
</p>
<p>
Mesa 11.0.1 implements the OpenGL 4.1 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
4.1 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
6dab262877e12c0546a0e2970c6835a0f217e6d4026ccecb3cd5dd733d1ce867 mesa-11.0.1.tar.gz
43d0dfcd1f1e36f07f8228cd76d90175d3fc74c1ed25d7071794a100a98ef2a6 mesa-11.0.1.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=38109">Bug 38109</a> - i915 driver crashes if too few vertices are submitted (Mesa 7.10.2)</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91114">Bug 91114</a> - ES3-CTS.gtf.GL3Tests.shadow.shadow_execution_vert fails</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91716">Bug 91716</a> - [bisected] piglit.shaders.glsl-vs-int-attrib regresses on 32 bit BYT, HSW, IVB, SNB</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91719">Bug 91719</a> - [SNB,HSW,BYT] dEQP regressions associated with using NIR for vertex shaders</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92009">Bug 92009</a> - ES3-CTS.gtf.GL3Tests.packed_pixels.packed_pixels fails</li>
</ul>
<h2>Changes</h2>
<p>Antia Puentes (2):</p>
<ul>
<li>i965/vec4: Fix saturation errors when coalescing registers</li>
<li>i965/vec4_nir: Load constants as integers</li>
</ul>
<p>Anuj Phogat (1):</p>
<ul>
<li>meta: Abort meta pbo path if TexSubImage need signed unsigned conversion</li>
</ul>
<p>Emil Velikov (2):</p>
<ul>
<li>docs: add sha256 checksums for 11.0.0</li>
<li>Update version to 11.0.1</li>
</ul>
<p>Iago Toral Quiroga (1):</p>
<ul>
<li>mesa: Fix GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for default framebuffer.</li>
</ul>
<p>Ian Romanick (5):</p>
<ul>
<li>t_dd_dmatmp: Make "count" actually be the count</li>
<li>t_dd_dmatmp: Clean up improper code formatting from previous patch</li>
<li>t_dd_dmatmp: Use '&amp; 3' instead of '% 4' everywhere</li>
<li>t_dd_dmatmp: Pull out common 'count -= count &amp; 3' code</li>
<li>t_dd_dmatmp: Use addition instead of subtraction in loop bounds</li>
</ul>
<p>Ilia Mirkin (6):</p>
<ul>
<li>st/mesa: avoid integer overflows with buffers &gt;= 512MB</li>
<li>nv50, nvc0: fix max texture buffer size to 128M elements</li>
<li>freedreno/a3xx: fix blending of L8 format</li>
<li>nv50,nvc0: detect underlying resource changes and update tic</li>
<li>nv50,nvc0: flush texture cache in presence of coherent bufs</li>
<li>radeonsi: load fmask ptr relative to the resources array</li>
</ul>
<p>Jason Ekstrand (2):</p>
<ul>
<li>nir: Fix a bunch of ralloc parenting errors</li>
<li>i965/vec4: Don't reswizzle hardware registers</li>
</ul>
<p>Jeremy Huddleston (1):</p>
<ul>
<li>configure.ac: Add support to enable read-only text segment on x86.</li>
</ul>
<p>Ray Strode (1):</p>
<ul>
<li>gbm: convert gbm bo format to fourcc format on dma-buf import</li>
</ul>
<p>Tapani Pälli (2):</p>
<ul>
<li>mesa: fix errors when reading depth with glReadPixels</li>
<li>i965: fix textureGrad for cubemaps</li>
</ul>
<p>Ulrich Weigand (1):</p>
<ul>
<li>mesa: Fix texture compression on big-endian systems</li>
</ul>
</div>
</body>
</html>
+85
View File
@@ -0,0 +1,85 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.0.2 Release Notes / September 28, 2015</h1>
<p>
Mesa 11.0.2 is a bug fix release which fixes bugs found since the 11.0.1 release.
</p>
<p>
Mesa 11.0.2 implements the OpenGL 4.1 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
4.1 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
45170773500d6ae2f9eb93fc85efee69f7c97084411ada4eddf92f78bca56d20 mesa-11.0.2.tar.gz
fce11fb27eb87adf1e620a76455d635c6136dfa49ae58c53b34ef8d0c7b7eae4 mesa-11.0.2.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91582">Bug 91582</a> - [bisected] Regression in DEQP gles2.functional.negative_api.texture.texsubimage2d_neg_offset</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91970">Bug 91970</a> - [BSW regression] dEQP-GLES3.functional.shaders.precision.int.highp_mul_vertex</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92095">Bug 92095</a> - [Regression, bisected] arb_shader_atomic_counters.compiler.builtins.frag</li>
</ul>
<h2>Changes</h2>
<p>Eduardo Lima Mitev (3):</p>
<ul>
<li>mesa: Fix order of format+type and internal format checks for glTexImageXD ops</li>
<li>mesa: Move _mesa_base_tex_format() from teximage to glformats files</li>
<li>mesa: Use the effective internal format instead for validation</li>
</ul>
<p>Emil Velikov (2):</p>
<ul>
<li>docs: add sha256 checksums for 11.0.1</li>
<li>Update version to 11.0.2</li>
</ul>
<p>Kristian Høgsberg Kristensen (1):</p>
<ul>
<li>i965: Respect stride and subreg_offset for ATTR registers</li>
</ul>
<p>Matt Turner (1):</p>
<ul>
<li>glsl: Expose gl_MaxTess{Control,Evaluation}AtomicCounters.</li>
</ul>
</div>
</body>
</html>
+6 -1
View File
@@ -44,7 +44,12 @@ Note: some of the new features are only available with certain drivers.
</p>
<ul>
TBD.
<li>GL_ARB_blend_func_extended on freedreno (a3xx)</li>
<li>GL_ARB_shader_storage_buffer_object on i965</li>
<li>GL_ARB_shader_texture_image_samples on i965, nv50, nvc0, r600, radeonsi</li>
<li>GL_ARB_texture_barrier / GL_NV_texture_barrier on i965</li>
<li>GL_ARB_texture_query_lod on softpipe</li>
<li>GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips</li>
</ul>
<h2>Bug fixes</h2>
+14
View File
@@ -63,6 +63,20 @@ execution. These are generally used for debugging.
Example: export MESA_GLSL=dump,nopt
</p>
<p>
Shaders can be dumped and replaced on runtime for debugging purposes. Mesa
needs to be configured with '--with-sha1' to enable this functionality. This
feature is not currently supported by SCons build.
This is controlled via following environment variables:
<ul>
<li><b>MESA_SHADER_DUMP_PATH</b> - path where shader sources are dumped
<li><b>MESA_SHADER_READ_PATH</b> - path where replacement shaders are read
</ul>
Note, path set must exist before running for dumping or replacing to work.
When both are set, these paths should be different so the dumped shaders do
not clobber the replacement shaders.
</p>
<h2 id="support">GLSL Version</h2>
+35
View File
@@ -26,6 +26,31 @@ VMware Workstation running on Linux or Windows and VMware Fusion running on
MacOS are all supported.
</p>
<p>
With the August 2015 Workstation 12 / Fusion 8 releases, OpenGL 3.3
is supported in the guest.
This requires:
<ul>
<li>The VM is configured for virtual hardware version 12.
<li>The host OS, GPU and graphics driver supports DX11 (Windows) or
OpenGL 4.0 (Linux, Mac)
<li>On Linux, the vmwgfx kernel module must be version 2.9.0 or later.
<li>A recent version of Mesa with the updated svga gallium driver.
</ul>
</p>
<p>
Otherwise, OpenGL 2.1 is supported.
</p>
<p>
OpenGL 3.3 support can be disabled by setting the environment variable
SVGA_VGPU10=0.
You will then have OpenGL 2.1 support.
This may be useful to work around application bugs (such as incorrect use
of the OpenGL 3.x core profile).
</p>
<p>
Most modern Linux distros include the SVGA3D driver so end users shouldn't
be concerned with this information.
@@ -227,6 +252,16 @@ If you don't see this, try setting this environment variable:
then rerun glxinfo and examine the output for error messages.
</p>
<p>
If OpenGL 3.3 is not working (you only get OpenGL 2.1):
</p>
<ul>
<li>Make sure the VM uses hardware version 12.
<li>Make sure the vmwgfx kernel module is version 2.9.0 or later.
<li>Check the vmware.log file for errors.
<li>Run 'dmesg | grep vmwgfx' and look for "DX: yes".
</div>
</body>
</html>
+23 -25
View File
@@ -102,9 +102,8 @@ call_once(once_flag *flag, void (*func)(void))
static inline int
cnd_broadcast(cnd_t *cond)
{
if (!cond) return thrd_error;
pthread_cond_broadcast(cond);
return thrd_success;
assert(cond != NULL);
return (pthread_cond_broadcast(cond) == 0) ? thrd_success : thrd_error;
}
// 7.25.3.2
@@ -119,18 +118,16 @@ cnd_destroy(cnd_t *cond)
static inline int
cnd_init(cnd_t *cond)
{
if (!cond) return thrd_error;
pthread_cond_init(cond, NULL);
return thrd_success;
assert(cond != NULL);
return (pthread_cond_init(cond, NULL) == 0) ? thrd_success : thrd_error;
}
// 7.25.3.4
static inline int
cnd_signal(cnd_t *cond)
{
if (!cond) return thrd_error;
pthread_cond_signal(cond);
return thrd_success;
assert(cond != NULL);
return (pthread_cond_signal(cond) == 0) ? thrd_success : thrd_error;
}
// 7.25.3.5
@@ -139,7 +136,8 @@ cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt)
{
struct timespec abs_time;
int rt;
if (!cond || !mtx || !xt) return thrd_error;
assert(mtx != NULL);
assert(cond != NULL);
rt = pthread_cond_timedwait(cond, mtx, &abs_time);
if (rt == ETIMEDOUT)
return thrd_busy;
@@ -150,9 +148,9 @@ cnd_timedwait(cnd_t *cond, mtx_t *mtx, const xtime *xt)
static inline int
cnd_wait(cnd_t *cond, mtx_t *mtx)
{
if (!cond || !mtx) return thrd_error;
pthread_cond_wait(cond, mtx);
return thrd_success;
assert(mtx != NULL);
assert(cond != NULL);
return (pthread_cond_wait(cond, mtx) == 0) ? thrd_success : thrd_error;
}
@@ -161,7 +159,7 @@ cnd_wait(cnd_t *cond, mtx_t *mtx)
static inline void
mtx_destroy(mtx_t *mtx)
{
assert(mtx);
assert(mtx != NULL);
pthread_mutex_destroy(mtx);
}
@@ -170,7 +168,7 @@ static inline int
mtx_init(mtx_t *mtx, int type)
{
pthread_mutexattr_t attr;
if (!mtx) return thrd_error;
assert(mtx != NULL);
if (type != mtx_plain && type != mtx_timed && type != mtx_try
&& type != (mtx_plain|mtx_recursive)
&& type != (mtx_timed|mtx_recursive)
@@ -188,9 +186,8 @@ mtx_init(mtx_t *mtx, int type)
static inline int
mtx_lock(mtx_t *mtx)
{
if (!mtx) return thrd_error;
pthread_mutex_lock(mtx);
return thrd_success;
assert(mtx != NULL);
return (pthread_mutex_lock(mtx) == 0) ? thrd_success : thrd_error;
}
static inline int
@@ -203,7 +200,9 @@ thrd_yield(void);
static inline int
mtx_timedlock(mtx_t *mtx, const xtime *xt)
{
if (!mtx || !xt) return thrd_error;
assert(mtx != NULL);
assert(xt != NULL);
{
#ifdef EMULATED_THREADS_USE_NATIVE_TIMEDLOCK
struct timespec ts;
@@ -233,7 +232,7 @@ mtx_timedlock(mtx_t *mtx, const xtime *xt)
static inline int
mtx_trylock(mtx_t *mtx)
{
if (!mtx) return thrd_error;
assert(mtx != NULL);
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
}
@@ -241,9 +240,8 @@ mtx_trylock(mtx_t *mtx)
static inline int
mtx_unlock(mtx_t *mtx)
{
if (!mtx) return thrd_error;
pthread_mutex_unlock(mtx);
return thrd_success;
assert(mtx != NULL);
return (pthread_mutex_unlock(mtx) == 0) ? thrd_success : thrd_error;
}
@@ -253,7 +251,7 @@ static inline int
thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
{
struct impl_thrd_param *pack;
if (!thr) return thrd_error;
assert(thr != NULL);
pack = (struct impl_thrd_param *)malloc(sizeof(struct impl_thrd_param));
if (!pack) return thrd_nomem;
pack->func = func;
@@ -329,7 +327,7 @@ thrd_yield(void)
static inline int
tss_create(tss_t *key, tss_dtor_t dtor)
{
if (!key) return thrd_error;
assert(key != NULL);
return (pthread_key_create(key, dtor) == 0) ? thrd_success : thrd_error;
}
+1
View File
@@ -66,6 +66,7 @@ AM_CPPFLAGS = \
noinst_LTLIBRARIES = libglsl_util.la
libglsl_util_la_SOURCES = \
glsl/shader_enums.c \
mesa/main/imports.c \
mesa/program/prog_hash_table.c \
mesa/program/symbol_table.c \
+1
View File
@@ -8,6 +8,7 @@ env = env.Clone()
env.Append(CPPPATH = [
'#/include',
'#/include/HaikuGL',
'#/src/egl/main',
'#/src',
])
+84 -44
View File
@@ -27,6 +27,7 @@
#define WL_HIDE_DEPRECATED
#include <stdbool.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
@@ -588,7 +589,8 @@ dri2_setup_screen(_EGLDisplay *disp)
__DRI2_RENDERER_HAS_FRAMEBUFFER_SRGB))
disp->Extensions.KHR_gl_colorspace = EGL_TRUE;
if (dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) {
if ((dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) ||
(dri2_dpy->swrast && dri2_dpy->swrast->base.version >= 3)) {
disp->Extensions.KHR_create_context = EGL_TRUE;
if (dri2_dpy->robustness)
@@ -784,7 +786,7 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp)
if (dri2_dpy->own_dri_screen)
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
if (dri2_dpy->fd)
if (dri2_dpy->fd >= 0)
close(dri2_dpy->fd);
if (dri2_dpy->driver)
dlclose(dri2_dpy->driver);
@@ -902,6 +904,55 @@ dri2_create_context_attribs_error(int dri_error)
_eglError(egl_error, "dri2_create_context");
}
static bool
dri2_fill_context_attribs(struct dri2_egl_context *dri2_ctx,
struct dri2_egl_display *dri2_dpy,
uint32_t *ctx_attribs,
unsigned *num_attribs)
{
int pos = 0;
assert(*num_attribs >= 8);
ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
ctx_attribs[pos++] = dri2_ctx->base.ClientMajorVersion;
ctx_attribs[pos++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
ctx_attribs[pos++] = dri2_ctx->base.ClientMinorVersion;
if (dri2_ctx->base.Flags != 0) {
/* If the implementation doesn't support the __DRI2_ROBUSTNESS
* extension, don't even try to send it the robust-access flag.
* It may explode. Instead, generate the required EGL error here.
*/
if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0
&& !dri2_dpy->robustness) {
_eglError(EGL_BAD_MATCH, "eglCreateContext");
return false;
}
ctx_attribs[pos++] = __DRI_CTX_ATTRIB_FLAGS;
ctx_attribs[pos++] = dri2_ctx->base.Flags;
}
if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) {
/* If the implementation doesn't support the __DRI2_ROBUSTNESS
* extension, don't even try to send it a reset strategy. It may
* explode. Instead, generate the required EGL error here.
*/
if (!dri2_dpy->robustness) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return false;
}
ctx_attribs[pos++] = __DRI_CTX_ATTRIB_RESET_STRATEGY;
ctx_attribs[pos++] = __DRI_CTX_RESET_LOSE_CONTEXT;
}
*num_attribs = pos;
return true;
}
/**
* Called via eglCreateContext(), drv->API.CreateContext().
*/
@@ -987,44 +1038,12 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
if (dri2_dpy->dri2) {
if (dri2_dpy->dri2->base.version >= 3) {
unsigned error;
unsigned num_attribs = 0;
unsigned num_attribs = 8;
uint32_t ctx_attribs[8];
ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMajorVersion;
ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION;
ctx_attribs[num_attribs++] = dri2_ctx->base.ClientMinorVersion;
if (dri2_ctx->base.Flags != 0) {
/* If the implementation doesn't support the __DRI2_ROBUSTNESS
* extension, don't even try to send it the robust-access flag.
* It may explode. Instead, generate the required EGL error here.
*/
if ((dri2_ctx->base.Flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0
&& !dri2_dpy->robustness) {
_eglError(EGL_BAD_MATCH, "eglCreateContext");
goto cleanup;
}
ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_FLAGS;
ctx_attribs[num_attribs++] = dri2_ctx->base.Flags;
}
if (dri2_ctx->base.ResetNotificationStrategy != EGL_NO_RESET_NOTIFICATION_KHR) {
/* If the implementation doesn't support the __DRI2_ROBUSTNESS
* extension, don't even try to send it a reset strategy. It may
* explode. Instead, generate the required EGL error here.
*/
if (!dri2_dpy->robustness) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
goto cleanup;
}
ctx_attribs[num_attribs++] = __DRI_CTX_ATTRIB_RESET_STRATEGY;
ctx_attribs[num_attribs++] = __DRI_CTX_RESET_LOSE_CONTEXT;
}
assert(num_attribs <= ARRAY_SIZE(ctx_attribs));
if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs,
&num_attribs))
goto cleanup;
dri2_ctx->dri_context =
dri2_dpy->dri2->createContextAttribs(dri2_dpy->dri_screen,
@@ -1046,12 +1065,33 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
}
} else {
assert(dri2_dpy->swrast);
dri2_ctx->dri_context =
dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen,
api,
dri_config,
shared,
dri2_ctx);
if (dri2_dpy->swrast->base.version >= 3) {
unsigned error;
unsigned num_attribs = 8;
uint32_t ctx_attribs[8];
if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs,
&num_attribs))
goto cleanup;
dri2_ctx->dri_context =
dri2_dpy->swrast->createContextAttribs(dri2_dpy->dri_screen,
api,
dri_config,
shared,
num_attribs / 2,
ctx_attribs,
& error,
dri2_ctx);
dri2_create_context_attribs_error(error);
} else {
dri2_ctx->dri_context =
dri2_dpy->swrast->createNewContextForAPI(dri2_dpy->dri_screen,
api,
dri_config,
shared,
dri2_ctx);
}
}
if (!dri2_ctx->dri_context)
+16 -17
View File
@@ -623,27 +623,19 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->own_device = 1;
gbm = gbm_create_device(fd);
if (gbm == NULL)
return EGL_FALSE;
goto cleanup;
} else {
fd = fcntl(gbm_device_get_fd(gbm), F_DUPFD_CLOEXEC, 3);
if (fd < 0)
goto cleanup;
}
if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0) {
free(dri2_dpy);
return EGL_FALSE;
}
if (strcmp(gbm_device_get_backend_name(gbm), "drm") != 0)
goto cleanup;
dri2_dpy->gbm_dri = gbm_dri_device(gbm);
if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI) {
free(dri2_dpy);
return EGL_FALSE;
}
if (fd < 0) {
fd = fcntl(gbm_device_get_fd(gbm), F_DUPFD_CLOEXEC, 3);
if (fd < 0) {
free(dri2_dpy);
return EGL_FALSE;
}
}
if (dri2_dpy->gbm_dri->base.type != GBM_DRM_DRIVER_TYPE_DRI)
goto cleanup;
dri2_dpy->fd = fd;
dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
@@ -727,4 +719,11 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
dri2_dpy->vtbl = &dri2_drm_display_vtbl;
return EGL_TRUE;
cleanup:
if (fd >= 0)
close(fd);
free(dri2_dpy);
return EGL_FALSE;
}
+1
View File
@@ -1804,6 +1804,7 @@ dri2_initialize_wayland_swrast(_EGLDriver *drv, _EGLDisplay *disp)
if (roundtrip(dri2_dpy) < 0 || dri2_dpy->formats == 0)
goto cleanup_shm;
dri2_dpy->fd = -1;
dri2_dpy->driver_name = strdup("swrast");
if (!dri2_load_driver_swrast(disp))
goto cleanup_shm;
+1
View File
@@ -1161,6 +1161,7 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
* Every hardware driver_name is set using strdup. Doing the same in
* here will allow is to simply free the memory at dri2_terminate().
*/
dri2_dpy->fd = -1;
dri2_dpy->driver_name = strdup("swrast");
if (!dri2_load_driver_swrast(disp))
goto cleanup_conn;
+1 -1
View File
@@ -197,7 +197,7 @@ drm_authenticate(struct wl_client *client,
wl_resource_post_event(resource, WL_DRM_AUTHENTICATED);
}
const static struct wl_drm_interface drm_interface = {
static const struct wl_drm_interface drm_interface = {
drm_authenticate,
drm_create_buffer,
drm_create_planar_buffer,
+29
View File
@@ -1,3 +1,32 @@
/*
* Copyright © 2011 Kristian Høgsberg
* Copyright © 2011 Benjamin Franzke
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and 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 <stdlib.h>
#include <wayland-client.h>
+14 -9
View File
@@ -38,18 +38,23 @@ libgallium_la_SOURCES += \
endif
indices/u_indices_gen.c: $(srcdir)/indices/u_indices_gen.py
$(AM_V_at)$(MKDIR_P) indices
$(AM_V_GEN) $(PYTHON2) $< > $@
MKDIR_GEN = $(AM_V_at)$(MKDIR_P) $(@D)
PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS)
indices/u_unfilled_gen.c: $(srcdir)/indices/u_unfilled_gen.py
$(AM_V_at)$(MKDIR_P) indices
$(AM_V_GEN) $(PYTHON2) $< > $@
indices/u_indices_gen.c: indices/u_indices_gen.py
$(MKDIR_GEN)
$(PYTHON_GEN) $(srcdir)/indices/u_indices_gen.py > $@
util/u_format_table.c: $(srcdir)/util/u_format_table.py $(srcdir)/util/u_format_pack.py $(srcdir)/util/u_format_parse.py $(srcdir)/util/u_format.csv
$(AM_V_at)$(MKDIR_P) util
$(AM_V_GEN) $(PYTHON2) $(srcdir)/util/u_format_table.py $(srcdir)/util/u_format.csv > $@
indices/u_unfilled_gen.c: indices/u_unfilled_gen.py
$(MKDIR_GEN)
$(PYTHON_GEN) $(srcdir)/indices/u_unfilled_gen.py > $@
util/u_format_table.c: util/u_format_table.py \
util/u_format_pack.py \
util/u_format_parse.py \
util/u_format.csv
$(MKDIR_GEN)
$(PYTHON_GEN) $(srcdir)/util/u_format_table.py $(srcdir)/util/u_format.csv > $@
noinst_LTLIBRARIES += libgalliumvl_stub.la
libgalliumvl_stub_la_SOURCES = \
+8
View File
@@ -129,6 +129,8 @@ C_SOURCES := \
rtasm/rtasm_execmem.h \
rtasm/rtasm_x86sse.c \
rtasm/rtasm_x86sse.h \
tgsi/tgsi_aa_point.c \
tgsi/tgsi_aa_point.h \
tgsi/tgsi_build.c \
tgsi/tgsi_build.h \
tgsi/tgsi_dump.c \
@@ -144,6 +146,8 @@ C_SOURCES := \
tgsi/tgsi_opcode_tmp.h \
tgsi/tgsi_parse.c \
tgsi/tgsi_parse.h \
tgsi/tgsi_point_sprite.c \
tgsi/tgsi_point_sprite.h \
tgsi/tgsi_sanity.c \
tgsi/tgsi_sanity.h \
tgsi/tgsi_scan.c \
@@ -154,6 +158,8 @@ C_SOURCES := \
tgsi/tgsi_text.h \
tgsi/tgsi_transform.c \
tgsi/tgsi_transform.h \
tgsi/tgsi_two_side.c \
tgsi/tgsi_two_side.h \
tgsi/tgsi_ureg.c \
tgsi/tgsi_ureg.h \
tgsi/tgsi_util.c \
@@ -260,6 +266,8 @@ C_SOURCES := \
util/u_pack_color.h \
util/u_pointer.h \
util/u_prim.h \
util/u_prim_restart.c \
util/u_prim_restart.h \
util/u_pstipple.c \
util/u_pstipple.h \
util/u_range.h \
@@ -240,7 +240,8 @@ aa_transform_prolog(struct tgsi_transform_context *ctx)
TGSI_FILE_INPUT, texInput, TGSI_SWIZZLE_W);
/* KILL_IF -tmp0.yyyy; # if -tmp0.y < 0, KILL */
tgsi_transform_kill_inst(ctx, TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y);
tgsi_transform_kill_inst(ctx, TGSI_FILE_TEMPORARY, tmp0,
TGSI_SWIZZLE_Y, TRUE);
/* compute coverage factor = (1-d)/(1-k) */
@@ -280,7 +280,8 @@ pstip_transform_prolog(struct tgsi_transform_context *ctx)
/* KILL_IF -texTemp.wwww; # if -texTemp < 0, KILL fragment */
tgsi_transform_kill_inst(ctx,
TGSI_FILE_TEMPORARY, pctx->texTemp, TGSI_SWIZZLE_W);
TGSI_FILE_TEMPORARY, pctx->texTemp,
TGSI_SWIZZLE_W, TRUE);
}
+1 -1
View File
@@ -311,7 +311,7 @@ lp_build_const_elem(struct gallivm_state *gallivm,
else {
double dscale = lp_const_scale(type);
elem = LLVMConstInt(elem_type, round(val*dscale), 0);
elem = LLVMConstInt(elem_type, (long long) round(val*dscale), 0);
}
return elem;
+172 -21
View File
@@ -94,6 +94,128 @@ struct ttn_compile {
#define ttn_channel(b, src, swiz) \
nir_swizzle(b, src, SWIZ(swiz, swiz, swiz, swiz), 1, false)
static gl_varying_slot
tgsi_varying_semantic_to_slot(unsigned semantic, unsigned index)
{
switch (semantic) {
case TGSI_SEMANTIC_POSITION:
return VARYING_SLOT_POS;
case TGSI_SEMANTIC_COLOR:
if (index == 0)
return VARYING_SLOT_COL0;
else
return VARYING_SLOT_COL1;
case TGSI_SEMANTIC_BCOLOR:
if (index == 0)
return VARYING_SLOT_BFC0;
else
return VARYING_SLOT_BFC1;
case TGSI_SEMANTIC_FOG:
return VARYING_SLOT_FOGC;
case TGSI_SEMANTIC_PSIZE:
return VARYING_SLOT_PSIZ;
case TGSI_SEMANTIC_GENERIC:
return VARYING_SLOT_VAR0 + index;
case TGSI_SEMANTIC_FACE:
return VARYING_SLOT_FACE;
case TGSI_SEMANTIC_EDGEFLAG:
return VARYING_SLOT_EDGE;
case TGSI_SEMANTIC_PRIMID:
return VARYING_SLOT_PRIMITIVE_ID;
case TGSI_SEMANTIC_CLIPDIST:
if (index == 0)
return VARYING_SLOT_CLIP_DIST0;
else
return VARYING_SLOT_CLIP_DIST1;
case TGSI_SEMANTIC_CLIPVERTEX:
return VARYING_SLOT_CLIP_VERTEX;
case TGSI_SEMANTIC_TEXCOORD:
return VARYING_SLOT_TEX0 + index;
case TGSI_SEMANTIC_PCOORD:
return VARYING_SLOT_PNTC;
case TGSI_SEMANTIC_VIEWPORT_INDEX:
return VARYING_SLOT_VIEWPORT;
case TGSI_SEMANTIC_LAYER:
return VARYING_SLOT_LAYER;
default:
fprintf(stderr, "Bad TGSI semantic: %d/%d\n", semantic, index);
abort();
}
}
/* Temporary helper to remap back to TGSI style semantic name/index
* values, for use in drivers that haven't been converted to using
* VARYING_SLOT_
*/
void
varying_slot_to_tgsi_semantic(gl_varying_slot slot,
unsigned *semantic_name, unsigned *semantic_index)
{
static const unsigned map[][2] = {
[VARYING_SLOT_POS] = { TGSI_SEMANTIC_POSITION, 0 },
[VARYING_SLOT_COL0] = { TGSI_SEMANTIC_COLOR, 0 },
[VARYING_SLOT_COL1] = { TGSI_SEMANTIC_COLOR, 1 },
[VARYING_SLOT_BFC0] = { TGSI_SEMANTIC_BCOLOR, 0 },
[VARYING_SLOT_BFC1] = { TGSI_SEMANTIC_BCOLOR, 1 },
[VARYING_SLOT_FOGC] = { TGSI_SEMANTIC_FOG, 0 },
[VARYING_SLOT_PSIZ] = { TGSI_SEMANTIC_PSIZE, 0 },
[VARYING_SLOT_FACE] = { TGSI_SEMANTIC_FACE, 0 },
[VARYING_SLOT_EDGE] = { TGSI_SEMANTIC_EDGEFLAG, 0 },
[VARYING_SLOT_PRIMITIVE_ID] = { TGSI_SEMANTIC_PRIMID, 0 },
[VARYING_SLOT_CLIP_DIST0] = { TGSI_SEMANTIC_CLIPDIST, 0 },
[VARYING_SLOT_CLIP_DIST1] = { TGSI_SEMANTIC_CLIPDIST, 1 },
[VARYING_SLOT_CLIP_VERTEX] = { TGSI_SEMANTIC_CLIPVERTEX, 0 },
[VARYING_SLOT_PNTC] = { TGSI_SEMANTIC_PCOORD, 0 },
[VARYING_SLOT_VIEWPORT] = { TGSI_SEMANTIC_VIEWPORT_INDEX, 0 },
[VARYING_SLOT_LAYER] = { TGSI_SEMANTIC_LAYER, 0 },
};
if (slot >= VARYING_SLOT_VAR0) {
*semantic_name = TGSI_SEMANTIC_GENERIC;
*semantic_index = slot - VARYING_SLOT_VAR0;
return;
}
if (slot >= VARYING_SLOT_TEX0 && slot <= VARYING_SLOT_TEX7) {
*semantic_name = TGSI_SEMANTIC_TEXCOORD;
*semantic_index = slot - VARYING_SLOT_TEX0;
return;
}
if (slot >= ARRAY_SIZE(map)) {
fprintf(stderr, "Unknown varying slot %d\n", slot);
abort();
}
*semantic_name = map[slot][0];
*semantic_index = map[slot][1];
}
/* Temporary helper to remap back to TGSI style semantic name/index
* values, for use in drivers that haven't been converted to using
* FRAG_RESULT_
*/
void
frag_result_to_tgsi_semantic(gl_frag_result slot,
unsigned *semantic_name, unsigned *semantic_index)
{
static const unsigned map[][2] = {
[FRAG_RESULT_DEPTH] = { TGSI_SEMANTIC_POSITION, 0 },
[FRAG_RESULT_COLOR] = { TGSI_SEMANTIC_COLOR, -1 },
[FRAG_RESULT_DATA0 + 0] = { TGSI_SEMANTIC_COLOR, 0 },
[FRAG_RESULT_DATA0 + 1] = { TGSI_SEMANTIC_COLOR, 1 },
[FRAG_RESULT_DATA0 + 2] = { TGSI_SEMANTIC_COLOR, 2 },
[FRAG_RESULT_DATA0 + 3] = { TGSI_SEMANTIC_COLOR, 3 },
[FRAG_RESULT_DATA0 + 4] = { TGSI_SEMANTIC_COLOR, 4 },
[FRAG_RESULT_DATA0 + 5] = { TGSI_SEMANTIC_COLOR, 5 },
[FRAG_RESULT_DATA0 + 6] = { TGSI_SEMANTIC_COLOR, 6 },
[FRAG_RESULT_DATA0 + 7] = { TGSI_SEMANTIC_COLOR, 7 },
};
*semantic_name = map[slot][0];
*semantic_index = map[slot][1];
}
static nir_ssa_def *
ttn_src_for_dest(nir_builder *b, nir_alu_dest *dest)
{
@@ -216,12 +338,15 @@ ttn_emit_declaration(struct ttn_compile *c)
var->data.mode = nir_var_shader_in;
var->name = ralloc_asprintf(var, "in_%d", idx);
/* We should probably translate to a VERT_ATTRIB_* or VARYING_SLOT_*
* instead, but nothing in NIR core is looking at the value
* currently, and this is less change to drivers.
*/
var->data.location = decl->Semantic.Name;
var->data.index = decl->Semantic.Index;
if (c->scan->processor == TGSI_PROCESSOR_FRAGMENT) {
var->data.location =
tgsi_varying_semantic_to_slot(decl->Semantic.Name,
decl->Semantic.Index);
} else {
assert(!decl->Declaration.Semantic);
var->data.location = VERT_ATTRIB_GENERIC0 + idx;
}
var->data.index = 0;
/* We definitely need to translate the interpolation field, because
* nir_print will decode it.
@@ -241,6 +366,8 @@ ttn_emit_declaration(struct ttn_compile *c)
exec_list_push_tail(&b->shader->inputs, &var->node);
break;
case TGSI_FILE_OUTPUT: {
int semantic_name = decl->Semantic.Name;
int semantic_index = decl->Semantic.Index;
/* Since we can't load from outputs in the IR, we make temporaries
* for the outputs and emit stores to the real outputs at the end of
* the shader.
@@ -252,14 +379,40 @@ ttn_emit_declaration(struct ttn_compile *c)
var->data.mode = nir_var_shader_out;
var->name = ralloc_asprintf(var, "out_%d", idx);
var->data.index = 0;
var->data.location = decl->Semantic.Name;
if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
decl->Semantic.Index == 0 &&
c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
var->data.index = -1;
else
var->data.index = decl->Semantic.Index;
if (c->scan->processor == TGSI_PROCESSOR_FRAGMENT) {
switch (semantic_name) {
case TGSI_SEMANTIC_COLOR: {
/* TODO tgsi loses some information, so we cannot
* actually differentiate here between DSB and MRT
* at this point. But so far no drivers using tgsi-
* to-nir support dual source blend:
*/
bool dual_src_blend = false;
if (dual_src_blend && (semantic_index == 1)) {
var->data.location = FRAG_RESULT_DATA0;
var->data.index = 1;
} else {
if (c->scan->properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
var->data.location = FRAG_RESULT_COLOR;
else
var->data.location = FRAG_RESULT_DATA0 + semantic_index;
}
break;
}
case TGSI_SEMANTIC_POSITION:
var->data.location = FRAG_RESULT_DEPTH;
break;
default:
fprintf(stderr, "Bad TGSI semantic: %d/%d\n",
decl->Semantic.Name, decl->Semantic.Index);
abort();
}
} else {
var->data.location =
tgsi_varying_semantic_to_slot(semantic_name, semantic_index);
}
if (is_array) {
unsigned j;
@@ -921,10 +1074,6 @@ ttn_if(struct ttn_compile *c, nir_ssa_def *src, bool is_uint)
{
nir_builder *b = &c->build;
/* Save the outside-of-the-if-statement node list. */
c->if_stack[c->if_stack_pos] = b->cursor;
c->if_stack_pos++;
src = ttn_channel(b, src, X);
nir_if *if_stmt = nir_if_create(b->shader);
@@ -935,6 +1084,9 @@ ttn_if(struct ttn_compile *c, nir_ssa_def *src, bool is_uint)
}
nir_builder_cf_insert(b, &if_stmt->cf_node);
c->if_stack[c->if_stack_pos] = nir_after_cf_node(&if_stmt->cf_node);
c->if_stack_pos++;
b->cursor = nir_after_cf_list(&if_stmt->then_list);
c->if_stack[c->if_stack_pos] = nir_after_cf_list(&if_stmt->else_list);
@@ -963,13 +1115,12 @@ ttn_bgnloop(struct ttn_compile *c)
{
nir_builder *b = &c->build;
/* Save the outside-of-the-loop node list. */
c->loop_stack[c->loop_stack_pos] = b->cursor;
c->loop_stack_pos++;
nir_loop *loop = nir_loop_create(b->shader);
nir_builder_cf_insert(b, &loop->cf_node);
c->loop_stack[c->loop_stack_pos] = nir_after_cf_node(&loop->cf_node);
c->loop_stack_pos++;
b->cursor = nir_after_cf_list(&loop->body);
}
+6
View File
@@ -28,3 +28,9 @@ struct nir_shader_compiler_options *options;
struct nir_shader *
tgsi_to_nir(const void *tgsi_tokens,
const struct nir_shader_compiler_options *options);
void
varying_slot_to_tgsi_semantic(gl_varying_slot slot,
unsigned *semantic_name, unsigned *semantic_index);
void
frag_result_to_tgsi_semantic(gl_frag_result slot,
unsigned *semantic_name, unsigned *semantic_index);
+2
View File
@@ -96,11 +96,13 @@ os_log_message(const char *message)
}
#if !defined(PIPE_SUBSYSTEM_EMBEDDED)
const char *
os_get_option(const char *name)
{
return getenv(name);
}
#endif /* !PIPE_SUBSYSTEM_EMBEDDED */
/**
@@ -166,6 +166,11 @@ pb_cache_manager_create(struct pb_manager *provider,
unsigned bypass_usage,
uint64_t maximum_cache_size);
/**
* Remove a buffer from the cache, but keep it alive.
*/
void
pb_cache_manager_remove_buffer(struct pb_buffer *buf);
struct pb_fence_ops;
@@ -104,18 +104,42 @@ pb_cache_manager(struct pb_manager *mgr)
}
static void
_pb_cache_manager_remove_buffer_locked(struct pb_cache_buffer *buf)
{
struct pb_cache_manager *mgr = buf->mgr;
if (buf->head.next) {
LIST_DEL(&buf->head);
assert(mgr->numDelayed);
--mgr->numDelayed;
mgr->cache_size -= buf->base.size;
}
buf->mgr = NULL;
}
void
pb_cache_manager_remove_buffer(struct pb_buffer *pb_buf)
{
struct pb_cache_buffer *buf = (struct pb_cache_buffer*)pb_buf;
struct pb_cache_manager *mgr = buf->mgr;
if (!mgr)
return;
pipe_mutex_lock(mgr->mutex);
_pb_cache_manager_remove_buffer_locked(buf);
pipe_mutex_unlock(mgr->mutex);
}
/**
* Actually destroy the buffer.
*/
static inline void
_pb_cache_buffer_destroy(struct pb_cache_buffer *buf)
{
struct pb_cache_manager *mgr = buf->mgr;
LIST_DEL(&buf->head);
assert(mgr->numDelayed);
--mgr->numDelayed;
mgr->cache_size -= buf->base.size;
if (buf->mgr)
_pb_cache_manager_remove_buffer_locked(buf);
assert(!pipe_is_referenced(&buf->base.reference));
pb_reference(&buf->buffer, NULL);
FREE(buf);
@@ -156,6 +180,12 @@ pb_cache_buffer_destroy(struct pb_buffer *_buf)
struct pb_cache_buffer *buf = pb_cache_buffer(_buf);
struct pb_cache_manager *mgr = buf->mgr;
if (!mgr) {
pb_reference(&buf->buffer, NULL);
FREE(buf);
return;
}
pipe_mutex_lock(mgr->mutex);
assert(!pipe_is_referenced(&buf->base.reference));
+309
View File
@@ -0,0 +1,309 @@
/*
* Copyright 2014 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL THE 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.
*/
/**
* This utility transforms the fragment shader to support anti-aliasing points.
*/
#include "util/u_debug.h"
#include "util/u_math.h"
#include "tgsi_info.h"
#include "tgsi_aa_point.h"
#include "tgsi_transform.h"
#define INVALID_INDEX 9999
struct aa_transform_context
{
struct tgsi_transform_context base;
unsigned tmp; // temp register
unsigned color_out; // frag color out register
unsigned color_tmp; // frag color temp register
unsigned num_tmp; // number of temp registers
unsigned num_imm; // number of immediates
unsigned num_input; // number of inputs
unsigned aa_point_coord_index;
};
static inline struct aa_transform_context *
aa_transform_context(struct tgsi_transform_context *ctx)
{
return (struct aa_transform_context *) ctx;
}
/**
* TGSI declaration transform callback.
*/
static void
aa_decl(struct tgsi_transform_context *ctx,
struct tgsi_full_declaration *decl)
{
struct aa_transform_context *ts = aa_transform_context(ctx);
if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
decl->Semantic.Index == 0) {
ts->color_out = decl->Range.First;
}
else if (decl->Declaration.File == TGSI_FILE_INPUT) {
ts->num_input++;
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
ts->num_tmp = MAX2(ts->num_tmp, decl->Range.Last + 1);
}
ctx->emit_declaration(ctx, decl);
}
/**
* TGSI immediate declaration transform callback.
*/
static void
aa_immediate(struct tgsi_transform_context *ctx,
struct tgsi_full_immediate *imm)
{
struct aa_transform_context *ts = aa_transform_context(ctx);
ctx->emit_immediate(ctx, imm);
ts->num_imm++;
}
/**
* TGSI transform prolog callback.
*/
static void
aa_prolog(struct tgsi_transform_context *ctx)
{
struct aa_transform_context *ts = aa_transform_context(ctx);
unsigned tmp0;
unsigned texIn;
unsigned imm;
/* Declare two temporary registers, one for temporary and
* one for color.
*/
ts->tmp = ts->num_tmp++;
ts->color_tmp = ts->num_tmp++;
tgsi_transform_temps_decl(ctx, ts->tmp, ts->color_tmp);
/* Declare new generic input/texcoord */
texIn = ts->num_input++;
tgsi_transform_input_decl(ctx, texIn, TGSI_SEMANTIC_GENERIC,
ts->aa_point_coord_index, TGSI_INTERPOLATE_LINEAR);
/* Declare extra immediates */
imm = ts->num_imm++;
tgsi_transform_immediate_decl(ctx, 0.5, 0.5, 0.45, 1.0);
/*
* Emit code to compute fragment coverage.
* The point always has radius 0.5. The threshold value will be a
* value less than, but close to 0.5, such as 0.45.
* We compute a coverage factor from the distance and threshold.
* If the coverage is negative, the fragment is outside the circle and
* it's discarded.
* If the coverage is >= 1, the fragment is fully inside the threshold
* distance. We limit/clamp the coverage to 1.
* Otherwise, the fragment is between the threshold value and 0.5 and we
* compute a coverage value in [0,1].
*
* Input reg (texIn) usage:
* texIn.x = x point coord in [0,1]
* texIn.y = y point coord in [0,1]
* texIn.z = "k" the smoothing threshold distance
* texIn.w = unused
*
* Temp reg (t0) usage:
* t0.x = distance of fragment from center point
* t0.y = boolean, is t0.x > 0.5, also misc temp usage
* t0.z = temporary for computing 1/(0.5-k) value
* t0.w = final coverage value
*/
tmp0 = ts->tmp;
/* SUB t0.xy, texIn, (0.5, 0,5) */
tgsi_transform_op2_inst(ctx, TGSI_OPCODE_SUB,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_XY,
TGSI_FILE_INPUT, texIn,
TGSI_FILE_IMMEDIATE, imm);
/* DP2 t0.x, t0.xy, t0.xy; # t0.x = x^2 + y^2 */
tgsi_transform_op2_inst(ctx, TGSI_OPCODE_DP2,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_X,
TGSI_FILE_TEMPORARY, tmp0,
TGSI_FILE_TEMPORARY, tmp0);
/* SQRT t0.x, t0.x */
tgsi_transform_op1_inst(ctx, TGSI_OPCODE_SQRT,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_X,
TGSI_FILE_TEMPORARY, tmp0);
/* compute coverage factor = (0.5-d)/(0.5-k) */
/* SUB t0.w, 0.5, texIn.z; # t0.w = 0.5-k */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SUB,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_W,
TGSI_FILE_IMMEDIATE, imm, TGSI_SWIZZLE_X,
TGSI_FILE_INPUT, texIn, TGSI_SWIZZLE_Z);
/* SUB t0.y, 0.5, t0.x; # t0.y = 0.5-d */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SUB,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_Y,
TGSI_FILE_IMMEDIATE, imm, TGSI_SWIZZLE_X,
TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_X);
/* DIV t0.w, t0.y, t0.w; # coverage = (0.5-d)/(0.5-k) */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_DIV,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_W,
TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_Y,
TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_W);
/* If the coverage value is negative, it means the fragment is outside
* the point's circular boundary. Kill it.
*/
/* KILL_IF tmp0.w; # if tmp0.w < 0 KILL */
tgsi_transform_kill_inst(ctx, TGSI_FILE_TEMPORARY, tmp0,
TGSI_SWIZZLE_W, FALSE);
/* If the distance is less than the threshold, the coverage/alpha value
* will be greater than one. Clamp to one here.
*/
/* MIN tmp0.w, tmp0.w, 1.0 */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MIN,
TGSI_FILE_TEMPORARY, tmp0, TGSI_WRITEMASK_W,
TGSI_FILE_TEMPORARY, tmp0, TGSI_SWIZZLE_W,
TGSI_FILE_IMMEDIATE, imm, TGSI_SWIZZLE_W);
}
/**
* TGSI instruction transform callback.
*/
static void
aa_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction *inst)
{
struct aa_transform_context *ts = aa_transform_context(ctx);
unsigned i;
/* Look for writes to color output reg and replace it with
* color temp reg.
*/
for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
struct tgsi_full_dst_register *dst = &inst->Dst[i];
if (dst->Register.File == TGSI_FILE_OUTPUT &&
dst->Register.Index == ts->color_out) {
dst->Register.File = TGSI_FILE_TEMPORARY;
dst->Register.Index = ts->color_tmp;
}
}
ctx->emit_instruction(ctx, inst);
}
/**
* TGSI transform epilog callback.
*/
static void
aa_epilog(struct tgsi_transform_context *ctx)
{
struct aa_transform_context *ts = aa_transform_context(ctx);
/* add alpha modulation code at tail of program */
assert(ts->color_out != INVALID_INDEX);
assert(ts->color_tmp != INVALID_INDEX);
/* MOV output.color.xyz colorTmp */
tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
TGSI_FILE_OUTPUT, ts->color_out,
TGSI_WRITEMASK_XYZ,
TGSI_FILE_TEMPORARY, ts->color_tmp);
/* MUL output.color.w colorTmp.w tmp0.w */
tgsi_transform_op2_inst(ctx, TGSI_OPCODE_MUL,
TGSI_FILE_OUTPUT, ts->color_out,
TGSI_WRITEMASK_W,
TGSI_FILE_TEMPORARY, ts->color_tmp,
TGSI_FILE_TEMPORARY, ts->tmp);
}
/**
* TGSI utility to transform a fragment shader to support antialiasing point.
*
* This utility accepts two inputs:
*\param tokens_in -- the original token string of the shader
*\param aa_point_coord_index -- the semantic index of the generic register
* that contains the point sprite texture coord
*
* For each fragment in the point, we compute the distance of the fragment
* from the point center using the point sprite texture coordinates.
* If the distance is greater than 0.5, we'll discard the fragment.
* Otherwise, we'll compute a coverage value which approximates how much
* of the fragment is inside the bounding circle of the point. If the distance
* is less than 'k', the coverage is 1. Else, the coverage is between 0 and 1.
* The final fragment color's alpha channel is then modulated by the coverage
* value.
*/
struct tgsi_token *
tgsi_add_aa_point(const struct tgsi_token *tokens_in,
const int aa_point_coord_index)
{
struct aa_transform_context transform;
const uint num_new_tokens = 200; /* should be enough */
const uint new_len = tgsi_num_tokens(tokens_in) + num_new_tokens;
struct tgsi_token *new_tokens;
/* allocate new tokens buffer */
new_tokens = tgsi_alloc_tokens(new_len);
if (!new_tokens)
return NULL;
/* setup transformation context */
memset(&transform, 0, sizeof(transform));
transform.base.transform_declaration = aa_decl;
transform.base.transform_instruction = aa_inst;
transform.base.transform_immediate = aa_immediate;
transform.base.prolog = aa_prolog;
transform.base.epilog = aa_epilog;
transform.tmp = INVALID_INDEX;
transform.color_out = INVALID_INDEX;
transform.color_tmp = INVALID_INDEX;
assert(aa_point_coord_index != -1);
transform.aa_point_coord_index = (unsigned)aa_point_coord_index;
transform.num_tmp = 0;
transform.num_imm = 0;
transform.num_input = 0;
/* transform the shader */
tgsi_transform_shader(tokens_in, new_tokens, new_len, &transform.base);
return new_tokens;
}
@@ -0,0 +1,35 @@
/*
* Copyright 2014 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL THE 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.
*/
#ifndef TGSI_AA_POINT_H
#define TGSI_AA_POINT_H
struct tgsi_token;
struct tgsi_token *
tgsi_add_aa_point(const struct tgsi_token *tokens_in,
const int aa_point_coord_index);
#endif /* TGSI_AA_POINT_H */
+63 -17
View File
@@ -2021,7 +2021,7 @@ fetch_sampler_unit(struct tgsi_exec_machine *mach,
/*
* execute a texture instruction.
*
* modifier is used to control the channel routing for the\
* modifier is used to control the channel routing for the
* instruction variants like proj, lod, and texture with lod bias.
* sampler indicates which src register the sampler is contained in.
*/
@@ -2032,7 +2032,7 @@ exec_tex(struct tgsi_exec_machine *mach,
{
const union tgsi_exec_channel *args[5], *proj = NULL;
union tgsi_exec_channel r[5];
enum tgsi_sampler_control control = tgsi_sampler_lod_none;
enum tgsi_sampler_control control = TGSI_SAMPLER_LOD_NONE;
uint chan;
uint unit;
int8_t offsets[3];
@@ -2078,11 +2078,11 @@ exec_tex(struct tgsi_exec_machine *mach,
args[i] = &ZeroVec;
if (modifier == TEX_MODIFIER_EXPLICIT_LOD)
control = tgsi_sampler_lod_explicit;
control = TGSI_SAMPLER_LOD_EXPLICIT;
else if (modifier == TEX_MODIFIER_LOD_BIAS)
control = tgsi_sampler_lod_bias;
control = TGSI_SAMPLER_LOD_BIAS;
else if (modifier == TEX_MODIFIER_GATHER)
control = tgsi_sampler_gather;
control = TGSI_SAMPLER_GATHER;
}
else {
for (i = dim; i < Elements(args); i++)
@@ -2132,6 +2132,46 @@ exec_tex(struct tgsi_exec_machine *mach,
}
}
static void
exec_lodq(struct tgsi_exec_machine *mach,
const struct tgsi_full_instruction *inst)
{
uint unit;
int dim;
int i;
union tgsi_exec_channel coords[4];
const union tgsi_exec_channel *args[Elements(coords)];
union tgsi_exec_channel r[2];
unit = fetch_sampler_unit(mach, inst, 1);
dim = tgsi_util_get_texture_coord_dim(inst->Texture.Texture, NULL);
assert(dim <= Elements(coords));
/* fetch coordinates */
for (i = 0; i < dim; i++) {
FETCH(&coords[i], 0, TGSI_CHAN_X + i);
args[i] = &coords[i];
}
for (i = dim; i < Elements(coords); i++) {
args[i] = &ZeroVec;
}
mach->Sampler->query_lod(mach->Sampler, unit, unit,
args[0]->f,
args[1]->f,
args[2]->f,
args[3]->f,
TGSI_SAMPLER_LOD_NONE,
r[0].f,
r[1].f);
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) {
store_dest(mach, &r[0], &inst->Dst[0], inst, TGSI_CHAN_X,
TGSI_EXEC_DATA_FLOAT);
}
if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) {
store_dest(mach, &r[1], &inst->Dst[0], inst, TGSI_CHAN_Y,
TGSI_EXEC_DATA_FLOAT);
}
}
static void
exec_txd(struct tgsi_exec_machine *mach,
@@ -2155,7 +2195,7 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, unit, unit,
&r[0], &ZeroVec, &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, C, LOD */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
@@ -2171,7 +2211,7 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, unit, unit,
&r[0], &r[1], &r[2], &ZeroVec, &ZeroVec, /* S, T, P, C, LOD */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
@@ -2185,7 +2225,7 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, unit, unit,
&r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, C, LOD */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
@@ -2205,7 +2245,7 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, unit, unit,
&r[0], &r[1], &r[2], &r[3], &ZeroVec, /* inputs */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
@@ -2225,7 +2265,7 @@ exec_txd(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, unit, unit,
&r[0], &r[1], &r[2], &r[3], &ZeroVec, /* inputs */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
@@ -2364,7 +2404,7 @@ exec_sample(struct tgsi_exec_machine *mach,
const uint sampler_unit = inst->Src[2].Register.Index;
union tgsi_exec_channel r[5], c1;
const union tgsi_exec_channel *lod = &ZeroVec;
enum tgsi_sampler_control control = tgsi_sampler_lod_none;
enum tgsi_sampler_control control = TGSI_SAMPLER_LOD_NONE;
uint chan;
unsigned char swizzles[4];
int8_t offsets[3];
@@ -2378,16 +2418,16 @@ exec_sample(struct tgsi_exec_machine *mach,
if (modifier == TEX_MODIFIER_LOD_BIAS) {
FETCH(&c1, 3, TGSI_CHAN_X);
lod = &c1;
control = tgsi_sampler_lod_bias;
control = TGSI_SAMPLER_LOD_BIAS;
}
else if (modifier == TEX_MODIFIER_EXPLICIT_LOD) {
FETCH(&c1, 3, TGSI_CHAN_X);
lod = &c1;
control = tgsi_sampler_lod_explicit;
control = TGSI_SAMPLER_LOD_EXPLICIT;
}
else {
assert(modifier == TEX_MODIFIER_LEVEL_ZERO);
control = tgsi_sampler_lod_zero;
control = TGSI_SAMPLER_LOD_ZERO;
}
}
@@ -2513,7 +2553,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, resource_unit, sampler_unit,
&r[0], &r[1], &ZeroVec, &ZeroVec, &ZeroVec, /* S, T, P, C, LOD */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* R, G, B, A */
break;
@@ -2529,7 +2569,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, resource_unit, sampler_unit,
&r[0], &r[1], &r[2], &ZeroVec, &ZeroVec, /* inputs */
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]); /* outputs */
break;
@@ -2547,7 +2587,7 @@ exec_sample_d(struct tgsi_exec_machine *mach,
fetch_texel(mach->Sampler, resource_unit, sampler_unit,
&r[0], &r[1], &r[2], &r[3], &ZeroVec,
derivs, offsets, tgsi_sampler_derivs_explicit,
derivs, offsets, TGSI_SAMPLER_DERIVS_EXPLICIT,
&r[0], &r[1], &r[2], &r[3]);
break;
@@ -4378,6 +4418,12 @@ exec_instruction(
exec_tex(mach, inst, TEX_MODIFIER_GATHER, 2);
break;
case TGSI_OPCODE_LODQ:
/* src[0] = texcoord */
/* src[1] = sampler unit */
exec_lodq(mach, inst);
break;
case TGSI_OPCODE_UP2H:
assert (0);
break;
+18 -7
View File
@@ -88,13 +88,14 @@ struct tgsi_interp_coef
float dady[TGSI_NUM_CHANNELS];
};
enum tgsi_sampler_control {
tgsi_sampler_lod_none,
tgsi_sampler_lod_bias,
tgsi_sampler_lod_explicit,
tgsi_sampler_lod_zero,
tgsi_sampler_derivs_explicit,
tgsi_sampler_gather,
enum tgsi_sampler_control
{
TGSI_SAMPLER_LOD_NONE,
TGSI_SAMPLER_LOD_BIAS,
TGSI_SAMPLER_LOD_EXPLICIT,
TGSI_SAMPLER_LOD_ZERO,
TGSI_SAMPLER_DERIVS_EXPLICIT,
TGSI_SAMPLER_GATHER,
};
/**
@@ -138,6 +139,16 @@ struct tgsi_sampler
const int j[TGSI_QUAD_SIZE], const int k[TGSI_QUAD_SIZE],
const int lod[TGSI_QUAD_SIZE], const int8_t offset[3],
float rgba[TGSI_NUM_CHANNELS][TGSI_QUAD_SIZE]);
void (*query_lod)(const struct tgsi_sampler *tgsi_sampler,
const unsigned sview_index,
const unsigned sampler_index,
const float s[TGSI_QUAD_SIZE],
const float t[TGSI_QUAD_SIZE],
const float p[TGSI_QUAD_SIZE],
const float c0[TGSI_QUAD_SIZE],
const enum tgsi_sampler_control control,
float mipmap[TGSI_QUAD_SIZE],
float lod[TGSI_QUAD_SIZE]);
};
#define TGSI_EXEC_NUM_TEMPS 4096
+2 -1
View File
@@ -141,7 +141,7 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 0, 0, 0, 1, 1, 0, NONE, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
{ 0, 0, 0, 0, 1, 0, NONE, "ENDSUB", TGSI_OPCODE_ENDSUB },
{ 1, 1, 1, 0, 0, 0, OTHR, "TXQ_LZ", TGSI_OPCODE_TXQ_LZ },
{ 0, 0, 0, 0, 0, 0, NONE, "", 104 }, /* removed */
{ 1, 1, 1, 0, 0, 0, OTHR, "TXQS", TGSI_OPCODE_TXQS },
{ 0, 0, 0, 0, 0, 0, NONE, "", 105 }, /* removed */
{ 0, 0, 0, 0, 0, 0, NONE, "", 106 }, /* removed */
{ 0, 0, 0, 0, 0, 0, NONE, "NOP", TGSI_OPCODE_NOP },
@@ -331,6 +331,7 @@ tgsi_opcode_infer_type( uint opcode )
case TGSI_OPCODE_SAD: /* XXX some src args may be signed for SAD ? */
case TGSI_OPCODE_TXQ:
case TGSI_OPCODE_TXQ_LZ:
case TGSI_OPCODE_TXQS:
case TGSI_OPCODE_F2U:
case TGSI_OPCODE_UDIV:
case TGSI_OPCODE_UMAD:
@@ -0,0 +1,582 @@
/*
* Copyright 2014 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL THE 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.
*/
/**
* This utility transforms the geometry shader to emulate point sprite by
* drawing a quad. It also adds an extra output for the original point position
* if the point position is to be written to a stream output buffer.
* Note: It assumes the driver will add a constant for the inverse viewport
* after the user defined constants.
*/
#include "util/u_debug.h"
#include "util/u_math.h"
#include "tgsi_info.h"
#include "tgsi_point_sprite.h"
#include "tgsi_transform.h"
#include "pipe/p_state.h"
#define INVALID_INDEX 9999
/* Set swizzle based on the immediates (0, 1, 0, -1) */
static inline unsigned
set_swizzle(int x, int y, int z, int w)
{
static const unsigned map[3] = {TGSI_SWIZZLE_W, TGSI_SWIZZLE_X,
TGSI_SWIZZLE_Y};
assert(x >= -1);
assert(x <= 1);
assert(y >= -1);
assert(y <= 1);
assert(z >= -1);
assert(z <= 1);
assert(w >= -1);
assert(w <= 1);
return map[x+1] | (map[y+1] << 2) | (map[z+1] << 4) | (map[w+1] << 6);
}
static inline unsigned
get_swizzle(unsigned swizzle, unsigned component)
{
assert(component < 4);
return (swizzle >> (component * 2)) & 0x3;
}
struct psprite_transform_context
{
struct tgsi_transform_context base;
unsigned num_tmp;
unsigned num_out;
unsigned num_orig_out;
unsigned num_const;
unsigned num_imm;
unsigned point_size_in; // point size input
unsigned point_size_out; // point size output
unsigned point_size_tmp; // point size temp
unsigned point_pos_in; // point pos input
unsigned point_pos_out; // point pos output
unsigned point_pos_sout; // original point pos for streamout
unsigned point_pos_tmp; // point pos temp
unsigned point_scale_tmp; // point scale temp
unsigned point_color_out; // point color output
unsigned point_color_tmp; // point color temp
unsigned point_imm; // point immediates
unsigned point_ivp; // point inverseViewport constant
unsigned point_dir_swz[4]; // point direction swizzle
unsigned point_coord_swz[4]; // point coord swizzle
unsigned point_coord_enable; // point coord enable mask
unsigned point_coord_decl; // point coord output declared mask
unsigned point_coord_out; // point coord output starting index
unsigned point_coord_aa; // aa point coord semantic index
unsigned point_coord_k; // aa point coord threshold distance
unsigned stream_out_point_pos:1; // set if to stream out original point pos
unsigned aa_point:1; // set if doing aa point
unsigned out_tmp_index[PIPE_MAX_SHADER_OUTPUTS];
int max_generic;
};
static inline struct psprite_transform_context *
psprite_transform_context(struct tgsi_transform_context *ctx)
{
return (struct psprite_transform_context *) ctx;
}
/**
* TGSI declaration transform callback.
*/
static void
psprite_decl(struct tgsi_transform_context *ctx,
struct tgsi_full_declaration *decl)
{
struct psprite_transform_context *ts = psprite_transform_context(ctx);
if (decl->Declaration.File == TGSI_FILE_INPUT) {
if (decl->Semantic.Name == TGSI_SEMANTIC_PSIZE) {
ts->point_size_in = decl->Range.First;
}
else if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) {
ts->point_pos_in = decl->Range.First;
}
}
else if (decl->Declaration.File == TGSI_FILE_OUTPUT) {
if (decl->Semantic.Name == TGSI_SEMANTIC_PSIZE) {
ts->point_size_out = decl->Range.First;
}
else if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) {
ts->point_pos_out = decl->Range.First;
}
else if (decl->Semantic.Name == TGSI_SEMANTIC_GENERIC &&
decl->Semantic.Index < 32) {
ts->point_coord_decl |= 1 << decl->Semantic.Index;
ts->max_generic = MAX2(ts->max_generic, decl->Semantic.Index);
}
ts->num_out = MAX2(ts->num_out, decl->Range.Last + 1);
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
ts->num_tmp = MAX2(ts->num_tmp, decl->Range.Last + 1);
}
else if (decl->Declaration.File == TGSI_FILE_CONSTANT) {
ts->num_const = MAX2(ts->num_const, decl->Range.Last + 1);
}
ctx->emit_declaration(ctx, decl);
}
/**
* TGSI immediate declaration transform callback.
*/
static void
psprite_immediate(struct tgsi_transform_context *ctx,
struct tgsi_full_immediate *imm)
{
struct psprite_transform_context *ts = psprite_transform_context(ctx);
ctx->emit_immediate(ctx, imm);
ts->num_imm++;
}
/**
* TGSI transform prolog callback.
*/
static void
psprite_prolog(struct tgsi_transform_context *ctx)
{
struct psprite_transform_context *ts = psprite_transform_context(ctx);
unsigned point_coord_enable, en;
int i;
/* Replace output registers with temporary registers */
for (i = 0; i < ts->num_out; i++) {
ts->out_tmp_index[i] = ts->num_tmp++;
}
ts->num_orig_out = ts->num_out;
/* Declare a tmp register for point scale */
ts->point_scale_tmp = ts->num_tmp++;
if (ts->point_size_out != INVALID_INDEX)
ts->point_size_tmp = ts->out_tmp_index[ts->point_size_out];
else
ts->point_size_tmp = ts->num_tmp++;
assert(ts->point_pos_out != INVALID_INDEX);
ts->point_pos_tmp = ts->out_tmp_index[ts->point_pos_out];
ts->out_tmp_index[ts->point_pos_out] = INVALID_INDEX;
/* Declare one more tmp register for point coord threshold distance
* if we are generating anti-aliased point.
*/
if (ts->aa_point)
ts->point_coord_k = ts->num_tmp++;
tgsi_transform_temps_decl(ctx, ts->point_size_tmp, ts->num_tmp-1);
/* Declare an extra output for the original point position for stream out */
if (ts->stream_out_point_pos) {
ts->point_pos_sout = ts->num_out++;
tgsi_transform_output_decl(ctx, ts->point_pos_sout,
TGSI_SEMANTIC_GENERIC, 0, 0);
}
/* point coord outputs to be declared */
point_coord_enable = ts->point_coord_enable & ~ts->point_coord_decl;
/* Declare outputs for those point coord that are enabled but are not
* already declared in this shader.
*/
ts->point_coord_out = ts->num_out;
if (point_coord_enable) {
for (i = 0, en = point_coord_enable; en; en>>=1, i++) {
if (en & 0x1) {
tgsi_transform_output_decl(ctx, ts->num_out++,
TGSI_SEMANTIC_GENERIC, i, 0);
ts->max_generic = MAX2(ts->max_generic, i);
}
}
}
/* add an extra generic output for aa point texcoord */
if (ts->aa_point) {
ts->point_coord_aa = ts->max_generic + 1;
assert((ts->point_coord_enable & (1 << ts->point_coord_aa)) == 0);
ts->point_coord_enable |= 1 << (ts->point_coord_aa);
tgsi_transform_output_decl(ctx, ts->num_out++, TGSI_SEMANTIC_GENERIC,
ts->point_coord_aa, 0);
}
/* Declare extra immediates */
ts->point_imm = ts->num_imm;
tgsi_transform_immediate_decl(ctx, 0, 1, 0.5, -1);
/* Declare point constant -
* constant.xy -- inverseViewport
* constant.z -- current point size
* constant.w -- max point size
* The driver needs to add this constant to the constant buffer
*/
ts->point_ivp = ts->num_const++;
tgsi_transform_const_decl(ctx, ts->point_ivp, ts->point_ivp);
/* If this geometry shader does not specify point size,
* get the current point size from the point constant.
*/
if (ts->point_size_out == INVALID_INDEX) {
struct tgsi_full_instruction inst;
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_MOV;
inst.Instruction.NumDstRegs = 1;
tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_TEMPORARY,
ts->point_size_tmp, TGSI_WRITEMASK_XYZW);
inst.Instruction.NumSrcRegs = 1;
tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_CONSTANT,
ts->point_ivp, TGSI_SWIZZLE_Z,
TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
ctx->emit_instruction(ctx, &inst);
}
}
/**
* Add the point sprite emulation instructions at the emit vertex instruction
*/
static void
psprite_emit_vertex_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction *vert_inst)
{
struct psprite_transform_context *ts = psprite_transform_context(ctx);
struct tgsi_full_instruction inst;
unsigned point_coord_enable, en;
unsigned i, j, s;
/* new point coord outputs */
point_coord_enable = ts->point_coord_enable & ~ts->point_coord_decl;
/* OUTPUT[pos_sout] = TEMP[pos] */
if (ts->point_pos_sout != INVALID_INDEX) {
tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
TGSI_FILE_OUTPUT, ts->point_pos_sout,
TGSI_WRITEMASK_XYZW,
TGSI_FILE_TEMPORARY, ts->point_pos_tmp);
}
/**
* Set up the point scale vector
* scale = pointSize * pos.w * inverseViewport
*/
/* MUL point_scale.x, point_size.x, point_pos.w */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MUL,
TGSI_FILE_TEMPORARY, ts->point_scale_tmp, TGSI_WRITEMASK_X,
TGSI_FILE_TEMPORARY, ts->point_size_tmp, TGSI_SWIZZLE_X,
TGSI_FILE_TEMPORARY, ts->point_pos_tmp, TGSI_SWIZZLE_W);
/* MUL point_scale.xy, point_scale.xx, inverseViewport.xy */
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_MUL;
inst.Instruction.NumDstRegs = 1;
tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_TEMPORARY,
ts->point_scale_tmp, TGSI_WRITEMASK_XY);
inst.Instruction.NumSrcRegs = 2;
tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_TEMPORARY,
ts->point_scale_tmp, TGSI_SWIZZLE_X,
TGSI_SWIZZLE_X, TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
tgsi_transform_src_reg(&inst.Src[1], TGSI_FILE_CONSTANT,
ts->point_ivp, TGSI_SWIZZLE_X,
TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
ctx->emit_instruction(ctx, &inst);
/**
* Set up the point coord threshold distance
* k = 0.5 - 1 / pointsize
*/
if (ts->aa_point) {
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_DIV,
TGSI_FILE_TEMPORARY, ts->point_coord_k,
TGSI_WRITEMASK_X,
TGSI_FILE_IMMEDIATE, ts->point_imm,
TGSI_SWIZZLE_Y,
TGSI_FILE_TEMPORARY, ts->point_size_tmp,
TGSI_SWIZZLE_X);
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_SUB,
TGSI_FILE_TEMPORARY, ts->point_coord_k,
TGSI_WRITEMASK_X,
TGSI_FILE_IMMEDIATE, ts->point_imm,
TGSI_SWIZZLE_Z,
TGSI_FILE_TEMPORARY, ts->point_coord_k,
TGSI_SWIZZLE_X);
}
for (i = 0; i < 4; i++) {
unsigned point_dir_swz = ts->point_dir_swz[i];
unsigned point_coord_swz = ts->point_coord_swz[i];
/* All outputs need to be emitted for each vertex */
for (j = 0; j < ts->num_orig_out; j++) {
if (ts->out_tmp_index[j] != INVALID_INDEX) {
tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
TGSI_FILE_OUTPUT, j,
TGSI_WRITEMASK_XYZW,
TGSI_FILE_TEMPORARY, ts->out_tmp_index[j]);
}
}
/* pos = point_scale * point_dir + point_pos */
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_MAD;
inst.Instruction.NumDstRegs = 1;
tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_OUTPUT, ts->point_pos_out,
TGSI_WRITEMASK_XYZW);
inst.Instruction.NumSrcRegs = 3;
tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_TEMPORARY, ts->point_scale_tmp,
TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_X,
TGSI_SWIZZLE_X);
tgsi_transform_src_reg(&inst.Src[1], TGSI_FILE_IMMEDIATE, ts->point_imm,
get_swizzle(point_dir_swz, 0),
get_swizzle(point_dir_swz, 1),
get_swizzle(point_dir_swz, 2),
get_swizzle(point_dir_swz, 3));
tgsi_transform_src_reg(&inst.Src[2], TGSI_FILE_TEMPORARY, ts->point_pos_tmp,
TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Z,
TGSI_SWIZZLE_W);
ctx->emit_instruction(ctx, &inst);
/* point coord */
for (j = 0, s = 0, en = point_coord_enable; en; en>>=1, s++) {
unsigned dstReg;
if (en & 0x1) {
dstReg = ts->point_coord_out + j;
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_MOV;
inst.Instruction.NumDstRegs = 1;
tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_OUTPUT,
dstReg, TGSI_WRITEMASK_XYZW);
inst.Instruction.NumSrcRegs = 1;
tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_IMMEDIATE, ts->point_imm,
get_swizzle(point_coord_swz, 0),
get_swizzle(point_coord_swz, 1),
get_swizzle(point_coord_swz, 2),
get_swizzle(point_coord_swz, 3));
ctx->emit_instruction(ctx, &inst);
/* MOV point_coord.z point_coord_k.x */
if (s == ts->point_coord_aa) {
tgsi_transform_op1_swz_inst(ctx, TGSI_OPCODE_MOV,
TGSI_FILE_OUTPUT, dstReg, TGSI_WRITEMASK_Z,
TGSI_FILE_TEMPORARY, ts->point_coord_k,
TGSI_SWIZZLE_X);
}
j++; /* the next point coord output offset */
}
}
/* Emit the EMIT instruction for each vertex of the quad */
ctx->emit_instruction(ctx, vert_inst);
}
/* Emit the ENDPRIM instruction for the quad */
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_ENDPRIM;
inst.Instruction.NumDstRegs = 0;
inst.Instruction.NumSrcRegs = 1;
inst.Src[0] = vert_inst->Src[0];
ctx->emit_instruction(ctx, &inst);
}
/**
* TGSI instruction transform callback.
*/
static void
psprite_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction *inst)
{
struct psprite_transform_context *ts = psprite_transform_context(ctx);
if (inst->Instruction.Opcode == TGSI_OPCODE_EMIT) {
psprite_emit_vertex_inst(ctx, inst);
}
else if (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT &&
inst->Dst[0].Register.Index == ts->point_size_out) {
/**
* Replace point size output reg with tmp reg.
* The tmp reg will be later used as a src reg for computing
* the point scale factor.
*/
inst->Dst[0].Register.File = TGSI_FILE_TEMPORARY;
inst->Dst[0].Register.Index = ts->point_size_tmp;
ctx->emit_instruction(ctx, inst);
/* Clamp the point size */
/* MAX point_size_tmp.x, point_size_tmp.x, point_imm.y */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MAX,
TGSI_FILE_TEMPORARY, ts->point_size_tmp, TGSI_WRITEMASK_X,
TGSI_FILE_TEMPORARY, ts->point_size_tmp, TGSI_SWIZZLE_X,
TGSI_FILE_IMMEDIATE, ts->point_imm, TGSI_SWIZZLE_Y);
/* MIN point_size_tmp.x, point_size_tmp.x, point_ivp.w */
tgsi_transform_op2_swz_inst(ctx, TGSI_OPCODE_MIN,
TGSI_FILE_TEMPORARY, ts->point_size_tmp, TGSI_WRITEMASK_X,
TGSI_FILE_TEMPORARY, ts->point_size_tmp, TGSI_SWIZZLE_X,
TGSI_FILE_CONSTANT, ts->point_ivp, TGSI_SWIZZLE_W);
}
else if (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT &&
inst->Dst[0].Register.Index == ts->point_pos_out) {
/**
* Replace point pos output reg with tmp reg.
*/
inst->Dst[0].Register.File = TGSI_FILE_TEMPORARY;
inst->Dst[0].Register.Index = ts->point_pos_tmp;
ctx->emit_instruction(ctx, inst);
}
else if (inst->Dst[0].Register.File == TGSI_FILE_OUTPUT) {
/**
* Replace output reg with tmp reg.
*/
inst->Dst[0].Register.File = TGSI_FILE_TEMPORARY;
inst->Dst[0].Register.Index = ts->out_tmp_index[inst->Dst[0].Register.Index];
ctx->emit_instruction(ctx, inst);
}
else {
ctx->emit_instruction(ctx, inst);
}
}
/**
* TGSI property instruction transform callback.
* Transforms a point into a 4-vertex triangle strip.
*/
static void
psprite_property(struct tgsi_transform_context *ctx,
struct tgsi_full_property *prop)
{
switch (prop->Property.PropertyName) {
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
prop->u[0].Data = PIPE_PRIM_TRIANGLE_STRIP;
break;
case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
prop->u[0].Data *= 4;
break;
default:
break;
}
ctx->emit_property(ctx, prop);
}
/**
* TGSI utility to transform a geometry shader to support point sprite.
*/
struct tgsi_token *
tgsi_add_point_sprite(const struct tgsi_token *tokens_in,
const unsigned point_coord_enable,
const bool sprite_origin_lower_left,
const bool stream_out_point_pos,
int *aa_point_coord_index)
{
struct psprite_transform_context transform;
const uint num_new_tokens = 200; /* should be enough */
const uint new_len = tgsi_num_tokens(tokens_in) + num_new_tokens;
struct tgsi_token *new_tokens;
/* setup transformation context */
memset(&transform, 0, sizeof(transform));
transform.base.transform_declaration = psprite_decl;
transform.base.transform_instruction = psprite_inst;
transform.base.transform_property = psprite_property;
transform.base.transform_immediate = psprite_immediate;
transform.base.prolog = psprite_prolog;
transform.point_size_in = INVALID_INDEX;
transform.point_size_out = INVALID_INDEX;
transform.point_size_tmp = INVALID_INDEX;
transform.point_pos_in = INVALID_INDEX;
transform.point_pos_out = INVALID_INDEX;
transform.point_pos_sout = INVALID_INDEX;
transform.point_pos_tmp = INVALID_INDEX;
transform.point_scale_tmp = INVALID_INDEX;
transform.point_imm = INVALID_INDEX;
transform.point_coord_aa = INVALID_INDEX;
transform.point_coord_k = INVALID_INDEX;
transform.stream_out_point_pos = stream_out_point_pos;
transform.point_coord_enable = point_coord_enable;
transform.aa_point = aa_point_coord_index != NULL;
transform.max_generic = -1;
/* point sprite directions based on the immediates (0, 1, 0.5, -1) */
/* (-1, -1, 0, 0) */
transform.point_dir_swz[0] = set_swizzle(-1, -1, 0, 0);
/* (-1, 1, 0, 0) */
transform.point_dir_swz[1] = set_swizzle(-1, 1, 0, 0);
/* (1, -1, 0, 0) */
transform.point_dir_swz[2] = set_swizzle(1, -1, 0, 0);
/* (1, 1, 0, 0) */
transform.point_dir_swz[3] = set_swizzle(1, 1, 0, 0);
/* point coord based on the immediates (0, 1, 0, -1) */
if (sprite_origin_lower_left) {
/* (0, 0, 0, 1) */
transform.point_coord_swz[0] = set_swizzle(0, 0, 0, 1);
/* (0, 1, 0, 1) */
transform.point_coord_swz[1] = set_swizzle(0, 1, 0, 1);
/* (1, 0, 0, 1) */
transform.point_coord_swz[2] = set_swizzle(1, 0, 0, 1);
/* (1, 1, 0, 1) */
transform.point_coord_swz[3] = set_swizzle(1, 1, 0, 1);
}
else {
/* (0, 1, 0, 1) */
transform.point_coord_swz[0] = set_swizzle(0, 1, 0, 1);
/* (0, 0, 0, 1) */
transform.point_coord_swz[1] = set_swizzle(0, 0, 0, 1);
/* (1, 1, 0, 1) */
transform.point_coord_swz[2] = set_swizzle(1, 1, 0, 1);
/* (1, 0, 0, 1) */
transform.point_coord_swz[3] = set_swizzle(1, 0, 0, 1);
}
/* allocate new tokens buffer */
new_tokens = tgsi_alloc_tokens(new_len);
if (!new_tokens)
return NULL;
/* transform the shader */
tgsi_transform_shader(tokens_in, new_tokens, new_len, &transform.base);
if (aa_point_coord_index)
*aa_point_coord_index = transform.point_coord_aa;
return new_tokens;
}
@@ -0,0 +1,38 @@
/*
* Copyright 2014 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL THE 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.
*/
#ifndef TGSI_POINT_SPRITE_H
#define TGSI_POINT_SPRITE_H
struct tgsi_token;
struct tgsi_token *
tgsi_add_point_sprite(const struct tgsi_token *tokens_in,
const unsigned point_coord_enable,
const bool sprite_origin_lower_left,
const bool stream_out_point_pos,
int *aa_point_coord_index);
#endif /* TGSI_POINT_SPRITE_H */
+20
View File
@@ -56,6 +56,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
{
uint procType, i;
struct tgsi_parse_context parse;
unsigned current_depth = 0;
memset(info, 0, sizeof(*info));
for (i = 0; i < TGSI_FILE_COUNT; i++)
@@ -100,6 +101,25 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
assert(fullinst->Instruction.Opcode < TGSI_OPCODE_LAST);
info->opcode_count[fullinst->Instruction.Opcode]++;
switch (fullinst->Instruction.Opcode) {
case TGSI_OPCODE_IF:
case TGSI_OPCODE_UIF:
case TGSI_OPCODE_BGNLOOP:
current_depth++;
info->max_depth = MAX2(info->max_depth, current_depth);
break;
case TGSI_OPCODE_ENDIF:
case TGSI_OPCODE_ENDLOOP:
current_depth--;
break;
default:
break;
}
if (fullinst->Instruction.Opcode >= TGSI_OPCODE_F2D &&
fullinst->Instruction.Opcode <= TGSI_OPCODE_DSSG)
info->uses_doubles = true;
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *src =
&fullinst->Src[i];
+6 -1
View File
@@ -95,7 +95,7 @@ struct tgsi_shader_info
boolean writes_viewport_index;
boolean writes_layer;
boolean is_msaa_sampler[PIPE_MAX_SAMPLERS];
boolean uses_doubles; /**< uses any of the double instructions */
unsigned clipdist_writemask;
unsigned culldist_writemask;
unsigned num_written_culldistance;
@@ -113,6 +113,11 @@ struct tgsi_shader_info
unsigned indirect_files_written;
unsigned properties[TGSI_PROPERTY_COUNT]; /* index with TGSI_PROPERTY_ */
/**
* Max nesting limit of loops/if's
*/
unsigned max_depth;
};
extern void
+68 -6
View File
@@ -95,19 +95,38 @@ struct tgsi_transform_context
* Helper for emitting temporary register declarations.
*/
static inline void
tgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
unsigned index)
tgsi_transform_temps_decl(struct tgsi_transform_context *ctx,
unsigned firstIdx, unsigned lastIdx)
{
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
decl.Range.First =
decl.Range.Last = index;
decl.Range.First = firstIdx;
decl.Range.Last = lastIdx;
ctx->emit_declaration(ctx, &decl);
}
static inline void
tgsi_transform_temp_decl(struct tgsi_transform_context *ctx,
unsigned index)
{
tgsi_transform_temps_decl(ctx, index, index);
}
static inline void
tgsi_transform_const_decl(struct tgsi_transform_context *ctx,
unsigned firstIdx, unsigned lastIdx)
{
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_CONSTANT;
decl.Range.First = firstIdx;
decl.Range.Last = lastIdx;
ctx->emit_declaration(ctx, &decl);
}
static inline void
tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
unsigned index,
@@ -129,6 +148,26 @@ tgsi_transform_input_decl(struct tgsi_transform_context *ctx,
ctx->emit_declaration(ctx, &decl);
}
static inline void
tgsi_transform_output_decl(struct tgsi_transform_context *ctx,
unsigned index,
unsigned sem_name, unsigned sem_index,
unsigned interp)
{
struct tgsi_full_declaration decl;
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_OUTPUT;
decl.Declaration.Interpolate = 1;
decl.Declaration.Semantic = 1;
decl.Semantic.Name = sem_name;
decl.Semantic.Index = sem_index;
decl.Range.First =
decl.Range.Last = index;
decl.Interp.Interpolate = interp;
ctx->emit_declaration(ctx, &decl);
}
static inline void
tgsi_transform_sampler_decl(struct tgsi_transform_context *ctx,
@@ -182,6 +221,28 @@ tgsi_transform_immediate_decl(struct tgsi_transform_context *ctx,
ctx->emit_immediate(ctx, &immed);
}
static inline void
tgsi_transform_dst_reg(struct tgsi_full_dst_register *reg,
unsigned file, unsigned index, unsigned writemask)
{
reg->Register.File = file;
reg->Register.Index = index;
reg->Register.WriteMask = writemask;
}
static inline void
tgsi_transform_src_reg(struct tgsi_full_src_register *reg,
unsigned file, unsigned index,
unsigned swizzleX, unsigned swizzleY,
unsigned swizzleZ, unsigned swizzleW)
{
reg->Register.File = file;
reg->Register.Index = index;
reg->Register.SwizzleX = swizzleX;
reg->Register.SwizzleY = swizzleY;
reg->Register.SwizzleZ = swizzleZ;
reg->Register.SwizzleW = swizzleW;
}
/**
* Helper for emitting 1-operand instructions.
@@ -399,7 +460,8 @@ static inline void
tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
unsigned src_file,
unsigned src_index,
unsigned src_swizzle)
unsigned src_swizzle,
boolean negate)
{
struct tgsi_full_instruction inst;
@@ -413,7 +475,7 @@ tgsi_transform_kill_inst(struct tgsi_transform_context *ctx,
inst.Src[0].Register.SwizzleY =
inst.Src[0].Register.SwizzleZ =
inst.Src[0].Register.SwizzleW = src_swizzle;
inst.Src[0].Register.Negate = 1;
inst.Src[0].Register.Negate = negate;
ctx->emit_instruction(ctx, &inst);
}
+228
View File
@@ -0,0 +1,228 @@
/*
* Copyright 2013 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL THE 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.
*/
/**
* This utility transforms fragment shaders to facilitate two-sided lighting.
*
* Basically, if the FS has any color inputs (TGSI_SEMANTIC_COLOR) we'll:
* 1. create corresponding back-color inputs (TGSI_SEMANTIC_BCOLOR)
* 2. use the FACE register to choose between front/back colors and put the
* selected color in new temp regs.
* 3. replace reads of the original color inputs with the new temp regs.
*
* Then, the driver just needs to link the VS front/back output colors to
* the FS front/back input colors.
*/
#include "util/u_debug.h"
#include "util/u_math.h"
#include "tgsi_info.h"
#include "tgsi_two_side.h"
#include "tgsi_transform.h"
#define INVALID_INDEX 9999
struct two_side_transform_context
{
struct tgsi_transform_context base;
uint num_temps;
uint num_inputs;
uint face_input; /**< index of the FACE input */
uint front_color_input[2]; /**< INPUT regs */
uint front_color_interp[2];/**< TGSI_INTERPOLATE_x */
uint back_color_input[2]; /**< INPUT regs */
uint new_colors[2]; /**< TEMP regs */
};
static inline struct two_side_transform_context *
two_side_transform_context(struct tgsi_transform_context *ctx)
{
return (struct two_side_transform_context *) ctx;
}
static void
xform_decl(struct tgsi_transform_context *ctx,
struct tgsi_full_declaration *decl)
{
struct two_side_transform_context *ts = two_side_transform_context(ctx);
if (decl->Declaration.File == TGSI_FILE_INPUT) {
if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR) {
/* found a front color */
assert(decl->Semantic.Index < 2);
ts->front_color_input[decl->Semantic.Index] = decl->Range.First;
ts->front_color_interp[decl->Semantic.Index] = decl->Interp.Interpolate;
}
else if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) {
ts->face_input = decl->Range.First;
}
ts->num_inputs = MAX2(ts->num_inputs, decl->Range.Last + 1);
}
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
ts->num_temps = MAX2(ts->num_temps, decl->Range.Last + 1);
}
ctx->emit_declaration(ctx, decl);
}
static void
emit_prolog(struct tgsi_transform_context *ctx)
{
struct two_side_transform_context *ts = two_side_transform_context(ctx);
struct tgsi_full_declaration decl;
struct tgsi_full_instruction inst;
uint num_colors = 0;
uint i;
/* Declare 0, 1 or 2 new BCOLOR inputs */
for (i = 0; i < 2; i++) {
if (ts->front_color_input[i] != INVALID_INDEX) {
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Interpolate = 1;
decl.Declaration.Semantic = 1;
decl.Semantic.Name = TGSI_SEMANTIC_BCOLOR;
decl.Semantic.Index = i;
decl.Range.First = decl.Range.Last = ts->num_inputs++;
decl.Interp.Interpolate = ts->front_color_interp[i];
ctx->emit_declaration(ctx, &decl);
ts->back_color_input[i] = decl.Range.First;
num_colors++;
}
}
if (num_colors > 0) {
/* Declare 1 or 2 temp registers */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_TEMPORARY;
decl.Range.First = ts->num_temps;
decl.Range.Last = ts->num_temps + num_colors - 1;
ctx->emit_declaration(ctx, &decl);
ts->new_colors[0] = ts->num_temps;
ts->new_colors[1] = ts->num_temps + 1;
if (ts->face_input == INVALID_INDEX) {
/* declare FACE INPUT register */
decl = tgsi_default_full_declaration();
decl.Declaration.File = TGSI_FILE_INPUT;
decl.Declaration.Semantic = 1;
decl.Semantic.Name = TGSI_SEMANTIC_FACE;
decl.Semantic.Index = 0;
decl.Range.First = decl.Range.Last = ts->num_inputs++;
ctx->emit_declaration(ctx, &decl);
ts->face_input = decl.Range.First;
}
/* CMP temp[c0], face, bcolor[c0], fcolor[c0]
* temp[c0] = face < 0.0 ? bcolor[c0] : fcolor[c0]
*/
for (i = 0; i < 2; i++) {
if (ts->front_color_input[i] != INVALID_INDEX) {
inst = tgsi_default_full_instruction();
inst.Instruction.Opcode = TGSI_OPCODE_CMP;
inst.Instruction.NumDstRegs = 1;
inst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
inst.Dst[0].Register.Index = ts->new_colors[i];
inst.Instruction.NumSrcRegs = 3;
inst.Src[0].Register.File = TGSI_FILE_INPUT;
inst.Src[0].Register.Index = ts->face_input;
inst.Src[1].Register.File = TGSI_FILE_INPUT;
inst.Src[1].Register.Index = ts->back_color_input[i];
inst.Src[2].Register.File = TGSI_FILE_INPUT;
inst.Src[2].Register.Index = ts->front_color_input[i];
ctx->emit_instruction(ctx, &inst);
}
}
}
}
static void
xform_inst(struct tgsi_transform_context *ctx,
struct tgsi_full_instruction *inst)
{
struct two_side_transform_context *ts = two_side_transform_context(ctx);
const struct tgsi_opcode_info *info =
tgsi_get_opcode_info(inst->Instruction.Opcode);
uint i, j;
/* Look for src regs which reference the input color and replace
* them with the temp color.
*/
for (i = 0; i < info->num_src; i++) {
if (inst->Src[i].Register.File == TGSI_FILE_INPUT) {
for (j = 0; j < 2; j++) {
if (inst->Src[i].Register.Index == ts->front_color_input[j]) {
/* replace color input with temp reg */
inst->Src[i].Register.File = TGSI_FILE_TEMPORARY;
inst->Src[i].Register.Index = ts->new_colors[j];
break;
}
}
}
}
ctx->emit_instruction(ctx, inst);
}
struct tgsi_token *
tgsi_add_two_side(const struct tgsi_token *tokens_in)
{
struct two_side_transform_context transform;
const uint num_new_tokens = 100; /* should be enough */
const uint new_len = tgsi_num_tokens(tokens_in) + num_new_tokens;
struct tgsi_token *new_tokens;
/* setup transformation context */
memset(&transform, 0, sizeof(transform));
transform.base.transform_declaration = xform_decl;
transform.base.transform_instruction = xform_inst;
transform.base.prolog = emit_prolog;
transform.face_input = INVALID_INDEX;
transform.front_color_input[0] = INVALID_INDEX;
transform.front_color_input[1] = INVALID_INDEX;
transform.front_color_interp[0] = TGSI_INTERPOLATE_COLOR;
transform.front_color_interp[1] = TGSI_INTERPOLATE_COLOR;
transform.back_color_input[0] = INVALID_INDEX;
transform.back_color_input[1] = INVALID_INDEX;
/* allocate new tokens buffer */
new_tokens = tgsi_alloc_tokens(new_len);
if (!new_tokens)
return NULL;
/* transform the shader */
tgsi_transform_shader(tokens_in, new_tokens, new_len, &transform.base);
return new_tokens;
}
@@ -0,0 +1,34 @@
/*
* Copyright 2013 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL THE 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.
*/
#ifndef TGSI_TWO_SIDE_H
#define TGSI_TWO_SIDE_H
struct tgsi_token;
struct tgsi_token *
tgsi_add_two_side(const struct tgsi_token *tokens_in);
#endif /* TGSI_TWO_SIDE_H */
+18
View File
@@ -462,3 +462,21 @@ tgsi_util_get_texture_coord_dim(int tgsi_tex, int *shadow_or_sample)
return dim;
}
boolean
tgsi_is_shadow_target(unsigned target)
{
switch (target) {
case TGSI_TEXTURE_SHADOW1D:
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_SHADOW1D_ARRAY:
case TGSI_TEXTURE_SHADOW2D_ARRAY:
case TGSI_TEXTURE_SHADOWCUBE:
case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
return TRUE;
default:
return FALSE;
}
}
+3
View File
@@ -82,6 +82,9 @@ tgsi_util_get_src_from_ind(const struct tgsi_ind_register *reg);
int
tgsi_util_get_texture_coord_dim(int tgsi_tex, int *shadow_or_sample);
boolean
tgsi_is_shadow_target(unsigned target);
#if defined __cplusplus
}
#endif
+7 -1
View File
@@ -1190,6 +1190,8 @@ static void blitter_draw(struct blitter_context_priv *ctx,
u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices,
&vb.buffer_offset, &vb.buffer);
if (!vb.buffer)
return;
u_upload_unmap(ctx->upload);
pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb);
@@ -2063,7 +2065,7 @@ void util_blitter_clear_buffer(struct blitter_context *blitter,
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
struct pipe_vertex_buffer vb = {0};
struct pipe_stream_output_target *so_target;
struct pipe_stream_output_target *so_target = NULL;
unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0};
assert(num_channels >= 1);
@@ -2089,6 +2091,9 @@ void util_blitter_clear_buffer(struct blitter_context *blitter,
u_upload_data(ctx->upload, 0, num_channels*4, clear_value,
&vb.buffer_offset, &vb.buffer);
if (!vb.buffer)
goto out;
vb.stride = 0;
blitter_set_running_flag(ctx);
@@ -2112,6 +2117,7 @@ void util_blitter_clear_buffer(struct blitter_context *blitter,
util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4);
out:
blitter_restore_vertex_states(ctx);
blitter_restore_render_cond(ctx);
blitter_unset_running_flag(ctx);
+15
View File
@@ -88,3 +88,18 @@ void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
*dst_count = util_last_bit(enabled_buffers);
}
void
util_set_index_buffer(struct pipe_index_buffer *dst,
const struct pipe_index_buffer *src)
{
if (src) {
pipe_resource_reference(&dst->buffer, src->buffer);
memcpy(dst, src, sizeof(*dst));
}
else {
pipe_resource_reference(&dst->buffer, NULL);
memset(dst, 0, sizeof(*dst));
}
}
+3
View File
@@ -44,6 +44,9 @@ void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst,
const struct pipe_vertex_buffer *src,
unsigned start_slot, unsigned count);
void util_set_index_buffer(struct pipe_index_buffer *dst,
const struct pipe_index_buffer *src);
#ifdef __cplusplus
}
#endif
+40
View File
@@ -389,6 +389,26 @@ unsigned ffs( unsigned u )
#define ffs __builtin_ffs
#endif
#ifdef HAVE___BUILTIN_FFSLL
#define ffsll __builtin_ffsll
#else
static inline int
ffsll(long long int val)
{
int bit;
bit = ffs((unsigned) (val & 0xffffffff));
if (bit != 0)
return bit;
bit = ffs((unsigned) (val >> 32));
if (bit != 0)
return 32 + bit;
return 0;
}
#endif
#endif /* FFS_DEFINED */
/**
@@ -483,6 +503,26 @@ u_bit_scan64(uint64_t *mask)
}
#endif
/* For looping over a bitmask when you want to loop over consecutive bits
* manually, for example:
*
* while (mask) {
* int start, count, i;
*
* u_bit_scan_consecutive_range(&mask, &start, &count);
*
* for (i = 0; i < count; i++)
* ... process element (start+i)
* }
*/
static inline void
u_bit_scan_consecutive_range(unsigned *mask, int *start, int *count)
{
*start = ffs(*mask) - 1;
*count = ffs(~(*mask >> *start)) - 1;
*mask &= ~(((1 << *count) - 1) << *start);
}
/**
* Return float bits.
*/
+267
View File
@@ -0,0 +1,267 @@
/*
* Copyright 2014 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "u_inlines.h"
#include "u_memory.h"
#include "u_prim_restart.h"
/**
* Translate an index buffer for primitive restart.
* Create a new index buffer which is a copy of the original index buffer
* except that instances of 'restart_index' are converted to 0xffff or
* 0xffffffff.
* Also, index buffers using 1-byte indexes are converted to 2-byte indexes.
*/
enum pipe_error
util_translate_prim_restart_ib(struct pipe_context *context,
struct pipe_index_buffer *src_buffer,
struct pipe_resource **dst_buffer,
unsigned num_indexes,
unsigned restart_index)
{
struct pipe_screen *screen = context->screen;
struct pipe_transfer *src_transfer = NULL, *dst_transfer = NULL;
void *src_map = NULL, *dst_map = NULL;
const unsigned src_index_size = src_buffer->index_size;
unsigned dst_index_size;
/* 1-byte indexes are converted to 2-byte indexes, 4-byte stays 4-byte */
dst_index_size = MAX2(2, src_buffer->index_size);
assert(dst_index_size == 2 || dst_index_size == 4);
/* no user buffers for now */
assert(src_buffer->user_buffer == NULL);
/* Create new index buffer */
*dst_buffer = pipe_buffer_create(screen, PIPE_BIND_INDEX_BUFFER,
PIPE_USAGE_STREAM,
num_indexes * dst_index_size);
if (!*dst_buffer)
goto error;
/* Map new / dest index buffer */
dst_map = pipe_buffer_map(context, *dst_buffer,
PIPE_TRANSFER_WRITE, &dst_transfer);
if (!dst_map)
goto error;
/* Map original / src index buffer */
src_map = pipe_buffer_map_range(context, src_buffer->buffer,
src_buffer->offset,
num_indexes * src_index_size,
PIPE_TRANSFER_READ,
&src_transfer);
if (!src_map)
goto error;
if (src_index_size == 1 && dst_index_size == 2) {
uint8_t *src = (uint8_t *) src_map;
uint16_t *dst = (uint16_t *) dst_map;
unsigned i;
for (i = 0; i < num_indexes; i++) {
dst[i] = (src[i] == restart_index) ? 0xffff : src[i];
}
}
else if (src_index_size == 2 && dst_index_size == 2) {
uint16_t *src = (uint16_t *) src_map;
uint16_t *dst = (uint16_t *) dst_map;
unsigned i;
for (i = 0; i < num_indexes; i++) {
dst[i] = (src[i] == restart_index) ? 0xffff : src[i];
}
}
else {
uint32_t *src = (uint32_t *) src_map;
uint32_t *dst = (uint32_t *) dst_map;
unsigned i;
assert(src_index_size == 4);
assert(dst_index_size == 4);
for (i = 0; i < num_indexes; i++) {
dst[i] = (src[i] == restart_index) ? 0xffffffff : src[i];
}
}
pipe_buffer_unmap(context, src_transfer);
pipe_buffer_unmap(context, dst_transfer);
return PIPE_OK;
error:
if (src_transfer)
pipe_buffer_unmap(context, src_transfer);
if (dst_transfer)
pipe_buffer_unmap(context, dst_transfer);
if (*dst_buffer)
screen->resource_destroy(screen, *dst_buffer);
return PIPE_ERROR_OUT_OF_MEMORY;
}
/** Helper structs for util_draw_vbo_without_prim_restart() */
struct range {
unsigned start, count;
};
struct range_info {
struct range *ranges;
unsigned count, max;
};
/**
* Helper function for util_draw_vbo_without_prim_restart()
* \return true for success, false if out of memory
*/
static boolean
add_range(struct range_info *info, unsigned start, unsigned count)
{
if (info->max == 0) {
info->max = 10;
info->ranges = MALLOC(info->max * sizeof(struct range));
if (!info->ranges) {
return FALSE;
}
}
else if (info->count == info->max) {
/* grow the ranges[] array */
info->ranges = REALLOC(info->ranges,
info->max * sizeof(struct range),
2 * info->max * sizeof(struct range));
if (!info->ranges) {
return FALSE;
}
info->max *= 2;
}
/* save the range */
info->ranges[info->count].start = start;
info->ranges[info->count].count = count;
info->count++;
return TRUE;
}
/**
* Implement primitive restart by breaking an indexed primitive into
* pieces which do not contain restart indexes. Each piece is then
* drawn by calling pipe_context::draw_vbo().
* \return PIPE_OK if no error, an error code otherwise.
*/
enum pipe_error
util_draw_vbo_without_prim_restart(struct pipe_context *context,
const struct pipe_index_buffer *ib,
const struct pipe_draw_info *info)
{
const void *src_map;
struct range_info ranges = {0};
struct pipe_draw_info new_info;
struct pipe_transfer *src_transfer = NULL;
unsigned i, start, count;
assert(info->indexed);
assert(info->primitive_restart);
/* Get pointer to the index data */
if (ib->buffer) {
/* map the index buffer (only the range we need to scan) */
src_map = pipe_buffer_map_range(context, ib->buffer,
ib->offset + info->start * ib->index_size,
info->count * ib->index_size,
PIPE_TRANSFER_READ,
&src_transfer);
if (!src_map) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
}
else {
if (!ib->user_buffer) {
debug_printf("User-space index buffer is null!");
return PIPE_ERROR_BAD_INPUT;
}
src_map = (const uint8_t *) ib->user_buffer
+ ib->offset
+ info->start * ib->index_size;
}
#define SCAN_INDEXES(TYPE) \
for (i = 0; i <= info->count; i++) { \
if (i == info->count || \
((const TYPE *) src_map)[i] == info->restart_index) { \
/* cut / restart */ \
if (count > 0) { \
if (!add_range(&ranges, info->start + start, count)) { \
if (src_transfer) \
pipe_buffer_unmap(context, src_transfer); \
return PIPE_ERROR_OUT_OF_MEMORY; \
} \
} \
start = i + 1; \
count = 0; \
} \
else { \
count++; \
} \
}
start = info->start;
count = 0;
switch (ib->index_size) {
case 1:
SCAN_INDEXES(uint8_t);
break;
case 2:
SCAN_INDEXES(uint16_t);
break;
case 4:
SCAN_INDEXES(uint32_t);
break;
default:
assert(!"Bad index size");
return PIPE_ERROR_BAD_INPUT;
}
/* unmap index buffer */
if (src_transfer)
pipe_buffer_unmap(context, src_transfer);
/* draw ranges between the restart indexes */
new_info = *info;
new_info.primitive_restart = FALSE;
for (i = 0; i < ranges.count; i++) {
new_info.start = ranges.ranges[i].start;
new_info.count = ranges.ranges[i].count;
context->draw_vbo(context, &new_info);
}
FREE(ranges.ranges);
return PIPE_OK;
}
@@ -0,0 +1,62 @@
/*
* Copyright 2014 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef U_PRIM_RESTART_H
#define U_PRIM_RESTART_H
#include "pipe/p_defines.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pipe_context;
struct pipe_draw_info;
struct pipe_index_buffer;
struct pipe_resource;
enum pipe_error
util_translate_prim_restart_ib(struct pipe_context *context,
struct pipe_index_buffer *src_buffer,
struct pipe_resource **dst_buffer,
unsigned num_indexes,
unsigned restart_index);
enum pipe_error
util_draw_vbo_without_prim_restart(struct pipe_context *context,
const struct pipe_index_buffer *ib,
const struct pipe_draw_info *info);
#ifdef __cplusplus
}
#endif
#endif
+1 -1
View File
@@ -339,7 +339,7 @@ pstip_transform_prolog(struct tgsi_transform_context *ctx)
/* KILL_IF -texTemp; # if -texTemp < 0, kill fragment */
tgsi_transform_kill_inst(ctx,
TGSI_FILE_TEMPORARY, texTemp,
TGSI_SWIZZLE_W);
TGSI_SWIZZLE_W, TRUE);
}
+12 -2
View File
@@ -42,6 +42,7 @@ struct u_rect {
};
/* Do two rectangles intersect?
* Note: empty rectangles are valid as inputs (and never intersect).
*/
static inline boolean
u_rect_test_intersection(const struct u_rect *a,
@@ -50,7 +51,11 @@ u_rect_test_intersection(const struct u_rect *a,
return (!(a->x1 < b->x0 ||
b->x1 < a->x0 ||
a->y1 < b->y0 ||
b->y1 < a->y0));
b->y1 < a->y0 ||
a->x1 < a->x0 ||
a->y1 < a->y0 ||
b->x1 < b->x0 ||
b->y1 < b->y0));
}
/* Find the intersection of two rectangles known to intersect.
@@ -82,7 +87,12 @@ u_rect_possible_intersection(const struct u_rect *a,
u_rect_find_intersection(a,b);
}
else {
b->x0 = b->x1 = b->y0 = b->y1 = 0;
/*
* Note the u_rect_xx tests deal with inclusive coordinates
* hence all-zero would not be an empty box.
*/
b->x0 = b->y0 = 0;
b->x1 = b->y1 = -1;
}
}
@@ -831,3 +831,54 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
return ureg_create_shader_and_destroy(ureg, pipe);
}
void *
util_make_geometry_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
const ubyte *semantic_names,
const ubyte *semantic_indexes)
{
static const unsigned zero[4] = {0, 0, 0, 0};
struct ureg_program *ureg;
struct ureg_dst dst[PIPE_MAX_SHADER_OUTPUTS];
struct ureg_src src[PIPE_MAX_SHADER_INPUTS];
struct ureg_src imm;
unsigned i;
ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY);
if (ureg == NULL)
return NULL;
ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_POINTS);
ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_POINTS);
ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 1);
ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, 1);
imm = ureg_DECL_immediate_uint(ureg, zero, 4);
/**
* Loop over all the attribs and declare the corresponding
* declarations in the geometry shader
*/
for (i = 0; i < num_attribs; i++) {
src[i] = ureg_DECL_input(ureg, semantic_names[i],
semantic_indexes[i], 0, 1);
src[i] = ureg_src_dimension(src[i], 0);
dst[i] = ureg_DECL_output(ureg, semantic_names[i], semantic_indexes[i]);
}
/* MOV dst[i] src[i] */
for (i = 0; i < num_attribs; i++) {
ureg_MOV(ureg, dst[i], src[i]);
}
/* EMIT IMM[0] */
ureg_insn(ureg, TGSI_OPCODE_EMIT, NULL, 0, &imm, 1);
/* END */
ureg_END(ureg);
return ureg_create_shader_and_destroy(ureg, pipe);
}
@@ -146,6 +146,12 @@ util_make_fs_msaa_resolve_bilinear(struct pipe_context *pipe,
unsigned tgsi_tex, unsigned nr_samples,
enum tgsi_return_type stype);
extern void *
util_make_geometry_passthrough_shader(struct pipe_context *pipe,
uint num_attribs,
const ubyte *semantic_names,
const ubyte *semantic_indexes);
#ifdef __cplusplus
}
#endif
+3
View File
@@ -199,6 +199,8 @@ util_memmove(void *dest, const void *src, size_t n)
}
#define util_strcasecmp stricmp
#else
#define util_vsnprintf vsnprintf
@@ -211,6 +213,7 @@ util_memmove(void *dest, const void *src, size_t n)
#define util_strncat strncat
#define util_strstr strstr
#define util_memmove memmove
#define util_strcasecmp strcasecmp
#endif
+56 -71
View File
@@ -129,9 +129,9 @@ void u_upload_destroy( struct u_upload_mgr *upload )
}
static enum pipe_error
u_upload_alloc_buffer( struct u_upload_mgr *upload,
unsigned min_size )
static void
u_upload_alloc_buffer(struct u_upload_mgr *upload,
unsigned min_size)
{
struct pipe_screen *screen = upload->pipe->screen;
struct pipe_resource buffer;
@@ -161,9 +161,8 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
}
upload->buffer = screen->resource_create(screen, &buffer);
if (upload->buffer == NULL) {
return PIPE_ERROR_OUT_OF_MEMORY;
}
if (upload->buffer == NULL)
return;
/* Map the new buffer. */
upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
@@ -172,52 +171,54 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
if (upload->map == NULL) {
upload->transfer = NULL;
pipe_resource_reference(&upload->buffer, NULL);
return PIPE_ERROR_OUT_OF_MEMORY;
return;
}
upload->offset = 0;
return PIPE_OK;
}
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
unsigned *out_offset,
struct pipe_resource **outbuf,
void **ptr )
void
u_upload_alloc(struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
unsigned *out_offset,
struct pipe_resource **outbuf,
void **ptr)
{
unsigned alloc_size = align( size, upload->alignment );
unsigned alloc_size = align(size, upload->alignment);
unsigned alloc_offset = align(min_out_offset, upload->alignment);
unsigned buffer_size = upload->buffer ? upload->buffer->width0 : 0;
unsigned offset;
/* Init these return values here in case we fail below to make
* sure the caller doesn't get garbage values.
*/
*out_offset = ~0;
pipe_resource_reference(outbuf, NULL);
*ptr = NULL;
/* Make sure we have enough space in the upload buffer
* for the sub-allocation. */
if (!upload->buffer ||
MAX2(upload->offset, alloc_offset) + alloc_size > upload->buffer->width0) {
enum pipe_error ret = u_upload_alloc_buffer(upload,
alloc_offset + alloc_size);
if (ret != PIPE_OK)
return ret;
if (unlikely(MAX2(upload->offset, alloc_offset) + alloc_size > buffer_size)) {
u_upload_alloc_buffer(upload, alloc_offset + alloc_size);
if (unlikely(!upload->buffer)) {
*out_offset = ~0;
pipe_resource_reference(outbuf, NULL);
*ptr = NULL;
return;
}
buffer_size = upload->buffer->width0;
}
offset = MAX2(upload->offset, alloc_offset);
if (!upload->map) {
if (unlikely(!upload->map)) {
upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
offset,
upload->buffer->width0 - offset,
buffer_size - offset,
upload->map_flags,
&upload->transfer);
if (!upload->map) {
if (unlikely(!upload->map)) {
upload->transfer = NULL;
return PIPE_ERROR_OUT_OF_MEMORY;
*out_offset = ~0;
pipe_resource_reference(outbuf, NULL);
*ptr = NULL;
return;
}
upload->map -= offset;
@@ -229,46 +230,37 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
/* Emit the return values: */
*ptr = upload->map + offset;
pipe_resource_reference( outbuf, upload->buffer );
pipe_resource_reference(outbuf, upload->buffer);
*out_offset = offset;
upload->offset = offset + alloc_size;
return PIPE_OK;
}
enum pipe_error u_upload_data( struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
const void *data,
unsigned *out_offset,
struct pipe_resource **outbuf)
void u_upload_data(struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
const void *data,
unsigned *out_offset,
struct pipe_resource **outbuf)
{
uint8_t *ptr;
enum pipe_error ret = u_upload_alloc(upload, min_out_offset, size,
out_offset, outbuf,
(void**)&ptr);
if (ret != PIPE_OK)
return ret;
memcpy(ptr, data, size);
return PIPE_OK;
u_upload_alloc(upload, min_out_offset, size,
out_offset, outbuf,
(void**)&ptr);
if (ptr)
memcpy(ptr, data, size);
}
/* As above, but upload the full contents of a buffer. Useful for
* uploading user buffers, avoids generating an explosion of GPU
* buffers if you have an app that does lots of small vertex buffer
* renders or DrawElements calls.
*/
enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned offset,
unsigned size,
struct pipe_resource *inbuf,
unsigned *out_offset,
struct pipe_resource **outbuf)
/* XXX: Remove. It's basically a CPU fallback of resource_copy_region. */
void u_upload_buffer(struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned offset,
unsigned size,
struct pipe_resource *inbuf,
unsigned *out_offset,
struct pipe_resource **outbuf)
{
enum pipe_error ret = PIPE_OK;
struct pipe_transfer *transfer = NULL;
const char *map = NULL;
@@ -279,20 +271,13 @@ enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
&transfer);
if (map == NULL) {
return PIPE_ERROR_OUT_OF_MEMORY;
pipe_resource_reference(outbuf, NULL);
return;
}
if (0)
debug_printf("upload ptr %p ofs %d sz %d\n", map, offset, size);
ret = u_upload_data( upload,
min_out_offset,
size,
map,
out_offset,
outbuf);
u_upload_data(upload, min_out_offset, size, map, out_offset, outbuf);
pipe_buffer_unmap( upload->pipe, transfer );
return ret;
}
+19 -19
View File
@@ -78,12 +78,12 @@ void u_upload_unmap( struct u_upload_mgr *upload );
* \param outbuf Pointer to where the upload buffer will be returned.
* \param ptr Pointer to the allocated memory that is returned.
*/
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
unsigned *out_offset,
struct pipe_resource **outbuf,
void **ptr );
void u_upload_alloc(struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
unsigned *out_offset,
struct pipe_resource **outbuf,
void **ptr);
/**
@@ -92,12 +92,12 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
* Same as u_upload_alloc, but in addition to that, it copies "data"
* to the pointer returned from u_upload_alloc.
*/
enum pipe_error u_upload_data( struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
const void *data,
unsigned *out_offset,
struct pipe_resource **outbuf);
void u_upload_data(struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned size,
const void *data,
unsigned *out_offset,
struct pipe_resource **outbuf);
/**
@@ -106,13 +106,13 @@ enum pipe_error u_upload_data( struct u_upload_mgr *upload,
* Same as u_upload_data, except that the input data comes from a buffer
* instead of a user pointer.
*/
enum pipe_error u_upload_buffer( struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned offset,
unsigned size,
struct pipe_resource *inbuf,
unsigned *out_offset,
struct pipe_resource **outbuf);
void u_upload_buffer(struct u_upload_mgr *upload,
unsigned min_out_offset,
unsigned offset,
unsigned size,
struct pipe_resource *inbuf,
unsigned *out_offset,
struct pipe_resource **outbuf);
+17 -19
View File
@@ -406,7 +406,6 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
struct pipe_resource *out_buffer = NULL;
uint8_t *out_map;
unsigned out_offset, mask;
enum pipe_error err;
/* Get a translate object. */
tr = translate_cache_find(mgr->translate_cache, key);
@@ -454,12 +453,12 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
assert((ib->buffer || ib->user_buffer) && ib->index_size);
/* Create and map the output buffer. */
err = u_upload_alloc(mgr->uploader, 0,
key->output_stride * num_indices,
&out_offset, &out_buffer,
(void**)&out_map);
if (err != PIPE_OK)
return err;
u_upload_alloc(mgr->uploader, 0,
key->output_stride * num_indices,
&out_offset, &out_buffer,
(void**)&out_map);
if (!out_buffer)
return PIPE_ERROR_OUT_OF_MEMORY;
if (ib->user_buffer) {
map = (uint8_t*)ib->user_buffer + offset;
@@ -486,13 +485,13 @@ u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key,
}
} else {
/* Create and map the output buffer. */
err = u_upload_alloc(mgr->uploader,
key->output_stride * start_vertex,
key->output_stride * num_vertices,
&out_offset, &out_buffer,
(void**)&out_map);
if (err != PIPE_OK)
return err;
u_upload_alloc(mgr->uploader,
key->output_stride * start_vertex,
key->output_stride * num_vertices,
&out_offset, &out_buffer,
(void**)&out_map);
if (!out_buffer)
return PIPE_ERROR_OUT_OF_MEMORY;
out_offset -= key->output_stride * start_vertex;
@@ -977,7 +976,6 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
unsigned start, end;
struct pipe_vertex_buffer *real_vb;
const uint8_t *ptr;
enum pipe_error err;
i = u_bit_scan(&buffer_mask);
@@ -988,10 +986,10 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
real_vb = &mgr->real_vertex_buffer[i];
ptr = mgr->vertex_buffer[i].user_buffer;
err = u_upload_data(mgr->uploader, start, end - start, ptr + start,
&real_vb->buffer_offset, &real_vb->buffer);
if (err != PIPE_OK)
return err;
u_upload_data(mgr->uploader, start, end - start, ptr + start,
&real_vb->buffer_offset, &real_vb->buffer);
if (!real_vb->buffer)
return PIPE_ERROR_OUT_OF_MEMORY;
real_vb->buffer_offset -= start;
}
+1
View File
@@ -267,6 +267,7 @@ The integer capabilities:
* ``PIPE_CAP_DEPTH_BOUNDS_TEST``: Whether bounds_test, bounds_min, and
bounds_max states of pipe_depth_stencil_alpha_state behave according
to the GL_EXT_depth_bounds_test specification.
* ``PIPE_CAP_TGSI_TXQS``: Whether the `TXQS` opcode is supported
.. _pipe_capf:
+11 -1
View File
@@ -960,7 +960,6 @@ XXX doesn't look like most of the opcodes really belong here.
For components which don't return a resource dimension, their value
is undefined.
.. math::
lod = src0.x
@@ -973,6 +972,17 @@ XXX doesn't look like most of the opcodes really belong here.
dst.w = texture\_levels(unit)
.. opcode:: TXQS - Texture Samples Query
This retrieves the number of samples in the texture, and stores it
into the x component. The other components are undefined.
.. math::
dst.x = texture\_samples(unit)
.. opcode:: TG4 - Texture Gather
As per ARB_texture_gather, gathers the four texels to be used in a bi-linear
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63915 bytes, from 2015-08-24 16:56:28)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12)
Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
+19 -4
View File
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63915 bytes, from 2015-08-24 16:56:28)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12)
Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -280,6 +280,8 @@ enum a3xx_rb_blend_opcode {
enum a3xx_intp_mode {
SMOOTH = 0,
FLAT = 1,
ZERO = 2,
ONE = 3,
};
enum a3xx_repl_mode {
@@ -684,6 +686,12 @@ static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460
#define A3XX_GRAS_CL_CLIP_CNTL_ZCOORD 0x00800000
#define A3XX_GRAS_CL_CLIP_CNTL_WCOORD 0x01000000
#define A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE 0x02000000
#define A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__MASK 0x1c000000
#define A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__SHIFT 26
static inline uint32_t A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES(uint32_t val)
{
return ((val) << A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__SHIFT) & A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__MASK;
}
#define REG_A3XX_GRAS_CL_GB_CLIP_ADJ 0x00002044
#define A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK 0x000003ff
@@ -774,7 +782,7 @@ static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val)
#define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT 0
static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val)
{
return ((((int32_t)(val * 16384.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK;
return ((((int32_t)(val * 1048576.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK;
}
#define REG_A3XX_GRAS_SU_POLY_OFFSET_OFFSET 0x0000206d
@@ -895,6 +903,9 @@ static inline uint32_t A3XX_RB_MODE_CONTROL_MRT(uint32_t val)
#define A3XX_RB_MODE_CONTROL_PACKER_TIMER_ENABLE 0x00010000
#define REG_A3XX_RB_RENDER_CONTROL 0x000020c1
#define A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE 0x00000001
#define A3XX_RB_RENDER_CONTROL_YUV_IN_ENABLE 0x00000002
#define A3XX_RB_RENDER_CONTROL_COV_VALUE_INPUT_ENABLE 0x00000004
#define A3XX_RB_RENDER_CONTROL_FACENESS 0x00000008
#define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__MASK 0x00000ff0
#define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__SHIFT 4
@@ -908,6 +919,8 @@ static inline uint32_t A3XX_RB_RENDER_CONTROL_BIN_WIDTH(uint32_t val)
#define A3XX_RB_RENDER_CONTROL_YCOORD 0x00008000
#define A3XX_RB_RENDER_CONTROL_ZCOORD 0x00010000
#define A3XX_RB_RENDER_CONTROL_WCOORD 0x00020000
#define A3XX_RB_RENDER_CONTROL_I_CLAMP_ENABLE 0x00080000
#define A3XX_RB_RENDER_CONTROL_COV_VALUE_OUTPUT_ENABLE 0x00100000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST 0x00400000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK 0x07000000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT 24
@@ -915,6 +928,8 @@ static inline uint32_t A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(enum adreno_compar
{
return ((val) << A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT) & A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK;
}
#define A3XX_RB_RENDER_CONTROL_ALPHA_TO_COVERAGE 0x40000000
#define A3XX_RB_RENDER_CONTROL_ALPHA_TO_ONE 0x80000000
#define REG_A3XX_RB_MSAA_CONTROL 0x000020c2
#define A3XX_RB_MSAA_CONTROL_DISABLE 0x00000400
@@ -28,6 +28,7 @@
#include "pipe/p_state.h"
#include "util/u_blend.h"
#include "util/u_dual_blend.h"
#include "util/u_string.h"
#include "util/u_memory.h"
@@ -131,5 +132,8 @@ fd3_blend_state_create(struct pipe_context *pctx,
so->rb_mrt[i].control |= A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_ALWAYS);
}
if (cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0))
so->rb_render_control = A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE;
return so;
}
@@ -36,6 +36,7 @@
struct fd3_blend_stateobj {
struct pipe_blend_state base;
uint32_t rb_render_control;
struct {
/* Blend control bits for color if there is an alpha channel */
uint32_t blend_control_rgb;
@@ -73,22 +73,6 @@ struct fd3_context {
*/
struct fd_vertex_state blit_vbuf_state;
/*
* Border color layout *appears* to be as arrays of 0x40 byte
* elements, with frag shader elements starting at (16 x 0x40).
* But at some point I should probably experiment more with
* samplers in vertex shaders to be sure. Unclear about why
* there is this offset when there are separate VS and FS base
* addr regs.
*
* The first 8 bytes of each entry are the requested border
* color in fp16. Unclear about the rest.. could be used for
* other formats, or could simply be for aligning the pitch
* to 32 pixels.
*/
#define BORDERCOLOR_SIZE 0x40
struct u_upload_mgr *border_color_uploader;
struct pipe_resource *border_color_buf;
+35 -65
View File
@@ -149,6 +149,8 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
&fd3_ctx->border_color_buf,
&ptr);
fd_setup_border_colors(tex, ptr, tex_off[sb]);
if (tex->num_samplers > 0) {
/* output sampler state: */
OUT_PKT3(ring, CP_LOAD_STATE, 2 + (2 * tex->num_samplers));
@@ -163,57 +165,6 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
const struct fd3_sampler_stateobj *sampler = tex->samplers[i] ?
fd3_sampler_stateobj(tex->samplers[i]) :
&dummy_sampler;
uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
(BORDERCOLOR_SIZE * tex_off[sb]) +
(BORDERCOLOR_SIZE * i));
uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
/*
* XXX HACK ALERT XXX
*
* The border colors need to be swizzled in a particular
* format-dependent order. Even though samplers don't know about
* formats, we can assume that with a GL state tracker, there's a
* 1:1 correspondence between sampler and texture. Take advantage
* of that knowledge.
*/
if (i < tex->num_textures && tex->textures[i]) {
const struct util_format_description *desc =
util_format_description(tex->textures[i]->format);
for (j = 0; j < 4; j++) {
if (desc->swizzle[j] >= 4)
continue;
const struct util_format_channel_description *chan =
&desc->channel[desc->swizzle[j]];
int size = chan->size;
/* The Z16 texture format we use seems to look in the
* 32-bit border color slots
*/
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
size = 32;
/* Formats like R11G11B10 or RGB9_E5 don't specify
* per-channel sizes properly.
*/
if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
size = 16;
if (chan->pure_integer && size > 16)
bcolor32[desc->swizzle[j] + 4] =
sampler->base.border_color.i[j];
else if (size > 16)
bcolor32[desc->swizzle[j]] =
fui(sampler->base.border_color.f[j]);
else if (chan->pure_integer)
bcolor[desc->swizzle[j] + 8] =
sampler->base.border_color.i[j];
else
bcolor[desc->swizzle[j]] =
util_float_to_half(sampler->base.border_color.f[j]);
}
}
OUT_RING(ring, sampler->texsamp0);
OUT_RING(ring, sampler->texsamp1);
@@ -400,15 +351,27 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
unsigned vtxcnt_regid = regid(63, 0);
for (i = 0; i < vp->inputs_count; i++) {
uint8_t semantic = sem2name(vp->inputs[i].semantic);
if (semantic == TGSI_SEMANTIC_VERTEXID_NOBASE)
vertex_regid = vp->inputs[i].regid;
else if (semantic == TGSI_SEMANTIC_INSTANCEID)
instance_regid = vp->inputs[i].regid;
else if (semantic == IR3_SEMANTIC_VTXCNT)
vtxcnt_regid = vp->inputs[i].regid;
else if (i < vtx->vtx->num_elements && vp->inputs[i].compmask)
if (vp->inputs[i].sysval) {
switch(vp->inputs[i].slot) {
case SYSTEM_VALUE_BASE_VERTEX:
/* handled elsewhere */
break;
case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
vertex_regid = vp->inputs[i].regid;
break;
case SYSTEM_VALUE_INSTANCE_ID:
instance_regid = vp->inputs[i].regid;
break;
case SYSTEM_VALUE_VERTEX_CNT:
vtxcnt_regid = vp->inputs[i].regid;
break;
default:
unreachable("invalid system value");
break;
}
} else if (i < vtx->vtx->num_elements && vp->inputs[i].compmask) {
last = i;
}
}
/* hw doesn't like to be configured for zero vbo's, it seems: */
@@ -419,7 +382,7 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
return;
for (i = 0, j = 0; i <= last; i++) {
assert(sem2name(vp->inputs[i].semantic) == 0);
assert(!vp->inputs[i].sysval);
if (vp->inputs[i].compmask) {
struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];
const struct pipe_vertex_buffer *vb =
@@ -492,8 +455,10 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(ctx->sample_mask));
}
if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) && !emit->key.binning_pass) {
uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control;
if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG | FD_DIRTY_BLEND_DUAL)) &&
!emit->key.binning_pass) {
uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control |
fd3_blend_stateobj(ctx->blend)->rb_render_control;
val |= COND(fp->frag_face, A3XX_RB_RENDER_CONTROL_FACENESS);
val |= COND(fp->frag_coord, A3XX_RB_RENDER_CONTROL_XCOORD |
@@ -564,7 +529,8 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
val |= COND(fp->frag_coord, A3XX_GRAS_CL_CLIP_CNTL_ZCOORD |
A3XX_GRAS_CL_CLIP_CNTL_WCOORD);
/* TODO only use if prog doesn't use clipvertex/clipdist */
val |= MIN2(util_bitcount(ctx->rasterizer->clip_plane_enable), 6) << 26;
val |= A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES(
MIN2(util_bitcount(ctx->rasterizer->clip_plane_enable), 6));
OUT_PKT0(ring, REG_A3XX_GRAS_CL_CLIP_CNTL, 1);
OUT_RING(ring, val);
}
@@ -639,9 +605,13 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(ctx->viewport.scale[2]));
}
if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER)) {
if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_BLEND_DUAL)) {
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
fd3_program_emit(ring, emit, pfb->nr_cbufs, pfb->cbufs);
int nr_cbufs = pfb->nr_cbufs;
if (fd3_blend_stateobj(ctx->blend)->rb_render_control &
A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE)
nr_cbufs++;
fd3_program_emit(ring, emit, nr_cbufs, pfb->cbufs);
}
/* TODO we should not need this or fd_wfi() before emit_constants():
@@ -355,6 +355,8 @@ fd3_fs_output_format(enum pipe_format format)
case PIPE_FORMAT_R16G16_FLOAT:
case PIPE_FORMAT_R11G11B10_FLOAT:
return RB_R16G16B16A16_FLOAT;
case PIPE_FORMAT_L8_UNORM:
return RB_R8G8B8A8_UNORM;
default:
return fd3_pipe2color(format);
}
@@ -194,24 +194,17 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
/* seems like vs->constlen + fs->constlen > 256, then CONSTMODE=1 */
constmode = ((vp->constlen + fp->constlen) > 256) ? 1 : 0;
pos_regid = ir3_find_output_regid(vp,
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
posz_regid = ir3_find_output_regid(fp,
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
psize_regid = ir3_find_output_regid(vp,
ir3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
pos_regid = ir3_find_output_regid(vp, VARYING_SLOT_POS);
posz_regid = ir3_find_output_regid(fp, FRAG_RESULT_DEPTH);
psize_regid = ir3_find_output_regid(vp, VARYING_SLOT_PSIZ);
if (fp->color0_mrt) {
color_regid[0] = color_regid[1] = color_regid[2] = color_regid[3] =
ir3_find_output_regid(fp, ir3_semantic_name(TGSI_SEMANTIC_COLOR, 0));
ir3_find_output_regid(fp, FRAG_RESULT_COLOR);
} else {
for (i = 0; i < fp->outputs_count; i++) {
ir3_semantic sem = fp->outputs[i].semantic;
unsigned idx = sem2idx(sem);
if (sem2name(sem) != TGSI_SEMANTIC_COLOR)
continue;
debug_assert(idx < ARRAY_SIZE(color_regid));
color_regid[idx] = fp->outputs[i].regid;
}
color_regid[0] = ir3_find_output_regid(fp, FRAG_RESULT_DATA0);
color_regid[1] = ir3_find_output_regid(fp, FRAG_RESULT_DATA1);
color_regid[2] = ir3_find_output_regid(fp, FRAG_RESULT_DATA2);
color_regid[3] = ir3_find_output_regid(fp, FRAG_RESULT_DATA3);
}
/* adjust regids for alpha output formats. there is no alpha render
@@ -280,14 +273,14 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
j = ir3_next_varying(fp, j);
if (j < fp->inputs_count) {
k = ir3_find_output(vp, fp->inputs[j].semantic);
k = ir3_find_output(vp, fp->inputs[j].slot);
reg |= A3XX_SP_VS_OUT_REG_A_REGID(vp->outputs[k].regid);
reg |= A3XX_SP_VS_OUT_REG_A_COMPMASK(fp->inputs[j].compmask);
}
j = ir3_next_varying(fp, j);
if (j < fp->inputs_count) {
k = ir3_find_output(vp, fp->inputs[j].semantic);
k = ir3_find_output(vp, fp->inputs[j].slot);
reg |= A3XX_SP_VS_OUT_REG_B_REGID(vp->outputs[k].regid);
reg |= A3XX_SP_VS_OUT_REG_B_COMPMASK(fp->inputs[j].compmask);
}
@@ -394,7 +387,6 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
/* figure out VARYING_INTERP / FLAT_SHAD register values: */
for (j = -1; (j = ir3_next_varying(fp, j)) < (int)fp->inputs_count; ) {
uint32_t interp = fp->inputs[j].interpolate;
/* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
* instead.. rather than -8 everywhere else..
@@ -406,8 +398,8 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
*/
debug_assert((inloc % 4) == 0);
if ((interp == TGSI_INTERPOLATE_CONSTANT) ||
((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) {
if ((fp->inputs[j].interpolate == INTERP_QUALIFIER_FLAT) ||
(fp->inputs[j].rasterflat && emit->rasterflat)) {
uint32_t loc = inloc;
for (i = 0; i < 4; i++, loc++) {
vinterp[loc / 16] |= FLAT << ((loc % 16) * 2);
@@ -415,14 +407,20 @@ fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit,
}
}
/* Replace the .xy coordinates with S/T from the point sprite. Set
* interpolation bits for .zw such that they become .01
*/
if (emit->sprite_coord_enable & (1 << sem2idx(fp->inputs[j].semantic))) {
vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
<< ((inloc % 16) * 2);
vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
gl_varying_slot slot = fp->inputs[j].slot;
/* since we don't enable PIPE_CAP_TGSI_TEXCOORD: */
if (slot >= VARYING_SLOT_VAR0) {
unsigned texmask = 1 << (slot - VARYING_SLOT_VAR0);
/* Replace the .xy coordinates with S/T from the point sprite. Set
* interpolation bits for .zw such that they become .01
*/
if (emit->sprite_coord_enable & texmask) {
vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
<< ((inloc % 16) * 2);
vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
}
}
}
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63915 bytes, from 2015-08-24 16:56:28)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12)
Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -249,7 +249,8 @@ enum a4xx_tex_clamp {
A4XX_TEX_REPEAT = 0,
A4XX_TEX_CLAMP_TO_EDGE = 1,
A4XX_TEX_MIRROR_REPEAT = 2,
A4XX_TEX_CLAMP_NONE = 3,
A4XX_TEX_CLAMP_TO_BORDER = 3,
A4XX_TEX_MIRROR_CLAMP = 4,
};
enum a4xx_tex_aniso {
@@ -55,6 +55,8 @@ fd4_context_destroy(struct pipe_context *pctx)
pipe_resource_reference(&fd4_ctx->solid_vbuf, NULL);
pipe_resource_reference(&fd4_ctx->blit_texcoord_vbuf, NULL);
u_upload_destroy(fd4_ctx->border_color_uploader);
fd_context_destroy(pctx);
}
@@ -169,5 +171,8 @@ fd4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
fd4_query_context_init(pctx);
fd4_ctx->border_color_uploader = u_upload_create(pctx, 4096,
2 * PIPE_MAX_SAMPLERS * BORDERCOLOR_SIZE, 0);
return pctx;
}
@@ -29,6 +29,8 @@
#ifndef FD4_CONTEXT_H_
#define FD4_CONTEXT_H_
#include "util/u_upload_mgr.h"
#include "freedreno_drmif.h"
#include "freedreno_context.h"
@@ -70,6 +72,9 @@ struct fd4_context {
*/
struct fd_vertex_state blit_vbuf_state;
struct u_upload_mgr *border_color_uploader;
struct pipe_resource *border_color_buf;
/* if *any* of bits are set in {v,f}saturate_{s,t,r} */
bool vsaturate, fsaturate;
@@ -123,6 +123,7 @@ fd4_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info)
// TODO set .half_precision based on render target format,
// ie. float16 and smaller use half, float32 use full..
.half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
.ucp_enables = ctx->rasterizer ? ctx->rasterizer->clip_plane_enable : 0,
.has_per_samp = (fd4_ctx->fsaturate || fd4_ctx->vsaturate),
.vsaturate_s = fd4_ctx->vsaturate_s,
.vsaturate_t = fd4_ctx->vsaturate_t,
+41 -10
View File
@@ -124,7 +124,20 @@ static void
emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
enum adreno_state_block sb, struct fd_texture_stateobj *tex)
{
unsigned i;
static const uint32_t bcolor_reg[] = {
[SB_VERT_TEX] = REG_A4XX_TPL1_TP_VS_BORDER_COLOR_BASE_ADDR,
[SB_FRAG_TEX] = REG_A4XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR,
};
struct fd4_context *fd4_ctx = fd4_context(ctx);
unsigned i, off;
void *ptr;
u_upload_alloc(fd4_ctx->border_color_uploader,
0, 2 * PIPE_MAX_SAMPLERS * BORDERCOLOR_SIZE, &off,
&fd4_ctx->border_color_buf,
&ptr);
fd_setup_border_colors(tex, ptr, 0);
if (tex->num_samplers > 0) {
int num_samplers;
@@ -190,6 +203,11 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, 0x00000000);
}
}
OUT_PKT0(ring, bcolor_reg[sb], 1);
OUT_RELOC(ring, fd_resource(fd4_ctx->border_color_buf)->bo, off, 0, 0);
u_upload_unmap(fd4_ctx->border_color_uploader);
}
/* emit texture state for mem->gmem restore operation.. eventually it would
@@ -315,17 +333,30 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit)
unsigned vtxcnt_regid = regid(63, 0);
for (i = 0; i < vp->inputs_count; i++) {
uint8_t semantic = sem2name(vp->inputs[i].semantic);
if (semantic == TGSI_SEMANTIC_VERTEXID_NOBASE)
vertex_regid = vp->inputs[i].regid;
else if (semantic == TGSI_SEMANTIC_INSTANCEID)
instance_regid = vp->inputs[i].regid;
else if (semantic == IR3_SEMANTIC_VTXCNT)
vtxcnt_regid = vp->inputs[i].regid;
else if ((i < vtx->vtx->num_elements) && vp->inputs[i].compmask)
if (vp->inputs[i].sysval) {
switch(vp->inputs[i].slot) {
case SYSTEM_VALUE_BASE_VERTEX:
/* handled elsewhere */
break;
case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
vertex_regid = vp->inputs[i].regid;
break;
case SYSTEM_VALUE_INSTANCE_ID:
instance_regid = vp->inputs[i].regid;
break;
case SYSTEM_VALUE_VERTEX_CNT:
vtxcnt_regid = vp->inputs[i].regid;
break;
default:
unreachable("invalid system value");
break;
}
} else if (i < vtx->vtx->num_elements && vp->inputs[i].compmask) {
last = i;
}
}
/* hw doesn't like to be configured for zero vbo's, it seems: */
if ((vtx->vtx->num_elements == 0) &&
(vertex_regid == regid(63, 0)) &&
@@ -334,7 +365,7 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit)
return;
for (i = 0, j = 0; i <= last; i++) {
assert(sem2name(vp->inputs[i].semantic) == 0);
assert(!vp->inputs[i].sysval);
if (vp->inputs[i].compmask) {
struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];
const struct pipe_vertex_buffer *vb =
@@ -89,13 +89,14 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
_T(L8_UNORM, 8_UNORM, R8_UNORM, WZYX),
_T(I8_UNORM, 8_UNORM, NONE, WZYX),
/* NOTE: should be TFMT_8_UINT (which then gets remapped to
* TFMT_8_UNORM for mem2gmem in _gmem_restore_format()), but
* we don't know TFMT_8_UINT yet.. so just use TFMT_8_UNORM
* for now.. sampling from stencil as a texture might not
* work right, but at least should be fine for zsbuf..
*/
_T(S8_UINT, 8_UNORM, R8_UNORM, WZYX),
_T(A8_UINT, 8_UINT, NONE, WZYX),
_T(A8_SINT, 8_SINT, NONE, WZYX),
_T(L8_UINT, 8_UINT, NONE, WZYX),
_T(L8_SINT, 8_SINT, NONE, WZYX),
_T(I8_UINT, 8_UINT, NONE, WZYX),
_T(I8_SINT, 8_SINT, NONE, WZYX),
_T(S8_UINT, 8_UINT, R8_UNORM, WZYX),
/* 16-bit */
V_(R16_UNORM, 16_UNORM, NONE, WZYX),
@@ -227,27 +227,22 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
/* blob seems to always use constmode currently: */
constmode = 1;
pos_regid = ir3_find_output_regid(s[VS].v,
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
posz_regid = ir3_find_output_regid(s[FS].v,
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
psize_regid = ir3_find_output_regid(s[VS].v,
ir3_semantic_name(TGSI_SEMANTIC_PSIZE, 0));
pos_regid = ir3_find_output_regid(s[VS].v, VARYING_SLOT_POS);
posz_regid = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DEPTH);
psize_regid = ir3_find_output_regid(s[VS].v, VARYING_SLOT_PSIZ);
if (s[FS].v->color0_mrt) {
color_regid[0] = color_regid[1] = color_regid[2] = color_regid[3] =
color_regid[4] = color_regid[5] = color_regid[6] = color_regid[7] =
ir3_find_output_regid(s[FS].v, ir3_semantic_name(TGSI_SEMANTIC_COLOR, 0));
ir3_find_output_regid(s[FS].v, FRAG_RESULT_COLOR);
} else {
const struct ir3_shader_variant *fp = s[FS].v;
memset(color_regid, 0, sizeof(color_regid));
for (i = 0; i < fp->outputs_count; i++) {
ir3_semantic sem = fp->outputs[i].semantic;
unsigned idx = sem2idx(sem);
if (sem2name(sem) != TGSI_SEMANTIC_COLOR)
continue;
debug_assert(idx < ARRAY_SIZE(color_regid));
color_regid[idx] = fp->outputs[i].regid;
}
color_regid[0] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA0);
color_regid[1] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA1);
color_regid[2] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA2);
color_regid[3] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA3);
color_regid[4] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA4);
color_regid[5] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA5);
color_regid[6] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA6);
color_regid[7] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA7);
}
/* adjust regids for alpha output formats. there is no alpha render
@@ -257,7 +252,6 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
if (util_format_is_alpha(pipe_surface_format(bufs[i])))
color_regid[i] += 3;
/* TODO get these dynamically: */
face_regid = s[FS].v->frag_face ? regid(0,0) : regid(63,0);
coord_regid = s[FS].v->frag_coord ? regid(0,0) : regid(63,0);
@@ -348,14 +342,14 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
j = ir3_next_varying(s[FS].v, j);
if (j < s[FS].v->inputs_count) {
k = ir3_find_output(s[VS].v, s[FS].v->inputs[j].semantic);
k = ir3_find_output(s[VS].v, s[FS].v->inputs[j].slot);
reg |= A4XX_SP_VS_OUT_REG_A_REGID(s[VS].v->outputs[k].regid);
reg |= A4XX_SP_VS_OUT_REG_A_COMPMASK(s[FS].v->inputs[j].compmask);
}
j = ir3_next_varying(s[FS].v, j);
if (j < s[FS].v->inputs_count) {
k = ir3_find_output(s[VS].v, s[FS].v->inputs[j].semantic);
k = ir3_find_output(s[VS].v, s[FS].v->inputs[j].slot);
reg |= A4XX_SP_VS_OUT_REG_B_REGID(s[VS].v->outputs[k].regid);
reg |= A4XX_SP_VS_OUT_REG_B_COMPMASK(s[FS].v->inputs[j].compmask);
}
@@ -492,7 +486,6 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
*/
/* figure out VARYING_INTERP / VARYING_PS_REPL register values: */
for (j = -1; (j = ir3_next_varying(s[FS].v, j)) < (int)s[FS].v->inputs_count; ) {
uint32_t interp = s[FS].v->inputs[j].interpolate;
/* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
* instead.. rather than -8 everywhere else..
@@ -504,8 +497,8 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
*/
debug_assert((inloc % 4) == 0);
if ((interp == TGSI_INTERPOLATE_CONSTANT) ||
((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) {
if ((s[FS].v->inputs[j].interpolate == INTERP_QUALIFIER_FLAT) ||
(s[FS].v->inputs[j].rasterflat && emit->rasterflat)) {
uint32_t loc = inloc;
for (i = 0; i < 4; i++, loc++) {
@@ -514,14 +507,20 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
}
}
/* Replace the .xy coordinates with S/T from the point sprite. Set
* interpolation bits for .zw such that they become .01
*/
if (emit->sprite_coord_enable & (1 << sem2idx(s[FS].v->inputs[j].semantic))) {
vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
<< ((inloc % 16) * 2);
vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
gl_varying_slot slot = s[FS].v->inputs[j].slot;
/* since we don't enable PIPE_CAP_TGSI_TEXCOORD: */
if (slot >= VARYING_SLOT_VAR0) {
unsigned texmask = 1 << (slot - VARYING_SLOT_VAR0);
/* Replace the .xy coordinates with S/T from the point sprite. Set
* interpolation bits for .zw such that they become .01
*/
if (emit->sprite_coord_enable & texmask) {
vpsrepl[inloc / 16] |= (emit->sprite_coord_mode ? 0x0d : 0x09)
<< ((inloc % 16) * 2);
vinterp[(inloc + 2) / 16] |= 2 << (((inloc + 2) % 16) * 2);
vinterp[(inloc + 3) / 16] |= 3 << (((inloc + 3) % 16) * 2);
}
}
}
@@ -35,32 +35,32 @@
#include "fd4_texture.h"
#include "fd4_format.h"
/* TODO do we need to emulate clamp-to-edge like a3xx? */
static enum a4xx_tex_clamp
tex_clamp(unsigned wrap)
tex_clamp(unsigned wrap, bool clamp_to_edge)
{
/* hardware probably supports more, but we can't coax all the
* wrap/clamp modes out of the GLESv2 blob driver.
*
* TODO once we have basics working, go back and just try
* different values and see what happens
*/
/* Hardware does not support _CLAMP, but we emulate it: */
if (wrap == PIPE_TEX_WRAP_CLAMP) {
wrap = (clamp_to_edge) ?
PIPE_TEX_WRAP_CLAMP_TO_EDGE : PIPE_TEX_WRAP_CLAMP_TO_BORDER;
}
switch (wrap) {
case PIPE_TEX_WRAP_REPEAT:
return A4XX_TEX_REPEAT;
case PIPE_TEX_WRAP_CLAMP:
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
return A4XX_TEX_CLAMP_TO_EDGE;
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
// TODO
// return A4XX_TEX_CLAMP_TO_BORDER;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
return A4XX_TEX_CLAMP_TO_BORDER;
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
// TODO
// return A4XX_TEX_MIRROR_CLAMP;
/* only works for PoT.. need to emulate otherwise! */
return A4XX_TEX_MIRROR_CLAMP;
case PIPE_TEX_WRAP_MIRROR_REPEAT:
return A4XX_TEX_MIRROR_REPEAT;
case PIPE_TEX_WRAP_MIRROR_CLAMP:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
/* these two we could perhaps emulate, but we currently
* just don't advertise PIPE_CAP_TEXTURE_MIRROR_CLAMP
*/
default:
DBG("invalid wrap: %u", wrap);
return 0;
@@ -88,6 +88,7 @@ fd4_sampler_state_create(struct pipe_context *pctx,
struct fd4_sampler_stateobj *so = CALLOC_STRUCT(fd4_sampler_stateobj);
unsigned aniso = util_last_bit(MIN2(cso->max_anisotropy >> 1, 8));
bool miplinear = false;
bool clamp_to_edge;
if (!so)
return NULL;
@@ -97,14 +98,29 @@ fd4_sampler_state_create(struct pipe_context *pctx,
so->base = *cso;
/*
* For nearest filtering, _CLAMP means _CLAMP_TO_EDGE; for linear
* filtering, _CLAMP means _CLAMP_TO_BORDER while additionally
* clamping the texture coordinates to [0.0, 1.0].
*
* The clamping will be taken care of in the shaders. There are two
* filters here, but let the minification one has a say.
*/
clamp_to_edge = (cso->min_img_filter == PIPE_TEX_FILTER_NEAREST);
if (!clamp_to_edge) {
so->saturate_s = (cso->wrap_s == PIPE_TEX_WRAP_CLAMP);
so->saturate_t = (cso->wrap_t == PIPE_TEX_WRAP_CLAMP);
so->saturate_r = (cso->wrap_r == PIPE_TEX_WRAP_CLAMP);
}
so->texsamp0 =
COND(miplinear, A4XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR) |
A4XX_TEX_SAMP_0_XY_MAG(tex_filter(cso->mag_img_filter, aniso)) |
A4XX_TEX_SAMP_0_XY_MIN(tex_filter(cso->min_img_filter, aniso)) |
A4XX_TEX_SAMP_0_ANISO(aniso) |
A4XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s)) |
A4XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t)) |
A4XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r));
A4XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s, clamp_to_edge)) |
A4XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t, clamp_to_edge)) |
A4XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r, clamp_to_edge));
so->texsamp1 =
// COND(miplinear, A4XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR) |
@@ -122,6 +138,50 @@ fd4_sampler_state_create(struct pipe_context *pctx,
return so;
}
static void
fd4_sampler_states_bind(struct pipe_context *pctx,
unsigned shader, unsigned start,
unsigned nr, void **hwcso)
{
struct fd_context *ctx = fd_context(pctx);
struct fd4_context *fd4_ctx = fd4_context(ctx);
uint16_t saturate_s = 0, saturate_t = 0, saturate_r = 0;
unsigned i;
for (i = 0; i < nr; i++) {
if (hwcso[i]) {
struct fd4_sampler_stateobj *sampler =
fd4_sampler_stateobj(hwcso[i]);
if (sampler->saturate_s)
saturate_s |= (1 << i);
if (sampler->saturate_t)
saturate_t |= (1 << i);
if (sampler->saturate_r)
saturate_r |= (1 << i);
}
}
fd_sampler_states_bind(pctx, shader, start, nr, hwcso);
if (shader == PIPE_SHADER_FRAGMENT) {
fd4_ctx->fsaturate =
(saturate_s != 0) ||
(saturate_t != 0) ||
(saturate_r != 0);
fd4_ctx->fsaturate_s = saturate_s;
fd4_ctx->fsaturate_t = saturate_t;
fd4_ctx->fsaturate_r = saturate_r;
} else if (shader == PIPE_SHADER_VERTEX) {
fd4_ctx->vsaturate =
(saturate_s != 0) ||
(saturate_t != 0) ||
(saturate_r != 0);
fd4_ctx->vsaturate_s = saturate_s;
fd4_ctx->vsaturate_t = saturate_t;
fd4_ctx->vsaturate_r = saturate_r;
}
}
static enum a4xx_tex_type
tex_type(unsigned target)
{
@@ -209,7 +269,7 @@ void
fd4_texture_init(struct pipe_context *pctx)
{
pctx->create_sampler_state = fd4_sampler_state_create;
pctx->bind_sampler_states = fd_sampler_states_bind;
pctx->bind_sampler_states = fd4_sampler_states_bind;
pctx->create_sampler_view = fd4_sampler_view_create;
pctx->set_sampler_views = fd_set_sampler_views;
}
@@ -40,6 +40,7 @@
struct fd4_sampler_stateobj {
struct pipe_sampler_state base;
uint32_t texsamp0, texsamp1;
bool saturate_s, saturate_t, saturate_r;
};
static inline struct fd4_sampler_stateobj *
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63915 bytes, from 2015-08-24 16:56:28)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12)
Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -85,6 +85,10 @@ enum adreno_rb_blend_factor {
FACTOR_CONSTANT_ALPHA = 14,
FACTOR_ONE_MINUS_CONSTANT_ALPHA = 15,
FACTOR_SRC_ALPHA_SATURATE = 16,
FACTOR_SRC1_COLOR = 20,
FACTOR_ONE_MINUS_SRC1_COLOR = 21,
FACTOR_SRC1_ALPHA = 22,
FACTOR_ONE_MINUS_SRC1_ALPHA = 23,
};
enum adreno_rb_surface_endian {
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63915 bytes, from 2015-08-24 16:56:28)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12)
Copyright (C) 2013-2015 by the following authors:
- Rob Clark <robdclark@gmail.com> (robclark)
@@ -335,6 +335,7 @@ struct fd_context {
FD_DIRTY_SCISSOR = (1 << 17),
FD_DIRTY_STREAMOUT = (1 << 18),
FD_DIRTY_UCP = (1 << 19),
FD_DIRTY_BLEND_DUAL = (1 << 20),
} dirty;
struct pipe_blend_state *blend;
@@ -163,7 +163,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_MULTISAMPLE:
case PIPE_CAP_TEXTURE_BARRIER:
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
case PIPE_CAP_START_INSTANCE:
case PIPE_CAP_COMPUTE:
return 0;
@@ -235,6 +234,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
case PIPE_CAP_DEPTH_BOUNDS_TEST:
case PIPE_CAP_TGSI_TXQS:
return 0;
case PIPE_CAP_MAX_VIEWPORTS:
@@ -277,6 +277,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
/* Render targets. */
case PIPE_CAP_MAX_RENDER_TARGETS:
return screen->max_rts;
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
return is_a3xx(screen) ? 1 : 0;
/* Queries. */
case PIPE_CAP_QUERY_TIME_ELAPSED:
@@ -482,6 +484,7 @@ fd_screen_create(struct fd_device *dev)
pscreen = &screen->base;
screen->dev = dev;
screen->refcnt = 1;
// maybe this should be in context?
screen->pipe = fd_pipe_new(screen->dev, FD_PIPE_3D);
@@ -42,6 +42,16 @@ struct fd_bo;
struct fd_screen {
struct pipe_screen base;
/* it would be tempting to use pipe_reference here, but that
* really doesn't work well if it isn't the first member of
* the struct, so not quite so awesome to be adding refcnting
* further down the inheritance hierarchy:
*/
int refcnt;
/* place for winsys to stash it's own stuff: */
void *winsys_priv;
uint32_t gmemsize_bytes;
uint32_t device_id;
uint32_t gpu_id; /* 220, 305, etc */
@@ -27,6 +27,7 @@
*/
#include "pipe/p_state.h"
#include "util/u_dual_blend.h"
#include "util/u_string.h"
#include "util/u_memory.h"
#include "util/u_helpers.h"
@@ -225,8 +226,17 @@ static void
fd_blend_state_bind(struct pipe_context *pctx, void *hwcso)
{
struct fd_context *ctx = fd_context(pctx);
struct pipe_blend_state *cso = hwcso;
bool old_is_dual = ctx->blend ?
ctx->blend->rt[0].blend_enable && util_blend_state_is_dual(ctx->blend, 0) :
false;
bool new_is_dual = cso ?
cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0) :
false;
ctx->blend = hwcso;
ctx->dirty |= FD_DIRTY_BLEND;
if (old_is_dual != new_is_dual)
ctx->dirty |= FD_DIRTY_BLEND_DUAL;
}
static void
@@ -162,3 +162,69 @@ fd_texture_init(struct pipe_context *pctx)
pctx->sampler_view_destroy = fd_sampler_view_destroy;
}
/* helper for setting up border-color buffer for a3xx/a4xx: */
void
fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
unsigned offset)
{
unsigned i, j;
for (i = 0; i < tex->num_samplers; i++) {
struct pipe_sampler_state *sampler = tex->samplers[i];
uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
(BORDERCOLOR_SIZE * offset) +
(BORDERCOLOR_SIZE * i));
uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
if (!sampler)
continue;
/*
* XXX HACK ALERT XXX
*
* The border colors need to be swizzled in a particular
* format-dependent order. Even though samplers don't know about
* formats, we can assume that with a GL state tracker, there's a
* 1:1 correspondence between sampler and texture. Take advantage
* of that knowledge.
*/
if (i < tex->num_textures && tex->textures[i]) {
const struct util_format_description *desc =
util_format_description(tex->textures[i]->format);
for (j = 0; j < 4; j++) {
if (desc->swizzle[j] >= 4)
continue;
const struct util_format_channel_description *chan =
&desc->channel[desc->swizzle[j]];
int size = chan->size;
/* The Z16 texture format we use seems to look in the
* 32-bit border color slots
*/
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
size = 32;
/* Formats like R11G11B10 or RGB9_E5 don't specify
* per-channel sizes properly.
*/
if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
size = 16;
if (chan->pure_integer && size > 16)
bcolor32[desc->swizzle[j] + 4] =
sampler->border_color.i[j];
else if (size > 16)
bcolor32[desc->swizzle[j]] =
fui(sampler->border_color.f[j]);
else if (chan->pure_integer)
bcolor[desc->swizzle[j] + 8] =
sampler->border_color.i[j];
else
bcolor[desc->swizzle[j]] =
util_float_to_half(sampler->border_color.f[j]);
}
}
}
}
@@ -41,4 +41,35 @@ void fd_set_sampler_views(struct pipe_context *pctx, unsigned shader,
void fd_texture_init(struct pipe_context *pctx);
struct fd_texture_stateobj;
/* Both a3xx/a4xx share the same layout for the border-color buffer,
* which contains the pre-swizzled (based on texture format) border
* color value, with the following layout (per sampler):
*
* offset | description
* -------+-------------
* 0x00: | fp16[0] \
* | fp16[1] |___ swizzled fp16 channel values for "small float"
* | fp16[2] | formats (<= 16 bits per component, !integer)
* | fp16[3] /
* 0x08: | padding
* 0x10: | int16[0] \
* | int16[1] |___ swizzled int16 channels for for "small integer"
* | int16[2] | formats (<= 16 bits per component, integer)
* | int16[3] /
* 0x18: | padding
* 0x20: | fp32[0] \
* | fp32[1] |___ swizzled fp32 channel values for "large float"
* | fp32[2] | formats (> 16 bits per component, !integer)
* | fp32[3] /
* 0x30: | int32[0] \
* | int32[1] |___ swizzled int32 channel values for "large int"
* | int32[2] | formats (> 16 bits per component, integer)
* | int32[3] /
*/
#define BORDERCOLOR_SIZE 0x40
void fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
unsigned offset);
#endif /* FREEDRENO_TEXTURE_H_ */
@@ -104,10 +104,13 @@ fd_blend_factor(unsigned factor)
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
return FACTOR_ONE_MINUS_CONSTANT_ALPHA;
case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
return FACTOR_ONE_MINUS_SRC1_COLOR;
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
return FACTOR_ONE_MINUS_SRC1_ALPHA;
case PIPE_BLENDFACTOR_SRC1_COLOR:
return FACTOR_SRC1_COLOR;
case PIPE_BLENDFACTOR_SRC1_ALPHA:
/* I don't think these are supported */
return FACTOR_SRC1_ALPHA;
default:
DBG("invalid blend factor: %x", factor);
return 0;
@@ -94,6 +94,8 @@ static void print_usage(void)
printf(" --saturate-t MASK - bitmask of samplers to saturate T coord\n");
printf(" --saturate-r MASK - bitmask of samplers to saturate R coord\n");
printf(" --stream-out - enable stream-out (aka transform feedback)\n");
printf(" --ucp MASK - bitmask of enabled user-clip-planes\n");
printf(" --gpu GPU_ID - specify gpu-id (default 320)\n");
printf(" --help - show this message\n");
}
@@ -107,6 +109,7 @@ int main(int argc, char **argv)
struct ir3_shader_variant v;
struct ir3_shader s;
struct ir3_shader_key key = {};
unsigned gpu_id = 320;
const char *info;
void *ptr;
size_t size;
@@ -190,6 +193,20 @@ int main(int argc, char **argv)
continue;
}
if (!strcmp(argv[n], "--ucp")) {
debug_printf(" %s %s", argv[n], argv[n+1]);
key.ucp_enables = strtol(argv[n+1], NULL, 0);
n += 2;
continue;
}
if (!strcmp(argv[n], "--gpu")) {
debug_printf(" %s %s", argv[n], argv[n+1]);
gpu_id = strtol(argv[n+1], NULL, 0);
n += 2;
continue;
}
if (!strcmp(argv[n], "--help")) {
print_usage();
return 0;
@@ -232,7 +249,7 @@ int main(int argc, char **argv)
}
/* TODO cmdline option to target different gpus: */
compiler = ir3_compiler_create(320);
compiler = ir3_compiler_create(gpu_id);
info = "NIR compiler";
ret = ir3_compile_shader_nir(compiler, &v);
@@ -127,17 +127,44 @@ struct ir3_compile {
static struct ir3_instruction * create_immed(struct ir3_block *block, uint32_t val);
static struct ir3_block * get_block(struct ir3_compile *ctx, nir_block *nblock);
static struct nir_shader *to_nir(const struct tgsi_token *tokens)
static struct nir_shader *to_nir(struct ir3_compile *ctx,
const struct tgsi_token *tokens, struct ir3_shader_variant *so)
{
struct nir_shader_compiler_options options = {
static const nir_shader_compiler_options options = {
.lower_fpow = true,
.lower_fsat = true,
.lower_scmp = true,
.lower_flrp = true,
.lower_ffract = true,
.native_integers = true,
};
struct nir_lower_tex_options tex_options = {
.lower_rect = 0,
};
bool progress;
switch (so->type) {
case SHADER_FRAGMENT:
case SHADER_COMPUTE:
tex_options.saturate_s = so->key.fsaturate_s;
tex_options.saturate_t = so->key.fsaturate_t;
tex_options.saturate_r = so->key.fsaturate_r;
break;
case SHADER_VERTEX:
tex_options.saturate_s = so->key.vsaturate_s;
tex_options.saturate_t = so->key.vsaturate_t;
tex_options.saturate_r = so->key.vsaturate_r;
break;
}
if (ctx->compiler->gpu_id >= 400) {
/* a4xx seems to have *no* sam.p */
tex_options.lower_txp = ~0; /* lower all txp */
} else {
/* a3xx just needs to avoid sam.p for 3d tex */
tex_options.lower_txp = (1 << GLSL_SAMPLER_DIM_3D);
}
struct nir_shader *s = tgsi_to_nir(tokens, &options);
if (fd_mesa_debug & FD_DBG_OPTMSGS) {
@@ -148,6 +175,14 @@ static struct nir_shader *to_nir(const struct tgsi_token *tokens)
nir_opt_global_to_local(s);
nir_convert_to_ssa(s);
if (s->stage == MESA_SHADER_VERTEX) {
nir_lower_clip_vs(s, so->key.ucp_enables);
} else if (s->stage == MESA_SHADER_FRAGMENT) {
nir_lower_clip_fs(s, so->key.ucp_enables);
}
nir_lower_tex(s, &tex_options);
if (so->key.color_two_side)
nir_lower_two_sided_color(s);
nir_lower_idiv(s);
nir_lower_load_const_to_scalar(s);
@@ -179,49 +214,12 @@ static struct nir_shader *to_nir(const struct tgsi_token *tokens)
return s;
}
/* TODO nir doesn't lower everything for us yet, but ideally it would: */
static const struct tgsi_token *
lower_tgsi(struct ir3_compile *ctx, const struct tgsi_token *tokens,
struct ir3_shader_variant *so)
{
struct tgsi_shader_info info;
struct tgsi_lowering_config lconfig = {
.color_two_side = so->key.color_two_side,
.lower_FRC = true,
};
switch (so->type) {
case SHADER_FRAGMENT:
case SHADER_COMPUTE:
lconfig.saturate_s = so->key.fsaturate_s;
lconfig.saturate_t = so->key.fsaturate_t;
lconfig.saturate_r = so->key.fsaturate_r;
break;
case SHADER_VERTEX:
lconfig.saturate_s = so->key.vsaturate_s;
lconfig.saturate_t = so->key.vsaturate_t;
lconfig.saturate_r = so->key.vsaturate_r;
break;
}
if (ctx->compiler->gpu_id >= 400) {
/* a4xx seems to have *no* sam.p */
lconfig.lower_TXP = ~0; /* lower all txp */
} else {
/* a3xx just needs to avoid sam.p for 3d tex */
lconfig.lower_TXP = (1 << TGSI_TEXTURE_3D);
}
return tgsi_transform_lowering(&lconfig, tokens, &info);
}
static struct ir3_compile *
compile_init(struct ir3_compiler *compiler,
struct ir3_shader_variant *so,
const struct tgsi_token *tokens)
{
struct ir3_compile *ctx = rzalloc(NULL, struct ir3_compile);
const struct tgsi_token *lowered_tokens;
if (compiler->gpu_id >= 400) {
/* need special handling for "flat" */
@@ -248,13 +246,7 @@ compile_init(struct ir3_compiler *compiler,
ctx->block_ht = _mesa_hash_table_create(ctx,
_mesa_hash_pointer, _mesa_key_pointer_equal);
lowered_tokens = lower_tgsi(ctx, tokens, so);
if (!lowered_tokens)
lowered_tokens = tokens;
ctx->s = to_nir(lowered_tokens);
if (lowered_tokens != tokens)
free((void *)lowered_tokens);
ctx->s = to_nir(ctx, tokens, so);
so->first_driver_param = so->first_immediate = ctx->s->num_uniforms;
@@ -263,7 +255,7 @@ compile_init(struct ir3_compiler *compiler,
* num_uniform * vec4 - user consts
* 4 * vec4 - UBO addresses
* if (vertex shader) {
* 1 * vec4 - driver params (IR3_DP_*)
* N * vec4 - driver params (IR3_DP_*)
* 1 * vec4 - stream-out addresses
* }
*
@@ -275,8 +267,8 @@ compile_init(struct ir3_compiler *compiler,
so->first_immediate += 4;
if (so->type == SHADER_VERTEX) {
/* one (vec4) slot for driver params (see ir3_driver_param): */
so->first_immediate++;
/* driver params (see ir3_driver_param): */
so->first_immediate += IR3_DP_COUNT/4; /* convert to vec4 */
/* one (vec4) slot for stream-output base addresses: */
so->first_immediate++;
}
@@ -828,7 +820,9 @@ static struct ir3_instruction *
create_driver_param(struct ir3_compile *ctx, enum ir3_driver_param dp)
{
/* first four vec4 sysval's reserved for UBOs: */
unsigned r = regid(ctx->so->first_driver_param + 4, dp);
/* NOTE: dp is in scalar, but there can be >4 dp components: */
unsigned n = ctx->so->first_driver_param + IR3_DRIVER_PARAM_OFF;
unsigned r = regid(n + dp / 4, dp % 4);
return create_uniform(ctx, r);
}
@@ -1199,7 +1193,7 @@ emit_intrinsic_load_ubo(struct ir3_compile *ctx, nir_intrinsic_instr *intr,
struct ir3_block *b = ctx->block;
struct ir3_instruction *addr, *src0, *src1;
/* UBO addresses are the first driver params: */
unsigned ubo = regid(ctx->so->first_driver_param, 0);
unsigned ubo = regid(ctx->so->first_driver_param + IR3_UBOS_OFF, 0);
unsigned off = intr->const_index[0];
/* First src is ubo index, which could either be an immed or not: */
@@ -1349,17 +1343,18 @@ emit_intrinisic_store_var(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
}
}
static void add_sysval_input(struct ir3_compile *ctx, unsigned name,
static void add_sysval_input(struct ir3_compile *ctx, gl_system_value slot,
struct ir3_instruction *instr)
{
struct ir3_shader_variant *so = ctx->so;
unsigned r = regid(so->inputs_count, 0);
unsigned n = so->inputs_count++;
so->inputs[n].semantic = ir3_semantic_name(name, 0);
so->inputs[n].sysval = true;
so->inputs[n].slot = slot;
so->inputs[n].compmask = 1;
so->inputs[n].regid = r;
so->inputs[n].interpolate = TGSI_INTERPOLATE_CONSTANT;
so->inputs[n].interpolate = INTERP_QUALIFIER_FLAT;
so->total_in++;
ctx->ir->ninputs = MAX2(ctx->ir->ninputs, r + 1);
@@ -1437,7 +1432,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_load_base_vertex:
if (!ctx->basevertex) {
ctx->basevertex = create_driver_param(ctx, IR3_DP_VTXID_BASE);
add_sysval_input(ctx, TGSI_SEMANTIC_BASEVERTEX,
add_sysval_input(ctx, SYSTEM_VALUE_BASE_VERTEX,
ctx->basevertex);
}
dst[0] = ctx->basevertex;
@@ -1445,7 +1440,7 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_load_vertex_id_zero_base:
if (!ctx->vertex_id) {
ctx->vertex_id = create_input(ctx->block, 0);
add_sysval_input(ctx, TGSI_SEMANTIC_VERTEXID_NOBASE,
add_sysval_input(ctx, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE,
ctx->vertex_id);
}
dst[0] = ctx->vertex_id;
@@ -1453,11 +1448,17 @@ emit_intrinisic(struct ir3_compile *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_load_instance_id:
if (!ctx->instance_id) {
ctx->instance_id = create_input(ctx->block, 0);
add_sysval_input(ctx, TGSI_SEMANTIC_INSTANCEID,
add_sysval_input(ctx, SYSTEM_VALUE_INSTANCE_ID,
ctx->instance_id);
}
dst[0] = ctx->instance_id;
break;
case nir_intrinsic_load_user_clip_plane:
for (int i = 0; i < intr->num_components; i++) {
unsigned n = idx * 4 + i;
dst[i] = create_driver_param(ctx, IR3_DP_UCP0_X + n);
}
break;
case nir_intrinsic_discard_if:
case nir_intrinsic_discard: {
struct ir3_instruction *cond, *kill;
@@ -1623,6 +1624,7 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
case nir_texop_lod:
case nir_texop_tg4:
case nir_texop_query_levels:
case nir_texop_texture_samples:
compile_error(ctx, "Unhandled NIR tex type: %d\n", tex->op);
return;
}
@@ -2020,7 +2022,7 @@ emit_stream_out(struct ir3_compile *ctx)
* of the shader:
*/
vtxcnt = create_input(ctx->in_block, 0);
add_sysval_input(ctx, IR3_SEMANTIC_VTXCNT, vtxcnt);
add_sysval_input(ctx, SYSTEM_VALUE_VERTEX_CNT, vtxcnt);
maxvtxcnt = create_driver_param(ctx, IR3_DP_VTXCNT_MAX);
@@ -2064,7 +2066,7 @@ emit_stream_out(struct ir3_compile *ctx)
unsigned stride = strmout->stride[i];
struct ir3_instruction *base, *off;
base = create_uniform(ctx, regid(v->first_driver_param + 5, i));
base = create_uniform(ctx, regid(v->first_driver_param + IR3_TFBOS_OFF, i));
/* 24-bit should be enough: */
off = ir3_MUL_U(ctx->block, vtxcnt, 0,
@@ -2132,86 +2134,73 @@ setup_input(struct ir3_compile *ctx, nir_variable *in)
struct ir3_shader_variant *so = ctx->so;
unsigned array_len = MAX2(glsl_get_length(in->type), 1);
unsigned ncomp = glsl_get_components(in->type);
/* XXX: map loc slots to semantics */
unsigned semantic_name = in->data.location;
unsigned semantic_index = in->data.index;
unsigned n = in->data.driver_location;
unsigned slot = in->data.location;
DBG("; in: %u:%u, len=%ux%u, loc=%u",
semantic_name, semantic_index, array_len,
ncomp, n);
DBG("; in: slot=%u, len=%ux%u, drvloc=%u",
slot, array_len, ncomp, n);
so->inputs[n].semantic =
ir3_semantic_name(semantic_name, semantic_index);
so->inputs[n].slot = slot;
so->inputs[n].compmask = (1 << ncomp) - 1;
so->inputs[n].inloc = ctx->next_inloc;
so->inputs[n].interpolate = 0;
so->inputs[n].interpolate = INTERP_QUALIFIER_NONE;
so->inputs_count = MAX2(so->inputs_count, n + 1);
so->inputs[n].interpolate = in->data.interpolation;
/* the fdN_program_emit() code expects tgsi consts here, so map
* things back to tgsi for now:
*/
switch (in->data.interpolation) {
case INTERP_QUALIFIER_FLAT:
so->inputs[n].interpolate = TGSI_INTERPOLATE_CONSTANT;
break;
case INTERP_QUALIFIER_NOPERSPECTIVE:
so->inputs[n].interpolate = TGSI_INTERPOLATE_LINEAR;
break;
case INTERP_QUALIFIER_SMOOTH:
so->inputs[n].interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
break;
}
if (ctx->so->type == SHADER_FRAGMENT) {
for (int i = 0; i < ncomp; i++) {
struct ir3_instruction *instr = NULL;
unsigned idx = (n * 4) + i;
for (int i = 0; i < ncomp; i++) {
struct ir3_instruction *instr = NULL;
unsigned idx = (n * 4) + i;
if (ctx->so->type == SHADER_FRAGMENT) {
if (semantic_name == TGSI_SEMANTIC_POSITION) {
if (slot == VARYING_SLOT_POS) {
so->inputs[n].bary = false;
so->frag_coord = true;
instr = create_frag_coord(ctx, i);
} else if (semantic_name == TGSI_SEMANTIC_FACE) {
} else if (slot == VARYING_SLOT_FACE) {
so->inputs[n].bary = false;
so->frag_face = true;
instr = create_frag_face(ctx, i);
} else {
bool use_ldlv = false;
/* with NIR, we need to infer TGSI_INTERPOLATE_COLOR
* from the semantic name:
/* detect the special case for front/back colors where
* we need to do flat vs smooth shading depending on
* rast state:
*/
if ((in->data.interpolation == INTERP_QUALIFIER_NONE) &&
((semantic_name == TGSI_SEMANTIC_COLOR) ||
(semantic_name == TGSI_SEMANTIC_BCOLOR)))
so->inputs[n].interpolate = TGSI_INTERPOLATE_COLOR;
if (ctx->flat_bypass) {
/* with NIR, we need to infer TGSI_INTERPOLATE_COLOR
* from the semantic name:
*/
switch (so->inputs[n].interpolate) {
case TGSI_INTERPOLATE_COLOR:
if (!ctx->so->key.rasterflat)
break;
/* fallthrough */
case TGSI_INTERPOLATE_CONSTANT:
use_ldlv = true;
if (in->data.interpolation == INTERP_QUALIFIER_NONE) {
switch (slot) {
case VARYING_SLOT_COL0:
case VARYING_SLOT_COL1:
case VARYING_SLOT_BFC0:
case VARYING_SLOT_BFC1:
so->inputs[n].rasterflat = true;
break;
default:
break;
}
}
if (ctx->flat_bypass) {
if ((so->inputs[n].interpolate == INTERP_QUALIFIER_FLAT) ||
(so->inputs[n].rasterflat && ctx->so->key.rasterflat))
use_ldlv = true;
}
so->inputs[n].bary = true;
instr = create_frag_input(ctx,
so->inputs[n].inloc + i - 8, use_ldlv);
}
} else {
instr = create_input(ctx->block, idx);
}
ctx->ir->inputs[idx] = instr;
ctx->ir->inputs[idx] = instr;
}
} else if (ctx->so->type == SHADER_VERTEX) {
for (int i = 0; i < ncomp; i++) {
unsigned idx = (n * 4) + i;
ctx->ir->inputs[idx] = create_input(ctx->block, idx);
}
} else {
compile_error(ctx, "unknown shader type: %d\n", ctx->so->type);
}
if (so->inputs[n].bary || (ctx->so->type == SHADER_VERTEX)) {
@@ -2226,56 +2215,59 @@ setup_output(struct ir3_compile *ctx, nir_variable *out)
struct ir3_shader_variant *so = ctx->so;
unsigned array_len = MAX2(glsl_get_length(out->type), 1);
unsigned ncomp = glsl_get_components(out->type);
/* XXX: map loc slots to semantics */
unsigned semantic_name = out->data.location;
unsigned semantic_index = out->data.index;
unsigned n = out->data.driver_location;
unsigned slot = out->data.location;
unsigned comp = 0;
DBG("; out: %u:%u, len=%ux%u, loc=%u",
semantic_name, semantic_index, array_len,
ncomp, n);
DBG("; out: slot=%u, len=%ux%u, drvloc=%u",
slot, array_len, ncomp, n);
if (ctx->so->type == SHADER_VERTEX) {
switch (semantic_name) {
case TGSI_SEMANTIC_POSITION:
so->writes_pos = true;
break;
case TGSI_SEMANTIC_PSIZE:
so->writes_psize = true;
break;
case TGSI_SEMANTIC_COLOR:
case TGSI_SEMANTIC_BCOLOR:
case TGSI_SEMANTIC_GENERIC:
case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_TEXCOORD:
break;
default:
compile_error(ctx, "unknown VS semantic name: %s\n",
tgsi_semantic_names[semantic_name]);
}
} else {
switch (semantic_name) {
case TGSI_SEMANTIC_POSITION:
if (ctx->so->type == SHADER_FRAGMENT) {
switch (slot) {
case FRAG_RESULT_DEPTH:
comp = 2; /* tgsi will write to .z component */
so->writes_pos = true;
break;
case TGSI_SEMANTIC_COLOR:
if (semantic_index == -1) {
semantic_index = 0;
so->color0_mrt = 1;
}
case FRAG_RESULT_COLOR:
so->color0_mrt = 1;
break;
default:
compile_error(ctx, "unknown FS semantic name: %s\n",
tgsi_semantic_names[semantic_name]);
if (slot >= FRAG_RESULT_DATA0)
break;
compile_error(ctx, "unknown FS output name: %s\n",
gl_frag_result_name(slot));
}
} else if (ctx->so->type == SHADER_VERTEX) {
switch (slot) {
case VARYING_SLOT_POS:
so->writes_pos = true;
break;
case VARYING_SLOT_PSIZ:
so->writes_psize = true;
break;
case VARYING_SLOT_COL0:
case VARYING_SLOT_COL1:
case VARYING_SLOT_BFC0:
case VARYING_SLOT_BFC1:
case VARYING_SLOT_FOGC:
case VARYING_SLOT_CLIP_DIST0:
case VARYING_SLOT_CLIP_DIST1:
break;
default:
if (slot >= VARYING_SLOT_VAR0)
break;
if ((VARYING_SLOT_TEX0 <= slot) && (slot <= VARYING_SLOT_TEX7))
break;
compile_error(ctx, "unknown VS output name: %s\n",
gl_varying_slot_name(slot));
}
} else {
compile_error(ctx, "unknown shader type: %d\n", ctx->so->type);
}
compile_assert(ctx, n < ARRAY_SIZE(so->outputs));
so->outputs[n].semantic =
ir3_semantic_name(semantic_name, semantic_index);
so->outputs[n].slot = slot;
so->outputs[n].regid = regid(n, comp);
so->outputs_count = MAX2(so->outputs_count, n + 1);
@@ -2468,12 +2460,10 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
/* at this point, for binning pass, throw away unneeded outputs: */
if (so->key.binning_pass) {
for (i = 0, j = 0; i < so->outputs_count; i++) {
unsigned name = sem2name(so->outputs[i].semantic);
unsigned idx = sem2idx(so->outputs[i].semantic);
unsigned slot = so->outputs[i].slot;
/* throw away everything but first position/psize */
if ((idx == 0) && ((name == TGSI_SEMANTIC_POSITION) ||
(name == TGSI_SEMANTIC_PSIZE))) {
if ((slot == VARYING_SLOT_POS) || (slot == VARYING_SLOT_PSIZ)) {
if (i != j) {
so->outputs[j] = so->outputs[i];
ir->outputs[(j*4)+0] = ir->outputs[(i*4)+0];
@@ -2572,7 +2562,7 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
* but what we give the hw is the scalar register:
*/
if ((so->type == SHADER_FRAGMENT) &&
(sem2name(so->outputs[i].semantic) == TGSI_SEMANTIC_POSITION))
(so->outputs[i].slot == FRAG_RESULT_DEPTH))
so->outputs[i].regid += 2;
}
@@ -294,8 +294,7 @@ lower_if_else_block(nir_block *block, void *void_state)
sel->dest.write_mask = (1 << phi->dest.ssa.num_components) - 1;
nir_ssa_def_rewrite_uses(&phi->dest.ssa,
nir_src_for_ssa(&sel->dest.dest.ssa),
state->mem_ctx);
nir_src_for_ssa(&sel->dest.dest.ssa));
nir_instr_insert_before(&phi->instr, &sel->instr);
nir_instr_remove(&phi->instr);
+84 -32
View File
@@ -300,11 +300,11 @@ static void dump_reg(const char *name, uint32_t r)
debug_printf("; %s: r%d.%c\n", name, r >> 2, "xyzw"[r & 0x3]);
}
static void dump_semantic(struct ir3_shader_variant *so,
unsigned sem, const char *name)
static void dump_output(struct ir3_shader_variant *so,
unsigned slot, const char *name)
{
uint32_t regid;
regid = ir3_find_output_regid(so, ir3_semantic_name(sem, 0));
regid = ir3_find_output_regid(so, slot);
dump_reg(name, regid);
}
@@ -355,27 +355,51 @@ ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin)
disasm_a3xx(bin, so->info.sizedwords, 0, so->type);
debug_printf("; %s: outputs:", type);
for (i = 0; i < so->outputs_count; i++) {
uint8_t regid = so->outputs[i].regid;
ir3_semantic sem = so->outputs[i].semantic;
debug_printf(" r%d.%c (%u:%u)",
(regid >> 2), "xyzw"[regid & 0x3],
sem2name(sem), sem2idx(sem));
switch (so->type) {
case SHADER_VERTEX:
debug_printf("; %s: outputs:", type);
for (i = 0; i < so->outputs_count; i++) {
uint8_t regid = so->outputs[i].regid;
debug_printf(" r%d.%c (%s)",
(regid >> 2), "xyzw"[regid & 0x3],
gl_varying_slot_name(so->outputs[i].slot));
}
debug_printf("\n");
debug_printf("; %s: inputs:", type);
for (i = 0; i < so->inputs_count; i++) {
uint8_t regid = so->inputs[i].regid;
debug_printf(" r%d.%c (cm=%x,il=%u,b=%u)",
(regid >> 2), "xyzw"[regid & 0x3],
so->inputs[i].compmask,
so->inputs[i].inloc,
so->inputs[i].bary);
}
debug_printf("\n");
break;
case SHADER_FRAGMENT:
debug_printf("; %s: outputs:", type);
for (i = 0; i < so->outputs_count; i++) {
uint8_t regid = so->outputs[i].regid;
debug_printf(" r%d.%c (%s)",
(regid >> 2), "xyzw"[regid & 0x3],
gl_frag_result_name(so->outputs[i].slot));
}
debug_printf("\n");
debug_printf("; %s: inputs:", type);
for (i = 0; i < so->inputs_count; i++) {
uint8_t regid = so->inputs[i].regid;
debug_printf(" r%d.%c (%s,cm=%x,il=%u,b=%u)",
(regid >> 2), "xyzw"[regid & 0x3],
gl_varying_slot_name(so->inputs[i].slot),
so->inputs[i].compmask,
so->inputs[i].inloc,
so->inputs[i].bary);
}
debug_printf("\n");
break;
case SHADER_COMPUTE:
break;
}
debug_printf("\n");
debug_printf("; %s: inputs:", type);
for (i = 0; i < so->inputs_count; i++) {
uint8_t regid = so->inputs[i].regid;
ir3_semantic sem = so->inputs[i].semantic;
debug_printf(" r%d.%c (%u:%u,cm=%x,il=%u,b=%u)",
(regid >> 2), "xyzw"[regid & 0x3],
sem2name(sem), sem2idx(sem),
so->inputs[i].compmask,
so->inputs[i].inloc,
so->inputs[i].bary);
}
debug_printf("\n");
/* print generic shader info: */
debug_printf("; %s prog %d/%d: %u instructions, %d half, %d full\n",
@@ -391,13 +415,24 @@ ir3_shader_disasm(struct ir3_shader_variant *so, uint32_t *bin)
/* print shader type specific info: */
switch (so->type) {
case SHADER_VERTEX:
dump_semantic(so, TGSI_SEMANTIC_POSITION, "pos");
dump_semantic(so, TGSI_SEMANTIC_PSIZE, "psize");
dump_output(so, VARYING_SLOT_POS, "pos");
dump_output(so, VARYING_SLOT_PSIZ, "psize");
break;
case SHADER_FRAGMENT:
dump_reg("pos (bary)", so->pos_regid);
dump_semantic(so, TGSI_SEMANTIC_POSITION, "posz");
dump_semantic(so, TGSI_SEMANTIC_COLOR, "color");
dump_output(so, FRAG_RESULT_DEPTH, "posz");
if (so->color0_mrt) {
dump_output(so, FRAG_RESULT_COLOR, "color");
} else {
dump_output(so, FRAG_RESULT_DATA0, "data0");
dump_output(so, FRAG_RESULT_DATA1, "data1");
dump_output(so, FRAG_RESULT_DATA2, "data2");
dump_output(so, FRAG_RESULT_DATA3, "data3");
dump_output(so, FRAG_RESULT_DATA4, "data4");
dump_output(so, FRAG_RESULT_DATA5, "data5");
dump_output(so, FRAG_RESULT_DATA6, "data6");
dump_output(so, FRAG_RESULT_DATA7, "data7");
}
/* these two are hard-coded since we don't know how to
* program them to anything but all 0's...
*/
@@ -466,7 +501,7 @@ static void
emit_ubos(struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
struct fd_constbuf_stateobj *constbuf)
{
uint32_t offset = v->first_driver_param; /* UBOs after user consts */
uint32_t offset = v->first_driver_param + IR3_UBOS_OFF;
if (v->constlen > offset) {
struct fd_context *ctx = fd_context(v->shader->pctx);
uint32_t params = MIN2(4, v->constlen - offset) * 4;
@@ -519,7 +554,8 @@ emit_immediates(struct ir3_shader_variant *v, struct fd_ringbuffer *ring)
static void
emit_tfbos(struct ir3_shader_variant *v, struct fd_ringbuffer *ring)
{
uint32_t offset = v->first_driver_param + 5; /* streamout addresses after driver-params*/
/* streamout addresses after driver-params: */
uint32_t offset = v->first_driver_param + IR3_TFBOS_OFF;
if (v->constlen > offset) {
struct fd_context *ctx = fd_context(v->shader->pctx);
struct fd_streamout_stateobj *so = &ctx->streamout;
@@ -622,17 +658,33 @@ ir3_emit_consts(struct ir3_shader_variant *v, struct fd_ringbuffer *ring,
/* emit driver params every time: */
/* TODO skip emit if shader doesn't use driver params to avoid WFI.. */
if (info && (v->type == SHADER_VERTEX)) {
uint32_t offset = v->first_driver_param + 4; /* driver params after UBOs */
uint32_t offset = v->first_driver_param + IR3_DRIVER_PARAM_OFF;
if (v->constlen >= offset) {
uint32_t vertex_params[4] = {
uint32_t vertex_params[IR3_DP_COUNT] = {
[IR3_DP_VTXID_BASE] = info->indexed ?
info->index_bias : info->start,
[IR3_DP_VTXCNT_MAX] = max_tf_vtx(v),
};
/* if no user-clip-planes, we don't need to emit the
* entire thing:
*/
uint32_t vertex_params_size = 4;
if (v->key.ucp_enables) {
struct pipe_clip_state *ucp = &ctx->ucp;
unsigned pos = IR3_DP_UCP0_X;
for (unsigned i = 0; pos <= IR3_DP_UCP7_W; i++) {
for (unsigned j = 0; j < 4; j++) {
vertex_params[pos] = fui(ucp->ucp[i][j]);
pos++;
}
}
vertex_params_size = ARRAY_SIZE(vertex_params);
}
fd_wfi(ctx, ring);
ctx->emit_const(ring, SHADER_VERTEX, offset * 4, 0,
ARRAY_SIZE(vertex_params), vertex_params, NULL);
vertex_params_size, vertex_params, NULL);
/* if needed, emit stream-out buffer addresses: */
if (vertex_params[IR3_DP_VTXCNT_MAX] > 0) {
+54 -37
View File
@@ -30,6 +30,7 @@
#define IR3_SHADER_H_
#include "pipe/p_state.h"
#include "glsl/shader_enums.h"
#include "ir3.h"
#include "disasm.h"
@@ -38,29 +39,28 @@
enum ir3_driver_param {
IR3_DP_VTXID_BASE = 0,
IR3_DP_VTXCNT_MAX = 1,
/* user-clip-plane components, up to 8x vec4's: */
IR3_DP_UCP0_X = 4,
/* .... */
IR3_DP_UCP7_W = 35,
IR3_DP_COUNT = 36 /* must be aligned to vec4 */
};
/* internal semantic used for passing vtxcnt to vertex shader to
* implement transform feedback:
/* Layout of constant registers:
*
* num_uniform * vec4 - user consts
* 4 * vec4 - UBO addresses
* if (vertex shader) {
* N * vec4 - driver params (IR3_DP_*)
* 1 * vec4 - stream-out addresses
* }
*
* TODO this could be made more dynamic, to at least skip sections
* that we don't need..
*/
#define IR3_SEMANTIC_VTXCNT (TGSI_SEMANTIC_COUNT + 0)
typedef uint16_t ir3_semantic; /* semantic name + index */
static inline ir3_semantic
ir3_semantic_name(uint8_t name, uint16_t index)
{
return (name << 8) | (index & 0xff);
}
static inline uint8_t sem2name(ir3_semantic sem)
{
return sem >> 8;
}
static inline uint16_t sem2idx(ir3_semantic sem)
{
return sem & 0xff;
}
#define IR3_UBOS_OFF 0 /* UBOs after user consts */
#define IR3_DRIVER_PARAM_OFF 4 /* driver params after UBOs */
#define IR3_TFBOS_OFF (IR3_DRIVER_PARAM_OFF + IR3_DP_COUNT/4)
/* Configuration key used to identify a shader variant.. different
* shader variants can be used to implement features not supported
@@ -69,6 +69,11 @@ static inline uint16_t sem2idx(ir3_semantic sem)
struct ir3_shader_key {
union {
struct {
/*
* Combined Vertex/Fragment shader parameters:
*/
unsigned ucp_enables : 8;
/* do we need to check {v,f}saturate_{s,t,r}? */
unsigned has_per_samp : 1;
@@ -82,8 +87,8 @@ struct ir3_shader_key {
*/
unsigned color_two_side : 1;
unsigned half_precision : 1;
/* used when shader needs to handle flat varyings (a4xx),
* for TGSI_INTERPOLATE_COLOR:
/* used when shader needs to handle flat varyings (a4xx)
* for front/back color inputs to frag shader:
*/
unsigned rasterflat : 1;
};
@@ -147,10 +152,16 @@ struct ir3_shader_variant {
uint8_t pos_regid;
bool frag_coord, frag_face, color0_mrt;
/* NOTE: for input/outputs, slot is:
* gl_vert_attrib - for VS inputs
* gl_varying_slot - for VS output / FS input
* gl_frag_result - for FS output
*/
/* varyings/outputs: */
unsigned outputs_count;
struct {
ir3_semantic semantic;
uint8_t slot;
uint8_t regid;
} outputs[16 + 2]; /* +POSITION +PSIZE */
bool writes_pos, writes_psize;
@@ -158,7 +169,7 @@ struct ir3_shader_variant {
/* vertices/inputs: */
unsigned inputs_count;
struct {
ir3_semantic semantic;
uint8_t slot;
uint8_t regid;
uint8_t compmask;
uint8_t ncomp;
@@ -174,8 +185,12 @@ struct ir3_shader_variant {
* spots where inloc is used.
*/
uint8_t inloc;
uint8_t bary;
uint8_t interpolate;
/* vertex shader specific: */
bool sysval : 1; /* slot is a gl_system_value */
/* fragment shader specific: */
bool bary : 1; /* fetched varying (vs one loaded into reg) */
bool rasterflat : 1; /* special handling for emit->rasterflat */
enum glsl_interp_qualifier interpolate;
} inputs[16 + 2]; /* +POSITION +FACE */
unsigned total_in; /* sum of inputs (scalar) */
@@ -254,12 +269,12 @@ ir3_shader_stage(struct ir3_shader *shader)
#include "pipe/p_shader_tokens.h"
static inline int
ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
ir3_find_output(const struct ir3_shader_variant *so, gl_varying_slot slot)
{
int j;
for (j = 0; j < so->outputs_count; j++)
if (so->outputs[j].semantic == semantic)
if (so->outputs[j].slot == slot)
return j;
/* it seems optional to have a OUT.BCOLOR[n] for each OUT.COLOR[n]
@@ -269,18 +284,20 @@ ir3_find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
* OUT.COLOR[n] to IN.BCOLOR[n]. And visa versa if there is only
* a OUT.BCOLOR[n] but no matching OUT.COLOR[n]
*/
if (sem2name(semantic) == TGSI_SEMANTIC_BCOLOR) {
unsigned idx = sem2idx(semantic);
semantic = ir3_semantic_name(TGSI_SEMANTIC_COLOR, idx);
} else if (sem2name(semantic) == TGSI_SEMANTIC_COLOR) {
unsigned idx = sem2idx(semantic);
semantic = ir3_semantic_name(TGSI_SEMANTIC_BCOLOR, idx);
if (slot == VARYING_SLOT_BFC0) {
slot = VARYING_SLOT_COL0;
} else if (slot == VARYING_SLOT_BFC1) {
slot = VARYING_SLOT_COL1;
} else if (slot == VARYING_SLOT_COL0) {
slot = VARYING_SLOT_BFC0;
} else if (slot == VARYING_SLOT_COL1) {
slot = VARYING_SLOT_BFC1;
} else {
return 0;
}
for (j = 0; j < so->outputs_count; j++)
if (so->outputs[j].semantic == semantic)
if (so->outputs[j].slot == slot)
return j;
debug_assert(0);
@@ -298,11 +315,11 @@ ir3_next_varying(const struct ir3_shader_variant *so, int i)
}
static inline uint32_t
ir3_find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
ir3_find_output_regid(const struct ir3_shader_variant *so, unsigned slot)
{
int j;
for (j = 0; j < so->outputs_count; j++)
if (so->outputs[j].semantic == semantic)
if (so->outputs[j].slot == slot)
return so->outputs[j].regid;
return regid(63, 0);
}
+1 -1
View File
@@ -69,7 +69,7 @@ static boolean same_src_reg(struct i915_full_src_register *d1, struct i915_full_
d1->Register.Negate == d2->Register.Negate);
}
const static struct {
static const struct {
boolean is_texture;
boolean commutes;
unsigned neutral_element;
+1
View File
@@ -247,6 +247,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap)
case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
case PIPE_CAP_DEPTH_BOUNDS_TEST:
case PIPE_CAP_TGSI_TXQS:
return 0;
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
+1
View File
@@ -469,6 +469,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
case PIPE_CAP_DEPTH_BOUNDS_TEST:
case PIPE_CAP_TGSI_TXQS:
return 0;
case PIPE_CAP_VENDOR_ID:
+1
View File
@@ -296,6 +296,7 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY:
case PIPE_CAP_MAX_SHADER_PATCH_VARYINGS:
case PIPE_CAP_DEPTH_BOUNDS_TEST:
case PIPE_CAP_TGSI_TXQS:
return 0;
}
/* should only get here on unhandled cases */

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