Compare commits
133 Commits
vulkan-pro
...
mesa-11.0.
Author | SHA1 | Date | |
---|---|---|---|
|
51e0b06d99 | ||
|
f2bfaa8271 | ||
|
f15a7f3c6e | ||
|
cfddc456ae | ||
|
25e2a4136b | ||
|
ead4ce53f7 | ||
|
dace17bfd4 | ||
|
7f1a77ae66 | ||
|
bcb9e1d26b | ||
|
de1637c7fe | ||
|
cf716563a8 | ||
|
2c65e64881 | ||
|
8be6b32d65 | ||
|
0e0d008b2b | ||
|
007aae740e | ||
|
575f5a94c3 | ||
|
b1203ec9f3 | ||
|
c29e3f1bca | ||
|
c98217178b | ||
|
278739eb01 | ||
|
ae6dcfee56 | ||
|
9fcf28bb14 | ||
|
5fe09ffe6a | ||
|
395cd23690 | ||
|
d04024cffa | ||
|
370c2b344b | ||
|
bcb3bfd510 | ||
|
ebfa2ea34f | ||
|
3736ef3a17 | ||
|
d9e4a3ae6a | ||
|
1afea31ad8 | ||
|
d9b54a01be | ||
|
c4bae5792b | ||
|
4f1e500150 | ||
|
bd46093103 | ||
|
766d11e8f0 | ||
|
5923bd6d78 | ||
|
d0cf5100b5 | ||
|
e36ca8c2bb | ||
|
901744b2ff | ||
|
c62f82980c | ||
|
151f84f2db | ||
|
7d79ad95fd | ||
|
2becc98645 | ||
|
7cca7f71da | ||
|
94b8f60146 | ||
|
94bf2e2e05 | ||
|
78612aba51 | ||
|
0878187488 | ||
|
4ae2ffbff1 | ||
|
b0578c0061 | ||
|
b3dfd67feb | ||
|
017085efaf | ||
|
9e3528a844 | ||
|
84060d35bb | ||
|
2c581d04cc | ||
|
a1ac93fc4b | ||
|
1f2b601f8b | ||
|
4ca5756766 | ||
|
7023899ab9 | ||
|
2190f218ad | ||
|
2c27775a44 | ||
|
b7b8d4982d | ||
|
0d1f600c94 | ||
|
0c9f66829c | ||
|
11dc43424d | ||
|
ec9bafda70 | ||
|
6654483bc6 | ||
|
4b1ef5e842 | ||
|
95bc059c50 | ||
|
254a07841d | ||
|
271290f077 | ||
|
7bf27c2393 | ||
|
7f80a2383e | ||
|
3e1fde76b6 | ||
|
747e1b03bf | ||
|
b85ec1e34b | ||
|
acb822f1bd | ||
|
ddf459492d | ||
|
fcdaa190e5 | ||
|
0abcd9c8fc | ||
|
0b14d35863 | ||
|
a6710090af | ||
|
0c98ba7abf | ||
|
eef8258a86 | ||
|
747cd2c273 | ||
|
ecdd69cd05 | ||
|
74fa106932 | ||
|
1153420017 | ||
|
5704d473c8 | ||
|
eb2b88c44b | ||
|
5c08afc894 | ||
|
5fb758a418 | ||
|
bb37824959 | ||
|
8fc2cbb00e | ||
|
b497b88dbe | ||
|
dcb220f2f7 | ||
|
d9534e4785 | ||
|
63b4e6bfc9 | ||
|
a5dee22767 | ||
|
1aea7812b0 | ||
|
f0180a37d7 | ||
|
fe77d714f2 | ||
|
fb119b2260 | ||
|
50306a33b4 | ||
|
cf007af859 | ||
|
7d576419b2 | ||
|
893caebf44 | ||
|
3f8d44210c | ||
|
579ca506ae | ||
|
94205d0aa2 | ||
|
1b40221850 | ||
|
2fe87a1b68 | ||
|
b83b452eea | ||
|
68bd2ddda0 | ||
|
9db5c2ca2e | ||
|
08c41221d7 | ||
|
896ef5cb95 | ||
|
594388e577 | ||
|
812f2855dd | ||
|
5d8ce45d90 | ||
|
33b0f6e5e1 | ||
|
6659fba2c0 | ||
|
adae777f24 | ||
|
0b690e39dc | ||
|
67fc4b417a | ||
|
7a8d2048bc | ||
|
bf84c85130 | ||
|
aab6075613 | ||
|
2ef3434328 | ||
|
3d58fea2e3 | ||
|
ab94875352 | ||
|
f077632030 |
@@ -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
|
||||
|
156
configure.ac
156
configure.ac
@@ -9,7 +9,6 @@ dnl Copyright © 2009-2014 Jon TURNEY
|
||||
dnl Copyright © 2011-2012 Benjamin Franzke
|
||||
dnl Copyright © 2008-2014 David Airlie
|
||||
dnl Copyright © 2009-2013 Brian Paul
|
||||
dnl Copyright © 2003-2007 Keith Packard, Daniel Stone
|
||||
dnl
|
||||
dnl Permission is hereby granted, free of charge, to any person obtaining a
|
||||
dnl copy of this software and associated documentation files (the "Software"),
|
||||
@@ -988,144 +987,6 @@ fi
|
||||
|
||||
AC_SUBST([MESA_LLVM])
|
||||
|
||||
# SHA1 hashing
|
||||
AC_ARG_WITH([sha1],
|
||||
[AS_HELP_STRING([--with-sha1=libc|libmd|libnettle|libgcrypt|libcrypto|libsha1|CommonCrypto|CryptoAPI],
|
||||
[choose SHA1 implementation])])
|
||||
case "x$with_sha1" in
|
||||
x | xlibc | xlibmd | xlibnettle | xlibgcrypt | xlibcrypto | xlibsha1 | xCommonCrypto | xCryptoAPI)
|
||||
;;
|
||||
*)
|
||||
AC_MSG_ERROR([Illegal value for --with-sha1: $with_sha1])
|
||||
esac
|
||||
|
||||
AC_CHECK_FUNC([SHA1Init], [HAVE_SHA1_IN_LIBC=yes])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_LIBC" = xyes; then
|
||||
with_sha1=libc
|
||||
fi
|
||||
if test "x$with_sha1" = xlibc && test "x$HAVE_SHA1_IN_LIBC" != xyes; then
|
||||
AC_MSG_ERROR([sha1 in libc requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xlibc; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_LIBC], [1],
|
||||
[Use libc SHA1 functions])
|
||||
SHA1_LIBS=""
|
||||
fi
|
||||
AC_CHECK_FUNC([CC_SHA1_Init], [HAVE_SHA1_IN_COMMONCRYPTO=yes])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_COMMONCRYPTO" = xyes; then
|
||||
with_sha1=CommonCrypto
|
||||
fi
|
||||
if test "x$with_sha1" = xCommonCrypto && test "x$HAVE_SHA1_IN_COMMONCRYPTO" != xyes; then
|
||||
AC_MSG_ERROR([CommonCrypto requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xCommonCrypto; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_COMMONCRYPTO], [1],
|
||||
[Use CommonCrypto SHA1 functions])
|
||||
SHA1_LIBS=""
|
||||
fi
|
||||
dnl stdcall functions cannot be tested with AC_CHECK_LIB
|
||||
AC_CHECK_HEADER([wincrypt.h], [HAVE_SHA1_IN_CRYPTOAPI=yes], [], [#include <windows.h>])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_SHA1_IN_CRYPTOAPI" = xyes; then
|
||||
with_sha1=CryptoAPI
|
||||
fi
|
||||
if test "x$with_sha1" = xCryptoAPI && test "x$HAVE_SHA1_IN_CRYPTOAPI" != xyes; then
|
||||
AC_MSG_ERROR([CryptoAPI requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xCryptoAPI; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_CRYPTOAPI], [1],
|
||||
[Use CryptoAPI SHA1 functions])
|
||||
SHA1_LIBS=""
|
||||
fi
|
||||
AC_CHECK_LIB([md], [SHA1Init], [HAVE_LIBMD=yes])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_LIBMD" = xyes; then
|
||||
with_sha1=libmd
|
||||
fi
|
||||
if test "x$with_sha1" = xlibmd && test "x$HAVE_LIBMD" != xyes; then
|
||||
AC_MSG_ERROR([libmd requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xlibmd; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_LIBMD], [1],
|
||||
[Use libmd SHA1 functions])
|
||||
SHA1_LIBS=-lmd
|
||||
fi
|
||||
PKG_CHECK_MODULES([LIBSHA1], [libsha1], [HAVE_LIBSHA1=yes], [HAVE_LIBSHA1=no])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_LIBSHA1" = xyes; then
|
||||
with_sha1=libsha1
|
||||
fi
|
||||
if test "x$with_sha1" = xlibsha1 && test "x$HAVE_LIBSHA1" != xyes; then
|
||||
AC_MSG_ERROR([libsha1 requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xlibsha1; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_LIBSHA1], [1],
|
||||
[Use libsha1 for SHA1])
|
||||
SHA1_LIBS=-lsha1
|
||||
fi
|
||||
AC_CHECK_LIB([nettle], [nettle_sha1_init], [HAVE_LIBNETTLE=yes])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_LIBNETTLE" = xyes; then
|
||||
with_sha1=libnettle
|
||||
fi
|
||||
if test "x$with_sha1" = xlibnettle && test "x$HAVE_LIBNETTLE" != xyes; then
|
||||
AC_MSG_ERROR([libnettle requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xlibnettle; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_LIBNETTLE], [1],
|
||||
[Use libnettle SHA1 functions])
|
||||
SHA1_LIBS=-lnettle
|
||||
fi
|
||||
AC_CHECK_LIB([gcrypt], [gcry_md_open], [HAVE_LIBGCRYPT=yes])
|
||||
if test "x$with_sha1" = x && test "x$HAVE_LIBGCRYPT" = xyes; then
|
||||
with_sha1=libgcrypt
|
||||
fi
|
||||
if test "x$with_sha1" = xlibgcrypt && test "x$HAVE_LIBGCRYPT" != xyes; then
|
||||
AC_MSG_ERROR([libgcrypt requested but not found])
|
||||
fi
|
||||
if test "x$with_sha1" = xlibgcrypt; then
|
||||
AC_DEFINE([HAVE_SHA1_IN_LIBGCRYPT], [1],
|
||||
[Use libgcrypt SHA1 functions])
|
||||
SHA1_LIBS=-lgcrypt
|
||||
fi
|
||||
# We don't need all of the OpenSSL libraries, just libcrypto
|
||||
AC_CHECK_LIB([crypto], [SHA1_Init], [HAVE_LIBCRYPTO=yes])
|
||||
PKG_CHECK_MODULES([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes],
|
||||
[HAVE_OPENSSL_PKC=no])
|
||||
if test "x$HAVE_LIBCRYPTO" = xyes || test "x$HAVE_OPENSSL_PKC" = xyes; then
|
||||
if test "x$with_sha1" = x; then
|
||||
with_sha1=libcrypto
|
||||
fi
|
||||
else
|
||||
if test "x$with_sha1" = xlibcrypto; then
|
||||
AC_MSG_ERROR([OpenSSL libcrypto requested but not found])
|
||||
fi
|
||||
fi
|
||||
if test "x$with_sha1" = xlibcrypto; then
|
||||
if test "x$HAVE_LIBCRYPTO" = xyes; then
|
||||
SHA1_LIBS=-lcrypto
|
||||
else
|
||||
SHA1_LIBS="$OPENSSL_LIBS"
|
||||
SHA1_CFLAGS="$OPENSSL_CFLAGS"
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([for SHA1 implementation])
|
||||
AC_MSG_RESULT([$with_sha1])
|
||||
AC_SUBST(SHA1_LIBS)
|
||||
AC_SUBST(SHA1_CFLAGS)
|
||||
|
||||
# Allow user to configure out the shader-cache feature
|
||||
AC_ARG_ENABLE([shader-cache],
|
||||
AS_HELP_STRING([--disable-shader-cache], [Disable binary shader cache]),
|
||||
[enable_shader_cache="$enableval"],
|
||||
[if test "x$with_sha1" != "x"; then
|
||||
enable_shader_cache=yes
|
||||
else
|
||||
enable_shader_cache=no
|
||||
fi])
|
||||
if test "x$with_sha1" = "x"; then
|
||||
if test "x$enable_shader_cache" = "xyes"; then
|
||||
AC_MSG_ERROR([Cannot enable shader cache (no SHA-1 implementation found)])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL([ENABLE_SHADER_CACHE], [test x$enable_shader_cache = xyes])
|
||||
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
need_pci_id=yes ;;
|
||||
@@ -1289,6 +1150,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
|
||||
@@ -2317,7 +2188,6 @@ AC_CONFIG_FILES([Makefile
|
||||
src/gallium/auxiliary/Makefile
|
||||
src/gallium/auxiliary/pipe-loader/Makefile
|
||||
src/gallium/drivers/freedreno/Makefile
|
||||
src/gallium/drivers/ddebug/Makefile
|
||||
src/gallium/drivers/i915/Makefile
|
||||
src/gallium/drivers/ilo/Makefile
|
||||
src/gallium/drivers/llvmpipe/Makefile
|
||||
@@ -2485,12 +2355,6 @@ else
|
||||
echo " Gallium: no"
|
||||
fi
|
||||
|
||||
dnl Shader cache
|
||||
echo ""
|
||||
echo " Shader cache: $enable_shader_cache"
|
||||
if test "x$enable_shader_cache" = "xyes"; then
|
||||
echo " With SHA1 from: $with_sha1"
|
||||
fi
|
||||
|
||||
dnl Libraries
|
||||
echo ""
|
||||
|
@@ -196,7 +196,7 @@ GL 4.5, GLSL 4.50:
|
||||
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_KHR_context_flush_control DONE (all - but needs GLX/EGL extension to be useful)
|
||||
GL_KHR_context_flush_control DONE (all - but needs GLX/EXT extension to be useful)
|
||||
GL_KHR_robust_buffer_access_behavior not started
|
||||
GL_KHR_robustness 90% done (the ARB variant)
|
||||
GL_EXT_shader_integer_mix DONE (all drivers that support GLSL)
|
||||
|
@@ -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>
|
||||
|
134
docs/relnotes/11.0.1.html
Normal file
134
docs/relnotes/11.0.1.html
Normal file
@@ -0,0 +1,134 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Mesa Release Notes</title>
|
||||
<link rel="stylesheet" type="text/css" href="../mesa.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<h1>The Mesa 3D Graphics Library</h1>
|
||||
</div>
|
||||
|
||||
<iframe src="../contents.html"></iframe>
|
||||
<div class="content">
|
||||
|
||||
<h1>Mesa 11.0.1 Release Notes / September 26, 2015</h1>
|
||||
|
||||
<p>
|
||||
Mesa 11.0.1 is a bug fix release which fixes bugs found since the 11.0.0 release.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 11.0.1 implements the OpenGL 4.1 API, but the version reported by
|
||||
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
|
||||
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
|
||||
4.1 is <strong>only</strong> available if requested at context creation
|
||||
because compatibility contexts are not supported.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>SHA256 checksums</h2>
|
||||
<pre>
|
||||
6dab262877e12c0546a0e2970c6835a0f217e6d4026ccecb3cd5dd733d1ce867 mesa-11.0.1.tar.gz
|
||||
43d0dfcd1f1e36f07f8228cd76d90175d3fc74c1ed25d7071794a100a98ef2a6 mesa-11.0.1.tar.xz
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>New features</h2>
|
||||
<p>None</p>
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
|
||||
<p>This list is likely incomplete.</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=38109">Bug 38109</a> - i915 driver crashes if too few vertices are submitted (Mesa 7.10.2)</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91114">Bug 91114</a> - ES3-CTS.gtf.GL3Tests.shadow.shadow_execution_vert fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91716">Bug 91716</a> - [bisected] piglit.shaders.glsl-vs-int-attrib regresses on 32 bit BYT, HSW, IVB, SNB</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91719">Bug 91719</a> - [SNB,HSW,BYT] dEQP regressions associated with using NIR for vertex shaders</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92009">Bug 92009</a> - ES3-CTS.gtf.GL3Tests.packed_pixels.packed_pixels fails</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Changes</h2>
|
||||
|
||||
<p>Antia Puentes (2):</p>
|
||||
<ul>
|
||||
<li>i965/vec4: Fix saturation errors when coalescing registers</li>
|
||||
<li>i965/vec4_nir: Load constants as integers</li>
|
||||
</ul>
|
||||
|
||||
<p>Anuj Phogat (1):</p>
|
||||
<ul>
|
||||
<li>meta: Abort meta pbo path if TexSubImage need signed unsigned conversion</li>
|
||||
</ul>
|
||||
|
||||
<p>Emil Velikov (2):</p>
|
||||
<ul>
|
||||
<li>docs: add sha256 checksums for 11.0.0</li>
|
||||
<li>Update version to 11.0.1</li>
|
||||
</ul>
|
||||
|
||||
<p>Iago Toral Quiroga (1):</p>
|
||||
<ul>
|
||||
<li>mesa: Fix GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE for default framebuffer.</li>
|
||||
</ul>
|
||||
|
||||
<p>Ian Romanick (5):</p>
|
||||
<ul>
|
||||
<li>t_dd_dmatmp: Make "count" actually be the count</li>
|
||||
<li>t_dd_dmatmp: Clean up improper code formatting from previous patch</li>
|
||||
<li>t_dd_dmatmp: Use '& 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>
|
84
docs/relnotes/11.0.2.html
Normal file
84
docs/relnotes/11.0.2.html
Normal file
@@ -0,0 +1,84 @@
|
||||
<!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>
|
||||
TBD
|
||||
</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>
|
@@ -1,60 +0,0 @@
|
||||
<!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.1.0 Release Notes / TBD</h1>
|
||||
|
||||
<p>
|
||||
Mesa 11.1.0 is a new development release.
|
||||
People who are concerned with stability and reliability should stick
|
||||
with a previous release or wait for Mesa 11.1.1.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 11.1.0 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>
|
||||
TBD.
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>New features</h2>
|
||||
|
||||
<p>
|
||||
Note: some of the new features are only available with certain drivers.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
TBD.
|
||||
</ul>
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
|
||||
TBD.
|
||||
|
||||
<h2>Changes</h2>
|
||||
|
||||
TBD.
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -11,7 +11,6 @@ SUBDIRS += auxiliary
|
||||
##
|
||||
|
||||
SUBDIRS += \
|
||||
drivers/ddebug \
|
||||
drivers/noop \
|
||||
drivers/trace \
|
||||
drivers/rbug
|
||||
|
@@ -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 = \
|
||||
|
@@ -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;
|
||||
|
@@ -24,7 +24,6 @@
|
||||
|
||||
#include "util/ralloc.h"
|
||||
#include "glsl/nir/nir.h"
|
||||
#include "glsl/nir/nir_control_flow.h"
|
||||
#include "glsl/nir/nir_builder.h"
|
||||
#include "glsl/list.h"
|
||||
#include "glsl/shader_enums.h"
|
||||
@@ -65,24 +64,24 @@ struct ttn_compile {
|
||||
nir_register *addr_reg;
|
||||
|
||||
/**
|
||||
* Stack of nir_cursors where instructions should be pushed as we pop
|
||||
* Stack of cf_node_lists where instructions should be pushed as we pop
|
||||
* back out of the control flow stack.
|
||||
*
|
||||
* For each IF/ELSE/ENDIF block, if_stack[if_stack_pos] has where the else
|
||||
* instructions should be placed, and if_stack[if_stack_pos - 1] has where
|
||||
* the next instructions outside of the if/then/else block go.
|
||||
*/
|
||||
nir_cursor *if_stack;
|
||||
struct exec_list **if_stack;
|
||||
unsigned if_stack_pos;
|
||||
|
||||
/**
|
||||
* Stack of nir_cursors where instructions should be pushed as we pop
|
||||
* Stack of cf_node_lists where instructions should be pushed as we pop
|
||||
* back out of the control flow stack.
|
||||
*
|
||||
* loop_stack[loop_stack_pos - 1] contains the cf_node_list for the outside
|
||||
* of the loop.
|
||||
*/
|
||||
nir_cursor *loop_stack;
|
||||
struct exec_list **loop_stack;
|
||||
unsigned loop_stack_pos;
|
||||
|
||||
/* How many TGSI_FILE_IMMEDIATE vec4s have been parsed so far. */
|
||||
@@ -308,7 +307,7 @@ ttn_emit_immediate(struct ttn_compile *c)
|
||||
for (i = 0; i < 4; i++)
|
||||
load_const->value.u[i] = tgsi_imm->u[i].Uint;
|
||||
|
||||
nir_builder_instr_insert(b, &load_const->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &load_const->instr);
|
||||
}
|
||||
|
||||
static nir_src
|
||||
@@ -364,7 +363,7 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
|
||||
load->variables[0] = ttn_array_deref(c, load, var, offset, indirect);
|
||||
|
||||
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
|
||||
nir_builder_instr_insert(b, &load->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
|
||||
|
||||
src = nir_src_for_ssa(&load->dest.ssa);
|
||||
|
||||
@@ -415,7 +414,7 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
|
||||
load->num_components = ncomp;
|
||||
|
||||
nir_ssa_dest_init(&load->instr, &load->dest, ncomp, NULL);
|
||||
nir_builder_instr_insert(b, &load->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
|
||||
|
||||
src = nir_src_for_ssa(&load->dest.ssa);
|
||||
break;
|
||||
@@ -477,7 +476,7 @@ ttn_src_for_file_and_index(struct ttn_compile *c, unsigned file, unsigned index,
|
||||
srcn++;
|
||||
}
|
||||
nir_ssa_dest_init(&load->instr, &load->dest, 4, NULL);
|
||||
nir_builder_instr_insert(b, &load->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
|
||||
|
||||
src = nir_src_for_ssa(&load->dest.ssa);
|
||||
break;
|
||||
@@ -553,7 +552,7 @@ ttn_get_dest(struct ttn_compile *c, struct tgsi_full_dst_register *tgsi_fdst)
|
||||
|
||||
load->dest = nir_dest_for_reg(reg);
|
||||
|
||||
nir_builder_instr_insert(b, &load->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &load->instr);
|
||||
} else {
|
||||
assert(!tgsi_dst->Indirect);
|
||||
dest.dest.reg.reg = c->temp_regs[index].reg;
|
||||
@@ -668,7 +667,7 @@ ttn_alu(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
|
||||
instr->src[i].src = nir_src_for_ssa(src[i]);
|
||||
|
||||
instr->dest = dest;
|
||||
nir_builder_instr_insert(b, &instr->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -684,7 +683,7 @@ ttn_move_dest_masked(nir_builder *b, nir_alu_dest dest,
|
||||
mov->src[0].src = nir_src_for_ssa(def);
|
||||
for (unsigned i = def->num_components; i < 4; i++)
|
||||
mov->src[0].swizzle[i] = def->num_components - 1;
|
||||
nir_builder_instr_insert(b, &mov->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &mov->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -903,7 +902,7 @@ ttn_kill(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
|
||||
{
|
||||
nir_intrinsic_instr *discard =
|
||||
nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard);
|
||||
nir_builder_instr_insert(b, &discard->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -913,7 +912,7 @@ ttn_kill_if(nir_builder *b, nir_op op, nir_alu_dest dest, nir_ssa_def **src)
|
||||
nir_intrinsic_instr *discard =
|
||||
nir_intrinsic_instr_create(b->shader, nir_intrinsic_discard_if);
|
||||
discard->src[0] = nir_src_for_ssa(cmp);
|
||||
nir_builder_instr_insert(b, &discard->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &discard->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -922,7 +921,7 @@ 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[c->if_stack_pos] = b->cf_node_list;
|
||||
c->if_stack_pos++;
|
||||
|
||||
src = ttn_channel(b, src, X);
|
||||
@@ -933,11 +932,11 @@ ttn_if(struct ttn_compile *c, nir_ssa_def *src, bool is_uint)
|
||||
} else {
|
||||
if_stmt->condition = nir_src_for_ssa(nir_fne(b, src, nir_imm_int(b, 0)));
|
||||
}
|
||||
nir_builder_cf_insert(b, &if_stmt->cf_node);
|
||||
nir_cf_node_insert_end(b->cf_node_list, &if_stmt->cf_node);
|
||||
|
||||
b->cursor = nir_after_cf_list(&if_stmt->then_list);
|
||||
nir_builder_insert_after_cf_list(b, &if_stmt->then_list);
|
||||
|
||||
c->if_stack[c->if_stack_pos] = nir_after_cf_list(&if_stmt->else_list);
|
||||
c->if_stack[c->if_stack_pos] = &if_stmt->else_list;
|
||||
c->if_stack_pos++;
|
||||
}
|
||||
|
||||
@@ -946,7 +945,7 @@ ttn_else(struct ttn_compile *c)
|
||||
{
|
||||
nir_builder *b = &c->build;
|
||||
|
||||
b->cursor = c->if_stack[c->if_stack_pos - 1];
|
||||
nir_builder_insert_after_cf_list(b, c->if_stack[c->if_stack_pos - 1]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -955,7 +954,7 @@ ttn_endif(struct ttn_compile *c)
|
||||
nir_builder *b = &c->build;
|
||||
|
||||
c->if_stack_pos -= 2;
|
||||
b->cursor = c->if_stack[c->if_stack_pos];
|
||||
nir_builder_insert_after_cf_list(b, c->if_stack[c->if_stack_pos]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -964,27 +963,27 @@ 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[c->loop_stack_pos] = b->cf_node_list;
|
||||
c->loop_stack_pos++;
|
||||
|
||||
nir_loop *loop = nir_loop_create(b->shader);
|
||||
nir_builder_cf_insert(b, &loop->cf_node);
|
||||
nir_cf_node_insert_end(b->cf_node_list, &loop->cf_node);
|
||||
|
||||
b->cursor = nir_after_cf_list(&loop->body);
|
||||
nir_builder_insert_after_cf_list(b, &loop->body);
|
||||
}
|
||||
|
||||
static void
|
||||
ttn_cont(nir_builder *b)
|
||||
{
|
||||
nir_jump_instr *instr = nir_jump_instr_create(b->shader, nir_jump_continue);
|
||||
nir_builder_instr_insert(b, &instr->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
ttn_brk(nir_builder *b)
|
||||
{
|
||||
nir_jump_instr *instr = nir_jump_instr_create(b->shader, nir_jump_break);
|
||||
nir_builder_instr_insert(b, &instr->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -993,7 +992,7 @@ ttn_endloop(struct ttn_compile *c)
|
||||
nir_builder *b = &c->build;
|
||||
|
||||
c->loop_stack_pos--;
|
||||
b->cursor = c->loop_stack[c->loop_stack_pos];
|
||||
nir_builder_insert_after_cf_list(b, c->loop_stack[c->loop_stack_pos]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1280,7 +1279,7 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
|
||||
assert(src_number == num_srcs);
|
||||
|
||||
nir_ssa_dest_init(&instr->instr, &instr->dest, 4, NULL);
|
||||
nir_builder_instr_insert(b, &instr->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &instr->instr);
|
||||
|
||||
/* Resolve the writemask on the texture op. */
|
||||
ttn_move_dest(b, dest, &instr->dest.ssa);
|
||||
@@ -1319,10 +1318,10 @@ ttn_txq(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
|
||||
txs->src[0].src_type = nir_tex_src_lod;
|
||||
|
||||
nir_ssa_dest_init(&txs->instr, &txs->dest, 3, NULL);
|
||||
nir_builder_instr_insert(b, &txs->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &txs->instr);
|
||||
|
||||
nir_ssa_dest_init(&qlv->instr, &qlv->dest, 1, NULL);
|
||||
nir_builder_instr_insert(b, &qlv->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &qlv->instr);
|
||||
|
||||
ttn_move_dest_masked(b, dest, &txs->dest.ssa, TGSI_WRITEMASK_XYZ);
|
||||
ttn_move_dest_masked(b, dest, &qlv->dest.ssa, TGSI_WRITEMASK_W);
|
||||
@@ -1731,7 +1730,7 @@ ttn_emit_instruction(struct ttn_compile *c)
|
||||
store->variables[0] = ttn_array_deref(c, store, var, offset, indirect);
|
||||
store->src[0] = nir_src_for_reg(dest.dest.reg.reg);
|
||||
|
||||
nir_builder_instr_insert(b, &store->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1760,26 +1759,11 @@ ttn_add_output_stores(struct ttn_compile *c)
|
||||
store->const_index[0] = loc;
|
||||
store->src[0].reg.reg = c->output_regs[loc].reg;
|
||||
store->src[0].reg.base_offset = c->output_regs[loc].offset;
|
||||
nir_builder_instr_insert(b, &store->instr);
|
||||
nir_instr_insert_after_cf_list(b->cf_node_list, &store->instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gl_shader_stage
|
||||
tgsi_processor_to_shader_stage(unsigned processor)
|
||||
{
|
||||
switch (processor) {
|
||||
case TGSI_PROCESSOR_FRAGMENT: return MESA_SHADER_FRAGMENT;
|
||||
case TGSI_PROCESSOR_VERTEX: return MESA_SHADER_VERTEX;
|
||||
case TGSI_PROCESSOR_GEOMETRY: return MESA_SHADER_GEOMETRY;
|
||||
case TGSI_PROCESSOR_TESS_CTRL: return MESA_SHADER_TESS_CTRL;
|
||||
case TGSI_PROCESSOR_TESS_EVAL: return MESA_SHADER_TESS_EVAL;
|
||||
case TGSI_PROCESSOR_COMPUTE: return MESA_SHADER_COMPUTE;
|
||||
default:
|
||||
unreachable("invalid TGSI processor");
|
||||
};
|
||||
}
|
||||
|
||||
struct nir_shader *
|
||||
tgsi_to_nir(const void *tgsi_tokens,
|
||||
const nir_shader_compiler_options *options)
|
||||
@@ -1791,19 +1775,17 @@ tgsi_to_nir(const void *tgsi_tokens,
|
||||
int ret;
|
||||
|
||||
c = rzalloc(NULL, struct ttn_compile);
|
||||
|
||||
tgsi_scan_shader(tgsi_tokens, &scan);
|
||||
c->scan = &scan;
|
||||
|
||||
s = nir_shader_create(NULL, tgsi_processor_to_shader_stage(scan.processor),
|
||||
options);
|
||||
s = nir_shader_create(NULL, options);
|
||||
|
||||
nir_function *func = nir_function_create(s, "main");
|
||||
nir_function_overload *overload = nir_function_overload_create(func);
|
||||
nir_function_impl *impl = nir_function_impl_create(overload);
|
||||
|
||||
nir_builder_init(&c->build, impl);
|
||||
c->build.cursor = nir_after_cf_list(&impl->body);
|
||||
nir_builder_insert_after_cf_list(&c->build, &impl->body);
|
||||
|
||||
tgsi_scan_shader(tgsi_tokens, &scan);
|
||||
c->scan = &scan;
|
||||
|
||||
s->num_inputs = scan.file_max[TGSI_FILE_INPUT] + 1;
|
||||
s->num_uniforms = scan.const_file_max[0] + 1;
|
||||
@@ -1819,10 +1801,10 @@ tgsi_to_nir(const void *tgsi_tokens,
|
||||
c->num_samp_types = scan.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
|
||||
c->samp_types = rzalloc_array(c, nir_alu_type, c->num_samp_types);
|
||||
|
||||
c->if_stack = rzalloc_array(c, nir_cursor,
|
||||
c->if_stack = rzalloc_array(c, struct exec_list *,
|
||||
(scan.opcode_count[TGSI_OPCODE_IF] +
|
||||
scan.opcode_count[TGSI_OPCODE_UIF]) * 2);
|
||||
c->loop_stack = rzalloc_array(c, nir_cursor,
|
||||
c->loop_stack = rzalloc_array(c, struct exec_list *,
|
||||
scan.opcode_count[TGSI_OPCODE_BGNLOOP]);
|
||||
|
||||
ret = tgsi_parse_init(&parser, tgsi_tokens);
|
||||
|
@@ -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));
|
||||
|
||||
|
@@ -11,10 +11,6 @@
|
||||
* one or more debug driver: rbug, trace.
|
||||
*/
|
||||
|
||||
#ifdef GALLIUM_DDEBUG
|
||||
#include "ddebug/dd_public.h"
|
||||
#endif
|
||||
|
||||
#ifdef GALLIUM_TRACE
|
||||
#include "trace/tr_public.h"
|
||||
#endif
|
||||
@@ -34,10 +30,6 @@
|
||||
static inline struct pipe_screen *
|
||||
debug_screen_wrap(struct pipe_screen *screen)
|
||||
{
|
||||
#if defined(GALLIUM_DDEBUG)
|
||||
screen = ddebug_screen_create(screen);
|
||||
#endif
|
||||
|
||||
#if defined(GALLIUM_RBUG)
|
||||
screen = rbug_screen_create(screen);
|
||||
#endif
|
||||
|
@@ -372,28 +372,30 @@ void util_blitter_custom_resolve_color(struct blitter_context *blitter,
|
||||
*
|
||||
* States not listed here are not affected by util_blitter. */
|
||||
|
||||
static inline void
|
||||
util_blitter_save_blend(struct blitter_context *blitter, void *state)
|
||||
static inline
|
||||
void util_blitter_save_blend(struct blitter_context *blitter,
|
||||
void *state)
|
||||
{
|
||||
blitter->saved_blend_state = state;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
|
||||
void *state)
|
||||
static inline
|
||||
void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
|
||||
void *state)
|
||||
{
|
||||
blitter->saved_dsa_state = state;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_vertex_elements(struct blitter_context *blitter, void *state)
|
||||
static inline
|
||||
void util_blitter_save_vertex_elements(struct blitter_context *blitter,
|
||||
void *state)
|
||||
{
|
||||
blitter->saved_velem_state = state;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_stencil_ref(struct blitter_context *blitter,
|
||||
const struct pipe_stencil_ref *state)
|
||||
static inline
|
||||
void util_blitter_save_stencil_ref(struct blitter_context *blitter,
|
||||
const struct pipe_stencil_ref *state)
|
||||
{
|
||||
blitter->saved_stencil_ref = *state;
|
||||
}
|
||||
@@ -405,20 +407,23 @@ void util_blitter_save_rasterizer(struct blitter_context *blitter,
|
||||
blitter->saved_rs_state = state;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_fragment_shader(struct blitter_context *blitter, void *fs)
|
||||
static inline
|
||||
void util_blitter_save_fragment_shader(struct blitter_context *blitter,
|
||||
void *fs)
|
||||
{
|
||||
blitter->saved_fs = fs;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_vertex_shader(struct blitter_context *blitter, void *vs)
|
||||
static inline
|
||||
void util_blitter_save_vertex_shader(struct blitter_context *blitter,
|
||||
void *vs)
|
||||
{
|
||||
blitter->saved_vs = vs;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_geometry_shader(struct blitter_context *blitter, void *gs)
|
||||
static inline
|
||||
void util_blitter_save_geometry_shader(struct blitter_context *blitter,
|
||||
void *gs)
|
||||
{
|
||||
blitter->saved_gs = gs;
|
||||
}
|
||||
@@ -437,24 +442,24 @@ util_blitter_save_tesseval_shader(struct blitter_context *blitter,
|
||||
blitter->saved_tes = sh;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_framebuffer(struct blitter_context *blitter,
|
||||
const struct pipe_framebuffer_state *state)
|
||||
static inline
|
||||
void util_blitter_save_framebuffer(struct blitter_context *blitter,
|
||||
const struct pipe_framebuffer_state *state)
|
||||
{
|
||||
blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */
|
||||
util_copy_framebuffer_state(&blitter->saved_fb_state, state);
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_viewport(struct blitter_context *blitter,
|
||||
struct pipe_viewport_state *state)
|
||||
static inline
|
||||
void util_blitter_save_viewport(struct blitter_context *blitter,
|
||||
struct pipe_viewport_state *state)
|
||||
{
|
||||
blitter->saved_viewport = *state;
|
||||
}
|
||||
|
||||
static inline void
|
||||
util_blitter_save_scissor(struct blitter_context *blitter,
|
||||
struct pipe_scissor_state *state)
|
||||
static inline
|
||||
void util_blitter_save_scissor(struct blitter_context *blitter,
|
||||
struct pipe_scissor_state *state)
|
||||
{
|
||||
blitter->saved_scissor = *state;
|
||||
}
|
||||
|
@@ -21,8 +21,7 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Copied from EXT_texture_shared_exponent and edited, getting rid of
|
||||
* expensive float math bits too. */
|
||||
/* Copied from EXT_texture_shared_exponent and edited. */
|
||||
|
||||
#ifndef RGB9E5_H
|
||||
#define RGB9E5_H
|
||||
@@ -40,6 +39,7 @@
|
||||
#define RGB9E5_MANTISSA_VALUES (1<<RGB9E5_MANTISSA_BITS)
|
||||
#define MAX_RGB9E5_MANTISSA (RGB9E5_MANTISSA_VALUES-1)
|
||||
#define MAX_RGB9E5 (((float)MAX_RGB9E5_MANTISSA)/RGB9E5_MANTISSA_VALUES * (1<<MAX_RGB9E5_EXP))
|
||||
#define EPSILON_RGB9E5 ((1.0/RGB9E5_MANTISSA_VALUES) / (1<<RGB9E5_EXP_BIAS))
|
||||
|
||||
typedef union {
|
||||
unsigned int raw;
|
||||
@@ -74,59 +74,63 @@ typedef union {
|
||||
} field;
|
||||
} rgb9e5;
|
||||
|
||||
static inline float rgb9e5_ClampRange(float x)
|
||||
{
|
||||
if (x > 0.0f) {
|
||||
if (x >= MAX_RGB9E5) {
|
||||
return MAX_RGB9E5;
|
||||
} else {
|
||||
return x;
|
||||
}
|
||||
} else {
|
||||
/* NaN gets here too since comparisons with NaN always fail! */
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int rgb9e5_ClampRange(float x)
|
||||
/* Ok, FloorLog2 is not correct for the denorm and zero values, but we
|
||||
are going to do a max of this value with the minimum rgb9e5 exponent
|
||||
that will hide these problem cases. */
|
||||
static inline int rgb9e5_FloorLog2(float x)
|
||||
{
|
||||
float754 f;
|
||||
float754 max;
|
||||
f.value = x;
|
||||
max.value = MAX_RGB9E5;
|
||||
|
||||
if (f.raw > 0x7f800000)
|
||||
/* catches neg, NaNs */
|
||||
return 0;
|
||||
else if (f.raw >= max.raw)
|
||||
return max.raw;
|
||||
else
|
||||
return f.raw;
|
||||
f.value = x;
|
||||
return (f.field.biasedexponent - 127);
|
||||
}
|
||||
|
||||
static inline unsigned float3_to_rgb9e5(const float rgb[3])
|
||||
{
|
||||
rgb9e5 retval;
|
||||
int rm, gm, bm, exp_shared;
|
||||
float754 revdenom = {0};
|
||||
float754 rc, bc, gc, maxrgb;
|
||||
float maxrgb;
|
||||
int rm, gm, bm;
|
||||
float rc, gc, bc;
|
||||
int exp_shared, maxm;
|
||||
double denom;
|
||||
|
||||
rc.raw = rgb9e5_ClampRange(rgb[0]);
|
||||
gc.raw = rgb9e5_ClampRange(rgb[1]);
|
||||
bc.raw = rgb9e5_ClampRange(rgb[2]);
|
||||
maxrgb.raw = MAX3(rc.raw, gc.raw, bc.raw);
|
||||
rc = rgb9e5_ClampRange(rgb[0]);
|
||||
gc = rgb9e5_ClampRange(rgb[1]);
|
||||
bc = rgb9e5_ClampRange(rgb[2]);
|
||||
|
||||
/*
|
||||
* Compared to what the spec suggests, instead of conditionally adjusting
|
||||
* the exponent after the fact do it here by doing the equivalent of +0.5 -
|
||||
* the int add will spill over into the exponent in this case.
|
||||
*/
|
||||
maxrgb.raw += maxrgb.raw & (1 << (23-9));
|
||||
exp_shared = MAX2((maxrgb.raw >> 23), -RGB9E5_EXP_BIAS - 1 + 127) +
|
||||
1 + RGB9E5_EXP_BIAS - 127;
|
||||
revdenom.field.biasedexponent = 127 - (exp_shared - RGB9E5_EXP_BIAS -
|
||||
RGB9E5_MANTISSA_BITS) + 1;
|
||||
maxrgb = MAX3(rc, gc, bc);
|
||||
exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS;
|
||||
assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP);
|
||||
assert(exp_shared >= 0);
|
||||
/* This exp2 function could be replaced by a table. */
|
||||
denom = exp2(exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS);
|
||||
|
||||
/*
|
||||
* The spec uses strict round-up behavior (d3d10 disagrees, but in any case
|
||||
* must match what is done above for figuring out exponent).
|
||||
* We avoid the doubles ((int) rc * revdenom + 0.5) by doing the rounding
|
||||
* ourselves (revdenom was adjusted by +1, above).
|
||||
*/
|
||||
rm = (int) (rc.value * revdenom.value);
|
||||
gm = (int) (gc.value * revdenom.value);
|
||||
bm = (int) (bc.value * revdenom.value);
|
||||
rm = (rm & 1) + (rm >> 1);
|
||||
gm = (gm & 1) + (gm >> 1);
|
||||
bm = (bm & 1) + (bm >> 1);
|
||||
maxm = (int) floor(maxrgb / denom + 0.5);
|
||||
if (maxm == MAX_RGB9E5_MANTISSA+1) {
|
||||
denom *= 2;
|
||||
exp_shared += 1;
|
||||
assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP);
|
||||
} else {
|
||||
assert(maxm <= MAX_RGB9E5_MANTISSA);
|
||||
}
|
||||
|
||||
rm = (int) floor(rc / denom + 0.5);
|
||||
gm = (int) floor(gc / denom + 0.5);
|
||||
bm = (int) floor(bc / denom + 0.5);
|
||||
|
||||
assert(rm <= MAX_RGB9E5_MANTISSA);
|
||||
assert(gm <= MAX_RGB9E5_MANTISSA);
|
||||
@@ -147,15 +151,15 @@ static inline void rgb9e5_to_float3(unsigned rgb, float retval[3])
|
||||
{
|
||||
rgb9e5 v;
|
||||
int exponent;
|
||||
float754 scale = {0};
|
||||
float scale;
|
||||
|
||||
v.raw = rgb;
|
||||
exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS;
|
||||
scale.field.biasedexponent = exponent + 127;
|
||||
scale = exp2f(exponent);
|
||||
|
||||
retval[0] = v.field.r * scale.value;
|
||||
retval[1] = v.field.g * scale.value;
|
||||
retval[2] = v.field.b * scale.value;
|
||||
retval[0] = v.field.r * scale;
|
||||
retval[1] = v.field.g * scale;
|
||||
retval[2] = v.field.b * scale;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -457,7 +457,7 @@ null_constant_buffer(struct pipe_context *ctx)
|
||||
void
|
||||
util_run_tests(struct pipe_screen *screen)
|
||||
{
|
||||
struct pipe_context *ctx = screen->context_create(screen, NULL, 0);
|
||||
struct pipe_context *ctx = screen->context_create(screen, NULL);
|
||||
|
||||
tgsi_vs_window_space_position(ctx);
|
||||
null_sampler_view(ctx, TGSI_TEXTURE_2D);
|
||||
|
@@ -1120,7 +1120,7 @@ vl_create_mpeg12_decoder(struct pipe_context *context,
|
||||
|
||||
dec->base = *templat;
|
||||
dec->base.context = context;
|
||||
dec->context = context->screen->context_create(context->screen, NULL, 0);
|
||||
dec->context = context->screen->context_create(context->screen, NULL);
|
||||
|
||||
dec->base.destroy = vl_mpeg12_destroy;
|
||||
dec->base.begin_frame = vl_mpeg12_begin_frame;
|
||||
|
@@ -1,9 +0,0 @@
|
||||
include Makefile.sources
|
||||
include $(top_srcdir)/src/gallium/Automake.inc
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(GALLIUM_DRIVER_CFLAGS)
|
||||
|
||||
noinst_LTLIBRARIES = libddebug.la
|
||||
|
||||
libddebug_la_SOURCES = $(C_SOURCES)
|
@@ -1,6 +0,0 @@
|
||||
C_SOURCES := \
|
||||
dd_pipe.h \
|
||||
dd_public.h \
|
||||
dd_context.c \
|
||||
dd_draw.c \
|
||||
dd_screen.c
|
@@ -1,771 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "dd_pipe.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "util/u_memory.h"
|
||||
|
||||
|
||||
static void
|
||||
safe_memcpy(void *dst, const void *src, size_t size)
|
||||
{
|
||||
if (src)
|
||||
memcpy(dst, src, size);
|
||||
else
|
||||
memset(dst, 0, size);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* queries
|
||||
*/
|
||||
|
||||
static struct dd_query *
|
||||
dd_query(struct pipe_query *query)
|
||||
{
|
||||
return (struct dd_query *)query;
|
||||
}
|
||||
|
||||
static struct pipe_query *
|
||||
dd_query_unwrap(struct pipe_query *query)
|
||||
{
|
||||
if (query) {
|
||||
return dd_query(query)->query;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct pipe_query *
|
||||
dd_context_create_query(struct pipe_context *_pipe, unsigned query_type,
|
||||
unsigned index)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
struct pipe_query *query;
|
||||
|
||||
query = pipe->create_query(pipe, query_type, index);
|
||||
|
||||
/* Wrap query object. */
|
||||
if (query) {
|
||||
struct dd_query *dd_query = CALLOC_STRUCT(dd_query);
|
||||
if (dd_query) {
|
||||
dd_query->type = query_type;
|
||||
dd_query->query = query;
|
||||
query = (struct pipe_query *)dd_query;
|
||||
} else {
|
||||
pipe->destroy_query(pipe, query);
|
||||
query = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_destroy_query(struct pipe_context *_pipe,
|
||||
struct pipe_query *query)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->destroy_query(pipe, dd_query_unwrap(query));
|
||||
FREE(query);
|
||||
}
|
||||
|
||||
static boolean
|
||||
dd_context_begin_query(struct pipe_context *_pipe, struct pipe_query *query)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
return pipe->begin_query(pipe, dd_query_unwrap(query));
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_end_query(struct pipe_context *_pipe, struct pipe_query *query)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
pipe->end_query(pipe, dd_query_unwrap(query));
|
||||
}
|
||||
|
||||
static boolean
|
||||
dd_context_get_query_result(struct pipe_context *_pipe,
|
||||
struct pipe_query *query, boolean wait,
|
||||
union pipe_query_result *result)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
return pipe->get_query_result(pipe, dd_query_unwrap(query), wait, result);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_render_condition(struct pipe_context *_pipe,
|
||||
struct pipe_query *query, boolean condition,
|
||||
uint mode)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
pipe->render_condition(pipe, dd_query_unwrap(query), condition, mode);
|
||||
dctx->render_cond.query = dd_query(query);
|
||||
dctx->render_cond.condition = condition;
|
||||
dctx->render_cond.mode = mode;
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* constant (immutable) non-shader states
|
||||
*/
|
||||
|
||||
#define DD_CSO_CREATE(name, shortname) \
|
||||
static void * \
|
||||
dd_context_create_##name##_state(struct pipe_context *_pipe, \
|
||||
const struct pipe_##name##_state *state) \
|
||||
{ \
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe; \
|
||||
struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
|
||||
\
|
||||
if (!hstate) \
|
||||
return NULL; \
|
||||
hstate->cso = pipe->create_##name##_state(pipe, state); \
|
||||
hstate->state.shortname = *state; \
|
||||
return hstate; \
|
||||
}
|
||||
|
||||
#define DD_CSO_BIND(name, shortname) \
|
||||
static void \
|
||||
dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
|
||||
{ \
|
||||
struct dd_context *dctx = dd_context(_pipe); \
|
||||
struct pipe_context *pipe = dctx->pipe; \
|
||||
struct dd_state *hstate = state; \
|
||||
\
|
||||
dctx->shortname = hstate; \
|
||||
pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
|
||||
}
|
||||
|
||||
#define DD_CSO_DELETE(name) \
|
||||
static void \
|
||||
dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
|
||||
{ \
|
||||
struct dd_context *dctx = dd_context(_pipe); \
|
||||
struct pipe_context *pipe = dctx->pipe; \
|
||||
struct dd_state *hstate = state; \
|
||||
\
|
||||
pipe->delete_##name##_state(pipe, hstate->cso); \
|
||||
FREE(hstate); \
|
||||
}
|
||||
|
||||
#define DD_CSO_WHOLE(name, shortname) \
|
||||
DD_CSO_CREATE(name, shortname) \
|
||||
DD_CSO_BIND(name, shortname) \
|
||||
DD_CSO_DELETE(name)
|
||||
|
||||
DD_CSO_WHOLE(blend, blend)
|
||||
DD_CSO_WHOLE(rasterizer, rs)
|
||||
DD_CSO_WHOLE(depth_stencil_alpha, dsa)
|
||||
|
||||
DD_CSO_CREATE(sampler, sampler)
|
||||
DD_CSO_DELETE(sampler)
|
||||
|
||||
static void
|
||||
dd_context_bind_sampler_states(struct pipe_context *_pipe, unsigned shader,
|
||||
unsigned start, unsigned count, void **states)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
memcpy(&dctx->sampler_states[shader][start], states,
|
||||
sizeof(void*) * count);
|
||||
|
||||
if (states) {
|
||||
void *samp[PIPE_MAX_SAMPLERS];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct dd_state *s = states[i];
|
||||
samp[i] = s ? s->cso : NULL;
|
||||
}
|
||||
|
||||
pipe->bind_sampler_states(pipe, shader, start, count, samp);
|
||||
}
|
||||
else
|
||||
pipe->bind_sampler_states(pipe, shader, start, count, NULL);
|
||||
}
|
||||
|
||||
static void *
|
||||
dd_context_create_vertex_elements_state(struct pipe_context *_pipe,
|
||||
unsigned num_elems,
|
||||
const struct pipe_vertex_element *elems)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
struct dd_state *hstate = CALLOC_STRUCT(dd_state);
|
||||
|
||||
if (!hstate)
|
||||
return NULL;
|
||||
hstate->cso = pipe->create_vertex_elements_state(pipe, num_elems, elems);
|
||||
memcpy(hstate->state.velems.velems, elems, sizeof(elems[0]) * num_elems);
|
||||
hstate->state.velems.count = num_elems;
|
||||
return hstate;
|
||||
}
|
||||
|
||||
DD_CSO_BIND(vertex_elements, velems)
|
||||
DD_CSO_DELETE(vertex_elements)
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* shaders
|
||||
*/
|
||||
|
||||
#define DD_SHADER(NAME, name) \
|
||||
static void * \
|
||||
dd_context_create_##name##_state(struct pipe_context *_pipe, \
|
||||
const struct pipe_shader_state *state) \
|
||||
{ \
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe; \
|
||||
struct dd_state *hstate = CALLOC_STRUCT(dd_state); \
|
||||
\
|
||||
if (!hstate) \
|
||||
return NULL; \
|
||||
hstate->cso = pipe->create_##name##_state(pipe, state); \
|
||||
hstate->state.shader = *state; \
|
||||
hstate->state.shader.tokens = tgsi_dup_tokens(state->tokens); \
|
||||
return hstate; \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
dd_context_bind_##name##_state(struct pipe_context *_pipe, void *state) \
|
||||
{ \
|
||||
struct dd_context *dctx = dd_context(_pipe); \
|
||||
struct pipe_context *pipe = dctx->pipe; \
|
||||
struct dd_state *hstate = state; \
|
||||
\
|
||||
dctx->shaders[PIPE_SHADER_##NAME] = hstate; \
|
||||
pipe->bind_##name##_state(pipe, hstate ? hstate->cso : NULL); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
dd_context_delete_##name##_state(struct pipe_context *_pipe, void *state) \
|
||||
{ \
|
||||
struct dd_context *dctx = dd_context(_pipe); \
|
||||
struct pipe_context *pipe = dctx->pipe; \
|
||||
struct dd_state *hstate = state; \
|
||||
\
|
||||
pipe->delete_##name##_state(pipe, hstate->cso); \
|
||||
tgsi_free_tokens(hstate->state.shader.tokens); \
|
||||
FREE(hstate); \
|
||||
}
|
||||
|
||||
DD_SHADER(FRAGMENT, fs)
|
||||
DD_SHADER(VERTEX, vs)
|
||||
DD_SHADER(GEOMETRY, gs)
|
||||
DD_SHADER(TESS_CTRL, tcs)
|
||||
DD_SHADER(TESS_EVAL, tes)
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* immediate states
|
||||
*/
|
||||
|
||||
#define DD_IMM_STATE(name, type, deref, ref) \
|
||||
static void \
|
||||
dd_context_set_##name(struct pipe_context *_pipe, type deref) \
|
||||
{ \
|
||||
struct dd_context *dctx = dd_context(_pipe); \
|
||||
struct pipe_context *pipe = dctx->pipe; \
|
||||
\
|
||||
dctx->name = deref; \
|
||||
pipe->set_##name(pipe, ref); \
|
||||
}
|
||||
|
||||
DD_IMM_STATE(blend_color, const struct pipe_blend_color, *state, state)
|
||||
DD_IMM_STATE(stencil_ref, const struct pipe_stencil_ref, *state, state)
|
||||
DD_IMM_STATE(clip_state, const struct pipe_clip_state, *state, state)
|
||||
DD_IMM_STATE(sample_mask, unsigned, sample_mask, sample_mask)
|
||||
DD_IMM_STATE(min_samples, unsigned, min_samples, min_samples)
|
||||
DD_IMM_STATE(framebuffer_state, const struct pipe_framebuffer_state, *state, state)
|
||||
DD_IMM_STATE(polygon_stipple, const struct pipe_poly_stipple, *state, state)
|
||||
|
||||
static void
|
||||
dd_context_set_constant_buffer(struct pipe_context *_pipe,
|
||||
uint shader, uint index,
|
||||
struct pipe_constant_buffer *constant_buffer)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->constant_buffers[shader][index], constant_buffer,
|
||||
sizeof(*constant_buffer));
|
||||
pipe->set_constant_buffer(pipe, shader, index, constant_buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_scissor_states(struct pipe_context *_pipe,
|
||||
unsigned start_slot, unsigned num_scissors,
|
||||
const struct pipe_scissor_state *states)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->scissors[start_slot], states,
|
||||
sizeof(*states) * num_scissors);
|
||||
pipe->set_scissor_states(pipe, start_slot, num_scissors, states);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_viewport_states(struct pipe_context *_pipe,
|
||||
unsigned start_slot, unsigned num_viewports,
|
||||
const struct pipe_viewport_state *states)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->viewports[start_slot], states,
|
||||
sizeof(*states) * num_viewports);
|
||||
pipe->set_viewport_states(pipe, start_slot, num_viewports, states);
|
||||
}
|
||||
|
||||
static void dd_context_set_tess_state(struct pipe_context *_pipe,
|
||||
const float default_outer_level[4],
|
||||
const float default_inner_level[2])
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
memcpy(dctx->tess_default_levels, default_outer_level, sizeof(float) * 4);
|
||||
memcpy(dctx->tess_default_levels+4, default_inner_level, sizeof(float) * 2);
|
||||
pipe->set_tess_state(pipe, default_outer_level, default_inner_level);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* views
|
||||
*/
|
||||
|
||||
static struct pipe_surface *
|
||||
dd_context_create_surface(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource,
|
||||
const struct pipe_surface *surf_tmpl)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
struct pipe_surface *view =
|
||||
pipe->create_surface(pipe, resource, surf_tmpl);
|
||||
|
||||
if (!view)
|
||||
return NULL;
|
||||
view->context = _pipe;
|
||||
return view;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_surface_destroy(struct pipe_context *_pipe,
|
||||
struct pipe_surface *surf)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->surface_destroy(pipe, surf);
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
dd_context_create_sampler_view(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource,
|
||||
const struct pipe_sampler_view *templ)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
struct pipe_sampler_view *view =
|
||||
pipe->create_sampler_view(pipe, resource, templ);
|
||||
|
||||
if (!view)
|
||||
return NULL;
|
||||
view->context = _pipe;
|
||||
return view;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_sampler_view_destroy(struct pipe_context *_pipe,
|
||||
struct pipe_sampler_view *view)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->sampler_view_destroy(pipe, view);
|
||||
}
|
||||
|
||||
static struct pipe_image_view *
|
||||
dd_context_create_image_view(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource,
|
||||
const struct pipe_image_view *templ)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
struct pipe_image_view *view =
|
||||
pipe->create_image_view(pipe, resource, templ);
|
||||
|
||||
if (!view)
|
||||
return NULL;
|
||||
view->context = _pipe;
|
||||
return view;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_image_view_destroy(struct pipe_context *_pipe,
|
||||
struct pipe_image_view *view)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->image_view_destroy(pipe, view);
|
||||
}
|
||||
|
||||
static struct pipe_stream_output_target *
|
||||
dd_context_create_stream_output_target(struct pipe_context *_pipe,
|
||||
struct pipe_resource *res,
|
||||
unsigned buffer_offset,
|
||||
unsigned buffer_size)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
struct pipe_stream_output_target *view =
|
||||
pipe->create_stream_output_target(pipe, res, buffer_offset,
|
||||
buffer_size);
|
||||
|
||||
if (!view)
|
||||
return NULL;
|
||||
view->context = _pipe;
|
||||
return view;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_stream_output_target_destroy(struct pipe_context *_pipe,
|
||||
struct pipe_stream_output_target *target)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->stream_output_target_destroy(pipe, target);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* set states
|
||||
*/
|
||||
|
||||
static void
|
||||
dd_context_set_sampler_views(struct pipe_context *_pipe, unsigned shader,
|
||||
unsigned start, unsigned num,
|
||||
struct pipe_sampler_view **views)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->sampler_views[shader][start], views,
|
||||
sizeof(views[0]) * num);
|
||||
pipe->set_sampler_views(pipe, shader, start, num, views);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_shader_images(struct pipe_context *_pipe, unsigned shader,
|
||||
unsigned start, unsigned num,
|
||||
struct pipe_image_view **views)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->shader_images[shader][start], views,
|
||||
sizeof(views[0]) * num);
|
||||
pipe->set_shader_images(pipe, shader, start, num, views);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_shader_buffers(struct pipe_context *_pipe, unsigned shader,
|
||||
unsigned start, unsigned num_buffers,
|
||||
struct pipe_shader_buffer *buffers)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->shader_buffers[shader][start], buffers,
|
||||
sizeof(buffers[0]) * num_buffers);
|
||||
pipe->set_shader_buffers(pipe, shader, start, num_buffers, buffers);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_vertex_buffers(struct pipe_context *_pipe,
|
||||
unsigned start, unsigned num_buffers,
|
||||
const struct pipe_vertex_buffer *buffers)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->vertex_buffers[start], buffers,
|
||||
sizeof(buffers[0]) * num_buffers);
|
||||
pipe->set_vertex_buffers(pipe, start, num_buffers, buffers);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_index_buffer(struct pipe_context *_pipe,
|
||||
const struct pipe_index_buffer *ib)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
safe_memcpy(&dctx->index_buffer, ib, sizeof(*ib));
|
||||
pipe->set_index_buffer(pipe, ib);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_set_stream_output_targets(struct pipe_context *_pipe,
|
||||
unsigned num_targets,
|
||||
struct pipe_stream_output_target **tgs,
|
||||
const unsigned *offsets)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
dctx->num_so_targets = num_targets;
|
||||
safe_memcpy(dctx->so_targets, tgs, sizeof(*tgs) * num_targets);
|
||||
safe_memcpy(dctx->so_offsets, offsets, sizeof(*offsets) * num_targets);
|
||||
pipe->set_stream_output_targets(pipe, num_targets, tgs, offsets);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_destroy(struct pipe_context *_pipe)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
pipe->destroy(pipe);
|
||||
FREE(dctx);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* transfer
|
||||
*/
|
||||
|
||||
static void *
|
||||
dd_context_transfer_map(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource, unsigned level,
|
||||
unsigned usage, const struct pipe_box *box,
|
||||
struct pipe_transfer **transfer)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
return pipe->transfer_map(pipe, resource, level, usage, box, transfer);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_transfer_flush_region(struct pipe_context *_pipe,
|
||||
struct pipe_transfer *transfer,
|
||||
const struct pipe_box *box)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->transfer_flush_region(pipe, transfer, box);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_transfer_unmap(struct pipe_context *_pipe,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->transfer_unmap(pipe, transfer);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_transfer_inline_write(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource,
|
||||
unsigned level, unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
const void *data, unsigned stride,
|
||||
unsigned layer_stride)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->transfer_inline_write(pipe, resource, level, usage, box, data,
|
||||
stride, layer_stride);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* miscellaneous
|
||||
*/
|
||||
|
||||
static void
|
||||
dd_context_texture_barrier(struct pipe_context *_pipe)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->texture_barrier(pipe);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_memory_barrier(struct pipe_context *_pipe, unsigned flags)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->memory_barrier(pipe, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_get_sample_position(struct pipe_context *_pipe,
|
||||
unsigned sample_count, unsigned sample_index,
|
||||
float *out_value)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
return pipe->get_sample_position(pipe, sample_count, sample_index,
|
||||
out_value);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_invalidate_resource(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
pipe->invalidate_resource(pipe, resource);
|
||||
}
|
||||
|
||||
static enum pipe_reset_status
|
||||
dd_context_get_device_reset_status(struct pipe_context *_pipe)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
return pipe->get_device_reset_status(pipe);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_dump_debug_state(struct pipe_context *_pipe, FILE *stream,
|
||||
unsigned flags)
|
||||
{
|
||||
struct pipe_context *pipe = dd_context(_pipe)->pipe;
|
||||
|
||||
return pipe->dump_debug_state(pipe, stream, flags);
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe)
|
||||
{
|
||||
struct dd_context *dctx;
|
||||
|
||||
if (!pipe)
|
||||
return NULL;
|
||||
|
||||
dctx = CALLOC_STRUCT(dd_context);
|
||||
if (!dctx) {
|
||||
pipe->destroy(pipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dctx->pipe = pipe;
|
||||
dctx->base.priv = pipe->priv; /* expose wrapped priv data */
|
||||
dctx->base.screen = &dscreen->base;
|
||||
|
||||
dctx->base.destroy = dd_context_destroy;
|
||||
|
||||
CTX_INIT(render_condition);
|
||||
CTX_INIT(create_query);
|
||||
CTX_INIT(destroy_query);
|
||||
CTX_INIT(begin_query);
|
||||
CTX_INIT(end_query);
|
||||
CTX_INIT(get_query_result);
|
||||
CTX_INIT(create_blend_state);
|
||||
CTX_INIT(bind_blend_state);
|
||||
CTX_INIT(delete_blend_state);
|
||||
CTX_INIT(create_sampler_state);
|
||||
CTX_INIT(bind_sampler_states);
|
||||
CTX_INIT(delete_sampler_state);
|
||||
CTX_INIT(create_rasterizer_state);
|
||||
CTX_INIT(bind_rasterizer_state);
|
||||
CTX_INIT(delete_rasterizer_state);
|
||||
CTX_INIT(create_depth_stencil_alpha_state);
|
||||
CTX_INIT(bind_depth_stencil_alpha_state);
|
||||
CTX_INIT(delete_depth_stencil_alpha_state);
|
||||
CTX_INIT(create_fs_state);
|
||||
CTX_INIT(bind_fs_state);
|
||||
CTX_INIT(delete_fs_state);
|
||||
CTX_INIT(create_vs_state);
|
||||
CTX_INIT(bind_vs_state);
|
||||
CTX_INIT(delete_vs_state);
|
||||
CTX_INIT(create_gs_state);
|
||||
CTX_INIT(bind_gs_state);
|
||||
CTX_INIT(delete_gs_state);
|
||||
CTX_INIT(create_tcs_state);
|
||||
CTX_INIT(bind_tcs_state);
|
||||
CTX_INIT(delete_tcs_state);
|
||||
CTX_INIT(create_tes_state);
|
||||
CTX_INIT(bind_tes_state);
|
||||
CTX_INIT(delete_tes_state);
|
||||
CTX_INIT(create_vertex_elements_state);
|
||||
CTX_INIT(bind_vertex_elements_state);
|
||||
CTX_INIT(delete_vertex_elements_state);
|
||||
CTX_INIT(set_blend_color);
|
||||
CTX_INIT(set_stencil_ref);
|
||||
CTX_INIT(set_sample_mask);
|
||||
CTX_INIT(set_min_samples);
|
||||
CTX_INIT(set_clip_state);
|
||||
CTX_INIT(set_constant_buffer);
|
||||
CTX_INIT(set_framebuffer_state);
|
||||
CTX_INIT(set_polygon_stipple);
|
||||
CTX_INIT(set_scissor_states);
|
||||
CTX_INIT(set_viewport_states);
|
||||
CTX_INIT(set_sampler_views);
|
||||
CTX_INIT(set_tess_state);
|
||||
CTX_INIT(set_shader_buffers);
|
||||
CTX_INIT(set_shader_images);
|
||||
CTX_INIT(set_vertex_buffers);
|
||||
CTX_INIT(set_index_buffer);
|
||||
CTX_INIT(create_stream_output_target);
|
||||
CTX_INIT(stream_output_target_destroy);
|
||||
CTX_INIT(set_stream_output_targets);
|
||||
CTX_INIT(create_sampler_view);
|
||||
CTX_INIT(sampler_view_destroy);
|
||||
CTX_INIT(create_surface);
|
||||
CTX_INIT(surface_destroy);
|
||||
CTX_INIT(create_image_view);
|
||||
CTX_INIT(image_view_destroy);
|
||||
CTX_INIT(transfer_map);
|
||||
CTX_INIT(transfer_flush_region);
|
||||
CTX_INIT(transfer_unmap);
|
||||
CTX_INIT(transfer_inline_write);
|
||||
CTX_INIT(texture_barrier);
|
||||
CTX_INIT(memory_barrier);
|
||||
/* create_video_codec */
|
||||
/* create_video_buffer */
|
||||
/* create_compute_state */
|
||||
/* bind_compute_state */
|
||||
/* delete_compute_state */
|
||||
/* set_compute_resources */
|
||||
/* set_global_binding */
|
||||
CTX_INIT(get_sample_position);
|
||||
CTX_INIT(invalidate_resource);
|
||||
CTX_INIT(get_device_reset_status);
|
||||
CTX_INIT(dump_debug_state);
|
||||
|
||||
dd_init_draw_functions(dctx);
|
||||
|
||||
dctx->sample_mask = ~0;
|
||||
return &dctx->base;
|
||||
}
|
@@ -1,807 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "dd_pipe.h"
|
||||
|
||||
#include "util/u_dump.h"
|
||||
#include "util/u_format.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
#include "os/os_process.h"
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
enum call_type
|
||||
{
|
||||
CALL_DRAW_VBO,
|
||||
CALL_RESOURCE_COPY_REGION,
|
||||
CALL_BLIT,
|
||||
CALL_FLUSH_RESOURCE,
|
||||
CALL_CLEAR,
|
||||
CALL_CLEAR_BUFFER,
|
||||
CALL_CLEAR_RENDER_TARGET,
|
||||
CALL_CLEAR_DEPTH_STENCIL,
|
||||
};
|
||||
|
||||
struct call_resource_copy_region
|
||||
{
|
||||
struct pipe_resource *dst;
|
||||
unsigned dst_level;
|
||||
unsigned dstx, dsty, dstz;
|
||||
struct pipe_resource *src;
|
||||
unsigned src_level;
|
||||
const struct pipe_box *src_box;
|
||||
};
|
||||
|
||||
struct call_clear
|
||||
{
|
||||
unsigned buffers;
|
||||
const union pipe_color_union *color;
|
||||
double depth;
|
||||
unsigned stencil;
|
||||
};
|
||||
|
||||
struct call_clear_buffer
|
||||
{
|
||||
struct pipe_resource *res;
|
||||
unsigned offset;
|
||||
unsigned size;
|
||||
const void *clear_value;
|
||||
int clear_value_size;
|
||||
};
|
||||
|
||||
struct dd_call
|
||||
{
|
||||
enum call_type type;
|
||||
|
||||
union {
|
||||
struct pipe_draw_info draw_vbo;
|
||||
struct call_resource_copy_region resource_copy_region;
|
||||
struct pipe_blit_info blit;
|
||||
struct pipe_resource *flush_resource;
|
||||
struct call_clear clear;
|
||||
struct call_clear_buffer clear_buffer;
|
||||
} info;
|
||||
};
|
||||
|
||||
|
||||
static FILE *
|
||||
dd_get_file_stream(struct dd_context *dctx)
|
||||
{
|
||||
struct pipe_screen *screen = dctx->pipe->screen;
|
||||
static unsigned index;
|
||||
char proc_name[128], dir[256], name[512];
|
||||
FILE *f;
|
||||
|
||||
if (!os_get_process_name(proc_name, sizeof(proc_name))) {
|
||||
fprintf(stderr, "dd: can't get the process name\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(dir, sizeof(dir), "%s/"DD_DIR, debug_get_option("HOME", "."));
|
||||
|
||||
if (mkdir(dir, 0774) && errno != EEXIST) {
|
||||
fprintf(stderr, "dd: can't create a directory (%i)\n", errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(name, sizeof(name), "%s/%s_%u_%08u", dir, proc_name, getpid(), index++);
|
||||
f = fopen(name, "w");
|
||||
if (!f) {
|
||||
fprintf(stderr, "dd: can't open file %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fprintf(f, "Driver vendor: %s\n", screen->get_vendor(screen));
|
||||
fprintf(f, "Device vendor: %s\n", screen->get_device_vendor(screen));
|
||||
fprintf(f, "Device name: %s\n\n", screen->get_name(screen));
|
||||
return f;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_close_file_stream(FILE *f)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
dd_num_active_viewports(struct dd_context *dctx)
|
||||
{
|
||||
struct tgsi_shader_info info;
|
||||
const struct tgsi_token *tokens;
|
||||
|
||||
if (dctx->shaders[PIPE_SHADER_GEOMETRY])
|
||||
tokens = dctx->shaders[PIPE_SHADER_GEOMETRY]->state.shader.tokens;
|
||||
else if (dctx->shaders[PIPE_SHADER_TESS_EVAL])
|
||||
tokens = dctx->shaders[PIPE_SHADER_TESS_EVAL]->state.shader.tokens;
|
||||
else if (dctx->shaders[PIPE_SHADER_VERTEX])
|
||||
tokens = dctx->shaders[PIPE_SHADER_VERTEX]->state.shader.tokens;
|
||||
else
|
||||
return 1;
|
||||
|
||||
tgsi_scan_shader(tokens, &info);
|
||||
return info.writes_viewport_index ? PIPE_MAX_VIEWPORTS : 1;
|
||||
}
|
||||
|
||||
#define COLOR_RESET "\033[0m"
|
||||
#define COLOR_SHADER "\033[1;32m"
|
||||
#define COLOR_STATE "\033[1;33m"
|
||||
|
||||
#define DUMP(name, var) do { \
|
||||
fprintf(f, COLOR_STATE #name ": " COLOR_RESET); \
|
||||
util_dump_##name(f, var); \
|
||||
fprintf(f, "\n"); \
|
||||
} while(0)
|
||||
|
||||
#define DUMP_I(name, var, i) do { \
|
||||
fprintf(f, COLOR_STATE #name " %i: " COLOR_RESET, i); \
|
||||
util_dump_##name(f, var); \
|
||||
fprintf(f, "\n"); \
|
||||
} while(0)
|
||||
|
||||
#define DUMP_M(name, var, member) do { \
|
||||
fprintf(f, " " #member ": "); \
|
||||
util_dump_##name(f, (var)->member); \
|
||||
fprintf(f, "\n"); \
|
||||
} while(0)
|
||||
|
||||
#define DUMP_M_ADDR(name, var, member) do { \
|
||||
fprintf(f, " " #member ": "); \
|
||||
util_dump_##name(f, &(var)->member); \
|
||||
fprintf(f, "\n"); \
|
||||
} while(0)
|
||||
|
||||
static void
|
||||
print_named_value(FILE *f, const char *name, int value)
|
||||
{
|
||||
fprintf(f, COLOR_STATE "%s" COLOR_RESET " = %i\n", name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
print_named_xvalue(FILE *f, const char *name, int value)
|
||||
{
|
||||
fprintf(f, COLOR_STATE "%s" COLOR_RESET " = 0x%08x\n", name, value);
|
||||
}
|
||||
|
||||
static void
|
||||
util_dump_uint(FILE *f, unsigned i)
|
||||
{
|
||||
fprintf(f, "%u", i);
|
||||
}
|
||||
|
||||
static void
|
||||
util_dump_hex(FILE *f, unsigned i)
|
||||
{
|
||||
fprintf(f, "0x%x", i);
|
||||
}
|
||||
|
||||
static void
|
||||
util_dump_double(FILE *f, double d)
|
||||
{
|
||||
fprintf(f, "%f", d);
|
||||
}
|
||||
|
||||
static void
|
||||
util_dump_format(FILE *f, enum pipe_format format)
|
||||
{
|
||||
fprintf(f, "%s", util_format_name(format));
|
||||
}
|
||||
|
||||
static void
|
||||
util_dump_color_union(FILE *f, const union pipe_color_union *color)
|
||||
{
|
||||
fprintf(f, "{f = {%f, %f, %f, %f}, ui = {%u, %u, %u, %u}",
|
||||
color->f[0], color->f[1], color->f[2], color->f[3],
|
||||
color->ui[0], color->ui[1], color->ui[2], color->ui[3]);
|
||||
}
|
||||
|
||||
static void
|
||||
util_dump_query(FILE *f, struct dd_query *query)
|
||||
{
|
||||
if (query->type >= PIPE_QUERY_DRIVER_SPECIFIC)
|
||||
fprintf(f, "PIPE_QUERY_DRIVER_SPECIFIC + %i",
|
||||
query->type - PIPE_QUERY_DRIVER_SPECIFIC);
|
||||
else
|
||||
fprintf(f, "%s", util_dump_query_type(query->type, false));
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_render_condition(struct dd_context *dctx, FILE *f)
|
||||
{
|
||||
if (dctx->render_cond.query) {
|
||||
fprintf(f, "render condition:\n");
|
||||
DUMP_M(query, &dctx->render_cond, query);
|
||||
DUMP_M(uint, &dctx->render_cond, condition);
|
||||
DUMP_M(uint, &dctx->render_cond, mode);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_draw_vbo(struct dd_context *dctx, struct pipe_draw_info *info, FILE *f)
|
||||
{
|
||||
int sh, i;
|
||||
const char *shader_str[PIPE_SHADER_TYPES];
|
||||
|
||||
shader_str[PIPE_SHADER_VERTEX] = "VERTEX";
|
||||
shader_str[PIPE_SHADER_TESS_CTRL] = "TESS_CTRL";
|
||||
shader_str[PIPE_SHADER_TESS_EVAL] = "TESS_EVAL";
|
||||
shader_str[PIPE_SHADER_GEOMETRY] = "GEOMETRY";
|
||||
shader_str[PIPE_SHADER_FRAGMENT] = "FRAGMENT";
|
||||
shader_str[PIPE_SHADER_COMPUTE] = "COMPUTE";
|
||||
|
||||
DUMP(draw_info, info);
|
||||
if (info->indexed) {
|
||||
DUMP(index_buffer, &dctx->index_buffer);
|
||||
if (dctx->index_buffer.buffer)
|
||||
DUMP_M(resource, &dctx->index_buffer, buffer);
|
||||
}
|
||||
if (info->count_from_stream_output)
|
||||
DUMP_M(stream_output_target, info,
|
||||
count_from_stream_output);
|
||||
if (info->indirect)
|
||||
DUMP_M(resource, info, indirect);
|
||||
fprintf(f, "\n");
|
||||
|
||||
/* TODO: dump active queries */
|
||||
|
||||
dd_dump_render_condition(dctx, f);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_ATTRIBS; i++)
|
||||
if (dctx->vertex_buffers[i].buffer ||
|
||||
dctx->vertex_buffers[i].user_buffer) {
|
||||
DUMP_I(vertex_buffer, &dctx->vertex_buffers[i], i);
|
||||
if (dctx->vertex_buffers[i].buffer)
|
||||
DUMP_M(resource, &dctx->vertex_buffers[i], buffer);
|
||||
}
|
||||
|
||||
if (dctx->velems) {
|
||||
print_named_value(f, "num vertex elements",
|
||||
dctx->velems->state.velems.count);
|
||||
for (i = 0; i < dctx->velems->state.velems.count; i++) {
|
||||
fprintf(f, " ");
|
||||
DUMP_I(vertex_element, &dctx->velems->state.velems.velems[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
print_named_value(f, "num stream output targets", dctx->num_so_targets);
|
||||
for (i = 0; i < dctx->num_so_targets; i++)
|
||||
if (dctx->so_targets[i]) {
|
||||
DUMP_I(stream_output_target, dctx->so_targets[i], i);
|
||||
DUMP_M(resource, dctx->so_targets[i], buffer);
|
||||
fprintf(f, " offset = %i\n", dctx->so_offsets[i]);
|
||||
}
|
||||
|
||||
fprintf(f, "\n");
|
||||
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
|
||||
if (sh == PIPE_SHADER_COMPUTE)
|
||||
continue;
|
||||
|
||||
if (sh == PIPE_SHADER_TESS_CTRL &&
|
||||
!dctx->shaders[PIPE_SHADER_TESS_CTRL] &&
|
||||
dctx->shaders[PIPE_SHADER_TESS_EVAL])
|
||||
fprintf(f, "tess_state: {default_outer_level = {%f, %f, %f, %f}, "
|
||||
"default_inner_level = {%f, %f}}\n",
|
||||
dctx->tess_default_levels[0],
|
||||
dctx->tess_default_levels[1],
|
||||
dctx->tess_default_levels[2],
|
||||
dctx->tess_default_levels[3],
|
||||
dctx->tess_default_levels[4],
|
||||
dctx->tess_default_levels[5]);
|
||||
|
||||
if (sh == PIPE_SHADER_FRAGMENT)
|
||||
if (dctx->rs) {
|
||||
unsigned num_viewports = dd_num_active_viewports(dctx);
|
||||
|
||||
if (dctx->rs->state.rs.clip_plane_enable)
|
||||
DUMP(clip_state, &dctx->clip_state);
|
||||
|
||||
for (i = 0; i < num_viewports; i++)
|
||||
DUMP_I(viewport_state, &dctx->viewports[i], i);
|
||||
|
||||
if (dctx->rs->state.rs.scissor)
|
||||
for (i = 0; i < num_viewports; i++)
|
||||
DUMP_I(scissor_state, &dctx->scissors[i], i);
|
||||
|
||||
DUMP(rasterizer_state, &dctx->rs->state.rs);
|
||||
|
||||
if (dctx->rs->state.rs.poly_stipple_enable)
|
||||
DUMP(poly_stipple, &dctx->polygon_stipple);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
if (!dctx->shaders[sh])
|
||||
continue;
|
||||
|
||||
fprintf(f, COLOR_SHADER "begin shader: %s" COLOR_RESET "\n", shader_str[sh]);
|
||||
DUMP(shader_state, &dctx->shaders[sh]->state.shader);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++)
|
||||
if (dctx->constant_buffers[sh][i].buffer ||
|
||||
dctx->constant_buffers[sh][i].user_buffer) {
|
||||
DUMP_I(constant_buffer, &dctx->constant_buffers[sh][i], i);
|
||||
if (dctx->constant_buffers[sh][i].buffer)
|
||||
DUMP_M(resource, &dctx->constant_buffers[sh][i], buffer);
|
||||
}
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
if (dctx->sampler_states[sh][i])
|
||||
DUMP_I(sampler_state, &dctx->sampler_states[sh][i]->state.sampler, i);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
if (dctx->sampler_views[sh][i]) {
|
||||
DUMP_I(sampler_view, dctx->sampler_views[sh][i], i);
|
||||
DUMP_M(resource, dctx->sampler_views[sh][i], texture);
|
||||
}
|
||||
|
||||
/* TODO: print shader images */
|
||||
/* TODO: print shader buffers */
|
||||
|
||||
fprintf(f, COLOR_SHADER "end shader: %s" COLOR_RESET "\n\n", shader_str[sh]);
|
||||
}
|
||||
|
||||
if (dctx->dsa)
|
||||
DUMP(depth_stencil_alpha_state, &dctx->dsa->state.dsa);
|
||||
DUMP(stencil_ref, &dctx->stencil_ref);
|
||||
|
||||
if (dctx->blend)
|
||||
DUMP(blend_state, &dctx->blend->state.blend);
|
||||
DUMP(blend_color, &dctx->blend_color);
|
||||
|
||||
print_named_value(f, "min_samples", dctx->min_samples);
|
||||
print_named_xvalue(f, "sample_mask", dctx->sample_mask);
|
||||
fprintf(f, "\n");
|
||||
|
||||
DUMP(framebuffer_state, &dctx->framebuffer_state);
|
||||
for (i = 0; i < dctx->framebuffer_state.nr_cbufs; i++)
|
||||
if (dctx->framebuffer_state.cbufs[i]) {
|
||||
fprintf(f, " " COLOR_STATE "cbufs[%i]:" COLOR_RESET "\n ", i);
|
||||
DUMP(surface, dctx->framebuffer_state.cbufs[i]);
|
||||
fprintf(f, " ");
|
||||
DUMP(resource, dctx->framebuffer_state.cbufs[i]->texture);
|
||||
}
|
||||
if (dctx->framebuffer_state.zsbuf) {
|
||||
fprintf(f, " " COLOR_STATE "zsbuf:" COLOR_RESET "\n ");
|
||||
DUMP(surface, dctx->framebuffer_state.zsbuf);
|
||||
fprintf(f, " ");
|
||||
DUMP(resource, dctx->framebuffer_state.zsbuf->texture);
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_resource_copy_region(struct dd_context *dctx,
|
||||
struct call_resource_copy_region *info,
|
||||
FILE *f)
|
||||
{
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
DUMP_M(resource, info, dst);
|
||||
DUMP_M(uint, info, dst_level);
|
||||
DUMP_M(uint, info, dstx);
|
||||
DUMP_M(uint, info, dsty);
|
||||
DUMP_M(uint, info, dstz);
|
||||
DUMP_M(resource, info, src);
|
||||
DUMP_M(uint, info, src_level);
|
||||
DUMP_M(box, info, src_box);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_blit(struct dd_context *dctx, struct pipe_blit_info *info, FILE *f)
|
||||
{
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
DUMP_M(resource, info, dst.resource);
|
||||
DUMP_M(uint, info, dst.level);
|
||||
DUMP_M_ADDR(box, info, dst.box);
|
||||
DUMP_M(format, info, dst.format);
|
||||
|
||||
DUMP_M(resource, info, src.resource);
|
||||
DUMP_M(uint, info, src.level);
|
||||
DUMP_M_ADDR(box, info, src.box);
|
||||
DUMP_M(format, info, src.format);
|
||||
|
||||
DUMP_M(hex, info, mask);
|
||||
DUMP_M(uint, info, filter);
|
||||
DUMP_M(uint, info, scissor_enable);
|
||||
DUMP_M_ADDR(scissor_state, info, scissor);
|
||||
DUMP_M(uint, info, render_condition_enable);
|
||||
|
||||
if (info->render_condition_enable)
|
||||
dd_dump_render_condition(dctx, f);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_flush_resource(struct dd_context *dctx, struct pipe_resource *res,
|
||||
FILE *f)
|
||||
{
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
DUMP(resource, res);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_clear(struct dd_context *dctx, struct call_clear *info, FILE *f)
|
||||
{
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
DUMP_M(uint, info, buffers);
|
||||
DUMP_M(color_union, info, color);
|
||||
DUMP_M(double, info, depth);
|
||||
DUMP_M(hex, info, stencil);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_clear_buffer(struct dd_context *dctx, struct call_clear_buffer *info,
|
||||
FILE *f)
|
||||
{
|
||||
int i;
|
||||
const char *value = (const char*)info->clear_value;
|
||||
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
DUMP_M(resource, info, res);
|
||||
DUMP_M(uint, info, offset);
|
||||
DUMP_M(uint, info, size);
|
||||
DUMP_M(uint, info, clear_value_size);
|
||||
|
||||
fprintf(f, " clear_value:");
|
||||
for (i = 0; i < info->clear_value_size; i++)
|
||||
fprintf(f, " %02x", value[i]);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_clear_render_target(struct dd_context *dctx, FILE *f)
|
||||
{
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_clear_depth_stencil(struct dd_context *dctx, FILE *f)
|
||||
{
|
||||
fprintf(f, "%s:\n", __func__+8);
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_driver_state(struct dd_context *dctx, FILE *f, unsigned flags)
|
||||
{
|
||||
if (dctx->pipe->dump_debug_state) {
|
||||
fprintf(f,"\n\n**************************************************"
|
||||
"***************************\n");
|
||||
fprintf(f, "Driver-specific state:\n\n");
|
||||
dctx->pipe->dump_debug_state(dctx->pipe, f, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dd_dump_call(struct dd_context *dctx, struct dd_call *call, unsigned flags)
|
||||
{
|
||||
FILE *f = dd_get_file_stream(dctx);
|
||||
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
switch (call->type) {
|
||||
case CALL_DRAW_VBO:
|
||||
dd_dump_draw_vbo(dctx, &call->info.draw_vbo, f);
|
||||
break;
|
||||
case CALL_RESOURCE_COPY_REGION:
|
||||
dd_dump_resource_copy_region(dctx, &call->info.resource_copy_region, f);
|
||||
break;
|
||||
case CALL_BLIT:
|
||||
dd_dump_blit(dctx, &call->info.blit, f);
|
||||
break;
|
||||
case CALL_FLUSH_RESOURCE:
|
||||
dd_dump_flush_resource(dctx, call->info.flush_resource, f);
|
||||
break;
|
||||
case CALL_CLEAR:
|
||||
dd_dump_clear(dctx, &call->info.clear, f);
|
||||
break;
|
||||
case CALL_CLEAR_BUFFER:
|
||||
dd_dump_clear_buffer(dctx, &call->info.clear_buffer, f);
|
||||
break;
|
||||
case CALL_CLEAR_RENDER_TARGET:
|
||||
dd_dump_clear_render_target(dctx, f);
|
||||
break;
|
||||
case CALL_CLEAR_DEPTH_STENCIL:
|
||||
dd_dump_clear_depth_stencil(dctx, f);
|
||||
}
|
||||
|
||||
dd_dump_driver_state(dctx, f, flags);
|
||||
dd_close_file_stream(f);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_kill_process(void)
|
||||
{
|
||||
sync();
|
||||
fprintf(stderr, "dd: Aborting the process...\n");
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
abort();
|
||||
}
|
||||
|
||||
static bool
|
||||
dd_flush_and_check_hang(struct dd_context *dctx,
|
||||
struct pipe_fence_handle **flush_fence,
|
||||
unsigned flush_flags)
|
||||
{
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
uint64_t timeout_ms = dd_screen(dctx->base.screen)->timeout_ms;
|
||||
bool idle;
|
||||
|
||||
assert(timeout_ms > 0);
|
||||
|
||||
pipe->flush(pipe, &fence, flush_flags);
|
||||
if (flush_fence)
|
||||
screen->fence_reference(screen, flush_fence, fence);
|
||||
if (!fence)
|
||||
return false;
|
||||
|
||||
idle = screen->fence_finish(screen, fence, timeout_ms * 1000000);
|
||||
screen->fence_reference(screen, &fence, NULL);
|
||||
if (!idle)
|
||||
fprintf(stderr, "dd: GPU hang detected!\n");
|
||||
return !idle;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_flush_and_handle_hang(struct dd_context *dctx,
|
||||
struct pipe_fence_handle **fence, unsigned flags,
|
||||
const char *cause)
|
||||
{
|
||||
if (dd_flush_and_check_hang(dctx, fence, flags)) {
|
||||
FILE *f = dd_get_file_stream(dctx);
|
||||
|
||||
if (f) {
|
||||
fprintf(f, "dd: %s.\n", cause);
|
||||
dd_dump_driver_state(dctx, f, PIPE_DEBUG_DEVICE_IS_HUNG);
|
||||
dd_close_file_stream(f);
|
||||
}
|
||||
|
||||
/* Terminate the process to prevent future hangs. */
|
||||
dd_kill_process();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_flush(struct pipe_context *_pipe,
|
||||
struct pipe_fence_handle **fence, unsigned flags)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
|
||||
switch (dd_screen(dctx->base.screen)->mode) {
|
||||
case DD_DETECT_HANGS:
|
||||
dd_flush_and_handle_hang(dctx, fence, flags,
|
||||
"GPU hang detected in pipe->flush()");
|
||||
break;
|
||||
case DD_DUMP_ALL_CALLS:
|
||||
pipe->flush(pipe, fence, flags);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dd_before_draw(struct dd_context *dctx)
|
||||
{
|
||||
if (dd_screen(dctx->base.screen)->mode == DD_DETECT_HANGS &&
|
||||
!dd_screen(dctx->base.screen)->no_flush)
|
||||
dd_flush_and_handle_hang(dctx, NULL, 0,
|
||||
"GPU hang most likely caused by internal "
|
||||
"driver commands");
|
||||
}
|
||||
|
||||
static void
|
||||
dd_after_draw(struct dd_context *dctx, struct dd_call *call)
|
||||
{
|
||||
switch (dd_screen(dctx->base.screen)->mode) {
|
||||
case DD_DETECT_HANGS:
|
||||
if (!dd_screen(dctx->base.screen)->no_flush &&
|
||||
dd_flush_and_check_hang(dctx, NULL, 0)) {
|
||||
dd_dump_call(dctx, call, PIPE_DEBUG_DEVICE_IS_HUNG);
|
||||
|
||||
/* Terminate the process to prevent future hangs. */
|
||||
dd_kill_process();
|
||||
}
|
||||
break;
|
||||
case DD_DUMP_ALL_CALLS:
|
||||
dd_dump_call(dctx, call, 0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_draw_vbo(struct pipe_context *_pipe,
|
||||
const struct pipe_draw_info *info)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_DRAW_VBO;
|
||||
call.info.draw_vbo = *info;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->draw_vbo(pipe, info);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_resource_copy_region(struct pipe_context *_pipe,
|
||||
struct pipe_resource *dst, unsigned dst_level,
|
||||
unsigned dstx, unsigned dsty, unsigned dstz,
|
||||
struct pipe_resource *src, unsigned src_level,
|
||||
const struct pipe_box *src_box)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_RESOURCE_COPY_REGION;
|
||||
call.info.resource_copy_region.dst = dst;
|
||||
call.info.resource_copy_region.dst_level = dst_level;
|
||||
call.info.resource_copy_region.dstx = dstx;
|
||||
call.info.resource_copy_region.dsty = dsty;
|
||||
call.info.resource_copy_region.dstz = dstz;
|
||||
call.info.resource_copy_region.src = src;
|
||||
call.info.resource_copy_region.src_level = src_level;
|
||||
call.info.resource_copy_region.src_box = src_box;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->resource_copy_region(pipe,
|
||||
dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_blit(struct pipe_context *_pipe, const struct pipe_blit_info *info)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_BLIT;
|
||||
call.info.blit = *info;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->blit(pipe, info);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_flush_resource(struct pipe_context *_pipe,
|
||||
struct pipe_resource *resource)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_FLUSH_RESOURCE;
|
||||
call.info.flush_resource = resource;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->flush_resource(pipe, resource);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_clear(struct pipe_context *_pipe, unsigned buffers,
|
||||
const union pipe_color_union *color, double depth,
|
||||
unsigned stencil)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_CLEAR;
|
||||
call.info.clear.buffers = buffers;
|
||||
call.info.clear.color = color;
|
||||
call.info.clear.depth = depth;
|
||||
call.info.clear.stencil = stencil;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->clear(pipe, buffers, color, depth, stencil);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_clear_render_target(struct pipe_context *_pipe,
|
||||
struct pipe_surface *dst,
|
||||
const union pipe_color_union *color,
|
||||
unsigned dstx, unsigned dsty,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_CLEAR_RENDER_TARGET;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->clear_render_target(pipe, dst, color, dstx, dsty, width, height);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_clear_depth_stencil(struct pipe_context *_pipe,
|
||||
struct pipe_surface *dst, unsigned clear_flags,
|
||||
double depth, unsigned stencil, unsigned dstx,
|
||||
unsigned dsty, unsigned width, unsigned height)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_CLEAR_DEPTH_STENCIL;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->clear_depth_stencil(pipe, dst, clear_flags, depth, stencil,
|
||||
dstx, dsty, width, height);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_context_clear_buffer(struct pipe_context *_pipe, struct pipe_resource *res,
|
||||
unsigned offset, unsigned size,
|
||||
const void *clear_value, int clear_value_size)
|
||||
{
|
||||
struct dd_context *dctx = dd_context(_pipe);
|
||||
struct pipe_context *pipe = dctx->pipe;
|
||||
struct dd_call call;
|
||||
|
||||
call.type = CALL_CLEAR_BUFFER;
|
||||
call.info.clear_buffer.res = res;
|
||||
call.info.clear_buffer.offset = offset;
|
||||
call.info.clear_buffer.size = size;
|
||||
call.info.clear_buffer.clear_value = clear_value;
|
||||
call.info.clear_buffer.clear_value_size = clear_value_size;
|
||||
|
||||
dd_before_draw(dctx);
|
||||
pipe->clear_buffer(pipe, res, offset, size, clear_value, clear_value_size);
|
||||
dd_after_draw(dctx, &call);
|
||||
}
|
||||
|
||||
void
|
||||
dd_init_draw_functions(struct dd_context *dctx)
|
||||
{
|
||||
CTX_INIT(flush);
|
||||
CTX_INIT(draw_vbo);
|
||||
CTX_INIT(resource_copy_region);
|
||||
CTX_INIT(blit);
|
||||
CTX_INIT(clear);
|
||||
CTX_INIT(clear_render_target);
|
||||
CTX_INIT(clear_depth_stencil);
|
||||
CTX_INIT(clear_buffer);
|
||||
CTX_INIT(flush_resource);
|
||||
/* launch_grid */
|
||||
}
|
@@ -1,141 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef DD_H_
|
||||
#define DD_H_
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
/* name of the directory in home */
|
||||
#define DD_DIR "ddebug_dumps"
|
||||
|
||||
enum dd_mode {
|
||||
DD_DETECT_HANGS,
|
||||
DD_DUMP_ALL_CALLS
|
||||
};
|
||||
|
||||
struct dd_screen
|
||||
{
|
||||
struct pipe_screen base;
|
||||
struct pipe_screen *screen;
|
||||
unsigned timeout_ms;
|
||||
enum dd_mode mode;
|
||||
bool no_flush;
|
||||
};
|
||||
|
||||
struct dd_query
|
||||
{
|
||||
unsigned type;
|
||||
struct pipe_query *query;
|
||||
};
|
||||
|
||||
struct dd_state
|
||||
{
|
||||
void *cso;
|
||||
|
||||
union {
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_depth_stencil_alpha_state dsa;
|
||||
struct pipe_rasterizer_state rs;
|
||||
struct pipe_sampler_state sampler;
|
||||
struct {
|
||||
struct pipe_vertex_element velems[PIPE_MAX_ATTRIBS];
|
||||
unsigned count;
|
||||
} velems;
|
||||
struct pipe_shader_state shader;
|
||||
} state;
|
||||
};
|
||||
|
||||
struct dd_context
|
||||
{
|
||||
struct pipe_context base;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
struct {
|
||||
struct dd_query *query;
|
||||
bool condition;
|
||||
unsigned mode;
|
||||
} render_cond;
|
||||
|
||||
struct pipe_index_buffer index_buffer;
|
||||
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS];
|
||||
|
||||
unsigned num_so_targets;
|
||||
struct pipe_stream_output_target *so_targets[PIPE_MAX_SO_BUFFERS];
|
||||
unsigned so_offsets[PIPE_MAX_SO_BUFFERS];
|
||||
|
||||
struct dd_state *shaders[PIPE_SHADER_TYPES];
|
||||
struct pipe_constant_buffer constant_buffers[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
|
||||
struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
struct dd_state *sampler_states[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
struct pipe_image_view *shader_images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
|
||||
struct pipe_shader_buffer shader_buffers[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
|
||||
|
||||
struct dd_state *velems;
|
||||
struct dd_state *rs;
|
||||
struct dd_state *dsa;
|
||||
struct dd_state *blend;
|
||||
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_stencil_ref stencil_ref;
|
||||
unsigned sample_mask;
|
||||
unsigned min_samples;
|
||||
struct pipe_clip_state clip_state;
|
||||
struct pipe_framebuffer_state framebuffer_state;
|
||||
struct pipe_poly_stipple polygon_stipple;
|
||||
struct pipe_scissor_state scissors[PIPE_MAX_VIEWPORTS];
|
||||
struct pipe_viewport_state viewports[PIPE_MAX_VIEWPORTS];
|
||||
float tess_default_levels[6];
|
||||
};
|
||||
|
||||
|
||||
struct pipe_context *
|
||||
dd_context_create(struct dd_screen *dscreen, struct pipe_context *pipe);
|
||||
|
||||
void
|
||||
dd_init_draw_functions(struct dd_context *dctx);
|
||||
|
||||
|
||||
static inline struct dd_context *
|
||||
dd_context(struct pipe_context *pipe)
|
||||
{
|
||||
return (struct dd_context *)pipe;
|
||||
}
|
||||
|
||||
static inline struct dd_screen *
|
||||
dd_screen(struct pipe_screen *screen)
|
||||
{
|
||||
return (struct dd_screen*)screen;
|
||||
}
|
||||
|
||||
|
||||
#define CTX_INIT(_member) \
|
||||
dctx->base._member = dctx->pipe->_member ? dd_context_##_member : NULL
|
||||
|
||||
#endif /* DD_H_ */
|
@@ -1,36 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
* Copyright 2010 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef DD_PUBLIC_H_
|
||||
#define DD_PUBLIC_H_
|
||||
|
||||
struct pipe_screen;
|
||||
|
||||
struct pipe_screen *
|
||||
ddebug_screen_create(struct pipe_screen *screen);
|
||||
|
||||
#endif /* DD_PUBLIC_H_ */
|
@@ -1,353 +0,0 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 VMware, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include "dd_pipe.h"
|
||||
#include "dd_public.h"
|
||||
#include "util/u_memory.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static const char *
|
||||
dd_screen_get_name(struct pipe_screen *_screen)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_name(screen);
|
||||
}
|
||||
|
||||
static const char *
|
||||
dd_screen_get_vendor(struct pipe_screen *_screen)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_vendor(screen);
|
||||
}
|
||||
|
||||
static const char *
|
||||
dd_screen_get_device_vendor(struct pipe_screen *_screen)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_device_vendor(screen);
|
||||
}
|
||||
|
||||
static int
|
||||
dd_screen_get_param(struct pipe_screen *_screen,
|
||||
enum pipe_cap param)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_param(screen, param);
|
||||
}
|
||||
|
||||
static float
|
||||
dd_screen_get_paramf(struct pipe_screen *_screen,
|
||||
enum pipe_capf param)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_paramf(screen, param);
|
||||
}
|
||||
|
||||
static int
|
||||
dd_screen_get_shader_param(struct pipe_screen *_screen, unsigned shader,
|
||||
enum pipe_shader_cap param)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_shader_param(screen, shader, param);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
dd_screen_get_timestamp(struct pipe_screen *_screen)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_timestamp(screen);
|
||||
}
|
||||
|
||||
static struct pipe_context *
|
||||
dd_screen_context_create(struct pipe_screen *_screen, void *priv,
|
||||
unsigned flags)
|
||||
{
|
||||
struct dd_screen *dscreen = dd_screen(_screen);
|
||||
struct pipe_screen *screen = dscreen->screen;
|
||||
|
||||
flags |= PIPE_CONTEXT_DEBUG;
|
||||
|
||||
return dd_context_create(dscreen,
|
||||
screen->context_create(screen, priv, flags));
|
||||
}
|
||||
|
||||
static boolean
|
||||
dd_screen_is_format_supported(struct pipe_screen *_screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned sample_count,
|
||||
unsigned tex_usage)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->is_format_supported(screen, format, target, sample_count,
|
||||
tex_usage);
|
||||
}
|
||||
|
||||
static boolean
|
||||
dd_screen_can_create_resource(struct pipe_screen *_screen,
|
||||
const struct pipe_resource *templat)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->can_create_resource(screen, templat);
|
||||
}
|
||||
|
||||
static void
|
||||
dd_screen_flush_frontbuffer(struct pipe_screen *_screen,
|
||||
struct pipe_resource *resource,
|
||||
unsigned level, unsigned layer,
|
||||
void *context_private,
|
||||
struct pipe_box *sub_box)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
screen->flush_frontbuffer(screen, resource, level, layer, context_private,
|
||||
sub_box);
|
||||
}
|
||||
|
||||
static int
|
||||
dd_screen_get_driver_query_info(struct pipe_screen *_screen,
|
||||
unsigned index,
|
||||
struct pipe_driver_query_info *info)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_driver_query_info(screen, index, info);
|
||||
}
|
||||
|
||||
static int
|
||||
dd_screen_get_driver_query_group_info(struct pipe_screen *_screen,
|
||||
unsigned index,
|
||||
struct pipe_driver_query_group_info *info)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->get_driver_query_group_info(screen, index, info);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* resource
|
||||
*/
|
||||
|
||||
static struct pipe_resource *
|
||||
dd_screen_resource_create(struct pipe_screen *_screen,
|
||||
const struct pipe_resource *templat)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
struct pipe_resource *res = screen->resource_create(screen, templat);
|
||||
|
||||
if (!res)
|
||||
return NULL;
|
||||
res->screen = _screen;
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
dd_screen_resource_from_handle(struct pipe_screen *_screen,
|
||||
const struct pipe_resource *templ,
|
||||
struct winsys_handle *handle)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
struct pipe_resource *res =
|
||||
screen->resource_from_handle(screen, templ, handle);
|
||||
|
||||
if (!res)
|
||||
return NULL;
|
||||
res->screen = _screen;
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct pipe_resource *
|
||||
dd_screen_resource_from_user_memory(struct pipe_screen *_screen,
|
||||
const struct pipe_resource *templ,
|
||||
void *user_memory)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
struct pipe_resource *res =
|
||||
screen->resource_from_user_memory(screen, templ, user_memory);
|
||||
|
||||
if (!res)
|
||||
return NULL;
|
||||
res->screen = _screen;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
dd_screen_resource_destroy(struct pipe_screen *_screen,
|
||||
struct pipe_resource *res)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
screen->resource_destroy(screen, res);
|
||||
}
|
||||
|
||||
static boolean
|
||||
dd_screen_resource_get_handle(struct pipe_screen *_screen,
|
||||
struct pipe_resource *resource,
|
||||
struct winsys_handle *handle)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->resource_get_handle(screen, resource, handle);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* fence
|
||||
*/
|
||||
|
||||
static void
|
||||
dd_screen_fence_reference(struct pipe_screen *_screen,
|
||||
struct pipe_fence_handle **pdst,
|
||||
struct pipe_fence_handle *src)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
screen->fence_reference(screen, pdst, src);
|
||||
}
|
||||
|
||||
static boolean
|
||||
dd_screen_fence_finish(struct pipe_screen *_screen,
|
||||
struct pipe_fence_handle *fence,
|
||||
uint64_t timeout)
|
||||
{
|
||||
struct pipe_screen *screen = dd_screen(_screen)->screen;
|
||||
|
||||
return screen->fence_finish(screen, fence, timeout);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* screen
|
||||
*/
|
||||
|
||||
static void
|
||||
dd_screen_destroy(struct pipe_screen *_screen)
|
||||
{
|
||||
struct dd_screen *dscreen = dd_screen(_screen);
|
||||
struct pipe_screen *screen = dscreen->screen;
|
||||
|
||||
screen->destroy(screen);
|
||||
FREE(dscreen);
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
ddebug_screen_create(struct pipe_screen *screen)
|
||||
{
|
||||
struct dd_screen *dscreen;
|
||||
const char *option = debug_get_option("GALLIUM_DDEBUG", NULL);
|
||||
bool dump_always = option && !strcmp(option, "always");
|
||||
bool no_flush = option && strstr(option, "noflush");
|
||||
bool help = option && !strcmp(option, "help");
|
||||
unsigned timeout = 0;
|
||||
|
||||
if (help) {
|
||||
puts("Gallium driver debugger");
|
||||
puts("");
|
||||
puts("Usage:");
|
||||
puts("");
|
||||
puts(" GALLIUM_DDEBUG=always");
|
||||
puts(" Dump context and driver information after every draw call into");
|
||||
puts(" $HOME/"DD_DIR"/.");
|
||||
puts("");
|
||||
puts(" GALLIUM_DDEBUG=[timeout in ms] noflush");
|
||||
puts(" Flush and detect a device hang after every draw call based on the given");
|
||||
puts(" fence timeout and dump context and driver information into");
|
||||
puts(" $HOME/"DD_DIR"/ when a hang is detected.");
|
||||
puts(" If 'noflush' is specified, only detect hangs in pipe->flush.");
|
||||
puts("");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (!option)
|
||||
return screen;
|
||||
if (!dump_always && sscanf(option, "%u", &timeout) != 1)
|
||||
return screen;
|
||||
|
||||
dscreen = CALLOC_STRUCT(dd_screen);
|
||||
if (!dscreen)
|
||||
return NULL;
|
||||
|
||||
#define SCR_INIT(_member) \
|
||||
dscreen->base._member = screen->_member ? dd_screen_##_member : NULL
|
||||
|
||||
dscreen->base.destroy = dd_screen_destroy;
|
||||
dscreen->base.get_name = dd_screen_get_name;
|
||||
dscreen->base.get_vendor = dd_screen_get_vendor;
|
||||
dscreen->base.get_device_vendor = dd_screen_get_device_vendor;
|
||||
dscreen->base.get_param = dd_screen_get_param;
|
||||
dscreen->base.get_paramf = dd_screen_get_paramf;
|
||||
dscreen->base.get_shader_param = dd_screen_get_shader_param;
|
||||
/* get_video_param */
|
||||
/* get_compute_param */
|
||||
SCR_INIT(get_timestamp);
|
||||
dscreen->base.context_create = dd_screen_context_create;
|
||||
dscreen->base.is_format_supported = dd_screen_is_format_supported;
|
||||
/* is_video_format_supported */
|
||||
SCR_INIT(can_create_resource);
|
||||
dscreen->base.resource_create = dd_screen_resource_create;
|
||||
dscreen->base.resource_from_handle = dd_screen_resource_from_handle;
|
||||
SCR_INIT(resource_from_user_memory);
|
||||
dscreen->base.resource_get_handle = dd_screen_resource_get_handle;
|
||||
dscreen->base.resource_destroy = dd_screen_resource_destroy;
|
||||
SCR_INIT(flush_frontbuffer);
|
||||
SCR_INIT(fence_reference);
|
||||
SCR_INIT(fence_finish);
|
||||
SCR_INIT(get_driver_query_info);
|
||||
SCR_INIT(get_driver_query_group_info);
|
||||
|
||||
#undef SCR_INIT
|
||||
|
||||
dscreen->screen = screen;
|
||||
dscreen->timeout_ms = timeout;
|
||||
dscreen->mode = dump_always ? DD_DUMP_ALL_CALLS : DD_DETECT_HANGS;
|
||||
dscreen->no_flush = no_flush;
|
||||
|
||||
switch (dscreen->mode) {
|
||||
case DD_DUMP_ALL_CALLS:
|
||||
fprintf(stderr, "Gallium debugger active. Logging all calls.\n");
|
||||
break;
|
||||
case DD_DETECT_HANGS:
|
||||
fprintf(stderr, "Gallium debugger active. "
|
||||
"The hang detection timout is %i ms.\n", timeout);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return &dscreen->base;
|
||||
}
|
@@ -86,7 +86,7 @@ static const uint8_t a20x_primtypes[PIPE_PRIM_MAX] = {
|
||||
};
|
||||
|
||||
struct pipe_context *
|
||||
fd2_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||
fd2_context_create(struct pipe_screen *pscreen, void *priv)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
struct fd2_context *fd2_ctx = CALLOC_STRUCT(fd2_context);
|
||||
|
@@ -47,6 +47,6 @@ fd2_context(struct fd_context *ctx)
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
fd2_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
|
||||
fd2_context_create(struct pipe_screen *pscreen, void *priv);
|
||||
|
||||
#endif /* FD2_CONTEXT_H_ */
|
||||
|
@@ -680,7 +680,6 @@ static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460
|
||||
#define A3XX_GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE 0x00080000
|
||||
#define A3XX_GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE 0x00100000
|
||||
#define A3XX_GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE 0x00200000
|
||||
#define A3XX_GRAS_CL_CLIP_CNTL_ZERO_GB_SCALE_Z 0x00400000
|
||||
#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
|
||||
|
@@ -98,7 +98,7 @@ static const uint8_t primtypes[PIPE_PRIM_MAX] = {
|
||||
};
|
||||
|
||||
struct pipe_context *
|
||||
fd3_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||
fd3_context_create(struct pipe_screen *pscreen, void *priv)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
struct fd3_context *fd3_ctx = CALLOC_STRUCT(fd3_context);
|
||||
|
@@ -119,6 +119,6 @@ fd3_context(struct fd_context *ctx)
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
fd3_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
|
||||
fd3_context_create(struct pipe_screen *pscreen, void *priv);
|
||||
|
||||
#endif /* FD3_CONTEXT_H_ */
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -65,8 +65,7 @@ fd3_rasterizer_state_create(struct pipe_context *pctx,
|
||||
if (cso->multisample)
|
||||
TODO
|
||||
*/
|
||||
so->gras_cl_clip_cntl = A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER /* ??? */ |
|
||||
COND(cso->clip_halfz, A3XX_GRAS_CL_CLIP_CNTL_ZERO_GB_SCALE_Z);
|
||||
so->gras_cl_clip_cntl = A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER; /* ??? */
|
||||
so->gras_su_point_minmax =
|
||||
A3XX_GRAS_SU_POINT_MINMAX_MIN(psize_min) |
|
||||
A3XX_GRAS_SU_POINT_MINMAX_MAX(psize_max);
|
||||
|
@@ -96,7 +96,7 @@ static const uint8_t primtypes[PIPE_PRIM_MAX] = {
|
||||
};
|
||||
|
||||
struct pipe_context *
|
||||
fd4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||
fd4_context_create(struct pipe_screen *pscreen, void *priv)
|
||||
{
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
struct fd4_context *fd4_ctx = CALLOC_STRUCT(fd4_context);
|
||||
|
@@ -97,6 +97,6 @@ fd4_context(struct fd_context *ctx)
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
fd4_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
|
||||
fd4_context_create(struct pipe_screen *pscreen, void *priv);
|
||||
|
||||
#endif /* FD4_CONTEXT_H_ */
|
||||
|
@@ -191,7 +191,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
return 16383;
|
||||
|
||||
case PIPE_CAP_DEPTH_CLIP_DISABLE:
|
||||
case PIPE_CAP_CLIP_HALFZ:
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
|
||||
return is_a3xx(screen);
|
||||
|
||||
@@ -229,6 +228,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
|
||||
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
|
||||
case PIPE_CAP_SAMPLER_VIEW_TARGET:
|
||||
case PIPE_CAP_CLIP_HALFZ:
|
||||
case PIPE_CAP_POLYGON_OFFSET_CLAMP:
|
||||
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
|
||||
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:
|
||||
|
@@ -2312,7 +2312,7 @@ emit_instructions(struct ir3_compile *ctx)
|
||||
ctx->ir = ir3_create(ctx->compiler, ninputs, noutputs);
|
||||
|
||||
/* Create inputs in first block: */
|
||||
ctx->block = get_block(ctx, nir_start_block(fxn));
|
||||
ctx->block = get_block(ctx, fxn->start_block);
|
||||
ctx->in_block = ctx->block;
|
||||
list_addtail(&ctx->block->node, &ctx->ir->block_list);
|
||||
|
||||
|
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "ir3_nir.h"
|
||||
#include "glsl/nir/nir_builder.h"
|
||||
#include "glsl/nir/nir_control_flow.h"
|
||||
|
||||
/* Based on nir_opt_peephole_select, and hacked up to more aggressively
|
||||
* flatten anything that can be flattened
|
||||
@@ -172,7 +171,7 @@ flatten_block(nir_builder *bld, nir_block *if_block, nir_block *prev_block,
|
||||
(intr->intrinsic == nir_intrinsic_discard_if)) {
|
||||
nir_ssa_def *discard_cond;
|
||||
|
||||
bld->cursor = nir_after_instr(
|
||||
nir_builder_insert_after_instr(bld,
|
||||
nir_block_last_instr(prev_block));
|
||||
|
||||
if (invert) {
|
||||
|
@@ -155,7 +155,7 @@ static void i915_destroy(struct pipe_context *pipe)
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
i915_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
|
||||
i915_create_context(struct pipe_screen *screen, void *priv)
|
||||
{
|
||||
struct i915_context *i915;
|
||||
|
||||
|
@@ -401,7 +401,7 @@ void i915_init_string_functions( struct i915_context *i915 );
|
||||
* i915_context.c
|
||||
*/
|
||||
struct pipe_context *i915_create_context(struct pipe_screen *screen,
|
||||
void *priv, unsigned flags);
|
||||
void *priv);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
|
@@ -135,7 +135,7 @@ ilo_context_destroy(struct pipe_context *pipe)
|
||||
}
|
||||
|
||||
static struct pipe_context *
|
||||
ilo_context_create(struct pipe_screen *screen, void *priv, unsigned flags)
|
||||
ilo_context_create(struct pipe_screen *screen, void *priv)
|
||||
{
|
||||
struct ilo_screen *is = ilo_screen(screen);
|
||||
struct ilo_context *ilo;
|
||||
|
@@ -128,8 +128,7 @@ llvmpipe_render_condition ( struct pipe_context *pipe,
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
llvmpipe_create_context(struct pipe_screen *screen, void *priv,
|
||||
unsigned flags)
|
||||
llvmpipe_create_context( struct pipe_screen *screen, void *priv )
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe;
|
||||
|
||||
|
@@ -160,8 +160,7 @@ struct llvmpipe_context {
|
||||
|
||||
|
||||
struct pipe_context *
|
||||
llvmpipe_create_context(struct pipe_screen *screen, void *priv,
|
||||
unsigned flags);
|
||||
llvmpipe_create_context( struct pipe_screen *screen, void *priv );
|
||||
|
||||
struct pipe_resource *
|
||||
llvmpipe_user_buffer_create(struct pipe_screen *screen,
|
||||
|
@@ -260,8 +260,7 @@ static void noop_destroy_context(struct pipe_context *ctx)
|
||||
FREE(ctx);
|
||||
}
|
||||
|
||||
static struct pipe_context *noop_create_context(struct pipe_screen *screen,
|
||||
void *priv, unsigned flags)
|
||||
static struct pipe_context *noop_create_context(struct pipe_screen *screen, void *priv)
|
||||
{
|
||||
struct pipe_context *ctx = CALLOC_STRUCT(pipe_context);
|
||||
|
||||
|
@@ -884,7 +884,7 @@ CodeEmitterNV50::emitINTERP(const Instruction *i)
|
||||
defId(i->def(0), 2);
|
||||
srcAddr8(i->src(0), 16);
|
||||
|
||||
if (i->getInterpMode() == NV50_IR_INTERP_FLAT) {
|
||||
if (i->encSize != 8 && i->getInterpMode() == NV50_IR_INTERP_FLAT) {
|
||||
code[0] |= 1 << 8;
|
||||
} else {
|
||||
if (i->op == OP_PINTERP) {
|
||||
@@ -896,10 +896,11 @@ CodeEmitterNV50::emitINTERP(const Instruction *i)
|
||||
}
|
||||
|
||||
if (i->encSize == 8) {
|
||||
code[1] =
|
||||
(code[0] & (3 << 24)) >> (24 - 16) |
|
||||
(code[0] & (1 << 8)) << (18 - 8);
|
||||
code[0] &= ~0x03000100;
|
||||
if (i->getInterpMode() == NV50_IR_INTERP_FLAT)
|
||||
code[1] = 4 << 16;
|
||||
else
|
||||
code[1] = (code[0] & (3 << 24)) >> (24 - 16);
|
||||
code[0] &= ~0x03000000;
|
||||
code[0] |= 1;
|
||||
emitFlagsRd(i);
|
||||
}
|
||||
|
@@ -202,7 +202,10 @@ NV50LegalizePostRA::visit(Function *fn)
|
||||
Program *prog = fn->getProgram();
|
||||
|
||||
r63 = new_LValue(fn, FILE_GPR);
|
||||
r63->reg.data.id = 63;
|
||||
if (prog->maxGPR < 63)
|
||||
r63->reg.data.id = 63;
|
||||
else
|
||||
r63->reg.data.id = 127;
|
||||
|
||||
// this is actually per-program, but we can do it all on visiting main()
|
||||
std::list<Instruction *> *outWrites =
|
||||
|
@@ -2602,6 +2602,10 @@ NV50PostRaConstantFolding::visit(BasicBlock *bb)
|
||||
!isFloatType(i->dType))
|
||||
break;
|
||||
|
||||
if (i->getDef(0)->reg.data.id >= 64 ||
|
||||
i->getSrc(0)->reg.data.id >= 64)
|
||||
break;
|
||||
|
||||
def = i->getSrc(1)->getInsn();
|
||||
if (def->op == OP_MOV && def->src(0).getFile() == FILE_IMMEDIATE) {
|
||||
vtmp = i->getSrc(1);
|
||||
|
@@ -411,7 +411,7 @@ int ImmediateValue::print(char *buf, size_t size, DataType ty) const
|
||||
case TYPE_U64:
|
||||
case TYPE_S64:
|
||||
default:
|
||||
PRINT("0x%016"PRIx64, reg.data.u64);
|
||||
PRINT("0x%016" PRIx64, reg.data.u64);
|
||||
break;
|
||||
}
|
||||
return pos;
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <stack>
|
||||
#include <limits>
|
||||
#include <tr1/unordered_map>
|
||||
|
||||
namespace nv50_ir {
|
||||
|
||||
@@ -222,6 +223,7 @@ private:
|
||||
private:
|
||||
virtual bool visit(BasicBlock *);
|
||||
inline bool needNewElseBlock(BasicBlock *b, BasicBlock *p);
|
||||
inline void splitEdges(BasicBlock *b);
|
||||
};
|
||||
|
||||
class ArgumentMovesPass : public Pass {
|
||||
@@ -345,28 +347,55 @@ RegAlloc::PhiMovesPass::needNewElseBlock(BasicBlock *b, BasicBlock *p)
|
||||
return (n == 2);
|
||||
}
|
||||
|
||||
// For each operand of each PHI in b, generate a new value by inserting a MOV
|
||||
// at the end of the block it is coming from and replace the operand with its
|
||||
// result. This eliminates liveness conflicts and enables us to let values be
|
||||
// copied to the right register if such a conflict exists nonetheless.
|
||||
struct PhiMapHash {
|
||||
size_t operator()(const std::pair<Instruction *, BasicBlock *>& val) const {
|
||||
return std::tr1::hash<Instruction*>()(val.first) * 31 +
|
||||
std::tr1::hash<BasicBlock*>()(val.second);
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::tr1::unordered_map<
|
||||
std::pair<Instruction *, BasicBlock *>, Value *, PhiMapHash> PhiMap;
|
||||
|
||||
// Critical edges need to be split up so that work can be inserted along
|
||||
// specific edge transitions. Unfortunately manipulating incident edges into a
|
||||
// BB invalidates all the PHI nodes since their sources are implicitly ordered
|
||||
// by incident edge order.
|
||||
//
|
||||
// These MOVs are also crucial in making sure the live intervals of phi srces
|
||||
// are extended until the end of the loop, since they are not included in the
|
||||
// live-in sets.
|
||||
bool
|
||||
RegAlloc::PhiMovesPass::visit(BasicBlock *bb)
|
||||
// TODO: Make it so that that is not the case, and PHI nodes store pointers to
|
||||
// the original BBs.
|
||||
void
|
||||
RegAlloc::PhiMovesPass::splitEdges(BasicBlock *bb)
|
||||
{
|
||||
Instruction *phi, *mov;
|
||||
BasicBlock *pb, *pn;
|
||||
|
||||
Instruction *phi;
|
||||
Graph::EdgeIterator ei;
|
||||
std::stack<BasicBlock *> stack;
|
||||
int j = 0;
|
||||
|
||||
for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
|
||||
for (ei = bb->cfg.incident(); !ei.end(); ei.next()) {
|
||||
pb = BasicBlock::get(ei.getNode());
|
||||
assert(pb);
|
||||
if (needNewElseBlock(bb, pb))
|
||||
stack.push(pb);
|
||||
}
|
||||
|
||||
// No critical edges were found, no need to perform any work.
|
||||
if (stack.empty())
|
||||
return;
|
||||
|
||||
// We're about to, potentially, reorder the inbound edges. This means that
|
||||
// we need to hold on to the (phi, bb) -> src mapping, and fix up the phi
|
||||
// nodes after the graph has been modified.
|
||||
PhiMap phis;
|
||||
|
||||
j = 0;
|
||||
for (ei = bb->cfg.incident(); !ei.end(); ei.next(), j++) {
|
||||
pb = BasicBlock::get(ei.getNode());
|
||||
for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next)
|
||||
phis.insert(std::make_pair(std::make_pair(phi, pb), phi->getSrc(j)));
|
||||
}
|
||||
|
||||
while (!stack.empty()) {
|
||||
pb = stack.top();
|
||||
pn = new BasicBlock(func);
|
||||
@@ -379,12 +408,47 @@ RegAlloc::PhiMovesPass::visit(BasicBlock *bb)
|
||||
assert(pb->getExit()->op != OP_CALL);
|
||||
if (pb->getExit()->asFlow()->target.bb == bb)
|
||||
pb->getExit()->asFlow()->target.bb = pn;
|
||||
|
||||
for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
|
||||
PhiMap::iterator it = phis.find(std::make_pair(phi, pb));
|
||||
assert(it != phis.end());
|
||||
phis.insert(std::make_pair(std::make_pair(phi, pn), it->second));
|
||||
phis.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
// Now go through and fix up all of the phi node sources.
|
||||
j = 0;
|
||||
for (ei = bb->cfg.incident(); !ei.end(); ei.next(), j++) {
|
||||
pb = BasicBlock::get(ei.getNode());
|
||||
for (phi = bb->getPhi(); phi && phi->op == OP_PHI; phi = phi->next) {
|
||||
PhiMap::const_iterator it = phis.find(std::make_pair(phi, pb));
|
||||
assert(it != phis.end());
|
||||
|
||||
phi->setSrc(j, it->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For each operand of each PHI in b, generate a new value by inserting a MOV
|
||||
// at the end of the block it is coming from and replace the operand with its
|
||||
// result. This eliminates liveness conflicts and enables us to let values be
|
||||
// copied to the right register if such a conflict exists nonetheless.
|
||||
//
|
||||
// These MOVs are also crucial in making sure the live intervals of phi srces
|
||||
// are extended until the end of the loop, since they are not included in the
|
||||
// live-in sets.
|
||||
bool
|
||||
RegAlloc::PhiMovesPass::visit(BasicBlock *bb)
|
||||
{
|
||||
Instruction *phi, *mov;
|
||||
|
||||
splitEdges(bb);
|
||||
|
||||
// insert MOVs (phi->src(j) should stem from j-th in-BB)
|
||||
int j = 0;
|
||||
for (Graph::EdgeIterator ei = bb->cfg.incident(); !ei.end(); ei.next()) {
|
||||
pb = BasicBlock::get(ei.getNode());
|
||||
BasicBlock *pb = BasicBlock::get(ei.getNode());
|
||||
if (!pb->isTerminated())
|
||||
pb->insertTail(new_FlowInstruction(func, OP_BRA, bb));
|
||||
|
||||
|
@@ -206,8 +206,8 @@ nouveau_transfer_write(struct nouveau_context *nv, struct nouveau_transfer *tx,
|
||||
nv->copy_data(nv, buf->bo, buf->offset + base, buf->domain,
|
||||
tx->bo, tx->offset + offset, NOUVEAU_BO_GART, size);
|
||||
else
|
||||
if ((buf->base.bind & PIPE_BIND_CONSTANT_BUFFER) && nv->push_cb && can_cb)
|
||||
nv->push_cb(nv, buf->bo, buf->domain, buf->offset, buf->base.width0,
|
||||
if (nv->push_cb && can_cb)
|
||||
nv->push_cb(nv, buf,
|
||||
base, size / 4, (const uint32_t *)data);
|
||||
else
|
||||
nv->push_data(nv, buf->bo, buf->offset + base, buf->domain, size, data);
|
||||
@@ -532,8 +532,13 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
|
||||
struct nv04_resource *buf = nv04_resource(transfer->resource);
|
||||
|
||||
if (tx->base.usage & PIPE_TRANSFER_WRITE) {
|
||||
if (!(tx->base.usage & PIPE_TRANSFER_FLUSH_EXPLICIT) && tx->map)
|
||||
nouveau_transfer_write(nv, tx, 0, tx->base.box.width);
|
||||
if (!(tx->base.usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
|
||||
if (tx->map)
|
||||
nouveau_transfer_write(nv, tx, 0, tx->base.box.width);
|
||||
|
||||
util_range_add(&buf->valid_buffer_range,
|
||||
tx->base.box.x, tx->base.box.x + tx->base.box.width);
|
||||
}
|
||||
|
||||
if (likely(buf->domain)) {
|
||||
const uint8_t bind = buf->base.bind;
|
||||
@@ -541,9 +546,6 @@ nouveau_buffer_transfer_unmap(struct pipe_context *pipe,
|
||||
if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
|
||||
nv->vbo_dirty = true;
|
||||
}
|
||||
|
||||
util_range_add(&buf->valid_buffer_range,
|
||||
tx->base.box.x, tx->base.box.x + tx->base.box.width);
|
||||
}
|
||||
|
||||
if (!tx->bo && (tx->base.usage & PIPE_TRANSFER_WRITE))
|
||||
|
@@ -41,6 +41,8 @@ struct nv04_resource {
|
||||
uint8_t status;
|
||||
uint8_t domain;
|
||||
|
||||
uint16_t cb_bindings[6]; /* per-shader per-slot bindings */
|
||||
|
||||
struct nouveau_fence *fence;
|
||||
struct nouveau_fence *fence_wr;
|
||||
|
||||
|
@@ -6,6 +6,8 @@
|
||||
|
||||
#define NOUVEAU_MAX_SCRATCH_BUFS 4
|
||||
|
||||
struct nv04_resource;
|
||||
|
||||
struct nouveau_context {
|
||||
struct pipe_context pipe;
|
||||
struct nouveau_screen *screen;
|
||||
@@ -23,8 +25,7 @@ struct nouveau_context {
|
||||
unsigned, const void *);
|
||||
/* base, size refer to the whole constant buffer */
|
||||
void (*push_cb)(struct nouveau_context *,
|
||||
struct nouveau_bo *, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
struct nv04_resource *,
|
||||
unsigned offset, unsigned words, const uint32_t *);
|
||||
|
||||
/* @return: @ref reduced by nr of references found in context */
|
||||
|
@@ -190,7 +190,7 @@ nv30_context_destroy(struct pipe_context *pipe)
|
||||
} while(0)
|
||||
|
||||
struct pipe_context *
|
||||
nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
||||
nv30_context_create(struct pipe_screen *pscreen, void *priv)
|
||||
{
|
||||
struct nv30_screen *screen = nv30_screen(pscreen);
|
||||
struct nv30_context *nv30 = CALLOC_STRUCT(nv30_context);
|
||||
|
@@ -132,7 +132,7 @@ nv30_context(struct pipe_context *pipe)
|
||||
}
|
||||
|
||||
struct pipe_context *
|
||||
nv30_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags);
|
||||
nv30_context_create(struct pipe_screen *pscreen, void *priv);
|
||||
|
||||
void
|
||||
nv30_vbo_init(struct pipe_context *pipe);
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "util/u_surface.h"
|
||||
|
||||
#include "nv_m2mf.xml.h"
|
||||
#include "nv_object.xml.h"
|
||||
#include "nv30/nv30_screen.h"
|
||||
#include "nv30/nv30_context.h"
|
||||
#include "nv30/nv30_resource.h"
|
||||
@@ -144,21 +145,54 @@ nv30_resource_copy_region(struct pipe_context *pipe,
|
||||
nv30_transfer_rect(nv30, NEAREST, &src, &dst);
|
||||
}
|
||||
|
||||
void
|
||||
nv30_resource_resolve(struct pipe_context *pipe,
|
||||
const struct pipe_resolve_info *info)
|
||||
static void
|
||||
nv30_resource_resolve(struct nv30_context *nv30,
|
||||
const struct pipe_blit_info *info)
|
||||
{
|
||||
#if 0
|
||||
struct nv30_context *nv30 = nv30_context(pipe);
|
||||
struct nv30_miptree *src_mt = nv30_miptree(info->src.resource);
|
||||
struct nv30_rect src, dst;
|
||||
unsigned x, x0, x1, y, y1, w, h;
|
||||
|
||||
define_rect(info->src.res, 0, 0, info->src.x0, info->src.y0,
|
||||
info->src.x1 - info->src.x0, info->src.y1 - info->src.y0, &src);
|
||||
define_rect(info->dst.res, info->dst.level, 0, info->dst.x0, info->dst.y0,
|
||||
info->dst.x1 - info->dst.x0, info->dst.y1 - info->dst.y0, &dst);
|
||||
define_rect(info->src.resource, 0, info->src.box.z, info->src.box.x,
|
||||
info->src.box.y, info->src.box.width, info->src.box.height, &src);
|
||||
define_rect(info->dst.resource, 0, info->dst.box.z, info->dst.box.x,
|
||||
info->dst.box.y, info->dst.box.width, info->dst.box.height, &dst);
|
||||
|
||||
nv30_transfer_rect(nv30, BILINEAR, &src, &dst);
|
||||
#endif
|
||||
x0 = src.x0;
|
||||
x1 = src.x1;
|
||||
y1 = src.y1;
|
||||
|
||||
/* On nv3x we must use sifm which is restricted to 1024x1024 tiles */
|
||||
for (y = src.y0; y < y1; y += h) {
|
||||
h = y1 - y;
|
||||
if (h > 1024)
|
||||
h = 1024;
|
||||
|
||||
src.y0 = 0;
|
||||
src.y1 = h;
|
||||
src.h = h;
|
||||
|
||||
dst.y1 = dst.y0 + (h >> src_mt->ms_y);
|
||||
dst.h = h >> src_mt->ms_y;
|
||||
|
||||
for (x = x0; x < x1; x += w) {
|
||||
w = x1 - x;
|
||||
if (w > 1024)
|
||||
w = 1024;
|
||||
|
||||
src.offset = y * src.pitch + x * src.cpp;
|
||||
src.x0 = 0;
|
||||
src.x1 = w;
|
||||
src.w = w;
|
||||
|
||||
dst.offset = (y >> src_mt->ms_y) * dst.pitch +
|
||||
(x >> src_mt->ms_x) * dst.cpp;
|
||||
dst.x1 = dst.x0 + (w >> src_mt->ms_x);
|
||||
dst.w = w >> src_mt->ms_x;
|
||||
|
||||
nv30_transfer_rect(nv30, BILINEAR, &src, &dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -172,7 +206,7 @@ nv30_blit(struct pipe_context *pipe,
|
||||
info.dst.resource->nr_samples <= 1 &&
|
||||
!util_format_is_depth_or_stencil(info.src.resource->format) &&
|
||||
!util_format_is_pure_integer(info.src.resource->format)) {
|
||||
debug_printf("nv30: color resolve unimplemented\n");
|
||||
nv30_resource_resolve(nv30, blit_info);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,6 +396,7 @@ nv30_miptree_create(struct pipe_screen *pscreen,
|
||||
blocksz = util_format_get_blocksize(pt->format);
|
||||
|
||||
if ((pt->target == PIPE_TEXTURE_RECT) ||
|
||||
(pt->bind & PIPE_BIND_SCANOUT) ||
|
||||
!util_is_power_of_two(pt->width0) ||
|
||||
!util_is_power_of_two(pt->height0) ||
|
||||
!util_is_power_of_two(pt->depth0) ||
|
||||
@@ -369,6 +404,14 @@ nv30_miptree_create(struct pipe_screen *pscreen,
|
||||
util_format_is_float(pt->format) || mt->ms_mode) {
|
||||
mt->uniform_pitch = util_format_get_nblocksx(pt->format, w) * blocksz;
|
||||
mt->uniform_pitch = align(mt->uniform_pitch, 64);
|
||||
if (pt->bind & PIPE_BIND_SCANOUT) {
|
||||
struct nv30_screen *screen = nv30_screen(pscreen);
|
||||
int pitch_align = MAX2(
|
||||
screen->eng3d->oclass >= NV40_3D_CLASS ? 1024 : 256,
|
||||
/* round_down_pow2(mt->uniform_pitch / 4) */
|
||||
1 << (util_last_bit(mt->uniform_pitch / 4) - 1));
|
||||
mt->uniform_pitch = align(mt->uniform_pitch, pitch_align);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mt->uniform_pitch)
|
||||
|
@@ -65,9 +65,6 @@ nv30_resource_copy_region(struct pipe_context *pipe,
|
||||
struct pipe_resource *src, unsigned src_level,
|
||||
const struct pipe_box *src_box);
|
||||
|
||||
void
|
||||
nv30_resource_resolve(struct pipe_context *, const struct pipe_resolve_info *);
|
||||
|
||||
void
|
||||
nv30_blit(struct pipe_context *pipe,
|
||||
const struct pipe_blit_info *blit_info);
|
||||
|
@@ -319,8 +319,9 @@ nv30_screen_is_format_supported(struct pipe_screen *pscreen,
|
||||
unsigned sample_count,
|
||||
unsigned bindings)
|
||||
{
|
||||
if (sample_count > 4)
|
||||
if (sample_count > nv30_screen(pscreen)->max_sample_count)
|
||||
return false;
|
||||
|
||||
if (!(0x00000017 & (1 << sample_count)))
|
||||
return false;
|
||||
|
||||
@@ -450,6 +451,23 @@ nv30_screen_create(struct nouveau_device *dev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some modern apps try to use msaa without keeping in mind the
|
||||
* restrictions on videomem of older cards. Resulting in dmesg saying:
|
||||
* [ 1197.850642] nouveau E[soffice.bin[3785]] fail ttm_validate
|
||||
* [ 1197.850648] nouveau E[soffice.bin[3785]] validating bo list
|
||||
* [ 1197.850654] nouveau E[soffice.bin[3785]] validate: -12
|
||||
*
|
||||
* Because we are running out of video memory, after which the program
|
||||
* using the msaa visual freezes, and eventually the entire system freezes.
|
||||
*
|
||||
* To work around this we do not allow msaa visauls by default and allow
|
||||
* the user to override this via NV30_MAX_MSAA.
|
||||
*/
|
||||
screen->max_sample_count = debug_get_num_option("NV30_MAX_MSAA", 0);
|
||||
if (screen->max_sample_count > 4)
|
||||
screen->max_sample_count = 4;
|
||||
|
||||
pscreen = &screen->base.base;
|
||||
pscreen->destroy = nv30_screen_destroy;
|
||||
pscreen->get_param = nv30_screen_get_param;
|
||||
|
@@ -38,6 +38,8 @@ struct nv30_screen {
|
||||
/*XXX: nvfx state */
|
||||
struct nouveau_heap *vp_exec_heap;
|
||||
struct nouveau_heap *vp_data_heap;
|
||||
|
||||
unsigned max_sample_count;
|
||||
};
|
||||
|
||||
static inline struct nv30_screen *
|
||||
|
@@ -371,7 +371,7 @@ nv30_transfer_rect_blit(XFER_ARGS)
|
||||
static bool
|
||||
nv30_transfer_sifm(XFER_ARGS)
|
||||
{
|
||||
if (!src->pitch || (src->w | src->h) > 1024 || src->w < 2 || src->h < 2)
|
||||
if (!src->pitch || src->w > 1024 || src->h > 1024 || src->w < 2 || src->h < 2)
|
||||
return false;
|
||||
|
||||
if (src->d > 1 || dst->d > 1)
|
||||
@@ -381,7 +381,7 @@ nv30_transfer_sifm(XFER_ARGS)
|
||||
return false;
|
||||
|
||||
if (!dst->pitch) {
|
||||
if ((dst->w | dst->h) > 2048 || dst->w < 2 || dst->h < 2)
|
||||
if (dst->w > 2048 || dst->h > 2048 || dst->w < 2 || dst->h < 2)
|
||||
return false;
|
||||
} else {
|
||||
if (dst->domain != NOUVEAU_BO_VRAM)
|
||||
|
@@ -199,9 +199,13 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
if (nv50->idxbuf.buffer == res)
|
||||
if (nv50->idxbuf.buffer == res) {
|
||||
/* Just rebind to the bufctx as there is no separate dirty bit */
|
||||
nouveau_bufctx_reset(nv50->bufctx_3d, NV50_BIND_INDEX);
|
||||
BCTX_REFN(nv50->bufctx_3d, INDEX, nv04_resource(res), RD);
|
||||
if (!--ref)
|
||||
return ref;
|
||||
}
|
||||
|
||||
for (s = 0; s < 3; ++s) {
|
||||
assert(nv50->num_textures[s] <= PIPE_MAX_SAMPLERS);
|
||||
@@ -240,7 +244,7 @@ nv50_context_get_sample_position(struct pipe_context *, unsigned, unsigned,
|
||||
float *);
|
||||
|
||||
struct pipe_context *
|
||||
nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
||||
nv50_create(struct pipe_screen *pscreen, void *priv)
|
||||
{
|
||||
struct nv50_screen *screen = nv50_screen(pscreen);
|
||||
struct nv50_context *nv50;
|
||||
|
@@ -186,7 +186,7 @@ nv50_context_shader_stage(unsigned pipe)
|
||||
}
|
||||
|
||||
/* nv50_context.c */
|
||||
struct pipe_context *nv50_create(struct pipe_screen *, void *, unsigned flags);
|
||||
struct pipe_context *nv50_create(struct pipe_screen *, void *);
|
||||
|
||||
void nv50_bufctx_fence(struct nouveau_bufctx *, bool on_flush);
|
||||
|
||||
@@ -197,7 +197,7 @@ extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *);
|
||||
|
||||
/* nv50_query.c */
|
||||
void nv50_init_query_functions(struct nv50_context *);
|
||||
void nv50_query_pushbuf_submit(struct nouveau_pushbuf *,
|
||||
void nv50_query_pushbuf_submit(struct nouveau_pushbuf *, uint16_t method,
|
||||
struct pipe_query *, unsigned result_offset);
|
||||
void nv84_query_fifo_wait(struct nouveau_pushbuf *, struct pipe_query *);
|
||||
void nva0_so_target_save_offset(struct pipe_context *,
|
||||
|
@@ -203,8 +203,10 @@ const struct nv50_format nv50_format_table[PIPE_FORMAT_COUNT] =
|
||||
F3B(B5G6R5_UNORM, B5G6R5_UNORM, C2, C1, C0, xx, UNORM, 5_6_5, TD),
|
||||
C4B(B5G5R5A1_UNORM, BGR5_A1_UNORM, C2, C1, C0, C3, UNORM, 5_5_5_1, TD),
|
||||
F3B(B5G5R5X1_UNORM, BGR5_X1_UNORM, C2, C1, C0, xx, UNORM, 5_5_5_1, TD),
|
||||
#if NOUVEAU_DRIVER != 0xc0
|
||||
C4B(B4G4R4A4_UNORM, NONE, C2, C1, C0, C3, UNORM, 4_4_4_4, T),
|
||||
F3B(B4G4R4X4_UNORM, NONE, C2, C1, C0, xx, UNORM, 4_4_4_4, T),
|
||||
#endif
|
||||
F3B(R9G9B9E5_FLOAT, NONE, C0, C1, C2, xx, FLOAT, 9_9_9_E5, T),
|
||||
|
||||
C4A(R10G10B10A2_UNORM, RGB10_A2_UNORM, C0, C1, C2, C3, UNORM, 10_10_10_2,
|
||||
|
@@ -66,6 +66,7 @@ nv50_vertprog_assign_slots(struct nv50_ir_prog_info *info)
|
||||
case TGSI_SEMANTIC_VERTEXID:
|
||||
prog->vp.attrs[2] |= NV50_3D_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID;
|
||||
prog->vp.attrs[2] |= NV50_3D_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID_DRAW_ARRAYS_ADD_START;
|
||||
prog->vp.vertexid = 1;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
|
@@ -76,6 +76,7 @@ struct nv50_program {
|
||||
ubyte psiz; /* output slot of point size */
|
||||
ubyte bfc[2]; /* indices into varying for FFC (FP) or BFC (VP) */
|
||||
ubyte edgeflag;
|
||||
ubyte vertexid;
|
||||
ubyte clpd[2]; /* output slot of clip distance[i]'s 1st component */
|
||||
ubyte clpd_nr;
|
||||
} vp;
|
||||
|
@@ -266,6 +266,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
nv50_query_get(push, q, 0, 0x1000f010);
|
||||
break;
|
||||
case NVA0_QUERY_STREAM_OUTPUT_BUFFER_OFFSET:
|
||||
q->sequence++;
|
||||
nv50_query_get(push, q, 0, 0x0d005002 | (q->index << 5));
|
||||
break;
|
||||
case PIPE_QUERY_TIMESTAMP_DISJOINT:
|
||||
@@ -451,18 +452,18 @@ nv50_render_condition(struct pipe_context *pipe,
|
||||
}
|
||||
|
||||
void
|
||||
nv50_query_pushbuf_submit(struct nouveau_pushbuf *push,
|
||||
nv50_query_pushbuf_submit(struct nouveau_pushbuf *push, uint16_t method,
|
||||
struct pipe_query *pq, unsigned result_offset)
|
||||
{
|
||||
struct nv50_query *q = nv50_query(pq);
|
||||
|
||||
/* XXX: does this exist ? */
|
||||
#define NV50_IB_ENTRY_1_NO_PREFETCH (0 << (31 - 8))
|
||||
nv50_query_update(q);
|
||||
if (q->state != NV50_QUERY_STATE_READY)
|
||||
nouveau_bo_wait(q->bo, NOUVEAU_BO_RD, push->client);
|
||||
q->state = NV50_QUERY_STATE_READY;
|
||||
|
||||
PUSH_REFN(push, q->bo, NOUVEAU_BO_RD | NOUVEAU_BO_GART);
|
||||
nouveau_pushbuf_space(push, 0, 0, 1);
|
||||
nouveau_pushbuf_data(push, q->bo, q->offset + result_offset, 4 |
|
||||
NV50_IB_ENTRY_1_NO_PREFETCH);
|
||||
BEGIN_NV04(push, SUBC_3D(method), 1);
|
||||
PUSH_DATA (push, q->data[result_offset / 4]);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -100,7 +100,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_MAX_TEXEL_OFFSET:
|
||||
return 7;
|
||||
case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
|
||||
return 65536;
|
||||
return 128 * 1024 * 1024;
|
||||
case PIPE_CAP_GLSL_FEATURE_LEVEL:
|
||||
return 330;
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
|
@@ -641,12 +641,12 @@ nv50_stream_output_validate(struct nv50_context *nv50)
|
||||
PUSH_DATA (push, so->num_attribs[i]);
|
||||
if (n == 4) {
|
||||
PUSH_DATA(push, targ->pipe.buffer_size);
|
||||
|
||||
BEGIN_NV04(push, NVA0_3D(STRMOUT_OFFSET(i)), 1);
|
||||
if (!targ->clean) {
|
||||
assert(targ->pq);
|
||||
nv50_query_pushbuf_submit(push, targ->pq, 0x4);
|
||||
nv50_query_pushbuf_submit(push, NVA0_3D_STRMOUT_OFFSET(i),
|
||||
targ->pq, 0x4);
|
||||
} else {
|
||||
BEGIN_NV04(push, NVA0_3D(STRMOUT_OFFSET(i)), 1);
|
||||
PUSH_DATA(push, 0);
|
||||
targ->clean = false;
|
||||
}
|
||||
@@ -655,6 +655,7 @@ nv50_stream_output_validate(struct nv50_context *nv50)
|
||||
(so->stride[i] * nv50->state.prim_size);
|
||||
prims = MIN2(prims, limit);
|
||||
}
|
||||
targ->stride = so->stride[i];
|
||||
BCTX_REFN(nv50->bufctx_3d, SO, buf, WR);
|
||||
}
|
||||
if (prims != ~0) {
|
||||
|
@@ -503,7 +503,8 @@ static struct state_validate {
|
||||
{ nv50_validate_samplers, NV50_NEW_SAMPLERS },
|
||||
{ nv50_stream_output_validate, NV50_NEW_STRMOUT |
|
||||
NV50_NEW_VERTPROG | NV50_NEW_GMTYPROG },
|
||||
{ nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS },
|
||||
{ nv50_vertex_arrays_validate, NV50_NEW_VERTEX | NV50_NEW_ARRAYS |
|
||||
NV50_NEW_VERTPROG },
|
||||
{ nv50_validate_min_samples, NV50_NEW_MIN_SAMPLES },
|
||||
};
|
||||
#define validate_list_len (sizeof(validate_list) / sizeof(validate_list[0]))
|
||||
|
@@ -221,6 +221,26 @@ nv50_create_texture_view(struct pipe_context *pipe,
|
||||
return &view->pipe;
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_update_tic(struct nv50_context *nv50, struct nv50_tic_entry *tic,
|
||||
struct nv04_resource *res)
|
||||
{
|
||||
uint64_t address = res->address;
|
||||
if (res->base.target != PIPE_BUFFER)
|
||||
return;
|
||||
address += tic->pipe.u.buf.first_element *
|
||||
util_format_get_blocksize(tic->pipe.format);
|
||||
if (tic->tic[1] == (uint32_t)address &&
|
||||
(tic->tic[2] & 0xff) == address >> 32)
|
||||
return;
|
||||
|
||||
nv50_screen_tic_unlock(nv50->screen, tic);
|
||||
tic->id = -1;
|
||||
tic->tic[1] = address;
|
||||
tic->tic[2] &= 0xffffff00;
|
||||
tic->tic[2] |= address >> 32;
|
||||
}
|
||||
|
||||
static bool
|
||||
nv50_validate_tic(struct nv50_context *nv50, int s)
|
||||
{
|
||||
@@ -240,6 +260,7 @@ nv50_validate_tic(struct nv50_context *nv50, int s)
|
||||
continue;
|
||||
}
|
||||
res = &nv50_miptree(tic->pipe.texture)->base;
|
||||
nv50_update_tic(nv50, tic, res);
|
||||
|
||||
if (tic->id < 0) {
|
||||
tic->id = nv50_screen_tic_alloc(nv50->screen, tic);
|
||||
|
@@ -293,7 +293,8 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
||||
uint64_t addrs[PIPE_MAX_ATTRIBS];
|
||||
uint32_t limits[PIPE_MAX_ATTRIBS];
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
struct nv50_vertex_stateobj *vertex = nv50->vertex;
|
||||
struct nv50_vertex_stateobj dummy = {};
|
||||
struct nv50_vertex_stateobj *vertex = nv50->vertex ? nv50->vertex : &dummy;
|
||||
struct pipe_vertex_buffer *vb;
|
||||
struct nv50_vertex_element *ve;
|
||||
uint32_t mask;
|
||||
@@ -301,6 +302,14 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
||||
unsigned i;
|
||||
const unsigned n = MAX2(vertex->num_elements, nv50->state.num_vtxelts);
|
||||
|
||||
/* A vertexid is not generated for inline data uploads. Have to use a
|
||||
* VBO. This check must come after the vertprog has been validated,
|
||||
* otherwise vertexid may be unset.
|
||||
*/
|
||||
assert(nv50->vertprog->translated);
|
||||
if (nv50->vertprog->vp.vertexid)
|
||||
nv50->vbo_push_hint = 0;
|
||||
|
||||
if (unlikely(vertex->need_conversion))
|
||||
nv50->vbo_fifo = ~0;
|
||||
else
|
||||
@@ -317,7 +326,6 @@ nv50_vertex_arrays_validate(struct nv50_context *nv50)
|
||||
if (buf && buf->status & NOUVEAU_BUFFER_STATUS_GPU_WRITING) {
|
||||
buf->status &= ~NOUVEAU_BUFFER_STATUS_GPU_WRITING;
|
||||
nv50->base.vbo_dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -736,9 +744,8 @@ nva0_draw_stream_output(struct nv50_context *nv50,
|
||||
BEGIN_NV04(push, NVA0_3D(DRAW_TFB_BASE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NVA0_3D(DRAW_TFB_STRIDE), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
BEGIN_NV04(push, NVA0_3D(DRAW_TFB_BYTES), 1);
|
||||
nv50_query_pushbuf_submit(push, so->pq, 0x4);
|
||||
PUSH_DATA (push, so->stride);
|
||||
nv50_query_pushbuf_submit(push, NVA0_3D_DRAW_TFB_BYTES, so->pq, 0x4);
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_END_GL), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
||||
@@ -761,6 +768,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
{
|
||||
struct nv50_context *nv50 = nv50_context(pipe);
|
||||
struct nouveau_pushbuf *push = nv50->base.pushbuf;
|
||||
bool tex_dirty = false;
|
||||
int i, s;
|
||||
|
||||
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
|
||||
@@ -790,6 +798,9 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
|
||||
push->kick_notify = nv50_draw_vbo_kick_notify;
|
||||
|
||||
/* TODO: Instead of iterating over all the buffer resources looking for
|
||||
* coherent buffers, keep track of a context-wide count.
|
||||
*/
|
||||
for (s = 0; s < 3 && !nv50->cb_dirty; ++s) {
|
||||
uint32_t valid = nv50->constbuf_valid[s];
|
||||
|
||||
@@ -817,6 +828,21 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
nv50->cb_dirty = false;
|
||||
}
|
||||
|
||||
for (s = 0; s < 3 && !tex_dirty; ++s) {
|
||||
for (i = 0; i < nv50->num_textures[s] && !tex_dirty; ++i) {
|
||||
if (!nv50->textures[s][i] ||
|
||||
nv50->textures[s][i]->texture->target != PIPE_BUFFER)
|
||||
continue;
|
||||
if (nv50->textures[s][i]->texture->flags &
|
||||
PIPE_RESOURCE_FLAG_MAP_COHERENT)
|
||||
tex_dirty = true;
|
||||
}
|
||||
}
|
||||
if (tex_dirty) {
|
||||
BEGIN_NV04(push, NV50_3D(TEX_CACHE_CTL), 1);
|
||||
PUSH_DATA (push, 0x20);
|
||||
}
|
||||
|
||||
if (nv50->vbo_fifo) {
|
||||
nv50_push_vbo(nv50, info);
|
||||
push->kick_notify = nv50_default_kick_notify;
|
||||
@@ -838,10 +864,6 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
nv50->base.vbo_dirty = true;
|
||||
}
|
||||
|
||||
if (!nv50->base.vbo_dirty && nv50->idxbuf.buffer &&
|
||||
nv50->idxbuf.buffer->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)
|
||||
nv50->base.vbo_dirty = true;
|
||||
|
||||
if (nv50->base.vbo_dirty) {
|
||||
BEGIN_NV04(push, NV50_3D(VERTEX_ARRAY_FLUSH), 1);
|
||||
PUSH_DATA (push, 0);
|
||||
|
@@ -262,7 +262,7 @@ nvc0_context_get_sample_position(struct pipe_context *, unsigned, unsigned,
|
||||
float *);
|
||||
|
||||
struct pipe_context *
|
||||
nvc0_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
|
||||
nvc0_create(struct pipe_screen *pscreen, void *priv)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0_screen(pscreen);
|
||||
struct nvc0_context *nvc0;
|
||||
|
@@ -214,7 +214,7 @@ nvc0_shader_stage(unsigned pipe)
|
||||
|
||||
|
||||
/* nvc0_context.c */
|
||||
struct pipe_context *nvc0_create(struct pipe_screen *, void *, unsigned flags);
|
||||
struct pipe_context *nvc0_create(struct pipe_screen *, void *);
|
||||
void nvc0_bufctx_fence(struct nvc0_context *, struct nouveau_bufctx *,
|
||||
bool on_flush);
|
||||
void nvc0_default_kick_notify(struct nouveau_pushbuf *);
|
||||
@@ -299,10 +299,10 @@ nve4_p2mf_push_linear(struct nouveau_context *nv,
|
||||
struct nouveau_bo *dst, unsigned offset, unsigned domain,
|
||||
unsigned size, const void *data);
|
||||
void
|
||||
nvc0_cb_push(struct nouveau_context *,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
unsigned offset, unsigned words, const uint32_t *data);
|
||||
nvc0_cb_bo_push(struct nouveau_context *,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
unsigned offset, unsigned words, const uint32_t *data);
|
||||
|
||||
/* nvc0_vbo.c */
|
||||
void nvc0_draw_vbo(struct pipe_context *, const struct pipe_draw_info *);
|
||||
|
@@ -449,7 +449,7 @@ nvc0_fp_gen_header(struct nvc0_program *fp, struct nv50_ir_prog_info *info)
|
||||
|
||||
for (i = 0; i < info->numOutputs; ++i) {
|
||||
if (info->out[i].sn == TGSI_SEMANTIC_COLOR)
|
||||
fp->hdr[18] |= info->out[i].mask << info->out[i].slot[0];
|
||||
fp->hdr[18] |= 0xf << info->out[i].slot[0];
|
||||
}
|
||||
|
||||
fp->fp.early_z = info->prop.fp.earlyFragTests;
|
||||
|
@@ -56,10 +56,10 @@ struct nvc0_query {
|
||||
|
||||
#define NVC0_QUERY_ALLOC_SPACE 256
|
||||
|
||||
static boolean nvc0_hw_sm_query_begin(struct nvc0_context *,
|
||||
static boolean nvc0_mp_pm_query_begin(struct nvc0_context *,
|
||||
struct nvc0_query *);
|
||||
static void nvc0_hw_sm_query_end(struct nvc0_context *, struct nvc0_query *);
|
||||
static boolean nvc0_hw_sm_query_result(struct nvc0_context *,
|
||||
static void nvc0_mp_pm_query_end(struct nvc0_context *, struct nvc0_query *);
|
||||
static boolean nvc0_mp_pm_query_result(struct nvc0_context *,
|
||||
struct nvc0_query *, void *, boolean);
|
||||
|
||||
static inline struct nvc0_query *
|
||||
@@ -159,7 +159,7 @@ nvc0_query_create(struct pipe_context *pipe, unsigned type, unsigned index)
|
||||
} else
|
||||
#endif
|
||||
if (nvc0->screen->base.device->drm_version >= 0x01000101) {
|
||||
if (type >= NVE4_HW_SM_QUERY(0) && type <= NVE4_HW_SM_QUERY_LAST) {
|
||||
if (type >= NVE4_PM_QUERY(0) && type <= NVE4_PM_QUERY_LAST) {
|
||||
/* for each MP:
|
||||
* [00] = WS0.C0
|
||||
* [04] = WS0.C1
|
||||
@@ -189,7 +189,7 @@ nvc0_query_create(struct pipe_context *pipe, unsigned type, unsigned index)
|
||||
space = (4 * 4 + 4 + 4) * nvc0->screen->mp_count * sizeof(uint32_t);
|
||||
break;
|
||||
} else
|
||||
if (type >= NVC0_HW_SM_QUERY(0) && type <= NVC0_HW_SM_QUERY_LAST) {
|
||||
if (type >= NVC0_PM_QUERY(0) && type <= NVC0_PM_QUERY_LAST) {
|
||||
/* for each MP:
|
||||
* [00] = MP.C0
|
||||
* [04] = MP.C1
|
||||
@@ -327,9 +327,9 @@ nvc0_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
q->u.value = 0;
|
||||
} else
|
||||
#endif
|
||||
if ((q->type >= NVE4_HW_SM_QUERY(0) && q->type <= NVE4_HW_SM_QUERY_LAST) ||
|
||||
(q->type >= NVC0_HW_SM_QUERY(0) && q->type <= NVC0_HW_SM_QUERY_LAST)) {
|
||||
ret = nvc0_hw_sm_query_begin(nvc0, q);
|
||||
if ((q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_LAST) ||
|
||||
(q->type >= NVC0_PM_QUERY(0) && q->type <= NVC0_PM_QUERY_LAST)) {
|
||||
ret = nvc0_mp_pm_query_begin(nvc0, q);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -412,9 +412,9 @@ nvc0_query_end(struct pipe_context *pipe, struct pipe_query *pq)
|
||||
return;
|
||||
} else
|
||||
#endif
|
||||
if ((q->type >= NVE4_HW_SM_QUERY(0) && q->type <= NVE4_HW_SM_QUERY_LAST) ||
|
||||
(q->type >= NVC0_HW_SM_QUERY(0) && q->type <= NVC0_HW_SM_QUERY_LAST)) {
|
||||
nvc0_hw_sm_query_end(nvc0, q);
|
||||
if ((q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_LAST) ||
|
||||
(q->type >= NVC0_PM_QUERY(0) && q->type <= NVC0_PM_QUERY_LAST)) {
|
||||
nvc0_mp_pm_query_end(nvc0, q);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -453,9 +453,9 @@ nvc0_query_result(struct pipe_context *pipe, struct pipe_query *pq,
|
||||
return true;
|
||||
} else
|
||||
#endif
|
||||
if ((q->type >= NVE4_HW_SM_QUERY(0) && q->type <= NVE4_HW_SM_QUERY_LAST) ||
|
||||
(q->type >= NVC0_HW_SM_QUERY(0) && q->type <= NVC0_HW_SM_QUERY_LAST)) {
|
||||
return nvc0_hw_sm_query_result(nvc0, q, result, wait);
|
||||
if ((q->type >= NVE4_PM_QUERY(0) && q->type <= NVE4_PM_QUERY_LAST) ||
|
||||
(q->type >= NVC0_PM_QUERY(0) && q->type <= NVC0_PM_QUERY_LAST)) {
|
||||
return nvc0_mp_pm_query_result(nvc0, q, result, wait);
|
||||
}
|
||||
|
||||
if (q->state != NVC0_QUERY_STATE_READY)
|
||||
@@ -692,7 +692,7 @@ static const char *nvc0_drv_stat_names[] =
|
||||
* We could add a kernel interface for it, but reading the counters like this
|
||||
* has the advantage of being async (if get_result isn't called immediately).
|
||||
*/
|
||||
static const uint64_t nve4_read_hw_sm_counters_code[] =
|
||||
static const uint64_t nve4_read_mp_pm_counters_code[] =
|
||||
{
|
||||
/* sched 0x20 0x20 0x20 0x20 0x20 0x20 0x20
|
||||
* mov b32 $r8 $tidx
|
||||
@@ -776,33 +776,6 @@ static const uint64_t nve4_read_hw_sm_counters_code[] =
|
||||
static const char *nve4_pm_query_names[] =
|
||||
{
|
||||
/* MP counters */
|
||||
"active_cycles",
|
||||
"active_warps",
|
||||
"atom_count",
|
||||
"branch",
|
||||
"divergent_branch",
|
||||
"gld_request",
|
||||
"global_ld_mem_divergence_replays",
|
||||
"global_store_transaction",
|
||||
"global_st_mem_divergence_replays",
|
||||
"gred_count",
|
||||
"gst_request",
|
||||
"inst_executed",
|
||||
"inst_issued",
|
||||
"inst_issued1",
|
||||
"inst_issued2",
|
||||
"l1_global_load_hit",
|
||||
"l1_global_load_miss",
|
||||
"l1_local_load_hit",
|
||||
"l1_local_load_miss",
|
||||
"l1_local_store_hit",
|
||||
"l1_local_store_miss",
|
||||
"l1_shared_load_transactions",
|
||||
"l1_shared_store_transactions",
|
||||
"local_load",
|
||||
"local_load_transactions",
|
||||
"local_store",
|
||||
"local_store_transactions",
|
||||
"prof_trigger_00",
|
||||
"prof_trigger_01",
|
||||
"prof_trigger_02",
|
||||
@@ -811,14 +784,41 @@ static const char *nve4_pm_query_names[] =
|
||||
"prof_trigger_05",
|
||||
"prof_trigger_06",
|
||||
"prof_trigger_07",
|
||||
"shared_load",
|
||||
"shared_load_replay",
|
||||
"shared_store",
|
||||
"shared_store_replay",
|
||||
"sm_cta_launched",
|
||||
"threads_launched",
|
||||
"uncached_global_load_transaction",
|
||||
"warps_launched",
|
||||
"threads_launched",
|
||||
"sm_cta_launched",
|
||||
"inst_issued1",
|
||||
"inst_issued2",
|
||||
"inst_executed",
|
||||
"local_load",
|
||||
"local_store",
|
||||
"shared_load",
|
||||
"shared_store",
|
||||
"l1_local_load_hit",
|
||||
"l1_local_load_miss",
|
||||
"l1_local_store_hit",
|
||||
"l1_local_store_miss",
|
||||
"gld_request",
|
||||
"gst_request",
|
||||
"l1_global_load_hit",
|
||||
"l1_global_load_miss",
|
||||
"uncached_global_load_transaction",
|
||||
"global_store_transaction",
|
||||
"branch",
|
||||
"divergent_branch",
|
||||
"active_warps",
|
||||
"active_cycles",
|
||||
"inst_issued",
|
||||
"atom_count",
|
||||
"gred_count",
|
||||
"shared_load_replay",
|
||||
"shared_store_replay",
|
||||
"local_load_transactions",
|
||||
"local_store_transactions",
|
||||
"l1_shared_load_transactions",
|
||||
"l1_shared_store_transactions",
|
||||
"global_ld_mem_divergence_replays",
|
||||
"global_st_mem_divergence_replays",
|
||||
/* metrics, i.e. functions of the MP counters */
|
||||
"metric-ipc", /* inst_executed, clock */
|
||||
"metric-ipac", /* inst_executed, active_cycles */
|
||||
@@ -852,7 +852,7 @@ struct nvc0_mp_counter_cfg
|
||||
#define NVC0_COUNTER_OP2_AVG_DIV_MM 5 /* avg(ctr0 / ctr1) */
|
||||
#define NVC0_COUNTER_OP2_AVG_DIV_M0 6 /* avg(ctr0) / ctr1 of MP[0]) */
|
||||
|
||||
struct nvc0_hw_sm_query_cfg
|
||||
struct nvc0_mp_pm_query_cfg
|
||||
{
|
||||
struct nvc0_mp_counter_cfg ctr[4];
|
||||
uint8_t num_counters;
|
||||
@@ -860,17 +860,17 @@ struct nvc0_hw_sm_query_cfg
|
||||
uint8_t norm[2]; /* normalization num,denom */
|
||||
};
|
||||
|
||||
#define _Q1A(n, f, m, g, s, nu, dn) [NVE4_HW_SM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g, s }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { nu, dn } }
|
||||
#define _Q1B(n, f, m, g, s, nu, dn) [NVE4_HW_SM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 0, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g, s }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { nu, dn } }
|
||||
#define _M2A(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_HW_SM_QUERY_METRIC_##n] = { { \
|
||||
#define _Q1A(n, f, m, g, s, nu, dn) [NVE4_PM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g, s }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { nu, dn } }
|
||||
#define _Q1B(n, f, m, g, s, nu, dn) [NVE4_PM_QUERY_##n] = { { { f, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m, 0, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g, s }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { nu, dn } }
|
||||
#define _M2A(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_PM_QUERY_METRIC_##n] = { { \
|
||||
{ f0, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m0, 0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g0, s0 }, \
|
||||
{ f1, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m1, 0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g1, s1 }, \
|
||||
{}, {}, }, 2, NVC0_COUNTER_OP2_##o, { nu, dn } }
|
||||
#define _M2B(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_HW_SM_QUERY_METRIC_##n] = { { \
|
||||
#define _M2B(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_PM_QUERY_METRIC_##n] = { { \
|
||||
{ f0, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m0, 0, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g0, s0 }, \
|
||||
{ f1, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m1, 0, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g1, s1 }, \
|
||||
{}, {}, }, 2, NVC0_COUNTER_OP2_##o, { nu, dn } }
|
||||
#define _M2AB(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_HW_SM_QUERY_METRIC_##n] = { { \
|
||||
#define _M2AB(n, f0, m0, g0, s0, f1, m1, g1, s1, o, nu, dn) [NVE4_PM_QUERY_METRIC_##n] = { { \
|
||||
{ f0, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m0, 0, 0, NVE4_COMPUTE_MP_PM_A_SIGSEL_##g0, s0 }, \
|
||||
{ f1, NVE4_COMPUTE_MP_PM_FUNC_MODE_##m1, 0, 1, NVE4_COMPUTE_MP_PM_B_SIGSEL_##g1, s1 }, \
|
||||
{}, {}, }, 2, NVC0_COUNTER_OP2_##o, { nu, dn } }
|
||||
@@ -881,35 +881,8 @@ struct nvc0_hw_sm_query_cfg
|
||||
* metric-ipXc: we simply multiply by 4 to account for the 4 warp schedulers;
|
||||
* this is inaccurate !
|
||||
*/
|
||||
static const struct nvc0_hw_sm_query_cfg nve4_hw_sm_queries[] =
|
||||
static const struct nvc0_mp_pm_query_cfg nve4_mp_pm_queries[] =
|
||||
{
|
||||
_Q1B(ACTIVE_CYCLES, 0x0001, B6, WARP, 0x00000000, 1, 1),
|
||||
_Q1B(ACTIVE_WARPS, 0x003f, B6, WARP, 0x31483104, 2, 1),
|
||||
_Q1A(ATOM_COUNT, 0x0001, B6, BRANCH, 0x00000000, 1, 1),
|
||||
_Q1A(BRANCH, 0x0001, B6, BRANCH, 0x0000000c, 1, 1),
|
||||
_Q1A(DIVERGENT_BRANCH, 0x0001, B6, BRANCH, 0x00000010, 1, 1),
|
||||
_Q1A(GLD_REQUEST, 0x0001, B6, LDST, 0x00000010, 1, 1),
|
||||
_Q1B(GLD_MEM_DIV_REPLAY, 0x0001, B6, REPLAY, 0x00000010, 1, 1),
|
||||
_Q1B(GST_TRANSACTIONS, 0x0001, B6, MEM, 0x00000004, 1, 1),
|
||||
_Q1B(GST_MEM_DIV_REPLAY, 0x0001, B6, REPLAY, 0x00000014, 1, 1),
|
||||
_Q1A(GRED_COUNT, 0x0001, B6, BRANCH, 0x00000008, 1, 1),
|
||||
_Q1A(GST_REQUEST, 0x0001, B6, LDST, 0x00000014, 1, 1),
|
||||
_Q1A(INST_EXECUTED, 0x0003, B6, EXEC, 0x00000398, 1, 1),
|
||||
_Q1A(INST_ISSUED, 0x0003, B6, ISSUE, 0x00000104, 1, 1),
|
||||
_Q1A(INST_ISSUED1, 0x0001, B6, ISSUE, 0x00000004, 1, 1),
|
||||
_Q1A(INST_ISSUED2, 0x0001, B6, ISSUE, 0x00000008, 1, 1),
|
||||
_Q1B(L1_GLD_HIT, 0x0001, B6, L1, 0x00000010, 1, 1),
|
||||
_Q1B(L1_GLD_MISS, 0x0001, B6, L1, 0x00000014, 1, 1),
|
||||
_Q1B(L1_LOCAL_LD_HIT, 0x0001, B6, L1, 0x00000000, 1, 1),
|
||||
_Q1B(L1_LOCAL_LD_MISS, 0x0001, B6, L1, 0x00000004, 1, 1),
|
||||
_Q1B(L1_LOCAL_ST_HIT, 0x0001, B6, L1, 0x00000008, 1, 1),
|
||||
_Q1B(L1_LOCAL_ST_MISS, 0x0001, B6, L1, 0x0000000c, 1, 1),
|
||||
_Q1B(L1_SHARED_LD_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x00000008, 1, 1),
|
||||
_Q1B(L1_SHARED_ST_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x0000000c, 1, 1),
|
||||
_Q1A(LOCAL_LD, 0x0001, B6, LDST, 0x00000008, 1, 1),
|
||||
_Q1B(LOCAL_LD_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x00000000, 1, 1),
|
||||
_Q1A(LOCAL_ST, 0x0001, B6, LDST, 0x0000000c, 1, 1),
|
||||
_Q1B(LOCAL_ST_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x00000004, 1, 1),
|
||||
_Q1A(PROF_TRIGGER_0, 0x0001, B6, USER, 0x00000000, 1, 1),
|
||||
_Q1A(PROF_TRIGGER_1, 0x0001, B6, USER, 0x00000004, 1, 1),
|
||||
_Q1A(PROF_TRIGGER_2, 0x0001, B6, USER, 0x00000008, 1, 1),
|
||||
@@ -918,14 +891,41 @@ static const struct nvc0_hw_sm_query_cfg nve4_hw_sm_queries[] =
|
||||
_Q1A(PROF_TRIGGER_5, 0x0001, B6, USER, 0x00000014, 1, 1),
|
||||
_Q1A(PROF_TRIGGER_6, 0x0001, B6, USER, 0x00000018, 1, 1),
|
||||
_Q1A(PROF_TRIGGER_7, 0x0001, B6, USER, 0x0000001c, 1, 1),
|
||||
_Q1A(SHARED_LD, 0x0001, B6, LDST, 0x00000000, 1, 1),
|
||||
_Q1B(SHARED_LD_REPLAY, 0x0001, B6, REPLAY, 0x00000008, 1, 1),
|
||||
_Q1A(SHARED_ST, 0x0001, B6, LDST, 0x00000004, 1, 1),
|
||||
_Q1B(SHARED_ST_REPLAY, 0x0001, B6, REPLAY, 0x0000000c, 1, 1),
|
||||
_Q1B(SM_CTA_LAUNCHED, 0x0001, B6, WARP, 0x0000001c, 1, 1),
|
||||
_Q1A(THREADS_LAUNCHED, 0x003f, B6, LAUNCH, 0x398a4188, 1, 1),
|
||||
_Q1B(UNCACHED_GLD_TRANSACTIONS, 0x0001, B6, MEM, 0x00000000, 1, 1),
|
||||
_Q1A(WARPS_LAUNCHED, 0x0001, B6, LAUNCH, 0x00000004, 1, 1),
|
||||
_Q1A(LAUNCHED_WARPS, 0x0001, B6, LAUNCH, 0x00000004, 1, 1),
|
||||
_Q1A(LAUNCHED_THREADS, 0x003f, B6, LAUNCH, 0x398a4188, 1, 1),
|
||||
_Q1B(LAUNCHED_CTA, 0x0001, B6, WARP, 0x0000001c, 1, 1),
|
||||
_Q1A(INST_ISSUED1, 0x0001, B6, ISSUE, 0x00000004, 1, 1),
|
||||
_Q1A(INST_ISSUED2, 0x0001, B6, ISSUE, 0x00000008, 1, 1),
|
||||
_Q1A(INST_ISSUED, 0x0003, B6, ISSUE, 0x00000104, 1, 1),
|
||||
_Q1A(INST_EXECUTED, 0x0003, B6, EXEC, 0x00000398, 1, 1),
|
||||
_Q1A(LD_SHARED, 0x0001, B6, LDST, 0x00000000, 1, 1),
|
||||
_Q1A(ST_SHARED, 0x0001, B6, LDST, 0x00000004, 1, 1),
|
||||
_Q1A(LD_LOCAL, 0x0001, B6, LDST, 0x00000008, 1, 1),
|
||||
_Q1A(ST_LOCAL, 0x0001, B6, LDST, 0x0000000c, 1, 1),
|
||||
_Q1A(GLD_REQUEST, 0x0001, B6, LDST, 0x00000010, 1, 1),
|
||||
_Q1A(GST_REQUEST, 0x0001, B6, LDST, 0x00000014, 1, 1),
|
||||
_Q1B(L1_LOCAL_LOAD_HIT, 0x0001, B6, L1, 0x00000000, 1, 1),
|
||||
_Q1B(L1_LOCAL_LOAD_MISS, 0x0001, B6, L1, 0x00000004, 1, 1),
|
||||
_Q1B(L1_LOCAL_STORE_HIT, 0x0001, B6, L1, 0x00000008, 1, 1),
|
||||
_Q1B(L1_LOCAL_STORE_MISS, 0x0001, B6, L1, 0x0000000c, 1, 1),
|
||||
_Q1B(L1_GLOBAL_LOAD_HIT, 0x0001, B6, L1, 0x00000010, 1, 1),
|
||||
_Q1B(L1_GLOBAL_LOAD_MISS, 0x0001, B6, L1, 0x00000014, 1, 1),
|
||||
_Q1B(GLD_TRANSACTIONS_UNCACHED, 0x0001, B6, MEM, 0x00000000, 1, 1),
|
||||
_Q1B(GST_TRANSACTIONS, 0x0001, B6, MEM, 0x00000004, 1, 1),
|
||||
_Q1A(BRANCH, 0x0001, B6, BRANCH, 0x0000000c, 1, 1),
|
||||
_Q1A(BRANCH_DIVERGENT, 0x0001, B6, BRANCH, 0x00000010, 1, 1),
|
||||
_Q1B(ACTIVE_WARPS, 0x003f, B6, WARP, 0x31483104, 2, 1),
|
||||
_Q1B(ACTIVE_CYCLES, 0x0001, B6, WARP, 0x00000000, 1, 1),
|
||||
_Q1A(ATOM_COUNT, 0x0001, B6, BRANCH, 0x00000000, 1, 1),
|
||||
_Q1A(GRED_COUNT, 0x0001, B6, BRANCH, 0x00000008, 1, 1),
|
||||
_Q1B(LD_SHARED_REPLAY, 0x0001, B6, REPLAY, 0x00000008, 1, 1),
|
||||
_Q1B(ST_SHARED_REPLAY, 0x0001, B6, REPLAY, 0x0000000c, 1, 1),
|
||||
_Q1B(LD_LOCAL_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x00000000, 1, 1),
|
||||
_Q1B(ST_LOCAL_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x00000004, 1, 1),
|
||||
_Q1B(L1_LD_SHARED_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x00000008, 1, 1),
|
||||
_Q1B(L1_ST_SHARED_TRANSACTIONS, 0x0001, B6, TRANSACTION, 0x0000000c, 1, 1),
|
||||
_Q1B(GLD_MEM_DIV_REPLAY, 0x0001, B6, REPLAY, 0x00000010, 1, 1),
|
||||
_Q1B(GST_MEM_DIV_REPLAY, 0x0001, B6, REPLAY, 0x00000014, 1, 1),
|
||||
_M2AB(IPC, 0x3, B6, EXEC, 0x398, 0xffff, LOGOP, WARP, 0x0, DIV_SUM_M0, 10, 1),
|
||||
_M2AB(IPAC, 0x3, B6, EXEC, 0x398, 0x1, B6, WARP, 0x0, AVG_DIV_MM, 10, 1),
|
||||
_M2A(IPEC, 0x3, B6, EXEC, 0x398, 0xe, LOGOP, EXEC, 0x398, AVG_DIV_MM, 10, 1),
|
||||
@@ -940,7 +940,7 @@ static const struct nvc0_hw_sm_query_cfg nve4_hw_sm_queries[] =
|
||||
#undef _M2B
|
||||
|
||||
/* === PERFORMANCE MONITORING COUNTERS for NVC0:NVE4 === */
|
||||
static const uint64_t nvc0_read_hw_sm_counters_code[] =
|
||||
static const uint64_t nvc0_read_mp_pm_counters_code[] =
|
||||
{
|
||||
/* mov b32 $r8 $tidx
|
||||
* mov b32 $r9 $physid
|
||||
@@ -993,21 +993,29 @@ static const uint64_t nvc0_read_hw_sm_counters_code[] =
|
||||
static const char *nvc0_pm_query_names[] =
|
||||
{
|
||||
/* MP counters */
|
||||
"active_cycles",
|
||||
"active_warps",
|
||||
"atom_count",
|
||||
"inst_executed",
|
||||
"branch",
|
||||
"divergent_branch",
|
||||
"gld_request",
|
||||
"active_warps",
|
||||
"active_cycles",
|
||||
"warps_launched",
|
||||
"threads_launched",
|
||||
"shared_load",
|
||||
"shared_store",
|
||||
"local_load",
|
||||
"local_store",
|
||||
"gred_count",
|
||||
"atom_count",
|
||||
"gld_request",
|
||||
"gst_request",
|
||||
"inst_executed",
|
||||
"inst_issued1_0",
|
||||
"inst_issued1_1",
|
||||
"inst_issued2_0",
|
||||
"inst_issued2_1",
|
||||
"local_load",
|
||||
"local_store",
|
||||
"thread_inst_executed_0",
|
||||
"thread_inst_executed_1",
|
||||
"thread_inst_executed_2",
|
||||
"thread_inst_executed_3",
|
||||
"prof_trigger_00",
|
||||
"prof_trigger_01",
|
||||
"prof_trigger_02",
|
||||
@@ -1016,35 +1024,35 @@ static const char *nvc0_pm_query_names[] =
|
||||
"prof_trigger_05",
|
||||
"prof_trigger_06",
|
||||
"prof_trigger_07",
|
||||
"shared_load",
|
||||
"shared_store",
|
||||
"threads_launched",
|
||||
"thread_inst_executed_0",
|
||||
"thread_inst_executed_1",
|
||||
"thread_inst_executed_2",
|
||||
"thread_inst_executed_3",
|
||||
"warps_launched",
|
||||
};
|
||||
|
||||
#define _Q(n, f, m, g, c, s0, s1, s2, s3, s4, s5) [NVC0_HW_SM_QUERY_##n] = { { { f, NVC0_COMPUTE_MP_PM_OP_MODE_##m, c, 0, g, s0|(s1 << 8)|(s2 << 16)|(s3 << 24)|(s4##ULL << 32)|(s5##ULL << 40) }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { 1, 1 } }
|
||||
#define _Q(n, f, m, g, c, s0, s1, s2, s3, s4, s5) [NVC0_PM_QUERY_##n] = { { { f, NVC0_COMPUTE_MP_PM_OP_MODE_##m, c, 0, g, s0|(s1 << 8)|(s2 << 16)|(s3 << 24)|(s4##ULL << 32)|(s5##ULL << 40) }, {}, {}, {} }, 1, NVC0_COUNTER_OPn_SUM, { 1, 1 } }
|
||||
|
||||
static const struct nvc0_hw_sm_query_cfg nvc0_hw_sm_queries[] =
|
||||
static const struct nvc0_mp_pm_query_cfg nvc0_mp_pm_queries[] =
|
||||
{
|
||||
_Q(ACTIVE_CYCLES, 0xaaaa, LOGOP, 0x11, 1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(ACTIVE_WARPS, 0xaaaa, LOGOP, 0x24, 6, 0x10, 0x21, 0x32, 0x43, 0x54, 0x65),
|
||||
_Q(ATOM_COUNT, 0xaaaa, LOGOP, 0x63, 1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(BRANCH, 0xaaaa, LOGOP, 0x1a, 2, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(DIVERGENT_BRANCH, 0xaaaa, LOGOP, 0x19, 2, 0x20, 0x31, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(GLD_REQUEST, 0xaaaa, LOGOP, 0x64, 1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(GRED_COUNT, 0xaaaa, LOGOP, 0x63, 1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(GST_REQUEST, 0xaaaa, LOGOP, 0x64, 1, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(INST_EXECUTED, 0xaaaa, LOGOP, 0x2d, 3, 0x00, 0x11, 0x22, 0x00, 0x00, 0x00),
|
||||
_Q(BRANCH, 0xaaaa, LOGOP, 0x1a, 2, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(BRANCH_DIVERGENT, 0xaaaa, LOGOP, 0x19, 2, 0x20, 0x31, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(ACTIVE_WARPS, 0xaaaa, LOGOP, 0x24, 6, 0x10, 0x21, 0x32, 0x43, 0x54, 0x65),
|
||||
_Q(ACTIVE_CYCLES, 0xaaaa, LOGOP, 0x11, 1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(LAUNCHED_WARPS, 0xaaaa, LOGOP, 0x26, 1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(LAUNCHED_THREADS, 0xaaaa, LOGOP, 0x26, 6, 0x10, 0x21, 0x32, 0x43, 0x54, 0x65),
|
||||
_Q(LD_SHARED, 0xaaaa, LOGOP, 0x64, 1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(ST_SHARED, 0xaaaa, LOGOP, 0x64, 1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(LD_LOCAL, 0xaaaa, LOGOP, 0x64, 1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(ST_LOCAL, 0xaaaa, LOGOP, 0x64, 1, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(GRED_COUNT, 0xaaaa, LOGOP, 0x63, 1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(ATOM_COUNT, 0xaaaa, LOGOP, 0x63, 1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(GLD_REQUEST, 0xaaaa, LOGOP, 0x64, 1, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(GST_REQUEST, 0xaaaa, LOGOP, 0x64, 1, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(INST_ISSUED1_0, 0xaaaa, LOGOP, 0x7e, 1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(INST_ISSUED1_1, 0xaaaa, LOGOP, 0x7e, 1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(INST_ISSUED2_0, 0xaaaa, LOGOP, 0x7e, 1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(INST_ISSUED2_1, 0xaaaa, LOGOP, 0x7e, 1, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(LOCAL_LD, 0xaaaa, LOGOP, 0x64, 1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(LOCAL_ST, 0xaaaa, LOGOP, 0x64, 1, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(TH_INST_EXECUTED_0, 0xaaaa, LOGOP, 0xa3, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(TH_INST_EXECUTED_1, 0xaaaa, LOGOP, 0xa5, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(TH_INST_EXECUTED_2, 0xaaaa, LOGOP, 0xa4, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(TH_INST_EXECUTED_3, 0xaaaa, LOGOP, 0xa6, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(PROF_TRIGGER_0, 0xaaaa, LOGOP, 0x01, 1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(PROF_TRIGGER_1, 0xaaaa, LOGOP, 0x01, 1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(PROF_TRIGGER_2, 0xaaaa, LOGOP, 0x01, 1, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
@@ -1053,46 +1061,38 @@ static const struct nvc0_hw_sm_query_cfg nvc0_hw_sm_queries[] =
|
||||
_Q(PROF_TRIGGER_5, 0xaaaa, LOGOP, 0x01, 1, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(PROF_TRIGGER_6, 0xaaaa, LOGOP, 0x01, 1, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(PROF_TRIGGER_7, 0xaaaa, LOGOP, 0x01, 1, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(SHARED_LD, 0xaaaa, LOGOP, 0x64, 1, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(SHARED_ST, 0xaaaa, LOGOP, 0x64, 1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
_Q(THREADS_LAUNCHED, 0xaaaa, LOGOP, 0x26, 6, 0x10, 0x21, 0x32, 0x43, 0x54, 0x65),
|
||||
_Q(TH_INST_EXECUTED_0, 0xaaaa, LOGOP, 0xa3, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(TH_INST_EXECUTED_1, 0xaaaa, LOGOP, 0xa5, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(TH_INST_EXECUTED_2, 0xaaaa, LOGOP, 0xa4, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(TH_INST_EXECUTED_3, 0xaaaa, LOGOP, 0xa6, 6, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55),
|
||||
_Q(WARPS_LAUNCHED, 0xaaaa, LOGOP, 0x26, 1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
};
|
||||
|
||||
#undef _Q
|
||||
|
||||
static const struct nvc0_hw_sm_query_cfg *
|
||||
nvc0_hw_sm_query_get_cfg(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
static const struct nvc0_mp_pm_query_cfg *
|
||||
nvc0_mp_pm_query_get_cfg(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0->screen;
|
||||
|
||||
if (screen->base.class_3d >= NVE4_3D_CLASS)
|
||||
return &nve4_hw_sm_queries[q->type - PIPE_QUERY_DRIVER_SPECIFIC];
|
||||
return &nvc0_hw_sm_queries[q->type - NVC0_HW_SM_QUERY(0)];
|
||||
return &nve4_mp_pm_queries[q->type - PIPE_QUERY_DRIVER_SPECIFIC];
|
||||
return &nvc0_mp_pm_queries[q->type - NVC0_PM_QUERY(0)];
|
||||
}
|
||||
|
||||
boolean
|
||||
nvc0_hw_sm_query_begin(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
nvc0_mp_pm_query_begin(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0->screen;
|
||||
struct nouveau_pushbuf *push = nvc0->base.pushbuf;
|
||||
const bool is_nve4 = screen->base.class_3d >= NVE4_3D_CLASS;
|
||||
const struct nvc0_hw_sm_query_cfg *cfg;
|
||||
const struct nvc0_mp_pm_query_cfg *cfg;
|
||||
unsigned i, c;
|
||||
unsigned num_ab[2] = { 0, 0 };
|
||||
|
||||
cfg = nvc0_hw_sm_query_get_cfg(nvc0, q);
|
||||
cfg = nvc0_mp_pm_query_get_cfg(nvc0, q);
|
||||
|
||||
/* check if we have enough free counter slots */
|
||||
for (i = 0; i < cfg->num_counters; ++i)
|
||||
num_ab[cfg->ctr[i].sig_dom]++;
|
||||
|
||||
if (screen->pm.num_hw_sm_active[0] + num_ab[0] > 4 ||
|
||||
screen->pm.num_hw_sm_active[1] + num_ab[1] > 4) {
|
||||
if (screen->pm.num_mp_pm_active[0] + num_ab[0] > 4 ||
|
||||
screen->pm.num_mp_pm_active[1] + num_ab[1] > 4) {
|
||||
NOUVEAU_ERR("Not enough free MP counter slots !\n");
|
||||
return false;
|
||||
}
|
||||
@@ -1113,14 +1113,14 @@ nvc0_hw_sm_query_begin(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
for (i = 0; i < cfg->num_counters; ++i) {
|
||||
const unsigned d = cfg->ctr[i].sig_dom;
|
||||
|
||||
if (!screen->pm.num_hw_sm_active[d]) {
|
||||
if (!screen->pm.num_mp_pm_active[d]) {
|
||||
uint32_t m = (1 << 22) | (1 << (7 + (8 * !d)));
|
||||
if (screen->pm.num_hw_sm_active[!d])
|
||||
if (screen->pm.num_mp_pm_active[!d])
|
||||
m |= 1 << (7 + (8 * d));
|
||||
BEGIN_NVC0(push, SUBC_SW(0x0600), 1);
|
||||
PUSH_DATA (push, m);
|
||||
}
|
||||
screen->pm.num_hw_sm_active[d]++;
|
||||
screen->pm.num_mp_pm_active[d]++;
|
||||
|
||||
for (c = d * 4; c < (d * 4 + 4); ++c) {
|
||||
if (!screen->pm.mp_counter[c]) {
|
||||
@@ -1163,7 +1163,7 @@ nvc0_hw_sm_query_begin(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_hw_sm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
nvc0_mp_pm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
{
|
||||
struct nvc0_screen *screen = nvc0->screen;
|
||||
struct pipe_context *pipe = &nvc0->base.pipe;
|
||||
@@ -1174,9 +1174,9 @@ nvc0_hw_sm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
const uint block[3] = { 32, is_nve4 ? 4 : 1, 1 };
|
||||
const uint grid[3] = { screen->mp_count, 1, 1 };
|
||||
unsigned c;
|
||||
const struct nvc0_hw_sm_query_cfg *cfg;
|
||||
const struct nvc0_mp_pm_query_cfg *cfg;
|
||||
|
||||
cfg = nvc0_hw_sm_query_get_cfg(nvc0, q);
|
||||
cfg = nvc0_mp_pm_query_get_cfg(nvc0, q);
|
||||
|
||||
if (unlikely(!screen->pm.prog)) {
|
||||
struct nvc0_program *prog = CALLOC_STRUCT(nvc0_program);
|
||||
@@ -1185,11 +1185,11 @@ nvc0_hw_sm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
prog->num_gprs = 14;
|
||||
prog->parm_size = 12;
|
||||
if (is_nve4) {
|
||||
prog->code = (uint32_t *)nve4_read_hw_sm_counters_code;
|
||||
prog->code_size = sizeof(nve4_read_hw_sm_counters_code);
|
||||
prog->code = (uint32_t *)nve4_read_mp_pm_counters_code;
|
||||
prog->code_size = sizeof(nve4_read_mp_pm_counters_code);
|
||||
} else {
|
||||
prog->code = (uint32_t *)nvc0_read_hw_sm_counters_code;
|
||||
prog->code_size = sizeof(nvc0_read_hw_sm_counters_code);
|
||||
prog->code = (uint32_t *)nvc0_read_mp_pm_counters_code;
|
||||
prog->code_size = sizeof(nvc0_read_mp_pm_counters_code);
|
||||
}
|
||||
screen->pm.prog = prog;
|
||||
}
|
||||
@@ -1207,7 +1207,7 @@ nvc0_hw_sm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
/* release counters for this query */
|
||||
for (c = 0; c < 8; ++c) {
|
||||
if (nvc0_query(screen->pm.mp_counter[c]) == q) {
|
||||
screen->pm.num_hw_sm_active[c / 4]--;
|
||||
screen->pm.num_mp_pm_active[c / 4]--;
|
||||
screen->pm.mp_counter[c] = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1234,7 +1234,7 @@ nvc0_hw_sm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
q = nvc0_query(screen->pm.mp_counter[c]);
|
||||
if (!q)
|
||||
continue;
|
||||
cfg = nvc0_hw_sm_query_get_cfg(nvc0, q);
|
||||
cfg = nvc0_mp_pm_query_get_cfg(nvc0, q);
|
||||
for (i = 0; i < cfg->num_counters; ++i) {
|
||||
if (mask & (1 << q->ctr[i]))
|
||||
break;
|
||||
@@ -1250,10 +1250,10 @@ nvc0_hw_sm_query_end(struct nvc0_context *nvc0, struct nvc0_query *q)
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nvc0_hw_sm_query_read_data(uint32_t count[32][4],
|
||||
nvc0_mp_pm_query_read_data(uint32_t count[32][4],
|
||||
struct nvc0_context *nvc0, bool wait,
|
||||
struct nvc0_query *q,
|
||||
const struct nvc0_hw_sm_query_cfg *cfg,
|
||||
const struct nvc0_mp_pm_query_cfg *cfg,
|
||||
unsigned mp_count)
|
||||
{
|
||||
unsigned p, c;
|
||||
@@ -1275,10 +1275,10 @@ nvc0_hw_sm_query_read_data(uint32_t count[32][4],
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nve4_hw_sm_query_read_data(uint32_t count[32][4],
|
||||
nve4_mp_pm_query_read_data(uint32_t count[32][4],
|
||||
struct nvc0_context *nvc0, bool wait,
|
||||
struct nvc0_query *q,
|
||||
const struct nvc0_hw_sm_query_cfg *cfg,
|
||||
const struct nvc0_mp_pm_query_cfg *cfg,
|
||||
unsigned mp_count)
|
||||
{
|
||||
unsigned p, c, d;
|
||||
@@ -1317,22 +1317,22 @@ nve4_hw_sm_query_read_data(uint32_t count[32][4],
|
||||
* NOTE: Interpretation of IPC requires knowledge of MP count.
|
||||
*/
|
||||
static boolean
|
||||
nvc0_hw_sm_query_result(struct nvc0_context *nvc0, struct nvc0_query *q,
|
||||
nvc0_mp_pm_query_result(struct nvc0_context *nvc0, struct nvc0_query *q,
|
||||
void *result, boolean wait)
|
||||
{
|
||||
uint32_t count[32][4];
|
||||
uint64_t value = 0;
|
||||
unsigned mp_count = MIN2(nvc0->screen->mp_count_compute, 32);
|
||||
unsigned p, c;
|
||||
const struct nvc0_hw_sm_query_cfg *cfg;
|
||||
const struct nvc0_mp_pm_query_cfg *cfg;
|
||||
bool ret;
|
||||
|
||||
cfg = nvc0_hw_sm_query_get_cfg(nvc0, q);
|
||||
cfg = nvc0_mp_pm_query_get_cfg(nvc0, q);
|
||||
|
||||
if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS)
|
||||
ret = nve4_hw_sm_query_read_data(count, nvc0, wait, q, cfg, mp_count);
|
||||
ret = nve4_mp_pm_query_read_data(count, nvc0, wait, q, cfg, mp_count);
|
||||
else
|
||||
ret = nvc0_hw_sm_query_read_data(count, nvc0, wait, q, cfg, mp_count);
|
||||
ret = nvc0_mp_pm_query_read_data(count, nvc0, wait, q, cfg, mp_count);
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
@@ -1410,11 +1410,11 @@ nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen,
|
||||
if (screen->base.device->drm_version >= 0x01000101) {
|
||||
if (screen->compute) {
|
||||
if (screen->base.class_3d == NVE4_3D_CLASS) {
|
||||
count += NVE4_HW_SM_QUERY_COUNT;
|
||||
count += NVE4_PM_QUERY_COUNT;
|
||||
} else
|
||||
if (screen->base.class_3d < NVE4_3D_CLASS) {
|
||||
/* NVC0_COMPUTE is not always enabled */
|
||||
count += NVC0_HW_SM_QUERY_COUNT;
|
||||
count += NVC0_PM_QUERY_COUNT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1444,15 +1444,15 @@ nvc0_screen_get_driver_query_info(struct pipe_screen *pscreen,
|
||||
if (screen->compute) {
|
||||
if (screen->base.class_3d == NVE4_3D_CLASS) {
|
||||
info->name = nve4_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
|
||||
info->query_type = NVE4_HW_SM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
|
||||
info->query_type = NVE4_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
|
||||
info->max_value.u64 =
|
||||
(id < NVE4_HW_SM_QUERY_METRIC_MP_OCCUPANCY) ? 0 : 100;
|
||||
(id < NVE4_PM_QUERY_METRIC_MP_OCCUPANCY) ? 0 : 100;
|
||||
info->group_id = NVC0_QUERY_MP_COUNTER_GROUP;
|
||||
return 1;
|
||||
} else
|
||||
if (screen->base.class_3d < NVE4_3D_CLASS) {
|
||||
info->name = nvc0_pm_query_names[id - NVC0_QUERY_DRV_STAT_COUNT];
|
||||
info->query_type = NVC0_HW_SM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
|
||||
info->query_type = NVC0_PM_QUERY(id - NVC0_QUERY_DRV_STAT_COUNT);
|
||||
info->group_id = NVC0_QUERY_MP_COUNTER_GROUP;
|
||||
return 1;
|
||||
}
|
||||
@@ -1494,7 +1494,7 @@ nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
|
||||
info->type = PIPE_DRIVER_QUERY_GROUP_TYPE_GPU;
|
||||
|
||||
if (screen->base.class_3d == NVE4_3D_CLASS) {
|
||||
info->num_queries = NVE4_HW_SM_QUERY_COUNT;
|
||||
info->num_queries = NVE4_PM_QUERY_COUNT;
|
||||
|
||||
/* On NVE4+, each multiprocessor have 8 hardware counters separated
|
||||
* in two distinct domains, but we allow only one active query
|
||||
@@ -1504,7 +1504,7 @@ nvc0_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
|
||||
return 1;
|
||||
} else
|
||||
if (screen->base.class_3d < NVE4_3D_CLASS) {
|
||||
info->num_queries = NVC0_HW_SM_QUERY_COUNT;
|
||||
info->num_queries = NVC0_PM_QUERY_COUNT;
|
||||
|
||||
/* On NVC0:NVE4, each multiprocessor have 8 hardware counters
|
||||
* in a single domain. */
|
||||
|
@@ -87,7 +87,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET:
|
||||
return 31;
|
||||
case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
|
||||
return 65536;
|
||||
return 128 * 1024 * 1024;
|
||||
case PIPE_CAP_GLSL_FEATURE_LEVEL:
|
||||
return 410;
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
|
@@ -95,7 +95,7 @@ struct nvc0_screen {
|
||||
struct {
|
||||
struct nvc0_program *prog; /* compute state object to read MP counters */
|
||||
struct pipe_query *mp_counter[8]; /* counter to query allocation */
|
||||
uint8_t num_hw_sm_active[2];
|
||||
uint8_t num_mp_pm_active[2];
|
||||
bool mp_counters_enabled;
|
||||
} pm;
|
||||
|
||||
@@ -120,139 +120,156 @@ nvc0_screen(struct pipe_screen *screen)
|
||||
|
||||
/* Performance counter queries:
|
||||
*/
|
||||
#define NVE4_HW_SM_QUERY(i) (PIPE_QUERY_DRIVER_SPECIFIC + (i))
|
||||
#define NVE4_HW_SM_QUERY_LAST NVE4_HW_SM_QUERY(NVE4_HW_SM_QUERY_COUNT - 1)
|
||||
enum nve4_pm_queries
|
||||
{
|
||||
NVE4_HW_SM_QUERY_ACTIVE_CYCLES = 0,
|
||||
NVE4_HW_SM_QUERY_ACTIVE_WARPS,
|
||||
NVE4_HW_SM_QUERY_ATOM_COUNT,
|
||||
NVE4_HW_SM_QUERY_BRANCH,
|
||||
NVE4_HW_SM_QUERY_DIVERGENT_BRANCH,
|
||||
NVE4_HW_SM_QUERY_GLD_REQUEST,
|
||||
NVE4_HW_SM_QUERY_GLD_MEM_DIV_REPLAY,
|
||||
NVE4_HW_SM_QUERY_GST_TRANSACTIONS,
|
||||
NVE4_HW_SM_QUERY_GST_MEM_DIV_REPLAY,
|
||||
NVE4_HW_SM_QUERY_GRED_COUNT,
|
||||
NVE4_HW_SM_QUERY_GST_REQUEST,
|
||||
NVE4_HW_SM_QUERY_INST_EXECUTED,
|
||||
NVE4_HW_SM_QUERY_INST_ISSUED,
|
||||
NVE4_HW_SM_QUERY_INST_ISSUED1,
|
||||
NVE4_HW_SM_QUERY_INST_ISSUED2,
|
||||
NVE4_HW_SM_QUERY_L1_GLD_HIT,
|
||||
NVE4_HW_SM_QUERY_L1_GLD_MISS,
|
||||
NVE4_HW_SM_QUERY_L1_LOCAL_LD_HIT,
|
||||
NVE4_HW_SM_QUERY_L1_LOCAL_LD_MISS,
|
||||
NVE4_HW_SM_QUERY_L1_LOCAL_ST_HIT,
|
||||
NVE4_HW_SM_QUERY_L1_LOCAL_ST_MISS,
|
||||
NVE4_HW_SM_QUERY_L1_SHARED_LD_TRANSACTIONS,
|
||||
NVE4_HW_SM_QUERY_L1_SHARED_ST_TRANSACTIONS,
|
||||
NVE4_HW_SM_QUERY_LOCAL_LD,
|
||||
NVE4_HW_SM_QUERY_LOCAL_LD_TRANSACTIONS,
|
||||
NVE4_HW_SM_QUERY_LOCAL_ST,
|
||||
NVE4_HW_SM_QUERY_LOCAL_ST_TRANSACTIONS,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_0,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_1,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_2,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_3,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_4,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_5,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_6,
|
||||
NVE4_HW_SM_QUERY_PROF_TRIGGER_7,
|
||||
NVE4_HW_SM_QUERY_SHARED_LD,
|
||||
NVE4_HW_SM_QUERY_SHARED_LD_REPLAY,
|
||||
NVE4_HW_SM_QUERY_SHARED_ST,
|
||||
NVE4_HW_SM_QUERY_SHARED_ST_REPLAY,
|
||||
NVE4_HW_SM_QUERY_SM_CTA_LAUNCHED,
|
||||
NVE4_HW_SM_QUERY_THREADS_LAUNCHED,
|
||||
NVE4_HW_SM_QUERY_UNCACHED_GLD_TRANSACTIONS,
|
||||
NVE4_HW_SM_QUERY_WARPS_LAUNCHED,
|
||||
NVE4_HW_SM_QUERY_METRIC_IPC,
|
||||
NVE4_HW_SM_QUERY_METRIC_IPAC,
|
||||
NVE4_HW_SM_QUERY_METRIC_IPEC,
|
||||
NVE4_HW_SM_QUERY_METRIC_MP_OCCUPANCY,
|
||||
NVE4_HW_SM_QUERY_METRIC_MP_EFFICIENCY,
|
||||
NVE4_HW_SM_QUERY_METRIC_INST_REPLAY_OHEAD,
|
||||
NVE4_HW_SM_QUERY_COUNT
|
||||
};
|
||||
#define NVE4_PM_QUERY_COUNT 49
|
||||
#define NVE4_PM_QUERY(i) (PIPE_QUERY_DRIVER_SPECIFIC + (i))
|
||||
#define NVE4_PM_QUERY_LAST NVE4_PM_QUERY(NVE4_PM_QUERY_COUNT - 1)
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_0 0
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_1 1
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_2 2
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_3 3
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_4 4
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_5 5
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_6 6
|
||||
#define NVE4_PM_QUERY_PROF_TRIGGER_7 7
|
||||
#define NVE4_PM_QUERY_LAUNCHED_WARPS 8
|
||||
#define NVE4_PM_QUERY_LAUNCHED_THREADS 9
|
||||
#define NVE4_PM_QUERY_LAUNCHED_CTA 10
|
||||
#define NVE4_PM_QUERY_INST_ISSUED1 11
|
||||
#define NVE4_PM_QUERY_INST_ISSUED2 12
|
||||
#define NVE4_PM_QUERY_INST_EXECUTED 13
|
||||
#define NVE4_PM_QUERY_LD_LOCAL 14
|
||||
#define NVE4_PM_QUERY_ST_LOCAL 15
|
||||
#define NVE4_PM_QUERY_LD_SHARED 16
|
||||
#define NVE4_PM_QUERY_ST_SHARED 17
|
||||
#define NVE4_PM_QUERY_L1_LOCAL_LOAD_HIT 18
|
||||
#define NVE4_PM_QUERY_L1_LOCAL_LOAD_MISS 19
|
||||
#define NVE4_PM_QUERY_L1_LOCAL_STORE_HIT 20
|
||||
#define NVE4_PM_QUERY_L1_LOCAL_STORE_MISS 21
|
||||
#define NVE4_PM_QUERY_GLD_REQUEST 22
|
||||
#define NVE4_PM_QUERY_GST_REQUEST 23
|
||||
#define NVE4_PM_QUERY_L1_GLOBAL_LOAD_HIT 24
|
||||
#define NVE4_PM_QUERY_L1_GLOBAL_LOAD_MISS 25
|
||||
#define NVE4_PM_QUERY_GLD_TRANSACTIONS_UNCACHED 26
|
||||
#define NVE4_PM_QUERY_GST_TRANSACTIONS 27
|
||||
#define NVE4_PM_QUERY_BRANCH 28
|
||||
#define NVE4_PM_QUERY_BRANCH_DIVERGENT 29
|
||||
#define NVE4_PM_QUERY_ACTIVE_WARPS 30
|
||||
#define NVE4_PM_QUERY_ACTIVE_CYCLES 31
|
||||
#define NVE4_PM_QUERY_INST_ISSUED 32
|
||||
#define NVE4_PM_QUERY_ATOM_COUNT 33
|
||||
#define NVE4_PM_QUERY_GRED_COUNT 34
|
||||
#define NVE4_PM_QUERY_LD_SHARED_REPLAY 35
|
||||
#define NVE4_PM_QUERY_ST_SHARED_REPLAY 36
|
||||
#define NVE4_PM_QUERY_LD_LOCAL_TRANSACTIONS 37
|
||||
#define NVE4_PM_QUERY_ST_LOCAL_TRANSACTIONS 38
|
||||
#define NVE4_PM_QUERY_L1_LD_SHARED_TRANSACTIONS 39
|
||||
#define NVE4_PM_QUERY_L1_ST_SHARED_TRANSACTIONS 40
|
||||
#define NVE4_PM_QUERY_GLD_MEM_DIV_REPLAY 41
|
||||
#define NVE4_PM_QUERY_GST_MEM_DIV_REPLAY 42
|
||||
#define NVE4_PM_QUERY_METRIC_IPC 43
|
||||
#define NVE4_PM_QUERY_METRIC_IPAC 44
|
||||
#define NVE4_PM_QUERY_METRIC_IPEC 45
|
||||
#define NVE4_PM_QUERY_METRIC_MP_OCCUPANCY 46
|
||||
#define NVE4_PM_QUERY_METRIC_MP_EFFICIENCY 47
|
||||
#define NVE4_PM_QUERY_METRIC_INST_REPLAY_OHEAD 48
|
||||
|
||||
#define NVC0_HW_SM_QUERY(i) (PIPE_QUERY_DRIVER_SPECIFIC + 2048 + (i))
|
||||
#define NVC0_HW_SM_QUERY_LAST NVC0_HW_SM_QUERY(NVC0_HW_SM_QUERY_COUNT - 1)
|
||||
enum nvc0_pm_queries
|
||||
{
|
||||
NVC0_HW_SM_QUERY_ACTIVE_CYCLES = 0,
|
||||
NVC0_HW_SM_QUERY_ACTIVE_WARPS,
|
||||
NVC0_HW_SM_QUERY_ATOM_COUNT,
|
||||
NVC0_HW_SM_QUERY_BRANCH,
|
||||
NVC0_HW_SM_QUERY_DIVERGENT_BRANCH,
|
||||
NVC0_HW_SM_QUERY_GLD_REQUEST,
|
||||
NVC0_HW_SM_QUERY_GRED_COUNT,
|
||||
NVC0_HW_SM_QUERY_GST_REQUEST,
|
||||
NVC0_HW_SM_QUERY_INST_EXECUTED,
|
||||
NVC0_HW_SM_QUERY_INST_ISSUED1_0,
|
||||
NVC0_HW_SM_QUERY_INST_ISSUED1_1,
|
||||
NVC0_HW_SM_QUERY_INST_ISSUED2_0,
|
||||
NVC0_HW_SM_QUERY_INST_ISSUED2_1,
|
||||
NVC0_HW_SM_QUERY_LOCAL_LD,
|
||||
NVC0_HW_SM_QUERY_LOCAL_ST,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_0,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_1,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_2,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_3,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_4,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_5,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_6,
|
||||
NVC0_HW_SM_QUERY_PROF_TRIGGER_7,
|
||||
NVC0_HW_SM_QUERY_SHARED_LD,
|
||||
NVC0_HW_SM_QUERY_SHARED_ST,
|
||||
NVC0_HW_SM_QUERY_THREADS_LAUNCHED,
|
||||
NVC0_HW_SM_QUERY_TH_INST_EXECUTED_0,
|
||||
NVC0_HW_SM_QUERY_TH_INST_EXECUTED_1,
|
||||
NVC0_HW_SM_QUERY_TH_INST_EXECUTED_2,
|
||||
NVC0_HW_SM_QUERY_TH_INST_EXECUTED_3,
|
||||
NVC0_HW_SM_QUERY_WARPS_LAUNCHED,
|
||||
NVC0_HW_SM_QUERY_COUNT
|
||||
};
|
||||
/*
|
||||
#define NVE4_PM_QUERY_GR_IDLE 50
|
||||
#define NVE4_PM_QUERY_BSP_IDLE 51
|
||||
#define NVE4_PM_QUERY_VP_IDLE 52
|
||||
#define NVE4_PM_QUERY_PPP_IDLE 53
|
||||
#define NVE4_PM_QUERY_CE0_IDLE 54
|
||||
#define NVE4_PM_QUERY_CE1_IDLE 55
|
||||
#define NVE4_PM_QUERY_CE2_IDLE 56
|
||||
*/
|
||||
/* L2 queries (PCOUNTER) */
|
||||
/*
|
||||
#define NVE4_PM_QUERY_L2_SUBP_WRITE_L1_SECTOR_QUERIES 57
|
||||
...
|
||||
*/
|
||||
/* TEX queries (PCOUNTER) */
|
||||
/*
|
||||
#define NVE4_PM_QUERY_TEX0_CACHE_SECTOR_QUERIES 58
|
||||
...
|
||||
*/
|
||||
|
||||
#define NVC0_PM_QUERY_COUNT 31
|
||||
#define NVC0_PM_QUERY(i) (PIPE_QUERY_DRIVER_SPECIFIC + 2048 + (i))
|
||||
#define NVC0_PM_QUERY_LAST NVC0_PM_QUERY(NVC0_PM_QUERY_COUNT - 1)
|
||||
#define NVC0_PM_QUERY_INST_EXECUTED 0
|
||||
#define NVC0_PM_QUERY_BRANCH 1
|
||||
#define NVC0_PM_QUERY_BRANCH_DIVERGENT 2
|
||||
#define NVC0_PM_QUERY_ACTIVE_WARPS 3
|
||||
#define NVC0_PM_QUERY_ACTIVE_CYCLES 4
|
||||
#define NVC0_PM_QUERY_LAUNCHED_WARPS 5
|
||||
#define NVC0_PM_QUERY_LAUNCHED_THREADS 6
|
||||
#define NVC0_PM_QUERY_LD_SHARED 7
|
||||
#define NVC0_PM_QUERY_ST_SHARED 8
|
||||
#define NVC0_PM_QUERY_LD_LOCAL 9
|
||||
#define NVC0_PM_QUERY_ST_LOCAL 10
|
||||
#define NVC0_PM_QUERY_GRED_COUNT 11
|
||||
#define NVC0_PM_QUERY_ATOM_COUNT 12
|
||||
#define NVC0_PM_QUERY_GLD_REQUEST 13
|
||||
#define NVC0_PM_QUERY_GST_REQUEST 14
|
||||
#define NVC0_PM_QUERY_INST_ISSUED1_0 15
|
||||
#define NVC0_PM_QUERY_INST_ISSUED1_1 16
|
||||
#define NVC0_PM_QUERY_INST_ISSUED2_0 17
|
||||
#define NVC0_PM_QUERY_INST_ISSUED2_1 18
|
||||
#define NVC0_PM_QUERY_TH_INST_EXECUTED_0 19
|
||||
#define NVC0_PM_QUERY_TH_INST_EXECUTED_1 20
|
||||
#define NVC0_PM_QUERY_TH_INST_EXECUTED_2 21
|
||||
#define NVC0_PM_QUERY_TH_INST_EXECUTED_3 22
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_0 23
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_1 24
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_2 25
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_3 26
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_4 27
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_5 28
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_6 29
|
||||
#define NVC0_PM_QUERY_PROF_TRIGGER_7 30
|
||||
|
||||
/* Driver statistics queries:
|
||||
*/
|
||||
#define NVC0_QUERY_DRV_STAT(i) (PIPE_QUERY_DRIVER_SPECIFIC + 1024 + (i))
|
||||
#define NVC0_QUERY_DRV_STAT_LAST NVC0_QUERY_DRV_STAT(NVC0_QUERY_DRV_STAT_COUNT - 1)
|
||||
enum nvc0_drv_stats_queries
|
||||
{
|
||||
#ifdef NOUVEAU_ENABLE_DRIVER_STATISTICS
|
||||
NVC0_QUERY_DRV_STAT_TEX_OBJECT_CURRENT_COUNT = 0,
|
||||
NVC0_QUERY_DRV_STAT_TEX_OBJECT_CURRENT_BYTES,
|
||||
NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_BYTES_VID,
|
||||
NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_BYTES_SYS,
|
||||
NVC0_QUERY_DRV_STAT_TEX_TRANSFERS_READ,
|
||||
NVC0_QUERY_DRV_STAT_TEX_TRANSFERS_WRITE,
|
||||
NVC0_QUERY_DRV_STAT_TEX_COPY_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_TEX_BLIT_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_TEX_CACHE_FLUSH_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_BUF_TRANSFERS_READ,
|
||||
NVC0_QUERY_DRV_STAT_BUF_TRANSFERS_WRITE,
|
||||
NVC0_QUERY_DRV_STAT_BUF_READ_BYTES_STAGING_VID,
|
||||
NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_DIRECT,
|
||||
NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_STAGING_VID,
|
||||
NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_STAGING_SYS,
|
||||
NVC0_QUERY_DRV_STAT_BUF_COPY_BYTES,
|
||||
NVC0_QUERY_DRV_STAT_BUF_NON_KERNEL_FENCE_SYNC_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_ANY_NON_KERNEL_FENCE_SYNC_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_QUERY_SYNC_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_GPU_SERIALIZE_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_DRAW_CALLS_ARRAY,
|
||||
NVC0_QUERY_DRV_STAT_DRAW_CALLS_INDEXED,
|
||||
NVC0_QUERY_DRV_STAT_DRAW_CALLS_FALLBACK_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_USER_BUFFER_UPLOAD_BYTES,
|
||||
NVC0_QUERY_DRV_STAT_CONSTBUF_UPLOAD_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_CONSTBUF_UPLOAD_BYTES,
|
||||
NVC0_QUERY_DRV_STAT_PUSHBUF_COUNT,
|
||||
NVC0_QUERY_DRV_STAT_RESOURCE_VALIDATE_COUNT,
|
||||
|
||||
#define NVC0_QUERY_DRV_STAT(i) (PIPE_QUERY_DRIVER_SPECIFIC + 1024 + (i))
|
||||
#define NVC0_QUERY_DRV_STAT_COUNT 29
|
||||
#define NVC0_QUERY_DRV_STAT_LAST NVC0_QUERY_DRV_STAT(NVC0_QUERY_DRV_STAT_COUNT - 1)
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_OBJECT_CURRENT_COUNT 0
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_OBJECT_CURRENT_BYTES 1
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_COUNT 2
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_BYTES_VID 3
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_OBJECT_CURRENT_BYTES_SYS 4
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_TRANSFERS_READ 5
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_TRANSFERS_WRITE 6
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_COPY_COUNT 7
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_BLIT_COUNT 8
|
||||
#define NVC0_QUERY_DRV_STAT_TEX_CACHE_FLUSH_COUNT 9
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_TRANSFERS_READ 10
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_TRANSFERS_WRITE 11
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_READ_BYTES_STAGING_VID 12
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_DIRECT 13
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_STAGING_VID 14
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_WRITE_BYTES_STAGING_SYS 15
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_COPY_BYTES 16
|
||||
#define NVC0_QUERY_DRV_STAT_BUF_NON_KERNEL_FENCE_SYNC_COUNT 17
|
||||
#define NVC0_QUERY_DRV_STAT_ANY_NON_KERNEL_FENCE_SYNC_COUNT 18
|
||||
#define NVC0_QUERY_DRV_STAT_QUERY_SYNC_COUNT 19
|
||||
#define NVC0_QUERY_DRV_STAT_GPU_SERIALIZE_COUNT 20
|
||||
#define NVC0_QUERY_DRV_STAT_DRAW_CALLS_ARRAY 21
|
||||
#define NVC0_QUERY_DRV_STAT_DRAW_CALLS_INDEXED 22
|
||||
#define NVC0_QUERY_DRV_STAT_DRAW_CALLS_FALLBACK_COUNT 23
|
||||
#define NVC0_QUERY_DRV_STAT_USER_BUFFER_UPLOAD_BYTES 24
|
||||
#define NVC0_QUERY_DRV_STAT_CONSTBUF_UPLOAD_COUNT 25
|
||||
#define NVC0_QUERY_DRV_STAT_CONSTBUF_UPLOAD_BYTES 26
|
||||
#define NVC0_QUERY_DRV_STAT_PUSHBUF_COUNT 27
|
||||
#define NVC0_QUERY_DRV_STAT_RESOURCE_VALIDATE_COUNT 28
|
||||
|
||||
#else
|
||||
|
||||
#define NVC0_QUERY_DRV_STAT_COUNT 0
|
||||
|
||||
#endif
|
||||
NVC0_QUERY_DRV_STAT_COUNT
|
||||
};
|
||||
|
||||
int nvc0_screen_get_driver_query_info(struct pipe_screen *, unsigned,
|
||||
struct pipe_driver_query_info *);
|
||||
|
@@ -831,6 +831,8 @@ nvc0_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index,
|
||||
}
|
||||
nvc0->constbuf_dirty[s] |= 1 << i;
|
||||
|
||||
if (nvc0->constbuf[s][i].u.buf)
|
||||
nv04_resource(nvc0->constbuf[s][i].u.buf)->cb_bindings[s] &= ~(1 << i);
|
||||
pipe_resource_reference(&nvc0->constbuf[s][i].u.buf, res);
|
||||
|
||||
nvc0->constbuf[s][i].user = (cb && cb->user_buffer) ? true : false;
|
||||
|
@@ -440,7 +440,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
|
||||
PUSH_DATA (push, (0 << 4) | 1);
|
||||
}
|
||||
nvc0_cb_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
|
||||
nvc0_cb_bo_push(&nvc0->base, bo, NV_VRAM_DOMAIN(&nvc0->screen->base),
|
||||
base, nvc0->state.uniform_buffer_bound[s],
|
||||
0, (size + 3) / 4,
|
||||
nvc0->constbuf[s][0].u.data);
|
||||
@@ -458,6 +458,7 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
|
||||
BCTX_REFN(nvc0->bufctx_3d, CB(s, i), res, RD);
|
||||
|
||||
nvc0->cb_dirty = 1; /* Force cache flush for UBO. */
|
||||
res->cb_bindings[s] |= 1 << i;
|
||||
} else {
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_BIND(s)), 1);
|
||||
PUSH_DATA (push, (i << 4) | 0);
|
||||
|
@@ -226,6 +226,26 @@ nvc0_create_texture_view(struct pipe_context *pipe,
|
||||
return &view->pipe;
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_update_tic(struct nvc0_context *nvc0, struct nv50_tic_entry *tic,
|
||||
struct nv04_resource *res)
|
||||
{
|
||||
uint64_t address = res->address;
|
||||
if (res->base.target != PIPE_BUFFER)
|
||||
return;
|
||||
address += tic->pipe.u.buf.first_element *
|
||||
util_format_get_blocksize(tic->pipe.format);
|
||||
if (tic->tic[1] == (uint32_t)address &&
|
||||
(tic->tic[2] & 0xff) == address >> 32)
|
||||
return;
|
||||
|
||||
nvc0_screen_tic_unlock(nvc0->screen, tic);
|
||||
tic->id = -1;
|
||||
tic->tic[1] = address;
|
||||
tic->tic[2] &= 0xffffff00;
|
||||
tic->tic[2] |= address >> 32;
|
||||
}
|
||||
|
||||
static bool
|
||||
nvc0_validate_tic(struct nvc0_context *nvc0, int s)
|
||||
{
|
||||
@@ -247,6 +267,7 @@ nvc0_validate_tic(struct nvc0_context *nvc0, int s)
|
||||
continue;
|
||||
}
|
||||
res = nv04_resource(tic->pipe.texture);
|
||||
nvc0_update_tic(nvc0, tic, res);
|
||||
|
||||
if (tic->id < 0) {
|
||||
tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
|
||||
@@ -313,6 +334,7 @@ nve4_validate_tic(struct nvc0_context *nvc0, unsigned s)
|
||||
continue;
|
||||
}
|
||||
res = nv04_resource(tic->pipe.texture);
|
||||
nvc0_update_tic(nvc0, tic, res);
|
||||
|
||||
if (tic->id < 0) {
|
||||
tic->id = nvc0_screen_tic_alloc(nvc0->screen, tic);
|
||||
|
@@ -506,11 +506,48 @@ nvc0_miptree_transfer_unmap(struct pipe_context *pctx,
|
||||
}
|
||||
|
||||
/* This happens rather often with DTD9/st. */
|
||||
void
|
||||
static void
|
||||
nvc0_cb_push(struct nouveau_context *nv,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
struct nv04_resource *res,
|
||||
unsigned offset, unsigned words, const uint32_t *data)
|
||||
{
|
||||
struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
|
||||
struct nvc0_constbuf *cb = NULL;
|
||||
int s;
|
||||
|
||||
/* Go through all the constbuf binding points of this buffer and try to
|
||||
* find one which contains the region to be updated.
|
||||
*/
|
||||
for (s = 0; s < 6 && !cb; s++) {
|
||||
uint16_t bindings = res->cb_bindings[s];
|
||||
while (bindings) {
|
||||
int i = ffs(bindings) - 1;
|
||||
uint32_t cb_offset = nvc0->constbuf[s][i].offset;
|
||||
|
||||
bindings &= ~(1 << i);
|
||||
if (cb_offset <= offset &&
|
||||
cb_offset + nvc0->constbuf[s][i].size >= offset + words * 4) {
|
||||
cb = &nvc0->constbuf[s][i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
nvc0_cb_bo_push(nv, res->bo, res->domain,
|
||||
res->offset + cb->offset, cb->size,
|
||||
offset - cb->offset, words, data);
|
||||
} else {
|
||||
nv->push_data(nv, res->bo, res->offset + offset, res->domain,
|
||||
words * 4, data);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nvc0_cb_bo_push(struct nouveau_context *nv,
|
||||
struct nouveau_bo *bo, unsigned domain,
|
||||
unsigned base, unsigned size,
|
||||
unsigned offset, unsigned words, const uint32_t *data)
|
||||
{
|
||||
struct nouveau_pushbuf *push = nv->pushbuf;
|
||||
|
||||
@@ -520,6 +557,9 @@ nvc0_cb_push(struct nouveau_context *nv,
|
||||
assert(!(offset & 3));
|
||||
size = align(size, 0x100);
|
||||
|
||||
assert(offset < size);
|
||||
assert(offset + words * 4 <= size);
|
||||
|
||||
BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
|
||||
PUSH_DATA (push, size);
|
||||
PUSH_DATAh(push, bo->offset + base);
|
||||
|
@@ -899,6 +899,9 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
|
||||
push->kick_notify = nvc0_draw_vbo_kick_notify;
|
||||
|
||||
/* TODO: Instead of iterating over all the buffer resources looking for
|
||||
* coherent buffers, keep track of a context-wide count.
|
||||
*/
|
||||
for (s = 0; s < 5 && !nvc0->cb_dirty; ++s) {
|
||||
uint32_t valid = nvc0->constbuf_valid[s];
|
||||
|
||||
@@ -924,6 +927,23 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
|
||||
nvc0->cb_dirty = false;
|
||||
}
|
||||
|
||||
for (s = 0; s < 5; ++s) {
|
||||
for (int i = 0; i < nvc0->num_textures[s]; ++i) {
|
||||
struct nv50_tic_entry *tic = nv50_tic_entry(nvc0->textures[s][i]);
|
||||
struct pipe_resource *res;
|
||||
if (!tic)
|
||||
continue;
|
||||
res = nvc0->textures[s][i]->texture;
|
||||
if (res->target != PIPE_BUFFER ||
|
||||
!(res->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT))
|
||||
continue;
|
||||
|
||||
BEGIN_NVC0(push, NVC0_3D(TEX_CACHE_CTL), 1);
|
||||
PUSH_DATA (push, (tic->id << 4) | 1);
|
||||
NOUVEAU_DRV_STAT(&nvc0->screen->base, tex_cache_flush_count, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (nvc0->state.vbo_mode) {
|
||||
nvc0_push_vbo(nvc0, info);
|
||||
push->kick_notify = nvc0_default_kick_notify;
|
||||
|
@@ -363,7 +363,7 @@ static void r300_init_states(struct pipe_context *pipe)
|
||||
}
|
||||
|
||||
struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
||||
void *priv, unsigned flags)
|
||||
void *priv)
|
||||
{
|
||||
struct r300_context* r300 = CALLOC_STRUCT(r300_context);
|
||||
struct r300_screen* r300screen = r300_screen(screen);
|
||||
|
@@ -705,7 +705,7 @@ r300_get_nonnull_cb(struct pipe_framebuffer_state *fb, unsigned i)
|
||||
}
|
||||
|
||||
struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
||||
void *priv, unsigned flags);
|
||||
void *priv);
|
||||
|
||||
/* Context initialization. */
|
||||
struct draw_stage* r300_draw_stage(struct r300_context* r300);
|
||||
|
@@ -120,7 +120,7 @@ int64_t compute_memory_prealloc_chunk(
|
||||
|
||||
assert(size_in_dw <= pool->size_in_dw);
|
||||
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_prealloc_chunk() size_in_dw = %"PRIi64"\n",
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_prealloc_chunk() size_in_dw = %ld\n",
|
||||
size_in_dw);
|
||||
|
||||
LIST_FOR_EACH_ENTRY(item, pool->item_list, link) {
|
||||
@@ -151,7 +151,7 @@ struct list_head *compute_memory_postalloc_chunk(
|
||||
struct compute_memory_item *next;
|
||||
struct list_head *next_link;
|
||||
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_postalloc_chunck() start_in_dw = %"PRIi64"\n",
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_postalloc_chunck() start_in_dw = %ld\n",
|
||||
start_in_dw);
|
||||
|
||||
/* Check if we can insert it in the front of the list */
|
||||
@@ -568,7 +568,7 @@ void compute_memory_free(struct compute_memory_pool* pool, int64_t id)
|
||||
struct pipe_screen *screen = (struct pipe_screen *)pool->screen;
|
||||
struct pipe_resource *res;
|
||||
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_free() id + %"PRIi64" \n", id);
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_free() id + %ld \n", id);
|
||||
|
||||
LIST_FOR_EACH_ENTRY_SAFE(item, next, pool->item_list, link) {
|
||||
|
||||
@@ -628,7 +628,7 @@ struct compute_memory_item* compute_memory_alloc(
|
||||
{
|
||||
struct compute_memory_item *new_item = NULL;
|
||||
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_alloc() size_in_dw = %"PRIi64" (%"PRIi64" bytes)\n",
|
||||
COMPUTE_DBG(pool->screen, "* compute_memory_alloc() size_in_dw = %ld (%ld bytes)\n",
|
||||
size_in_dw, 4 * size_in_dw);
|
||||
|
||||
new_item = (struct compute_memory_item *)
|
||||
|
@@ -1853,7 +1853,7 @@ static void evergreen_emit_vertex_buffers(struct r600_context *rctx,
|
||||
radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 8, 0) | pkt_flags);
|
||||
radeon_emit(cs, (resource_offset + buffer_index) * 8);
|
||||
radeon_emit(cs, va); /* RESOURCEi_WORD0 */
|
||||
radeon_emit(cs, rbuffer->buf->size - vb->buffer_offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, rbuffer->b.b.width0 - vb->buffer_offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, /* RESOURCEi_WORD2 */
|
||||
S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
|
||||
S_030008_STRIDE(vb->stride) |
|
||||
@@ -1923,7 +1923,7 @@ static void evergreen_emit_constant_buffers(struct r600_context *rctx,
|
||||
radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 8, 0) | pkt_flags);
|
||||
radeon_emit(cs, (buffer_id_base + buffer_index) * 8);
|
||||
radeon_emit(cs, va); /* RESOURCEi_WORD0 */
|
||||
radeon_emit(cs, rbuffer->buf->size - cb->buffer_offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, rbuffer->b.b.width0 - cb->buffer_offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, /* RESOURCEi_WORD2 */
|
||||
S_030008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) |
|
||||
S_030008_STRIDE(gs_ring_buffer ? 4 : 16) |
|
||||
@@ -2143,11 +2143,11 @@ static void evergreen_emit_shader_stages(struct r600_context *rctx, struct r600_
|
||||
if (state->geom_enable) {
|
||||
uint32_t cut_val;
|
||||
|
||||
if (rctx->gs_shader->gs_max_out_vertices <= 128)
|
||||
if (rctx->gs_shader->current->shader.gs_max_out_vertices <= 128)
|
||||
cut_val = V_028A40_GS_CUT_128;
|
||||
else if (rctx->gs_shader->gs_max_out_vertices <= 256)
|
||||
else if (rctx->gs_shader->current->shader.gs_max_out_vertices <= 256)
|
||||
cut_val = V_028A40_GS_CUT_256;
|
||||
else if (rctx->gs_shader->gs_max_out_vertices <= 512)
|
||||
else if (rctx->gs_shader->current->shader.gs_max_out_vertices <= 512)
|
||||
cut_val = V_028A40_GS_CUT_512;
|
||||
else
|
||||
cut_val = V_028A40_GS_CUT_1024;
|
||||
@@ -3013,7 +3013,7 @@ void evergreen_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader
|
||||
struct r600_shader *rshader = &shader->shader;
|
||||
struct r600_shader *cp_shader = &shader->gs_copy_shader->shader;
|
||||
unsigned gsvs_itemsize =
|
||||
(cp_shader->ring_item_size * shader->selector->gs_max_out_vertices) >> 2;
|
||||
(cp_shader->ring_item_size * rshader->gs_max_out_vertices) >> 2;
|
||||
|
||||
r600_init_command_buffer(cb, 64);
|
||||
|
||||
@@ -3022,14 +3022,14 @@ void evergreen_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader
|
||||
r600_store_context_reg(cb, R_028AB8_VGT_VTX_CNT_EN, 1);
|
||||
|
||||
r600_store_context_reg(cb, R_028B38_VGT_GS_MAX_VERT_OUT,
|
||||
S_028B38_MAX_VERT_OUT(shader->selector->gs_max_out_vertices));
|
||||
S_028B38_MAX_VERT_OUT(rshader->gs_max_out_vertices));
|
||||
r600_store_context_reg(cb, R_028A6C_VGT_GS_OUT_PRIM_TYPE,
|
||||
r600_conv_prim_to_gs_out(shader->selector->gs_output_prim));
|
||||
r600_conv_prim_to_gs_out(rshader->gs_output_prim));
|
||||
|
||||
if (rctx->screen->b.info.drm_minor >= 35) {
|
||||
r600_store_context_reg(cb, R_028B90_VGT_GS_INSTANCE_CNT,
|
||||
S_028B90_CNT(MIN2(shader->selector->gs_num_invocations, 127)) |
|
||||
S_028B90_ENABLE(shader->selector->gs_num_invocations > 0));
|
||||
S_028B90_CNT(MIN2(rshader->gs_num_invocations, 127)) |
|
||||
S_028B90_ENABLE(rshader->gs_num_invocations > 0));
|
||||
}
|
||||
r600_store_context_reg_seq(cb, R_02891C_SQ_GS_VERT_ITEMSIZE, 4);
|
||||
r600_store_value(cb, cp_shader->ring_item_size >> 2);
|
||||
|
@@ -108,8 +108,7 @@ static void r600_destroy_context(struct pipe_context *context)
|
||||
FREE(rctx);
|
||||
}
|
||||
|
||||
static struct pipe_context *r600_create_context(struct pipe_screen *screen,
|
||||
void *priv, unsigned flags)
|
||||
static struct pipe_context *r600_create_context(struct pipe_screen *screen, void *priv)
|
||||
{
|
||||
struct r600_context *rctx = CALLOC_STRUCT(r600_context);
|
||||
struct r600_screen* rscreen = (struct r600_screen *)screen;
|
||||
@@ -625,7 +624,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
|
||||
rscreen->global_pool = compute_memory_pool_new(rscreen);
|
||||
|
||||
/* Create the auxiliary context. This must be done last. */
|
||||
rscreen->b.aux_context = rscreen->b.b.context_create(&rscreen->b.b, NULL, 0);
|
||||
rscreen->b.aux_context = rscreen->b.b.context_create(&rscreen->b.b, NULL);
|
||||
|
||||
#if 0 /* This is for testing whether aux_context and buffer clearing work correctly. */
|
||||
struct pipe_resource templ = {};
|
||||
|
@@ -36,8 +36,6 @@
|
||||
#include "util/list.h"
|
||||
#include "util/u_transfer.h"
|
||||
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
#define R600_NUM_ATOMS 75
|
||||
|
||||
#define R600_MAX_VIEWPORTS 16
|
||||
@@ -307,18 +305,12 @@ struct r600_pipe_shader_selector {
|
||||
|
||||
struct tgsi_token *tokens;
|
||||
struct pipe_stream_output_info so;
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
unsigned num_shaders;
|
||||
|
||||
/* PIPE_SHADER_[VERTEX|FRAGMENT|...] */
|
||||
unsigned type;
|
||||
|
||||
/* geometry shader properties */
|
||||
unsigned gs_output_prim;
|
||||
unsigned gs_max_out_vertices;
|
||||
unsigned gs_num_invocations;
|
||||
|
||||
unsigned nr_ps_max_color_exports;
|
||||
};
|
||||
|
||||
|
@@ -141,7 +141,7 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
|
||||
bool dump = r600_can_dump_shader(&rctx->screen->b, sel->tokens);
|
||||
unsigned use_sb = !(rctx->screen->b.debug_flags & DBG_NO_SB);
|
||||
unsigned sb_disasm = use_sb || (rctx->screen->b.debug_flags & DBG_SB_DISASM);
|
||||
unsigned export_shader = key.vs.as_es;
|
||||
unsigned export_shader;
|
||||
|
||||
shader->shader.bc.isa = rctx->isa;
|
||||
|
||||
@@ -220,6 +220,7 @@ int r600_pipe_shader_create(struct pipe_context *ctx,
|
||||
}
|
||||
break;
|
||||
case TGSI_PROCESSOR_VERTEX:
|
||||
export_shader = key.vs.as_es;
|
||||
if (rctx->b.chip_class >= EVERGREEN) {
|
||||
if (export_shader)
|
||||
evergreen_update_es_state(ctx, shader);
|
||||
@@ -1809,6 +1810,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
struct tgsi_token *tokens = pipeshader->selector->tokens;
|
||||
struct pipe_stream_output_info so = pipeshader->selector->so;
|
||||
struct tgsi_full_immediate *immediate;
|
||||
struct tgsi_full_property *property;
|
||||
struct r600_shader_ctx ctx;
|
||||
struct r600_bytecode_output output[32];
|
||||
unsigned output_done, noutput;
|
||||
@@ -1829,8 +1831,6 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
ctx.shader = shader;
|
||||
ctx.native_integers = true;
|
||||
|
||||
shader->vs_as_gs_a = key.vs.as_gs_a;
|
||||
shader->vs_as_es = key.vs.as_es;
|
||||
|
||||
r600_bytecode_init(ctx.bc, rscreen->b.chip_class, rscreen->b.family,
|
||||
rscreen->has_compressed_msaa_texturing);
|
||||
@@ -1839,13 +1839,18 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
shader->indirect_files = ctx.info.indirect_files;
|
||||
indirect_gprs = ctx.info.indirect_files & ~(1 << TGSI_FILE_CONSTANT);
|
||||
tgsi_parse_init(&ctx.parse, tokens);
|
||||
ctx.type = ctx.info.processor;
|
||||
ctx.type = ctx.parse.FullHeader.Processor.Processor;
|
||||
shader->processor_type = ctx.type;
|
||||
ctx.bc->type = shader->processor_type;
|
||||
|
||||
ring_outputs = key.vs.as_es || (ctx.type == TGSI_PROCESSOR_GEOMETRY);
|
||||
if (ctx.type == TGSI_PROCESSOR_VERTEX) {
|
||||
shader->vs_as_gs_a = key.vs.as_gs_a;
|
||||
shader->vs_as_es = key.vs.as_es;
|
||||
}
|
||||
|
||||
if (key.vs.as_es) {
|
||||
ring_outputs = shader->vs_as_es || ctx.type == TGSI_PROCESSOR_GEOMETRY;
|
||||
|
||||
if (shader->vs_as_es) {
|
||||
ctx.gs_for_vs = &rctx->gs_shader->current->shader;
|
||||
} else {
|
||||
ctx.gs_for_vs = NULL;
|
||||
@@ -1865,7 +1870,8 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
shader->nr_ps_color_exports = 0;
|
||||
shader->nr_ps_max_color_exports = 0;
|
||||
|
||||
shader->two_side = key.ps.color_two_side;
|
||||
if (ctx.type == TGSI_PROCESSOR_FRAGMENT)
|
||||
shader->two_side = key.ps.color_two_side;
|
||||
|
||||
/* register allocations */
|
||||
/* Values [0,127] correspond to GPR[0..127].
|
||||
@@ -1967,12 +1973,6 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
ctx.nliterals = 0;
|
||||
ctx.literals = NULL;
|
||||
shader->fs_write_all = FALSE;
|
||||
if (ctx.info.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS])
|
||||
shader->fs_write_all = TRUE;
|
||||
|
||||
shader->vs_position_window_space = FALSE;
|
||||
if (ctx.info.properties[TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION])
|
||||
shader->vs_position_window_space = TRUE;
|
||||
|
||||
if (shader->vs_as_gs_a)
|
||||
vs_add_primid_output(&ctx, key.vs.prim_id_out);
|
||||
@@ -1999,7 +1999,34 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
goto out_err;
|
||||
break;
|
||||
case TGSI_TOKEN_TYPE_INSTRUCTION:
|
||||
break;
|
||||
case TGSI_TOKEN_TYPE_PROPERTY:
|
||||
property = &ctx.parse.FullToken.FullProperty;
|
||||
switch (property->Property.PropertyName) {
|
||||
case TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS:
|
||||
if (property->u[0].Data == 1)
|
||||
shader->fs_write_all = TRUE;
|
||||
break;
|
||||
case TGSI_PROPERTY_VS_WINDOW_SPACE_POSITION:
|
||||
if (property->u[0].Data == 1)
|
||||
shader->vs_position_window_space = TRUE;
|
||||
break;
|
||||
case TGSI_PROPERTY_VS_PROHIBIT_UCPS:
|
||||
/* we don't need this one */
|
||||
break;
|
||||
case TGSI_PROPERTY_GS_INPUT_PRIM:
|
||||
shader->gs_input_prim = property->u[0].Data;
|
||||
break;
|
||||
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
|
||||
shader->gs_output_prim = property->u[0].Data;
|
||||
break;
|
||||
case TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES:
|
||||
shader->gs_max_out_vertices = property->u[0].Data;
|
||||
break;
|
||||
case TGSI_PROPERTY_GS_INVOCATIONS:
|
||||
shader->gs_num_invocations = property->u[0].Data;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
R600_ERR("unsupported token type %d\n", ctx.parse.FullToken.Token.Type);
|
||||
@@ -2248,7 +2275,7 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
|
||||
convert_edgeflag_to_int(&ctx);
|
||||
|
||||
if (ring_outputs) {
|
||||
if (key.vs.as_es)
|
||||
if (shader->vs_as_es)
|
||||
emit_gs_ring_writes(&ctx, FALSE);
|
||||
} else {
|
||||
/* Export output */
|
||||
|
@@ -78,6 +78,11 @@ struct r600_shader {
|
||||
/* Temporarily workaround SB not handling CF_INDEX_[01] index registers */
|
||||
boolean uses_index_registers;
|
||||
|
||||
/* geometry shader properties */
|
||||
unsigned gs_input_prim;
|
||||
unsigned gs_output_prim;
|
||||
unsigned gs_max_out_vertices;
|
||||
unsigned gs_num_invocations;
|
||||
/* size in bytes of a data item in the ring (single vertex data) */
|
||||
unsigned ring_item_size;
|
||||
|
||||
|
@@ -1007,7 +1007,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
|
||||
|
||||
/* CMASK. */
|
||||
if (!rctx->dummy_cmask ||
|
||||
rctx->dummy_cmask->buf->size < cmask.size ||
|
||||
rctx->dummy_cmask->b.b.width0 < cmask.size ||
|
||||
rctx->dummy_cmask->buf->alignment % cmask.alignment != 0) {
|
||||
struct pipe_transfer *transfer;
|
||||
void *ptr;
|
||||
@@ -1025,7 +1025,7 @@ static void r600_init_color_surface(struct r600_context *rctx,
|
||||
|
||||
/* FMASK. */
|
||||
if (!rctx->dummy_fmask ||
|
||||
rctx->dummy_fmask->buf->size < fmask.size ||
|
||||
rctx->dummy_fmask->b.b.width0 < fmask.size ||
|
||||
rctx->dummy_fmask->buf->alignment % fmask.alignment != 0) {
|
||||
pipe_resource_reference((struct pipe_resource**)&rctx->dummy_fmask, NULL);
|
||||
rctx->dummy_fmask = r600_buffer_create_helper(rscreen, fmask.size, fmask.alignment);
|
||||
@@ -1694,7 +1694,7 @@ static void r600_emit_vertex_buffers(struct r600_context *rctx, struct r600_atom
|
||||
radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
|
||||
radeon_emit(cs, (320 + buffer_index) * 7);
|
||||
radeon_emit(cs, offset); /* RESOURCEi_WORD0 */
|
||||
radeon_emit(cs, rbuffer->buf->size - offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, rbuffer->b.b.width0 - offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, /* RESOURCEi_WORD2 */
|
||||
S_038008_ENDIAN_SWAP(r600_endian_swap(32)) |
|
||||
S_038008_STRIDE(vb->stride));
|
||||
@@ -1743,7 +1743,7 @@ static void r600_emit_constant_buffers(struct r600_context *rctx,
|
||||
radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
|
||||
radeon_emit(cs, (buffer_id_base + buffer_index) * 7);
|
||||
radeon_emit(cs, offset); /* RESOURCEi_WORD0 */
|
||||
radeon_emit(cs, rbuffer->buf->size - offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, rbuffer->b.b.width0 - offset - 1); /* RESOURCEi_WORD1 */
|
||||
radeon_emit(cs, /* RESOURCEi_WORD2 */
|
||||
S_038008_ENDIAN_SWAP(gs_ring_buffer ? ENDIAN_NONE : r600_endian_swap(32)) |
|
||||
S_038008_STRIDE(gs_ring_buffer ? 4 : 16));
|
||||
@@ -1951,11 +1951,11 @@ static void r600_emit_shader_stages(struct r600_context *rctx, struct r600_atom
|
||||
if (state->geom_enable) {
|
||||
uint32_t cut_val;
|
||||
|
||||
if (rctx->gs_shader->gs_max_out_vertices <= 128)
|
||||
if (rctx->gs_shader->current->shader.gs_max_out_vertices <= 128)
|
||||
cut_val = V_028A40_GS_CUT_128;
|
||||
else if (rctx->gs_shader->gs_max_out_vertices <= 256)
|
||||
else if (rctx->gs_shader->current->shader.gs_max_out_vertices <= 256)
|
||||
cut_val = V_028A40_GS_CUT_256;
|
||||
else if (rctx->gs_shader->gs_max_out_vertices <= 512)
|
||||
else if (rctx->gs_shader->current->shader.gs_max_out_vertices <= 512)
|
||||
cut_val = V_028A40_GS_CUT_512;
|
||||
else
|
||||
cut_val = V_028A40_GS_CUT_1024;
|
||||
@@ -2051,7 +2051,7 @@ bool r600_adjust_gprs(struct r600_context *rctx)
|
||||
/* always privilege vs stage so that at worst we have the
|
||||
* pixel stage producing wrong output (not the vertex
|
||||
* stage) */
|
||||
new_num_ps_gprs = max_gprs - ((new_num_vs_gprs - new_num_es_gprs - new_num_gs_gprs) + def_num_clause_temp_gprs * 2);
|
||||
new_num_ps_gprs = max_gprs - ((new_num_vs_gprs + new_num_es_gprs + new_num_gs_gprs) + def_num_clause_temp_gprs * 2);
|
||||
new_num_vs_gprs = num_vs_gprs;
|
||||
new_num_gs_gprs = num_gs_gprs;
|
||||
new_num_es_gprs = num_es_gprs;
|
||||
@@ -2650,7 +2650,7 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
|
||||
struct r600_shader *rshader = &shader->shader;
|
||||
struct r600_shader *cp_shader = &shader->gs_copy_shader->shader;
|
||||
unsigned gsvs_itemsize =
|
||||
(cp_shader->ring_item_size * shader->selector->gs_max_out_vertices) >> 2;
|
||||
(cp_shader->ring_item_size * rshader->gs_max_out_vertices) >> 2;
|
||||
|
||||
r600_init_command_buffer(cb, 64);
|
||||
|
||||
@@ -2659,10 +2659,10 @@ void r600_update_gs_state(struct pipe_context *ctx, struct r600_pipe_shader *sha
|
||||
|
||||
if (rctx->b.chip_class >= R700) {
|
||||
r600_store_context_reg(cb, R_028B38_VGT_GS_MAX_VERT_OUT,
|
||||
S_028B38_MAX_VERT_OUT(shader->selector->gs_max_out_vertices));
|
||||
S_028B38_MAX_VERT_OUT(rshader->gs_max_out_vertices));
|
||||
}
|
||||
r600_store_context_reg(cb, R_028A6C_VGT_GS_OUT_PRIM_TYPE,
|
||||
r600_conv_prim_to_gs_out(shader->selector->gs_output_prim));
|
||||
r600_conv_prim_to_gs_out(rshader->gs_output_prim));
|
||||
|
||||
r600_store_context_reg(cb, R_0288C8_SQ_GS_VERT_ITEMSIZE,
|
||||
cp_shader->ring_item_size >> 2);
|
||||
|
@@ -34,7 +34,6 @@
|
||||
#include "util/u_upload_mgr.h"
|
||||
#include "util/u_math.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
#include "tgsi/tgsi_scan.h"
|
||||
|
||||
void r600_init_command_buffer(struct r600_command_buffer *cb, unsigned num_dw)
|
||||
{
|
||||
@@ -844,19 +843,6 @@ static void *r600_create_shader_state(struct pipe_context *ctx,
|
||||
sel->type = pipe_shader_type;
|
||||
sel->tokens = tgsi_dup_tokens(state->tokens);
|
||||
sel->so = state->stream_output;
|
||||
tgsi_scan_shader(state->tokens, &sel->info);
|
||||
|
||||
switch (pipe_shader_type) {
|
||||
case PIPE_SHADER_GEOMETRY:
|
||||
sel->gs_output_prim =
|
||||
sel->info.properties[TGSI_PROPERTY_GS_OUTPUT_PRIM];
|
||||
sel->gs_max_out_vertices =
|
||||
sel->info.properties[TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES];
|
||||
sel->gs_num_invocations =
|
||||
sel->info.properties[TGSI_PROPERTY_GS_INVOCATIONS];
|
||||
break;
|
||||
}
|
||||
|
||||
return sel;
|
||||
}
|
||||
|
||||
@@ -1563,7 +1549,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
|
||||
unsigned prim = info.mode;
|
||||
|
||||
if (rctx->gs_shader) {
|
||||
prim = rctx->gs_shader->gs_output_prim;
|
||||
prim = rctx->gs_shader->current->shader.gs_output_prim;
|
||||
}
|
||||
prim = r600_conv_prim_to_gs_out(prim); /* decrease the number of types to 3 */
|
||||
|
||||
|
@@ -3428,6 +3428,7 @@
|
||||
#define S_0085F0_SO3_DEST_BASE_ENA(x) (((x) & 0x1) << 5)
|
||||
#define G_0085F0_SO3_DEST_BASE_ENA(x) (((x) >> 5) & 0x1)
|
||||
#define C_0085F0_SO3_DEST_BASE_ENA 0xFFFFFFDF
|
||||
#define S_0085F0_CB0_DEST_BASE_ENA_SHIFT 6
|
||||
#define S_0085F0_CB0_DEST_BASE_ENA(x) (((x) & 0x1) << 6)
|
||||
#define G_0085F0_CB0_DEST_BASE_ENA(x) (((x) >> 6) & 0x1)
|
||||
#define C_0085F0_CB0_DEST_BASE_ENA 0xFFFFFFBF
|
||||
|
@@ -341,8 +341,8 @@ static void r600_emit_query_predication(struct r600_common_context *ctx, struct
|
||||
|
||||
while (results_base < qbuf->results_end) {
|
||||
radeon_emit(cs, PKT3(PKT3_SET_PREDICATION, 1, 0));
|
||||
radeon_emit(cs, va + results_base);
|
||||
radeon_emit(cs, op | (((va + results_base) >> 32) & 0xFF));
|
||||
radeon_emit(cs, (va + results_base) & 0xFFFFFFFFUL);
|
||||
radeon_emit(cs, op | (((va + results_base) >> 32UL) & 0xFF));
|
||||
r600_emit_reloc(ctx, &ctx->rings.gfx, qbuf->buf, RADEON_USAGE_READ,
|
||||
RADEON_PRIO_MIN);
|
||||
results_base += query->result_size;
|
||||
|
@@ -680,7 +680,7 @@ struct radeon_winsys {
|
||||
uint64_t (*query_value)(struct radeon_winsys *ws,
|
||||
enum radeon_value_id value);
|
||||
|
||||
bool (*read_registers)(struct radeon_winsys *ws, unsigned reg_offset,
|
||||
void (*read_registers)(struct radeon_winsys *ws, unsigned reg_offset,
|
||||
unsigned num_registers, uint32_t *out);
|
||||
};
|
||||
|
||||
|
1
src/gallium/drivers/radeonsi/.gitignore
vendored
1
src/gallium/drivers/radeonsi/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
sid_tables.h
|
@@ -31,12 +31,3 @@ AM_CFLAGS = \
|
||||
noinst_LTLIBRARIES = libradeonsi.la
|
||||
|
||||
libradeonsi_la_SOURCES = $(C_SOURCES)
|
||||
|
||||
sid_tables.h: $(srcdir)/sid_tables.py $(srcdir)/sid.h
|
||||
$(AM_V_GEN) $(PYTHON2) $(srcdir)/sid_tables.py $(srcdir)/sid.h > $@
|
||||
|
||||
EXTRA_DIST = \
|
||||
sid_tables.py
|
||||
|
||||
BUILT_SOURCES =\
|
||||
sid_tables.h
|
||||
|
@@ -4,10 +4,8 @@ C_SOURCES := \
|
||||
si_commands.c \
|
||||
si_compute.c \
|
||||
si_cp_dma.c \
|
||||
si_debug.c \
|
||||
si_descriptors.c \
|
||||
sid.h \
|
||||
sid_tables.h \
|
||||
si_dma.c \
|
||||
si_hw_context.c \
|
||||
si_pipe.c \
|
||||
|
@@ -362,7 +362,7 @@ static void si_launch_grid(
|
||||
shader_va += pc;
|
||||
#endif
|
||||
si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ, RADEON_PRIO_SHADER_DATA);
|
||||
si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, shader_va >> 8);
|
||||
si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, (shader_va >> 8) & 0xffffffff);
|
||||
si_pm4_set_reg(pm4, R_00B834_COMPUTE_PGM_HI, shader_va >> 40);
|
||||
|
||||
si_pm4_set_reg(pm4, R_00B848_COMPUTE_PGM_RSRC1,
|
||||
|
@@ -47,11 +47,10 @@ static void si_emit_cp_dma_copy_buffer(struct si_context *sctx,
|
||||
unsigned size, unsigned flags)
|
||||
{
|
||||
struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs;
|
||||
uint32_t sync_flag = flags & R600_CP_DMA_SYNC ? S_411_CP_SYNC(1) : 0;
|
||||
uint32_t raw_wait = flags & SI_CP_DMA_RAW_WAIT ? S_414_RAW_WAIT(1) : 0;
|
||||
uint32_t sync_flag = flags & R600_CP_DMA_SYNC ? PKT3_CP_DMA_CP_SYNC : 0;
|
||||
uint32_t raw_wait = flags & SI_CP_DMA_RAW_WAIT ? PKT3_CP_DMA_CMD_RAW_WAIT : 0;
|
||||
uint32_t sel = flags & CIK_CP_DMA_USE_L2 ?
|
||||
S_411_SRC_SEL(V_411_SRC_ADDR_TC_L2) |
|
||||
S_411_DSL_SEL(V_411_DST_ADDR_TC_L2) : 0;
|
||||
PKT3_CP_DMA_SRC_SEL(3) | PKT3_CP_DMA_DST_SEL(3) : 0;
|
||||
|
||||
assert(size);
|
||||
assert((size & ((1<<21)-1)) == size);
|
||||
@@ -80,16 +79,16 @@ static void si_emit_cp_dma_clear_buffer(struct si_context *sctx,
|
||||
uint32_t clear_value, unsigned flags)
|
||||
{
|
||||
struct radeon_winsys_cs *cs = sctx->b.rings.gfx.cs;
|
||||
uint32_t sync_flag = flags & R600_CP_DMA_SYNC ? S_411_CP_SYNC(1) : 0;
|
||||
uint32_t raw_wait = flags & SI_CP_DMA_RAW_WAIT ? S_414_RAW_WAIT(1) : 0;
|
||||
uint32_t dst_sel = flags & CIK_CP_DMA_USE_L2 ? S_411_DSL_SEL(V_411_DST_ADDR_TC_L2) : 0;
|
||||
uint32_t sync_flag = flags & R600_CP_DMA_SYNC ? PKT3_CP_DMA_CP_SYNC : 0;
|
||||
uint32_t raw_wait = flags & SI_CP_DMA_RAW_WAIT ? PKT3_CP_DMA_CMD_RAW_WAIT : 0;
|
||||
uint32_t dst_sel = flags & CIK_CP_DMA_USE_L2 ? PKT3_CP_DMA_DST_SEL(3) : 0;
|
||||
|
||||
assert(size);
|
||||
assert((size & ((1<<21)-1)) == size);
|
||||
|
||||
if (sctx->b.chip_class >= CIK) {
|
||||
radeon_emit(cs, PKT3(PKT3_DMA_DATA, 5, 0));
|
||||
radeon_emit(cs, sync_flag | dst_sel | S_411_SRC_SEL(V_411_DATA)); /* CP_SYNC [31] | SRC_SEL[30:29] */
|
||||
radeon_emit(cs, sync_flag | dst_sel | PKT3_CP_DMA_SRC_SEL(2)); /* CP_SYNC [31] | SRC_SEL[30:29] */
|
||||
radeon_emit(cs, clear_value); /* DATA [31:0] */
|
||||
radeon_emit(cs, 0);
|
||||
radeon_emit(cs, dst_va); /* DST_ADDR_LO [31:0] */
|
||||
@@ -98,7 +97,7 @@ static void si_emit_cp_dma_clear_buffer(struct si_context *sctx,
|
||||
} else {
|
||||
radeon_emit(cs, PKT3(PKT3_CP_DMA, 4, 0));
|
||||
radeon_emit(cs, clear_value); /* DATA [31:0] */
|
||||
radeon_emit(cs, sync_flag | S_411_SRC_SEL(V_411_DATA)); /* CP_SYNC [31] | SRC_SEL[30:29] */
|
||||
radeon_emit(cs, sync_flag | PKT3_CP_DMA_SRC_SEL(2)); /* CP_SYNC [31] | SRC_SEL[30:29] */
|
||||
radeon_emit(cs, dst_va); /* DST_ADDR_LO [31:0] */
|
||||
radeon_emit(cs, (dst_va >> 32) & 0xffff); /* DST_ADDR_HI [15:0] */
|
||||
radeon_emit(cs, size | raw_wait); /* COMMAND [29:22] | BYTE_COUNT [20:0] */
|
||||
|
@@ -1,439 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Advanced Micro Devices, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors:
|
||||
* Marek Olšák <maraeo@gmail.com>
|
||||
*/
|
||||
|
||||
#include "si_pipe.h"
|
||||
#include "si_shader.h"
|
||||
#include "sid.h"
|
||||
#include "sid_tables.h"
|
||||
|
||||
|
||||
static void si_dump_shader(struct si_shader_selector *sel, const char *name,
|
||||
FILE *f)
|
||||
{
|
||||
if (!sel || !sel->current)
|
||||
return;
|
||||
|
||||
fprintf(f, "%s shader disassembly:\n", name);
|
||||
si_dump_shader_key(sel->type, &sel->current->key, f);
|
||||
fprintf(f, "%s\n\n", sel->current->binary.disasm_string);
|
||||
}
|
||||
|
||||
/* Parsed IBs are difficult to read without colors. Use "less -R file" to
|
||||
* read them, or use "aha -b -f file" to convert them to html.
|
||||
*/
|
||||
#define COLOR_RESET "\033[0m"
|
||||
#define COLOR_RED "\033[31m"
|
||||
#define COLOR_GREEN "\033[1;32m"
|
||||
#define COLOR_YELLOW "\033[1;33m"
|
||||
#define COLOR_CYAN "\033[1;36m"
|
||||
|
||||
#define INDENT_PKT 8
|
||||
|
||||
static void print_spaces(FILE *f, unsigned num)
|
||||
{
|
||||
fprintf(f, "%*s", num, "");
|
||||
}
|
||||
|
||||
static void print_value(FILE *file, uint32_t value, int bits)
|
||||
{
|
||||
/* Guess if it's int or float */
|
||||
if (value <= (1 << 15))
|
||||
fprintf(file, "%u\n", value);
|
||||
else {
|
||||
float f = uif(value);
|
||||
|
||||
if (fabs(f) < 100000 && f*10 == floor(f*10))
|
||||
fprintf(file, "%.1ff\n", f);
|
||||
else
|
||||
/* Don't print more leading zeros than there are bits. */
|
||||
fprintf(file, "0x%0*x\n", bits / 4, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_named_value(FILE *file, const char *name, uint32_t value,
|
||||
int bits)
|
||||
{
|
||||
print_spaces(file, INDENT_PKT);
|
||||
fprintf(file, COLOR_YELLOW "%s" COLOR_RESET " <- ", name);
|
||||
print_value(file, value, bits);
|
||||
}
|
||||
|
||||
static void si_dump_reg(FILE *file, unsigned offset, uint32_t value,
|
||||
uint32_t field_mask)
|
||||
{
|
||||
int r, f;
|
||||
|
||||
for (r = 0; r < ARRAY_SIZE(reg_table); r++) {
|
||||
const struct si_reg *reg = ®_table[r];
|
||||
|
||||
if (reg->offset == offset) {
|
||||
bool first_field = true;
|
||||
|
||||
print_spaces(file, INDENT_PKT);
|
||||
fprintf(file, COLOR_YELLOW "%s" COLOR_RESET " <- ",
|
||||
reg->name);
|
||||
|
||||
if (!reg->num_fields) {
|
||||
print_value(file, value, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
for (f = 0; f < reg->num_fields; f++) {
|
||||
const struct si_field *field = ®->fields[f];
|
||||
uint32_t val = (value & field->mask) >>
|
||||
(ffs(field->mask) - 1);
|
||||
|
||||
if (!(field->mask & field_mask))
|
||||
continue;
|
||||
|
||||
/* Indent the field. */
|
||||
if (!first_field)
|
||||
print_spaces(file,
|
||||
INDENT_PKT + strlen(reg->name) + 4);
|
||||
|
||||
/* Print the field. */
|
||||
fprintf(file, "%s = ", field->name);
|
||||
|
||||
if (val < field->num_values && field->values[val])
|
||||
fprintf(file, "%s\n", field->values[val]);
|
||||
else
|
||||
print_value(file, val,
|
||||
util_bitcount(field->mask));
|
||||
|
||||
first_field = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(file, COLOR_YELLOW "0x%05x" COLOR_RESET " = 0x%08x", offset, value);
|
||||
}
|
||||
|
||||
static void si_parse_set_reg_packet(FILE *f, uint32_t *ib, unsigned count,
|
||||
unsigned reg_offset)
|
||||
{
|
||||
unsigned reg = (ib[1] << 2) + reg_offset;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
si_dump_reg(f, reg + i*4, ib[2+i], ~0);
|
||||
}
|
||||
|
||||
static uint32_t *si_parse_packet3(FILE *f, uint32_t *ib, int *num_dw,
|
||||
int trace_id)
|
||||
{
|
||||
unsigned count = PKT_COUNT_G(ib[0]);
|
||||
unsigned op = PKT3_IT_OPCODE_G(ib[0]);
|
||||
const char *predicate = PKT3_PREDICATE(ib[0]) ? "(predicate)" : "";
|
||||
int i;
|
||||
|
||||
/* Print the name first. */
|
||||
for (i = 0; i < ARRAY_SIZE(packet3_table); i++)
|
||||
if (packet3_table[i].op == op)
|
||||
break;
|
||||
|
||||
if (i < ARRAY_SIZE(packet3_table))
|
||||
if (op == PKT3_SET_CONTEXT_REG ||
|
||||
op == PKT3_SET_CONFIG_REG ||
|
||||
op == PKT3_SET_UCONFIG_REG ||
|
||||
op == PKT3_SET_SH_REG)
|
||||
fprintf(f, COLOR_CYAN "%s%s" COLOR_CYAN ":\n",
|
||||
packet3_table[i].name, predicate);
|
||||
else
|
||||
fprintf(f, COLOR_GREEN "%s%s" COLOR_RESET ":\n",
|
||||
packet3_table[i].name, predicate);
|
||||
else
|
||||
fprintf(f, COLOR_RED "PKT3_UNKNOWN 0x%x%s" COLOR_RESET ":\n",
|
||||
op, predicate);
|
||||
|
||||
/* Print the contents. */
|
||||
switch (op) {
|
||||
case PKT3_SET_CONTEXT_REG:
|
||||
si_parse_set_reg_packet(f, ib, count, SI_CONTEXT_REG_OFFSET);
|
||||
break;
|
||||
case PKT3_SET_CONFIG_REG:
|
||||
si_parse_set_reg_packet(f, ib, count, SI_CONFIG_REG_OFFSET);
|
||||
break;
|
||||
case PKT3_SET_UCONFIG_REG:
|
||||
si_parse_set_reg_packet(f, ib, count, CIK_UCONFIG_REG_OFFSET);
|
||||
break;
|
||||
case PKT3_SET_SH_REG:
|
||||
si_parse_set_reg_packet(f, ib, count, SI_SH_REG_OFFSET);
|
||||
break;
|
||||
case PKT3_DRAW_PREAMBLE:
|
||||
si_dump_reg(f, R_030908_VGT_PRIMITIVE_TYPE, ib[1], ~0);
|
||||
si_dump_reg(f, R_028AA8_IA_MULTI_VGT_PARAM, ib[2], ~0);
|
||||
si_dump_reg(f, R_028B58_VGT_LS_HS_CONFIG, ib[3], ~0);
|
||||
break;
|
||||
case PKT3_ACQUIRE_MEM:
|
||||
si_dump_reg(f, R_0301F0_CP_COHER_CNTL, ib[1], ~0);
|
||||
si_dump_reg(f, R_0301F4_CP_COHER_SIZE, ib[2], ~0);
|
||||
si_dump_reg(f, R_030230_CP_COHER_SIZE_HI, ib[3], ~0);
|
||||
si_dump_reg(f, R_0301F8_CP_COHER_BASE, ib[4], ~0);
|
||||
si_dump_reg(f, R_0301E4_CP_COHER_BASE_HI, ib[5], ~0);
|
||||
print_named_value(f, "POLL_INTERVAL", ib[6], 16);
|
||||
break;
|
||||
case PKT3_SURFACE_SYNC:
|
||||
si_dump_reg(f, R_0085F0_CP_COHER_CNTL, ib[1], ~0);
|
||||
si_dump_reg(f, R_0085F4_CP_COHER_SIZE, ib[2], ~0);
|
||||
si_dump_reg(f, R_0085F8_CP_COHER_BASE, ib[3], ~0);
|
||||
print_named_value(f, "POLL_INTERVAL", ib[4], 16);
|
||||
break;
|
||||
case PKT3_EVENT_WRITE:
|
||||
si_dump_reg(f, R_028A90_VGT_EVENT_INITIATOR, ib[1],
|
||||
S_028A90_EVENT_TYPE(~0));
|
||||
print_named_value(f, "EVENT_INDEX", (ib[1] >> 8) & 0xf, 4);
|
||||
print_named_value(f, "INV_L2", (ib[1] >> 20) & 0x1, 1);
|
||||
if (count > 0) {
|
||||
print_named_value(f, "ADDRESS_LO", ib[2], 32);
|
||||
print_named_value(f, "ADDRESS_HI", ib[3], 16);
|
||||
}
|
||||
break;
|
||||
case PKT3_DRAW_INDEX_AUTO:
|
||||
si_dump_reg(f, R_030930_VGT_NUM_INDICES, ib[1], ~0);
|
||||
si_dump_reg(f, R_0287F0_VGT_DRAW_INITIATOR, ib[2], ~0);
|
||||
break;
|
||||
case PKT3_DRAW_INDEX_2:
|
||||
si_dump_reg(f, R_028A78_VGT_DMA_MAX_SIZE, ib[1], ~0);
|
||||
si_dump_reg(f, R_0287E8_VGT_DMA_BASE, ib[2], ~0);
|
||||
si_dump_reg(f, R_0287E4_VGT_DMA_BASE_HI, ib[3], ~0);
|
||||
si_dump_reg(f, R_030930_VGT_NUM_INDICES, ib[4], ~0);
|
||||
si_dump_reg(f, R_0287F0_VGT_DRAW_INITIATOR, ib[5], ~0);
|
||||
break;
|
||||
case PKT3_INDEX_TYPE:
|
||||
si_dump_reg(f, R_028A7C_VGT_DMA_INDEX_TYPE, ib[1], ~0);
|
||||
break;
|
||||
case PKT3_NUM_INSTANCES:
|
||||
si_dump_reg(f, R_030934_VGT_NUM_INSTANCES, ib[1], ~0);
|
||||
break;
|
||||
case PKT3_WRITE_DATA:
|
||||
si_dump_reg(f, R_370_CONTROL, ib[1], ~0);
|
||||
si_dump_reg(f, R_371_DST_ADDR_LO, ib[2], ~0);
|
||||
si_dump_reg(f, R_372_DST_ADDR_HI, ib[3], ~0);
|
||||
for (i = 2; i < count; i++) {
|
||||
print_spaces(f, INDENT_PKT);
|
||||
fprintf(f, "0x%08x\n", ib[2+i]);
|
||||
}
|
||||
break;
|
||||
case PKT3_CP_DMA:
|
||||
si_dump_reg(f, R_410_CP_DMA_WORD0, ib[1], ~0);
|
||||
si_dump_reg(f, R_411_CP_DMA_WORD1, ib[2], ~0);
|
||||
si_dump_reg(f, R_412_CP_DMA_WORD2, ib[3], ~0);
|
||||
si_dump_reg(f, R_413_CP_DMA_WORD3, ib[4], ~0);
|
||||
si_dump_reg(f, R_414_COMMAND, ib[5], ~0);
|
||||
break;
|
||||
case PKT3_DMA_DATA:
|
||||
si_dump_reg(f, R_500_DMA_DATA_WORD0, ib[1], ~0);
|
||||
si_dump_reg(f, R_501_SRC_ADDR_LO, ib[2], ~0);
|
||||
si_dump_reg(f, R_502_SRC_ADDR_HI, ib[3], ~0);
|
||||
si_dump_reg(f, R_503_DST_ADDR_LO, ib[4], ~0);
|
||||
si_dump_reg(f, R_504_DST_ADDR_HI, ib[5], ~0);
|
||||
si_dump_reg(f, R_414_COMMAND, ib[6], ~0);
|
||||
break;
|
||||
case PKT3_NOP:
|
||||
if (ib[0] == 0xffff1000) {
|
||||
count = -1; /* One dword NOP. */
|
||||
break;
|
||||
} else if (count == 0 && SI_IS_TRACE_POINT(ib[1])) {
|
||||
unsigned packet_id = SI_GET_TRACE_POINT_ID(ib[1]);
|
||||
|
||||
print_spaces(f, INDENT_PKT);
|
||||
fprintf(f, COLOR_RED "Trace point ID: %u\n", packet_id);
|
||||
|
||||
if (trace_id == -1)
|
||||
break; /* tracing was disabled */
|
||||
|
||||
print_spaces(f, INDENT_PKT);
|
||||
if (packet_id < trace_id)
|
||||
fprintf(f, COLOR_RED
|
||||
"This trace point was reached by the CP."
|
||||
COLOR_RESET "\n");
|
||||
else if (packet_id == trace_id)
|
||||
fprintf(f, COLOR_RED
|
||||
"!!!!! This is the last trace point that "
|
||||
"was reached by the CP !!!!!"
|
||||
COLOR_RESET "\n");
|
||||
else if (packet_id+1 == trace_id)
|
||||
fprintf(f, COLOR_RED
|
||||
"!!!!! This is the first trace point that "
|
||||
"was NOT been reached by the CP !!!!!"
|
||||
COLOR_RESET "\n");
|
||||
else
|
||||
fprintf(f, COLOR_RED
|
||||
"!!!!! This trace point was NOT reached "
|
||||
"by the CP !!!!!"
|
||||
COLOR_RESET "\n");
|
||||
break;
|
||||
}
|
||||
/* fall through, print all dwords */
|
||||
default:
|
||||
for (i = 0; i < count+1; i++) {
|
||||
print_spaces(f, INDENT_PKT);
|
||||
fprintf(f, "0x%08x\n", ib[1+i]);
|
||||
}
|
||||
}
|
||||
|
||||
ib += count + 2;
|
||||
*num_dw -= count + 2;
|
||||
return ib;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse and print an IB into a file.
|
||||
*
|
||||
* \param f file
|
||||
* \param ib IB
|
||||
* \param num_dw size of the IB
|
||||
* \param chip_class chip class
|
||||
* \param trace_id the last trace ID that is known to have been reached
|
||||
* and executed by the CP, typically read from a buffer
|
||||
*/
|
||||
static void si_parse_ib(FILE *f, uint32_t *ib, int num_dw, int trace_id)
|
||||
{
|
||||
fprintf(f, "------------------ IB begin ------------------\n");
|
||||
|
||||
while (num_dw > 0) {
|
||||
unsigned type = PKT_TYPE_G(ib[0]);
|
||||
|
||||
switch (type) {
|
||||
case 3:
|
||||
ib = si_parse_packet3(f, ib, &num_dw, trace_id);
|
||||
break;
|
||||
case 2:
|
||||
/* type-2 nop */
|
||||
if (ib[0] == 0x80000000) {
|
||||
fprintf(f, COLOR_GREEN "NOP (type 2)" COLOR_RESET "\n");
|
||||
ib++;
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
fprintf(f, "Unknown packet type %i\n", type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(f, "------------------- IB end -------------------\n");
|
||||
if (num_dw < 0) {
|
||||
printf("Packet ends after the end of IB.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void si_dump_mmapped_reg(struct si_context *sctx, FILE *f,
|
||||
unsigned offset)
|
||||
{
|
||||
struct radeon_winsys *ws = sctx->b.ws;
|
||||
uint32_t value;
|
||||
|
||||
if (ws->read_registers(ws, offset, 1, &value))
|
||||
si_dump_reg(f, offset, value, ~0);
|
||||
}
|
||||
|
||||
static void si_dump_debug_registers(struct si_context *sctx, FILE *f)
|
||||
{
|
||||
if (sctx->screen->b.info.drm_major == 2 &&
|
||||
sctx->screen->b.info.drm_minor < 42)
|
||||
return; /* no radeon support */
|
||||
|
||||
fprintf(f, "Memory-mapped registers:\n");
|
||||
si_dump_mmapped_reg(sctx, f, R_008010_GRBM_STATUS);
|
||||
|
||||
/* No other registers can be read on DRM < 3.1.0. */
|
||||
if (sctx->screen->b.info.drm_major < 3 ||
|
||||
sctx->screen->b.info.drm_minor < 1) {
|
||||
fprintf(f, "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
si_dump_mmapped_reg(sctx, f, R_008008_GRBM_STATUS2);
|
||||
si_dump_mmapped_reg(sctx, f, R_008014_GRBM_STATUS_SE0);
|
||||
si_dump_mmapped_reg(sctx, f, R_008018_GRBM_STATUS_SE1);
|
||||
si_dump_mmapped_reg(sctx, f, R_008038_GRBM_STATUS_SE2);
|
||||
si_dump_mmapped_reg(sctx, f, R_00803C_GRBM_STATUS_SE3);
|
||||
si_dump_mmapped_reg(sctx, f, R_00D034_SDMA0_STATUS_REG);
|
||||
si_dump_mmapped_reg(sctx, f, R_00D834_SDMA1_STATUS_REG);
|
||||
si_dump_mmapped_reg(sctx, f, R_000E50_SRBM_STATUS);
|
||||
si_dump_mmapped_reg(sctx, f, R_000E4C_SRBM_STATUS2);
|
||||
si_dump_mmapped_reg(sctx, f, R_000E54_SRBM_STATUS3);
|
||||
si_dump_mmapped_reg(sctx, f, R_008680_CP_STAT);
|
||||
si_dump_mmapped_reg(sctx, f, R_008674_CP_STALLED_STAT1);
|
||||
si_dump_mmapped_reg(sctx, f, R_008678_CP_STALLED_STAT2);
|
||||
si_dump_mmapped_reg(sctx, f, R_008670_CP_STALLED_STAT3);
|
||||
si_dump_mmapped_reg(sctx, f, R_008210_CP_CPC_STATUS);
|
||||
si_dump_mmapped_reg(sctx, f, R_008214_CP_CPC_BUSY_STAT);
|
||||
si_dump_mmapped_reg(sctx, f, R_008218_CP_CPC_STALLED_STAT1);
|
||||
si_dump_mmapped_reg(sctx, f, R_00821C_CP_CPF_STATUS);
|
||||
si_dump_mmapped_reg(sctx, f, R_008220_CP_CPF_BUSY_STAT);
|
||||
si_dump_mmapped_reg(sctx, f, R_008224_CP_CPF_STALLED_STAT1);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
static void si_dump_debug_state(struct pipe_context *ctx, FILE *f,
|
||||
unsigned flags)
|
||||
{
|
||||
struct si_context *sctx = (struct si_context*)ctx;
|
||||
|
||||
if (flags & PIPE_DEBUG_DEVICE_IS_HUNG)
|
||||
si_dump_debug_registers(sctx, f);
|
||||
|
||||
si_dump_shader(sctx->vs_shader, "Vertex", f);
|
||||
si_dump_shader(sctx->tcs_shader, "Tessellation control", f);
|
||||
si_dump_shader(sctx->tes_shader, "Tessellation evaluation", f);
|
||||
si_dump_shader(sctx->gs_shader, "Geometry", f);
|
||||
si_dump_shader(sctx->ps_shader, "Fragment", f);
|
||||
|
||||
if (sctx->last_ib) {
|
||||
int last_trace_id = -1;
|
||||
|
||||
if (sctx->last_trace_buf) {
|
||||
/* We are expecting that the ddebug pipe has already
|
||||
* waited for the context, so this buffer should be idle.
|
||||
* If the GPU is hung, there is no point in waiting for it.
|
||||
*/
|
||||
uint32_t *map =
|
||||
sctx->b.ws->buffer_map(sctx->last_trace_buf->cs_buf,
|
||||
NULL,
|
||||
PIPE_TRANSFER_UNSYNCHRONIZED |
|
||||
PIPE_TRANSFER_READ);
|
||||
if (map)
|
||||
last_trace_id = *map;
|
||||
}
|
||||
|
||||
si_parse_ib(f, sctx->last_ib, sctx->last_ib_dw_size,
|
||||
last_trace_id);
|
||||
free(sctx->last_ib); /* dump only once */
|
||||
sctx->last_ib = NULL;
|
||||
r600_resource_reference(&sctx->last_trace_buf, NULL);
|
||||
}
|
||||
|
||||
fprintf(f, "Done.\n");
|
||||
}
|
||||
|
||||
void si_init_debug_functions(struct si_context *sctx)
|
||||
{
|
||||
sctx->b.b.dump_debug_state = si_dump_debug_state;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user