Merge branch 'master' of ../mesa into vulkan
This commit is contained in:
+2
-1
@@ -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
@@ -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
@@ -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
@@ -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>
|
||||
|
||||
@@ -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 & 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
@@ -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.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 > 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: "Found invalid pixel values"</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=90925">Bug 90925</a> - "high fidelity": 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 >= 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>
|
||||
@@ -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>
|
||||
@@ -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 >= 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
@@ -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 (& 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 <= (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 < 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->ws->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@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 > 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 & 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: "Found invalid pixel values"</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> - "high fidelity": 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 >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@execution@geometry@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("OSMesaPixelStore") 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 "Unsupported or undefined LONG_BIT"</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 & 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>
|
||||
|
||||
@@ -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 '& 3' instead of '% 4' everywhere</li>
|
||||
<li>t_dd_dmatmp: Pull out common 'count -= count & 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 >= 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -8,6 +8,7 @@ env = env.Clone()
|
||||
|
||||
env.Append(CPPPATH = [
|
||||
'#/include',
|
||||
'#/include/HaikuGL',
|
||||
'#/src/egl/main',
|
||||
'#/src',
|
||||
])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = \
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user