Compare commits
253 Commits
bisect-tem
...
mesa-10.3.
Author | SHA1 | Date | |
---|---|---|---|
|
1a9cc5f50d | ||
|
3be619f4b4 | ||
|
d5700dc276 | ||
|
d5ada3364f | ||
|
36b7043611 | ||
|
894ac63c34 | ||
|
d26258166c | ||
|
e8c7affa66 | ||
|
62b2c8aca0 | ||
|
e71a41852b | ||
|
136ab97b46 | ||
|
4956788a5f | ||
|
bcf414c1a8 | ||
|
d45d00cf38 | ||
|
4ed4dec642 | ||
|
a3d5e59563 | ||
|
69ac2043cf | ||
|
eaff221c9c | ||
|
a95a93b557 | ||
|
b0d6ba5970 | ||
|
b379e36e64 | ||
|
d6aab6b0c9 | ||
|
5b76a32132 | ||
|
708ee6f188 | ||
|
971ae04fe6 | ||
|
64373f072c | ||
|
9ea0efd1e2 | ||
|
bc96be5662 | ||
|
323380b7ed | ||
|
832cb958ff | ||
|
8a61e39531 | ||
|
4b30efcf99 | ||
|
bce1e7e1c9 | ||
|
bce2d42ddb | ||
|
7e81f4a7e7 | ||
|
63b8a08c45 | ||
|
4a97401abf | ||
|
dd79de214d | ||
|
1acdeab8a4 | ||
|
64e4ac780e | ||
|
5bc1397bda | ||
|
3b1a59259b | ||
|
74a92b1f34 | ||
|
af52b00b19 | ||
|
556d74b810 | ||
|
502c295025 | ||
|
c4f58245d0 | ||
|
eb496ff68d | ||
|
e8820c85b4 | ||
|
da71ef1893 | ||
|
0a003d1dbc | ||
|
3b755280af | ||
|
476c8c5028 | ||
|
6d5a3daca9 | ||
|
4d20bc6e8d | ||
|
f1fd768b98 | ||
|
d37c083778 | ||
|
b46151f2ca | ||
|
419acd3068 | ||
|
64ce1bf8f6 | ||
|
e67e5c6582 | ||
|
d654082d14 | ||
|
1a7fb8f04a | ||
|
fb10a43b84 | ||
|
e1c2a8f2cb | ||
|
0b339336b5 | ||
|
00c3ef169f | ||
|
f61b2185db | ||
|
637ddce9cc | ||
|
737c900506 | ||
|
336b75faca | ||
|
7f6c0f4de4 | ||
|
1a755fcc3a | ||
|
2a90f0fb85 | ||
|
3a64feedb8 | ||
|
544a368626 | ||
|
e10a243abf | ||
|
a3f6e58d6d | ||
|
14f6eb92f8 | ||
|
c3ee102f8e | ||
|
1c160747d0 | ||
|
c912acad17 | ||
|
81bd498908 | ||
|
6244af1343 | ||
|
5af1301751 | ||
|
3f545b96e5 | ||
|
69c1aa728d | ||
|
1d1bc7f7c2 | ||
|
34b62bd12e | ||
|
695a4b2b4e | ||
|
0e9bb8efe4 | ||
|
1a36639b06 | ||
|
06d5717692 | ||
|
852bb5dd62 | ||
|
b2c855b7f9 | ||
|
91f9cbc996 | ||
|
852da37330 | ||
|
ea955ffd4d | ||
|
9995edb700 | ||
|
8dfb9773c4 | ||
|
e90f0daaaa | ||
|
7fded6b548 | ||
|
5e5b48b10e | ||
|
d1794194f6 | ||
|
9599470642 | ||
|
3b6a4758fa | ||
|
e0aaa9591b | ||
|
724f71ef39 | ||
|
6fa07d1d48 | ||
|
8f6f6a28fa | ||
|
10d8287074 | ||
|
c759d1b6bf | ||
|
b37c1d4642 | ||
|
fb20a5aa98 | ||
|
4f33ded115 | ||
|
13a4fd2430 | ||
|
5e6ee119c0 | ||
|
85d7eb730a | ||
|
64c2bdc334 | ||
|
125cd86cd4 | ||
|
e3e68a36db | ||
|
745a0bfd62 | ||
|
ada5fd6e85 | ||
|
ecd2d078ac | ||
|
08f7e3591d | ||
|
fa98c74692 | ||
|
088d350178 | ||
|
85421100fb | ||
|
c90cd077bd | ||
|
dffbee6668 | ||
|
58ba481e8e | ||
|
ccf908e382 | ||
|
ed440234d4 | ||
|
d95520d297 | ||
|
3e980357c5 | ||
|
384816c6db | ||
|
d556ed889d | ||
|
d9444533aa | ||
|
9328440ef7 | ||
|
1ac204121b | ||
|
fef6059a81 | ||
|
34809f8eef | ||
|
9a79018840 | ||
|
5aff846a60 | ||
|
fb4e23626f | ||
|
607d0b9578 | ||
|
4fce87bcee | ||
|
8e2d0f59f7 | ||
|
4748d2f065 | ||
|
f74bca93b4 | ||
|
ceebec140b | ||
|
095a6a0af1 | ||
|
04a9d7d44a | ||
|
d4289fc37b | ||
|
9599cd6a2f | ||
|
27f70a9273 | ||
|
0a6e33ea74 | ||
|
18571edea8 | ||
|
1b12af300d | ||
|
4c4846b588 | ||
|
e471841048 | ||
|
f86efb4285 | ||
|
84a58f462a | ||
|
605734780e | ||
|
efe8fc687d | ||
|
051543962f | ||
|
b92ea2a10d | ||
|
b0131d951b | ||
|
0c1f24b46c | ||
|
a4d4ab929e | ||
|
2b43d48509 | ||
|
62f56a08af | ||
|
a3c52ce0b4 | ||
|
6c562f3d1a | ||
|
6240628e05 | ||
|
0f4dc09807 | ||
|
eeba3c94b1 | ||
|
0eeec2871d | ||
|
8f1ccf3577 | ||
|
8e05b2bfae | ||
|
997f634c33 | ||
|
a58ae20536 | ||
|
80f93d6937 | ||
|
860af662fa | ||
|
10aee701ae | ||
|
afe5db3293 | ||
|
d9df31cc6e | ||
|
f009cb080e | ||
|
09a763bea5 | ||
|
9c5ffa7f7a | ||
|
31414ada14 | ||
|
002c284fb4 | ||
|
73192345c3 | ||
|
6bc4331c8e | ||
|
72d8ebb7fb | ||
|
9f67c26d1b | ||
|
07426ad102 | ||
|
414de21449 | ||
|
31adc40680 | ||
|
a318e2f383 | ||
|
3a49ccc134 | ||
|
b148cd6586 | ||
|
7fb0fed989 | ||
|
8e551f4220 | ||
|
bb06f2cd93 | ||
|
d3745890c6 | ||
|
7a2018b968 | ||
|
4e1ca4a190 | ||
|
06f1f1ea81 | ||
|
e842a02df3 | ||
|
96bca3617c | ||
|
c221e96a13 | ||
|
640ddefd96 | ||
|
7cd0fa023e | ||
|
cd94c64421 | ||
|
e9923b2194 | ||
|
2e56334a2a | ||
|
ead7f72a2c | ||
|
139d176f54 | ||
|
941b2ae35f | ||
|
4b38838ef4 | ||
|
3fdd08c9b4 | ||
|
f8ff31e528 | ||
|
ab53a29892 | ||
|
4073e96a3b | ||
|
4eed41b967 | ||
|
c546523b4d | ||
|
282a3098e6 | ||
|
ec4a333c37 | ||
|
35bb6b058c | ||
|
24e226d0f5 | ||
|
39ad62ce51 | ||
|
f2b2309281 | ||
|
a4b3c4e3ec | ||
|
01dda9d0bd | ||
|
49cd42aab1 | ||
|
eaa9e14ce5 | ||
|
58be4ab741 | ||
|
447785af9d | ||
|
390a9f6cb7 | ||
|
0fbb9a599d | ||
|
2310a4b4cf | ||
|
8ef3d4fe03 | ||
|
0c67167370 | ||
|
60f136eed9 | ||
|
d2fb1da46d | ||
|
627d31dc36 | ||
|
e4f54d8b47 | ||
|
2edc941e75 | ||
|
eb96819386 | ||
|
f2a1b7d508 | ||
|
53728f60aa | ||
|
04c3c03682 |
@@ -81,6 +81,7 @@ SUBDIRS := \
|
||||
src/mapi \
|
||||
src/glsl \
|
||||
src/mesa \
|
||||
src/util \
|
||||
src/egl/main
|
||||
|
||||
ifeq ($(strip $(MESA_BUILD_CLASSIC)),true)
|
||||
|
11
Makefile.am
11
Makefile.am
@@ -64,14 +64,13 @@ IGNORE_FILES = \
|
||||
|
||||
parsers: configure
|
||||
$(MAKE) -C src/glsl glsl_parser.cpp glsl_parser.h glsl_lexer.cpp glcpp/glcpp-lex.c glcpp/glcpp-parse.c glcpp/glcpp-parse.h
|
||||
$(MAKE) -C src/mesa program/lex.yy.c program/program_parse.tab.c program/program_parse.tab.h
|
||||
|
||||
# Everything for new a Mesa release:
|
||||
ARCHIVES = $(PACKAGE_NAME).tar.gz \
|
||||
$(PACKAGE_NAME).tar.bz2 \
|
||||
$(PACKAGE_NAME).zip
|
||||
|
||||
tarballs: md5
|
||||
tarballs: checksums
|
||||
rm -f ../$(PACKAGE_DIR) $(PACKAGE_NAME).tar
|
||||
|
||||
manifest.txt: .git
|
||||
@@ -98,9 +97,9 @@ $(PACKAGE_NAME).zip: parsers ../$(PACKAGE_DIR) manifest.txt
|
||||
zip -q -@ $(PACKAGE_NAME).zip < $(PACKAGE_DIR)/manifest.txt ; \
|
||||
mv $(PACKAGE_NAME).zip $(PACKAGE_DIR)
|
||||
|
||||
md5: $(ARCHIVES)
|
||||
@-md5sum $(PACKAGE_NAME).tar.gz
|
||||
@-md5sum $(PACKAGE_NAME).tar.bz2
|
||||
@-md5sum $(PACKAGE_NAME).zip
|
||||
checksums: $(ARCHIVES)
|
||||
@-sha256sum $(PACKAGE_NAME).tar.gz
|
||||
@-sha256sum $(PACKAGE_NAME).tar.bz2
|
||||
@-sha256sum $(PACKAGE_NAME).zip
|
||||
|
||||
.PHONY: tarballs md5
|
||||
|
64
configure.ac
64
configure.ac
@@ -355,6 +355,24 @@ AC_LINK_IFELSE(
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
|
||||
|
||||
dnl
|
||||
dnl Check if linker supports dynamic list files
|
||||
dnl
|
||||
AC_MSG_CHECKING([if the linker supports --dynamic-list])
|
||||
save_LDFLAGS=$LDFLAGS
|
||||
LDFLAGS="$LDFLAGS -Wl,--dynamic-list=conftest.dyn"
|
||||
cat > conftest.dyn <<EOF
|
||||
{
|
||||
radeon_drm_winsys_create;
|
||||
};
|
||||
EOF
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_SOURCE([int main() { return 0;}])],
|
||||
[have_ld_dynamic_list=yes;AC_MSG_RESULT(yes)],
|
||||
[have_ld_dynamic_list=no; AC_MSG_RESULT(no)])
|
||||
LDFLAGS=$save_LDFLAGS
|
||||
AM_CONDITIONAL(HAVE_LD_DYNAMIC_LIST, test "$have_ld_dynamic_list" = "yes")
|
||||
|
||||
dnl
|
||||
dnl compatibility symlinks
|
||||
dnl
|
||||
@@ -802,6 +820,11 @@ fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_SHARED_GLAPI, test "x$enable_shared_glapi" = xyes)
|
||||
|
||||
# Build the pipe-drivers as separate libraries/modules.
|
||||
# Do not touch this unless you know what you are doing.
|
||||
# XXX: Expose via configure option ?
|
||||
enable_shared_pipe_drivers=no
|
||||
|
||||
dnl
|
||||
dnl Driver specific build directories
|
||||
dnl
|
||||
@@ -822,7 +845,7 @@ esac
|
||||
if test "x$enable_dri" = xyes; then
|
||||
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS sw/dri"
|
||||
GALLIUM_STATE_TRACKERS_DIRS="dri $GALLIUM_STATE_TRACKERS_DIRS"
|
||||
enable_gallium_loader=yes
|
||||
enable_gallium_loader="$enable_shared_pipe_drivers"
|
||||
fi
|
||||
|
||||
if test "x$enable_gallium_osmesa" = xyes; then
|
||||
@@ -1295,7 +1318,8 @@ if test "x$enable_gallium_egl" = xyes; then
|
||||
|
||||
GALLIUM_STATE_TRACKERS_DIRS="egl $GALLIUM_STATE_TRACKERS_DIRS"
|
||||
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS egl-static"
|
||||
# enable_gallium_loader=yes
|
||||
# XXX: Uncomment once converted to use static/shared pipe-drivers
|
||||
# enable_gallium_loader=$enable_shared_pipe_drivers
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_EGL, test "x$enable_gallium_egl" = xyes)
|
||||
|
||||
@@ -1324,7 +1348,7 @@ if test "x$enable_gallium_gbm" = xyes; then
|
||||
|
||||
GALLIUM_STATE_TRACKERS_DIRS="gbm $GALLIUM_STATE_TRACKERS_DIRS"
|
||||
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS gbm"
|
||||
enable_gallium_loader=yes
|
||||
enable_gallium_loader=$enable_shared_pipe_drivers
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_GBM, test "x$enable_gallium_gbm" = xyes)
|
||||
|
||||
@@ -1341,7 +1365,7 @@ if test "x$enable_xa" = xyes; then
|
||||
Example: ./configure --enable-xa --with-gallium-drivers=svga...])
|
||||
fi
|
||||
GALLIUM_STATE_TRACKERS_DIRS="xa $GALLIUM_STATE_TRACKERS_DIRS"
|
||||
enable_gallium_loader=yes
|
||||
enable_gallium_loader=$enable_shared_pipe_drivers
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_ST_XA, test "x$enable_xa" = xyes)
|
||||
|
||||
@@ -1389,7 +1413,7 @@ fi
|
||||
if test "x$enable_xvmc" = xyes; then
|
||||
PKG_CHECK_MODULES([XVMC], [xvmc >= $XVMC_REQUIRED x11-xcb xcb-dri2 >= $XCBDRI2_REQUIRED])
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xvmc"
|
||||
enable_gallium_loader=yes
|
||||
enable_gallium_loader=$enable_shared_pipe_drivers
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_ST_XVMC, test "x$enable_xvmc" = xyes)
|
||||
|
||||
@@ -1397,14 +1421,14 @@ if test "x$enable_vdpau" = xyes; then
|
||||
PKG_CHECK_MODULES([VDPAU], [vdpau >= $VDPAU_REQUIRED x11-xcb xcb-dri2 >= $XCBDRI2_REQUIRED],
|
||||
[VDPAU_LIBS="`$PKG_CONFIG --libs x11-xcb xcb-dri2`"])
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS vdpau"
|
||||
enable_gallium_loader=yes
|
||||
enable_gallium_loader=$enable_shared_pipe_drivers
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_ST_VDPAU, test "x$enable_vdpau" = xyes)
|
||||
|
||||
if test "x$enable_omx" = xyes; then
|
||||
PKG_CHECK_MODULES([OMX], [libomxil-bellagio >= $LIBOMXIL_BELLAGIO_REQUIRED x11-xcb xcb-dri2 >= $XCBDRI2_REQUIRED])
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS omx"
|
||||
enable_gallium_loader=yes
|
||||
enable_gallium_loader=$enable_shared_pipe_drivers
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_ST_OMX, test "x$enable_omx" = xyes)
|
||||
|
||||
@@ -1456,6 +1480,7 @@ if test "x$enable_opencl" = xyes; then
|
||||
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS clover"
|
||||
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS opencl"
|
||||
# XXX: Use $enable_shared_pipe_drivers once converted to use static/shared pipe-drivers
|
||||
enable_gallium_loader=yes
|
||||
|
||||
if test "x$enable_opencl_icd" = xyes; then
|
||||
@@ -1630,6 +1655,7 @@ strip_unwanted_llvm_flags() {
|
||||
# Use \> (marks the end of the word)
|
||||
echo `$1` | sed \
|
||||
-e 's/-DNDEBUG\>//g' \
|
||||
-e 's/-D_GNU_SOURCE\>//g' \
|
||||
-e 's/-pedantic\>//g' \
|
||||
-e 's/-Wcovered-switch-default\>//g' \
|
||||
-e 's/-O.\>//g' \
|
||||
@@ -1678,11 +1704,10 @@ if test "x$enable_gallium_llvm" = xyes; then
|
||||
AC_COMPUTE_INT([LLVM_VERSION_MINOR], [LLVM_VERSION_MINOR],
|
||||
[#include "${LLVM_INCLUDEDIR}/llvm/Config/llvm-config.h"])
|
||||
|
||||
dnl In LLVM 3.4.1 patch level was defined in config.h and not
|
||||
dnl llvm-config.h
|
||||
AC_COMPUTE_INT([LLVM_VERSION_PATCH], [LLVM_VERSION_PATCH],
|
||||
[#include "${LLVM_INCLUDEDIR}/llvm/Config/config.h"],
|
||||
LLVM_VERSION_PATCH=0) dnl Default if LLVM_VERSION_PATCH not found
|
||||
LLVM_VERSION_PATCH=`echo $LLVM_VERSION | cut -d. -f3 | egrep -o '^[[0-9]]+'`
|
||||
if test -z "$LLVM_VERSION_PATCH"; then
|
||||
LLVM_VERSION_PATCH=0
|
||||
fi
|
||||
|
||||
if test -n "${LLVM_VERSION_MAJOR}"; then
|
||||
LLVM_VERSION_INT="${LLVM_VERSION_MAJOR}0${LLVM_VERSION_MINOR}"
|
||||
@@ -1756,6 +1781,7 @@ dnl
|
||||
dnl Gallium Tests
|
||||
dnl
|
||||
if test "x$enable_gallium_tests" = xyes; then
|
||||
# XXX: Use $enable_shared_pipe_drivers once converted to use static/shared pipe-drivers
|
||||
enable_gallium_loader=yes
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_TESTS, test "x$enable_gallium_tests" = xyes)
|
||||
@@ -1889,6 +1915,9 @@ if test -n "$with_gallium_drivers"; then
|
||||
case "x$driver" in
|
||||
xsvga)
|
||||
HAVE_GALLIUM_SVGA=yes
|
||||
if test "x$have_libdrm" != xyes; then
|
||||
AC_MSG_ERROR([Building svga requires libdrm >= $LIBDRM_REQUIRED])
|
||||
fi
|
||||
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS svga softpipe"
|
||||
gallium_require_drm_loader
|
||||
gallium_check_st "svga/drm" "dri/vmwgfx" "xa/vmwgfx"
|
||||
@@ -2028,7 +2057,12 @@ if test "x$MESA_LLVM" != x0; then
|
||||
dnl already added all of these objects to LLVM_LIBS.
|
||||
fi
|
||||
else
|
||||
AC_MSG_WARN([Building mesa with staticly linked LLVM may cause compilation issues])
|
||||
AC_MSG_WARN([Building mesa with statically linked LLVM may cause compilation issues])
|
||||
dnl We need to link to llvm system libs when using static libs
|
||||
dnl However, only llvm 3.5+ provides --system-libs
|
||||
if test $LLVM_VERSION_MAJOR -eq 3 -a $LLVM_VERSION_MINOR -ge 5; then
|
||||
LLVM_LIBS="$LLVM_LIBS `$LLVM_CONFIG --system-libs`"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -2051,9 +2085,7 @@ AM_CONDITIONAL(NEED_GALLIUM_SOFTPIPE_DRIVER, test "x$HAVE_GALLIUM_SVGA" = xyes -
|
||||
AM_CONDITIONAL(NEED_GALLIUM_LLVMPIPE_DRIVER, test "x$HAVE_GALLIUM_SOFTPIPE" = xyes \
|
||||
&& test "x$MESA_LLVM" = x1)
|
||||
|
||||
# Enable static gallium targets for now.
|
||||
# Do not touch this unless you know what you are doing.
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_STATIC_TARGETS, test "xyes" = xyes)
|
||||
AM_CONDITIONAL(HAVE_GALLIUM_STATIC_TARGETS, test "x$enable_shared_pipe_drivers" = xno)
|
||||
|
||||
# NOTE: anything using xcb or other client side libs ends up in separate
|
||||
# _CLIENT variables. The pipe loader is built in two variants,
|
||||
|
@@ -16,6 +16,17 @@
|
||||
|
||||
<h1>News</h1>
|
||||
|
||||
<h2>September 19, 2014</h2>
|
||||
<p>
|
||||
<a href="relnotes/10.3.html">Mesa 10.3</a> is released. This is a new
|
||||
development release. See the release notes for more information about
|
||||
the release.
|
||||
</p>
|
||||
<p>
|
||||
Also, <a href="relnotes/10.2.8.html">Mesa 10.2.8</a> is released.
|
||||
This is a bug fix release from the 10.2 branch.
|
||||
</p>
|
||||
|
||||
<h2>August 19, 2014</h2>
|
||||
<p>
|
||||
<a href="relnotes/10.2.6.html">Mesa 10.2.6</a> is released.
|
||||
|
@@ -21,6 +21,8 @@ The release notes summarize what's new or changed in each Mesa release.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="relnotes/10.3.html">10.3 release notes</a>
|
||||
<li><a href="relnotes/10.2.8.html">10.2.8 release notes</a>
|
||||
<li><a href="relnotes/10.2.6.html">10.2.6 release notes</a>
|
||||
<li><a href="relnotes/10.2.5.html">10.2.5 release notes</a>
|
||||
<li><a href="relnotes/10.2.4.html">10.2.4 release notes</a>
|
||||
|
158
docs/relnotes/10.3.1.html
Normal file
158
docs/relnotes/10.3.1.html
Normal file
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Mesa Release Notes</title>
|
||||
<link rel="stylesheet" type="text/css" href="../mesa.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<h1>The Mesa 3D Graphics Library</h1>
|
||||
</div>
|
||||
|
||||
<iframe src="../contents.html"></iframe>
|
||||
<div class="content">
|
||||
|
||||
<h1>Mesa 10.3.1 Release Notes / October 12, 2014</h1>
|
||||
|
||||
<p>
|
||||
Mesa 10.3.1 is a bug fix release which fixes bugs found since the 10.3 release.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 10.3.1 implements the OpenGL 3.3 API, but the version reported by
|
||||
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
|
||||
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 3.3. OpenGL
|
||||
3.3 is <strong>only</strong> available if requested at context creation
|
||||
because compatibility contexts are not supported.
|
||||
</p>
|
||||
|
||||
<h2>SHA256 checksums</h2>
|
||||
<pre>
|
||||
155afcbad17be8bb80282c761b957d5cc716c14a1fa16c4f5ee04e76df729c6d MesaLib-10.3.1.tar.gz
|
||||
b081d077d717e5d56f2d59677490856052c41573e50378ff86d6c72456714add MesaLib-10.3.1.tar.bz2
|
||||
07a14febfed06412d519e091a62d24513fee6745f1a6f8a8f1956bfe04b77d15 MesaLib-10.3.1.zip
|
||||
</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=79462">Bug 79462</a> - [NVC0/Codegen] Shader compilation falis in spill logic</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82932">Bug 82932</a> - [SNB+ Bisected]Ogles3conform ES3-CTS.shaders.indexing.vector_subscript.vec3_static_loop_subscript_write_direct_read_vertex fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83506">Bug 83506</a> - [UBO] row_major layout ignored inside structures</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83533">Bug 83533</a> - [UBO] nested structures don't get appropriate padding</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83570">Bug 83570</a> - Glyphy demo throws unhandled Integer division by zero exception</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83741">Bug 83741</a> - [UBO] row_major layout partially ignored for arrays of structures</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84178">Bug 84178</a> - Big glamor regression in Xorg server 1.6.99.1 GIT: x11perf 1.5 Test: PutImage XY 500x500 Square</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Changes</h2>
|
||||
|
||||
<p>Andreas Pokorny (2):</p>
|
||||
<ul>
|
||||
<li>egl/drm: expose KHR_image_pixmap extension</li>
|
||||
<li>i915: Fix black buffers when importing prime fds</li>
|
||||
</ul>
|
||||
|
||||
<p>Brian Paul (1):</p>
|
||||
<ul>
|
||||
<li>mesa: fix prog_optimize.c assertions triggered by SWZ opcode</li>
|
||||
</ul>
|
||||
|
||||
<p>Emil Velikov (2):</p>
|
||||
<ul>
|
||||
<li>docs: Add 10.3 sha256 sums, news item and link release notes</li>
|
||||
<li>Update VERSION to 10.3.1</li>
|
||||
</ul>
|
||||
|
||||
<p>Ian Romanick (4):</p>
|
||||
<ul>
|
||||
<li>glsl: Make sure fields after small structs have correct padding</li>
|
||||
<li>glsl: Make sure row-major array-of-structure get correct layout</li>
|
||||
<li>glsl: Round struct size up to at least 16 bytes</li>
|
||||
<li>glsl: Strip arrayness from ir_type_dereference_variable too</li>
|
||||
</ul>
|
||||
|
||||
<p>Ilia Mirkin (5):</p>
|
||||
<ul>
|
||||
<li>nv50/ir: avoid deleting pseudo instructions too early</li>
|
||||
<li>gm107/ir: fix manual TXD for array targets</li>
|
||||
<li>gm107/ir: fix texture argument order</li>
|
||||
<li>gm107/ir: add support for indirect const buffer selection</li>
|
||||
<li>gm107/ir: take relative pfetch offset into account</li>
|
||||
</ul>
|
||||
|
||||
<p>Keith Packard (1):</p>
|
||||
<ul>
|
||||
<li>glx/dri3: Provide error diagnostics when DRI3 allocation fails</li>
|
||||
</ul>
|
||||
|
||||
<p>Kenneth Graunke (2):</p>
|
||||
<ul>
|
||||
<li>mesa: Use proper structure for glGet*(GL_TEXTURE_COORD_ARRAY*).</li>
|
||||
<li>mesa: Set correct array element in vbo_exec_vtx_init.</li>
|
||||
</ul>
|
||||
|
||||
<p>Marek Olšák (3):</p>
|
||||
<ul>
|
||||
<li>radeonsi: release GS rings at context destruction</li>
|
||||
<li>radeonsi: properly destroy the GS copy shader and scratch_bo for compute</li>
|
||||
<li>st/dri: remove GALLIUM_MSAA and __GL_FSAA_MODE environment variables</li>
|
||||
</ul>
|
||||
|
||||
<p>Michel Dänzer (1):</p>
|
||||
<ul>
|
||||
<li>st/mesa: Use PIPE_USAGE_STAGING for GL_STATIC/DYNAMIC/STREAM_READ buffers</li>
|
||||
</ul>
|
||||
|
||||
<p>Richard Sandiford (2):</p>
|
||||
<ul>
|
||||
<li>mesa: Fix alpha component in unpack_R8G8B8X8_SRGB.</li>
|
||||
<li>swrast: Fix handling of MESA_FORMAT_L8A8_SRGB for big-endian</li>
|
||||
</ul>
|
||||
|
||||
<p>Roland Scheidegger (1):</p>
|
||||
<ul>
|
||||
<li>gallivm: fix idiv</li>
|
||||
</ul>
|
||||
|
||||
<p>Thomas Hellstrom (1):</p>
|
||||
<ul>
|
||||
<li>st/xa: Fix regression in xa_yuv_planar_blit()</li>
|
||||
</ul>
|
||||
|
||||
<p>Tom Stellard (2):</p>
|
||||
<ul>
|
||||
<li>clover: Add support to mem objects for multiple destructor callbacks v2</li>
|
||||
<li>configure.ac: Compute LLVM_VERSION_PATCH using llvm-config</li>
|
||||
</ul>
|
||||
|
||||
<p>Tomasz Figa (3):</p>
|
||||
<ul>
|
||||
<li>util: Include in Android builds</li>
|
||||
<li>st/mesa: Generate format_info.c in Android builds</li>
|
||||
<li>st/mesa: Fix paths used in Android builds</li>
|
||||
</ul>
|
||||
|
||||
<p>rconde (1):</p>
|
||||
<ul>
|
||||
<li>gallivm,tgsi: fix idiv by zero crash</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
115
docs/relnotes/10.3.2.html
Normal file
115
docs/relnotes/10.3.2.html
Normal file
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Mesa Release Notes</title>
|
||||
<link rel="stylesheet" type="text/css" href="../mesa.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<h1>The Mesa 3D Graphics Library</h1>
|
||||
</div>
|
||||
|
||||
<iframe src="../contents.html"></iframe>
|
||||
<div class="content">
|
||||
|
||||
<h1>Mesa 10.3.2 Release Notes / October 24, 2014</h1>
|
||||
|
||||
<p>
|
||||
Mesa 10.3.2 is a bug fix release which fixes bugs found since the 10.3 release.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 10.3.2 implements the OpenGL 3.3 API, but the version reported by
|
||||
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
|
||||
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 3.3. OpenGL
|
||||
3.3 is <strong>only</strong> available if requested at context creation
|
||||
because compatibility contexts are not supported.
|
||||
</p>
|
||||
|
||||
<h2>SHA256 checksums</h2>
|
||||
<pre>
|
||||
e65f8e691f06f111c1aeb3a376b13c9cc88cb162bee2709e0e7e6b0e6628ca75 MesaLib-10.3.2.tar.gz
|
||||
e9849bcb9aa9acd98a753d6d46d2e7d7238d3367036e11357a60efd16de8bea3 MesaLib-10.3.2.tar.bz2
|
||||
427dc0d670d38e713ebff2675665ec2fe4ff7d04ce227bd54de946999fc1d234 MesaLib-10.3.2.zip
|
||||
</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=54372">Bug 54372</a> - GLX_INTEL_swap_event crashes driver when swapping window buffers</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81680">Bug 81680</a> - [r600g] Firefox crashes with hardware acceleration turned on</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84140">Bug 84140</a> - mplayer crashes playing some files using vdpau output</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=84662">Bug 84662</a> - Long pauses with Unreal demo Elemental on R9270X since : Always flush the HDP cache before submitting a CS to the GPU</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=85267">Bug 85267</a> - vlc crashes with vdpau (Radeon 3850HD) [r600]</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Changes</h2>
|
||||
|
||||
<p>Brian Paul (3):</p>
|
||||
<ul>
|
||||
<li>mesa: fix spurious wglGetProcAddress / GL_INVALID_OPERATION error</li>
|
||||
<li>st/wgl: add WINAPI qualifiers on wgl function typedefs</li>
|
||||
<li>glsl: fix several use-after-free bugs</li>
|
||||
</ul>
|
||||
|
||||
<p>Daniel Manjarres (1):</p>
|
||||
<ul>
|
||||
<li>glx: Fix glxUseXFont for glxWindow and glxPixmaps</li>
|
||||
</ul>
|
||||
|
||||
<p>Dave Airlie (1):</p>
|
||||
<ul>
|
||||
<li>mesa: fix GetTexImage for 1D array depth textures</li>
|
||||
</ul>
|
||||
|
||||
<p>Emil Velikov (2):</p>
|
||||
<ul>
|
||||
<li>docs: Add sha256 sums for the 10.3.1 release</li>
|
||||
<li>Update VERSION to 10.3.2</li>
|
||||
</ul>
|
||||
|
||||
<p>Ilia Mirkin (4):</p>
|
||||
<ul>
|
||||
<li>gm107/ir: add dnz emission for fmul</li>
|
||||
<li>gk110/ir: add dnz flag emission for fmul/fmad</li>
|
||||
<li>nouveau: 3d textures are unsupported, limit 3d levels to 1</li>
|
||||
<li>st/gbm: fix order of arguments passed to is_format_supported</li>
|
||||
</ul>
|
||||
|
||||
<p>Kenneth Graunke (3):</p>
|
||||
<ul>
|
||||
<li>i965: Add a BRW_MOCS_PTE #define.</li>
|
||||
<li>i965: Use BDW_MOCS_PTE for renderbuffers.</li>
|
||||
<li>i965: Fix register write checks.</li>
|
||||
</ul>
|
||||
|
||||
<p>Marek Olšák (2):</p>
|
||||
<ul>
|
||||
<li>st/mesa: use pipe_sampler_view_release for releasing sampler views</li>
|
||||
<li>glsl_to_tgsi: fix the value of gl_FrontFacing with native integers</li>
|
||||
</ul>
|
||||
|
||||
<p>Michel Dänzer (4):</p>
|
||||
<ul>
|
||||
<li>radeonsi: Clear sampler view flags when binding a buffer</li>
|
||||
<li>r600g,radeonsi: Always use GTT again for PIPE_USAGE_STREAM buffers</li>
|
||||
<li>winsys/radeon: Use separate caching buffer manager for each set of flags</li>
|
||||
<li>r600g: Drop references to destroyed blend state</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
207
docs/relnotes/10.3.3.html
Normal file
207
docs/relnotes/10.3.3.html
Normal file
@@ -0,0 +1,207 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<title>Mesa Release Notes</title>
|
||||
<link rel="stylesheet" type="text/css" href="../mesa.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<h1>The Mesa 3D Graphics Library</h1>
|
||||
</div>
|
||||
|
||||
<iframe src="../contents.html"></iframe>
|
||||
<div class="content">
|
||||
|
||||
<h1>Mesa 10.3.3 Release Notes / November 8, 2014</h1>
|
||||
|
||||
<p>
|
||||
Mesa 10.3.3 is a bug fix release which fixes bugs found since the 10.3.2 release.
|
||||
</p>
|
||||
<p>
|
||||
Mesa 10.3.3 implements the OpenGL 3.3 API, but the version reported by
|
||||
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
|
||||
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
|
||||
Some drivers don't support all the features required in OpenGL 3.3. OpenGL
|
||||
3.3 is <strong>only</strong> available if requested at context creation
|
||||
because compatibility contexts are not supported.
|
||||
</p>
|
||||
|
||||
<h2>SHA256 checksums</h2>
|
||||
<pre>
|
||||
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=70410">Bug 70410</a> - egl-static/Makefile: linking fails with llvm >= 3.4</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82921">Bug 82921</a> - layout(location=0) emits error >= MAX_UNIFORM_LOCATIONS due to integer underflow</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83574">Bug 83574</a> - [llvmpipe] [softpipe] piglit arb_explicit_uniform_location-use-of-unused-loc regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=85454">Bug 85454</a> - Unigine Sanctuary with Wine crashes on Mesa Git</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=85918">Bug 85918</a> - Mesa: MSVC 2010/2012 Compile error</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Changes</h2>
|
||||
|
||||
<p>Anuj Phogat (2):</p>
|
||||
<ul>
|
||||
<li>glsl: Fix crash due to negative array index</li>
|
||||
<li>glsl: Use signed array index in update_max_array_access()</li>
|
||||
</ul>
|
||||
|
||||
<p>Brian Paul (1):</p>
|
||||
<ul>
|
||||
<li>mesa: fix UNCLAMPED_FLOAT_TO_UBYTE() macro for MSVC</li>
|
||||
</ul>
|
||||
|
||||
<p>Emil Velikov (2):</p>
|
||||
<ul>
|
||||
<li>docs: Add sha256 sums for the 10.3.2 release</li>
|
||||
<li>Update version to 10.3.3</li>
|
||||
</ul>
|
||||
|
||||
<p>Ilia Mirkin (27):</p>
|
||||
<ul>
|
||||
<li>freedreno/ir3: fix FSLT/etc handling to return 0/-1 instead of 0/1.0</li>
|
||||
<li>freedreno/ir3: INEG operates on src0, not src1</li>
|
||||
<li>freedreno/ir3: add UARL support</li>
|
||||
<li>freedreno/ir3: negate result of USLT/etc</li>
|
||||
<li>freedreno/ir3: use unsigned comparison for UIF</li>
|
||||
<li>freedreno/ir3: add TXL support</li>
|
||||
<li>freedreno/ir3: fix UCMP handling</li>
|
||||
<li>freedreno/ir3: implement UMUL correctly</li>
|
||||
<li>freedreno: add default .dir-locals.el for emacs settings</li>
|
||||
<li>freedreno/ir3: make texture instruction construction more dynamic</li>
|
||||
<li>freedreno/ir3: fix TXB/TXL to actually pull the bias/lod argument</li>
|
||||
<li>freedreno/ir3: add TXQ support</li>
|
||||
<li>freedreno/ir3: add TXB2 support</li>
|
||||
<li>freedreno: dual-source render targets are not supported</li>
|
||||
<li>freedreno: instanced drawing/compute not yet supported</li>
|
||||
<li>freedreno/ir3: avoid fan-in sources referring to same instruction</li>
|
||||
<li>freedreno/ir3: add IDIV/UDIV support</li>
|
||||
<li>freedreno/ir3: add UMOD support, based on UDIV</li>
|
||||
<li>freedreno/ir3: add MOD support</li>
|
||||
<li>freedreno/ir3: add ISSG support</li>
|
||||
<li>freedreno/ir3: add UMAD support</li>
|
||||
<li>freedreno/ir3: make TXQ return integers, not floats</li>
|
||||
<li>freedreno/ir3: shadow comes before array</li>
|
||||
<li>freedreno/ir3: add texture offset support</li>
|
||||
<li>freedreno/ir3: add TXD support and expose ARB_shader_texture_lod</li>
|
||||
<li>freedreno/ir3: add TXF support</li>
|
||||
<li>freedreno: positions come out as integers, not half-integers</li>
|
||||
</ul>
|
||||
|
||||
<p>Jan Vesely (1):</p>
|
||||
<ul>
|
||||
<li>configure: include llvm systemlibs when using static llvm</li>
|
||||
</ul>
|
||||
|
||||
<p>Marek Olšák (5):</p>
|
||||
<ul>
|
||||
<li>r600g: fix polygon mode for points and lines and point/line fill modes</li>
|
||||
<li>radeonsi: fix polygon mode for points and lines and point/line fill modes</li>
|
||||
<li>radeonsi: fix incorrect index buffer max size for lowered 8-bit indices</li>
|
||||
<li>Revert "st/mesa: set MaxUnrollIterations = 255"</li>
|
||||
<li>r300g: remove enabled/disabled hyperz and AA compression messages</li>
|
||||
</ul>
|
||||
|
||||
<p>Mauro Rossi (1):</p>
|
||||
<ul>
|
||||
<li>gallium/nouveau: fully build the driver under android</li>
|
||||
</ul>
|
||||
|
||||
<p>Michel Dänzer (1):</p>
|
||||
<ul>
|
||||
<li>radeon/llvm: Dynamically allocate branch/loop stack arrays</li>
|
||||
</ul>
|
||||
|
||||
<p>Rob Clark (62):</p>
|
||||
<ul>
|
||||
<li>freedreno/ir3: detect scheduler fail</li>
|
||||
<li>freedreno/ir3: add TXB</li>
|
||||
<li>freedreno/ir3: add DDX/DDY</li>
|
||||
<li>freedreno/ir3: bit of debug</li>
|
||||
<li>freedreno/ir3: fix error in bail logic</li>
|
||||
<li>freedreno/ir3: fix constlen with relative addressing</li>
|
||||
<li>freedreno/ir3: add no-copy-propagate fallback step</li>
|
||||
<li>freedreno: don't overflow cmdstream buffer so much</li>
|
||||
<li>freedreno/ir3: fix potential segfault in RA</li>
|
||||
<li>freedreno: update generated headers</li>
|
||||
<li>freedreno/a3xx: enable hw primitive-restart</li>
|
||||
<li>freedreno/a3xx: handle rendering to layer != 0</li>
|
||||
<li>freedreno: update generated headers</li>
|
||||
<li>freedreno/a3xx: format fixes</li>
|
||||
<li>util/u_format: add _is_alpha()</li>
|
||||
<li>freedreno/a3xx: alpha render-target shenanigans</li>
|
||||
<li>freedreno/ir3: catch incorrect usage of tmp-dst</li>
|
||||
<li>freedreno/ir3: add missing put_dst</li>
|
||||
<li>freedreno: "fix" problems with excessive flushes</li>
|
||||
<li>freedreno: update generated headers</li>
|
||||
<li>freedreno/a3xx: 3d/array textures</li>
|
||||
<li>freedreno: add DRM_CONF_SHARE_FD</li>
|
||||
<li>freedreno/a3xx: more texture array fixes</li>
|
||||
<li>freedreno/a3xx: initial texture border-color</li>
|
||||
<li>freedreno: fix compiler warning</li>
|
||||
<li>freedreno: don't advertise mirror-clamp support</li>
|
||||
<li>freedreno: update generated headers</li>
|
||||
<li>freedreno: we have more than 0 viewports!</li>
|
||||
<li>freedreno: turn missing caps into compile warnings</li>
|
||||
<li>freedreno/a3xx: add LOD_BIAS</li>
|
||||
<li>freedreno/a3xx: add flat interpolation mode</li>
|
||||
<li>freedreno/a3xx: add 32bit integer vtx formats</li>
|
||||
<li>freedreno/a3xx: fix border color order</li>
|
||||
<li>freedreno: move bind_sampler_states to per-generation</li>
|
||||
<li>freedreno: add texcoord clamp support to lowering</li>
|
||||
<li>freedreno/a3xx: add support to emulate GL_CLAMP</li>
|
||||
<li>freedreno/a3xx: re-emit shaders on variant change</li>
|
||||
<li>freedreno/lowering: fix token calculation for lowering</li>
|
||||
<li>freedreno: destroy transfer pool after blitter</li>
|
||||
<li>freedreno: max-texture-lod-bias should be 15.0f</li>
|
||||
<li>freedreno: update generated headers</li>
|
||||
<li>freedreno/a3xx: handle large shader program sizes</li>
|
||||
<li>freedreno/a3xx: emit all immediates in one shot</li>
|
||||
<li>freedreno/ir3: fix lockups with lame FRAG shaders</li>
|
||||
<li>freedreno/a3xx: handle VS only outputting BCOLOR</li>
|
||||
<li>freedreno: query fixes</li>
|
||||
<li>freedreno/a3xx: refactor vertex state emit</li>
|
||||
<li>freedreno/a3xx: refactor/optimize emit</li>
|
||||
<li>freedreno/ir3: optimize shader key comparision</li>
|
||||
<li>freedreno: inline fd_draw_emit()</li>
|
||||
<li>freedreno: fix layer_stride</li>
|
||||
<li>freedreno: update generated headers</li>
|
||||
<li>freedreno/ir3: large const support</li>
|
||||
<li>freedreno/a3xx: more layer/level fixes</li>
|
||||
<li>freedreno/ir3: comment + better fxn name</li>
|
||||
<li>freedreno/ir3: fix potential gpu lockup with kill</li>
|
||||
<li>freedreno/a3xx: disable early-z when we have kill's</li>
|
||||
<li>freedreno/ir3: add debug flag to disable cp</li>
|
||||
<li>freedreno: clear vs scissor</li>
|
||||
<li>freedreno: mark scissor state dirty when enable bit changes</li>
|
||||
<li>freedreno/a3xx: fix viewport state during clear</li>
|
||||
<li>freedreno/a3xx: fix depth/stencil restore format</li>
|
||||
</ul>
|
||||
|
||||
<p>Tapani Pälli (2):</p>
|
||||
<ul>
|
||||
<li>glsl: fix uniform location count used for glsl types</li>
|
||||
<li>mesa: check that uniform exists in glUniform* functions</li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@@ -14,7 +14,7 @@
|
||||
<iframe src="../contents.html"></iframe>
|
||||
<div class="content">
|
||||
|
||||
<h1>Mesa 10.3 Release Notes / TBD</h1>
|
||||
<h1>Mesa 10.3 Release Notes / September 19, 2014</h1>
|
||||
|
||||
<p>
|
||||
Mesa 10.3 is a new development release.
|
||||
@@ -31,9 +31,11 @@ because compatibility contexts are not supported.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>MD5 checksums</h2>
|
||||
<h2>SHA256 checksums</h2>
|
||||
<pre>
|
||||
TBD.
|
||||
9a1bf52040fc3dda81e83a35f944f1c3f532847dbe9fdf57161265cf71ea1bae MesaLib-10.3.0.tar.gz
|
||||
0283bfe710fa449ed82e465cfa09612a269e19abb7e0382082608062ce7960b5 MesaLib-10.3.0.tar.bz2
|
||||
221420763c2c3a244836a736e735612c4a6a0377b4e5223fca1e612f49906789 MesaLib-10.3.0.zip
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -75,7 +77,249 @@ DRM drivers that don't have a full-fledged GEM (such as qxl or simpledrm)</li>
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
|
||||
TBD.
|
||||
<ul>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=50754">Bug 50754</a> - Building 32 bit mesa on 64 bit OS fails since change for automake</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=53617">Bug 53617</a> - [llvmpipe] piglit fbo-depthtex regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=54372">Bug 54372</a> - GLX_INTEL_swap_event crashes driver when swapping window buffers</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=56127">Bug 56127</a> - [ILK bisected]unigine-sanctruary performance reduced by 98%</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66184">Bug 66184</a> - src/mesa/state_tracker/st_glsl_to_tgsi.cpp:3216:simplify_cmp: Assertion `inst->dst.index < 4096' failed.</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=66452">Bug 66452</a> - JUNIPER UVD accelerated playback of WMV3 streams does not work</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=68365">Bug 68365</a> - [SNB Bisected]Piglit spec_ARB_framebuffer_object_fbo-blit-stretch fail</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=70441">Bug 70441</a> - [Gen4-5 clip] Piglit spec_OpenGL_1.1_polygon-offset hits (execsize >= width) assertion</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=73846">Bug 73846</a> - [llvmpipe] lp_test_format fails with llvm-3.5svn >= r199602</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=74005">Bug 74005</a> - [i965 Bisected]Piglit/glx_glx-make-glxdrawable-current fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=74863">Bug 74863</a> - [r600g] HyperZ broken on RV770 and CYPRESS (Left 4 Dead 2 trees corruption) bisected!</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=75010">Bug 75010</a> - clang: error: unknown argument: '-fstack-protector-strong'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=75478">Bug 75478</a> - [BDW]Some Piglit and Ogles2conform cases cause GPU hang</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=75664">Bug 75664</a> - Unigine Valley & Heaven "error: syntax error, unexpected EXTENSION, expecting $end" IVB HD4000</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=75878">Bug 75878</a> - [BDW] GPU hang running Raytracer WebGL demo</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=76188">Bug 76188</a> - EGL_EXT_image_dma_buf_import fd ownership is incorrect</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=76223">Bug 76223</a> - [radeonsi] luxmark segfault</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=76939">Bug 76939</a> - [BDW] GPU hang when running “Metro:Last Light “ /“Crusader Kings II”</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77245">Bug 77245</a> - Bogus GL_ARB_explicit_attrib_location layout identifier warnings</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77493">Bug 77493</a> - lp_test_arit fails with llvm >= llvm-3.5svn r206094</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77703">Bug 77703</a> - [ILK Bisected]Piglit glean_texCombine4 fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77704">Bug 77704</a> - [IVB/HSW Bisected]Ogles3conform GL3Tests_shadow_shadow_execution_frag.test fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77705">Bug 77705</a> - [SNB/IVB/HSW/BYT/BDW Bisected]Ogles3conform GL3Tests/packed_pixels/packed_pixels_pixelstore.test segfault</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77707">Bug 77707</a> - [ILK Bisected]Ogles2conform GL_sin_sin_float_frag_xvary.test fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77740">Bug 77740</a> - i965: Relax accumulator dependency scheduling on Gen < 6</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77852">Bug 77852</a> - [BDW]Piglit spec_ARB_framebuffer_object_fbo-drawbuffers-none_glBlitFramebuffer fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77856">Bug 77856</a> - [BDW]Piglit spec_OpenGL_3.0_clearbuffer-mixed-format fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=77865">Bug 77865</a> - [BDW] Many Ogles3conform framebuffer_blit cases fail</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78225">Bug 78225</a> - Compile error due to undefined reference to `gbm_dri_backend', fix attached</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78258">Bug 78258</a> - make check link_varyings.gl_ClipDistance failure</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78403">Bug 78403</a> - query_renderer_implementation_unittest.cpp:144:4: error: expected primary-expression before ‘.’ token</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78468">Bug 78468</a> - Compiling of shader gets stuck in infinite loop</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78537">Bug 78537</a> - no anisotropic filtering in a native Half-Life 2</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78546">Bug 78546</a> - [swrast] piglit copyteximage-border regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78581">Bug 78581</a> - OpenCL: clBuildProgram prints error messages directly rather than storing them</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78648">Bug 78648</a> - Texture artifacts in Kerbal Space Program</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78665">Bug 78665</a> - macros in builtin_functions.cpp make invalid assumptions about M_PI definitions</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78679">Bug 78679</a> - Gen4-5 code lost: runtime_check_aads_emit</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78691">Bug 78691</a> - [G45 - Tesseract] Mesa 10.1.2 implementation error: Unsupported opcode 169872468 in FS</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78692">Bug 78692</a> - Football Manager 2014, gameplay rendered black & white</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78716">Bug 78716</a> - Fix Mesa bugs for running Unreal Engine 4.1 Cave effects demo compiled for Linux</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78803">Bug 78803</a> - gallivm/lp_bld_debug.cpp:42:28: fatal error: llvm/IR/Module.h: No such file or directory</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78842">Bug 78842</a> - [swrast] piglit fcc-read-after-clear copy rb regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78843">Bug 78843</a> - [swrast] piglit copyteximage 1D regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78872">Bug 78872</a> - [ILK Bisected]Piglit spec_ARB_depth_buffer_float_fbo-depthstencil-GL_DEPTH32F_STENCIL8-blit Aborted</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78875">Bug 78875</a> - [ILK Bisected]Webglc conformance/uniforms/uniform-default-values.html fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=78888">Bug 78888</a> - test_eu_compact.c:54:3: error: implicit declaration of function ‘brw_disasm’ [-Werror=implicit-function-declaration]</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79029">Bug 79029</a> - INTEL_DEBUG=shader_time is full of lies</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79095">Bug 79095</a> - x86/common_x86.c:348:14: error: use of undeclared identifier 'bit_SSE4_1'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79115">Bug 79115</a> - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0) doesn't unbind stencil buffer</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79263">Bug 79263</a> - Linking error in egl_gallium.la when compiling 32 bit on multiarch</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79294">Bug 79294</a> - Xlib-based build broken on non x86/x86-64 architectures</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79373">Bug 79373</a> - Non-const initializers for matrix and vector constructors</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79382">Bug 79382</a> - build error: multiple definition of `loader_get_pci_id_for_fd'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79421">Bug 79421</a> - [llvmpipe] SIGSEGV src/gallium/drivers/llvmpipe/lp_rast_priv.h:218</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79440">Bug 79440</a> - prog_hash_table.c:146: undefined reference to `_mesa_error_no_memory'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79469">Bug 79469</a> - Commit e3cc0d90e14e62a0a787b6c07a6df0f5c84039be breaks unigine heaven</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79534">Bug 79534</a> - gen<7 renders garbage</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79616">Bug 79616</a> - L4D2 crash on startup</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79724">Bug 79724</a> - switch statement type check</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79729">Bug 79729</a> - [i965] glClear on a multisample texture doesn't work</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79809">Bug 79809</a> - radeonsi: mouse cursor corruption using weston on AMD Kaveri</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79823">Bug 79823</a> - [NV30/gallium] Mozilla apps freeze on startup with nouveau-dri-10.2.1 libs on dual-screen</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79885">Bug 79885</a> - commit b52a530 (gallium/egl: st_profiles are build time decision, treat them as such) broke egl</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79903">Bug 79903</a> - [HSW Bisected]Some Piglit and Ogles2conform cases fail</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79907">Bug 79907</a> - Mesa 10.2.1 --enable-vdpau default=auto broken</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=79948">Bug 79948</a> - [i965] Incorrect pixels when using discard and uniform loads</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80015">Bug 80015</a> - Transparency glitches in native Civilization 5 (Civ5) port</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80115">Bug 80115</a> - MESA_META_DRAW_BUFFERS induced GL_INVALID_VALUE errors</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80211">Bug 80211</a> - [ILK/SNB Bisected]Piglit shaders_glsl-fs-copy-propagation-texcoords-1 fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80247">Bug 80247</a> - Khronos conformance test ES3-CTS.gtf.GL3Tests.transform_feedback.transform_feedback_vertex_id fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80254">Bug 80254</a> - pipe_loader_sw.c:90: undefined reference to `dri_create_sw_winsys'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80541">Bug 80541</a> - [softpipe] piglit levelclamp regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80561">Bug 80561</a> - Incorrect implementation of some VDPAU APIs.</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80614">Bug 80614</a> - [regression] Error in `omxregister-bellagio': munmap_chunk(): invalid pointer: 0x00007f5f76626dab</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80778">Bug 80778</a> - [bisected regression] piglit spec/glsl-1.50/compiler/incorrect-in-layout-qualifier-repeated-prim.geom</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80827">Bug 80827</a> - [radeonsi,R9 270X] Corruptions in window menus in KDE</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80880">Bug 80880</a> - Unreal Engine 4 demos fail GLSL compiler assertion</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=80991">Bug 80991</a> - [BDW]Piglit spec_ARB_sample_shading_builtin-gl-sample-mask_2 fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81020">Bug 81020</a> - [radeonsi][regresssion] Wireframe of background rendered through objects in Half-Life 2: Episode 2 with MSAA enabled</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81150">Bug 81150</a> - [SNB]Piglit spec_arb_shading_language_packing_execution_built-in-functions_fs-packSnorm4x8 fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81157">Bug 81157</a> - [BDW]Piglit some spec_glsl-1.50_execution_built-in-functions* cases fail</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81450">Bug 81450</a> - [BDW]Piglit spec_glsl-1.30_execution_tex-miplevel-selection_textureGrad_1DArray cases intel_do_flush_locked failed</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81828">Bug 81828</a> - [BDW Bisected]Ogles3conform GL3Tests_packed_pixels_packed_pixels_pbo.test fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81834">Bug 81834</a> - TGSI constant buffer overrun causes assertion failure</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81857">Bug 81857</a> - [SNB+]Piglit spec_glsl-1.30_execution_switch_fs-default_last sporadically fail</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=81967">Bug 81967</a> - [regression] Selections in Blender renders wrong</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82139">Bug 82139</a> - [r600g, bisected] multiple ubo piglit regressions</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82159">Bug 82159</a> - No rule to make target `../../../../src/mesa/libmesa.la', needed by `collision'.</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82255">Bug 82255</a> - [VP2] Chroma planes are vertically stretched during VDPAU playback</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82268">Bug 82268</a> - Add support for the OpenRISC architecture (or1k)</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82428">Bug 82428</a> - [radeonsi,R9 270X] System lockup when using mplayer/mpv with VDPAU</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82472">Bug 82472</a> - piglit 16385-consecutive-chars regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82483">Bug 82483</a> - format_srgb.h:145: undefined reference to `util_format_srgb_to_linear_8unorm_table'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82517">Bug 82517</a> - [RADEONSI,VDPAU] SIGSEGV in map_msg_fb_buf called from ruvd_destroy, when closing a Tab with accelerated video player</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82534">Bug 82534</a> - src\egl\main\eglapi.h : fatal error LNK1107: invalid or corrupt file: cannot read at 0x2E02</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82536">Bug 82536</a> - u_current.h:72: undefined reference to `__imp__glapi_Dispatch'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82538">Bug 82538</a> - Super Maryo Chronicles fails with st/mesa assertion failure</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82539">Bug 82539</a> - vmw_screen_dri.lo In file included from vmw_screen_dri.c:41: vmwgfx_drm.h:32:17: error: drm.h: No such file or directory</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82546">Bug 82546</a> - [regression] libOSMesa build failure</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82574">Bug 82574</a> - GLSL: opt_vectorize goes wrong on texture lookups</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82628">Bug 82628</a> - bisected: GALLIUM_HUD hangs radeon 7970M (PRIME)</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82671">Bug 82671</a> - [r600g-evergreen][compute]Empty kernel execution causes crash</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82709">Bug 82709</a> - OpenCL not working on radeon hainan</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82796">Bug 82796</a> - [IVB/BYT-M/HSW/BDW Bisected]Synmark2_v6.0_OglTerrainFlyInst/OglTerrainPanInst cannot run as image validation failed</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82804">Bug 82804</a> - unreal engine 4 rendering errors</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82814">Bug 82814</a> - glDrawBuffers(0, NULL) segfaults in _mesa_drawbuffers</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82828">Bug 82828</a> - Regression: Crash in 3Dmark2001</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82846">Bug 82846</a> - [BDW Bisected] Gpu hang when running Lightsmark v2008/Warsow v1.0/Xonotic v0.7/unigine-demos</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82881">Bug 82881</a> - test_vec4_register_coalesce regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82882">Bug 82882</a> - [swrast] piglit glsl-fs-uniform-bool-1 regression</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82929">Bug 82929</a> - [BDW Bisected]glxgears causes X hang</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=82932">Bug 82932</a> - [SNB+ Bisected]Ogles3conform ES3-CTS.shaders.indexing.vector_subscript.vec3_static_loop_subscript_write_direct_read_vertex fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83046">Bug 83046</a> - [BDW bisected]] Warsow v1.0/Xonotic v0.7/Gputest v0.5_triangle_fullscreen/synmark2_v6/GLBenchmark v2.5.0/GLBenchmark v2.7.0/Ungine-demos performance reduced 30%~60%</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83079">Bug 83079</a> - [NVC0] Dota 2 (Linux native and Wine) crash with Nouveau Drivers</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83081">Bug 83081</a> - [BDW Bisected]Piglit spec_ARB_sample_shading_builtin-gl-sample-mask_2 is core dumped</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83127">Bug 83127</a> - [ILK Bisected]Piglit glean_texCombine fails</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83355">Bug 83355</a> - FTBFS: src/mesa/program/program_lexer.l:122:64: error: unknown type name 'YYSTYPE'</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83432">Bug 83432</a> - r600_query.c:269:r600_emit_query_end: Assertion `ctx->num_pipelinestat_queries > 0' failed [Gallium HUD]</li>
|
||||
|
||||
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=83468">Bug 83468</a> - [UBO] Using bool from UBO as if-statement condition asserts</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Changes</h2>
|
||||
|
||||
|
@@ -38,6 +38,7 @@ CHIPSET(0x6828, VERDE_6828, VERDE)
|
||||
CHIPSET(0x6829, VERDE_6829, VERDE)
|
||||
CHIPSET(0x682A, VERDE_682A, VERDE)
|
||||
CHIPSET(0x682B, VERDE_682B, VERDE)
|
||||
CHIPSET(0x682C, VERDE_682C, VERDE)
|
||||
CHIPSET(0x682D, VERDE_682D, VERDE)
|
||||
CHIPSET(0x682F, VERDE_682F, VERDE)
|
||||
CHIPSET(0x6830, VERDE_6830, VERDE)
|
||||
@@ -54,8 +55,11 @@ CHIPSET(0x6600, OLAND_6600, OLAND)
|
||||
CHIPSET(0x6601, OLAND_6601, OLAND)
|
||||
CHIPSET(0x6602, OLAND_6602, OLAND)
|
||||
CHIPSET(0x6603, OLAND_6603, OLAND)
|
||||
CHIPSET(0x6604, OLAND_6604, OLAND)
|
||||
CHIPSET(0x6605, OLAND_6605, OLAND)
|
||||
CHIPSET(0x6606, OLAND_6606, OLAND)
|
||||
CHIPSET(0x6607, OLAND_6607, OLAND)
|
||||
CHIPSET(0x6608, OLAND_6608, OLAND)
|
||||
CHIPSET(0x6610, OLAND_6610, OLAND)
|
||||
CHIPSET(0x6611, OLAND_6611, OLAND)
|
||||
CHIPSET(0x6613, OLAND_6613, OLAND)
|
||||
@@ -73,6 +77,8 @@ CHIPSET(0x666F, HAINAN_666F, HAINAN)
|
||||
|
||||
CHIPSET(0x6640, BONAIRE_6640, BONAIRE)
|
||||
CHIPSET(0x6641, BONAIRE_6641, BONAIRE)
|
||||
CHIPSET(0x6646, BONAIRE_6646, BONAIRE)
|
||||
CHIPSET(0x6647, BONAIRE_6647, BONAIRE)
|
||||
CHIPSET(0x6649, BONAIRE_6649, BONAIRE)
|
||||
CHIPSET(0x6650, BONAIRE_6650, BONAIRE)
|
||||
CHIPSET(0x6651, BONAIRE_6651, BONAIRE)
|
||||
@@ -132,6 +138,7 @@ CHIPSET(0x1313, KAVERI_1313, KAVERI)
|
||||
CHIPSET(0x1315, KAVERI_1315, KAVERI)
|
||||
CHIPSET(0x1316, KAVERI_1316, KAVERI)
|
||||
CHIPSET(0x1317, KAVERI_1317, KAVERI)
|
||||
CHIPSET(0x1318, KAVERI_1318, KAVERI)
|
||||
CHIPSET(0x131B, KAVERI_131B, KAVERI)
|
||||
CHIPSET(0x131C, KAVERI_131C, KAVERI)
|
||||
CHIPSET(0x131D, KAVERI_131D, KAVERI)
|
||||
|
@@ -681,6 +681,7 @@ dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp)
|
||||
i + 1, EGL_WINDOW_BIT, attr_list, NULL);
|
||||
}
|
||||
|
||||
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
|
||||
if (dri2_dpy->dri2)
|
||||
disp->Extensions.EXT_buffer_age = EGL_TRUE;
|
||||
|
||||
|
@@ -143,6 +143,7 @@ LOCAL_STATIC_LIBRARIES := \
|
||||
libmesa_st_egl \
|
||||
$(gallium_DRIVERS) \
|
||||
libmesa_st_mesa \
|
||||
libmesa_util \
|
||||
libmesa_glsl \
|
||||
libmesa_glsl_utils \
|
||||
libmesa_gallium \
|
||||
|
@@ -30,7 +30,9 @@ include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := $(C_SOURCES)
|
||||
|
||||
LOCAL_C_INCLUDES := $(GALLIUM_TOP)/auxiliary/util
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(GALLIUM_TOP)/auxiliary/util \
|
||||
$(MESA_TOP)/src
|
||||
|
||||
LOCAL_MODULE := libmesa_gallium
|
||||
|
||||
|
@@ -1850,7 +1850,7 @@ lp_build_trunc(struct lp_build_context *bld,
|
||||
const struct lp_type type = bld->type;
|
||||
struct lp_type inttype;
|
||||
struct lp_build_context intbld;
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 1<<24);
|
||||
LLVMValueRef trunc, res, anosign, mask;
|
||||
LLVMTypeRef int_vec_type = bld->int_vec_type;
|
||||
LLVMTypeRef vec_type = bld->vec_type;
|
||||
@@ -1905,7 +1905,7 @@ lp_build_round(struct lp_build_context *bld,
|
||||
const struct lp_type type = bld->type;
|
||||
struct lp_type inttype;
|
||||
struct lp_build_context intbld;
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 1<<24);
|
||||
LLVMValueRef res, anosign, mask;
|
||||
LLVMTypeRef int_vec_type = bld->int_vec_type;
|
||||
LLVMTypeRef vec_type = bld->vec_type;
|
||||
@@ -1958,7 +1958,7 @@ lp_build_floor(struct lp_build_context *bld,
|
||||
const struct lp_type type = bld->type;
|
||||
struct lp_type inttype;
|
||||
struct lp_build_context intbld;
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 1<<24);
|
||||
LLVMValueRef trunc, res, anosign, mask;
|
||||
LLVMTypeRef int_vec_type = bld->int_vec_type;
|
||||
LLVMTypeRef vec_type = bld->vec_type;
|
||||
@@ -2027,7 +2027,7 @@ lp_build_ceil(struct lp_build_context *bld,
|
||||
const struct lp_type type = bld->type;
|
||||
struct lp_type inttype;
|
||||
struct lp_build_context intbld;
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 2^24);
|
||||
LLVMValueRef cmpval = lp_build_const_vec(bld->gallivm, type, 1<<24);
|
||||
LLVMValueRef trunc, res, anosign, mask, tmp;
|
||||
LLVMTypeRef int_vec_type = bld->int_vec_type;
|
||||
LLVMTypeRef vec_type = bld->vec_type;
|
||||
|
@@ -464,6 +464,7 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
if((util_cpu_caps.has_sse2 || util_cpu_caps.has_altivec) &&
|
||||
src_type.width * src_type.length >= 128) {
|
||||
const char *intrinsic = NULL;
|
||||
boolean swap_intrinsic_operands = FALSE;
|
||||
|
||||
switch(src_type.width) {
|
||||
case 32:
|
||||
@@ -482,6 +483,9 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
} else {
|
||||
intrinsic = "llvm.ppc.altivec.vpkuwus";
|
||||
}
|
||||
#ifdef PIPE_ARCH_LITTLE_ENDIAN
|
||||
swap_intrinsic_operands = TRUE;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
@@ -490,12 +494,18 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
intrinsic = "llvm.x86.sse2.packsswb.128";
|
||||
} else if (util_cpu_caps.has_altivec) {
|
||||
intrinsic = "llvm.ppc.altivec.vpkshss";
|
||||
#ifdef PIPE_ARCH_LITTLE_ENDIAN
|
||||
swap_intrinsic_operands = TRUE;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (util_cpu_caps.has_sse2) {
|
||||
intrinsic = "llvm.x86.sse2.packuswb.128";
|
||||
} else if (util_cpu_caps.has_altivec) {
|
||||
intrinsic = "llvm.ppc.altivec.vpkshus";
|
||||
#ifdef PIPE_ARCH_LITTLE_ENDIAN
|
||||
swap_intrinsic_operands = TRUE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -504,7 +514,11 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
if (intrinsic) {
|
||||
if (src_type.width * src_type.length == 128) {
|
||||
LLVMTypeRef intr_vec_type = lp_build_vec_type(gallivm, intr_type);
|
||||
res = lp_build_intrinsic_binary(builder, intrinsic, intr_vec_type, lo, hi);
|
||||
if (swap_intrinsic_operands) {
|
||||
res = lp_build_intrinsic_binary(builder, intrinsic, intr_vec_type, hi, lo);
|
||||
} else {
|
||||
res = lp_build_intrinsic_binary(builder, intrinsic, intr_vec_type, lo, hi);
|
||||
}
|
||||
if (dst_vec_type != intr_vec_type) {
|
||||
res = LLVMBuildBitCast(builder, res, dst_vec_type, "");
|
||||
}
|
||||
@@ -513,6 +527,8 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
int num_split = src_type.width * src_type.length / 128;
|
||||
int i;
|
||||
int nlen = 128 / src_type.width;
|
||||
int lo_off = swap_intrinsic_operands ? nlen : 0;
|
||||
int hi_off = swap_intrinsic_operands ? 0 : nlen;
|
||||
struct lp_type ndst_type = lp_type_unorm(dst_type.width, 128);
|
||||
struct lp_type nintr_type = lp_type_unorm(intr_type.width, 128);
|
||||
LLVMValueRef tmpres[LP_MAX_VECTOR_WIDTH / 128];
|
||||
@@ -524,9 +540,9 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
|
||||
for (i = 0; i < num_split / 2; i++) {
|
||||
tmplo = lp_build_extract_range(gallivm,
|
||||
lo, i*nlen*2, nlen);
|
||||
lo, i*nlen*2 + lo_off, nlen);
|
||||
tmphi = lp_build_extract_range(gallivm,
|
||||
lo, i*nlen*2 + nlen, nlen);
|
||||
lo, i*nlen*2 + hi_off, nlen);
|
||||
tmpres[i] = lp_build_intrinsic_binary(builder, intrinsic,
|
||||
nintr_vec_type, tmplo, tmphi);
|
||||
if (ndst_vec_type != nintr_vec_type) {
|
||||
@@ -535,9 +551,9 @@ lp_build_pack2(struct gallivm_state *gallivm,
|
||||
}
|
||||
for (i = 0; i < num_split / 2; i++) {
|
||||
tmplo = lp_build_extract_range(gallivm,
|
||||
hi, i*nlen*2, nlen);
|
||||
hi, i*nlen*2 + lo_off, nlen);
|
||||
tmphi = lp_build_extract_range(gallivm,
|
||||
hi, i*nlen*2 + nlen, nlen);
|
||||
hi, i*nlen*2 + hi_off, nlen);
|
||||
tmpres[i+num_split/2] = lp_build_intrinsic_binary(builder, intrinsic,
|
||||
nintr_vec_type,
|
||||
tmplo, tmphi);
|
||||
|
@@ -1248,8 +1248,24 @@ idiv_emit_cpu(
|
||||
struct lp_build_tgsi_context * bld_base,
|
||||
struct lp_build_emit_data * emit_data)
|
||||
{
|
||||
emit_data->output[emit_data->chan] = lp_build_div(&bld_base->int_bld,
|
||||
emit_data->args[0], emit_data->args[1]);
|
||||
LLVMBuilderRef builder = bld_base->base.gallivm->builder;
|
||||
LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint_bld,
|
||||
PIPE_FUNC_EQUAL, emit_data->args[1],
|
||||
bld_base->uint_bld.zero);
|
||||
/* We want to make sure that we never divide/mod by zero to not
|
||||
* generate sigfpe. We don't want to crash just because the
|
||||
* shader is doing something weird. */
|
||||
LLVMValueRef divisor = LLVMBuildOr(builder,
|
||||
div_mask,
|
||||
emit_data->args[1], "");
|
||||
LLVMValueRef result = lp_build_div(&bld_base->int_bld,
|
||||
emit_data->args[0], divisor);
|
||||
LLVMValueRef not_div_mask = LLVMBuildNot(builder,
|
||||
div_mask,"");
|
||||
/* idiv by zero doesn't have a guaranteed return value chose 0 for now. */
|
||||
emit_data->output[emit_data->chan] = LLVMBuildAnd(builder,
|
||||
not_div_mask,
|
||||
result, "");
|
||||
}
|
||||
|
||||
/* TGSI_OPCODE_INEG (CPU Only) */
|
||||
@@ -1675,15 +1691,15 @@ udiv_emit_cpu(
|
||||
LLVMValueRef div_mask = lp_build_cmp(&bld_base->uint_bld,
|
||||
PIPE_FUNC_EQUAL, emit_data->args[1],
|
||||
bld_base->uint_bld.zero);
|
||||
/* We want to make sure that we never divide/mod by zero to not
|
||||
* generate sigfpe. We don't want to crash just because the
|
||||
/* We want to make sure that we never divide/mod by zero to not
|
||||
* generate sigfpe. We don't want to crash just because the
|
||||
* shader is doing something weird. */
|
||||
LLVMValueRef divisor = LLVMBuildOr(builder,
|
||||
div_mask,
|
||||
emit_data->args[1], "");
|
||||
LLVMValueRef result = lp_build_div(&bld_base->uint_bld,
|
||||
emit_data->args[0], divisor);
|
||||
/* udiv by zero is guaranteed to return 0xffffffff */
|
||||
/* udiv by zero is guaranteed to return 0xffffffff at least with d3d10 */
|
||||
emit_data->output[emit_data->chan] = LLVMBuildOr(builder,
|
||||
div_mask,
|
||||
result, "");
|
||||
|
@@ -465,7 +465,7 @@ dd_configuration(enum drm_conf conf)
|
||||
#endif
|
||||
#if defined(GALLIUM_FREEDRENO)
|
||||
if ((strcmp(driver_name, "kgsl") == 0) || (strcmp(driver_name, "msm") == 0))
|
||||
return NULL;
|
||||
return configuration_query(conf);
|
||||
else
|
||||
#endif
|
||||
return NULL;
|
||||
|
@@ -3340,10 +3340,10 @@ micro_idiv(union tgsi_exec_channel *dst,
|
||||
const union tgsi_exec_channel *src0,
|
||||
const union tgsi_exec_channel *src1)
|
||||
{
|
||||
dst->i[0] = src0->i[0] / src1->i[0];
|
||||
dst->i[1] = src0->i[1] / src1->i[1];
|
||||
dst->i[2] = src0->i[2] / src1->i[2];
|
||||
dst->i[3] = src0->i[3] / src1->i[3];
|
||||
dst->i[0] = src1->i[0] ? src0->i[0] / src1->i[0] : 0;
|
||||
dst->i[1] = src1->i[1] ? src0->i[1] / src1->i[1] : 0;
|
||||
dst->i[2] = src1->i[2] ? src0->i[2] / src1->i[2] : 0;
|
||||
dst->i[3] = src1->i[3] ? src0->i[3] / src1->i[3] : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -91,6 +91,23 @@ util_format_is_luminance(enum pipe_format format)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
boolean
|
||||
util_format_is_alpha(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(format);
|
||||
|
||||
if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB ||
|
||||
desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) &&
|
||||
desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_0 &&
|
||||
desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0 &&
|
||||
desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0 &&
|
||||
desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
boolean
|
||||
util_format_is_pure_integer(enum pipe_format format)
|
||||
{
|
||||
|
@@ -661,6 +661,8 @@ util_format_has_alpha(enum pipe_format format);
|
||||
boolean
|
||||
util_format_is_luminance(enum pipe_format format);
|
||||
|
||||
boolean
|
||||
util_format_is_alpha(enum pipe_format format);
|
||||
|
||||
boolean
|
||||
util_format_is_luminance_alpha(enum pipe_format format);
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -1060,6 +1060,7 @@ vl_compositor_render(struct vl_compositor_state *s,
|
||||
s->scissor.maxx = dst_surface->width;
|
||||
s->scissor.maxy = dst_surface->height;
|
||||
}
|
||||
c->pipe->set_scissor_states(c->pipe, 0, 1, &s->scissor);
|
||||
|
||||
gen_vertex_data(c, s, dirty_area);
|
||||
|
||||
@@ -1072,7 +1073,6 @@ vl_compositor_render(struct vl_compositor_state *s,
|
||||
dirty_area->x1 = dirty_area->y1 = MIN_DIRTY;
|
||||
}
|
||||
|
||||
c->pipe->set_scissor_states(c->pipe, 0, 1, &s->scissor);
|
||||
c->pipe->set_framebuffer_state(c->pipe, &c->fb_state);
|
||||
c->pipe->bind_vs_state(c->pipe, c->vs);
|
||||
c->pipe->set_vertex_buffers(c->pipe, 0, 1, &c->vertex_buf);
|
||||
|
8
src/gallium/drivers/freedreno/.dir-locals.el
Normal file
8
src/gallium/drivers/freedreno/.dir-locals.el
Normal file
@@ -0,0 +1,8 @@
|
||||
((nil
|
||||
(indent-tabs-mode . true)
|
||||
(tab-width . 4)
|
||||
(c-basic-offset . 4)
|
||||
(c-file-style . "k&r")
|
||||
(fill-column . 78)
|
||||
)
|
||||
)
|
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-07-19 17:20:53)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-07-19 17:21:17)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 36670 bytes, from 2014-07-19 17:18:34)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10347 bytes, from 2014-10-01 18:55:57)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 60533 bytes, from 2014-10-15 18:32:43)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48)
|
||||
|
||||
Copyright (C) 2013-2014 by the following authors:
|
||||
- Rob Clark <robdclark@gmail.com> (robclark)
|
||||
@@ -1243,13 +1243,13 @@ static inline uint32_t A2XX_CLEAR_COLOR_ALPHA(uint32_t val)
|
||||
#define A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT 0
|
||||
static inline uint32_t A2XX_PA_SU_POINT_SIZE_HEIGHT(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK;
|
||||
}
|
||||
#define A2XX_PA_SU_POINT_SIZE_WIDTH__MASK 0xffff0000
|
||||
#define A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT 16
|
||||
static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK;
|
||||
}
|
||||
|
||||
#define REG_A2XX_PA_SU_POINT_MINMAX 0x00002281
|
||||
@@ -1257,13 +1257,13 @@ static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val)
|
||||
#define A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT 0
|
||||
static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MIN(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK;
|
||||
}
|
||||
#define A2XX_PA_SU_POINT_MINMAX_MAX__MASK 0xffff0000
|
||||
#define A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT 16
|
||||
static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK;
|
||||
}
|
||||
|
||||
#define REG_A2XX_PA_SU_LINE_CNTL 0x00002282
|
||||
@@ -1271,7 +1271,7 @@ static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val)
|
||||
#define A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT 0
|
||||
static inline uint32_t A2XX_PA_SU_LINE_CNTL_WIDTH(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK;
|
||||
}
|
||||
|
||||
#define REG_A2XX_PA_SC_LINE_STIPPLE 0x00002283
|
||||
|
@@ -98,6 +98,7 @@ fd2_context_create(struct pipe_screen *pscreen, void *priv)
|
||||
pctx = &fd2_ctx->base.base;
|
||||
|
||||
fd2_ctx->base.dev = fd_device_ref(screen->dev);
|
||||
fd2_ctx->base.screen = fd_screen(pscreen);
|
||||
|
||||
pctx->destroy = fd2_context_destroy;
|
||||
pctx->create_blend_state = fd2_blend_state_create;
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "util/u_string.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "util/u_pack_color.h"
|
||||
|
||||
#include "freedreno_state.h"
|
||||
#include "freedreno_resource.h"
|
||||
@@ -57,8 +56,8 @@ emit_cacheflush(struct fd_ringbuffer *ring)
|
||||
static void
|
||||
emit_vertexbufs(struct fd_context *ctx)
|
||||
{
|
||||
struct fd_vertex_stateobj *vtx = ctx->vtx;
|
||||
struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
|
||||
struct fd_vertex_stateobj *vtx = ctx->vtx.vtx;
|
||||
struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vtx.vertexbuf;
|
||||
struct fd2_vertex_buf bufs[PIPE_MAX_ATTRIBS];
|
||||
unsigned i;
|
||||
|
||||
@@ -118,14 +117,6 @@ fd2_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
pack_rgba(enum pipe_format format, const float *rgba)
|
||||
{
|
||||
union util_color uc;
|
||||
util_pack_color(rgba, format, &uc);
|
||||
return uc.ui[0];
|
||||
}
|
||||
|
||||
static void
|
||||
fd2_clear(struct fd_context *ctx, unsigned buffers,
|
||||
const union pipe_color_union *color, double depth, unsigned stencil)
|
||||
|
@@ -317,10 +317,10 @@ fd2_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
|
||||
OUT_RING(ring, CP_REG(REG_A2XX_PA_CL_CLIP_CNTL));
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
|
||||
if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
|
||||
emit_mem2gmem_surf(ctx, bin_w * bin_h, pfb->zsbuf);
|
||||
|
||||
if (ctx->restore & FD_BUFFER_COLOR)
|
||||
if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR))
|
||||
emit_mem2gmem_surf(ctx, 0, pfb->cbufs[0]);
|
||||
|
||||
/* TODO blob driver seems to toss in a CACHE_FLUSH after each DRAW_INDX.. */
|
||||
|
@@ -174,7 +174,7 @@ patch_vtx_fetches(struct fd_context *ctx, struct fd2_shader_stateobj *so,
|
||||
struct ir2_instruction *instr = so->vfetch_instrs[i];
|
||||
struct pipe_vertex_element *elem = &vtx->pipe[i];
|
||||
struct pipe_vertex_buffer *vb =
|
||||
&ctx->vertexbuf.vb[elem->vertex_buffer_index];
|
||||
&ctx->vtx.vertexbuf.vb[elem->vertex_buffer_index];
|
||||
enum pipe_format format = elem->src_format;
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(format);
|
||||
@@ -258,7 +258,7 @@ fd2_program_validate(struct fd_context *ctx)
|
||||
|
||||
/* if necessary, fix up vertex fetch instructions: */
|
||||
if (ctx->dirty & (FD_DIRTY_VTXSTATE | FD_DIRTY_PROG))
|
||||
patch_vtx_fetches(ctx, prog->vp, ctx->vtx);
|
||||
patch_vtx_fetches(ctx, prog->vp, ctx->vtx.vtx);
|
||||
|
||||
/* if necessary, fix up texture fetch instructions: */
|
||||
if (ctx->dirty & (FD_DIRTY_TEXSTATE | FD_DIRTY_PROG)) {
|
||||
|
@@ -101,6 +101,25 @@ fd2_sampler_state_create(struct pipe_context *pctx,
|
||||
return so;
|
||||
}
|
||||
|
||||
static void
|
||||
fd2_sampler_states_bind(struct pipe_context *pctx,
|
||||
unsigned shader, unsigned start,
|
||||
unsigned nr, void **hwcso)
|
||||
{
|
||||
if (shader == PIPE_SHADER_FRAGMENT) {
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
|
||||
/* on a2xx, since there is a flat address space for textures/samplers,
|
||||
* a change in # of fragment textures/samplers will trigger patching and
|
||||
* re-emitting the vertex shader:
|
||||
*/
|
||||
if (nr != ctx->fragtex.num_samplers)
|
||||
ctx->dirty |= FD_DIRTY_TEXSTATE;
|
||||
}
|
||||
|
||||
fd_sampler_states_bind(pctx, shader, start, nr, hwcso);
|
||||
}
|
||||
|
||||
static struct pipe_sampler_view *
|
||||
fd2_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
const struct pipe_sampler_view *cso)
|
||||
@@ -154,5 +173,6 @@ void
|
||||
fd2_texture_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->create_sampler_state = fd2_sampler_state_create;
|
||||
pctx->bind_sampler_states = fd2_sampler_states_bind;
|
||||
pctx->create_sampler_view = fd2_sampler_view_create;
|
||||
}
|
||||
|
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-07-19 17:20:53)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-07-19 17:21:17)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 36670 bytes, from 2014-07-19 17:18:34)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10347 bytes, from 2014-10-01 18:55:57)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 60533 bytes, from 2014-10-15 18:32:43)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48)
|
||||
|
||||
Copyright (C) 2013-2014 by the following authors:
|
||||
- Rob Clark <robdclark@gmail.com> (robclark)
|
||||
@@ -86,6 +86,14 @@ enum a3xx_vtx_fmt {
|
||||
VFMT_NORM_USHORT_16_16 = 29,
|
||||
VFMT_NORM_USHORT_16_16_16 = 30,
|
||||
VFMT_NORM_USHORT_16_16_16_16 = 31,
|
||||
VFMT_UINT_32 = 32,
|
||||
VFMT_UINT_32_32 = 33,
|
||||
VFMT_UINT_32_32_32 = 34,
|
||||
VFMT_UINT_32_32_32_32 = 35,
|
||||
VFMT_INT_32 = 36,
|
||||
VFMT_INT_32_32 = 37,
|
||||
VFMT_INT_32_32_32 = 38,
|
||||
VFMT_INT_32_32_32_32 = 39,
|
||||
VFMT_UBYTE_8 = 40,
|
||||
VFMT_UBYTE_8_8 = 41,
|
||||
VFMT_UBYTE_8_8_8 = 42,
|
||||
@@ -112,6 +120,7 @@ enum a3xx_tex_fmt {
|
||||
TFMT_NORM_USHORT_565 = 4,
|
||||
TFMT_NORM_USHORT_5551 = 6,
|
||||
TFMT_NORM_USHORT_4444 = 7,
|
||||
TFMT_NORM_USHORT_Z16 = 9,
|
||||
TFMT_NORM_UINT_X8Z24 = 10,
|
||||
TFMT_NORM_UINT_NV12_UV_TILED = 17,
|
||||
TFMT_NORM_UINT_NV12_Y_TILED = 19,
|
||||
@@ -149,6 +158,7 @@ enum a3xx_color_fmt {
|
||||
RB_R8G8B8A8_UNORM = 8,
|
||||
RB_Z16_UNORM = 12,
|
||||
RB_A8_UNORM = 20,
|
||||
RB_R8_UNORM = 21,
|
||||
RB_R16G16B16A16_FLOAT = 27,
|
||||
RB_R32G32B32A32_FLOAT = 51,
|
||||
};
|
||||
@@ -194,6 +204,11 @@ enum a3xx_rb_blend_opcode {
|
||||
BLEND_MAX_DST_SRC = 4,
|
||||
};
|
||||
|
||||
enum a3xx_intp_mode {
|
||||
SMOOTH = 0,
|
||||
FLAT = 1,
|
||||
};
|
||||
|
||||
enum a3xx_tex_filter {
|
||||
A3XX_TEX_NEAREST = 0,
|
||||
A3XX_TEX_LINEAR = 1,
|
||||
@@ -632,13 +647,13 @@ static inline uint32_t A3XX_GRAS_CL_VPORT_ZSCALE(float val)
|
||||
#define A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT 0
|
||||
static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MIN(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MIN__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A3XX_GRAS_SU_POINT_MINMAX_MIN__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MIN__MASK;
|
||||
}
|
||||
#define A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK 0xffff0000
|
||||
#define A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT 16
|
||||
static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MAX(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK;
|
||||
return ((((uint32_t)(val * 16.0))) << A3XX_GRAS_SU_POINT_MINMAX_MAX__SHIFT) & A3XX_GRAS_SU_POINT_MINMAX_MAX__MASK;
|
||||
}
|
||||
|
||||
#define REG_A3XX_GRAS_SU_POINT_SIZE 0x00002069
|
||||
@@ -646,7 +661,7 @@ static inline uint32_t A3XX_GRAS_SU_POINT_MINMAX_MAX(float val)
|
||||
#define A3XX_GRAS_SU_POINT_SIZE__SHIFT 0
|
||||
static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 8.0))) << A3XX_GRAS_SU_POINT_SIZE__SHIFT) & A3XX_GRAS_SU_POINT_SIZE__MASK;
|
||||
return ((((int32_t)(val * 16.0))) << A3XX_GRAS_SU_POINT_SIZE__SHIFT) & A3XX_GRAS_SU_POINT_SIZE__MASK;
|
||||
}
|
||||
|
||||
#define REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE 0x0000206c
|
||||
@@ -654,7 +669,7 @@ static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val)
|
||||
#define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT 0
|
||||
static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 28.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK;
|
||||
return ((((int32_t)(val * 16384.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK;
|
||||
}
|
||||
|
||||
#define REG_A3XX_GRAS_SU_POLY_OFFSET_OFFSET 0x0000206d
|
||||
@@ -662,7 +677,7 @@ static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val)
|
||||
#define A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT 0
|
||||
static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_OFFSET(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 28.0))) << A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK;
|
||||
return ((((int32_t)(val * 16384.0))) << A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK;
|
||||
}
|
||||
|
||||
#define REG_A3XX_GRAS_SU_MODE_CONTROL 0x00002070
|
||||
@@ -673,7 +688,7 @@ static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_OFFSET(float val)
|
||||
#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3
|
||||
static inline uint32_t A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 4.0))) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
|
||||
return ((((int32_t)(val * 4.0))) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
|
||||
}
|
||||
#define A3XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800
|
||||
|
||||
@@ -1265,6 +1280,7 @@ static inline uint32_t A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(enum adreno_pa_
|
||||
{
|
||||
return ((val) << A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__SHIFT) & A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__MASK;
|
||||
}
|
||||
#define A3XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART 0x00100000
|
||||
#define A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST 0x02000000
|
||||
#define A3XX_PC_PRIM_VTX_CNTL_PSIZE 0x04000000
|
||||
|
||||
@@ -1281,7 +1297,12 @@ static inline uint32_t A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(enum a3xx_threadsize
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_SPSHADERRESTART 0x00000200
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_RESERVED2 0x00000400
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_CHUNKDISABLE 0x04000000
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_CONSTSWITCHMODE 0x08000000
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__MASK 0x08000000
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__SHIFT 27
|
||||
static inline uint32_t A3XX_HLSQ_CONTROL_0_REG_CONSTMODE(uint32_t val)
|
||||
{
|
||||
return ((val) << A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__SHIFT) & A3XX_HLSQ_CONTROL_0_REG_CONSTMODE__MASK;
|
||||
}
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_LAZYUPDATEDISABLE 0x10000000
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE 0x20000000
|
||||
#define A3XX_HLSQ_CONTROL_0_REG_TPFULLUPDATE 0x40000000
|
||||
@@ -1537,6 +1558,7 @@ static inline uint32_t A3XX_VFD_DECODE_INSTR_REGID(uint32_t val)
|
||||
{
|
||||
return ((val) << A3XX_VFD_DECODE_INSTR_REGID__SHIFT) & A3XX_VFD_DECODE_INSTR_REGID__MASK;
|
||||
}
|
||||
#define A3XX_VFD_DECODE_INSTR_INT 0x00100000
|
||||
#define A3XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000
|
||||
#define A3XX_VFD_DECODE_INSTR_SWAP__SHIFT 22
|
||||
static inline uint32_t A3XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val)
|
||||
@@ -1604,6 +1626,102 @@ static inline uint32_t A3XX_VPC_PACK_NUMNONPOSVSVAR(uint32_t val)
|
||||
static inline uint32_t REG_A3XX_VPC_VARYING_INTERP(uint32_t i0) { return 0x00002282 + 0x1*i0; }
|
||||
|
||||
static inline uint32_t REG_A3XX_VPC_VARYING_INTERP_MODE(uint32_t i0) { return 0x00002282 + 0x1*i0; }
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C0__MASK 0x00000003
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C0__SHIFT 0
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C0(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C0__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C0__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C1__MASK 0x0000000c
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C1__SHIFT 2
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C1(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C1__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C1__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C2__MASK 0x00000030
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C2__SHIFT 4
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C2(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C2__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C2__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C3__MASK 0x000000c0
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C3__SHIFT 6
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C3(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C3__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C3__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C4__MASK 0x00000300
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C4__SHIFT 8
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C4(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C4__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C4__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C5__MASK 0x00000c00
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C5__SHIFT 10
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C5(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C5__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C5__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C6__MASK 0x00003000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C6__SHIFT 12
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C6(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C6__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C6__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C7__MASK 0x0000c000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C7__SHIFT 14
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C7(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C7__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C7__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C8__MASK 0x00030000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C8__SHIFT 16
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C8(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C8__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C8__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C9__MASK 0x000c0000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_C9__SHIFT 18
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_C9(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_C9__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_C9__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CA__MASK 0x00300000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CA__SHIFT 20
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CA(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CA__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CA__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CB__MASK 0x00c00000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CB__SHIFT 22
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CB(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CB__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CB__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CC__MASK 0x03000000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CC__SHIFT 24
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CC(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CC__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CC__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CD__MASK 0x0c000000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CD__SHIFT 26
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CD(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CD__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CD__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CE__MASK 0x30000000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CE__SHIFT 28
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CE(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CE__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CE__MASK;
|
||||
}
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CF__MASK 0xc0000000
|
||||
#define A3XX_VPC_VARYING_INTERP_MODE_CF__SHIFT 30
|
||||
static inline uint32_t A3XX_VPC_VARYING_INTERP_MODE_CF(enum a3xx_intp_mode val)
|
||||
{
|
||||
return ((val) << A3XX_VPC_VARYING_INTERP_MODE_CF__SHIFT) & A3XX_VPC_VARYING_INTERP_MODE_CF__MASK;
|
||||
}
|
||||
|
||||
static inline uint32_t REG_A3XX_VPC_VARYING_PS_REPL(uint32_t i0) { return 0x00002286 + 0x1*i0; }
|
||||
|
||||
@@ -1696,7 +1814,7 @@ static inline uint32_t A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(uint32_t val)
|
||||
{
|
||||
return ((val) << A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT__SHIFT) & A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT__MASK;
|
||||
}
|
||||
#define A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__MASK 0x3f000000
|
||||
#define A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__MASK 0x7f000000
|
||||
#define A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__SHIFT 24
|
||||
static inline uint32_t A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(uint32_t val)
|
||||
{
|
||||
@@ -2347,17 +2465,23 @@ static inline uint32_t A3XX_TEX_SAMP_0_COMPARE_FUNC(enum adreno_compare_func val
|
||||
#define A3XX_TEX_SAMP_0_UNNORM_COORDS 0x80000000
|
||||
|
||||
#define REG_A3XX_TEX_SAMP_1 0x00000001
|
||||
#define A3XX_TEX_SAMP_1_LOD_BIAS__MASK 0x000007ff
|
||||
#define A3XX_TEX_SAMP_1_LOD_BIAS__SHIFT 0
|
||||
static inline uint32_t A3XX_TEX_SAMP_1_LOD_BIAS(float val)
|
||||
{
|
||||
return ((((int32_t)(val * 64.0))) << A3XX_TEX_SAMP_1_LOD_BIAS__SHIFT) & A3XX_TEX_SAMP_1_LOD_BIAS__MASK;
|
||||
}
|
||||
#define A3XX_TEX_SAMP_1_MAX_LOD__MASK 0x003ff000
|
||||
#define A3XX_TEX_SAMP_1_MAX_LOD__SHIFT 12
|
||||
static inline uint32_t A3XX_TEX_SAMP_1_MAX_LOD(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 12.0))) << A3XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A3XX_TEX_SAMP_1_MAX_LOD__MASK;
|
||||
return ((((uint32_t)(val * 64.0))) << A3XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A3XX_TEX_SAMP_1_MAX_LOD__MASK;
|
||||
}
|
||||
#define A3XX_TEX_SAMP_1_MIN_LOD__MASK 0xffc00000
|
||||
#define A3XX_TEX_SAMP_1_MIN_LOD__SHIFT 22
|
||||
static inline uint32_t A3XX_TEX_SAMP_1_MIN_LOD(float val)
|
||||
{
|
||||
return ((((uint32_t)(val * 12.0))) << A3XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A3XX_TEX_SAMP_1_MIN_LOD__MASK;
|
||||
return ((((uint32_t)(val * 64.0))) << A3XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A3XX_TEX_SAMP_1_MIN_LOD__MASK;
|
||||
}
|
||||
|
||||
#define REG_A3XX_TEX_CONST_0 0x00000000
|
||||
@@ -2448,6 +2572,24 @@ static inline uint32_t A3XX_TEX_CONST_2_SWAP(enum a3xx_color_swap val)
|
||||
}
|
||||
|
||||
#define REG_A3XX_TEX_CONST_3 0x00000003
|
||||
#define A3XX_TEX_CONST_3_LAYERSZ1__MASK 0x0000000f
|
||||
#define A3XX_TEX_CONST_3_LAYERSZ1__SHIFT 0
|
||||
static inline uint32_t A3XX_TEX_CONST_3_LAYERSZ1(uint32_t val)
|
||||
{
|
||||
return ((val >> 12) << A3XX_TEX_CONST_3_LAYERSZ1__SHIFT) & A3XX_TEX_CONST_3_LAYERSZ1__MASK;
|
||||
}
|
||||
#define A3XX_TEX_CONST_3_DEPTH__MASK 0x0ffe0000
|
||||
#define A3XX_TEX_CONST_3_DEPTH__SHIFT 17
|
||||
static inline uint32_t A3XX_TEX_CONST_3_DEPTH(uint32_t val)
|
||||
{
|
||||
return ((val) << A3XX_TEX_CONST_3_DEPTH__SHIFT) & A3XX_TEX_CONST_3_DEPTH__MASK;
|
||||
}
|
||||
#define A3XX_TEX_CONST_3_LAYERSZ2__MASK 0xf0000000
|
||||
#define A3XX_TEX_CONST_3_LAYERSZ2__SHIFT 28
|
||||
static inline uint32_t A3XX_TEX_CONST_3_LAYERSZ2(uint32_t val)
|
||||
{
|
||||
return ((val >> 12) << A3XX_TEX_CONST_3_LAYERSZ2__SHIFT) & A3XX_TEX_CONST_3_LAYERSZ2__MASK;
|
||||
}
|
||||
|
||||
|
||||
#endif /* A3XX_XML */
|
||||
|
@@ -49,6 +49,9 @@ fd3_context_destroy(struct pipe_context *pctx)
|
||||
fd_bo_del(fd3_ctx->fs_pvt_mem);
|
||||
fd_bo_del(fd3_ctx->vsc_size_mem);
|
||||
|
||||
pctx->delete_vertex_elements_state(pctx, fd3_ctx->solid_vbuf_state.vtx);
|
||||
pctx->delete_vertex_elements_state(pctx, fd3_ctx->blit_vbuf_state.vtx);
|
||||
|
||||
pipe_resource_reference(&fd3_ctx->solid_vbuf, NULL);
|
||||
pipe_resource_reference(&fd3_ctx->blit_texcoord_vbuf, NULL);
|
||||
|
||||
@@ -135,7 +138,38 @@ fd3_context_create(struct pipe_screen *pscreen, void *priv)
|
||||
fd3_ctx->solid_vbuf = create_solid_vertexbuf(pctx);
|
||||
fd3_ctx->blit_texcoord_vbuf = create_blit_texcoord_vertexbuf(pctx);
|
||||
|
||||
/* setup solid_vbuf_state: */
|
||||
fd3_ctx->solid_vbuf_state.vtx = pctx->create_vertex_elements_state(
|
||||
pctx, 1, (struct pipe_vertex_element[]){{
|
||||
.vertex_buffer_index = 0,
|
||||
.src_offset = 0,
|
||||
.src_format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}});
|
||||
fd3_ctx->solid_vbuf_state.vertexbuf.count = 1;
|
||||
fd3_ctx->solid_vbuf_state.vertexbuf.vb[0].stride = 12;
|
||||
fd3_ctx->solid_vbuf_state.vertexbuf.vb[0].buffer = fd3_ctx->solid_vbuf;
|
||||
|
||||
/* setup blit_vbuf_state: */
|
||||
fd3_ctx->blit_vbuf_state.vtx = pctx->create_vertex_elements_state(
|
||||
pctx, 2, (struct pipe_vertex_element[]){{
|
||||
.vertex_buffer_index = 0,
|
||||
.src_offset = 0,
|
||||
.src_format = PIPE_FORMAT_R32G32_FLOAT,
|
||||
}, {
|
||||
.vertex_buffer_index = 1,
|
||||
.src_offset = 0,
|
||||
.src_format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}});
|
||||
fd3_ctx->blit_vbuf_state.vertexbuf.count = 2;
|
||||
fd3_ctx->blit_vbuf_state.vertexbuf.vb[0].stride = 8;
|
||||
fd3_ctx->blit_vbuf_state.vertexbuf.vb[0].buffer = fd3_ctx->blit_texcoord_vbuf;
|
||||
fd3_ctx->blit_vbuf_state.vertexbuf.vb[1].stride = 12;
|
||||
fd3_ctx->blit_vbuf_state.vertexbuf.vb[1].buffer = fd3_ctx->solid_vbuf;
|
||||
|
||||
fd3_query_context_init(pctx);
|
||||
|
||||
fd3_ctx->border_color_uploader = u_upload_create(pctx, 4096,
|
||||
2 * PIPE_MAX_SAMPLERS * BORDERCOLOR_SIZE, 0);
|
||||
|
||||
return pctx;
|
||||
}
|
||||
|
@@ -29,10 +29,15 @@
|
||||
#ifndef FD3_CONTEXT_H_
|
||||
#define FD3_CONTEXT_H_
|
||||
|
||||
#include "util/u_upload_mgr.h"
|
||||
|
||||
#include "freedreno_drmif.h"
|
||||
|
||||
#include "freedreno_context.h"
|
||||
|
||||
#include "ir3_shader.h"
|
||||
|
||||
|
||||
struct fd3_context {
|
||||
struct fd_context base;
|
||||
|
||||
@@ -56,6 +61,55 @@ struct fd3_context {
|
||||
/* vertex buf used for mem->gmem tex coords:
|
||||
*/
|
||||
struct pipe_resource *blit_texcoord_vbuf;
|
||||
|
||||
/* vertex state for solid_vbuf:
|
||||
* - solid_vbuf / 12 / R32G32B32_FLOAT
|
||||
*/
|
||||
struct fd_vertex_state solid_vbuf_state;
|
||||
|
||||
/* vertex state for blit_prog:
|
||||
* - blit_texcoord_vbuf / 8 / R32G32_FLOAT
|
||||
* - solid_vbuf / 12 / R32G32B32_FLOAT
|
||||
*/
|
||||
struct fd_vertex_state blit_vbuf_state;
|
||||
|
||||
|
||||
/*
|
||||
* Border color layout *appears* to be as arrays of 0x40 byte
|
||||
* elements, with frag shader elements starting at (16 x 0x40).
|
||||
* But at some point I should probably experiment more with
|
||||
* samplers in vertex shaders to be sure. Unclear about why
|
||||
* there is this offset when there are separate VS and FS base
|
||||
* addr regs.
|
||||
*
|
||||
* The first 8 bytes of each entry are the requested border
|
||||
* color in fp16. Unclear about the rest.. could be used for
|
||||
* other formats, or could simply be for aligning the pitch
|
||||
* to 32 pixels.
|
||||
*/
|
||||
#define BORDERCOLOR_SIZE 0x40
|
||||
|
||||
struct u_upload_mgr *border_color_uploader;
|
||||
struct pipe_resource *border_color_buf;
|
||||
|
||||
/* if *any* of bits are set in {v,f}saturate_{s,t,r} */
|
||||
bool vsaturate, fsaturate;
|
||||
|
||||
/* bitmask of sampler which needs coords clamped for vertex
|
||||
* shader:
|
||||
*/
|
||||
unsigned vsaturate_s, vsaturate_t, vsaturate_r;
|
||||
|
||||
/* bitmask of sampler which needs coords clamped for frag
|
||||
* shader:
|
||||
*/
|
||||
unsigned fsaturate_s, fsaturate_t, fsaturate_r;
|
||||
|
||||
/* some state changes require a different shader variant. Keep
|
||||
* track of this so we know when we need to re-emit shader state
|
||||
* due to variant change. See fixup_shader_state()
|
||||
*/
|
||||
struct ir3_shader_key last_key;
|
||||
};
|
||||
|
||||
static INLINE struct fd3_context *
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "util/u_string.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_prim.h"
|
||||
#include "util/u_format.h"
|
||||
|
||||
#include "freedreno_state.h"
|
||||
#include "freedreno_resource.h"
|
||||
@@ -43,39 +44,15 @@
|
||||
|
||||
|
||||
static void
|
||||
emit_vertexbufs(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
struct ir3_shader_key key)
|
||||
draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
struct fd3_emit *emit)
|
||||
{
|
||||
struct fd_vertex_stateobj *vtx = ctx->vtx;
|
||||
struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
|
||||
struct fd3_vertex_buf bufs[PIPE_MAX_ATTRIBS];
|
||||
unsigned i;
|
||||
const struct pipe_draw_info *info = emit->info;
|
||||
|
||||
if (!vtx->num_elements)
|
||||
return;
|
||||
fd3_emit_state(ctx, ring, emit);
|
||||
|
||||
for (i = 0; i < vtx->num_elements; i++) {
|
||||
struct pipe_vertex_element *elem = &vtx->pipe[i];
|
||||
struct pipe_vertex_buffer *vb =
|
||||
&vertexbuf->vb[elem->vertex_buffer_index];
|
||||
bufs[i].offset = vb->buffer_offset + elem->src_offset;
|
||||
bufs[i].stride = vb->stride;
|
||||
bufs[i].prsc = vb->buffer;
|
||||
bufs[i].format = elem->src_format;
|
||||
}
|
||||
|
||||
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->prog.vp, key),
|
||||
bufs, vtx->num_elements);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
|
||||
struct fd_ringbuffer *ring, unsigned dirty, struct ir3_shader_key key)
|
||||
{
|
||||
fd3_emit_state(ctx, ring, &ctx->prog, dirty, key);
|
||||
|
||||
if (dirty & FD_DIRTY_VTXBUF)
|
||||
emit_vertexbufs(ctx, ring, key);
|
||||
if (emit->dirty & (FD_DIRTY_VTXBUF | FD_DIRTY_VTXSTATE))
|
||||
fd3_emit_vertex_bufs(ring, emit);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, 1);
|
||||
OUT_RING(ring, 0x0000000b); /* PC_VERTEX_REUSE_BLOCK_CNTL */
|
||||
@@ -91,27 +68,103 @@ draw_impl(struct fd_context *ctx, const struct pipe_draw_info *info,
|
||||
info->restart_index : 0xffffffff);
|
||||
|
||||
fd_draw_emit(ctx, ring,
|
||||
key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
|
||||
emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
|
||||
info);
|
||||
}
|
||||
|
||||
/* fixup dirty shader state in case some "unrelated" (from the state-
|
||||
* tracker's perspective) state change causes us to switch to a
|
||||
* different variant.
|
||||
*/
|
||||
static void
|
||||
fixup_shader_state(struct fd_context *ctx, struct ir3_shader_key *key)
|
||||
{
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
struct ir3_shader_key *last_key = &fd3_ctx->last_key;
|
||||
|
||||
if (!ir3_shader_key_equal(last_key, key)) {
|
||||
ctx->dirty |= FD_DIRTY_PROG;
|
||||
|
||||
if (last_key->has_per_samp || key->has_per_samp) {
|
||||
if ((last_key->vsaturate_s != key->vsaturate_s) ||
|
||||
(last_key->vsaturate_t != key->vsaturate_t) ||
|
||||
(last_key->vsaturate_r != key->vsaturate_r))
|
||||
ctx->prog.dirty |= FD_SHADER_DIRTY_VP;
|
||||
|
||||
if ((last_key->fsaturate_s != key->fsaturate_s) ||
|
||||
(last_key->fsaturate_t != key->fsaturate_t) ||
|
||||
(last_key->fsaturate_r != key->fsaturate_r))
|
||||
ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
|
||||
}
|
||||
|
||||
if (last_key->color_two_side != key->color_two_side)
|
||||
ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
|
||||
|
||||
if (last_key->half_precision != key->half_precision)
|
||||
ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
|
||||
|
||||
if (last_key->alpha != key->alpha)
|
||||
ctx->prog.dirty |= FD_SHADER_DIRTY_FP;
|
||||
|
||||
fd3_ctx->last_key = *key;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
|
||||
{
|
||||
unsigned dirty = ctx->dirty;
|
||||
struct ir3_shader_key key = {
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
struct fd3_emit emit = {
|
||||
.vtx = &ctx->vtx,
|
||||
.prog = &ctx->prog,
|
||||
.info = info,
|
||||
.key = {
|
||||
/* do binning pass first: */
|
||||
.binning_pass = true,
|
||||
.color_two_side = ctx->rasterizer ? ctx->rasterizer->light_twoside : false,
|
||||
.alpha = util_format_is_alpha(pipe_surface_format(ctx->framebuffer.cbufs[0])),
|
||||
// TODO set .half_precision based on render target format,
|
||||
// ie. float16 and smaller use half, float32 use full..
|
||||
.half_precision = !!(fd_mesa_debug & FD_DBG_FRAGHALF),
|
||||
.has_per_samp = fd3_ctx->fsaturate || fd3_ctx->vsaturate,
|
||||
.vsaturate_s = fd3_ctx->vsaturate_s,
|
||||
.vsaturate_t = fd3_ctx->vsaturate_t,
|
||||
.vsaturate_r = fd3_ctx->vsaturate_r,
|
||||
.fsaturate_s = fd3_ctx->fsaturate_s,
|
||||
.fsaturate_t = fd3_ctx->fsaturate_t,
|
||||
.fsaturate_r = fd3_ctx->fsaturate_r,
|
||||
},
|
||||
.rasterflat = ctx->rasterizer && ctx->rasterizer->flatshade,
|
||||
};
|
||||
draw_impl(ctx, info, ctx->binning_ring,
|
||||
dirty & ~(FD_DIRTY_BLEND), key);
|
||||
unsigned dirty;
|
||||
|
||||
fixup_shader_state(ctx, &emit.key);
|
||||
|
||||
dirty = ctx->dirty;
|
||||
emit.dirty = dirty & ~(FD_DIRTY_BLEND);
|
||||
draw_impl(ctx, ctx->binning_ring, &emit);
|
||||
|
||||
/* and now regular (non-binning) pass: */
|
||||
key.binning_pass = false;
|
||||
draw_impl(ctx, info, ctx->ring, dirty, key);
|
||||
emit.key.binning_pass = false;
|
||||
emit.dirty = dirty;
|
||||
emit.vp = NULL; /* we changed key so need to refetch vp */
|
||||
draw_impl(ctx, ctx->ring, &emit);
|
||||
}
|
||||
|
||||
/* clear operations ignore viewport state, so we need to reset it
|
||||
* based on framebuffer state:
|
||||
*/
|
||||
static void
|
||||
reset_viewport(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb)
|
||||
{
|
||||
float half_width = pfb->width * 0.5f;
|
||||
float half_height = pfb->height * 0.5f;
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_XOFFSET, 4);
|
||||
OUT_RING(ring, A3XX_GRAS_CL_VPORT_XOFFSET(half_width - 0.5));
|
||||
OUT_RING(ring, A3XX_GRAS_CL_VPORT_XSCALE(half_width));
|
||||
OUT_RING(ring, A3XX_GRAS_CL_VPORT_YOFFSET(half_height - 0.5));
|
||||
OUT_RING(ring, A3XX_GRAS_CL_VPORT_YSCALE(-half_height));
|
||||
}
|
||||
|
||||
/* binning pass cmds for a clear:
|
||||
@@ -127,19 +180,19 @@ fd3_clear_binning(struct fd_context *ctx, unsigned dirty)
|
||||
{
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
struct fd_ringbuffer *ring = ctx->binning_ring;
|
||||
struct ir3_shader_key key = {
|
||||
struct fd3_emit emit = {
|
||||
.vtx = &fd3_ctx->solid_vbuf_state,
|
||||
.prog = &ctx->solid_prog,
|
||||
.key = {
|
||||
.binning_pass = true,
|
||||
.half_precision = true,
|
||||
},
|
||||
.dirty = dirty,
|
||||
};
|
||||
|
||||
fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, key);
|
||||
|
||||
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
|
||||
(struct fd3_vertex_buf[]) {{
|
||||
.prsc = fd3_ctx->solid_vbuf,
|
||||
.stride = 12,
|
||||
.format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}}, 1);
|
||||
fd3_emit_state(ctx, ring, &emit);
|
||||
fd3_emit_vertex_bufs(ring, &emit);
|
||||
reset_viewport(ring, &ctx->framebuffer);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
|
||||
OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
|
||||
@@ -168,17 +221,23 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
|
||||
struct fd_ringbuffer *ring = ctx->ring;
|
||||
unsigned dirty = ctx->dirty;
|
||||
unsigned ce, i;
|
||||
struct ir3_shader_key key = {
|
||||
struct fd3_emit emit = {
|
||||
.vtx = &fd3_ctx->solid_vbuf_state,
|
||||
.prog = &ctx->solid_prog,
|
||||
.key = {
|
||||
.half_precision = true,
|
||||
},
|
||||
};
|
||||
|
||||
dirty &= FD_DIRTY_VIEWPORT | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
|
||||
dirty &= FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR;
|
||||
dirty |= FD_DIRTY_PROG;
|
||||
emit.dirty = dirty;
|
||||
|
||||
fd3_clear_binning(ctx, dirty);
|
||||
|
||||
/* emit generic state now: */
|
||||
fd3_emit_state(ctx, ring, &ctx->solid_prog, dirty, key);
|
||||
fd3_emit_state(ctx, ring, &emit);
|
||||
reset_viewport(ring, &ctx->framebuffer);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
|
||||
OUT_RING(ring, A3XX_RB_BLEND_ALPHA_UINT(0xff) |
|
||||
@@ -269,12 +328,7 @@ fd3_clear(struct fd_context *ctx, unsigned buffers,
|
||||
OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
|
||||
OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
|
||||
|
||||
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
|
||||
(struct fd3_vertex_buf[]) {{
|
||||
.prsc = fd3_ctx->solid_vbuf,
|
||||
.stride = 12,
|
||||
.format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}}, 1);
|
||||
fd3_emit_vertex_bufs(ring, &emit);
|
||||
|
||||
fd3_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
|
||||
|
||||
|
@@ -92,14 +92,13 @@ emit_constants(struct fd_ringbuffer *ring,
|
||||
uint32_t enabled_mask = constbuf->enabled_mask;
|
||||
uint32_t first_immediate;
|
||||
uint32_t base = 0;
|
||||
unsigned i;
|
||||
|
||||
// XXX TODO only emit dirty consts.. but we need to keep track if
|
||||
// they are clobbered by a clear, gmem2mem, or mem2gmem..
|
||||
constbuf->dirty_mask = enabled_mask;
|
||||
|
||||
/* in particular, with binning shader and a unneeded consts no
|
||||
* longer referenced, we could end up w/ constlen that is smaller
|
||||
/* in particular, with binning shader we may end up with unused
|
||||
* consts, ie. we could end up w/ constlen that is smaller
|
||||
* than first_immediate. In that case truncate the user consts
|
||||
* early to avoid HLSQ lockup caused by writing too many consts
|
||||
*/
|
||||
@@ -137,12 +136,21 @@ emit_constants(struct fd_ringbuffer *ring,
|
||||
|
||||
/* emit shader immediates: */
|
||||
if (shader) {
|
||||
for (i = 0; i < shader->immediates_count; i++) {
|
||||
base = 4 * (shader->first_immediate + i);
|
||||
if (base >= (4 * shader->constlen))
|
||||
break;
|
||||
int size = shader->immediates_count;
|
||||
base = shader->first_immediate;
|
||||
|
||||
/* truncate size to avoid writing constants that shader
|
||||
* does not use:
|
||||
*/
|
||||
size = MIN2(size + base, shader->constlen) - base;
|
||||
|
||||
/* convert out of vec4: */
|
||||
base *= 4;
|
||||
size *= 4;
|
||||
|
||||
if (size > 0) {
|
||||
fd3_emit_constant(ring, sb, base,
|
||||
0, 4, shader->immediates[i].val, NULL);
|
||||
0, size, shader->immediates[0].val, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,9 +160,8 @@ emit_constants(struct fd_ringbuffer *ring,
|
||||
#define BASETABLE_SZ A3XX_MAX_MIP_LEVELS
|
||||
|
||||
static void
|
||||
emit_textures(struct fd_ringbuffer *ring,
|
||||
enum adreno_state_block sb,
|
||||
struct fd_texture_stateobj *tex)
|
||||
emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
enum adreno_state_block sb, struct fd_texture_stateobj *tex)
|
||||
{
|
||||
static const unsigned tex_off[] = {
|
||||
[SB_VERT_TEX] = VERT_TEX_OFF,
|
||||
@@ -164,7 +171,18 @@ emit_textures(struct fd_ringbuffer *ring,
|
||||
[SB_VERT_TEX] = SB_VERT_MIPADDR,
|
||||
[SB_FRAG_TEX] = SB_FRAG_MIPADDR,
|
||||
};
|
||||
unsigned i, j;
|
||||
static const uint32_t bcolor_reg[] = {
|
||||
[SB_VERT_TEX] = REG_A3XX_TPL1_TP_VS_BORDER_COLOR_BASE_ADDR,
|
||||
[SB_FRAG_TEX] = REG_A3XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR,
|
||||
};
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
unsigned i, j, off;
|
||||
void *ptr;
|
||||
|
||||
u_upload_alloc(fd3_ctx->border_color_uploader,
|
||||
0, 2 * PIPE_MAX_SAMPLERS * BORDERCOLOR_SIZE, &off,
|
||||
&fd3_ctx->border_color_buf,
|
||||
&ptr);
|
||||
|
||||
if (tex->num_samplers > 0) {
|
||||
/* output sampler state: */
|
||||
@@ -180,6 +198,15 @@ emit_textures(struct fd_ringbuffer *ring,
|
||||
const struct fd3_sampler_stateobj *sampler = tex->samplers[i] ?
|
||||
fd3_sampler_stateobj(tex->samplers[i]) :
|
||||
&dummy_sampler;
|
||||
uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
|
||||
(BORDERCOLOR_SIZE * tex_off[sb]) +
|
||||
(BORDERCOLOR_SIZE * i));
|
||||
|
||||
bcolor[0] = util_float_to_half(sampler->base.border_color.f[2]);
|
||||
bcolor[1] = util_float_to_half(sampler->base.border_color.f[1]);
|
||||
bcolor[2] = util_float_to_half(sampler->base.border_color.f[0]);
|
||||
bcolor[3] = util_float_to_half(sampler->base.border_color.f[3]);
|
||||
|
||||
OUT_RING(ring, sampler->texsamp0);
|
||||
OUT_RING(ring, sampler->texsamp1);
|
||||
}
|
||||
@@ -215,14 +242,19 @@ emit_textures(struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
|
||||
CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
|
||||
for (i = 0; i < tex->num_textures; i++) {
|
||||
static const struct fd3_pipe_sampler_view dummy_view = {};
|
||||
static const struct fd3_pipe_sampler_view dummy_view = {
|
||||
.base.u.tex.first_level = 1,
|
||||
};
|
||||
const struct fd3_pipe_sampler_view *view = tex->textures[i] ?
|
||||
fd3_pipe_sampler_view(tex->textures[i]) :
|
||||
&dummy_view;
|
||||
struct fd_resource *rsc = view->tex_resource;
|
||||
unsigned start = view->base.u.tex.first_level;
|
||||
unsigned end = view->base.u.tex.last_level;
|
||||
|
||||
for (j = 0; j < view->mipaddrs; j++) {
|
||||
struct fd_resource_slice *slice = fd_resource_slice(rsc, j);
|
||||
for (j = 0; j < (end - start + 1); j++) {
|
||||
struct fd_resource_slice *slice =
|
||||
fd_resource_slice(rsc, j + start);
|
||||
OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
|
||||
}
|
||||
|
||||
@@ -232,18 +264,31 @@ emit_textures(struct fd_ringbuffer *ring,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OUT_PKT0(ring, bcolor_reg[sb], 1);
|
||||
OUT_RELOC(ring, fd_resource(fd3_ctx->border_color_buf)->bo, off, 0, 0);
|
||||
|
||||
u_upload_unmap(fd3_ctx->border_color_uploader);
|
||||
}
|
||||
|
||||
/* emit texture state for mem->gmem restore operation.. eventually it would
|
||||
* be good to get rid of this and use normal CSO/etc state for more of these
|
||||
* special cases, but for now the compiler is not sufficient..
|
||||
*
|
||||
* Also, for using normal state, not quite sure how to handle the special
|
||||
* case format (fd3_gmem_restore_format()) stuff for restoring depth/stencil.
|
||||
*/
|
||||
void
|
||||
fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf)
|
||||
{
|
||||
struct fd_resource *rsc = fd_resource(psurf->texture);
|
||||
unsigned lvl = psurf->u.tex.level;
|
||||
struct fd_resource_slice *slice = &rsc->slices[lvl];
|
||||
uint32_t layer_offset = slice->size0 * psurf->u.tex.first_layer;
|
||||
enum pipe_format format = fd3_gmem_restore_format(psurf->format);
|
||||
|
||||
debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
|
||||
|
||||
/* output sampler state: */
|
||||
OUT_PKT3(ring, CP_LOAD_STATE, 4);
|
||||
OUT_RING(ring, CP_LOAD_STATE_0_DST_OFF(FRAG_TEX_OFF) |
|
||||
@@ -267,14 +312,14 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf
|
||||
CP_LOAD_STATE_0_NUM_UNIT(1));
|
||||
OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
|
||||
CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
|
||||
OUT_RING(ring, A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(psurf->format)) |
|
||||
OUT_RING(ring, A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(format)) |
|
||||
A3XX_TEX_CONST_0_TYPE(A3XX_TEX_2D) |
|
||||
fd3_tex_swiz(format, PIPE_SWIZZLE_RED, PIPE_SWIZZLE_GREEN,
|
||||
PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA));
|
||||
OUT_RING(ring, A3XX_TEX_CONST_1_FETCHSIZE(TFETCH_DISABLE) |
|
||||
A3XX_TEX_CONST_1_WIDTH(psurf->width) |
|
||||
A3XX_TEX_CONST_1_HEIGHT(psurf->height));
|
||||
OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(rsc->slices[0].pitch * rsc->cpp) |
|
||||
OUT_RING(ring, A3XX_TEX_CONST_2_PITCH(slice->pitch * rsc->cpp) |
|
||||
A3XX_TEX_CONST_2_INDX(0));
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
@@ -286,18 +331,21 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf
|
||||
CP_LOAD_STATE_0_NUM_UNIT(1));
|
||||
OUT_RING(ring, CP_LOAD_STATE_1_STATE_TYPE(ST_CONSTANTS) |
|
||||
CP_LOAD_STATE_1_EXT_SRC_ADDR(0));
|
||||
OUT_RELOC(ring, rsc->bo, 0, 0, 0);
|
||||
OUT_RELOC(ring, rsc->bo, layer_offset, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
|
||||
struct ir3_shader_variant *vp,
|
||||
struct fd3_vertex_buf *vbufs, uint32_t n)
|
||||
fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
|
||||
{
|
||||
uint32_t i, j, last = 0;
|
||||
uint32_t total_in = 0;
|
||||
const struct fd_vertex_state *vtx = emit->vtx;
|
||||
struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
|
||||
unsigned n = MIN2(vtx->vtx->num_elements, vp->inputs_count);
|
||||
|
||||
n = MIN2(n, vp->inputs_count);
|
||||
/* hw doesn't like to be configured for zero vbo's, it seems: */
|
||||
if (vtx->vtx->num_elements == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
if (vp->inputs[i].compmask)
|
||||
@@ -305,22 +353,25 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
|
||||
|
||||
for (i = 0, j = 0; i <= last; i++) {
|
||||
if (vp->inputs[i].compmask) {
|
||||
struct pipe_resource *prsc = vbufs[i].prsc;
|
||||
struct fd_resource *rsc = fd_resource(prsc);
|
||||
enum pipe_format pfmt = vbufs[i].format;
|
||||
struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];
|
||||
const struct pipe_vertex_buffer *vb =
|
||||
&vtx->vertexbuf.vb[elem->vertex_buffer_index];
|
||||
struct fd_resource *rsc = fd_resource(vb->buffer);
|
||||
enum pipe_format pfmt = elem->src_format;
|
||||
enum a3xx_vtx_fmt fmt = fd3_pipe2vtx(pfmt);
|
||||
bool switchnext = (i != last);
|
||||
bool isint = util_format_is_pure_integer(pfmt);
|
||||
uint32_t fs = util_format_get_blocksize(pfmt);
|
||||
|
||||
debug_assert(fmt != ~0);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VFD_FETCH(j), 2);
|
||||
OUT_RING(ring, A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(fs - 1) |
|
||||
A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vbufs[i].stride) |
|
||||
A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(vb->stride) |
|
||||
COND(switchnext, A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT) |
|
||||
A3XX_VFD_FETCH_INSTR_0_INDEXCODE(j) |
|
||||
A3XX_VFD_FETCH_INSTR_0_STEPRATE(1));
|
||||
OUT_RELOC(ring, rsc->bo, vbufs[i].offset, 0, 0);
|
||||
OUT_RELOC(ring, rsc->bo, vb->buffer_offset + elem->src_offset, 0, 0);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VFD_DECODE_INSTR(j), 1);
|
||||
OUT_RING(ring, A3XX_VFD_DECODE_INSTR_CONSTFILL |
|
||||
@@ -330,6 +381,7 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
|
||||
A3XX_VFD_DECODE_INSTR_REGID(vp->inputs[i].regid) |
|
||||
A3XX_VFD_DECODE_INSTR_SHIFTCNT(fs) |
|
||||
A3XX_VFD_DECODE_INSTR_LASTCOMPVALID |
|
||||
COND(isint, A3XX_VFD_DECODE_INSTR_INT) |
|
||||
COND(switchnext, A3XX_VFD_DECODE_INSTR_SWITCHNEXT));
|
||||
|
||||
total_in += vp->inputs[i].ncomp;
|
||||
@@ -349,14 +401,11 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
|
||||
|
||||
void
|
||||
fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
struct fd_program_stateobj *prog, uint32_t dirty,
|
||||
struct ir3_shader_key key)
|
||||
struct fd3_emit *emit)
|
||||
{
|
||||
struct ir3_shader_variant *vp;
|
||||
struct ir3_shader_variant *fp;
|
||||
|
||||
fp = fd3_shader_variant(prog->fp, key);
|
||||
vp = fd3_shader_variant(prog->vp, key);
|
||||
struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
|
||||
struct ir3_shader_variant *fp = fd3_emit_get_fp(emit);
|
||||
uint32_t dirty = emit->dirty;
|
||||
|
||||
emit_marker(ring, 5);
|
||||
|
||||
@@ -367,7 +416,7 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(ctx->sample_mask));
|
||||
}
|
||||
|
||||
if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) && !key.binning_pass) {
|
||||
if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) && !emit->key.binning_pass) {
|
||||
uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control;
|
||||
|
||||
val |= COND(fp->frag_face, A3XX_RB_RENDER_CONTROL_FACENESS);
|
||||
@@ -409,6 +458,9 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
val |= A3XX_RB_DEPTH_CONTROL_FRAG_WRITES_Z;
|
||||
val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE;
|
||||
}
|
||||
if (fp->has_kill) {
|
||||
val |= A3XX_RB_DEPTH_CONTROL_EARLY_Z_DISABLE;
|
||||
}
|
||||
OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
|
||||
OUT_RING(ring, val);
|
||||
}
|
||||
@@ -439,17 +491,27 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, val);
|
||||
}
|
||||
|
||||
if (dirty & (FD_DIRTY_RASTERIZER | FD_DIRTY_PROG)) {
|
||||
/* NOTE: since primitive_restart is not actually part of any
|
||||
* state object, we need to make sure that we always emit
|
||||
* PRIM_VTX_CNTL.. either that or be more clever and detect
|
||||
* when it changes.
|
||||
*/
|
||||
if (emit->info) {
|
||||
const struct pipe_draw_info *info = emit->info;
|
||||
uint32_t val = fd3_rasterizer_stateobj(ctx->rasterizer)
|
||||
->pc_prim_vtx_cntl;
|
||||
|
||||
if (!key.binning_pass) {
|
||||
if (!emit->key.binning_pass) {
|
||||
uint32_t stride_in_vpc = align(fp->total_in, 4) / 4;
|
||||
if (stride_in_vpc > 0)
|
||||
stride_in_vpc = MAX2(stride_in_vpc, 2);
|
||||
val |= A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(stride_in_vpc);
|
||||
}
|
||||
|
||||
if (info->indexed && info->primitive_restart) {
|
||||
val |= A3XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART;
|
||||
}
|
||||
|
||||
val |= COND(vp->writes_psize, A3XX_PC_PRIM_VTX_CNTL_PSIZE);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
|
||||
@@ -482,9 +544,8 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(ctx->viewport.scale[2]));
|
||||
}
|
||||
|
||||
if (dirty & FD_DIRTY_PROG) {
|
||||
fd3_program_emit(ring, prog, key);
|
||||
}
|
||||
if (dirty & FD_DIRTY_PROG)
|
||||
fd3_program_emit(ring, emit);
|
||||
|
||||
/* TODO we should not need this or fd_wfi() before emit_constants():
|
||||
*/
|
||||
@@ -493,15 +554,15 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
|
||||
if ((dirty & (FD_DIRTY_PROG | FD_DIRTY_CONSTBUF)) &&
|
||||
/* evil hack to deal sanely with clear path: */
|
||||
(prog == &ctx->prog)) {
|
||||
(emit->prog == &ctx->prog)) {
|
||||
fd_wfi(ctx, ring);
|
||||
emit_constants(ring, SB_VERT_SHADER,
|
||||
&ctx->constbuf[PIPE_SHADER_VERTEX],
|
||||
(prog->dirty & FD_SHADER_DIRTY_VP) ? vp : NULL);
|
||||
if (!key.binning_pass) {
|
||||
(emit->prog->dirty & FD_SHADER_DIRTY_VP) ? vp : NULL);
|
||||
if (!emit->key.binning_pass) {
|
||||
emit_constants(ring, SB_FRAG_SHADER,
|
||||
&ctx->constbuf[PIPE_SHADER_FRAGMENT],
|
||||
(prog->dirty & FD_SHADER_DIRTY_FP) ? fp : NULL);
|
||||
(emit->prog->dirty & FD_SHADER_DIRTY_FP) ? fp : NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,14 +597,14 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
|
||||
if (dirty & FD_DIRTY_VERTTEX) {
|
||||
if (vp->has_samp)
|
||||
emit_textures(ring, SB_VERT_TEX, &ctx->verttex);
|
||||
emit_textures(ctx, ring, SB_VERT_TEX, &ctx->verttex);
|
||||
else
|
||||
dirty &= ~FD_DIRTY_VERTTEX;
|
||||
}
|
||||
|
||||
if (dirty & FD_DIRTY_FRAGTEX) {
|
||||
if (fp->has_samp)
|
||||
emit_textures(ring, SB_FRAG_TEX, &ctx->fragtex);
|
||||
emit_textures(ctx, ring, SB_FRAG_TEX, &ctx->fragtex);
|
||||
else
|
||||
dirty &= ~FD_DIRTY_FRAGTEX;
|
||||
}
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "freedreno_context.h"
|
||||
#include "fd3_util.h"
|
||||
#include "fd3_program.h"
|
||||
#include "ir3_shader.h"
|
||||
|
||||
struct fd_ringbuffer;
|
||||
@@ -46,21 +47,44 @@ void fd3_emit_constant(struct fd_ringbuffer *ring,
|
||||
void fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring,
|
||||
struct pipe_surface *psurf);
|
||||
|
||||
/* NOTE: this just exists because we don't have proper vertex/vertexbuf
|
||||
* state objs for clear, and mem2gmem/gmem2mem operations..
|
||||
*/
|
||||
struct fd3_vertex_buf {
|
||||
unsigned offset, stride;
|
||||
struct pipe_resource *prsc;
|
||||
enum pipe_format format;
|
||||
/* grouped together emit-state for prog/vertex/state emit: */
|
||||
struct fd3_emit {
|
||||
const struct fd_vertex_state *vtx;
|
||||
const struct fd_program_stateobj *prog;
|
||||
const struct pipe_draw_info *info;
|
||||
struct ir3_shader_key key;
|
||||
uint32_t dirty;
|
||||
bool rasterflat;
|
||||
|
||||
/* cached to avoid repeated lookups of same variants: */
|
||||
struct ir3_shader_variant *vp, *fp;
|
||||
};
|
||||
|
||||
void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring,
|
||||
struct ir3_shader_variant *vp,
|
||||
struct fd3_vertex_buf *vbufs, uint32_t n);
|
||||
static inline struct ir3_shader_variant *
|
||||
fd3_emit_get_vp(struct fd3_emit *emit)
|
||||
{
|
||||
if (!emit->vp) {
|
||||
struct fd3_shader_stateobj *so = emit->prog->vp;
|
||||
emit->vp = ir3_shader_variant(so->shader, emit->key);
|
||||
}
|
||||
return emit->vp;
|
||||
}
|
||||
|
||||
static inline struct ir3_shader_variant *
|
||||
fd3_emit_get_fp(struct fd3_emit *emit)
|
||||
{
|
||||
if (!emit->fp) {
|
||||
struct fd3_shader_stateobj *so = emit->prog->fp;
|
||||
emit->fp = ir3_shader_variant(so->shader, emit->key);
|
||||
}
|
||||
return emit->fp;
|
||||
}
|
||||
|
||||
void fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit);
|
||||
|
||||
void fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
struct fd_program_stateobj *prog, uint32_t dirty,
|
||||
struct ir3_shader_key key);
|
||||
struct fd3_emit *emit);
|
||||
|
||||
void fd3_emit_restore(struct fd_context *ctx);
|
||||
|
||||
#endif /* FD3_EMIT_H */
|
||||
|
@@ -69,6 +69,7 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
|
||||
struct fd_resource_slice *slice = NULL;
|
||||
uint32_t stride = 0;
|
||||
uint32_t base = 0;
|
||||
uint32_t layer_offset = 0;
|
||||
|
||||
if ((i < nr_bufs) && bufs[i]) {
|
||||
struct pipe_surface *psurf = bufs[i];
|
||||
@@ -78,6 +79,10 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
|
||||
format = fd3_pipe2color(psurf->format);
|
||||
swap = fd3_pipe2swap(psurf->format);
|
||||
|
||||
debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
|
||||
|
||||
layer_offset = slice->size0 * psurf->u.tex.first_layer;
|
||||
|
||||
if (bin_w) {
|
||||
stride = bin_w * rsc->cpp;
|
||||
|
||||
@@ -97,7 +102,8 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
|
||||
if (bin_w || (i >= nr_bufs)) {
|
||||
OUT_RING(ring, A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(base));
|
||||
} else {
|
||||
OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1);
|
||||
OUT_RELOCW(ring, rsc->bo,
|
||||
slice->offset + layer_offset, 0, -1);
|
||||
}
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(i), 1);
|
||||
@@ -152,6 +158,11 @@ emit_binning_workaround(struct fd_context *ctx)
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
struct fd_gmem_stateobj *gmem = &ctx->gmem;
|
||||
struct fd_ringbuffer *ring = ctx->ring;
|
||||
struct fd3_emit emit = {
|
||||
.vtx = &fd3_ctx->solid_vbuf_state,
|
||||
.prog = &ctx->solid_prog,
|
||||
.key = key,
|
||||
};
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_RB_MODE_CONTROL, 2);
|
||||
OUT_RING(ring, A3XX_RB_MODE_CONTROL_RENDER_MODE(RB_RESOLVE_PASS) |
|
||||
@@ -177,13 +188,8 @@ emit_binning_workaround(struct fd_context *ctx)
|
||||
A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(MSAA_ONE) |
|
||||
A3XX_GRAS_SC_CONTROL_RASTER_MODE(1));
|
||||
|
||||
fd3_program_emit(ring, &ctx->solid_prog, key);
|
||||
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
|
||||
(struct fd3_vertex_buf[]) {{
|
||||
.prsc = fd3_ctx->solid_vbuf,
|
||||
.stride = 12,
|
||||
.format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}}, 1);
|
||||
fd3_program_emit(ring, &emit);
|
||||
fd3_emit_vertex_bufs(ring, &emit);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 4);
|
||||
OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS) |
|
||||
@@ -303,12 +309,16 @@ emit_gmem2mem_surf(struct fd_context *ctx,
|
||||
struct fd_ringbuffer *ring = ctx->ring;
|
||||
struct fd_resource *rsc = fd_resource(psurf->texture);
|
||||
struct fd_resource_slice *slice = &rsc->slices[psurf->u.tex.level];
|
||||
uint32_t layer_offset = slice->size0 * psurf->u.tex.first_layer;
|
||||
|
||||
debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_RB_COPY_CONTROL, 4);
|
||||
OUT_RING(ring, A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(MSAA_ONE) |
|
||||
A3XX_RB_COPY_CONTROL_MODE(mode) |
|
||||
A3XX_RB_COPY_CONTROL_GMEM_BASE(base));
|
||||
OUT_RELOCW(ring, rsc->bo, slice->offset, 0, -1); /* RB_COPY_DEST_BASE */
|
||||
|
||||
OUT_RELOCW(ring, rsc->bo, slice->offset + layer_offset, 0, -1); /* RB_COPY_DEST_BASE */
|
||||
OUT_RING(ring, A3XX_RB_COPY_DEST_PITCH_PITCH(slice->pitch * rsc->cpp));
|
||||
OUT_RING(ring, A3XX_RB_COPY_DEST_INFO_TILE(LINEAR) |
|
||||
A3XX_RB_COPY_DEST_INFO_FORMAT(fd3_pipe2color(psurf->format)) |
|
||||
@@ -326,6 +336,11 @@ fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
struct fd_ringbuffer *ring = ctx->ring;
|
||||
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
|
||||
struct fd3_emit emit = {
|
||||
.vtx = &fd3_ctx->solid_vbuf_state,
|
||||
.prog = &ctx->solid_prog,
|
||||
.key = key,
|
||||
};
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
|
||||
OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
|
||||
@@ -398,13 +413,8 @@ fd3_emit_tile_gmem2mem(struct fd_context *ctx, struct fd_tile *tile)
|
||||
OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */
|
||||
OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */
|
||||
|
||||
fd3_program_emit(ring, &ctx->solid_prog, key);
|
||||
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->solid_prog.vp, key),
|
||||
(struct fd3_vertex_buf[]) {{
|
||||
.prsc = fd3_ctx->solid_vbuf,
|
||||
.stride = 12,
|
||||
.format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}}, 1);
|
||||
fd3_program_emit(ring, &emit);
|
||||
fd3_emit_vertex_bufs(ring, &emit);
|
||||
|
||||
if (ctx->resolve & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL)) {
|
||||
uint32_t base = depth_base(ctx);
|
||||
@@ -448,6 +458,11 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
|
||||
struct fd_gmem_stateobj *gmem = &ctx->gmem;
|
||||
struct fd_ringbuffer *ring = ctx->ring;
|
||||
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
|
||||
struct fd3_emit emit = {
|
||||
.vtx = &fd3_ctx->blit_vbuf_state,
|
||||
.prog = &ctx->blit_prog,
|
||||
.key = key,
|
||||
};
|
||||
float x0, y0, x1, y1;
|
||||
unsigned bin_w = tile->bin_w;
|
||||
unsigned bin_h = tile->bin_h;
|
||||
@@ -542,17 +557,8 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
|
||||
OUT_RING(ring, 0); /* VFD_INSTANCEID_OFFSET */
|
||||
OUT_RING(ring, 0); /* VFD_INDEX_OFFSET */
|
||||
|
||||
fd3_program_emit(ring, &ctx->blit_prog, key);
|
||||
fd3_emit_vertex_bufs(ring, fd3_shader_variant(ctx->blit_prog.vp, key),
|
||||
(struct fd3_vertex_buf[]) {{
|
||||
.prsc = fd3_ctx->blit_texcoord_vbuf,
|
||||
.stride = 8,
|
||||
.format = PIPE_FORMAT_R32G32_FLOAT,
|
||||
}, {
|
||||
.prsc = fd3_ctx->solid_vbuf,
|
||||
.stride = 12,
|
||||
.format = PIPE_FORMAT_R32G32B32_FLOAT,
|
||||
}}, 2);
|
||||
fd3_program_emit(ring, &emit);
|
||||
fd3_emit_vertex_bufs(ring, &emit);
|
||||
|
||||
/* for gmem pitch/base calculations, we need to use the non-
|
||||
* truncated tile sizes:
|
||||
@@ -560,10 +566,10 @@ fd3_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
|
||||
bin_w = gmem->bin_w;
|
||||
bin_h = gmem->bin_h;
|
||||
|
||||
if (ctx->restore & (FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
|
||||
if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_DEPTH | FD_BUFFER_STENCIL))
|
||||
emit_mem2gmem_surf(ctx, depth_base(ctx), pfb->zsbuf, bin_w);
|
||||
|
||||
if (ctx->restore & FD_BUFFER_COLOR)
|
||||
if (fd_gmem_needs_restore(ctx, tile, FD_BUFFER_COLOR))
|
||||
emit_mem2gmem_surf(ctx, 0, pfb->cbufs[0], bin_w);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_GRAS_SC_CONTROL, 1);
|
||||
@@ -603,8 +609,11 @@ fd3_emit_sysmem_prep(struct fd_context *ctx)
|
||||
struct fd_ringbuffer *ring = ctx->ring;
|
||||
uint32_t pitch = 0;
|
||||
|
||||
if (pfb->cbufs[0])
|
||||
pitch = fd_resource(pfb->cbufs[0]->texture)->slices[0].pitch;
|
||||
if (pfb->cbufs[0]) {
|
||||
struct pipe_surface *psurf = pfb->cbufs[0];
|
||||
unsigned lvl = psurf->u.tex.level;
|
||||
pitch = fd_resource(psurf->texture)->slices[lvl].pitch;
|
||||
}
|
||||
|
||||
fd3_emit_restore(ctx);
|
||||
|
||||
|
@@ -140,13 +140,21 @@ find_output(const struct ir3_shader_variant *so, ir3_semantic semantic)
|
||||
* in the vertex shader.. but the fragment shader doesn't know this
|
||||
* so it will always have both IN.COLOR[n] and IN.BCOLOR[n]. So
|
||||
* at link time if there is no matching OUT.BCOLOR[n], we must map
|
||||
* OUT.COLOR[n] to IN.BCOLOR[n].
|
||||
* OUT.COLOR[n] to IN.BCOLOR[n]. And visa versa if there is only
|
||||
* a OUT.BCOLOR[n] but no matching OUT.COLOR[n]
|
||||
*/
|
||||
if (sem2name(semantic) == TGSI_SEMANTIC_BCOLOR) {
|
||||
unsigned idx = sem2idx(semantic);
|
||||
return find_output(so, ir3_semantic_name(TGSI_SEMANTIC_COLOR, idx));
|
||||
semantic = ir3_semantic_name(TGSI_SEMANTIC_COLOR, idx);
|
||||
} else if (sem2name(semantic) == TGSI_SEMANTIC_COLOR) {
|
||||
unsigned idx = sem2idx(semantic);
|
||||
semantic = ir3_semantic_name(TGSI_SEMANTIC_BCOLOR, idx);
|
||||
}
|
||||
|
||||
for (j = 0; j < so->outputs_count; j++)
|
||||
if (so->outputs[j].semantic == semantic)
|
||||
return j;
|
||||
|
||||
debug_assert(0);
|
||||
|
||||
return 0;
|
||||
@@ -172,27 +180,72 @@ find_output_regid(const struct ir3_shader_variant *so, ir3_semantic semantic)
|
||||
}
|
||||
|
||||
void
|
||||
fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
struct fd_program_stateobj *prog, struct ir3_shader_key key)
|
||||
fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit)
|
||||
{
|
||||
const struct ir3_shader_variant *vp, *fp;
|
||||
const struct ir3_info *vsi, *fsi;
|
||||
enum a3xx_instrbuffermode fpbuffer, vpbuffer;
|
||||
uint32_t fpbuffersz, vpbuffersz, fsoff;
|
||||
uint32_t pos_regid, posz_regid, psize_regid, color_regid;
|
||||
int constmode;
|
||||
int i, j, k;
|
||||
|
||||
vp = fd3_shader_variant(prog->vp, key);
|
||||
vp = fd3_emit_get_vp(emit);
|
||||
|
||||
if (key.binning_pass) {
|
||||
if (emit->key.binning_pass) {
|
||||
/* use dummy stateobj to simplify binning vs non-binning: */
|
||||
static const struct ir3_shader_variant binning_fp = {};
|
||||
fp = &binning_fp;
|
||||
} else {
|
||||
fp = fd3_shader_variant(prog->fp, key);
|
||||
fp = fd3_emit_get_fp(emit);
|
||||
}
|
||||
|
||||
vsi = &vp->info;
|
||||
fsi = &fp->info;
|
||||
|
||||
fpbuffer = BUFFER;
|
||||
vpbuffer = BUFFER;
|
||||
fpbuffersz = fp->instrlen;
|
||||
vpbuffersz = vp->instrlen;
|
||||
|
||||
/*
|
||||
* Decide whether to use BUFFER or CACHE mode for VS and FS. It
|
||||
* appears like 256 is the hard limit, but when the combined size
|
||||
* exceeds 128 then blob will try to keep FS in BUFFER mode and
|
||||
* switch to CACHE for VS until VS is too large. The blob seems
|
||||
* to switch FS out of BUFFER mode at slightly under 128. But
|
||||
* a bit fuzzy on the decision tree, so use slightly conservative
|
||||
* limits.
|
||||
*
|
||||
* TODO check if these thresholds for BUFFER vs CACHE mode are the
|
||||
* same for all a3xx or whether we need to consider the gpuid
|
||||
*/
|
||||
|
||||
if ((fpbuffersz + vpbuffersz) > 128) {
|
||||
if (fpbuffersz < 112) {
|
||||
/* FP:BUFFER VP:CACHE */
|
||||
vpbuffer = CACHE;
|
||||
vpbuffersz = 256 - fpbuffersz;
|
||||
} else if (vpbuffersz < 112) {
|
||||
/* FP:CACHE VP:BUFFER */
|
||||
fpbuffer = CACHE;
|
||||
fpbuffersz = 256 - vpbuffersz;
|
||||
} else {
|
||||
/* FP:CACHE VP:CACHE */
|
||||
vpbuffer = fpbuffer = CACHE;
|
||||
vpbuffersz = fpbuffersz = 192;
|
||||
}
|
||||
}
|
||||
|
||||
if (fpbuffer == BUFFER) {
|
||||
fsoff = 128 - fpbuffersz;
|
||||
} else {
|
||||
fsoff = 256 - fpbuffersz;
|
||||
}
|
||||
|
||||
/* seems like vs->constlen + fs->constlen > 256, then CONSTMODE=1 */
|
||||
constmode = ((vp->constlen + fp->constlen) > 256) ? 1 : 0;
|
||||
|
||||
pos_regid = find_output_regid(vp,
|
||||
ir3_semantic_name(TGSI_SEMANTIC_POSITION, 0));
|
||||
posz_regid = find_output_regid(fp,
|
||||
@@ -208,6 +261,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_HLSQ_CONTROL_0_REG, 6);
|
||||
OUT_RING(ring, A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(FOUR_QUADS) |
|
||||
A3XX_HLSQ_CONTROL_0_REG_CONSTMODE(constmode) |
|
||||
/* NOTE: I guess SHADERRESTART and CONSTFULLUPDATE maybe
|
||||
* flush some caches? I think we only need to set those
|
||||
* bits if we have updated const or shader..
|
||||
@@ -221,14 +275,14 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, A3XX_HLSQ_CONTROL_3_REG_REGID(fp->pos_regid));
|
||||
OUT_RING(ring, A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH(vp->constlen) |
|
||||
A3XX_HLSQ_VS_CONTROL_REG_CONSTSTARTOFFSET(0) |
|
||||
A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH(vp->instrlen));
|
||||
A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH(vpbuffersz));
|
||||
OUT_RING(ring, A3XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH(fp->constlen) |
|
||||
A3XX_HLSQ_FS_CONTROL_REG_CONSTSTARTOFFSET(128) |
|
||||
A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH(fp->instrlen));
|
||||
A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH(fpbuffersz));
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_SP_CTRL_REG, 1);
|
||||
OUT_RING(ring, A3XX_SP_SP_CTRL_REG_CONSTMODE(0) |
|
||||
COND(key.binning_pass, A3XX_SP_SP_CTRL_REG_BINNING) |
|
||||
OUT_RING(ring, A3XX_SP_SP_CTRL_REG_CONSTMODE(constmode) |
|
||||
COND(emit->key.binning_pass, A3XX_SP_SP_CTRL_REG_BINNING) |
|
||||
A3XX_SP_SP_CTRL_REG_SLEEPMODE(1) |
|
||||
A3XX_SP_SP_CTRL_REG_L0MODE(0));
|
||||
|
||||
@@ -237,18 +291,18 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_VS_CTRL_REG0, 3);
|
||||
OUT_RING(ring, A3XX_SP_VS_CTRL_REG0_THREADMODE(MULTI) |
|
||||
A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE(BUFFER) |
|
||||
A3XX_SP_VS_CTRL_REG0_CACHEINVALID |
|
||||
A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE(vpbuffer) |
|
||||
COND(vpbuffer == CACHE, A3XX_SP_VS_CTRL_REG0_CACHEINVALID) |
|
||||
A3XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT(vsi->max_half_reg + 1) |
|
||||
A3XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT(vsi->max_reg + 1) |
|
||||
A3XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP(0) |
|
||||
A3XX_SP_VS_CTRL_REG0_THREADSIZE(TWO_QUADS) |
|
||||
A3XX_SP_VS_CTRL_REG0_SUPERTHREADMODE |
|
||||
COND(vp->has_samp, A3XX_SP_VS_CTRL_REG0_PIXLODENABLE) |
|
||||
A3XX_SP_VS_CTRL_REG0_LENGTH(vp->instrlen));
|
||||
A3XX_SP_VS_CTRL_REG0_LENGTH(vpbuffersz));
|
||||
OUT_RING(ring, A3XX_SP_VS_CTRL_REG1_CONSTLENGTH(vp->constlen) |
|
||||
A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(vp->total_in) |
|
||||
A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(MAX2(vsi->max_const, 0)));
|
||||
A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(MAX2(vp->constlen + 1, 0)));
|
||||
OUT_RING(ring, A3XX_SP_VS_PARAM_REG_POSREGID(pos_regid) |
|
||||
A3XX_SP_VS_PARAM_REG_PSIZEREGID(psize_regid) |
|
||||
A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(align(fp->total_in, 4) / 4));
|
||||
@@ -301,7 +355,7 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0));
|
||||
OUT_RELOC(ring, vp->bo, 0, 0, 0); /* SP_VS_OBJ_START_REG */
|
||||
|
||||
if (key.binning_pass) {
|
||||
if (emit->key.binning_pass) {
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_LENGTH_REG, 1);
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
@@ -309,35 +363,37 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, A3XX_SP_FS_CTRL_REG0_THREADMODE(MULTI) |
|
||||
A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE(BUFFER));
|
||||
OUT_RING(ring, 0x00000000);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_OBJ_OFFSET_REG, 1);
|
||||
OUT_RING(ring, A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(128) |
|
||||
A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0));
|
||||
} else {
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_LENGTH_REG, 1);
|
||||
OUT_RING(ring, A3XX_SP_FS_LENGTH_REG_SHADERLENGTH(fp->instrlen));
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_CTRL_REG0, 2);
|
||||
OUT_RING(ring, A3XX_SP_FS_CTRL_REG0_THREADMODE(MULTI) |
|
||||
A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE(BUFFER) |
|
||||
A3XX_SP_FS_CTRL_REG0_CACHEINVALID |
|
||||
A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE(fpbuffer) |
|
||||
COND(fpbuffer == CACHE, A3XX_SP_FS_CTRL_REG0_CACHEINVALID) |
|
||||
A3XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT(fsi->max_half_reg + 1) |
|
||||
A3XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(fsi->max_reg + 1) |
|
||||
A3XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP(1) |
|
||||
A3XX_SP_FS_CTRL_REG0_THREADSIZE(FOUR_QUADS) |
|
||||
A3XX_SP_FS_CTRL_REG0_SUPERTHREADMODE |
|
||||
COND(fp->has_samp > 0, A3XX_SP_FS_CTRL_REG0_PIXLODENABLE) |
|
||||
A3XX_SP_FS_CTRL_REG0_LENGTH(fp->instrlen));
|
||||
A3XX_SP_FS_CTRL_REG0_LENGTH(fpbuffersz));
|
||||
OUT_RING(ring, A3XX_SP_FS_CTRL_REG1_CONSTLENGTH(fp->constlen) |
|
||||
A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING(fp->total_in) |
|
||||
A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT(MAX2(fsi->max_const, 0)) |
|
||||
A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT(MAX2(fp->constlen + 1, 0)) |
|
||||
A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET(63));
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_OBJ_OFFSET_REG, 2);
|
||||
OUT_RING(ring, A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(128) |
|
||||
A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(0));
|
||||
OUT_RING(ring, A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(
|
||||
MAX2(128, vp->constlen)) |
|
||||
A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(fsoff));
|
||||
OUT_RELOC(ring, fp->bo, 0, 0, 0); /* SP_FS_OBJ_START_REG */
|
||||
}
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 2);
|
||||
OUT_RING(ring, 0x00000000); /* SP_FS_FLAT_SHAD_MODE_REG_0 */
|
||||
OUT_RING(ring, 0x00000000); /* SP_FS_FLAT_SHAD_MODE_REG_1 */
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_OUTPUT_REG, 1);
|
||||
if (fp->writes_pos) {
|
||||
OUT_RING(ring, A3XX_SP_FS_OUTPUT_REG_DEPTH_ENABLE |
|
||||
@@ -353,13 +409,37 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
OUT_RING(ring, A3XX_SP_FS_MRT_REG_REGID(0));
|
||||
OUT_RING(ring, A3XX_SP_FS_MRT_REG_REGID(0));
|
||||
|
||||
if (key.binning_pass) {
|
||||
if (emit->key.binning_pass) {
|
||||
OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2);
|
||||
OUT_RING(ring, A3XX_VPC_ATTR_THRDASSIGN(1) |
|
||||
A3XX_VPC_ATTR_LMSIZE(1) |
|
||||
COND(vp->writes_psize, A3XX_VPC_ATTR_PSIZE));
|
||||
OUT_RING(ring, 0x00000000);
|
||||
} else {
|
||||
uint32_t vinterp[4] = {0}, flatshade[2] = {0};
|
||||
|
||||
/* figure out VARYING_INTERP / FLAT_SHAD register values: */
|
||||
for (j = -1; (j = next_varying(fp, j)) < (int)fp->inputs_count; ) {
|
||||
uint32_t interp = fp->inputs[j].interpolate;
|
||||
if ((interp == TGSI_INTERPOLATE_CONSTANT) ||
|
||||
((interp == TGSI_INTERPOLATE_COLOR) && emit->rasterflat)) {
|
||||
/* TODO might be cleaner to just +8 in SP_VS_VPC_DST_REG
|
||||
* instead.. rather than -8 everywhere else..
|
||||
*/
|
||||
uint32_t loc = fp->inputs[j].inloc - 8;
|
||||
|
||||
/* currently assuming varyings aligned to 4 (not
|
||||
* packed):
|
||||
*/
|
||||
debug_assert((loc % 4) == 0);
|
||||
|
||||
for (i = 0; i < 4; i++, loc++) {
|
||||
vinterp[loc / 16] |= FLAT << ((loc % 16) * 2);
|
||||
flatshade[loc / 32] |= 1 << (loc % 32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VPC_ATTR, 2);
|
||||
OUT_RING(ring, A3XX_VPC_ATTR_TOTALATTR(fp->total_in) |
|
||||
A3XX_VPC_ATTR_THRDASSIGN(1) |
|
||||
@@ -369,29 +449,35 @@ fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
A3XX_VPC_PACK_NUMNONPOSVSVAR(fp->total_in));
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VPC_VARYING_INTERP_MODE(0), 4);
|
||||
OUT_RING(ring, fp->shader->vinterp[0]); /* VPC_VARYING_INTERP[0].MODE */
|
||||
OUT_RING(ring, fp->shader->vinterp[1]); /* VPC_VARYING_INTERP[1].MODE */
|
||||
OUT_RING(ring, fp->shader->vinterp[2]); /* VPC_VARYING_INTERP[2].MODE */
|
||||
OUT_RING(ring, fp->shader->vinterp[3]); /* VPC_VARYING_INTERP[3].MODE */
|
||||
OUT_RING(ring, vinterp[0]); /* VPC_VARYING_INTERP[0].MODE */
|
||||
OUT_RING(ring, vinterp[1]); /* VPC_VARYING_INTERP[1].MODE */
|
||||
OUT_RING(ring, vinterp[2]); /* VPC_VARYING_INTERP[2].MODE */
|
||||
OUT_RING(ring, vinterp[3]); /* VPC_VARYING_INTERP[3].MODE */
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VPC_VARYING_PS_REPL_MODE(0), 4);
|
||||
OUT_RING(ring, fp->shader->vpsrepl[0]); /* VPC_VARYING_PS_REPL[0].MODE */
|
||||
OUT_RING(ring, fp->shader->vpsrepl[1]); /* VPC_VARYING_PS_REPL[1].MODE */
|
||||
OUT_RING(ring, fp->shader->vpsrepl[2]); /* VPC_VARYING_PS_REPL[2].MODE */
|
||||
OUT_RING(ring, fp->shader->vpsrepl[3]); /* VPC_VARYING_PS_REPL[3].MODE */
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0, 2);
|
||||
OUT_RING(ring, flatshade[0]); /* SP_FS_FLAT_SHAD_MODE_REG_0 */
|
||||
OUT_RING(ring, flatshade[1]); /* SP_FS_FLAT_SHAD_MODE_REG_1 */
|
||||
}
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VFD_VS_THREADING_THRESHOLD, 1);
|
||||
OUT_RING(ring, A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD(15) |
|
||||
A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT(252));
|
||||
|
||||
emit_shader(ring, vp);
|
||||
if (vpbuffer == BUFFER)
|
||||
emit_shader(ring, vp);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1);
|
||||
OUT_RING(ring, 0x00000000); /* VFD_PERFCOUNTER0_SELECT */
|
||||
|
||||
if (!key.binning_pass) {
|
||||
emit_shader(ring, fp);
|
||||
if (!emit->key.binning_pass) {
|
||||
if (fpbuffer == BUFFER)
|
||||
emit_shader(ring, fp);
|
||||
|
||||
OUT_PKT0(ring, REG_A3XX_VFD_PERFCOUNTER0_SELECT, 1);
|
||||
OUT_RING(ring, 0x00000000); /* VFD_PERFCOUNTER0_SELECT */
|
||||
|
@@ -37,8 +37,9 @@ struct fd3_shader_stateobj {
|
||||
struct ir3_shader *shader;
|
||||
};
|
||||
|
||||
void fd3_program_emit(struct fd_ringbuffer *ring,
|
||||
struct fd_program_stateobj *prog, struct ir3_shader_key key);
|
||||
struct fd3_emit;
|
||||
|
||||
void fd3_program_emit(struct fd_ringbuffer *ring, struct fd3_emit *emit);
|
||||
|
||||
void fd3_prog_init(struct pipe_context *pctx);
|
||||
|
||||
|
@@ -119,14 +119,14 @@ occlusion_predicate_accumulate_result(struct fd_context *ctx,
|
||||
|
||||
static const struct fd_hw_sample_provider occlusion_counter = {
|
||||
.query_type = PIPE_QUERY_OCCLUSION_COUNTER,
|
||||
.active = FD_STAGE_DRAW, /* | FD_STAGE_CLEAR ??? */
|
||||
.active = FD_STAGE_DRAW,
|
||||
.get_sample = occlusion_get_sample,
|
||||
.accumulate_result = occlusion_counter_accumulate_result,
|
||||
};
|
||||
|
||||
static const struct fd_hw_sample_provider occlusion_predicate = {
|
||||
.query_type = PIPE_QUERY_OCCLUSION_PREDICATE,
|
||||
.active = FD_STAGE_DRAW, /* | FD_STAGE_CLEAR ??? */
|
||||
.active = FD_STAGE_DRAW,
|
||||
.get_sample = occlusion_get_sample,
|
||||
.accumulate_result = occlusion_predicate_accumulate_result,
|
||||
};
|
||||
|
@@ -36,28 +36,31 @@
|
||||
#include "fd3_util.h"
|
||||
|
||||
static enum a3xx_tex_clamp
|
||||
tex_clamp(unsigned wrap)
|
||||
tex_clamp(unsigned wrap, bool clamp_to_edge)
|
||||
{
|
||||
/* hardware probably supports more, but we can't coax all the
|
||||
* wrap/clamp modes out of the GLESv2 blob driver.
|
||||
*
|
||||
* TODO once we have basics working, go back and just try
|
||||
* different values and see what happens
|
||||
*/
|
||||
/* Hardware does not support _CLAMP, but we emulate it: */
|
||||
if (wrap == PIPE_TEX_WRAP_CLAMP) {
|
||||
wrap = (clamp_to_edge) ?
|
||||
PIPE_TEX_WRAP_CLAMP_TO_EDGE : PIPE_TEX_WRAP_CLAMP_TO_BORDER;
|
||||
}
|
||||
|
||||
switch (wrap) {
|
||||
case PIPE_TEX_WRAP_REPEAT:
|
||||
return A3XX_TEX_REPEAT;
|
||||
case PIPE_TEX_WRAP_CLAMP:
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
|
||||
return A3XX_TEX_CLAMP_TO_EDGE;
|
||||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
|
||||
return A3XX_TEX_CLAMP_TO_BORDER;
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
|
||||
/* only works for PoT.. need to emulate otherwise! */
|
||||
return A3XX_TEX_MIRROR_CLAMP;
|
||||
case PIPE_TEX_WRAP_MIRROR_REPEAT:
|
||||
return A3XX_TEX_MIRROR_REPEAT;
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP:
|
||||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
|
||||
/* these two we could perhaps emulate, but we currently
|
||||
* just don't advertise PIPE_CAP_TEXTURE_MIRROR_CLAMP
|
||||
*/
|
||||
default:
|
||||
DBG("invalid wrap: %u", wrap);
|
||||
return 0;
|
||||
@@ -84,6 +87,7 @@ fd3_sampler_state_create(struct pipe_context *pctx,
|
||||
{
|
||||
struct fd3_sampler_stateobj *so = CALLOC_STRUCT(fd3_sampler_stateobj);
|
||||
bool miplinear = false;
|
||||
bool clamp_to_edge;
|
||||
|
||||
if (!so)
|
||||
return NULL;
|
||||
@@ -93,20 +97,36 @@ fd3_sampler_state_create(struct pipe_context *pctx,
|
||||
|
||||
so->base = *cso;
|
||||
|
||||
/*
|
||||
* For nearest filtering, _CLAMP means _CLAMP_TO_EDGE; for linear
|
||||
* filtering, _CLAMP means _CLAMP_TO_BORDER while additionally
|
||||
* clamping the texture coordinates to [0.0, 1.0].
|
||||
*
|
||||
* The clamping will be taken care of in the shaders. There are two
|
||||
* filters here, but let the minification one has a say.
|
||||
*/
|
||||
clamp_to_edge = (cso->min_img_filter == PIPE_TEX_FILTER_NEAREST);
|
||||
if (!clamp_to_edge) {
|
||||
so->saturate_s = (cso->wrap_s == PIPE_TEX_WRAP_CLAMP);
|
||||
so->saturate_t = (cso->wrap_t == PIPE_TEX_WRAP_CLAMP);
|
||||
so->saturate_r = (cso->wrap_r == PIPE_TEX_WRAP_CLAMP);
|
||||
}
|
||||
|
||||
so->texsamp0 =
|
||||
COND(!cso->normalized_coords, A3XX_TEX_SAMP_0_UNNORM_COORDS) |
|
||||
COND(miplinear, A3XX_TEX_SAMP_0_MIPFILTER_LINEAR) |
|
||||
A3XX_TEX_SAMP_0_XY_MAG(tex_filter(cso->mag_img_filter)) |
|
||||
A3XX_TEX_SAMP_0_XY_MIN(tex_filter(cso->min_img_filter)) |
|
||||
A3XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s)) |
|
||||
A3XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t)) |
|
||||
A3XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r));
|
||||
A3XX_TEX_SAMP_0_WRAP_S(tex_clamp(cso->wrap_s, clamp_to_edge)) |
|
||||
A3XX_TEX_SAMP_0_WRAP_T(tex_clamp(cso->wrap_t, clamp_to_edge)) |
|
||||
A3XX_TEX_SAMP_0_WRAP_R(tex_clamp(cso->wrap_r, clamp_to_edge));
|
||||
|
||||
if (cso->compare_mode)
|
||||
so->texsamp0 |= A3XX_TEX_SAMP_0_COMPARE_FUNC(cso->compare_func); /* maps 1:1 */
|
||||
|
||||
if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
|
||||
so->texsamp1 =
|
||||
A3XX_TEX_SAMP_1_LOD_BIAS(cso->lod_bias) |
|
||||
A3XX_TEX_SAMP_1_MIN_LOD(cso->min_lod) |
|
||||
A3XX_TEX_SAMP_1_MAX_LOD(cso->max_lod);
|
||||
} else {
|
||||
@@ -116,6 +136,50 @@ fd3_sampler_state_create(struct pipe_context *pctx,
|
||||
return so;
|
||||
}
|
||||
|
||||
static void
|
||||
fd3_sampler_states_bind(struct pipe_context *pctx,
|
||||
unsigned shader, unsigned start,
|
||||
unsigned nr, void **hwcso)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct fd3_context *fd3_ctx = fd3_context(ctx);
|
||||
uint16_t saturate_s = 0, saturate_t = 0, saturate_r = 0;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (hwcso[i]) {
|
||||
struct fd3_sampler_stateobj *sampler =
|
||||
fd3_sampler_stateobj(hwcso[i]);
|
||||
if (sampler->saturate_s)
|
||||
saturate_s |= (1 << i);
|
||||
if (sampler->saturate_t)
|
||||
saturate_t |= (1 << i);
|
||||
if (sampler->saturate_r)
|
||||
saturate_r |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
fd_sampler_states_bind(pctx, shader, start, nr, hwcso);
|
||||
|
||||
if (shader == PIPE_SHADER_FRAGMENT) {
|
||||
fd3_ctx->fsaturate =
|
||||
(saturate_s != 0) ||
|
||||
(saturate_t != 0) ||
|
||||
(saturate_r != 0);
|
||||
fd3_ctx->fsaturate_s = saturate_s;
|
||||
fd3_ctx->fsaturate_t = saturate_t;
|
||||
fd3_ctx->fsaturate_r = saturate_r;
|
||||
} else if (shader == PIPE_SHADER_VERTEX) {
|
||||
fd3_ctx->vsaturate =
|
||||
(saturate_s != 0) ||
|
||||
(saturate_t != 0) ||
|
||||
(saturate_r != 0);
|
||||
fd3_ctx->vsaturate_s = saturate_s;
|
||||
fd3_ctx->vsaturate_t = saturate_t;
|
||||
fd3_ctx->vsaturate_r = saturate_r;
|
||||
}
|
||||
}
|
||||
|
||||
static enum a3xx_tex_type
|
||||
tex_type(unsigned target)
|
||||
{
|
||||
@@ -144,7 +208,8 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
{
|
||||
struct fd3_pipe_sampler_view *so = CALLOC_STRUCT(fd3_pipe_sampler_view);
|
||||
struct fd_resource *rsc = fd_resource(prsc);
|
||||
unsigned miplevels = cso->u.tex.last_level - cso->u.tex.first_level;
|
||||
unsigned lvl = cso->u.tex.first_level;
|
||||
unsigned miplevels = cso->u.tex.last_level - lvl;
|
||||
|
||||
if (!so)
|
||||
return NULL;
|
||||
@@ -156,7 +221,6 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
so->base.context = pctx;
|
||||
|
||||
so->tex_resource = rsc;
|
||||
so->mipaddrs = 1 + miplevels;
|
||||
|
||||
so->texconst0 =
|
||||
A3XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) |
|
||||
@@ -170,12 +234,29 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||
|
||||
so->texconst1 =
|
||||
A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
|
||||
A3XX_TEX_CONST_1_WIDTH(prsc->width0) |
|
||||
A3XX_TEX_CONST_1_HEIGHT(prsc->height0);
|
||||
A3XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
|
||||
A3XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
|
||||
/* when emitted, A3XX_TEX_CONST_2_INDX() must be OR'd in: */
|
||||
so->texconst2 =
|
||||
A3XX_TEX_CONST_2_PITCH(rsc->slices[0].pitch * rsc->cpp);
|
||||
so->texconst3 = 0x00000000; /* ??? */
|
||||
A3XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp);
|
||||
switch (prsc->target) {
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
so->texconst3 =
|
||||
A3XX_TEX_CONST_3_DEPTH(prsc->array_size - 1) |
|
||||
A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) |
|
||||
A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0);
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
so->texconst3 =
|
||||
A3XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) |
|
||||
A3XX_TEX_CONST_3_LAYERSZ1(rsc->slices[0].size0) |
|
||||
A3XX_TEX_CONST_3_LAYERSZ2(rsc->slices[0].size0);
|
||||
break;
|
||||
default:
|
||||
so->texconst3 = 0x00000000;
|
||||
break;
|
||||
}
|
||||
|
||||
return &so->base;
|
||||
}
|
||||
@@ -184,5 +265,6 @@ void
|
||||
fd3_texture_init(struct pipe_context *pctx)
|
||||
{
|
||||
pctx->create_sampler_state = fd3_sampler_state_create;
|
||||
pctx->bind_sampler_states = fd3_sampler_states_bind;
|
||||
pctx->create_sampler_view = fd3_sampler_view_create;
|
||||
}
|
||||
|
@@ -40,6 +40,7 @@
|
||||
struct fd3_sampler_stateobj {
|
||||
struct pipe_sampler_state base;
|
||||
uint32_t texsamp0, texsamp1;
|
||||
bool saturate_s, saturate_t, saturate_r;
|
||||
};
|
||||
|
||||
static INLINE struct fd3_sampler_stateobj *
|
||||
@@ -51,7 +52,6 @@ fd3_sampler_stateobj(struct pipe_sampler_state *samp)
|
||||
struct fd3_pipe_sampler_view {
|
||||
struct pipe_sampler_view base;
|
||||
struct fd_resource *tex_resource;
|
||||
uint32_t mipaddrs;
|
||||
uint32_t texconst0, texconst1, texconst2, texconst3;
|
||||
};
|
||||
|
||||
|
@@ -134,6 +134,14 @@ fd3_pipe2vtx(enum pipe_format format)
|
||||
case PIPE_FORMAT_R16G16_SNORM:
|
||||
return VFMT_NORM_SHORT_16_16;
|
||||
|
||||
case PIPE_FORMAT_R32_UINT:
|
||||
case PIPE_FORMAT_R32_USCALED:
|
||||
return VFMT_UINT_32;
|
||||
|
||||
case PIPE_FORMAT_R32_SINT:
|
||||
case PIPE_FORMAT_R32_SSCALED:
|
||||
return VFMT_INT_32;
|
||||
|
||||
case PIPE_FORMAT_R10G10B10A2_UNORM:
|
||||
return VFMT_NORM_UINT_10_10_10_2;
|
||||
|
||||
@@ -196,6 +204,14 @@ fd3_pipe2vtx(enum pipe_format format)
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
return VFMT_FLOAT_16_16_16_16;
|
||||
|
||||
case PIPE_FORMAT_R32G32_UINT:
|
||||
case PIPE_FORMAT_R32G32_USCALED:
|
||||
return VFMT_UINT_32_32;
|
||||
|
||||
case PIPE_FORMAT_R32G32_SINT:
|
||||
case PIPE_FORMAT_R32G32_SSCALED:
|
||||
return VFMT_INT_32_32;
|
||||
|
||||
/* 96-bit buffers. */
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
return VFMT_FLOAT_32_32_32;
|
||||
@@ -203,6 +219,14 @@ fd3_pipe2vtx(enum pipe_format format)
|
||||
case PIPE_FORMAT_R32G32B32_FIXED:
|
||||
return VFMT_FIXED_32_32_32;
|
||||
|
||||
case PIPE_FORMAT_R32G32B32_UINT:
|
||||
case PIPE_FORMAT_R32G32B32_USCALED:
|
||||
return VFMT_UINT_32_32_32;
|
||||
|
||||
case PIPE_FORMAT_R32G32B32_SINT:
|
||||
case PIPE_FORMAT_R32G32B32_SSCALED:
|
||||
return VFMT_INT_32_32_32;
|
||||
|
||||
/* 128-bit buffers. */
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
return VFMT_FLOAT_32_32_32_32;
|
||||
@@ -210,26 +234,20 @@ fd3_pipe2vtx(enum pipe_format format)
|
||||
case PIPE_FORMAT_R32G32B32A32_FIXED:
|
||||
return VFMT_FIXED_32_32_32_32;
|
||||
|
||||
/* TODO probably need gles3 blob drivers to find the 32bit int formats:
|
||||
case PIPE_FORMAT_R32G32B32A32_UINT:
|
||||
case PIPE_FORMAT_R32G32B32A32_USCALED:
|
||||
return VFMT_UINT_32_32_32_32;
|
||||
|
||||
case PIPE_FORMAT_R32G32B32A32_SINT:
|
||||
case PIPE_FORMAT_R32G32B32A32_SSCALED:
|
||||
return VFMT_INT_32_32_32_32;
|
||||
|
||||
/* TODO normalized 32bit int formats do not appear to be supported
|
||||
* natively.. will require either shader variant or VFD_DECODE
|
||||
* gymnastics like the blob driver does..
|
||||
case PIPE_FORMAT_R32G32B32A32_SNORM:
|
||||
case PIPE_FORMAT_R32G32B32A32_UNORM:
|
||||
case PIPE_FORMAT_R32G32B32A32_SINT:
|
||||
case PIPE_FORMAT_R32G32B32A32_UINT:
|
||||
|
||||
case PIPE_FORMAT_R32_UINT:
|
||||
case PIPE_FORMAT_R32_SINT:
|
||||
case PIPE_FORMAT_A32_UINT:
|
||||
case PIPE_FORMAT_A32_SINT:
|
||||
case PIPE_FORMAT_L32_UINT:
|
||||
case PIPE_FORMAT_L32_SINT:
|
||||
case PIPE_FORMAT_I32_UINT:
|
||||
case PIPE_FORMAT_I32_SINT:
|
||||
|
||||
case PIPE_FORMAT_R32G32_SINT:
|
||||
case PIPE_FORMAT_R32G32_UINT:
|
||||
case PIPE_FORMAT_L32A32_UINT:
|
||||
case PIPE_FORMAT_L32A32_SINT:
|
||||
*/
|
||||
*/
|
||||
|
||||
default:
|
||||
return ~0;
|
||||
@@ -246,6 +264,9 @@ fd3_pipe2tex(enum pipe_format format)
|
||||
case PIPE_FORMAT_I8_UNORM:
|
||||
return TFMT_NORM_UINT_8;
|
||||
|
||||
case PIPE_FORMAT_R8G8_UNORM:
|
||||
return TFMT_NORM_UINT_8_8;
|
||||
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8X8_UNORM:
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
@@ -257,13 +278,11 @@ fd3_pipe2tex(enum pipe_format format)
|
||||
return TFMT_NORM_UINT_8_8_8_8;
|
||||
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
|
||||
return TFMT_NORM_UINT_X8Z24;
|
||||
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
|
||||
return TFMT_NORM_UINT_8_8_8_8;
|
||||
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return TFMT_NORM_UINT_8_8;
|
||||
return TFMT_NORM_USHORT_Z16;
|
||||
|
||||
case PIPE_FORMAT_R16G16B16A16_FLOAT:
|
||||
case PIPE_FORMAT_R16G16B16X16_FLOAT:
|
||||
@@ -331,6 +350,8 @@ fd3_pipe2color(enum pipe_format format)
|
||||
|
||||
case PIPE_FORMAT_R8_UNORM:
|
||||
case PIPE_FORMAT_L8_UNORM:
|
||||
return RB_R8_UNORM;
|
||||
|
||||
case PIPE_FORMAT_A8_UNORM:
|
||||
return RB_A8_UNORM;
|
||||
|
||||
@@ -360,8 +381,9 @@ fd3_gmem_restore_format(enum pipe_format format)
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_Z24X8_UNORM:
|
||||
case PIPE_FORMAT_Z24_UNORM_S8_UINT:
|
||||
return PIPE_FORMAT_R8G8B8A8_UNORM;
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
return PIPE_FORMAT_R8G8_UNORM;
|
||||
default:
|
||||
return format;
|
||||
}
|
||||
|
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-07-19 17:20:53)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-07-19 17:21:17)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 36670 bytes, from 2014-07-19 17:18:34)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10347 bytes, from 2014-10-01 18:55:57)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 60533 bytes, from 2014-10-15 18:32:43)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48)
|
||||
|
||||
Copyright (C) 2013-2014 by the following authors:
|
||||
- Rob Clark <robdclark@gmail.com> (robclark)
|
||||
@@ -132,6 +132,7 @@ enum a3xx_threadmode {
|
||||
};
|
||||
|
||||
enum a3xx_instrbuffermode {
|
||||
CACHE = 0,
|
||||
BUFFER = 1,
|
||||
};
|
||||
|
||||
|
@@ -11,10 +11,10 @@ The rules-ng-ng source files this header was generated from are:
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2013-11-30 14:47:15)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 9859 bytes, from 2014-06-02 15:21:30)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14477 bytes, from 2014-07-19 17:20:53)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 58020 bytes, from 2014-07-19 17:21:17)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 36670 bytes, from 2014-07-19 17:18:34)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10347 bytes, from 2014-10-01 18:55:57)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14960 bytes, from 2014-07-27 17:22:13)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 60533 bytes, from 2014-10-15 18:32:43)
|
||||
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 41068 bytes, from 2014-08-01 12:22:48)
|
||||
|
||||
Copyright (C) 2013-2014 by the following authors:
|
||||
- Rob Clark <robdclark@gmail.com> (robclark)
|
||||
@@ -163,12 +163,16 @@ enum adreno_pm4_type3_packets {
|
||||
CP_INDIRECT_BUFFER_PFE = 63,
|
||||
CP_SET_BIN = 76,
|
||||
CP_TEST_TWO_MEMS = 113,
|
||||
CP_REG_WR_NO_CTXT = 120,
|
||||
CP_RECORD_PFP_TIMESTAMP = 17,
|
||||
CP_WAIT_FOR_ME = 19,
|
||||
CP_SET_DRAW_STATE = 67,
|
||||
CP_DRAW_INDX_OFFSET = 56,
|
||||
CP_DRAW_INDIRECT = 40,
|
||||
CP_DRAW_INDX_INDIRECT = 41,
|
||||
CP_DRAW_AUTO = 36,
|
||||
CP_UNKNOWN_1A = 26,
|
||||
CP_WIDE_REG_WRITE = 116,
|
||||
IN_IB_PREFETCH_END = 23,
|
||||
IN_SUBBLK_PREFETCH = 31,
|
||||
IN_INSTR_PREFETCH = 32,
|
||||
|
@@ -100,7 +100,7 @@ fd_context_render(struct pipe_context *pctx)
|
||||
if (!ctx->needs_flush)
|
||||
return;
|
||||
|
||||
fd_gmem_render_tiles(pctx);
|
||||
fd_gmem_render_tiles(ctx);
|
||||
|
||||
DBG("%p/%p/%p", ctx->ring->start, ctx->ring->cur, ctx->ring->end);
|
||||
|
||||
@@ -111,7 +111,7 @@ fd_context_render(struct pipe_context *pctx)
|
||||
fd_context_next_rb(pctx);
|
||||
|
||||
ctx->needs_flush = false;
|
||||
ctx->cleared = ctx->restore = ctx->resolve = 0;
|
||||
ctx->cleared = ctx->partial_cleared = ctx->restore = ctx->resolve = 0;
|
||||
ctx->gmem_reason = 0;
|
||||
ctx->num_draws = 0;
|
||||
|
||||
@@ -148,8 +148,6 @@ fd_context_destroy(struct pipe_context *pctx)
|
||||
fd_prog_fini(pctx);
|
||||
fd_hw_query_fini(pctx);
|
||||
|
||||
util_slab_destroy(&ctx->transfer_pool);
|
||||
|
||||
util_dynarray_fini(&ctx->draw_patches);
|
||||
|
||||
if (ctx->blitter)
|
||||
@@ -158,6 +156,8 @@ fd_context_destroy(struct pipe_context *pctx)
|
||||
if (ctx->primconvert)
|
||||
util_primconvert_destroy(ctx->primconvert);
|
||||
|
||||
util_slab_destroy(&ctx->transfer_pool);
|
||||
|
||||
fd_ringmarker_del(ctx->draw_start);
|
||||
fd_ringmarker_del(ctx->draw_end);
|
||||
fd_ringmarker_del(ctx->binning_start);
|
||||
|
@@ -83,6 +83,15 @@ struct fd_vertex_stateobj {
|
||||
unsigned num_elements;
|
||||
};
|
||||
|
||||
/* group together the vertex and vertexbuf state.. for ease of passing
|
||||
* around, and because various internal operations (gmem<->mem, etc)
|
||||
* need their own vertex state:
|
||||
*/
|
||||
struct fd_vertex_state {
|
||||
struct fd_vertex_stateobj *vtx;
|
||||
struct fd_vertexbuf_stateobj vertexbuf;
|
||||
};
|
||||
|
||||
/* Bitmask of stages in rendering that a particular query query is
|
||||
* active. Queries will be automatically started/stopped (generating
|
||||
* additional fd_hw_sample_period's) on entrance/exit from stages that
|
||||
@@ -174,6 +183,10 @@ struct fd_context {
|
||||
* there was a glClear() that invalidated the entire previous buffer
|
||||
* contents. Keep track of which buffer(s) are cleared, or needs
|
||||
* restore. Masks of PIPE_CLEAR_*
|
||||
*
|
||||
* The 'cleared' bits will be set for buffers which are *entirely*
|
||||
* cleared, and 'partial_cleared' bits will be set if you must
|
||||
* check cleared_scissor.
|
||||
*/
|
||||
enum {
|
||||
/* align bitmask values w/ PIPE_CLEAR_*.. since that is convenient.. */
|
||||
@@ -181,7 +194,7 @@ struct fd_context {
|
||||
FD_BUFFER_DEPTH = PIPE_CLEAR_DEPTH,
|
||||
FD_BUFFER_STENCIL = PIPE_CLEAR_STENCIL,
|
||||
FD_BUFFER_ALL = FD_BUFFER_COLOR | FD_BUFFER_DEPTH | FD_BUFFER_STENCIL,
|
||||
} cleared, restore, resolve;
|
||||
} cleared, partial_cleared, restore, resolve;
|
||||
|
||||
bool needs_flush;
|
||||
|
||||
@@ -222,6 +235,14 @@ struct fd_context {
|
||||
struct fd_ringbuffer *rings[8];
|
||||
unsigned rings_idx;
|
||||
|
||||
/* NOTE: currently using a single ringbuffer for both draw and
|
||||
* tiling commands, we need to make sure we need to leave enough
|
||||
* room at the end to append the tiling commands when we flush.
|
||||
* 0x7000 dwords should be a couple times more than we ever need
|
||||
* so should be a nice conservative threshold.
|
||||
*/
|
||||
#define FD_TILING_COMMANDS_DWORDS 0x7000
|
||||
|
||||
/* normal draw/clear cmds: */
|
||||
struct fd_ringbuffer *ring;
|
||||
struct fd_ringmarker *draw_start, *draw_end;
|
||||
@@ -260,6 +281,14 @@ struct fd_context {
|
||||
*/
|
||||
struct pipe_scissor_state max_scissor;
|
||||
|
||||
/* Track the cleared scissor for color/depth/stencil, so we know
|
||||
* which, if any, tiles need to be restored (mem2gmem). Only valid
|
||||
* if the corresponding bit in ctx->cleared is set.
|
||||
*/
|
||||
struct {
|
||||
struct pipe_scissor_state color, depth, stencil;
|
||||
} cleared_scissor;
|
||||
|
||||
/* Current gmem/tiling configuration.. gets updated on render_tiles()
|
||||
* if out of date with current maximal-scissor/cpp:
|
||||
*/
|
||||
@@ -297,7 +326,7 @@ struct fd_context {
|
||||
|
||||
struct fd_program_stateobj prog;
|
||||
|
||||
struct fd_vertex_stateobj *vtx;
|
||||
struct fd_vertex_state vtx;
|
||||
|
||||
struct pipe_blend_color blend_color;
|
||||
struct pipe_stencil_ref stencil_ref;
|
||||
@@ -306,7 +335,6 @@ struct fd_context {
|
||||
struct pipe_poly_stipple stipple;
|
||||
struct pipe_viewport_state viewport;
|
||||
struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
|
||||
struct fd_vertexbuf_stateobj vertexbuf;
|
||||
struct pipe_index_buffer indexbuf;
|
||||
|
||||
/* GMEM/tile handling fxns: */
|
||||
|
@@ -40,51 +40,6 @@
|
||||
#include "freedreno_util.h"
|
||||
|
||||
|
||||
static enum pc_di_index_size
|
||||
size2indextype(unsigned index_size)
|
||||
{
|
||||
switch (index_size) {
|
||||
case 1: return INDEX_SIZE_8_BIT;
|
||||
case 2: return INDEX_SIZE_16_BIT;
|
||||
case 4: return INDEX_SIZE_32_BIT;
|
||||
}
|
||||
DBG("unsupported index size: %d", index_size);
|
||||
assert(0);
|
||||
return INDEX_SIZE_IGN;
|
||||
}
|
||||
|
||||
/* this is same for a2xx/a3xx, so split into helper: */
|
||||
void
|
||||
fd_draw_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
enum pc_di_vis_cull_mode vismode,
|
||||
const struct pipe_draw_info *info)
|
||||
{
|
||||
struct pipe_index_buffer *idx = &ctx->indexbuf;
|
||||
struct fd_bo *idx_bo = NULL;
|
||||
enum pc_di_index_size idx_type = INDEX_SIZE_IGN;
|
||||
enum pc_di_src_sel src_sel;
|
||||
uint32_t idx_size, idx_offset;
|
||||
|
||||
if (info->indexed) {
|
||||
assert(!idx->user_buffer);
|
||||
|
||||
idx_bo = fd_resource(idx->buffer)->bo;
|
||||
idx_type = size2indextype(idx->index_size);
|
||||
idx_size = idx->index_size * info->count;
|
||||
idx_offset = idx->offset + (info->start * idx->index_size);
|
||||
src_sel = DI_SRC_SEL_DMA;
|
||||
} else {
|
||||
idx_bo = NULL;
|
||||
idx_type = INDEX_SIZE_IGN;
|
||||
idx_size = 0;
|
||||
idx_offset = 0;
|
||||
src_sel = DI_SRC_SEL_AUTO_INDEX;
|
||||
}
|
||||
|
||||
fd_draw(ctx, ring, ctx->primtypes[info->mode], vismode, src_sel,
|
||||
info->count, idx_type, idx_size, idx_offset, idx_bo);
|
||||
}
|
||||
|
||||
static void
|
||||
fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||
{
|
||||
@@ -152,13 +107,30 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
|
||||
ctx->stats.prims_emitted +=
|
||||
u_reduced_prims_for_vertices(info->mode, info->count);
|
||||
|
||||
/* any buffers that haven't been cleared, we need to restore: */
|
||||
/* any buffers that haven't been cleared yet, we need to restore: */
|
||||
ctx->restore |= buffers & (FD_BUFFER_ALL & ~ctx->cleared);
|
||||
/* and any buffers used, need to be resolved: */
|
||||
ctx->resolve |= buffers;
|
||||
|
||||
DBG("%x num_draws=%u (%s/%s)", buffers, ctx->num_draws,
|
||||
util_format_short_name(pipe_surface_format(pfb->cbufs[0])),
|
||||
util_format_short_name(pipe_surface_format(pfb->zsbuf)));
|
||||
|
||||
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_DRAW);
|
||||
ctx->draw(ctx, info);
|
||||
|
||||
/* if an app (or, well, piglit test) does many thousands of draws
|
||||
* without flush (or anything which implicitly flushes, like
|
||||
* changing render targets), we can exceed the ringbuffer size.
|
||||
* Since we don't currently have a sane way to wrapparound, and
|
||||
* we use the same buffer for both draw and tiling commands, for
|
||||
* now we need to do this hack and trigger flush if we are running
|
||||
* low on remaining space for cmds:
|
||||
*/
|
||||
if (((ctx->ring->cur - ctx->ring->start) >
|
||||
(ctx->ring->size/4 - FD_TILING_COMMANDS_DWORDS)) ||
|
||||
(fd_mesa_debug & FD_DBG_FLUSH))
|
||||
fd_context_render(pctx);
|
||||
}
|
||||
|
||||
/* TODO figure out how to make better use of existing state mechanism
|
||||
@@ -173,8 +145,30 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
|
||||
struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
|
||||
unsigned cleared_buffers;
|
||||
|
||||
ctx->cleared |= buffers;
|
||||
/* for bookkeeping about which buffers have been cleared (and thus
|
||||
* can fully or partially skip mem2gmem) we need to ignore buffers
|
||||
* that have already had a draw, in case apps do silly things like
|
||||
* clear after draw (ie. if you only clear the color buffer, but
|
||||
* something like alpha-test causes side effects from the draw in
|
||||
* the depth buffer, etc)
|
||||
*/
|
||||
cleared_buffers = buffers & (FD_BUFFER_ALL & ~ctx->restore);
|
||||
|
||||
/* do we have full-screen scissor? */
|
||||
if (!memcmp(scissor, &ctx->disabled_scissor, sizeof(*scissor))) {
|
||||
ctx->cleared |= cleared_buffers;
|
||||
} else {
|
||||
ctx->partial_cleared |= cleared_buffers;
|
||||
if (cleared_buffers & PIPE_CLEAR_COLOR)
|
||||
ctx->cleared_scissor.color = *scissor;
|
||||
if (cleared_buffers & PIPE_CLEAR_DEPTH)
|
||||
ctx->cleared_scissor.depth = *scissor;
|
||||
if (cleared_buffers & PIPE_CLEAR_STENCIL)
|
||||
ctx->cleared_scissor.stencil = *scissor;
|
||||
}
|
||||
ctx->resolve |= buffers;
|
||||
ctx->needs_flush = true;
|
||||
|
||||
|
@@ -33,15 +33,12 @@
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
#include "freedreno_context.h"
|
||||
#include "freedreno_resource.h"
|
||||
#include "freedreno_screen.h"
|
||||
#include "freedreno_util.h"
|
||||
|
||||
struct fd_ringbuffer;
|
||||
|
||||
void fd_draw_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
enum pc_di_vis_cull_mode vismode,
|
||||
const struct pipe_draw_info *info);
|
||||
|
||||
void fd_draw_init(struct pipe_context *pctx);
|
||||
|
||||
static inline void
|
||||
@@ -98,4 +95,50 @@ fd_draw(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
fd_reset_wfi(ctx);
|
||||
}
|
||||
|
||||
|
||||
static inline enum pc_di_index_size
|
||||
size2indextype(unsigned index_size)
|
||||
{
|
||||
switch (index_size) {
|
||||
case 1: return INDEX_SIZE_8_BIT;
|
||||
case 2: return INDEX_SIZE_16_BIT;
|
||||
case 4: return INDEX_SIZE_32_BIT;
|
||||
}
|
||||
DBG("unsupported index size: %d", index_size);
|
||||
assert(0);
|
||||
return INDEX_SIZE_IGN;
|
||||
}
|
||||
|
||||
/* this is same for a2xx/a3xx, so split into helper: */
|
||||
static inline void
|
||||
fd_draw_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
|
||||
enum pc_di_vis_cull_mode vismode,
|
||||
const struct pipe_draw_info *info)
|
||||
{
|
||||
struct pipe_index_buffer *idx = &ctx->indexbuf;
|
||||
struct fd_bo *idx_bo = NULL;
|
||||
enum pc_di_index_size idx_type = INDEX_SIZE_IGN;
|
||||
enum pc_di_src_sel src_sel;
|
||||
uint32_t idx_size, idx_offset;
|
||||
|
||||
if (info->indexed) {
|
||||
assert(!idx->user_buffer);
|
||||
|
||||
idx_bo = fd_resource(idx->buffer)->bo;
|
||||
idx_type = size2indextype(idx->index_size);
|
||||
idx_size = idx->index_size * info->count;
|
||||
idx_offset = idx->offset + (info->start * idx->index_size);
|
||||
src_sel = DI_SRC_SEL_DMA;
|
||||
} else {
|
||||
idx_bo = NULL;
|
||||
idx_type = INDEX_SIZE_IGN;
|
||||
idx_size = 0;
|
||||
idx_offset = 0;
|
||||
src_sel = DI_SRC_SEL_AUTO_INDEX;
|
||||
}
|
||||
|
||||
fd_draw(ctx, ring, ctx->primtypes[info->mode], vismode, src_sel,
|
||||
info->count, idx_type, idx_size, idx_offset, idx_bo);
|
||||
}
|
||||
|
||||
#endif /* FREEDRENO_DRAW_H_ */
|
||||
|
@@ -314,9 +314,8 @@ render_sysmem(struct fd_context *ctx)
|
||||
}
|
||||
|
||||
void
|
||||
fd_gmem_render_tiles(struct pipe_context *pctx)
|
||||
fd_gmem_render_tiles(struct fd_context *ctx)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
|
||||
uint32_t timestamp = 0;
|
||||
bool sysmem = false;
|
||||
@@ -381,28 +380,50 @@ fd_gmem_render_tiles(struct pipe_context *pctx)
|
||||
ctx->max_scissor.minx = ctx->max_scissor.miny = ~0;
|
||||
ctx->max_scissor.maxx = ctx->max_scissor.maxy = 0;
|
||||
|
||||
/* Note that because the per-tile setup and mem2gmem/gmem2mem are emitted
|
||||
* after the draw/clear calls, but executed before, we need to preemptively
|
||||
* flag some state as dirty before the first draw/clear call.
|
||||
*
|
||||
* TODO maybe we need to mark all state as dirty to not worry about state
|
||||
* being clobbered by other contexts?
|
||||
*/
|
||||
ctx->dirty |= FD_DIRTY_ZSA |
|
||||
FD_DIRTY_RASTERIZER |
|
||||
FD_DIRTY_FRAMEBUFFER |
|
||||
FD_DIRTY_SAMPLE_MASK |
|
||||
FD_DIRTY_VIEWPORT |
|
||||
FD_DIRTY_CONSTBUF |
|
||||
FD_DIRTY_PROG |
|
||||
FD_DIRTY_SCISSOR |
|
||||
/* probably only needed if we need to mem2gmem on the next
|
||||
* draw.. but not sure if there is a good way to know?
|
||||
*/
|
||||
FD_DIRTY_VERTTEX |
|
||||
FD_DIRTY_FRAGTEX |
|
||||
FD_DIRTY_BLEND;
|
||||
|
||||
if (fd_mesa_debug & FD_DBG_DGMEM)
|
||||
ctx->dirty = 0xffffffff;
|
||||
ctx->dirty = ~0;
|
||||
}
|
||||
|
||||
/* tile needs restore if it isn't completely contained within the
|
||||
* cleared scissor:
|
||||
*/
|
||||
static bool
|
||||
skip_restore(struct pipe_scissor_state *scissor, struct fd_tile *tile)
|
||||
{
|
||||
unsigned minx = tile->xoff;
|
||||
unsigned maxx = tile->xoff + tile->bin_w;
|
||||
unsigned miny = tile->yoff;
|
||||
unsigned maxy = tile->yoff + tile->bin_h;
|
||||
return (minx >= scissor->minx) && (maxx <= scissor->maxx) &&
|
||||
(miny >= scissor->miny) && (maxy <= scissor->maxy);
|
||||
}
|
||||
|
||||
/* When deciding whether a tile needs mem2gmem, we need to take into
|
||||
* account the scissor rect(s) that were cleared. To simplify we only
|
||||
* consider the last scissor rect for each buffer, since the common
|
||||
* case would be a single clear.
|
||||
*/
|
||||
bool
|
||||
fd_gmem_needs_restore(struct fd_context *ctx, struct fd_tile *tile,
|
||||
uint32_t buffers)
|
||||
{
|
||||
if (!(ctx->restore & buffers))
|
||||
return false;
|
||||
|
||||
/* if buffers partially cleared, then slow-path to figure out
|
||||
* if this particular tile needs restoring:
|
||||
*/
|
||||
if ((buffers & FD_BUFFER_COLOR) &&
|
||||
(ctx->partial_cleared & FD_BUFFER_COLOR) &&
|
||||
skip_restore(&ctx->cleared_scissor.color, tile))
|
||||
return false;
|
||||
if ((buffers & FD_BUFFER_DEPTH) &&
|
||||
(ctx->partial_cleared & FD_BUFFER_DEPTH) &&
|
||||
skip_restore(&ctx->cleared_scissor.depth, tile))
|
||||
return false;
|
||||
if ((buffers & FD_BUFFER_STENCIL) &&
|
||||
(ctx->partial_cleared & FD_BUFFER_STENCIL) &&
|
||||
skip_restore(&ctx->cleared_scissor.stencil, tile))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -55,6 +55,11 @@ struct fd_gmem_stateobj {
|
||||
bool has_zs; /* gmem config using depth/stencil? */
|
||||
};
|
||||
|
||||
void fd_gmem_render_tiles(struct pipe_context *pctx);
|
||||
struct fd_context;
|
||||
|
||||
void fd_gmem_render_tiles(struct fd_context *ctx);
|
||||
|
||||
bool fd_gmem_needs_restore(struct fd_context *ctx, struct fd_tile *tile,
|
||||
uint32_t buffers);
|
||||
|
||||
#endif /* FREEDRENO_GMEM_H_ */
|
||||
|
@@ -52,6 +52,7 @@ struct fd_lowering_context {
|
||||
#define B 1
|
||||
struct tgsi_full_src_register imm;
|
||||
int emitted_decls;
|
||||
unsigned saturate;
|
||||
};
|
||||
|
||||
static inline struct fd_lowering_context *
|
||||
@@ -130,12 +131,14 @@ aliases(const struct tgsi_full_dst_register *dst, unsigned dst_mask,
|
||||
static void
|
||||
create_mov(struct tgsi_transform_context *tctx,
|
||||
const struct tgsi_full_dst_register *dst,
|
||||
const struct tgsi_full_src_register *src, unsigned mask)
|
||||
const struct tgsi_full_src_register *src,
|
||||
unsigned mask, unsigned saturate)
|
||||
{
|
||||
struct tgsi_full_instruction new_inst;
|
||||
|
||||
new_inst = tgsi_default_full_instruction();
|
||||
new_inst.Instruction.Opcode = TGSI_OPCODE_MOV;
|
||||
new_inst.Instruction.Saturate = saturate;
|
||||
new_inst.Instruction.NumDstRegs = 1;
|
||||
reg_dst(&new_inst.Dst[0], dst, mask);
|
||||
new_inst.Instruction.NumSrcRegs = 1;
|
||||
@@ -143,6 +146,25 @@ create_mov(struct tgsi_transform_context *tctx,
|
||||
tctx->emit_instruction(tctx, &new_inst);
|
||||
}
|
||||
|
||||
/* to help calculate # of tgsi tokens for a lowering.. we assume
|
||||
* the worst case, ie. removed instructions don't have ADDR[] or
|
||||
* anything which increases the # of tokens per src/dst and the
|
||||
* inserted instructions do.
|
||||
*
|
||||
* OINST() - old instruction
|
||||
* 1 : instruction itself
|
||||
* 1 : dst
|
||||
* 1 * nargs : srcN
|
||||
*
|
||||
* NINST() - new instruction
|
||||
* 1 : instruction itself
|
||||
* 2 : dst
|
||||
* 2 * nargs : srcN
|
||||
*/
|
||||
|
||||
#define OINST(nargs) (1 + 1 + 1 * (nargs))
|
||||
#define NINST(nargs) (1 + 2 + 2 * (nargs))
|
||||
|
||||
/*
|
||||
* Lowering Translators:
|
||||
*/
|
||||
@@ -169,7 +191,8 @@ create_mov(struct tgsi_transform_context *tctx,
|
||||
* MOV dst.w, src1.w
|
||||
* MOV dst.x, imm{1.0}
|
||||
*/
|
||||
#define DST_GROW (19 - 4)
|
||||
#define DST_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1) + \
|
||||
NINST(1) + NINST(1) - OINST(2))
|
||||
#define DST_TMP 2
|
||||
static void
|
||||
transform_dst(struct tgsi_transform_context *tctx,
|
||||
@@ -182,12 +205,12 @@ transform_dst(struct tgsi_transform_context *tctx,
|
||||
struct tgsi_full_instruction new_inst;
|
||||
|
||||
if (aliases(dst, TGSI_WRITEMASK_Y, src0, TGSI_WRITEMASK_Z)) {
|
||||
create_mov(tctx, &ctx->tmp[A].dst, src0, TGSI_WRITEMASK_YZ);
|
||||
create_mov(tctx, &ctx->tmp[A].dst, src0, TGSI_WRITEMASK_YZ, 0);
|
||||
src0 = &ctx->tmp[A].src;
|
||||
}
|
||||
|
||||
if (aliases(dst, TGSI_WRITEMASK_YZ, src1, TGSI_WRITEMASK_W)) {
|
||||
create_mov(tctx, &ctx->tmp[B].dst, src1, TGSI_WRITEMASK_YW);
|
||||
create_mov(tctx, &ctx->tmp[B].dst, src1, TGSI_WRITEMASK_YW, 0);
|
||||
src1 = &ctx->tmp[B].src;
|
||||
}
|
||||
|
||||
@@ -249,7 +272,7 @@ transform_dst(struct tgsi_transform_context *tctx,
|
||||
* SUB dst.xyz, tmpA.xyz, tmpB.xyz
|
||||
* MOV dst.w, imm{1.0}
|
||||
*/
|
||||
#define XPD_GROW (15 - 4)
|
||||
#define XPD_GROW (NINST(2) + NINST(2) + NINST(2) + NINST(1) - OINST(2))
|
||||
#define XPD_TMP 2
|
||||
static void
|
||||
transform_xpd(struct tgsi_transform_context *tctx,
|
||||
@@ -320,7 +343,7 @@ transform_xpd(struct tgsi_transform_context *tctx,
|
||||
* SIN dst.y, src.x
|
||||
* MOV dst.zw, imm{0.0, 1.0}
|
||||
*/
|
||||
#define SCS_GROW (12 - 3)
|
||||
#define SCS_GROW (NINST(1) + NINST(1) + NINST(1) + NINST(1) - OINST(1))
|
||||
#define SCS_TMP 1
|
||||
static void
|
||||
transform_scs(struct tgsi_transform_context *tctx,
|
||||
@@ -332,7 +355,7 @@ transform_scs(struct tgsi_transform_context *tctx,
|
||||
struct tgsi_full_instruction new_inst;
|
||||
|
||||
if (aliases(dst, TGSI_WRITEMASK_X, src, TGSI_WRITEMASK_X)) {
|
||||
create_mov(tctx, &ctx->tmp[A].dst, src, TGSI_WRITEMASK_X);
|
||||
create_mov(tctx, &ctx->tmp[A].dst, src, TGSI_WRITEMASK_X, 0);
|
||||
src = &ctx->tmp[A].src;
|
||||
}
|
||||
|
||||
@@ -382,7 +405,7 @@ transform_scs(struct tgsi_transform_context *tctx,
|
||||
* MUL tmpB, tmpB, src2
|
||||
* ADD dst, tmpA, tmpB
|
||||
*/
|
||||
#define LRP_GROW (16 - 4)
|
||||
#define LRP_GROW (NINST(2) + NINST(2) + NINST(2) + NINST(2) - OINST(3))
|
||||
#define LRP_TMP 2
|
||||
static void
|
||||
transform_lrp(struct tgsi_transform_context *tctx,
|
||||
@@ -448,7 +471,7 @@ transform_lrp(struct tgsi_transform_context *tctx,
|
||||
* FLR tmpA, src
|
||||
* SUB dst, src, tmpA
|
||||
*/
|
||||
#define FRC_GROW (7 - 3)
|
||||
#define FRC_GROW (NINST(1) + NINST(2) - OINST(1))
|
||||
#define FRC_TMP 1
|
||||
static void
|
||||
transform_frc(struct tgsi_transform_context *tctx,
|
||||
@@ -492,7 +515,7 @@ transform_frc(struct tgsi_transform_context *tctx,
|
||||
* MUL tmpA.x, src1.x, tmpA.x
|
||||
* EX2 dst, tmpA.x
|
||||
*/
|
||||
#define POW_GROW (10 - 4)
|
||||
#define POW_GROW (NINST(1) + NINST(2) + NINST(1) - OINST(2))
|
||||
#define POW_TMP 1
|
||||
static void
|
||||
transform_pow(struct tgsi_transform_context *tctx,
|
||||
@@ -551,7 +574,8 @@ transform_pow(struct tgsi_transform_context *tctx,
|
||||
* MOV dst.yz, tmpA.xy
|
||||
* MOV dst.xw, imm{1.0}
|
||||
*/
|
||||
#define LIT_GROW (30 - 3)
|
||||
#define LIT_GROW (NINST(1) + NINST(3) + NINST(1) + NINST(2) + \
|
||||
NINST(1) + NINST(3) + NINST(1) + NINST(1) - OINST(1))
|
||||
#define LIT_TMP 1
|
||||
static void
|
||||
transform_lit(struct tgsi_transform_context *tctx,
|
||||
@@ -661,7 +685,8 @@ transform_lit(struct tgsi_transform_context *tctx,
|
||||
* MOV dst.z, tmpA.y
|
||||
* MOV dst.w, imm{1.0}
|
||||
*/
|
||||
#define EXP_GROW (19 - 3)
|
||||
#define EXP_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1) + \
|
||||
NINST(1)+ NINST(1) - OINST(1))
|
||||
#define EXP_TMP 1
|
||||
static void
|
||||
transform_exp(struct tgsi_transform_context *tctx,
|
||||
@@ -755,7 +780,8 @@ transform_exp(struct tgsi_transform_context *tctx,
|
||||
* MOV dst.xz, tmpA.yx
|
||||
* MOV dst.w, imm{1.0}
|
||||
*/
|
||||
#define LOG_GROW (25 - 3)
|
||||
#define LOG_GROW (NINST(1) + NINST(1) + NINST(1) + NINST(1) + \
|
||||
NINST(2) + NINST(1) + NINST(1) - OINST(1))
|
||||
#define LOG_TMP 1
|
||||
static void
|
||||
transform_log(struct tgsi_transform_context *tctx,
|
||||
@@ -879,11 +905,11 @@ transform_log(struct tgsi_transform_context *tctx,
|
||||
* }
|
||||
* ; fixup last instruction to replicate into dst
|
||||
*/
|
||||
#define DP4_GROW (19 - 4)
|
||||
#define DP3_GROW (14 - 4)
|
||||
#define DPH_GROW (18 - 4)
|
||||
#define DP2_GROW ( 9 - 4)
|
||||
#define DP2A_GROW (13 - 4)
|
||||
#define DP4_GROW (NINST(2) + NINST(3) + NINST(3) + NINST(3) - OINST(2))
|
||||
#define DP3_GROW (NINST(2) + NINST(3) + NINST(3) - OINST(2))
|
||||
#define DPH_GROW (NINST(2) + NINST(3) + NINST(3) + NINST(2) - OINST(2))
|
||||
#define DP2_GROW (NINST(2) + NINST(3) - OINST(2))
|
||||
#define DP2A_GROW (NINST(2) + NINST(3) + NINST(2) - OINST(3))
|
||||
#define DOTP_TMP 1
|
||||
static void
|
||||
transform_dotp(struct tgsi_transform_context *tctx,
|
||||
@@ -981,6 +1007,138 @@ transform_dotp(struct tgsi_transform_context *tctx,
|
||||
}
|
||||
}
|
||||
|
||||
/* Inserts a MOV_SAT for the needed components of tex coord. Note that
|
||||
* in the case of TXP, the clamping must happen *after* projection, so
|
||||
* we need to lower TXP to TEX.
|
||||
*
|
||||
* MOV tmpA, src0
|
||||
* if (opc == TXP) {
|
||||
* ; do perspective division manually before clamping:
|
||||
* RCP tmpB, tmpA.w
|
||||
* MUL tmpB.<pmask>, tmpA, tmpB.xxxx
|
||||
* opc = TEX;
|
||||
* }
|
||||
* MOV_SAT tmpA.<mask>, tmpA ; <mask> is the clamped s/t/r coords
|
||||
* <opc> dst, tmpA, ...
|
||||
*/
|
||||
#define SAMP_GROW (NINST(1) + NINST(1) + NINST(2) + NINST(1))
|
||||
#define SAMP_TMP 2
|
||||
static int
|
||||
transform_samp(struct tgsi_transform_context *tctx,
|
||||
struct tgsi_full_instruction *inst)
|
||||
{
|
||||
struct fd_lowering_context *ctx = fd_lowering_context(tctx);
|
||||
struct tgsi_full_src_register *coord = &inst->Src[0];
|
||||
struct tgsi_full_src_register *samp;
|
||||
struct tgsi_full_instruction new_inst;
|
||||
/* mask is clamped coords, pmask is all coords (for projection): */
|
||||
unsigned mask = 0, pmask = 0, smask;
|
||||
unsigned opcode = inst->Instruction.Opcode;
|
||||
|
||||
if (opcode == TGSI_OPCODE_TXB2) {
|
||||
samp = &inst->Src[2];
|
||||
} else {
|
||||
samp = &inst->Src[1];
|
||||
}
|
||||
|
||||
/* convert sampler # to bitmask to test: */
|
||||
smask = 1 << samp->Register.Index;
|
||||
|
||||
/* check if we actually need to lower this one: */
|
||||
if (!(ctx->saturate & smask))
|
||||
return -1;
|
||||
|
||||
/* figure out which coordinates need saturating:
|
||||
* - RECT textures should not get saturated
|
||||
* - array index coords should not get saturated
|
||||
*/
|
||||
switch (inst->Texture.Texture) {
|
||||
case TGSI_TEXTURE_3D:
|
||||
case TGSI_TEXTURE_CUBE:
|
||||
case TGSI_TEXTURE_CUBE_ARRAY:
|
||||
case TGSI_TEXTURE_SHADOWCUBE:
|
||||
case TGSI_TEXTURE_SHADOWCUBE_ARRAY:
|
||||
if (ctx->config->saturate_r & smask)
|
||||
mask |= TGSI_WRITEMASK_Z;
|
||||
pmask |= TGSI_WRITEMASK_Z;
|
||||
/* fallthrough */
|
||||
|
||||
case TGSI_TEXTURE_2D:
|
||||
case TGSI_TEXTURE_2D_ARRAY:
|
||||
case TGSI_TEXTURE_SHADOW2D:
|
||||
case TGSI_TEXTURE_SHADOW2D_ARRAY:
|
||||
case TGSI_TEXTURE_2D_MSAA:
|
||||
case TGSI_TEXTURE_2D_ARRAY_MSAA:
|
||||
if (ctx->config->saturate_t & smask)
|
||||
mask |= TGSI_WRITEMASK_Y;
|
||||
pmask |= TGSI_WRITEMASK_Y;
|
||||
/* fallthrough */
|
||||
|
||||
case TGSI_TEXTURE_1D:
|
||||
case TGSI_TEXTURE_1D_ARRAY:
|
||||
case TGSI_TEXTURE_SHADOW1D:
|
||||
case TGSI_TEXTURE_SHADOW1D_ARRAY:
|
||||
if (ctx->config->saturate_s & smask)
|
||||
mask |= TGSI_WRITEMASK_X;
|
||||
pmask |= TGSI_WRITEMASK_X;
|
||||
break;
|
||||
|
||||
/* TODO: I think we should ignore these?
|
||||
case TGSI_TEXTURE_RECT:
|
||||
case TGSI_TEXTURE_SHADOWRECT:
|
||||
*/
|
||||
}
|
||||
|
||||
/* sanity check.. driver could be asking to saturate a non-
|
||||
* existent coordinate component:
|
||||
*/
|
||||
if (!mask)
|
||||
return -1;
|
||||
|
||||
/* MOV tmpA, src0 */
|
||||
create_mov(tctx, &ctx->tmp[A].dst, coord, TGSI_WRITEMASK_XYZW, 0);
|
||||
|
||||
/* This is a bit sad.. we need to clamp *after* the coords
|
||||
* are projected, which means lowering TXP to TEX and doing
|
||||
* the projection ourself. But since I haven't figured out
|
||||
* how to make the lowering code deliver an electric shock
|
||||
* to anyone using GL_CLAMP, we must do this instead:
|
||||
*/
|
||||
if (opcode == TGSI_OPCODE_TXP) {
|
||||
/* RCP tmpB.x tmpA.w */
|
||||
new_inst = tgsi_default_full_instruction();
|
||||
new_inst.Instruction.Opcode = TGSI_OPCODE_RCP;
|
||||
new_inst.Instruction.NumDstRegs = 1;
|
||||
reg_dst(&new_inst.Dst[0], &ctx->tmp[B].dst, TGSI_WRITEMASK_X);
|
||||
new_inst.Instruction.NumSrcRegs = 1;
|
||||
reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(W,_,_,_));
|
||||
tctx->emit_instruction(tctx, &new_inst);
|
||||
|
||||
/* MUL tmpA.mask, tmpA, tmpB.xxxx */
|
||||
new_inst = tgsi_default_full_instruction();
|
||||
new_inst.Instruction.Opcode = TGSI_OPCODE_MUL;
|
||||
new_inst.Instruction.NumDstRegs = 1;
|
||||
reg_dst(&new_inst.Dst[0], &ctx->tmp[A].dst, pmask);
|
||||
new_inst.Instruction.NumSrcRegs = 2;
|
||||
reg_src(&new_inst.Src[0], &ctx->tmp[A].src, SWIZ(X,Y,Z,W));
|
||||
reg_src(&new_inst.Src[1], &ctx->tmp[B].src, SWIZ(X,X,X,X));
|
||||
tctx->emit_instruction(tctx, &new_inst);
|
||||
|
||||
opcode = TGSI_OPCODE_TEX;
|
||||
}
|
||||
|
||||
/* MOV_SAT tmpA.<mask>, tmpA */
|
||||
create_mov(tctx, &ctx->tmp[A].dst, &ctx->tmp[A].src, mask,
|
||||
TGSI_SAT_ZERO_ONE);
|
||||
|
||||
/* modify the texture samp instruction to take fixed up coord: */
|
||||
new_inst = *inst;
|
||||
new_inst.Instruction.Opcode = opcode;
|
||||
new_inst.Src[0] = ctx->tmp[A].src;
|
||||
tctx->emit_instruction(tctx, &new_inst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Two-sided color emulation:
|
||||
* For each COLOR input, create a corresponding BCOLOR input, plus
|
||||
@@ -990,7 +1148,7 @@ transform_dotp(struct tgsi_transform_context *tctx,
|
||||
2 + /* FACE */ \
|
||||
((n) * 2) + /* IN[] BCOLOR[n] */ \
|
||||
((n) * 1) + /* TEMP[] */ \
|
||||
((n) * 5) /* CMP instr */ \
|
||||
((n) * NINST(3)) /* CMP instr */ \
|
||||
)
|
||||
|
||||
static void
|
||||
@@ -1234,6 +1392,14 @@ transform_instr(struct tgsi_transform_context *tctx,
|
||||
goto skip;
|
||||
transform_dotp(tctx, inst);
|
||||
break;
|
||||
case TGSI_OPCODE_TEX:
|
||||
case TGSI_OPCODE_TXP:
|
||||
case TGSI_OPCODE_TXB:
|
||||
case TGSI_OPCODE_TXB2:
|
||||
case TGSI_OPCODE_TXL:
|
||||
if (transform_samp(tctx, inst))
|
||||
goto skip;
|
||||
break;
|
||||
default:
|
||||
skip:
|
||||
tctx->emit_instruction(tctx, inst);
|
||||
@@ -1254,6 +1420,9 @@ fd_transform_lowering(const struct fd_lowering_config *config,
|
||||
struct tgsi_token *newtoks;
|
||||
int newlen, numtmp;
|
||||
|
||||
/* sanity check in case limit is ever increased: */
|
||||
assert((sizeof(config->saturate_s) * 8) >= PIPE_MAX_SAMPLERS);
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.base.transform_instruction = transform_instr;
|
||||
ctx.info = info;
|
||||
@@ -1277,6 +1446,8 @@ fd_transform_lowering(const struct fd_lowering_config *config,
|
||||
}
|
||||
}
|
||||
|
||||
ctx.saturate = config->saturate_r | config->saturate_s | config->saturate_t;
|
||||
|
||||
#define OPCS(x) ((config->lower_ ## x) ? info->opcode_count[TGSI_OPCODE_ ## x] : 0)
|
||||
/* if there are no instructions to lower, then we are done: */
|
||||
if (!(OPCS(DST) ||
|
||||
@@ -1293,7 +1464,8 @@ fd_transform_lowering(const struct fd_lowering_config *config,
|
||||
OPCS(DPH) ||
|
||||
OPCS(DP2) ||
|
||||
OPCS(DP2A) ||
|
||||
ctx.two_side_colors))
|
||||
ctx.two_side_colors ||
|
||||
ctx.saturate))
|
||||
return NULL;
|
||||
|
||||
#if 0 /* debug */
|
||||
@@ -1359,6 +1531,15 @@ fd_transform_lowering(const struct fd_lowering_config *config,
|
||||
newlen += DP2A_GROW * OPCS(DP2A);
|
||||
numtmp = MAX2(numtmp, DOTP_TMP);
|
||||
}
|
||||
if (ctx.saturate) {
|
||||
int n = info->opcode_count[TGSI_OPCODE_TEX] +
|
||||
info->opcode_count[TGSI_OPCODE_TXP] +
|
||||
info->opcode_count[TGSI_OPCODE_TXB] +
|
||||
info->opcode_count[TGSI_OPCODE_TXB2] +
|
||||
info->opcode_count[TGSI_OPCODE_TXL];
|
||||
newlen += SAMP_GROW * n;
|
||||
numtmp = MAX2(numtmp, SAMP_TMP);
|
||||
}
|
||||
|
||||
/* specifically don't include two_side_colors temps in the count: */
|
||||
ctx.numtmp = numtmp;
|
||||
|
@@ -69,6 +69,16 @@ struct fd_lowering_config {
|
||||
unsigned lower_DPH : 1;
|
||||
unsigned lower_DP2 : 1;
|
||||
unsigned lower_DP2A : 1;
|
||||
|
||||
/* To emulate certain texture wrap modes, this can be used
|
||||
* to saturate the specified tex coord to [0.0, 1.0]. The
|
||||
* bits are according to sampler #, ie. if, for example:
|
||||
*
|
||||
* (conf->saturate_s & (1 << n))
|
||||
*
|
||||
* is true, then the s coord for sampler n is saturated.
|
||||
*/
|
||||
unsigned saturate_s, saturate_t, saturate_r;
|
||||
};
|
||||
|
||||
const struct tgsi_token * fd_transform_lowering(
|
||||
|
@@ -67,7 +67,7 @@ static const char *solid_vp =
|
||||
static const char *blit_fp =
|
||||
"FRAG \n"
|
||||
"PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1 \n"
|
||||
"DCL IN[0], TEXCOORD \n"
|
||||
"DCL IN[0], TEXCOORD[0], PERSPECTIVE \n"
|
||||
"DCL OUT[0], COLOR \n"
|
||||
"DCL SAMP[0] \n"
|
||||
" 0: TEX OUT[0], IN[0], SAMP[0], 2D \n"
|
||||
@@ -77,7 +77,7 @@ static const char *blit_vp =
|
||||
"VERT \n"
|
||||
"DCL IN[0] \n"
|
||||
"DCL IN[1] \n"
|
||||
"DCL OUT[0], TEXCOORD \n"
|
||||
"DCL OUT[0], TEXCOORD[0] \n"
|
||||
"DCL OUT[1], POSITION \n"
|
||||
" 0: MOV OUT[0], IN[0] \n"
|
||||
" 0: MOV OUT[1], IN[1] \n"
|
||||
|
@@ -183,12 +183,16 @@ fd_hw_get_query_result(struct fd_context *ctx, struct fd_query *q,
|
||||
return false;
|
||||
|
||||
/* if the app tries to read back the query result before the
|
||||
* back is submitted, that forces us to flush so that there
|
||||
* batch is submitted, that forces us to flush so that there
|
||||
* are actually results to wait for:
|
||||
*/
|
||||
if (!LIST_IS_EMPTY(&hq->list)) {
|
||||
/* if app didn't actually trigger any cmdstream, then
|
||||
* we have nothing to do:
|
||||
*/
|
||||
if (!ctx->needs_flush)
|
||||
return true;
|
||||
DBG("reading query result forces flush!");
|
||||
ctx->needs_flush = true;
|
||||
fd_context_render(&ctx->base);
|
||||
}
|
||||
|
||||
@@ -201,9 +205,6 @@ fd_hw_get_query_result(struct fd_context *ctx, struct fd_query *q,
|
||||
assert(LIST_IS_EMPTY(&hq->current_periods));
|
||||
assert(!hq->period);
|
||||
|
||||
if (LIST_IS_EMPTY(&hq->periods))
|
||||
return true;
|
||||
|
||||
/* if !wait, then check the last sample (the one most likely to
|
||||
* not be ready yet) and bail if it is not ready:
|
||||
*/
|
||||
|
@@ -116,7 +116,7 @@ fd_resource_transfer_map(struct pipe_context *pctx,
|
||||
ptrans->usage = usage;
|
||||
ptrans->box = *box;
|
||||
ptrans->stride = slice->pitch * rsc->cpp;
|
||||
ptrans->layer_stride = ptrans->stride;
|
||||
ptrans->layer_stride = slice->size0;
|
||||
|
||||
if (usage & PIPE_TRANSFER_READ)
|
||||
op |= DRM_FREEDRENO_PREP_READ;
|
||||
@@ -199,9 +199,8 @@ setup_slices(struct fd_resource *rsc)
|
||||
|
||||
for (level = 0; level <= prsc->last_level; level++) {
|
||||
struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
|
||||
uint32_t aligned_width = align(width, 32);
|
||||
|
||||
slice->pitch = aligned_width;
|
||||
slice->pitch = align(width, 32);
|
||||
slice->offset = size;
|
||||
slice->size0 = slice->pitch * height * rsc->cpp;
|
||||
|
||||
@@ -215,6 +214,35 @@ setup_slices(struct fd_resource *rsc)
|
||||
return size;
|
||||
}
|
||||
|
||||
/* 2d array and 3d textures seem to want their layers aligned to
|
||||
* page boundaries
|
||||
*/
|
||||
static uint32_t
|
||||
setup_slices_array(struct fd_resource *rsc)
|
||||
{
|
||||
struct pipe_resource *prsc = &rsc->base.b;
|
||||
uint32_t level, size = 0;
|
||||
uint32_t width = prsc->width0;
|
||||
uint32_t height = prsc->height0;
|
||||
uint32_t depth = prsc->depth0;
|
||||
|
||||
for (level = 0; level <= prsc->last_level; level++) {
|
||||
struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
|
||||
|
||||
slice->pitch = align(width, 32);
|
||||
slice->offset = size;
|
||||
slice->size0 = align(slice->pitch * height * rsc->cpp, 4096);
|
||||
|
||||
size += slice->size0 * depth * prsc->array_size;
|
||||
|
||||
width = u_minify(width, 1);
|
||||
height = u_minify(height, 1);
|
||||
depth = u_minify(depth, 1);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new texture object, using the given template info.
|
||||
*/
|
||||
@@ -246,7 +274,16 @@ fd_resource_create(struct pipe_screen *pscreen,
|
||||
|
||||
assert(rsc->cpp);
|
||||
|
||||
size = setup_slices(rsc);
|
||||
switch (tmpl->target) {
|
||||
case PIPE_TEXTURE_3D:
|
||||
case PIPE_TEXTURE_1D_ARRAY:
|
||||
case PIPE_TEXTURE_2D_ARRAY:
|
||||
size = setup_slices_array(rsc);
|
||||
break;
|
||||
default:
|
||||
size = setup_slices(rsc);
|
||||
break;
|
||||
}
|
||||
|
||||
realloc_bo(rsc, size);
|
||||
if (!rsc->bo)
|
||||
@@ -304,7 +341,36 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool render_blit(struct pipe_context *pctx, struct pipe_blit_info *info);
|
||||
static void fd_blitter_pipe_begin(struct fd_context *ctx);
|
||||
static void fd_blitter_pipe_end(struct fd_context *ctx);
|
||||
|
||||
/**
|
||||
* _copy_region using pipe (3d engine)
|
||||
*/
|
||||
static bool
|
||||
fd_blitter_pipe_copy_region(struct fd_context *ctx,
|
||||
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)
|
||||
{
|
||||
/* not until we allow rendertargets to be buffers */
|
||||
if (dst->target == PIPE_BUFFER || src->target == PIPE_BUFFER)
|
||||
return false;
|
||||
|
||||
if (!util_blitter_is_copy_supported(ctx->blitter, dst, src))
|
||||
return false;
|
||||
|
||||
fd_blitter_pipe_begin(ctx);
|
||||
util_blitter_copy_texture(ctx->blitter,
|
||||
dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box);
|
||||
fd_blitter_pipe_end(ctx);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a block of pixels from one resource to another.
|
||||
@@ -320,40 +386,33 @@ fd_resource_copy_region(struct pipe_context *pctx,
|
||||
unsigned src_level,
|
||||
const struct pipe_box *src_box)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
|
||||
/* TODO if we have 2d core, or other DMA engine that could be used
|
||||
* for simple copies and reasonably easily synchronized with the 3d
|
||||
* core, this is where we'd plug it in..
|
||||
*/
|
||||
struct pipe_blit_info info = {
|
||||
.dst = {
|
||||
.resource = dst,
|
||||
.box = {
|
||||
.x = dstx,
|
||||
.y = dsty,
|
||||
.z = dstz,
|
||||
.width = src_box->width,
|
||||
.height = src_box->height,
|
||||
.depth = src_box->depth,
|
||||
},
|
||||
.format = util_format_linear(dst->format),
|
||||
},
|
||||
.src = {
|
||||
.resource = src,
|
||||
.box = *src_box,
|
||||
.format = util_format_linear(src->format),
|
||||
},
|
||||
.mask = PIPE_MASK_RGBA,
|
||||
.filter = PIPE_TEX_FILTER_NEAREST,
|
||||
};
|
||||
render_blit(pctx, &info);
|
||||
|
||||
/* try blit on 3d pipe: */
|
||||
if (fd_blitter_pipe_copy_region(ctx,
|
||||
dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box))
|
||||
return;
|
||||
|
||||
/* else fallback to pure sw: */
|
||||
util_resource_copy_region(pctx,
|
||||
dst, dst_level, dstx, dsty, dstz,
|
||||
src, src_level, src_box);
|
||||
}
|
||||
|
||||
/* Optimal hardware path for blitting pixels.
|
||||
/**
|
||||
* Optimal hardware path for blitting pixels.
|
||||
* Scaling, format conversion, up- and downsampling (resolve) are allowed.
|
||||
*/
|
||||
static void
|
||||
fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct pipe_blit_info info = *blit_info;
|
||||
|
||||
if (info.src.resource->nr_samples > 1 &&
|
||||
@@ -373,23 +432,23 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
|
||||
info.mask &= ~PIPE_MASK_S;
|
||||
}
|
||||
|
||||
render_blit(pctx, &info);
|
||||
}
|
||||
|
||||
static bool
|
||||
render_blit(struct pipe_context *pctx, struct pipe_blit_info *info)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
|
||||
if (!util_blitter_is_blit_supported(ctx->blitter, info)) {
|
||||
if (!util_blitter_is_blit_supported(ctx->blitter, &info)) {
|
||||
DBG("blit unsupported %s -> %s",
|
||||
util_format_short_name(info->src.resource->format),
|
||||
util_format_short_name(info->dst.resource->format));
|
||||
return false;
|
||||
util_format_short_name(info.src.resource->format),
|
||||
util_format_short_name(info.dst.resource->format));
|
||||
return;
|
||||
}
|
||||
|
||||
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vertexbuf.vb);
|
||||
util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx);
|
||||
fd_blitter_pipe_begin(ctx);
|
||||
util_blitter_blit(ctx->blitter, &info);
|
||||
fd_blitter_pipe_end(ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
fd_blitter_pipe_begin(struct fd_context *ctx)
|
||||
{
|
||||
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
|
||||
util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx.vtx);
|
||||
util_blitter_save_vertex_shader(ctx->blitter, ctx->prog.vp);
|
||||
util_blitter_save_rasterizer(ctx->blitter, ctx->rasterizer);
|
||||
util_blitter_save_viewport(ctx->blitter, &ctx->viewport);
|
||||
@@ -407,15 +466,21 @@ render_blit(struct pipe_context *pctx, struct pipe_blit_info *info)
|
||||
ctx->fragtex.num_textures, ctx->fragtex.textures);
|
||||
|
||||
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_BLIT);
|
||||
util_blitter_blit(ctx->blitter, info);
|
||||
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
fd_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource)
|
||||
fd_blitter_pipe_end(struct fd_context *ctx)
|
||||
{
|
||||
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fd_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
|
||||
{
|
||||
struct fd_resource *rsc = fd_resource(prsc);
|
||||
|
||||
if (rsc->dirty)
|
||||
fd_context_render(pctx);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -60,7 +60,7 @@ static const struct debug_named_value debug_options[] = {
|
||||
{"msgs", FD_DBG_MSGS, "Print debug messages"},
|
||||
{"disasm", FD_DBG_DISASM, "Dump TGSI and adreno shader disassembly"},
|
||||
{"dclear", FD_DBG_DCLEAR, "Mark all state dirty after clear"},
|
||||
{"dgmem", FD_DBG_DGMEM, "Mark all state dirty after GMEM tile pass"},
|
||||
{"flush", FD_DBG_FLUSH, "Force flush after every draw"},
|
||||
{"dscis", FD_DBG_DSCIS, "Disable scissor optimization"},
|
||||
{"direct", FD_DBG_DIRECT, "Force inline (SS_DIRECT) state loads"},
|
||||
{"dbypass", FD_DBG_DBYPASS,"Disable GMEM bypass"},
|
||||
@@ -70,6 +70,7 @@ static const struct debug_named_value debug_options[] = {
|
||||
{"optmsgs", FD_DBG_OPTMSGS,"Enable optimizater debug messages"},
|
||||
{"optdump", FD_DBG_OPTDUMP,"Dump shader DAG to .dot files"},
|
||||
{"glsl130", FD_DBG_GLSL130,"Temporary flag to enable GLSL 130 on a3xx+"},
|
||||
{"nocp", FD_DBG_NOCP, "Disable copy-propagation"},
|
||||
DEBUG_NAMED_VALUE_END
|
||||
};
|
||||
|
||||
@@ -156,23 +157,18 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_ANISOTROPIC_FILTER:
|
||||
case PIPE_CAP_POINT_SPRITE:
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
||||
case PIPE_CAP_BLEND_EQUATION_SEPARATE:
|
||||
case PIPE_CAP_TEXTURE_SWIZZLE:
|
||||
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
|
||||
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:
|
||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP:
|
||||
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
|
||||
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
|
||||
case PIPE_CAP_TGSI_INSTANCEID:
|
||||
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
|
||||
case PIPE_CAP_COMPUTE:
|
||||
case PIPE_CAP_START_INSTANCE:
|
||||
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
|
||||
case PIPE_CAP_USER_CONSTANT_BUFFERS:
|
||||
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT:
|
||||
return 1;
|
||||
@@ -181,12 +177,23 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_TGSI_TEXCOORD:
|
||||
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
|
||||
case PIPE_CAP_CONDITIONAL_RENDER:
|
||||
case PIPE_CAP_PRIMITIVE_RESTART:
|
||||
case PIPE_CAP_TEXTURE_MULTISAMPLE:
|
||||
case PIPE_CAP_TEXTURE_BARRIER:
|
||||
case PIPE_CAP_SM3:
|
||||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
|
||||
case PIPE_CAP_CUBE_MAP_ARRAY:
|
||||
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
|
||||
case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
|
||||
case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
|
||||
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
|
||||
case PIPE_CAP_TGSI_INSTANCEID:
|
||||
case PIPE_CAP_START_INSTANCE:
|
||||
case PIPE_CAP_COMPUTE:
|
||||
return 0;
|
||||
|
||||
case PIPE_CAP_SM3:
|
||||
case PIPE_CAP_PRIMITIVE_RESTART:
|
||||
return (screen->gpu_id >= 300) ? 1 : 0;
|
||||
|
||||
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
|
||||
return 256;
|
||||
|
||||
@@ -199,7 +206,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_DEPTH_CLIP_DISABLE:
|
||||
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
|
||||
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
|
||||
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER:
|
||||
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
|
||||
case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
|
||||
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
|
||||
@@ -220,6 +227,9 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
|
||||
return 0;
|
||||
|
||||
case PIPE_CAP_MAX_VIEWPORTS:
|
||||
return 1;
|
||||
|
||||
/* Stream output. */
|
||||
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
|
||||
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
|
||||
@@ -235,11 +245,13 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
|
||||
/* Texturing. */
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
return MAX_MIP_LEVELS;
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
return 11;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
|
||||
return 0; /* TODO: a3xx+ should support (required in gles3) */
|
||||
return (screen->gpu_id >= 300) ? 256 : 0;
|
||||
|
||||
/* Render targets. */
|
||||
case PIPE_CAP_MAX_RENDER_TARGETS:
|
||||
@@ -277,11 +289,9 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
|
||||
return 10;
|
||||
case PIPE_CAP_UMA:
|
||||
return 1;
|
||||
|
||||
default:
|
||||
DBG("unknown param %d", param);
|
||||
return 0;
|
||||
}
|
||||
debug_printf("unknown param %d\n", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float
|
||||
@@ -296,16 +306,15 @@ fd_screen_get_paramf(struct pipe_screen *pscreen, enum pipe_capf param)
|
||||
case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
|
||||
return 16.0f;
|
||||
case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
|
||||
return 16.0f;
|
||||
return 15.0f;
|
||||
case PIPE_CAPF_GUARD_BAND_LEFT:
|
||||
case PIPE_CAPF_GUARD_BAND_TOP:
|
||||
case PIPE_CAPF_GUARD_BAND_RIGHT:
|
||||
case PIPE_CAPF_GUARD_BAND_BOTTOM:
|
||||
return 0.0f;
|
||||
default:
|
||||
DBG("unknown paramf %d", param);
|
||||
return 0;
|
||||
}
|
||||
debug_printf("unknown paramf %d\n", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -342,7 +351,11 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
|
||||
case PIPE_SHADER_CAP_MAX_TEMPS:
|
||||
return 64; /* Max native temporaries. */
|
||||
case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
|
||||
return ((screen->gpu_id >= 300) ? 1024 : 64) * sizeof(float[4]);
|
||||
/* NOTE: seems to be limit for a3xx is actually 512 but
|
||||
* split between VS and FS. Use lower limit of 256 to
|
||||
* avoid getting into impossible situations:
|
||||
*/
|
||||
return ((screen->gpu_id >= 300) ? 256 : 64) * sizeof(float[4]);
|
||||
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS:
|
||||
return 1;
|
||||
case PIPE_SHADER_CAP_MAX_PREDS:
|
||||
@@ -355,6 +368,7 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
|
||||
case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR:
|
||||
return 1;
|
||||
case PIPE_SHADER_CAP_SUBROUTINES:
|
||||
case PIPE_SHADER_CAP_DOUBLES:
|
||||
return 0;
|
||||
case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
|
||||
return 1;
|
||||
@@ -368,10 +382,8 @@ fd_screen_get_shader_param(struct pipe_screen *pscreen, unsigned shader,
|
||||
return 16;
|
||||
case PIPE_SHADER_CAP_PREFERRED_IR:
|
||||
return PIPE_SHADER_IR_TGSI;
|
||||
default:
|
||||
DBG("unknown shader param %d", param);
|
||||
return 0;
|
||||
}
|
||||
debug_printf("unknown shader param %d\n", param);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -388,6 +400,9 @@ fd_screen_bo_get_handle(struct pipe_screen *pscreen,
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
|
||||
whandle->handle = fd_bo_handle(bo);
|
||||
return TRUE;
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
|
||||
whandle->handle = fd_bo_dmabuf(bo);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
@@ -401,12 +416,17 @@ fd_screen_bo_from_handle(struct pipe_screen *pscreen,
|
||||
struct fd_screen *screen = fd_screen(pscreen);
|
||||
struct fd_bo *bo;
|
||||
|
||||
if (whandle->type != DRM_API_HANDLE_TYPE_SHARED) {
|
||||
if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
|
||||
bo = fd_bo_from_name(screen->dev, whandle->handle);
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
|
||||
bo = fd_bo_from_handle(screen->dev, whandle->handle, 0);
|
||||
} else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
|
||||
bo = fd_bo_from_dmabuf(screen->dev, whandle->handle);
|
||||
} else {
|
||||
DBG("Attempt to import unsupported handle type %d", whandle->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bo = fd_bo_from_name(screen->dev, whandle->handle);
|
||||
if (!bo) {
|
||||
DBG("ref name 0x%08x failed", whandle->handle);
|
||||
return NULL;
|
||||
|
@@ -177,7 +177,7 @@ fd_set_vertex_buffers(struct pipe_context *pctx,
|
||||
const struct pipe_vertex_buffer *vb)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct fd_vertexbuf_stateobj *so = &ctx->vertexbuf;
|
||||
struct fd_vertexbuf_stateobj *so = &ctx->vtx.vertexbuf;
|
||||
int i;
|
||||
|
||||
/* on a2xx, pitch is encoded in the vtx fetch instruction, so
|
||||
@@ -237,8 +237,18 @@ static void
|
||||
fd_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
struct pipe_scissor_state *old_scissor = fd_context_get_scissor(ctx);
|
||||
|
||||
ctx->rasterizer = hwcso;
|
||||
ctx->dirty |= FD_DIRTY_RASTERIZER;
|
||||
|
||||
/* if scissor enable bit changed we need to mark scissor
|
||||
* state as dirty as well:
|
||||
* NOTE: we can do a shallow compare, since we only care
|
||||
* if it changed to/from &ctx->disable_scissor
|
||||
*/
|
||||
if (old_scissor != fd_context_get_scissor(ctx))
|
||||
ctx->dirty |= FD_DIRTY_SCISSOR;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -286,7 +296,7 @@ static void
|
||||
fd_vertex_state_bind(struct pipe_context *pctx, void *hwcso)
|
||||
{
|
||||
struct fd_context *ctx = fd_context(pctx);
|
||||
ctx->vtx = hwcso;
|
||||
ctx->vtx.vtx = hwcso;
|
||||
ctx->dirty |= FD_DIRTY_VTXSTATE;
|
||||
}
|
||||
|
||||
|
@@ -49,7 +49,7 @@ fd_sampler_view_destroy(struct pipe_context *pctx,
|
||||
FREE(view);
|
||||
}
|
||||
|
||||
static void bind_sampler_states(struct fd_texture_stateobj *prog,
|
||||
static void bind_sampler_states(struct fd_texture_stateobj *tex,
|
||||
unsigned nr, void **hwcso)
|
||||
{
|
||||
unsigned i;
|
||||
@@ -58,19 +58,19 @@ static void bind_sampler_states(struct fd_texture_stateobj *prog,
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (hwcso[i])
|
||||
new_nr = i + 1;
|
||||
prog->samplers[i] = hwcso[i];
|
||||
prog->dirty_samplers |= (1 << i);
|
||||
tex->samplers[i] = hwcso[i];
|
||||
tex->dirty_samplers |= (1 << i);
|
||||
}
|
||||
|
||||
for (; i < prog->num_samplers; i++) {
|
||||
prog->samplers[i] = NULL;
|
||||
prog->dirty_samplers |= (1 << i);
|
||||
for (; i < tex->num_samplers; i++) {
|
||||
tex->samplers[i] = NULL;
|
||||
tex->dirty_samplers |= (1 << i);
|
||||
}
|
||||
|
||||
prog->num_samplers = new_nr;
|
||||
tex->num_samplers = new_nr;
|
||||
}
|
||||
|
||||
static void set_sampler_views(struct fd_texture_stateobj *prog,
|
||||
static void set_sampler_views(struct fd_texture_stateobj *tex,
|
||||
unsigned nr, struct pipe_sampler_view **views)
|
||||
{
|
||||
unsigned i;
|
||||
@@ -79,19 +79,19 @@ static void set_sampler_views(struct fd_texture_stateobj *prog,
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (views[i])
|
||||
new_nr = i + 1;
|
||||
pipe_sampler_view_reference(&prog->textures[i], views[i]);
|
||||
prog->dirty_samplers |= (1 << i);
|
||||
pipe_sampler_view_reference(&tex->textures[i], views[i]);
|
||||
tex->dirty_samplers |= (1 << i);
|
||||
}
|
||||
|
||||
for (; i < prog->num_textures; i++) {
|
||||
pipe_sampler_view_reference(&prog->textures[i], NULL);
|
||||
prog->dirty_samplers |= (1 << i);
|
||||
for (; i < tex->num_textures; i++) {
|
||||
pipe_sampler_view_reference(&tex->textures[i], NULL);
|
||||
tex->dirty_samplers |= (1 << i);
|
||||
}
|
||||
|
||||
prog->num_textures = new_nr;
|
||||
tex->num_textures = new_nr;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
fd_sampler_states_bind(struct pipe_context *pctx,
|
||||
unsigned shader, unsigned start,
|
||||
unsigned nr, void **hwcso)
|
||||
@@ -101,13 +101,6 @@ fd_sampler_states_bind(struct pipe_context *pctx,
|
||||
assert(start == 0);
|
||||
|
||||
if (shader == PIPE_SHADER_FRAGMENT) {
|
||||
/* on a2xx, since there is a flat address space for textures/samplers,
|
||||
* a change in # of fragment textures/samplers will trigger patching and
|
||||
* re-emitting the vertex shader:
|
||||
*/
|
||||
if (nr != ctx->fragtex.num_samplers)
|
||||
ctx->dirty |= FD_DIRTY_TEXSTATE;
|
||||
|
||||
bind_sampler_states(&ctx->fragtex, nr, hwcso);
|
||||
ctx->dirty |= FD_DIRTY_FRAGTEX;
|
||||
}
|
||||
@@ -169,6 +162,5 @@ fd_texture_init(struct pipe_context *pctx)
|
||||
|
||||
pctx->sampler_view_destroy = fd_sampler_view_destroy;
|
||||
|
||||
pctx->bind_sampler_states = fd_sampler_states_bind;
|
||||
pctx->set_sampler_views = fd_set_sampler_views;
|
||||
}
|
||||
|
@@ -31,6 +31,10 @@
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
|
||||
void fd_sampler_states_bind(struct pipe_context *pctx,
|
||||
unsigned shader, unsigned start,
|
||||
unsigned nr, void **hwcso);
|
||||
|
||||
void fd_texture_init(struct pipe_context *pctx);
|
||||
|
||||
#endif /* FREEDRENO_TEXTURE_H_ */
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_half.h"
|
||||
#include "util/u_dynarray.h"
|
||||
#include "util/u_pack_color.h"
|
||||
|
||||
#include "adreno_common.xml.h"
|
||||
#include "adreno_pm4.xml.h"
|
||||
@@ -55,7 +56,7 @@ enum adreno_stencil_op fd_stencil_op(unsigned op);
|
||||
#define FD_DBG_MSGS 0x0001
|
||||
#define FD_DBG_DISASM 0x0002
|
||||
#define FD_DBG_DCLEAR 0x0004
|
||||
#define FD_DBG_DGMEM 0x0008
|
||||
#define FD_DBG_FLUSH 0x0008
|
||||
#define FD_DBG_DSCIS 0x0010
|
||||
#define FD_DBG_DIRECT 0x0020
|
||||
#define FD_DBG_DBYPASS 0x0040
|
||||
@@ -65,6 +66,7 @@ enum adreno_stencil_op fd_stencil_op(unsigned op);
|
||||
#define FD_DBG_OPTMSGS 0x0400
|
||||
#define FD_DBG_OPTDUMP 0x0800
|
||||
#define FD_DBG_GLSL130 0x1000
|
||||
#define FD_DBG_NOCP 0x2000
|
||||
|
||||
extern int fd_mesa_debug;
|
||||
extern bool fd_binning_enabled;
|
||||
@@ -208,6 +210,10 @@ static inline void
|
||||
OUT_IB(struct fd_ringbuffer *ring, struct fd_ringmarker *start,
|
||||
struct fd_ringmarker *end)
|
||||
{
|
||||
uint32_t dwords = fd_ringmarker_dwords(start, end);
|
||||
|
||||
assert(dwords > 0);
|
||||
|
||||
/* for debug after a lock up, write a unique counter value
|
||||
* to scratch6 for each IB, to make it easier to match up
|
||||
* register dumps to cmdstream. The combination of IB and
|
||||
@@ -218,7 +224,7 @@ OUT_IB(struct fd_ringbuffer *ring, struct fd_ringmarker *start,
|
||||
|
||||
OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2);
|
||||
fd_ringbuffer_emit_reloc_ring(ring, start, end);
|
||||
OUT_RING(ring, fd_ringmarker_dwords(start, end));
|
||||
OUT_RING(ring, dwords);
|
||||
|
||||
emit_marker(ring, 6);
|
||||
}
|
||||
@@ -238,4 +244,24 @@ emit_marker(struct fd_ringbuffer *ring, int scratch_idx)
|
||||
OUT_RING(ring, ++marker_cnt);
|
||||
}
|
||||
|
||||
/* helper to get numeric value from environment variable.. mostly
|
||||
* just leaving this here because it is helpful to brute-force figure
|
||||
* out unknown formats, etc, which blob driver does not support:
|
||||
*/
|
||||
static inline uint32_t env2u(const char *envvar)
|
||||
{
|
||||
char *str = getenv(envvar);
|
||||
if (str)
|
||||
return strtol(str, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
pack_rgba(enum pipe_format format, const float *rgba)
|
||||
{
|
||||
union util_color uc;
|
||||
util_pack_color(rgba, format, &uc);
|
||||
return uc.ui[0];
|
||||
}
|
||||
|
||||
#endif /* FREEDRENO_UTIL_H_ */
|
||||
|
@@ -81,6 +81,8 @@ void ir3_destroy(struct ir3 *shader)
|
||||
shader->chunk = chunk->next;
|
||||
free(chunk);
|
||||
}
|
||||
free(shader->instrs);
|
||||
free(shader->baryfs);
|
||||
free(shader);
|
||||
}
|
||||
|
||||
@@ -104,7 +106,7 @@ static uint32_t reg(struct ir3_register *reg, struct ir3_info *info,
|
||||
val.iim_val = reg->iim_val;
|
||||
} else {
|
||||
int8_t components = util_last_bit(reg->wrmask);
|
||||
int8_t max = (reg->num + repeat + components - 1) >> 2;
|
||||
int16_t max = (reg->num + repeat + components - 1) >> 2;
|
||||
|
||||
val.comp = reg->num & 0x3;
|
||||
val.num = reg->num >> 2;
|
||||
@@ -596,6 +598,15 @@ static void insert_instr(struct ir3 *shader,
|
||||
shader->instrs_sz * sizeof(shader->instrs[0]));
|
||||
}
|
||||
shader->instrs[shader->instrs_count++] = instr;
|
||||
|
||||
if (is_input(instr)) {
|
||||
if (shader->baryfs_count == shader->baryfs_sz) {
|
||||
shader->baryfs_sz = MAX2(2 * shader->baryfs_sz, 16);
|
||||
shader->baryfs = realloc(shader->baryfs,
|
||||
shader->baryfs_sz * sizeof(shader->baryfs[0]));
|
||||
}
|
||||
shader->baryfs[shader->baryfs_count++] = instr;
|
||||
}
|
||||
}
|
||||
|
||||
struct ir3_block * ir3_block_create(struct ir3 *shader,
|
||||
|
@@ -47,7 +47,7 @@ struct ir3_info {
|
||||
*/
|
||||
int8_t max_reg; /* highest GPR # used by shader */
|
||||
int8_t max_half_reg;
|
||||
int8_t max_const;
|
||||
int16_t max_const;
|
||||
};
|
||||
|
||||
struct ir3_register {
|
||||
@@ -97,6 +97,8 @@ struct ir3_register {
|
||||
int wrmask;
|
||||
};
|
||||
|
||||
#define IR3_INSTR_SRCS 10
|
||||
|
||||
struct ir3_instruction {
|
||||
struct ir3_block *block;
|
||||
int category;
|
||||
@@ -156,7 +158,7 @@ struct ir3_instruction {
|
||||
} flags;
|
||||
int repeat;
|
||||
unsigned regs_count;
|
||||
struct ir3_register *regs[5];
|
||||
struct ir3_register *regs[1 + IR3_INSTR_SRCS];
|
||||
union {
|
||||
struct {
|
||||
char inv;
|
||||
@@ -208,7 +210,11 @@ struct ir3_instruction {
|
||||
* result of moving a const to a reg would have a low cost, so to
|
||||
* it could make sense to duplicate the instruction at various
|
||||
* points where the result is needed to reduce register footprint.
|
||||
*
|
||||
* DEPTH_UNUSED used to mark unused instructions after depth
|
||||
* calculation pass.
|
||||
*/
|
||||
#define DEPTH_UNUSED ~0
|
||||
unsigned depth;
|
||||
};
|
||||
struct ir3_instruction *next;
|
||||
@@ -222,6 +228,8 @@ struct ir3_heap_chunk;
|
||||
struct ir3 {
|
||||
unsigned instrs_count, instrs_sz;
|
||||
struct ir3_instruction **instrs;
|
||||
unsigned baryfs_count, baryfs_sz;
|
||||
struct ir3_instruction **baryfs;
|
||||
unsigned heap_idx;
|
||||
struct ir3_heap_chunk *chunk;
|
||||
};
|
||||
@@ -270,6 +278,10 @@ static inline void ir3_clear_mark(struct ir3 *shader)
|
||||
/* TODO would be nice to drop the instruction array.. for
|
||||
* new compiler, _clear_mark() is all we use it for, and
|
||||
* we could probably manage a linked list instead..
|
||||
*
|
||||
* Also, we'll probably want to mark instructions within
|
||||
* a block, so tracking the list of instrs globally is
|
||||
* unlikely to be what we want.
|
||||
*/
|
||||
unsigned i;
|
||||
for (i = 0; i < shader->instrs_count; i++) {
|
||||
@@ -406,12 +418,12 @@ void ir3_block_depth(struct ir3_block *block);
|
||||
void ir3_block_cp(struct ir3_block *block);
|
||||
|
||||
/* scheduling: */
|
||||
void ir3_block_sched(struct ir3_block *block);
|
||||
int ir3_block_sched(struct ir3_block *block);
|
||||
|
||||
/* register assignment: */
|
||||
int ir3_block_ra(struct ir3_block *block, enum shader_t type,
|
||||
bool half_precision, bool frag_coord, bool frag_face,
|
||||
bool *has_samp);
|
||||
bool *has_samp, int *max_bary);
|
||||
|
||||
#ifndef ARRAY_SIZE
|
||||
# define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
@@ -444,7 +456,7 @@ static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg)
|
||||
{
|
||||
unsigned idx = regmask_idx(reg);
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++, idx++)
|
||||
for (i = 0; i < IR3_INSTR_SRCS; i++, idx++)
|
||||
if (reg->wrmask & (1 << i))
|
||||
(*regmask)[idx / 8] |= 1 << (idx % 8);
|
||||
}
|
||||
@@ -457,7 +469,7 @@ static inline void regmask_set_if_not(regmask_t *a,
|
||||
{
|
||||
unsigned idx = regmask_idx(reg);
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++, idx++)
|
||||
for (i = 0; i < IR3_INSTR_SRCS; i++, idx++)
|
||||
if (reg->wrmask & (1 << i))
|
||||
if (!((*b)[idx / 8] & (1 << (idx % 8))))
|
||||
(*a)[idx / 8] |= 1 << (idx % 8);
|
||||
@@ -468,7 +480,7 @@ static inline unsigned regmask_get(regmask_t *regmask,
|
||||
{
|
||||
unsigned idx = regmask_idx(reg);
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++, idx++)
|
||||
for (i = 0; i < IR3_INSTR_SRCS; i++, idx++)
|
||||
if (reg->wrmask & (1 << i))
|
||||
if ((*regmask)[idx / 8] & (1 << (idx % 8)))
|
||||
return true;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -34,7 +34,7 @@
|
||||
|
||||
int ir3_compile_shader(struct ir3_shader_variant *so,
|
||||
const struct tgsi_token *tokens,
|
||||
struct ir3_shader_key key);
|
||||
struct ir3_shader_key key, bool cp);
|
||||
int ir3_compile_shader_old(struct ir3_shader_variant *so,
|
||||
const struct tgsi_token *tokens,
|
||||
struct ir3_shader_key key);
|
||||
|
@@ -125,7 +125,7 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
|
||||
{
|
||||
unsigned ret, base = 0;
|
||||
struct tgsi_shader_info *info = &ctx->info;
|
||||
const struct fd_lowering_config lconfig = {
|
||||
struct fd_lowering_config lconfig = {
|
||||
.color_two_side = so->key.color_two_side,
|
||||
.lower_DST = true,
|
||||
.lower_XPD = true,
|
||||
@@ -143,6 +143,20 @@ compile_init(struct ir3_compile_context *ctx, struct ir3_shader_variant *so,
|
||||
.lower_DP2A = true,
|
||||
};
|
||||
|
||||
switch (so->type) {
|
||||
case SHADER_FRAGMENT:
|
||||
case SHADER_COMPUTE:
|
||||
lconfig.saturate_s = so->key.fsaturate_s;
|
||||
lconfig.saturate_t = so->key.fsaturate_t;
|
||||
lconfig.saturate_r = so->key.fsaturate_r;
|
||||
break;
|
||||
case SHADER_VERTEX:
|
||||
lconfig.saturate_s = so->key.vsaturate_s;
|
||||
lconfig.saturate_t = so->key.vsaturate_t;
|
||||
lconfig.saturate_r = so->key.vsaturate_r;
|
||||
break;
|
||||
}
|
||||
|
||||
ctx->tokens = fd_transform_lowering(&lconfig, tokens, &ctx->info);
|
||||
ctx->free_tokens = !!ctx->tokens;
|
||||
if (!ctx->tokens) {
|
||||
|
@@ -70,7 +70,7 @@ static void walk_children(struct ir3_instruction *instr, bool keep)
|
||||
static struct ir3_instruction *
|
||||
instr_cp_fanin(struct ir3_instruction *instr)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned i, j;
|
||||
|
||||
/* we need to handle fanin specially, to detect cases
|
||||
* when we need to keep a mov
|
||||
@@ -92,7 +92,15 @@ instr_cp_fanin(struct ir3_instruction *instr)
|
||||
if (is_meta(cand) && (cand->opc == OPC_META_FO))
|
||||
cand = instr_cp(src->instr, true);
|
||||
|
||||
src->instr = cand;
|
||||
/* we can't have 2 registers referring to the same instruction, so
|
||||
* go through and check if any already refer to the candidate
|
||||
* instruction. if so, don't do the propagation.
|
||||
*/
|
||||
for (j = 1; j < instr->regs_count; j++)
|
||||
if (instr->regs[j]->instr == cand)
|
||||
break;
|
||||
if (j == instr->regs_count)
|
||||
src->instr = cand;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -150,10 +150,22 @@ void ir3_block_depth(struct ir3_block *block)
|
||||
if (block->outputs[i])
|
||||
ir3_instr_depth(block->outputs[i]);
|
||||
|
||||
/* at this point, any unvisited input is unused: */
|
||||
/* mark un-used instructions: */
|
||||
for (i = 0; i < block->shader->instrs_count; i++) {
|
||||
struct ir3_instruction *instr = block->shader->instrs[i];
|
||||
|
||||
/* just consider instructions within this block: */
|
||||
if (instr->block != block)
|
||||
continue;
|
||||
|
||||
if (!ir3_instr_check_mark(instr))
|
||||
instr->depth = DEPTH_UNUSED;
|
||||
}
|
||||
|
||||
/* cleanup unused inputs: */
|
||||
for (i = 0; i < block->ninputs; i++) {
|
||||
struct ir3_instruction *in = block->inputs[i];
|
||||
if (in && !ir3_instr_check_mark(in))
|
||||
if (in && (in->depth == DEPTH_UNUSED))
|
||||
block->inputs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@@ -322,7 +322,8 @@ static void ir3_block_dump(struct ir3_dump_ctx *ctx,
|
||||
|
||||
/* draw instruction graph: */
|
||||
for (i = 0; i < block->noutputs; i++)
|
||||
dump_instr(ctx, block->outputs[i]);
|
||||
if (block->outputs[i])
|
||||
dump_instr(ctx, block->outputs[i]);
|
||||
|
||||
/* draw outputs: */
|
||||
fprintf(ctx->f, "output%lx [shape=record,label=\"outputs", PTRID(block));
|
||||
|
@@ -58,6 +58,7 @@ struct ir3_ra_ctx {
|
||||
bool frag_face;
|
||||
bool has_samp;
|
||||
int cnt;
|
||||
int max_bary;
|
||||
bool error;
|
||||
};
|
||||
|
||||
@@ -253,7 +254,9 @@ static int alloc_block(struct ir3_ra_ctx *ctx,
|
||||
(instr->regs_count == 1)) {
|
||||
unsigned i, base = instr->regs[0]->num & ~0x3;
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct ir3_instruction *in = ctx->block->inputs[base + i];
|
||||
struct ir3_instruction *in = NULL;
|
||||
if ((base + i) < ctx->block->ninputs)
|
||||
in = ctx->block->inputs[base + i];
|
||||
if (in)
|
||||
compute_clobbers(ctx, in->next, in, &liveregs);
|
||||
}
|
||||
@@ -471,7 +474,9 @@ static void ra_assign_dst_shader_input(struct ir3_visitor *v,
|
||||
|
||||
/* trigger assignment of all our companion input components: */
|
||||
for (i = 0; i < 4; i++) {
|
||||
struct ir3_instruction *in = instr->block->inputs[i+base];
|
||||
struct ir3_instruction *in = NULL;
|
||||
if ((base + i) < instr->block->ninputs)
|
||||
in = instr->block->inputs[base + i];
|
||||
if (in && is_meta(in) && (in->opc == OPC_META_INPUT))
|
||||
ra_assign(a->ctx, in, a->num + off + i);
|
||||
}
|
||||
@@ -610,6 +615,12 @@ static void legalize(struct ir3_ra_ctx *ctx, struct ir3_block *block)
|
||||
if (is_meta(n))
|
||||
continue;
|
||||
|
||||
if (is_input(n)) {
|
||||
struct ir3_register *inloc = n->regs[1];
|
||||
assert(inloc->flags & IR3_REG_IMMED);
|
||||
ctx->max_bary = MAX2(ctx->max_bary, inloc->iim_val);
|
||||
}
|
||||
|
||||
for (i = 1; i < n->regs_count; i++) {
|
||||
reg = n->regs[i];
|
||||
|
||||
@@ -771,7 +782,7 @@ static int block_ra(struct ir3_ra_ctx *ctx, struct ir3_block *block)
|
||||
|
||||
int ir3_block_ra(struct ir3_block *block, enum shader_t type,
|
||||
bool half_precision, bool frag_coord, bool frag_face,
|
||||
bool *has_samp)
|
||||
bool *has_samp, int *max_bary)
|
||||
{
|
||||
struct ir3_ra_ctx ctx = {
|
||||
.block = block,
|
||||
@@ -779,12 +790,14 @@ int ir3_block_ra(struct ir3_block *block, enum shader_t type,
|
||||
.half_precision = half_precision,
|
||||
.frag_coord = frag_coord,
|
||||
.frag_face = frag_face,
|
||||
.max_bary = -1,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ir3_clear_mark(block->shader);
|
||||
ret = block_ra(&ctx, block);
|
||||
*has_samp = ctx.has_samp;
|
||||
*max_bary = ctx.max_bary;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@@ -64,6 +64,7 @@ struct ir3_sched_ctx {
|
||||
struct ir3_instruction *addr; /* current a0.x user, if any */
|
||||
struct ir3_instruction *pred; /* current p0.x user, if any */
|
||||
unsigned cnt;
|
||||
bool error;
|
||||
};
|
||||
|
||||
static struct ir3_instruction *
|
||||
@@ -161,7 +162,8 @@ static void schedule(struct ir3_sched_ctx *ctx,
|
||||
* Delay-slot calculation. Follows fanin/fanout.
|
||||
*/
|
||||
|
||||
static unsigned delay_calc2(struct ir3_sched_ctx *ctx,
|
||||
/* calculate delay for specified src: */
|
||||
static unsigned delay_calc_srcn(struct ir3_sched_ctx *ctx,
|
||||
struct ir3_instruction *assigner,
|
||||
struct ir3_instruction *consumer, unsigned srcn)
|
||||
{
|
||||
@@ -172,7 +174,7 @@ static unsigned delay_calc2(struct ir3_sched_ctx *ctx,
|
||||
for (i = 1; i < assigner->regs_count; i++) {
|
||||
struct ir3_register *reg = assigner->regs[i];
|
||||
if (reg->flags & IR3_REG_SSA) {
|
||||
unsigned d = delay_calc2(ctx, reg->instr,
|
||||
unsigned d = delay_calc_srcn(ctx, reg->instr,
|
||||
consumer, srcn);
|
||||
delay = MAX2(delay, d);
|
||||
}
|
||||
@@ -185,6 +187,7 @@ static unsigned delay_calc2(struct ir3_sched_ctx *ctx,
|
||||
return delay;
|
||||
}
|
||||
|
||||
/* calculate delay for instruction (maximum of delay for all srcs): */
|
||||
static unsigned delay_calc(struct ir3_sched_ctx *ctx,
|
||||
struct ir3_instruction *instr)
|
||||
{
|
||||
@@ -193,7 +196,7 @@ static unsigned delay_calc(struct ir3_sched_ctx *ctx,
|
||||
for (i = 1; i < instr->regs_count; i++) {
|
||||
struct ir3_register *reg = instr->regs[i];
|
||||
if (reg->flags & IR3_REG_SSA) {
|
||||
unsigned d = delay_calc2(ctx, reg->instr,
|
||||
unsigned d = delay_calc_srcn(ctx, reg->instr,
|
||||
instr, i - 1);
|
||||
delay = MAX2(delay, d);
|
||||
}
|
||||
@@ -239,6 +242,32 @@ static int trysched(struct ir3_sched_ctx *ctx,
|
||||
if (delay)
|
||||
return delay;
|
||||
|
||||
/* if the instruction is a kill, we need to ensure *every*
|
||||
* bary.f is scheduled. The hw seems unhappy if the thread
|
||||
* gets killed before the end-input (ei) flag is hit.
|
||||
*
|
||||
* We could do this by adding each bary.f instruction as
|
||||
* virtual ssa src for the kill instruction. But we have
|
||||
* fixed length instr->regs[].
|
||||
*
|
||||
* TODO this wouldn't be quite right if we had multiple
|
||||
* basic blocks, if any block was conditional. We'd need
|
||||
* to schedule the bary.f's outside of any block which
|
||||
* was conditional that contained a kill.. I think..
|
||||
*/
|
||||
if (is_kill(instr)) {
|
||||
struct ir3 *ir = instr->block->shader;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ir->baryfs_count; i++) {
|
||||
if (ir->baryfs[i]->depth == DEPTH_UNUSED)
|
||||
continue;
|
||||
delay = trysched(ctx, ir->baryfs[i]);
|
||||
if (delay)
|
||||
return delay;
|
||||
}
|
||||
}
|
||||
|
||||
/* if this is a write to address/predicate register, and that
|
||||
* register is currently in use, we need to defer until it is
|
||||
* free:
|
||||
@@ -308,7 +337,8 @@ static int block_sched_undelayed(struct ir3_sched_ctx *ctx,
|
||||
struct ir3_instruction *instr = block->head;
|
||||
bool addr_in_use = false;
|
||||
bool pred_in_use = false;
|
||||
unsigned cnt = ~0;
|
||||
bool all_delayed = true;
|
||||
unsigned cnt = ~0, attempted = 0;
|
||||
|
||||
while (instr) {
|
||||
struct ir3_instruction *next = instr->next;
|
||||
@@ -317,6 +347,10 @@ static int block_sched_undelayed(struct ir3_sched_ctx *ctx,
|
||||
|
||||
if (addr || pred) {
|
||||
int ret = trysched(ctx, instr);
|
||||
|
||||
if (ret != DELAYED)
|
||||
all_delayed = false;
|
||||
|
||||
if (ret == SCHEDULED)
|
||||
cnt = 0;
|
||||
else if (ret > 0)
|
||||
@@ -325,6 +359,8 @@ static int block_sched_undelayed(struct ir3_sched_ctx *ctx,
|
||||
addr_in_use = true;
|
||||
if (pred)
|
||||
pred_in_use = true;
|
||||
|
||||
attempted++;
|
||||
}
|
||||
|
||||
instr = next;
|
||||
@@ -336,6 +372,12 @@ static int block_sched_undelayed(struct ir3_sched_ctx *ctx,
|
||||
if (!pred_in_use)
|
||||
ctx->pred = NULL;
|
||||
|
||||
/* detect if we've gotten ourselves into an impossible situation
|
||||
* and bail if needed
|
||||
*/
|
||||
if (all_delayed && (attempted > 0))
|
||||
ctx->error = true;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
@@ -356,7 +398,7 @@ static void block_sched(struct ir3_sched_ctx *ctx, struct ir3_block *block)
|
||||
}
|
||||
}
|
||||
|
||||
while ((instr = block->head)) {
|
||||
while ((instr = block->head) && !ctx->error) {
|
||||
/* NOTE: always grab next *before* trysched(), in case the
|
||||
* instruction is actually scheduled (and therefore moved
|
||||
* from depth list into scheduled list)
|
||||
@@ -393,9 +435,12 @@ static void block_sched(struct ir3_sched_ctx *ctx, struct ir3_block *block)
|
||||
block->head = reverse(ctx->scheduled);
|
||||
}
|
||||
|
||||
void ir3_block_sched(struct ir3_block *block)
|
||||
int ir3_block_sched(struct ir3_block *block)
|
||||
{
|
||||
struct ir3_sched_ctx ctx = {0};
|
||||
ir3_clear_mark(block->shader);
|
||||
block_sched(&ctx, block);
|
||||
if (ctx.error)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -68,7 +68,11 @@ assemble_variant(struct ir3_shader_variant *v)
|
||||
free(bin);
|
||||
|
||||
v->instrlen = v->info.sizedwords / 8;
|
||||
v->constlen = v->info.max_const + 1;
|
||||
/* NOTE: if relative addressing is used, we set constlen in
|
||||
* the compiler (to worst-case value) since we don't know in
|
||||
* the assembler what the max addr reg value can be:
|
||||
*/
|
||||
v->constlen = MAX2(v->constlen, v->info.max_const + 1);
|
||||
}
|
||||
|
||||
/* for vertex shader, the inputs are loaded into registers before the shader
|
||||
@@ -81,16 +85,27 @@ fixup_vp_regfootprint(struct ir3_shader_variant *v)
|
||||
unsigned i;
|
||||
for (i = 0; i < v->inputs_count; i++) {
|
||||
if (v->inputs[i].compmask) {
|
||||
uint32_t regid = (v->inputs[i].regid + 3) >> 2;
|
||||
int32_t regid = (v->inputs[i].regid + 3) >> 2;
|
||||
v->info.max_reg = MAX2(v->info.max_reg, regid);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < v->outputs_count; i++) {
|
||||
uint32_t regid = (v->outputs[i].regid + 3) >> 2;
|
||||
int32_t regid = (v->outputs[i].regid + 3) >> 2;
|
||||
v->info.max_reg = MAX2(v->info.max_reg, regid);
|
||||
}
|
||||
}
|
||||
|
||||
/* reset before attempting to compile again.. */
|
||||
static void reset_variant(struct ir3_shader_variant *v, const char *msg)
|
||||
{
|
||||
debug_error(msg);
|
||||
v->inputs_count = 0;
|
||||
v->outputs_count = 0;
|
||||
v->total_in = 0;
|
||||
v->has_samp = false;
|
||||
v->immediates_count = 0;
|
||||
}
|
||||
|
||||
static struct ir3_shader_variant *
|
||||
create_variant(struct ir3_shader *shader, struct ir3_shader_key key)
|
||||
{
|
||||
@@ -112,15 +127,12 @@ create_variant(struct ir3_shader *shader, struct ir3_shader_key key)
|
||||
}
|
||||
|
||||
if (!(fd_mesa_debug & FD_DBG_NOOPT)) {
|
||||
ret = ir3_compile_shader(v, tokens, key);
|
||||
ret = ir3_compile_shader(v, tokens, key, true);
|
||||
if (ret) {
|
||||
debug_error("new compiler failed, trying fallback!");
|
||||
|
||||
v->inputs_count = 0;
|
||||
v->outputs_count = 0;
|
||||
v->total_in = 0;
|
||||
v->has_samp = false;
|
||||
v->immediates_count = 0;
|
||||
reset_variant(v, "new compiler failed, trying without copy propagation!");
|
||||
ret = ir3_compile_shader(v, tokens, key, false);
|
||||
if (ret)
|
||||
reset_variant(v, "new compiler failed, trying fallback!");
|
||||
}
|
||||
} else {
|
||||
ret = -1; /* force fallback to old compiler */
|
||||
@@ -165,16 +177,30 @@ ir3_shader_variant(struct ir3_shader *shader, struct ir3_shader_key key)
|
||||
* so normalize the key to avoid constructing multiple identical
|
||||
* variants:
|
||||
*/
|
||||
if (shader->type == SHADER_FRAGMENT) {
|
||||
switch (shader->type) {
|
||||
case SHADER_FRAGMENT:
|
||||
case SHADER_COMPUTE:
|
||||
key.binning_pass = false;
|
||||
}
|
||||
if (shader->type == SHADER_VERTEX) {
|
||||
if (key.has_per_samp) {
|
||||
key.vsaturate_s = 0;
|
||||
key.vsaturate_t = 0;
|
||||
key.vsaturate_r = 0;
|
||||
}
|
||||
break;
|
||||
case SHADER_VERTEX:
|
||||
key.color_two_side = false;
|
||||
key.half_precision = false;
|
||||
key.alpha = false;
|
||||
if (key.has_per_samp) {
|
||||
key.fsaturate_s = 0;
|
||||
key.fsaturate_t = 0;
|
||||
key.fsaturate_r = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (v = shader->variants; v; v = v->next)
|
||||
if (!memcmp(&key, &v->key, sizeof(key)))
|
||||
if (ir3_shader_key_equal(&key, &v->key))
|
||||
return v;
|
||||
|
||||
/* compile new variant if it doesn't exist already: */
|
||||
|
@@ -54,14 +54,54 @@ static inline uint16_t sem2idx(ir3_semantic sem)
|
||||
* in hw (two sided color), binning-pass vertex shader, etc.
|
||||
*/
|
||||
struct ir3_shader_key {
|
||||
/* vertex shader variant parameters: */
|
||||
unsigned binning_pass : 1;
|
||||
union {
|
||||
struct {
|
||||
/* do we need to check {v,f}saturate_{s,t,r}? */
|
||||
unsigned has_per_samp : 1;
|
||||
|
||||
/*
|
||||
* Vertex shader variant parameters:
|
||||
*/
|
||||
unsigned binning_pass : 1;
|
||||
|
||||
/*
|
||||
* Fragment shader variant parameters:
|
||||
*/
|
||||
unsigned color_two_side : 1;
|
||||
unsigned half_precision : 1;
|
||||
/* For rendering to alpha, we need a bit of special handling
|
||||
* since the hw always takes gl_FragColor starting from x
|
||||
* component, rather than figuring out to take the w component.
|
||||
* We could be more clever and generate variants for other
|
||||
* render target formats (ie. luminance formats are xxx1), but
|
||||
* let's start with this and see how it goes:
|
||||
*/
|
||||
unsigned alpha : 1;
|
||||
};
|
||||
uint32_t global;
|
||||
};
|
||||
|
||||
/* bitmask of sampler which needs coords clamped for vertex
|
||||
* shader:
|
||||
*/
|
||||
uint16_t vsaturate_s, vsaturate_t, vsaturate_r;
|
||||
|
||||
/* bitmask of sampler which needs coords clamped for frag
|
||||
* shader:
|
||||
*/
|
||||
uint16_t fsaturate_s, fsaturate_t, fsaturate_r;
|
||||
|
||||
/* fragment shader variant parameters: */
|
||||
unsigned color_two_side : 1;
|
||||
unsigned half_precision : 1;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
ir3_shader_key_equal(struct ir3_shader_key *a, struct ir3_shader_key *b)
|
||||
{
|
||||
/* slow-path if we need to check {v,f}saturate_{s,t,r} */
|
||||
if (a->has_per_samp || b->has_per_samp)
|
||||
return memcmp(a, b, sizeof(struct ir3_shader_key)) == 0;
|
||||
return a->global == b->global;
|
||||
}
|
||||
|
||||
struct ir3_shader_variant {
|
||||
struct fd_bo *bo;
|
||||
|
||||
@@ -110,9 +150,20 @@ struct ir3_shader_variant {
|
||||
uint8_t regid;
|
||||
uint8_t compmask;
|
||||
uint8_t ncomp;
|
||||
/* in theory inloc of fs should match outloc of vs: */
|
||||
/* In theory inloc of fs should match outloc of vs. Or
|
||||
* rather the outloc of the vs is 8 plus the offset passed
|
||||
* to bary.f. Presumably that +8 is to account for
|
||||
* gl_Position/gl_PointSize?
|
||||
*
|
||||
* NOTE inloc is currently aligned to 4 (we don't try
|
||||
* to pack varyings). Changing this would likely break
|
||||
* assumptions in few places (like setting up of flat
|
||||
* shading in fd3_program) so be sure to check all the
|
||||
* spots where inloc is used.
|
||||
*/
|
||||
uint8_t inloc;
|
||||
uint8_t bary;
|
||||
uint8_t interpolate;
|
||||
} inputs[16 + 2]; /* +POSITION +FACE */
|
||||
|
||||
unsigned total_in; /* sum of inputs (scalar) */
|
||||
@@ -120,6 +171,9 @@ struct ir3_shader_variant {
|
||||
/* do we have one or more texture sample instructions: */
|
||||
bool has_samp;
|
||||
|
||||
/* do we have kill instructions: */
|
||||
bool has_kill;
|
||||
|
||||
/* const reg # of first immediate, ie. 1 == c1
|
||||
* (not regid, because TGSI thinks in terms of vec4 registers,
|
||||
* not scalar registers)
|
||||
@@ -147,9 +201,9 @@ struct ir3_shader {
|
||||
struct ir3_shader_variant *variants;
|
||||
|
||||
/* so far, only used for blit_prog shader.. values for
|
||||
* VPC_VARYING_INTERP[i].MODE and VPC_VARYING_PS_REPL[i].MODE
|
||||
* VPC_VARYING_PS_REPL[i].MODE
|
||||
*/
|
||||
uint32_t vinterp[4], vpsrepl[4];
|
||||
uint32_t vpsrepl[4];
|
||||
};
|
||||
|
||||
|
||||
|
@@ -32,7 +32,7 @@ LOCAL_SRC_FILES := \
|
||||
$(C_SOURCES) \
|
||||
$(NV30_C_SOURCES) \
|
||||
$(NV50_CODEGEN_SOURCES) \
|
||||
$(NV50_C_SOURES) \
|
||||
$(NV50_C_SOURCES) \
|
||||
$(NVC0_CODEGEN_SOURCES) \
|
||||
$(NVC0_C_SOURCES)
|
||||
|
||||
|
@@ -140,6 +140,7 @@ private:
|
||||
code[(0x##b) / 32] |= 1 << ((0x##b) % 32)
|
||||
|
||||
#define FTZ_(b) if (i->ftz) code[(0x##b) / 32] |= 1 << ((0x##b) % 32)
|
||||
#define DNZ_(b) if (i->dnz) code[(0x##b) / 32] |= 1 << ((0x##b) % 32)
|
||||
|
||||
#define SAT_(b) if (i->saturate) code[(0x##b) / 32] |= 1 << ((0x##b) % 32)
|
||||
|
||||
@@ -464,6 +465,7 @@ CodeEmitterGK110::emitFMAD(const Instruction *i)
|
||||
SAT_(35);
|
||||
RND_(36, F);
|
||||
FTZ_(38);
|
||||
DNZ_(39);
|
||||
|
||||
bool neg1 = (i->src(0).mod ^ i->src(1).mod).neg();
|
||||
|
||||
@@ -487,6 +489,7 @@ CodeEmitterGK110::emitFMUL(const Instruction *i)
|
||||
emitForm_L(i, 0x200, 0x2, Modifier(0));
|
||||
|
||||
FTZ_(38);
|
||||
DNZ_(39);
|
||||
SAT_(3a);
|
||||
if (neg)
|
||||
code[1] ^= 1 << 22;
|
||||
@@ -499,6 +502,7 @@ CodeEmitterGK110::emitFMUL(const Instruction *i)
|
||||
|
||||
RND_(2a, F);
|
||||
FTZ_(2f);
|
||||
DNZ_(30);
|
||||
SAT_(35);
|
||||
|
||||
if (code[0] & 0x1) {
|
||||
|
@@ -432,7 +432,7 @@ CodeEmitterGM107::emitNEG2(int pos, const ValueRef &a, const ValueRef &b)
|
||||
void
|
||||
CodeEmitterGM107::emitFMZ(int pos, int len)
|
||||
{
|
||||
emitField(pos, len, /*XXX: insn->dnz << 1 | */ insn->ftz);
|
||||
emitField(pos, len, insn->dnz << 1 | insn->ftz);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -58,6 +58,7 @@ GM107LoweringPass::handleManualTXD(TexInstruction *i)
|
||||
Value *zero = bld.loadImm(bld.getSSA(), 0);
|
||||
int l, c;
|
||||
const int dim = i->tex.target.getDim();
|
||||
const int array = i->tex.target.isArray();
|
||||
|
||||
i->op = OP_TEX; // no need to clone dPdx/dPdy later
|
||||
|
||||
@@ -69,7 +70,7 @@ GM107LoweringPass::handleManualTXD(TexInstruction *i)
|
||||
// mov coordinates from lane l to all lanes
|
||||
bld.mkOp(OP_QUADON, TYPE_NONE, NULL);
|
||||
for (c = 0; c < dim; ++c) {
|
||||
bld.mkOp2(OP_SHFL, TYPE_F32, crd[c], i->getSrc(c), bld.mkImm(l));
|
||||
bld.mkOp2(OP_SHFL, TYPE_F32, crd[c], i->getSrc(c + array), bld.mkImm(l));
|
||||
add = bld.mkOp2(OP_QUADOP, TYPE_F32, crd[c], crd[c], zero);
|
||||
add->subOp = 0x00;
|
||||
add->lanes = 1; /* abused for .ndv */
|
||||
@@ -94,7 +95,7 @@ GM107LoweringPass::handleManualTXD(TexInstruction *i)
|
||||
// texture
|
||||
bld.insert(tex = cloneForward(func, i));
|
||||
for (c = 0; c < dim; ++c)
|
||||
tex->setSrc(c, crd[c]);
|
||||
tex->setSrc(c + array, crd[c]);
|
||||
bld.mkOp(OP_QUADPOP, TYPE_NONE, NULL);
|
||||
|
||||
// save results
|
||||
@@ -158,7 +159,10 @@ GM107LoweringPass::handlePFETCH(Instruction *i)
|
||||
bld.mkOp2(OP_SHR , TYPE_U32, tmp1, tmp0, bld.mkImm(16));
|
||||
bld.mkOp2(OP_AND , TYPE_U32, tmp0, tmp0, bld.mkImm(0xff));
|
||||
bld.mkOp2(OP_AND , TYPE_U32, tmp1, tmp1, bld.mkImm(0xff));
|
||||
bld.mkOp1(OP_MOV , TYPE_U32, tmp2, bld.mkImm(i->getSrc(0)->reg.data.u32));
|
||||
if (i->getSrc(1))
|
||||
bld.mkOp2(OP_ADD , TYPE_U32, tmp2, i->getSrc(0), i->getSrc(1));
|
||||
else
|
||||
bld.mkOp1(OP_MOV , TYPE_U32, tmp2, i->getSrc(0));
|
||||
bld.mkOp3(OP_MAD , TYPE_U32, tmp0, tmp0, tmp1, tmp2);
|
||||
i->setSrc(0, tmp0);
|
||||
i->setSrc(1, NULL);
|
||||
@@ -240,6 +244,20 @@ GM107LoweringPass::visit(Instruction *i)
|
||||
i->op = OP_VFETCH;
|
||||
assert(prog->getType() != Program::TYPE_FRAGMENT); // INTERP
|
||||
}
|
||||
} else if (i->src(0).getFile() == FILE_MEMORY_CONST) {
|
||||
if (i->src(0).isIndirect(1)) {
|
||||
Value *ptr;
|
||||
if (i->src(0).isIndirect(0))
|
||||
ptr = bld.mkOp3v(OP_INSBF, TYPE_U32, bld.getSSA(),
|
||||
i->getIndirect(0, 1), bld.mkImm(0x1010),
|
||||
i->getIndirect(0, 0));
|
||||
else
|
||||
ptr = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
|
||||
i->getIndirect(0, 1), bld.mkImm(16));
|
||||
i->setIndirect(0, 1, NULL);
|
||||
i->setIndirect(0, 0, ptr);
|
||||
i->subOp = NV50_IR_SUBOP_LDC_IS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OP_ATOM:
|
||||
|
@@ -174,15 +174,29 @@ NVC0LegalizePostRA::findOverwritingDefs(const Instruction *texi,
|
||||
}
|
||||
|
||||
void
|
||||
NVC0LegalizePostRA::findFirstUses(const Instruction *texi,
|
||||
const Instruction *insn,
|
||||
std::list<TexUse> &uses)
|
||||
NVC0LegalizePostRA::findFirstUses(
|
||||
const Instruction *texi,
|
||||
const Instruction *insn,
|
||||
std::list<TexUse> &uses,
|
||||
std::tr1::unordered_set<const Instruction *>& visited)
|
||||
{
|
||||
for (int d = 0; insn->defExists(d); ++d) {
|
||||
Value *v = insn->getDef(d);
|
||||
for (Value::UseIterator u = v->uses.begin(); u != v->uses.end(); ++u) {
|
||||
Instruction *usei = (*u)->getInsn();
|
||||
|
||||
// NOTE: In case of a loop that overwrites a value but never uses
|
||||
// it, it can happen that we have a cycle of uses that consists only
|
||||
// of phis and no-op moves and will thus cause an infinite loop here
|
||||
// since these are not considered actual uses.
|
||||
// The most obvious (and perhaps the only) way to prevent this is to
|
||||
// remember which instructions we've already visited.
|
||||
|
||||
if (visited.find(usei) != visited.end())
|
||||
continue;
|
||||
|
||||
visited.insert(usei);
|
||||
|
||||
if (usei->op == OP_PHI || usei->op == OP_UNION) {
|
||||
// need a barrier before WAW cases
|
||||
for (int s = 0; usei->srcExists(s); ++s) {
|
||||
@@ -197,11 +211,11 @@ NVC0LegalizePostRA::findFirstUses(const Instruction *texi,
|
||||
usei->op == OP_PHI ||
|
||||
usei->op == OP_UNION) {
|
||||
// these uses don't manifest in the machine code
|
||||
findFirstUses(texi, usei, uses);
|
||||
findFirstUses(texi, usei, uses, visited);
|
||||
} else
|
||||
if (usei->op == OP_MOV && usei->getDef(0)->equals(usei->getSrc(0)) &&
|
||||
usei->subOp != NV50_IR_SUBOP_MOV_FINAL) {
|
||||
findFirstUses(texi, usei, uses);
|
||||
findFirstUses(texi, usei, uses, visited);
|
||||
} else {
|
||||
addTexUse(uses, usei, insn);
|
||||
}
|
||||
@@ -257,8 +271,10 @@ NVC0LegalizePostRA::insertTextureBarriers(Function *fn)
|
||||
uses = new std::list<TexUse>[texes.size()];
|
||||
if (!uses)
|
||||
return false;
|
||||
for (size_t i = 0; i < texes.size(); ++i)
|
||||
findFirstUses(texes[i], texes[i], uses[i]);
|
||||
for (size_t i = 0; i < texes.size(); ++i) {
|
||||
std::tr1::unordered_set<const Instruction *> visited;
|
||||
findFirstUses(texes[i], texes[i], uses[i], visited);
|
||||
}
|
||||
|
||||
// determine the barrier level at each use
|
||||
for (size_t i = 0; i < texes.size(); ++i) {
|
||||
@@ -591,6 +607,21 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
|
||||
// lod bias
|
||||
// depth compare
|
||||
// offsets (same as fermi, except txd which takes it with array)
|
||||
//
|
||||
// Maxwell (tex):
|
||||
// array
|
||||
// coords
|
||||
// indirect handle
|
||||
// sample
|
||||
// lod bias
|
||||
// depth compare
|
||||
// offsets
|
||||
//
|
||||
// Maxwell (txd):
|
||||
// indirect handle
|
||||
// coords
|
||||
// array + offsets
|
||||
// derivatives
|
||||
|
||||
if (chipset >= NVISA_GK104_CHIPSET) {
|
||||
if (i->tex.rIndirectSrc >= 0 || i->tex.sIndirectSrc >= 0) {
|
||||
@@ -624,12 +655,17 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
|
||||
const int sat = (i->op == OP_TXF) ? 1 : 0;
|
||||
DataType sTy = (i->op == OP_TXF) ? TYPE_U32 : TYPE_F32;
|
||||
bld.mkCvt(OP_CVT, TYPE_U16, layer, sTy, src)->saturate = sat;
|
||||
for (int s = dim; s >= 1; --s)
|
||||
i->setSrc(s, i->getSrc(s - 1));
|
||||
i->setSrc(0, layer);
|
||||
if (i->op != OP_TXD || chipset < NVISA_GM107_CHIPSET) {
|
||||
for (int s = dim; s >= 1; --s)
|
||||
i->setSrc(s, i->getSrc(s - 1));
|
||||
i->setSrc(0, layer);
|
||||
} else {
|
||||
i->setSrc(dim, layer);
|
||||
}
|
||||
}
|
||||
// Move the indirect reference to the first place
|
||||
if (i->tex.rIndirectSrc >= 0) {
|
||||
if (i->tex.rIndirectSrc >= 0 && (
|
||||
i->op == OP_TXD || chipset < NVISA_GM107_CHIPSET)) {
|
||||
Value *hnd = i->getIndirectR();
|
||||
|
||||
i->setIndirectR(NULL);
|
||||
@@ -732,8 +768,10 @@ NVC0LoweringPass::handleTEX(TexInstruction *i)
|
||||
// create it if it's not already there, and INSBF it if it already
|
||||
// is.
|
||||
s = (i->tex.rIndirectSrc >= 0) ? 1 : 0;
|
||||
if (chipset >= NVISA_GM107_CHIPSET)
|
||||
s += dim;
|
||||
if (i->tex.target.isArray()) {
|
||||
bld.mkOp3(OP_INSBF, TYPE_U32, i->getSrc(0),
|
||||
bld.mkOp3(OP_INSBF, TYPE_U32, i->getSrc(s),
|
||||
bld.loadImm(NULL, imm), bld.mkImm(0xc10),
|
||||
i->getSrc(s));
|
||||
} else {
|
||||
|
@@ -20,6 +20,8 @@
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <tr1/unordered_set>
|
||||
|
||||
#include "codegen/nv50_ir.h"
|
||||
#include "codegen/nv50_ir_build_util.h"
|
||||
|
||||
@@ -69,7 +71,8 @@ private:
|
||||
bool insertTextureBarriers(Function *);
|
||||
inline bool insnDominatedBy(const Instruction *, const Instruction *) const;
|
||||
void findFirstUses(const Instruction *tex, const Instruction *def,
|
||||
std::list<TexUse>&);
|
||||
std::list<TexUse>&,
|
||||
std::tr1::unordered_set<const Instruction *>&);
|
||||
void findOverwritingDefs(const Instruction *tex, Instruction *insn,
|
||||
const BasicBlock *term,
|
||||
std::list<TexUse>&);
|
||||
|
@@ -567,6 +567,10 @@ ConstantFolding::expr(Instruction *i,
|
||||
ImmediateValue src0;
|
||||
if (i->src(0).getImmediate(src0))
|
||||
expr(i, src0, *i->getSrc(1)->asImm());
|
||||
if (i->saturate && !prog->getTarget()->isSatSupported(i)) {
|
||||
bld.setPosition(i, false);
|
||||
i->setSrc(1, bld.loadImm(NULL, res.data.u32));
|
||||
}
|
||||
} else {
|
||||
i->op = i->saturate ? OP_SAT : OP_MOV; /* SAT handled by unary() */
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <stack>
|
||||
#include <limits>
|
||||
#include <tr1/unordered_set>
|
||||
|
||||
namespace nv50_ir {
|
||||
|
||||
@@ -1547,6 +1548,11 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
|
||||
LValue *lval = it->first->asLValue();
|
||||
Symbol *mem = it->second ? it->second->asSym() : NULL;
|
||||
|
||||
// Keep track of which instructions to delete later. Deleting them
|
||||
// inside the loop is unsafe since a single instruction may have
|
||||
// multiple destinations that all need to be spilled (like OP_SPLIT).
|
||||
std::tr1::unordered_set<Instruction *> to_del;
|
||||
|
||||
for (Value::DefIterator d = lval->defs.begin(); d != lval->defs.end();
|
||||
++d) {
|
||||
Value *slot = mem ?
|
||||
@@ -1579,7 +1585,7 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
|
||||
d = lval->defs.erase(d);
|
||||
--d;
|
||||
if (slot->reg.file == FILE_MEMORY_LOCAL)
|
||||
delete_Instruction(func->getProgram(), defi);
|
||||
to_del.insert(defi);
|
||||
else
|
||||
defi->setDef(0, slot);
|
||||
} else {
|
||||
@@ -1587,6 +1593,9 @@ SpillCodeInserter::run(const std::list<ValuePair>& lst)
|
||||
}
|
||||
}
|
||||
|
||||
for (std::tr1::unordered_set<Instruction *>::const_iterator it = to_del.begin();
|
||||
it != to_del.end(); ++it)
|
||||
delete_Instruction(func->getProgram(), *it);
|
||||
}
|
||||
|
||||
// TODO: We're not trying to reuse old slots in a potential next iteration.
|
||||
@@ -1657,6 +1666,10 @@ RegAlloc::execFunc()
|
||||
ret && i <= func->loopNestingBound;
|
||||
sequence = func->cfg.nextSequence(), ++i)
|
||||
ret = buildLiveSets(BasicBlock::get(func->cfg.getRoot()));
|
||||
// reset marker
|
||||
for (ArrayList::Iterator bi = func->allBBlocks.iterator();
|
||||
!bi.end(); bi.next())
|
||||
BasicBlock::get(bi)->liveSet.marker = false;
|
||||
if (!ret)
|
||||
break;
|
||||
func->orderInstructions(this->insns);
|
||||
@@ -1908,6 +1921,13 @@ RegAlloc::InsertConstraintsPass::texConstraintGM107(TexInstruction *tex)
|
||||
if (isTextureOp(tex->op)) {
|
||||
if (tex->op != OP_TXQ) {
|
||||
s = tex->tex.target.getArgCount() - tex->tex.target.isMS();
|
||||
if (tex->op == OP_TXD) {
|
||||
// Indirect handle belongs in the first arg
|
||||
if (tex->tex.rIndirectSrc >= 0)
|
||||
s++;
|
||||
if (!tex->tex.target.isArray() && tex->tex.useOffsets)
|
||||
s++;
|
||||
}
|
||||
n = tex->srcCount(0xff) - s;
|
||||
} else {
|
||||
s = tex->srcCount(0xff);
|
||||
|
@@ -449,7 +449,7 @@ TargetNV50::isModSupported(const Instruction *insn, int s, Modifier mod) const
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (s > 3)
|
||||
if (s >= 3)
|
||||
return false;
|
||||
return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
|
||||
}
|
||||
|
@@ -423,7 +423,7 @@ TargetNVC0::isModSupported(const Instruction *insn, int s, Modifier mod) const
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (s > 3)
|
||||
if (s >= 3)
|
||||
return false;
|
||||
return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
|
||||
}
|
||||
|
@@ -254,7 +254,9 @@ bool BitSet::resize(unsigned int nBits)
|
||||
return false;
|
||||
}
|
||||
if (n > p)
|
||||
memset(&data[4 * p + 4], 0, (n - p) * 4);
|
||||
memset(&data[p], 0, (n - p) * 4);
|
||||
if (nBits < size && (nBits % 32))
|
||||
data[(nBits + 31) / 32 - 1] &= (1 << (nBits % 32)) - 1;
|
||||
|
||||
size = nBits;
|
||||
return true;
|
||||
@@ -274,8 +276,8 @@ bool BitSet::allocate(unsigned int nBits, bool zero)
|
||||
if (zero)
|
||||
memset(data, 0, (size + 7) / 8);
|
||||
else
|
||||
if (nBits)
|
||||
data[(size + 31) / 32 - 1] = 0; // clear unused bits (e.g. for popCount)
|
||||
if (size % 32) // clear unused bits (e.g. for popCount)
|
||||
data[(size + 31) / 32 - 1] &= (1 << (size % 32)) - 1;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@@ -484,6 +484,7 @@ public:
|
||||
FREE(data);
|
||||
}
|
||||
|
||||
// allocate will keep old data iff size is unchanged
|
||||
bool allocate(unsigned int nBits, bool zero);
|
||||
bool resize(unsigned int nBits); // keep old data, zero additional bits
|
||||
|
||||
|
@@ -39,6 +39,8 @@ struct nouveau_vp3_video_buffer {
|
||||
#define VP_OFFSET 0x200
|
||||
#define COMM_OFFSET 0x500
|
||||
|
||||
#define NOUVEAU_VP3_BSP_RESERVED_SIZE 0x700
|
||||
|
||||
#define NOUVEAU_VP3_DEBUG_FENCE 0
|
||||
|
||||
#if NOUVEAU_VP3_DEBUG_FENCE
|
||||
|
@@ -78,10 +78,10 @@ struct mpeg4_picparm_vp {
|
||||
uint8_t top_field_first; // bool, written to vuc
|
||||
|
||||
uint8_t pad4[3]; // 59, 5a, 5b, contains garbage on blob
|
||||
uint32_t pad5[0x10]; // 5c...9c non-inclusive, but WHY?
|
||||
|
||||
uint32_t intra[0x10]; // 9c
|
||||
uint32_t non_intra[0x10]; // bc
|
||||
uint32_t intra[0x10]; // 5c
|
||||
uint32_t non_intra[0x10]; // 9c
|
||||
uint32_t pad5[0x10]; // bc what does this do?
|
||||
// udc..uff pad?
|
||||
};
|
||||
|
||||
@@ -196,11 +196,15 @@ nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp
|
||||
/* Try to find a real empty spot first, there should be one..
|
||||
*/
|
||||
for (i = 0; i < dec->base.max_references + 1; ++i) {
|
||||
if (dec->refs[i].last_used != seq) {
|
||||
if (dec->refs[i].vidbuf == target) {
|
||||
empty_spot = i;
|
||||
break;
|
||||
}
|
||||
} else if (!dec->refs[i].last_used) {
|
||||
empty_spot = i;
|
||||
} else if (empty_spot == ~0U && dec->refs[i].last_used != seq)
|
||||
empty_spot = i;
|
||||
}
|
||||
|
||||
assert(empty_spot < dec->base.max_references+1);
|
||||
dec->refs[empty_spot].last_used = seq;
|
||||
// debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, empty_spot);
|
||||
@@ -267,7 +271,6 @@ nouveau_vp3_fill_picparm_mpeg4_vp(struct nouveau_vp3_decoder *dec,
|
||||
{
|
||||
struct mpeg4_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
|
||||
uint32_t ring, ret = 0x01014; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
|
||||
assert(!(dec->base.width & 0xf));
|
||||
*is_ref = desc->vop_coding_type <= 1;
|
||||
|
||||
pic_vp->width = dec->base.width;
|
||||
@@ -463,14 +466,45 @@ void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
|
||||
case PIPE_VIDEO_FORMAT_MPEG12:
|
||||
*caps = nouveau_vp3_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp);
|
||||
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
|
||||
switch (desc.mpeg12->picture_structure) {
|
||||
case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP:
|
||||
dec->refs[target->valid_ref].decoded_top = 1;
|
||||
break;
|
||||
case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM:
|
||||
dec->refs[target->valid_ref].decoded_bottom = 1;
|
||||
break;
|
||||
default:
|
||||
dec->refs[target->valid_ref].decoded_top = 1;
|
||||
dec->refs[target->valid_ref].decoded_bottom = 1;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case PIPE_VIDEO_FORMAT_MPEG4:
|
||||
*caps = nouveau_vp3_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp);
|
||||
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
|
||||
// XXX: Correct?
|
||||
if (!desc.mpeg4->interlaced) {
|
||||
dec->refs[target->valid_ref].decoded_top = 1;
|
||||
dec->refs[target->valid_ref].decoded_bottom = 1;
|
||||
} else if (desc.mpeg4->top_field_first) {
|
||||
if (!dec->refs[target->valid_ref].decoded_top)
|
||||
dec->refs[target->valid_ref].decoded_top = 1;
|
||||
else
|
||||
dec->refs[target->valid_ref].decoded_bottom = 1;
|
||||
} else {
|
||||
if (!dec->refs[target->valid_ref].decoded_bottom)
|
||||
dec->refs[target->valid_ref].decoded_bottom = 1;
|
||||
else
|
||||
dec->refs[target->valid_ref].decoded_top = 1;
|
||||
}
|
||||
return;
|
||||
case PIPE_VIDEO_FORMAT_VC1: {
|
||||
*caps = nouveau_vp3_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp);
|
||||
nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
|
||||
if (desc.vc1->frame_coding_mode == 3)
|
||||
debug_printf("Field-Interlaced possibly incorrectly handled\n");
|
||||
dec->refs[target->valid_ref].decoded_top = 1;
|
||||
dec->refs[target->valid_ref].decoded_bottom = 1;
|
||||
return;
|
||||
}
|
||||
case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
|
||||
|
@@ -585,9 +585,12 @@ nv50_stage_sampler_states_bind(struct nv50_context *nv50, int s,
|
||||
nv50_screen_tsc_unlock(nv50->screen, old);
|
||||
}
|
||||
assert(nv50->num_samplers[s] <= PIPE_MAX_SAMPLERS);
|
||||
for (; i < nv50->num_samplers[s]; ++i)
|
||||
if (nv50->samplers[s][i])
|
||||
for (; i < nv50->num_samplers[s]; ++i) {
|
||||
if (nv50->samplers[s][i]) {
|
||||
nv50_screen_tsc_unlock(nv50->screen, nv50->samplers[s][i]);
|
||||
nv50->samplers[s][i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nv50->num_samplers[s] = nr;
|
||||
|
||||
|
@@ -54,8 +54,8 @@ nv50_validate_fb(struct nv50_context *nv50)
|
||||
assert(mt->layout_3d || !array_mode || array_size == 1);
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(i)), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATAh(push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[sf->base.format].rt);
|
||||
if (likely(nouveau_bo_memtype(bo))) {
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
@@ -97,8 +97,8 @@ nv50_validate_fb(struct nv50_context *nv50)
|
||||
int unk = mt->base.base.target == PIPE_TEXTURE_3D || sf->depth == 1;
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATAh(push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[fb->zsbuf->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
|
@@ -114,8 +114,8 @@ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
|
||||
PUSH_DATA (push, mt->level[level].pitch);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
PUSH_DATAh(push, mt->base.address + offset);
|
||||
PUSH_DATA (push, mt->base.address + offset);
|
||||
} else {
|
||||
BEGIN_NV04(push, SUBC_2D(mthd), 5);
|
||||
PUSH_DATA (push, format);
|
||||
@@ -126,8 +126,8 @@ nv50_2d_texture_set(struct nouveau_pushbuf *push, int dst,
|
||||
BEGIN_NV04(push, SUBC_2D(mthd + 0x18), 4);
|
||||
PUSH_DATA (push, width);
|
||||
PUSH_DATA (push, height);
|
||||
PUSH_DATAh(push, bo->offset + offset);
|
||||
PUSH_DATA (push, bo->offset + offset);
|
||||
PUSH_DATAh(push, mt->base.address + offset);
|
||||
PUSH_DATA (push, mt->base.address + offset);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@@ -299,8 +299,8 @@ nv50_clear_render_target(struct pipe_context *pipe,
|
||||
BEGIN_NV04(push, NV50_3D(RT_CONTROL), 1);
|
||||
PUSH_DATA (push, 1);
|
||||
BEGIN_NV04(push, NV50_3D(RT_ADDRESS_HIGH(0)), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATAh(push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[dst->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
@@ -381,8 +381,8 @@ nv50_clear_depth_stencil(struct pipe_context *pipe,
|
||||
nv50->scissors_dirty |= 1;
|
||||
|
||||
BEGIN_NV04(push, NV50_3D(ZETA_ADDRESS_HIGH), 5);
|
||||
PUSH_DATAh(push, bo->offset + sf->offset);
|
||||
PUSH_DATA (push, bo->offset + sf->offset);
|
||||
PUSH_DATAh(push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, mt->base.address + sf->offset);
|
||||
PUSH_DATA (push, nv50_format_table[dst->format].rt);
|
||||
PUSH_DATA (push, mt->level[sf->base.u.tex.level].tile_mode);
|
||||
PUSH_DATA (push, mt->layer_stride >> 2);
|
||||
|
@@ -24,6 +24,8 @@ nv50_m2mf_rect_setup(struct nv50_m2mf_rect *rect,
|
||||
rect->bo = mt->base.bo;
|
||||
rect->domain = mt->base.domain;
|
||||
rect->base = mt->level[l].offset;
|
||||
if (mt->base.bo->offset != mt->base.address)
|
||||
rect->base += mt->base.address - mt->base.bo->offset;
|
||||
rect->pitch = mt->level[l].pitch;
|
||||
if (util_format_is_plain(res->format)) {
|
||||
rect->width = w << mt->ms_x;
|
||||
|
@@ -482,12 +482,14 @@ nv84_create_decoder(struct pipe_context *context,
|
||||
mip.level[0].pitch = surf.width * 4;
|
||||
mip.base.domain = NOUVEAU_BO_VRAM;
|
||||
mip.base.bo = dec->mbring;
|
||||
mip.base.address = dec->mbring->offset;
|
||||
context->clear_render_target(context, &surf.base, &color, 0, 0, 64, 4760);
|
||||
surf.offset = dec->vpring->size / 2 - 0x1000;
|
||||
surf.width = 1024;
|
||||
surf.height = 1;
|
||||
mip.level[0].pitch = surf.width * 4;
|
||||
mip.base.bo = dec->vpring;
|
||||
mip.base.address = dec->vpring->offset;
|
||||
context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1);
|
||||
surf.offset = dec->vpring->size - 0x1000;
|
||||
context->clear_render_target(context, &surf.base, &color, 0, 0, 1024, 1);
|
||||
@@ -683,17 +685,14 @@ nv84_video_buffer_create(struct pipe_context *pipe,
|
||||
bo_size, &cfg, &buffer->full))
|
||||
goto error;
|
||||
|
||||
mt0->base.bo = buffer->interlaced;
|
||||
nouveau_bo_ref(buffer->interlaced, &mt0->base.bo);
|
||||
mt0->base.domain = NOUVEAU_BO_VRAM;
|
||||
mt0->base.offset = 0;
|
||||
mt0->base.address = buffer->interlaced->offset + mt0->base.offset;
|
||||
nouveau_bo_ref(buffer->interlaced, &empty);
|
||||
mt0->base.address = buffer->interlaced->offset;
|
||||
|
||||
mt1->base.bo = buffer->interlaced;
|
||||
nouveau_bo_ref(buffer->interlaced, &mt1->base.bo);
|
||||
mt1->base.domain = NOUVEAU_BO_VRAM;
|
||||
mt1->base.offset = mt0->layer_stride * 2;
|
||||
mt1->base.address = buffer->interlaced->offset + mt1->base.offset;
|
||||
nouveau_bo_ref(buffer->interlaced, &empty);
|
||||
mt1->base.offset = mt0->total_size;
|
||||
mt1->base.address = buffer->interlaced->offset + mt0->total_size;
|
||||
|
||||
memset(&sv_templ, 0, sizeof(sv_templ));
|
||||
for (component = 0, i = 0; i < 2; ++i ) {
|
||||
|
@@ -42,8 +42,8 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
|
||||
struct nouveau_pushbuf *push = dec->pushbuf[0];
|
||||
enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
|
||||
uint32_t bsp_addr, comm_addr, inter_addr;
|
||||
uint32_t slice_size, bucket_size, ring_size;
|
||||
uint32_t caps;
|
||||
uint32_t slice_size, bucket_size, ring_size, bsp_size;
|
||||
uint32_t caps, i;
|
||||
int ret;
|
||||
struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
|
||||
struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
|
||||
@@ -65,6 +65,41 @@ nv98_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
|
||||
fence_extra = 4;
|
||||
#endif
|
||||
|
||||
bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;
|
||||
for (i = 0; i < num_buffers; i++)
|
||||
bsp_size += num_bytes[i];
|
||||
bsp_size += 256; /* the 4 end markers */
|
||||
|
||||
if (!bsp_bo || bsp_size > bsp_bo->size) {
|
||||
struct nouveau_bo *tmp_bo = NULL;
|
||||
|
||||
/* round up to the nearest mb */
|
||||
bsp_size += (1 << 20) - 1;
|
||||
bsp_size &= ~((1 << 20) - 1);
|
||||
|
||||
ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_size, NULL, &tmp_bo);
|
||||
if (ret) {
|
||||
debug_printf("reallocating bsp %u -> %u failed with %i\n",
|
||||
bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_size, ret);
|
||||
return -1;
|
||||
}
|
||||
nouveau_bo_ref(NULL, &bsp_bo);
|
||||
bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;
|
||||
}
|
||||
|
||||
if (!inter_bo || bsp_bo->size * 4 > inter_bo->size) {
|
||||
struct nouveau_bo *tmp_bo = NULL;
|
||||
|
||||
ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_bo->size * 4, NULL, &tmp_bo);
|
||||
if (ret) {
|
||||
debug_printf("reallocating inter %u -> %u failed with %i\n",
|
||||
inter_bo ? (unsigned)inter_bo->size : 0, (unsigned)bsp_bo->size * 4, ret);
|
||||
return -1;
|
||||
}
|
||||
nouveau_bo_ref(NULL, &inter_bo);
|
||||
bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;
|
||||
}
|
||||
|
||||
ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
|
||||
if (ret) {
|
||||
debug_printf("map failed: %i %s\n", ret, strerror(-ret));
|
||||
|
@@ -59,7 +59,6 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32
|
||||
static void
|
||||
nv98_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target)
|
||||
{
|
||||
dec->refs[target->valid_ref].vidbuf = NULL;
|
||||
dec->refs[target->valid_ref].last_used = 0;
|
||||
// debug_printf("Unreffed %p\n", target);
|
||||
}
|
||||
|
@@ -261,7 +261,6 @@ nvc0_miptree_create(struct pipe_screen *pscreen,
|
||||
|
||||
if (pt->usage == PIPE_USAGE_STAGING) {
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_RECT:
|
||||
if (pt->last_level == 0 &&
|
||||
|
@@ -173,16 +173,12 @@ nvc0_create_decoder(struct pipe_context *context,
|
||||
ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
|
||||
0x100, 4 << 20, &cfg, &dec->inter_bo[0]);
|
||||
if (!ret) {
|
||||
if (!kepler)
|
||||
nouveau_bo_ref(dec->inter_bo[0], &dec->inter_bo[1]);
|
||||
else
|
||||
ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
|
||||
0x100, dec->inter_bo[0]->size, &cfg,
|
||||
&dec->inter_bo[1]);
|
||||
ret = nouveau_bo_new(screen->device, NOUVEAU_BO_VRAM,
|
||||
0x100, dec->inter_bo[0]->size, &cfg,
|
||||
&dec->inter_bo[1]);
|
||||
}
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
switch (u_reduce_video_profile(templ->profile)) {
|
||||
case PIPE_VIDEO_FORMAT_MPEG12: {
|
||||
codec = 1;
|
||||
|
@@ -42,8 +42,8 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
|
||||
struct nouveau_pushbuf *push = dec->pushbuf[0];
|
||||
enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
|
||||
uint32_t bsp_addr, comm_addr, inter_addr;
|
||||
uint32_t slice_size, bucket_size, ring_size;
|
||||
uint32_t caps;
|
||||
uint32_t slice_size, bucket_size, ring_size, bsp_size;
|
||||
uint32_t caps, i;
|
||||
int ret;
|
||||
struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
|
||||
struct nouveau_bo *inter_bo = dec->inter_bo[comm_seq & 1];
|
||||
@@ -65,6 +65,49 @@ nvc0_decoder_bsp(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
|
||||
fence_extra = 4;
|
||||
#endif
|
||||
|
||||
bsp_size = NOUVEAU_VP3_BSP_RESERVED_SIZE;
|
||||
for (i = 0; i < num_buffers; i++)
|
||||
bsp_size += num_bytes[i];
|
||||
bsp_size += 256; /* the 4 end markers */
|
||||
|
||||
if (!bsp_bo || bsp_size > bsp_bo->size) {
|
||||
union nouveau_bo_config cfg;
|
||||
struct nouveau_bo *tmp_bo = NULL;
|
||||
|
||||
cfg.nvc0.tile_mode = 0x10;
|
||||
cfg.nvc0.memtype = 0xfe;
|
||||
|
||||
/* round up to the nearest mb */
|
||||
bsp_size += (1 << 20) - 1;
|
||||
bsp_size &= ~((1 << 20) - 1);
|
||||
|
||||
ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_size, &cfg, &tmp_bo);
|
||||
if (ret) {
|
||||
debug_printf("reallocating bsp %u -> %u failed with %i\n",
|
||||
bsp_bo ? (unsigned)bsp_bo->size : 0, bsp_size, ret);
|
||||
return -1;
|
||||
}
|
||||
nouveau_bo_ref(NULL, &bsp_bo);
|
||||
bo_refs[0].bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH] = bsp_bo = tmp_bo;
|
||||
}
|
||||
|
||||
if (!inter_bo || bsp_bo->size * 4 > inter_bo->size) {
|
||||
union nouveau_bo_config cfg;
|
||||
struct nouveau_bo *tmp_bo = NULL;
|
||||
|
||||
cfg.nvc0.tile_mode = 0x10;
|
||||
cfg.nvc0.memtype = 0xfe;
|
||||
|
||||
ret = nouveau_bo_new(dec->bitplane_bo->device, NOUVEAU_BO_VRAM, 0, bsp_bo->size * 4, &cfg, &tmp_bo);
|
||||
if (ret) {
|
||||
debug_printf("reallocating inter %u -> %u failed with %i\n",
|
||||
inter_bo ? (unsigned)inter_bo->size : 0, (unsigned)bsp_bo->size * 4, ret);
|
||||
return -1;
|
||||
}
|
||||
nouveau_bo_ref(NULL, &inter_bo);
|
||||
bo_refs[1].bo = dec->inter_bo[comm_seq & 1] = inter_bo = tmp_bo;
|
||||
}
|
||||
|
||||
ret = nouveau_bo_map(bsp_bo, NOUVEAU_BO_WR, dec->client);
|
||||
if (ret) {
|
||||
debug_printf("map failed: %i %s\n", ret, strerror(-ret));
|
||||
|
@@ -59,7 +59,6 @@ static void dump_comm_vp(struct nouveau_vp3_decoder *dec, struct comm *comm, u32
|
||||
static void
|
||||
nvc0_decoder_kick_ref(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *target)
|
||||
{
|
||||
dec->refs[target->valid_ref].vidbuf = NULL;
|
||||
dec->refs[target->valid_ref].last_used = 0;
|
||||
// debug_printf("Unreffed %p\n", target);
|
||||
}
|
||||
|
@@ -572,14 +572,16 @@ static void do_advanced_regalloc(struct regalloc_state * s)
|
||||
graph = ra_alloc_interference_graph(ra_state->regs,
|
||||
node_count + s->NumInputs);
|
||||
|
||||
for (node_index = 0; node_index < node_count; node_index++) {
|
||||
ra_set_node_class(graph, node_index, node_classes[node_index]);
|
||||
}
|
||||
|
||||
/* Build the interference graph */
|
||||
for (var_ptr = variables, node_index = 0; var_ptr;
|
||||
var_ptr = var_ptr->Next,node_index++) {
|
||||
struct rc_list * a, * b;
|
||||
unsigned int b_index;
|
||||
|
||||
ra_set_node_class(graph, node_index, node_classes[node_index]);
|
||||
|
||||
for (a = var_ptr, b = var_ptr->Next, b_index = node_index + 1;
|
||||
b; b = b->Next, b_index++) {
|
||||
struct rc_variable * var_a = a->Item;
|
||||
|
@@ -546,9 +546,9 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx,
|
||||
S_028814_CULL_FRONT((state->cull_face & PIPE_FACE_FRONT) ? 1 : 0) |
|
||||
S_028814_CULL_BACK((state->cull_face & PIPE_FACE_BACK) ? 1 : 0) |
|
||||
S_028814_FACE(!state->front_ccw) |
|
||||
S_028814_POLY_OFFSET_FRONT_ENABLE(state->offset_tri) |
|
||||
S_028814_POLY_OFFSET_BACK_ENABLE(state->offset_tri) |
|
||||
S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_tri) |
|
||||
S_028814_POLY_OFFSET_FRONT_ENABLE(util_get_offset(state, state->fill_front)) |
|
||||
S_028814_POLY_OFFSET_BACK_ENABLE(util_get_offset(state, state->fill_back)) |
|
||||
S_028814_POLY_OFFSET_PARA_ENABLE(state->offset_point || state->offset_line) |
|
||||
S_028814_POLY_MODE(state->fill_front != PIPE_POLYGON_MODE_FILL ||
|
||||
state->fill_back != PIPE_POLYGON_MODE_FILL) |
|
||||
S_028814_POLYMODE_FRONT_PTYPE(r600_translate_fill(state->fill_front)) |
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user