Merge remote-tracking branch 'mesa-public/master' into vulkan

This pulls in nir cloning and some much-needed upstream refactors.
This commit is contained in:
Jason Ekstrand 2015-11-23 14:03:47 -08:00
commit 179fc4aae8
330 changed files with 13682 additions and 6260 deletions

View file

@ -32,6 +32,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS = \
--enable-vdpau \
--enable-xa \
--enable-xvmc \
--disable-llvm-shared-libs \
--with-egl-platforms=x11,wayland,drm \
--with-dri-drivers=i915,i965,nouveau,radeon,r200,swrast \
--with-gallium-drivers=i915,ilo,nouveau,r300,r600,radeonsi,freedreno,svga,swrast

View file

@ -1 +1 @@
11.1.0-devel
11.2.0-devel

View file

@ -768,6 +768,11 @@ linux*)
dri3_default=no
;;
esac
if test "x$enable_dri" = xno; then
dri3_default=no
fi
AC_ARG_ENABLE([dri3],
[AS_HELP_STRING([--enable-dri3],
[enable DRI3 @<:@default=auto@:>@])],
@ -957,8 +962,13 @@ gnu*|cygwin*)
dri_platform='drm' ;;
esac
if test "x$enable_dri" = xyes -a "x$dri_platform" = xdrm -a "x$have_libdrm" = xyes; then
have_drisw_kms='yes'
fi
AM_CONDITIONAL(HAVE_DRICOMMON, test "x$enable_dri" = xyes )
AM_CONDITIONAL(HAVE_DRISW, test "x$enable_dri" = xyes )
AM_CONDITIONAL(HAVE_DRISW_KMS, test "x$have_drisw_kms" = xyes )
AM_CONDITIONAL(HAVE_DRI2, test "x$enable_dri" = xyes -a "x$dri_platform" = xdrm -a "x$have_libdrm" = xyes )
AM_CONDITIONAL(HAVE_DRI3, test "x$enable_dri3" = xyes -a "x$dri_platform" = xdrm -a "x$have_libdrm" = xyes )
AM_CONDITIONAL(HAVE_APPLEDRI, test "x$enable_dri" = xyes -a "x$dri_platform" = xapple )
@ -993,10 +1003,6 @@ if test -n "$with_gallium_drivers" -a "x$enable_glx$enable_xlib_glx" = xyesyes;
NEED_WINSYS_XLIB="yes"
fi
if test "x$enable_dri" = xyes; then
enable_gallium_loader="$enable_shared_pipe_drivers"
fi
if test "x$enable_gallium_osmesa" = xyes; then
if ! echo "$with_gallium_drivers" | grep -q 'swrast'; then
AC_MSG_ERROR([gallium_osmesa requires the gallium swrast driver])
@ -1227,7 +1233,8 @@ xyesno)
if test x"$enable_dri3" = xyes; then
PKG_CHECK_EXISTS([xcb >= $XCB_REQUIRED], [], AC_MSG_ERROR([DRI3 requires xcb >= $XCB_REQUIRED]))
dri_modules="$dri_modules xcb-dri3 xcb-present xcb-sync xshmfence >= $XSHMFENCE_REQUIRED"
dri3_modules="xcb-dri3 xcb-present xcb-sync xshmfence >= $XSHMFENCE_REQUIRED"
PKG_CHECK_MODULES([XCB_DRI3], [$dri3_modules])
fi
fi
if test x"$dri_platform" = xapple ; then
@ -1570,6 +1577,12 @@ if test "x$enable_egl" = xyes; then
if test "x$enable_shared_glapi" = xno; then
AC_MSG_ERROR([egl_dri2 requires --enable-shared-glapi])
fi
if test "x$enable_dri3" = xyes; then
HAVE_EGL_DRIVER_DRI3=1
if test "x$enable_shared_glapi" = xno; then
AC_MSG_ERROR([egl_dri3 requires --enable-shared-glapi])
fi
fi
else
# Avoid building an "empty" libEGL. Drop/update this
# when other backends (haiku?) come along.
@ -1595,7 +1608,6 @@ if test "x$enable_xa" = xyes; then
enabling XA.
Example: ./configure --enable-xa --with-gallium-drivers=svga...])
fi
enable_gallium_loader=$enable_shared_pipe_drivers
gallium_st="$gallium_st xa"
fi
AM_CONDITIONAL(HAVE_ST_XA, test "x$enable_xa" = xyes)
@ -1641,28 +1653,24 @@ AM_CONDITIONAL(NEED_GALLIUM_VL_WINSYS, test "x$need_gallium_vl_winsys" = xyes)
if test "x$enable_xvmc" = xyes; then
PKG_CHECK_MODULES([XVMC], [xvmc >= $XVMC_REQUIRED])
enable_gallium_loader=$enable_shared_pipe_drivers
gallium_st="$gallium_st xvmc"
fi
AM_CONDITIONAL(HAVE_ST_XVMC, test "x$enable_xvmc" = xyes)
if test "x$enable_vdpau" = xyes; then
PKG_CHECK_MODULES([VDPAU], [vdpau >= $VDPAU_REQUIRED])
enable_gallium_loader=$enable_shared_pipe_drivers
gallium_st="$gallium_st vdpau"
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])
enable_gallium_loader=$enable_shared_pipe_drivers
gallium_st="$gallium_st omx"
fi
AM_CONDITIONAL(HAVE_ST_OMX, test "x$enable_omx" = xyes)
if test "x$enable_va" = xyes; then
PKG_CHECK_MODULES([VA], [libva >= $LIBVA_REQUIRED])
enable_gallium_loader=$enable_shared_pipe_drivers
gallium_st="$gallium_st va"
fi
AM_CONDITIONAL(HAVE_ST_VA, test "x$enable_va" = xyes)
@ -1685,7 +1693,6 @@ if test "x$enable_nine" = xyes; then
AC_MSG_WARN([using nine together with wine requires DRI3 enabled system])
fi
enable_gallium_loader=$enable_shared_pipe_drivers
gallium_st="$gallium_st nine"
fi
AM_CONDITIONAL(HAVE_ST_NINE, test "x$enable_nine" = xyes)
@ -1724,8 +1731,6 @@ if test "x$enable_opencl" = xyes; then
AC_SUBST([LIBCLC_LIBEXECDIR])
fi
# XXX: Use $enable_shared_pipe_drivers once converted to use static/shared pipe-drivers
enable_gallium_loader=yes
gallium_st="$gallium_st clover"
if test "x$enable_opencl_icd" = xyes; then
@ -2006,10 +2011,6 @@ AC_SUBST([XVMC_LIB_INSTALL_DIR])
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)
dnl Directory for VDPAU libs
@ -2064,14 +2065,8 @@ gallium_require_llvm() {
}
gallium_require_drm_loader() {
if test "x$enable_gallium_loader" = xyes; then
if test "x$need_pci_id$have_pci_id" = xyesno; then
AC_MSG_ERROR([Gallium drm loader requires libudev >= $LIBUDEV_REQUIRED or sysfs])
fi
enable_gallium_drm_loader=yes
fi
if test "x$enable_va" = xyes && test "x$7" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $7"
if test "x$need_pci_id$have_pci_id" = xyesno; then
AC_MSG_ERROR([Gallium drm loader requires libudev >= $LIBUDEV_REQUIRED or sysfs])
fi
}
@ -2186,7 +2181,9 @@ if test -n "$with_gallium_drivers"; then
gallium_require_drm_loader
PKG_CHECK_MODULES([SIMPENROSE], [simpenrose],
[USE_VC4_SIMULATOR=yes], [USE_VC4_SIMULATOR=no])
[USE_VC4_SIMULATOR=yes;
DEFINES="$DEFINES -DUSE_VC4_SIMULATOR"],
[USE_VC4_SIMULATOR=no])
;;
xvirgl)
HAVE_GALLIUM_VIRGL=yes
@ -2269,23 +2266,15 @@ AM_CONDITIONAL(HAVE_GALLIUM_VIRGL, test "x$HAVE_GALLIUM_VIRGL" = 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,
# one that is standalone and does not link any x client libs (for
# use by XA tracker in particular, but could be used in any case
# where communication with xserver is not desired).
if test "x$enable_gallium_loader" = xyes; then
if test "x$enable_dri" = xyes; then
GALLIUM_PIPE_LOADER_DEFINES="$GALLIUM_PIPE_LOADER_DEFINES -DHAVE_PIPE_LOADER_DRI"
fi
if test "x$enable_gallium_drm_loader" = xyes; then
GALLIUM_PIPE_LOADER_DEFINES="$GALLIUM_PIPE_LOADER_DEFINES -DHAVE_PIPE_LOADER_DRM"
fi
AC_SUBST([GALLIUM_PIPE_LOADER_DEFINES])
if test "x$enable_dri" = xyes; then
GALLIUM_PIPE_LOADER_DEFINES="$GALLIUM_PIPE_LOADER_DEFINES -DHAVE_PIPE_LOADER_DRI"
fi
if test "x$have_drisw_kms" = xyes; then
GALLIUM_PIPE_LOADER_DEFINES="$GALLIUM_PIPE_LOADER_DEFINES -DHAVE_PIPE_LOADER_KMS"
fi
AC_SUBST([GALLIUM_PIPE_LOADER_DEFINES])
AM_CONDITIONAL(HAVE_I915_DRI, test x$HAVE_I915_DRI = xyes)
AM_CONDITIONAL(HAVE_I965_DRI, test x$HAVE_I965_DRI = xyes)
AM_CONDITIONAL(HAVE_NOUVEAU_DRI, test x$HAVE_NOUVEAU_DRI = xyes)
@ -2299,8 +2288,6 @@ AM_CONDITIONAL(NEED_RADEON_DRM_WINSYS, test "x$HAVE_GALLIUM_R300" = xyes -o \
AM_CONDITIONAL(NEED_WINSYS_XLIB, test "x$NEED_WINSYS_XLIB" = xyes)
AM_CONDITIONAL(NEED_RADEON_LLVM, test x$NEED_RADEON_LLVM = xyes)
AM_CONDITIONAL(USE_R600_LLVM_COMPILER, test x$USE_R600_LLVM_COMPILER = xyes)
AM_CONDITIONAL(HAVE_LOADER_GALLIUM, test x$enable_gallium_loader = xyes)
AM_CONDITIONAL(HAVE_DRM_LOADER_GALLIUM, test x$enable_gallium_drm_loader = xyes)
AM_CONDITIONAL(HAVE_GALLIUM_COMPUTE, test x$enable_opencl = xyes)
AM_CONDITIONAL(HAVE_MESA_LLVM, test x$MESA_LLVM = x1)
AM_CONDITIONAL(USE_VC4_SIMULATOR, test x$USE_VC4_SIMULATOR = xyes)
@ -2532,6 +2519,9 @@ if test "$enable_egl" = yes; then
if test "x$HAVE_EGL_DRIVER_DRI2" != "x"; then
egl_drivers="$egl_drivers builtin:egl_dri2"
fi
if test "x$HAVE_EGL_DRIVER_DRI3" != "x"; then
egl_drivers="$egl_drivers builtin:egl_dri3"
fi
echo " EGL drivers: $egl_drivers"
fi

View file

@ -179,7 +179,7 @@ GL 4.4, GLSL 4.40:
GL_ARB_buffer_storage DONE (i965, nv50, nvc0, r600, radeonsi)
GL_ARB_clear_texture DONE (i965, nv50, nvc0)
GL_ARB_enhanced_layouts in progress (Timothy)
- compile-time constant expressions in progress
- compile-time constant expressions DONE
- explicit byte offsets for blocks in progress
- forced alignment within blocks in progress
- specified vec4-slot component numbers in progress

View file

@ -179,6 +179,14 @@ Mesa EGL supports different sets of environment variables. See the
<li>GALLIUM_HUD - draws various information on the screen, like framerate,
cpu load, driver statistics, performance counters, etc.
Set GALLIUM_HUD=help and run e.g. glxgears for more info.
<li>GALLIUM_HUD_PERIOD - sets the hud update rate in seconds (float). Use zero
to update every frame. The default period is 1/2 second.
<li>GALLIUM_HUD_VISIBLE - control default visibility, defaults to true.
<li>GALLIUM_HUD_TOGGLE_SIGNAL - toggle visibility via user specified signal.
Especially useful to toggle hud at specific points of application and
disable for unencumbered viewing the rest of the time. For example, set
GALLIUM_HUD_VISIBLE to false and GALLIUM_HUD_SIGNAL_TOGGLE to 10 (SIGUSR1).
Use kill -10 <pid> to toggle the hud as desired.
<li>GALLIUM_LOG_FILE - specifies a file for logging all errors, warnings, etc.
rather than stderr.
<li>GALLIUM_PRINT_OPTIONS - if non-zero, print all the Gallium environment

View file

@ -16,6 +16,12 @@
<h1>News</h1>
<h2>November 21, 2015</h2>
<p>
<a href="relnotes/11.0.6.html">Mesa 11.0.6</a> is released.
This is a bug-fix release.
</p>
<h2>November 11, 2015</h2>
<p>
<a href="relnotes/11.0.5.html">Mesa 11.0.5</a> is released.

View file

@ -21,6 +21,7 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<ul>
<li><a href="relnotes/11.0.6.html">11.0.6 release notes</a>
<li><a href="relnotes/11.0.5.html">11.0.5 release notes</a>
<li><a href="relnotes/11.0.4.html">11.0.4 release notes</a>
<li><a href="relnotes/11.0.3.html">11.0.3 release notes</a>

145
docs/relnotes/11.0.6.html Normal file
View file

@ -0,0 +1,145 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.0.6 Release Notes / November 21, 2015</h1>
<p>
Mesa 11.0.6 is a bug fix release which fixes bugs found since the 11.0.5 release.
</p>
<p>
Mesa 11.0.6 implements the OpenGL 4.1 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
4.1 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
4bdf054af66ebabf3eca0616f9f5e44c2f234695661b570261c391bc2f4f7482 mesa-11.0.6.tar.gz
8340e64cdc91999840404c211496f3de38e7b4cb38db34e2f72f1642c5134760 mesa-11.0.6.tar.xz
</pre>
<h2>New features</h2>
<p>None</p>
<h2>Bug fixes</h2>
<p>This list is likely incomplete.</p>
<ul>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=91780">Bug 91780</a> - Rendering issues with geometry shader</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92588">Bug 92588</a> - [HSW,BDW,BSW,SKL-Y][GLES 3.1 CTS] ES31-CTS.arrays_of_arrays.InteractionFunctionCalls2 - assert</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92738">Bug 92738</a> - Randon R7 240 doesn't work on 16KiB page size platform</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92860">Bug 92860</a> - [radeonsi][bisected] st/mesa: implement ARB_copy_image - Corruption in ARK Survival Evolved</li>
<li><a href="https://bugs.freedesktop.org/show_bug.cgi?id=92900">Bug 92900</a> - [regression bisected] About 700 piglit regressions is what could go wrong</li>
</ul>
<h2>Changes</h2>
<p>Alex Deucher (1):</p>
<ul>
<li>radeonsi: enable optimal raster config setting for fiji (v2)</li>
</ul>
<p>Ben Widawsky (1):</p>
<ul>
<li>i965/skl/gt4: Fix URB programming restriction.</li>
</ul>
<p>Boyuan Zhang (2):</p>
<ul>
<li>st/vaapi: fix vaapi VC-1 simple/main corruption v2</li>
<li>radeon/uvd: fix VC-1 simple/main profile decode v2</li>
</ul>
<p>Dave Airlie (1):</p>
<ul>
<li>r600: initialised PGM_RESOURCES_2 for ES/GS</li>
</ul>
<p>Emil Velikov (4):</p>
<ul>
<li>docs: add sha256 checksums for 11.0.5</li>
<li>cherry-ignore: add the swrast front buffer support</li>
<li>automake: use static llvm for make distcheck</li>
<li>Update version to 11.0.6</li>
</ul>
<p>Eric Anholt (3):</p>
<ul>
<li>vc4: Return GL_OUT_OF_MEMORY when buffer allocation fails.</li>
<li>vc4: Return NULL when we can't make our shadow for a sampler view.</li>
<li>vc4: Add support for nir_op_uge, using the carry bit on QPU_A_SUB.</li>
</ul>
<p>Ian Romanick (2):</p>
<ul>
<li>meta/generate_mipmap: Don't leak the sampler object</li>
<li>meta/generate_mipmap: Only modify the draw framebuffer binding in fallback_required</li>
</ul>
<p>Ilia Mirkin (2):</p>
<ul>
<li>mesa/copyimage: allow width/height to not be multiples of block</li>
<li>nouveau: don't expose HEVC decoding support</li>
</ul>
<p>Jason Ekstrand (1):</p>
<ul>
<li>nir/vars_to_ssa: Rework copy set handling in lower_copies_to_load_store</li>
</ul>
<p>Kenneth Graunke (1):</p>
<ul>
<li>glsl: Allow implicit int -&gt; uint conversions for the % operator.</li>
</ul>
<p>Marek Olšák (1):</p>
<ul>
<li>radeonsi: initialize SX_PS_DOWNCONVERT to 0 on Stoney</li>
</ul>
<p>Michel Dänzer (1):</p>
<ul>
<li>winsys/radeon: Use CPU page size instead of hardcoding 4096 bytes v3</li>
</ul>
<p>Oded Gabbay (1):</p>
<ul>
<li>llvmpipe: use simple coeffs calc for 128bit vectors</li>
</ul>
<p>Roland Scheidegger (2):</p>
<ul>
<li>radeon: fix bgrx8/xrgb8 blits</li>
<li>r200: fix bgrx8/xrgb8 blits</li>
</ul>
</div>
</body>
</html>

View file

@ -44,25 +44,41 @@ Note: some of the new features are only available with certain drivers.
</p>
<ul>
<li>OpenGL 3.1 support on freedreno (a3xx, a4xx)</li>
<li>OpenGL 3.3 support for VMware guest VM driver (supported by Workstation 12
and Fusion 8).
<li>GL_AMD_performance_monitor on nv50</li>
<li>GL_ARB_arrays_of_arrays on i965</li>
<li>GL_ARB_blend_func_extended on freedreno (a3xx)</li>
<li>GL_ARB_clear_texture on nv50, nvc0</li>
<li>GL_ARB_clip_control on freedreno/a4xx</li>
<li>GL_ARB_copy_image on nv50, nvc0, radeonsi</li>
<li>GL_ARB_depth_clamp on freedreno/a4xx</li>
<li>GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips</li>
<li>GL_ARB_gpu_shader5 on r600 for Evergreen and later chips</li>
<li>GL_ARB_seamless_cubemap_per_texture on freedreno/a4xx</li>
<li>GL_ARB_shader_clock on i965 (gen7+)</li>
<li>GL_ARB_shader_stencil_export on i965 (gen9+)</li>
<li>GL_ARB_shader_storage_buffer_object on i965</li>
<li>GL_ARB_shader_texture_image_samples on i965, nv50, nvc0, r600, radeonsi</li>
<li>GL_ARB_texture_barrier / GL_NV_texture_barrier on i965</li>
<li>GL_ARB_texture_buffer_range on freedreno/a3xx</li>
<li>GL_ARB_texture_compression_bptc on freedreno/a4xx</li>
<li>GL_ARB_texture_query_lod on softpipe</li>
<li>GL_ARB_texture_view on radeonsi and r600 (for evergeen and newer)</li>
<li>GL_ARB_vertex_type_2_10_10_10_rev on freedreno (a3xx, a4xx)</li>
<li>GL_EXT_blend_func_extended on all drivers that support the ARB version</li>
<li>GL_EXT_buffer_storage implemented for when ES 3.1 support is gained</li>
<li>GL_EXT_draw_elements_base_vertex on all drivers</li>
<li>GL_EXT_texture_compression_rgtc / latc on freedreno (a3xx & a4xx)</li>
<li>GL_KHR_debug (GLES)</li>
<li>GL_NV_conditional_render on freedreno</li>
<li>GL_OES_draw_elements_base_vertex on all drivers</li>
<li>EGL_KHR_create_context on softpipe, llvmpipe</li>
<li>EGL_KHR_gl_colorspace on softpipe, llvmpipe</li>
<li>new virgl gallium driver for qemu virtio-gpu</li>
<li>16x multisampling on i965 (gen9+)</li>
<li>GL_EXT_shader_samples_identical on i965.</li>
</ul>
<h2>Bug fixes</h2>

67
docs/relnotes/11.2.0.html Normal file
View file

@ -0,0 +1,67 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Mesa Release Notes</title>
<link rel="stylesheet" type="text/css" href="../mesa.css">
</head>
<body>
<div class="header">
<h1>The Mesa 3D Graphics Library</h1>
</div>
<iframe src="../contents.html"></iframe>
<div class="content">
<h1>Mesa 11.2.0 Release Notes / TBD</h1>
<p>
Mesa 11.2.0 is a new development release.
People who are concerned with stability and reliability should stick
with a previous release or wait for Mesa 11.2.1.
</p>
<p>
Mesa 11.2.0 implements the OpenGL 4.1 API, but the version reported by
glGetString(GL_VERSION) or glGetIntegerv(GL_MAJOR_VERSION) /
glGetIntegerv(GL_MINOR_VERSION) depends on the particular driver being used.
Some drivers don't support all the features required in OpenGL 4.1. OpenGL
4.1 is <strong>only</strong> available if requested at context creation
because compatibility contexts are not supported.
</p>
<h2>SHA256 checksums</h2>
<pre>
TBD.
</pre>
<h2>New features</h2>
<p>
Note: some of the new features are only available with certain drivers.
</p>
<ul>
<li>GL_ARB_base_instance on freedreno/a4xx</li>
<li>GL_ARB_texture_buffer_object_rgb32 on freedreno/a4xx</li>
<li>GL_ARB_texture_buffer_range on freedreno/a4xx</li>
<li>GL_ARB_texture_query_lod on freedreno/a4xx</li>
<li>GL_ARB_texture_rgb10_a2ui on freedreno/a4xx</li>
<li>GL_ARB_texture_view on freedreno/a4xx</li>
<li>GL_ARB_vertex_type_10f_11f_11f_rev on freedreno/a4xx</li>
<li>GL_KHR_texture_compression_astc_ldr on freedreno/a4xx</li>
</ul>
<h2>Bug fixes</h2>
TBD.
<h2>Changes</h2>
TBD.
</div>
</body>
</html>

View file

@ -0,0 +1,176 @@
Name
EXT_shader_samples_identical
Name Strings
GL_EXT_shader_samples_identical
Contact
Ian Romanick, Intel (ian.d.romanick 'at' intel.com)
Contributors
Chris Forbes, Mesa
Magnus Wendt, Intel
Neil S. Roberts, Intel
Graham Sellers, AMD
Status
XXX - Not complete yet.
Version
Last Modified Date: November 19, 2015
Revision: 6
Number
TBD
Dependencies
OpenGL 3.2, or OpenGL ES 3.1, or ARB_texture_multisample is required.
This extension is written against the OpenGL 4.5 (Core Profile)
Specification
Overview
Multisampled antialiasing has become a common method for improving the
quality of rendered images. Multisampling differs from supersampling in
that the color of a primitive that covers all or part of a pixel is
resolved once, regardless of the number of samples covered. If a large
polygon is rendered, the colors of all samples in each interior pixel will
be the same. This suggests a simple compression scheme that can reduce
the necessary memory bandwidth requirements. In one such scheme, each
sample is stored in a separate slice of the multisample surface. An
additional multisample control surface (MCS) contains a mapping from pixel
samples to slices.
If all the values stored in the MCS for a particular pixel are the same,
then all the samples have the same value. Applications can take advantage
of this information to reduce the bandwidth of reading multisample
textures. A custom multisample resolve filter could optimize resolving
pixels where every sample is identical by reading the color once.
color = texelFetch(sampler, coordinate, 0);
if (!textureSamplesIdenticalEXT(sampler, coordinate)) {
for (int i = 1; i < MAX_SAMPLES; i++) {
vec4 c = texelFetch(sampler, coordinate, i);
//... accumulate c into color
}
}
New Procedures and Functions
None.
New Tokens
None.
Additions to the OpenGL 4.5 (Core Profile) Specification
None.
Modifications to The OpenGL Shading Language Specification, Version 4.50.5
Including the following line in a shader can be used to control the
language features described in this extension:
#extension GL_EXT_shader_samples_identical
A new preprocessor #define is added to the OpenGL Shading Language:
#define GL_EXT_shader_samples_identical
Add to the table in section 8.7 "Texture Lookup Functions"
Syntax:
bool textureSamplesIdenticalEXT(gsampler2DMS sampler, ivec2 coord)
bool textureSamplesIdenticalEXT(gsampler2DMSArray sampler,
ivec3 coord)
Description:
Returns true if it can be determined that all samples within the texel
of the multisample texture bound to <sampler> at <coord> contain the
same values or false if this cannot be determined."
Additions to the AGL/EGL/GLX/WGL Specifications
None
Errors
None
New State
None
New Implementation Dependent State
None
Issues
1) What should the new functions be called?
RESOLVED: textureSamplesIdenticalEXT. Initially
textureAllSamplesIdenticalEXT was considered, but
textureSamplesIdenticalEXT is more similar to the existing textureSamples
function.
2) It seems like applications could implement additional optimization if
they were provided with raw MCS data. Should this extension also
provide that data?
There are a number of challenges in providing raw MCS data. The biggest
problem being that the amount of MCS data depends on the number of
samples, and that is not known at compile time. Additionally, without new
texelFetch functions, applications would have difficulty utilizing the
information.
Another option is to have a function that returns an array of tuples of
sample number and count. This also has difficulties with the maximum
array size not being known at compile time.
RESOLVED: Do not expose raw MCS data in this extension.
3) Should this extension also extend SPIR-V?
RESOLVED: Yes, but this has not yet been written.
4) Is it possible for textureSamplesIdenticalEXT to report false negatives?
RESOLVED: Yes. It is possible that the underlying hardware may not detect
that separate writes of the same color to different samples of a pixel are
the same. The shader function is at the whim of the underlying hardware
implementation. It is also possible that a compressed multisample surface
is not used. In that case the function will likely always return false.
Revision History
Rev Date Author Changes
--- ---------- -------- ---------------------------------------------
1 2014/08/20 cforbes Initial version
2 2015/10/23 idr Change from MESA to EXT. Rebase on OpenGL 4.5,
and add dependency on OpenGL ES 3.1. Initial
draft of overview section and issues 1 through
3.
3 2015/10/27 idr Typo fixes.
4 2015/11/10 idr Rename extension from EXT_shader_multisample_compression
to EXT_shader_samples_identical.
Add issue #4.
5 2015/11/18 idr Fix some typos spotted by gsellers. Change the
name of the name of the function to
textureSamplesIdenticalEXT.
6 2015/11/19 idr Fix more typos spotted by Nicolai Hähnle.

View file

@ -47,12 +47,21 @@ libEGL_la_LDFLAGS = \
$(LD_NO_UNDEFINED)
dri2_backend_FILES =
dri3_backend_FILES =
if HAVE_EGL_PLATFORM_X11
AM_CFLAGS += -DHAVE_X11_PLATFORM
AM_CFLAGS += $(XCB_DRI2_CFLAGS)
libEGL_la_LIBADD += $(XCB_DRI2_LIBS)
dri2_backend_FILES += drivers/dri2/platform_x11.c
if HAVE_DRI3
dri3_backend_FILES += \
drivers/dri2/platform_x11_dri3.c \
drivers/dri2/platform_x11_dri3.h
libEGL_la_LIBADD += $(top_builddir)/src/loader/libloader_dri3_helper.la
endif
endif
if HAVE_EGL_PLATFORM_WAYLAND
@ -88,7 +97,8 @@ AM_CFLAGS += \
libEGL_la_SOURCES += \
$(dri2_backend_core_FILES) \
$(dri2_backend_FILES)
$(dri2_backend_FILES) \
$(dri3_backend_FILES)
libEGL_la_LIBADD += $(top_builddir)/src/loader/libloader.la
libEGL_la_LIBADD += $(DLOPEN_LIBS) $(LIBDRM_LIBS)
@ -111,7 +121,10 @@ egl_HEADERS = \
$(top_srcdir)/include/EGL/eglmesaext.h \
$(top_srcdir)/include/EGL/eglplatform.h
TESTS = egl-symbols-check
EXTRA_DIST = \
egl-symbols-check \
SConscript \
drivers/haiku \
docs \

View file

@ -352,6 +352,12 @@ struct dri2_extension_match {
int offset;
};
static struct dri2_extension_match dri3_driver_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) },
{ __DRI_IMAGE_DRIVER, 1, offsetof(struct dri2_egl_display, image_driver) },
{ NULL, 0, 0 }
};
static struct dri2_extension_match dri2_driver_extensions[] = {
{ __DRI_CORE, 1, offsetof(struct dri2_egl_display, core) },
{ __DRI_DRI2, 2, offsetof(struct dri2_egl_display, dri2) },
@ -385,13 +391,13 @@ dri2_bind_extensions(struct dri2_egl_display *dri2_dpy,
void *field;
for (i = 0; extensions[i]; i++) {
_eglLog(_EGL_DEBUG, "DRI2: found extension `%s'", extensions[i]->name);
_eglLog(_EGL_DEBUG, "found extension `%s'", extensions[i]->name);
for (j = 0; matches[j].name; j++) {
if (strcmp(extensions[i]->name, matches[j].name) == 0 &&
extensions[i]->version >= matches[j].version) {
field = ((char *) dri2_dpy + matches[j].offset);
*(const __DRIextension **) field = extensions[i];
_eglLog(_EGL_INFO, "DRI2: found extension %s version %d",
_eglLog(_EGL_INFO, "found extension %s version %d",
extensions[i]->name, extensions[i]->version);
}
}
@ -400,7 +406,7 @@ dri2_bind_extensions(struct dri2_egl_display *dri2_dpy,
for (j = 0; matches[j].name; j++) {
field = ((char *) dri2_dpy + matches[j].offset);
if (*(const __DRIextension **) field == NULL) {
_eglLog(_EGL_WARNING, "DRI2: did not find extension %s version %d",
_eglLog(_EGL_WARNING, "did not find extension %s version %d",
matches[j].name, matches[j].version);
ret = EGL_FALSE;
}
@ -493,6 +499,25 @@ dri2_open_driver(_EGLDisplay *disp)
return extensions;
}
EGLBoolean
dri2_load_driver_dri3(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy = disp->DriverData;
const __DRIextension **extensions;
extensions = dri2_open_driver(disp);
if (!extensions)
return EGL_FALSE;
if (!dri2_bind_extensions(dri2_dpy, dri3_driver_extensions, extensions)) {
dlclose(dri2_dpy->driver);
return EGL_FALSE;
}
dri2_dpy->driver_extensions = extensions;
return EGL_TRUE;
}
EGLBoolean
dri2_load_driver(_EGLDisplay *disp)
{
@ -550,7 +575,9 @@ dri2_setup_screen(_EGLDisplay *disp)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int api_mask;
if (dri2_dpy->dri2) {
if (dri2_dpy->image_driver) {
api_mask = dri2_dpy->image_driver->getAPIMask(dri2_dpy->dri_screen);
} else if (dri2_dpy->dri2) {
api_mask = dri2_dpy->dri2->getAPIMask(dri2_dpy->dri_screen);
} else {
assert(dri2_dpy->swrast);
@ -570,7 +597,7 @@ dri2_setup_screen(_EGLDisplay *disp)
if (api_mask & (1 << __DRI_API_GLES3))
disp->ClientAPIs |= EGL_OPENGL_ES3_BIT_KHR;
assert(dri2_dpy->dri2 || dri2_dpy->swrast);
assert(dri2_dpy->image_driver || dri2_dpy->dri2 || dri2_dpy->swrast);
disp->Extensions.KHR_surfaceless_context = EGL_TRUE;
disp->Extensions.MESA_configless_context = EGL_TRUE;
@ -578,7 +605,8 @@ dri2_setup_screen(_EGLDisplay *disp)
__DRI2_RENDERER_HAS_FRAMEBUFFER_SRGB))
disp->Extensions.KHR_gl_colorspace = EGL_TRUE;
if ((dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) ||
if (dri2_dpy->image_driver ||
(dri2_dpy->dri2 && dri2_dpy->dri2->base.version >= 3) ||
(dri2_dpy->swrast && dri2_dpy->swrast->base.version >= 3)) {
disp->Extensions.KHR_create_context = EGL_TRUE;
@ -641,7 +669,14 @@ dri2_create_screen(_EGLDisplay *disp)
dri2_dpy = disp->DriverData;
if (dri2_dpy->dri2) {
if (dri2_dpy->image_driver) {
dri2_dpy->dri_screen =
dri2_dpy->image_driver->createNewScreen2(0, dri2_dpy->fd,
dri2_dpy->extensions,
dri2_dpy->driver_extensions,
&dri2_dpy->driver_configs,
disp);
} else if (dri2_dpy->dri2) {
if (dri2_dpy->dri2->base.version >= 4) {
dri2_dpy->dri_screen =
dri2_dpy->dri2->createNewScreen2(0, dri2_dpy->fd,
@ -677,7 +712,7 @@ dri2_create_screen(_EGLDisplay *disp)
extensions = dri2_dpy->core->getExtensions(dri2_dpy->dri_screen);
if (dri2_dpy->dri2) {
if (dri2_dpy->image_driver || dri2_dpy->dri2) {
if (!dri2_bind_extensions(dri2_dpy, dri2_core_extensions, extensions))
goto cleanup_dri_screen;
} else {
@ -1024,7 +1059,26 @@ dri2_create_context(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
else
dri_config = NULL;
if (dri2_dpy->dri2) {
if (dri2_dpy->image_driver) {
unsigned error;
unsigned num_attribs = 8;
uint32_t ctx_attribs[8];
if (!dri2_fill_context_attribs(dri2_ctx, dri2_dpy, ctx_attribs,
&num_attribs))
goto cleanup;
dri2_ctx->dri_context =
dri2_dpy->image_driver->createContextAttribs(dri2_dpy->dri_screen,
api,
dri_config,
shared,
num_attribs / 2,
ctx_attribs,
& error,
dri2_ctx);
dri2_create_context_attribs_error(error);
} else if (dri2_dpy->dri2) {
if (dri2_dpy->dri2->base.version >= 3) {
unsigned error;
unsigned num_attribs = 8;
@ -1119,11 +1173,10 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
{
struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv);
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_dsurf = dri2_egl_surface(dsurf);
struct dri2_egl_surface *dri2_rsurf = dri2_egl_surface(rsurf);
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
_EGLContext *old_ctx;
_EGLSurface *old_dsurf, *old_rsurf;
_EGLSurface *tmp_dsurf, *tmp_rsurf;
__DRIdrawable *ddraw, *rdraw;
__DRIcontext *cctx;
@ -1135,8 +1188,8 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
if (old_ctx && dri2_drv->glFlush)
dri2_drv->glFlush();
ddraw = (dri2_dsurf) ? dri2_dsurf->dri_drawable : NULL;
rdraw = (dri2_rsurf) ? dri2_rsurf->dri_drawable : NULL;
ddraw = (dsurf) ? dri2_dpy->vtbl->get_dri_drawable(dsurf) : NULL;
rdraw = (rsurf) ? dri2_dpy->vtbl->get_dri_drawable(rsurf) : NULL;
cctx = (dri2_ctx) ? dri2_ctx->dri_context : NULL;
if (old_ctx) {
@ -1156,10 +1209,10 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
return EGL_TRUE;
} else {
/* undo the previous _eglBindContext */
_eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &dsurf, &rsurf);
_eglBindContext(old_ctx, old_dsurf, old_rsurf, &ctx, &tmp_dsurf, &tmp_rsurf);
assert(&dri2_ctx->base == ctx &&
&dri2_dsurf->base == dsurf &&
&dri2_rsurf->base == rsurf);
tmp_dsurf == dsurf &&
tmp_rsurf == rsurf);
_eglPutSurface(dsurf);
_eglPutSurface(rsurf);
@ -1173,6 +1226,14 @@ dri2_make_current(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
}
}
__DRIdrawable *
dri2_surface_get_dri_drawable(_EGLSurface *surf)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
return dri2_surf->dri_drawable;
}
/*
* Called from eglGetProcAddress() via drv->API.GetProcAddress().
*/
@ -1235,7 +1296,7 @@ void
dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
__DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(draw);
if (dri2_dpy->flush) {
if (dri2_dpy->flush->base.version >= 4) {
@ -1253,12 +1314,12 @@ dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw)
* after calling eglSwapBuffers."
*/
dri2_dpy->flush->flush_with_flags(dri2_ctx->dri_context,
dri2_surf->dri_drawable,
dri_drawable,
__DRI2_FLUSH_DRAWABLE |
__DRI2_FLUSH_INVALIDATE_ANCILLARY,
__DRI2_THROTTLE_SWAPBUFFER);
} else {
dri2_dpy->flush->flush(dri2_surf->dri_drawable);
dri2_dpy->flush->flush(dri_drawable);
}
}
}
@ -1315,7 +1376,8 @@ static EGLBoolean
dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(ctx->DrawSurface);
_EGLSurface *surf = ctx->DrawSurface;
__DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
(void) drv;
@ -1323,7 +1385,7 @@ dri2_wait_client(_EGLDriver *drv, _EGLDisplay *disp, _EGLContext *ctx)
* we need to copy fake to real here.*/
if (dri2_dpy->flush != NULL)
dri2_dpy->flush->flush(dri2_surf->dri_drawable);
dri2_dpy->flush->flush(dri_drawable);
return EGL_TRUE;
}
@ -1346,10 +1408,10 @@ dri2_bind_tex_image(_EGLDriver *drv,
_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct dri2_egl_context *dri2_ctx;
_EGLContext *ctx;
GLint format, target;
__DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
ctx = _eglGetCurrentContext();
dri2_ctx = dri2_egl_context(ctx);
@ -1357,7 +1419,7 @@ dri2_bind_tex_image(_EGLDriver *drv,
if (!_eglBindTexImage(drv, disp, surf, buffer))
return EGL_FALSE;
switch (dri2_surf->base.TextureFormat) {
switch (surf->TextureFormat) {
case EGL_TEXTURE_RGB:
format = __DRI_TEXTURE_FORMAT_RGB;
break;
@ -1369,7 +1431,7 @@ dri2_bind_tex_image(_EGLDriver *drv,
format = __DRI_TEXTURE_FORMAT_RGBA;
}
switch (dri2_surf->base.TextureTarget) {
switch (surf->TextureTarget) {
case EGL_TEXTURE_2D:
target = GL_TEXTURE_2D;
break;
@ -1380,7 +1442,7 @@ dri2_bind_tex_image(_EGLDriver *drv,
(*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context,
target, format,
dri2_surf->dri_drawable);
dri_drawable);
return EGL_TRUE;
}
@ -1390,10 +1452,10 @@ dri2_release_tex_image(_EGLDriver *drv,
_EGLDisplay *disp, _EGLSurface *surf, EGLint buffer)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
struct dri2_egl_context *dri2_ctx;
_EGLContext *ctx;
GLint target;
__DRIdrawable *dri_drawable = dri2_dpy->vtbl->get_dri_drawable(surf);
ctx = _eglGetCurrentContext();
dri2_ctx = dri2_egl_context(ctx);
@ -1401,7 +1463,7 @@ dri2_release_tex_image(_EGLDriver *drv,
if (!_eglReleaseTexImage(drv, disp, surf, buffer))
return EGL_FALSE;
switch (dri2_surf->base.TextureTarget) {
switch (surf->TextureTarget) {
case EGL_TEXTURE_2D:
target = GL_TEXTURE_2D;
break;
@ -1413,7 +1475,7 @@ dri2_release_tex_image(_EGLDriver *drv,
dri2_dpy->tex_buffer->releaseTexBuffer != NULL) {
(*dri2_dpy->tex_buffer->releaseTexBuffer)(dri2_ctx->dri_context,
target,
dri2_surf->dri_drawable);
dri_drawable);
}
return EGL_TRUE;

View file

@ -35,6 +35,10 @@
#include <xcb/dri2.h>
#include <xcb/xfixes.h>
#include <X11/Xlib-xcb.h>
#ifdef HAVE_DRI3
#include "loader_dri3_helper.h"
#endif
#endif
#ifdef HAVE_WAYLAND_PLATFORM
@ -145,6 +149,8 @@ struct dri2_egl_display_vtbl {
EGLBoolean (*get_sync_values)(_EGLDisplay *display, _EGLSurface *surface,
EGLuint64KHR *ust, EGLuint64KHR *msc,
EGLuint64KHR *sbc);
__DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf);
};
struct dri2_egl_display
@ -158,6 +164,7 @@ struct dri2_egl_display
const __DRIconfig **driver_configs;
void *driver;
const __DRIcoreExtension *core;
const __DRIimageDriverExtension *image_driver;
const __DRIdri2Extension *dri2;
const __DRIswrastExtension *swrast;
const __DRI2flushExtension *flush;
@ -190,6 +197,9 @@ struct dri2_egl_display
#ifdef HAVE_X11_PLATFORM
xcb_connection_t *conn;
int screen;
#ifdef HAVE_DRI3
struct loader_dri3_extensions loader_dri3_ext;
#endif
#endif
#ifdef HAVE_WAYLAND_PLATFORM
@ -203,8 +213,9 @@ struct dri2_egl_display
int formats;
uint32_t capabilities;
int is_render_node;
int is_different_gpu;
#endif
int is_different_gpu;
};
struct dri2_egl_context
@ -324,9 +335,15 @@ dri2_setup_screen(_EGLDisplay *disp);
EGLBoolean
dri2_load_driver_swrast(_EGLDisplay *disp);
EGLBoolean
dri2_load_driver_dri3(_EGLDisplay *disp);
EGLBoolean
dri2_create_screen(_EGLDisplay *disp);
__DRIdrawable *
dri2_surface_get_dri_drawable(_EGLSurface *surf);
__DRIimage *
dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);

View file

@ -650,6 +650,7 @@ static struct dri2_egl_display_vtbl droid_display_vtbl = {
.query_buffer_age = dri2_fallback_query_buffer_age,
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
EGLBoolean

View file

@ -594,6 +594,7 @@ static struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
.query_buffer_age = dri2_drm_query_buffer_age,
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
EGLBoolean

View file

@ -1025,6 +1025,7 @@ static struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
.query_buffer_age = dri2_wl_query_buffer_age,
.create_wayland_buffer_from_image = dri2_wl_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
static EGLBoolean
@ -1752,6 +1753,7 @@ static struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
.query_buffer_age = dri2_fallback_query_buffer_age,
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
static EGLBoolean

View file

@ -45,6 +45,10 @@
#include "egl_dri2_fallbacks.h"
#include "loader.h"
#ifdef HAVE_DRI3
#include "platform_x11_dri3.h"
#endif
static EGLBoolean
dri2_x11_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint interval);
@ -703,7 +707,7 @@ dri2_x11_local_authenticate(_EGLDisplay *disp)
static EGLBoolean
dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
_EGLDisplay *disp)
_EGLDisplay *disp, bool supports_preserved)
{
xcb_screen_iterator_t s;
xcb_depth_iterator_t d;
@ -724,8 +728,10 @@ dri2_x11_add_configs_for_visuals(struct dri2_egl_display *dri2_dpy,
surface_type =
EGL_WINDOW_BIT |
EGL_PIXMAP_BIT |
EGL_PBUFFER_BIT |
EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
EGL_PBUFFER_BIT;
if (supports_preserved)
surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
while (d.rem > 0) {
EGLBoolean class_added[6] = { 0, };
@ -1112,6 +1118,7 @@ static struct dri2_egl_display_vtbl dri2_x11_swrast_display_vtbl = {
.query_buffer_age = dri2_fallback_query_buffer_age,
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_fallback_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
static struct dri2_egl_display_vtbl dri2_x11_display_vtbl = {
@ -1130,6 +1137,7 @@ static struct dri2_egl_display_vtbl dri2_x11_display_vtbl = {
.query_buffer_age = dri2_fallback_query_buffer_age,
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri2_x11_get_sync_values,
.get_dri_drawable = dri2_surface_get_dri_drawable,
};
static EGLBoolean
@ -1179,7 +1187,7 @@ dri2_initialize_x11_swrast(_EGLDriver *drv, _EGLDisplay *disp)
if (!dri2_create_screen(disp))
goto cleanup_driver;
if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp))
if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true))
goto cleanup_configs;
/* Fill vtbl last to prevent accidentally calling virtual function during
@ -1250,6 +1258,100 @@ dri2_x11_setup_swap_interval(struct dri2_egl_display *dri2_dpy)
}
}
#ifdef HAVE_DRI3
static EGLBoolean
dri2_initialize_x11_dri3(_EGLDriver *drv, _EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
dri2_dpy = calloc(1, sizeof *dri2_dpy);
if (!dri2_dpy)
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
disp->DriverData = (void *) dri2_dpy;
if (disp->PlatformDisplay == NULL) {
dri2_dpy->conn = xcb_connect(0, &dri2_dpy->screen);
dri2_dpy->own_device = true;
} else {
Display *dpy = disp->PlatformDisplay;
dri2_dpy->conn = XGetXCBConnection(dpy);
dri2_dpy->screen = DefaultScreen(dpy);
}
if (xcb_connection_has_error(dri2_dpy->conn)) {
_eglLog(_EGL_WARNING, "DRI3: xcb_connect failed");
goto cleanup_dpy;
}
if (dri2_dpy->conn) {
if (!dri3_x11_connect(dri2_dpy))
goto cleanup_conn;
}
if (!dri2_load_driver_dri3(disp))
goto cleanup_conn;
dri2_dpy->extensions[0] = &dri3_image_loader_extension.base;
dri2_dpy->extensions[1] = &use_invalidate.base;
dri2_dpy->extensions[2] = &image_lookup_extension.base;
dri2_dpy->extensions[3] = NULL;
dri2_dpy->swap_available = true;
dri2_dpy->invalidate_available = true;
if (!dri2_create_screen(disp))
goto cleanup_fd;
dri2_x11_setup_swap_interval(dri2_dpy);
if (!dri2_dpy->is_different_gpu)
disp->Extensions.KHR_image_pixmap = EGL_TRUE;
disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
disp->Extensions.CHROMIUM_sync_control = EGL_TRUE;
disp->Extensions.EXT_buffer_age = EGL_TRUE;
#ifdef HAVE_WAYLAND_PLATFORM
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif
if (dri2_dpy->conn) {
if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, false))
goto cleanup_configs;
}
dri2_dpy->loader_dri3_ext.core = dri2_dpy->core;
dri2_dpy->loader_dri3_ext.image_driver = dri2_dpy->image_driver;
dri2_dpy->loader_dri3_ext.flush = dri2_dpy->flush;
dri2_dpy->loader_dri3_ext.tex_buffer = dri2_dpy->tex_buffer;
dri2_dpy->loader_dri3_ext.image = dri2_dpy->image;
dri2_dpy->loader_dri3_ext.config = dri2_dpy->config;
/* Fill vtbl last to prevent accidentally calling virtual function during
* initialization.
*/
dri2_dpy->vtbl = &dri3_x11_display_vtbl;
_eglLog(_EGL_INFO, "Using DRI3");
return EGL_TRUE;
cleanup_configs:
_eglCleanupDisplay(disp);
dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen);
dlclose(dri2_dpy->driver);
cleanup_fd:
close(dri2_dpy->fd);
cleanup_conn:
if (disp->PlatformDisplay == NULL)
xcb_disconnect(dri2_dpy->conn);
cleanup_dpy:
free(dri2_dpy);
return EGL_FALSE;
}
#endif
static EGLBoolean
dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
{
@ -1321,7 +1423,7 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
#endif
if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp))
if (!dri2_x11_add_configs_for_visuals(dri2_dpy, disp, true))
goto cleanup_configs;
/* Fill vtbl last to prevent accidentally calling virtual function during
@ -1329,6 +1431,8 @@ dri2_initialize_x11_dri2(_EGLDriver *drv, _EGLDisplay *disp)
*/
dri2_dpy->vtbl = &dri2_x11_display_vtbl;
_eglLog(_EGL_INFO, "Using DRI2");
return EGL_TRUE;
cleanup_configs:
@ -1355,9 +1459,16 @@ dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp)
int x11_dri2_accel = (getenv("LIBGL_ALWAYS_SOFTWARE") == NULL);
if (x11_dri2_accel) {
if (!dri2_initialize_x11_dri2(drv, disp)) {
initialized = dri2_initialize_x11_swrast(drv, disp);
#ifdef HAVE_DRI3
if (getenv("LIBGL_DRI3_DISABLE") != NULL ||
!dri2_initialize_x11_dri3(drv, disp)) {
#endif
if (!dri2_initialize_x11_dri2(drv, disp)) {
initialized = dri2_initialize_x11_swrast(drv, disp);
}
#ifdef HAVE_DRI3
}
#endif
} else {
initialized = dri2_initialize_x11_swrast(drv, disp);
}

View file

@ -0,0 +1,547 @@
/*
* Copyright © 2015 Boyan Ding
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <xcb/xcb.h>
#include <xcb/dri3.h>
#include <xcb/present.h>
#include <xf86drm.h>
#include "egl_dri2.h"
#include "egl_dri2_fallbacks.h"
#include "platform_x11_dri3.h"
#include "loader.h"
#include "loader_dri3_helper.h"
static struct dri3_egl_surface *
loader_drawable_to_egl_surface(struct loader_dri3_drawable *draw) {
size_t offset = offsetof(struct dri3_egl_surface, loader_drawable);
return (struct dri3_egl_surface *)(((void*) draw) - offset);
}
static int
egl_dri3_get_swap_interval(struct loader_dri3_drawable *draw)
{
struct dri3_egl_surface *dri3_surf = loader_drawable_to_egl_surface(draw);
return dri3_surf->base.SwapInterval;
}
static int
egl_dri3_clamp_swap_interval(struct loader_dri3_drawable *draw, int interval)
{
struct dri3_egl_surface *dri3_surf = loader_drawable_to_egl_surface(draw);
if (interval > dri3_surf->base.Config->MaxSwapInterval)
interval = dri3_surf->base.Config->MaxSwapInterval;
else if (interval < dri3_surf->base.Config->MinSwapInterval)
interval = dri3_surf->base.Config->MinSwapInterval;
return interval;
}
static void
egl_dri3_set_swap_interval(struct loader_dri3_drawable *draw, int interval)
{
struct dri3_egl_surface *dri3_surf = loader_drawable_to_egl_surface(draw);
dri3_surf->base.SwapInterval = interval;
}
static void
egl_dri3_set_drawable_size(struct loader_dri3_drawable *draw,
int width, int height)
{
struct dri3_egl_surface *dri3_surf = loader_drawable_to_egl_surface(draw);
dri3_surf->base.Width = width;
dri3_surf->base.Height = height;
}
static bool
egl_dri3_in_current_context(struct loader_dri3_drawable *draw)
{
struct dri3_egl_surface *dri3_surf = loader_drawable_to_egl_surface(draw);
_EGLContext *ctx = _eglGetCurrentContext();
return ctx->Resource.Display == dri3_surf->base.Resource.Display;
}
static __DRIcontext *
egl_dri3_get_dri_context(struct loader_dri3_drawable *draw)
{
_EGLContext *ctx = _eglGetCurrentContext();
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
return dri2_ctx->dri_context;
}
static void
egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
{
struct dri3_egl_surface *dri3_surf = loader_drawable_to_egl_surface(draw);
_EGLDisplay *disp = dri3_surf->base.Resource.Display;
dri2_flush_drawable_for_swapbuffers(disp, &dri3_surf->base);
}
static struct loader_dri3_vtable egl_dri3_vtable = {
.get_swap_interval = egl_dri3_get_swap_interval,
.clamp_swap_interval = egl_dri3_clamp_swap_interval,
.set_swap_interval = egl_dri3_set_swap_interval,
.set_drawable_size = egl_dri3_set_drawable_size,
.in_current_context = egl_dri3_in_current_context,
.get_dri_context = egl_dri3_get_dri_context,
.flush_drawable = egl_dri3_flush_drawable,
.show_fps = NULL,
};
static EGLBoolean
dri3_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surf);
(void) drv;
if (!_eglPutSurface(surf))
return EGL_TRUE;
loader_dri3_drawable_fini(&dri3_surf->loader_drawable);
free(surf);
return EGL_TRUE;
}
static EGLBoolean
dri3_set_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint interval)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surf);
loader_dri3_set_swap_interval(&dri3_surf->loader_drawable, interval);
return EGL_TRUE;
}
static xcb_screen_t *
get_xcb_screen(xcb_screen_iterator_t iter, int screen)
{
for (; iter.rem; --screen, xcb_screen_next(&iter))
if (screen == 0)
return iter.data;
return NULL;
}
static _EGLSurface *
dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type,
_EGLConfig *conf, void *native_surface,
const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
struct dri3_egl_surface *dri3_surf;
const __DRIconfig *dri_config;
xcb_drawable_t drawable;
xcb_screen_iterator_t s;
xcb_screen_t *screen;
STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface));
drawable = (uintptr_t) native_surface;
(void) drv;
dri3_surf = calloc(1, sizeof *dri3_surf);
if (!dri3_surf) {
_eglError(EGL_BAD_ALLOC, "dri3_create_surface");
return NULL;
}
if (!_eglInitSurface(&dri3_surf->base, disp, type, conf, attrib_list))
goto cleanup_surf;
if (type == EGL_PBUFFER_BIT) {
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
screen = get_xcb_screen(s, dri2_dpy->screen);
if (!screen) {
_eglError(EGL_BAD_NATIVE_WINDOW, "dri3_create_surface");
goto cleanup_surf;
}
drawable = xcb_generate_id(dri2_dpy->conn);
xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize,
drawable, screen->root,
dri3_surf->base.Width, dri3_surf->base.Height);
}
dri_config = dri2_get_dri_config(dri2_conf, type,
dri3_surf->base.GLColorspace);
if (loader_dri3_drawable_init(dri2_dpy->conn, drawable,
dri2_dpy->dri_screen,
dri2_dpy->is_different_gpu, dri_config,
&dri2_dpy->loader_dri3_ext,
&egl_dri3_vtable,
&dri3_surf->loader_drawable)) {
_eglError(EGL_BAD_ALLOC, "dri3_surface_create");
goto cleanup_pixmap;
}
return &dri3_surf->base;
cleanup_pixmap:
if (type == EGL_PBUFFER_BIT)
xcb_free_pixmap(dri2_dpy->conn, drawable);
cleanup_surf:
free(dri3_surf);
return NULL;
}
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
static _EGLSurface *
dri3_create_window_surface(_EGLDriver *drv, _EGLDisplay *disp,
_EGLConfig *conf, void *native_window,
const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
_EGLSurface *surf;
surf = dri3_create_surface(drv, disp, EGL_WINDOW_BIT, conf,
native_window, attrib_list);
if (surf != NULL)
dri3_set_swap_interval(drv, disp, surf, dri2_dpy->default_swap_interval);
return surf;
}
static _EGLSurface *
dri3_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *disp,
_EGLConfig *conf, void *native_pixmap,
const EGLint *attrib_list)
{
return dri3_create_surface(drv, disp, EGL_PIXMAP_BIT, conf,
native_pixmap, attrib_list);
}
static _EGLSurface *
dri3_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *disp,
_EGLConfig *conf, const EGLint *attrib_list)
{
return dri3_create_surface(drv, disp, EGL_PBUFFER_BIT, conf,
XCB_WINDOW_NONE, attrib_list);
}
static EGLBoolean
dri3_get_sync_values(_EGLDisplay *display, _EGLSurface *surface,
EGLuint64KHR *ust, EGLuint64KHR *msc,
EGLuint64KHR *sbc)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surface);
return loader_dri3_wait_for_msc(&dri3_surf->loader_drawable, 0, 0, 0,
(int64_t *) ust, (int64_t *) msc,
(int64_t *) sbc) ? EGL_TRUE : EGL_FALSE;
}
static _EGLImage *
dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
EGLClientBuffer buffer, const EGLint *attr_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_image *dri2_img;
xcb_drawable_t drawable;
xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
xcb_dri3_buffer_from_pixmap_reply_t *bp_reply;
unsigned int format;
drawable = (xcb_drawable_t) (uintptr_t) buffer;
bp_cookie = xcb_dri3_buffer_from_pixmap(dri2_dpy->conn, drawable);
bp_reply = xcb_dri3_buffer_from_pixmap_reply(dri2_dpy->conn,
bp_cookie, NULL);
if (!bp_reply) {
_eglError(EGL_BAD_ALLOC, "xcb_dri3_buffer_from_pixmap");
return NULL;
}
switch (bp_reply->depth) {
case 16:
format = __DRI_IMAGE_FORMAT_RGB565;
break;
case 24:
format = __DRI_IMAGE_FORMAT_XRGB8888;
break;
case 32:
format = __DRI_IMAGE_FORMAT_ARGB8888;
break;
default:
_eglError(EGL_BAD_PARAMETER,
"dri3_create_image_khr: unsupported pixmap depth");
free(bp_reply);
return EGL_NO_IMAGE_KHR;
}
dri2_img = malloc(sizeof *dri2_img);
if (!dri2_img) {
_eglError(EGL_BAD_ALLOC, "dri3_create_image_khr");
return EGL_NO_IMAGE_KHR;
}
if (!_eglInitImage(&dri2_img->base, disp)) {
free(dri2_img);
return EGL_NO_IMAGE_KHR;
}
dri2_img->dri_image = loader_dri3_create_image(dri2_dpy->conn,
bp_reply,
format,
dri2_dpy->dri_screen,
dri2_dpy->image,
dri2_img);
free(bp_reply);
return &dri2_img->base;
}
static _EGLImage *
dri3_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
_EGLContext *ctx, EGLenum target,
EGLClientBuffer buffer, const EGLint *attr_list)
{
(void) drv;
switch (target) {
case EGL_NATIVE_PIXMAP_KHR:
return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
default:
return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
}
}
/**
* Called by the driver when it needs to update the real front buffer with the
* contents of its fake front buffer.
*/
static void
dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
{
/* There does not seem to be any kind of consensus on whether we should
* support front-buffer rendering or not:
* http://lists.freedesktop.org/archives/mesa-dev/2013-June/040129.html
*/
_eglLog(_EGL_WARNING, "FIXME: egl/x11 doesn't support front buffer rendering.");
(void) driDrawable;
(void) loaderPrivate;
}
const __DRIimageLoaderExtension dri3_image_loader_extension = {
.base = { __DRI_IMAGE_LOADER, 1 },
.getBuffers = loader_dri3_get_buffers,
.flushFrontBuffer = dri3_flush_front_buffer,
};
static EGLBoolean
dri3_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(draw);
/* No-op for a pixmap or pbuffer surface */
if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT)
return 0;
return loader_dri3_swap_buffers_msc(&dri3_surf->loader_drawable,
0, 0, 0, 0,
draw->SwapBehavior == EGL_BUFFER_PRESERVED) != -1;
}
static EGLBoolean
dri3_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
void *native_pixmap_target)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surf);
xcb_pixmap_t target;
STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_pixmap_target));
target = (uintptr_t) native_pixmap_target;
loader_dri3_copy_drawable(&dri3_surf->loader_drawable, target,
dri3_surf->loader_drawable.drawable);
return EGL_TRUE;
}
static int
dri3_query_buffer_age(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surf);
return loader_dri3_query_buffer_age(&dri3_surf->loader_drawable);
}
static __DRIdrawable *
dri3_get_dri_drawable(_EGLSurface *surf)
{
struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surf);
return dri3_surf->loader_drawable.dri_drawable;
}
struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
.authenticate = NULL,
.create_window_surface = dri3_create_window_surface,
.create_pixmap_surface = dri3_create_pixmap_surface,
.create_pbuffer_surface = dri3_create_pbuffer_surface,
.destroy_surface = dri3_destroy_surface,
.create_image = dri3_create_image_khr,
.swap_interval = dri3_set_swap_interval,
.swap_buffers = dri3_swap_buffers,
.swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
.swap_buffers_region = dri2_fallback_swap_buffers_region,
.post_sub_buffer = dri2_fallback_post_sub_buffer,
.copy_buffers = dri3_copy_buffers,
.query_buffer_age = dri3_query_buffer_age,
.create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image,
.get_sync_values = dri3_get_sync_values,
.get_dri_drawable = dri3_get_dri_drawable,
};
static char *
dri3_get_device_name(int fd)
{
char *ret = NULL;
ret = drmGetRenderDeviceNameFromFd(fd);
if (ret)
return ret;
/* For dri3, render node support is required for WL_bind_wayland_display.
* In order not to regress on older systems without kernel or libdrm
* support, fall back to dri2. User can override it with environment
* variable if they don't need to use that extension.
*/
if (getenv("EGL_FORCE_DRI3") == NULL) {
_eglLog(_EGL_WARNING, "Render node support not available, falling back to dri2");
_eglLog(_EGL_WARNING, "If you want to force dri3, set EGL_FORCE_DRI3 environment variable");
} else
ret = loader_get_device_name_for_fd(fd);
return ret;
}
EGLBoolean
dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
{
xcb_dri3_query_version_reply_t *dri3_query;
xcb_dri3_query_version_cookie_t dri3_query_cookie;
xcb_present_query_version_reply_t *present_query;
xcb_present_query_version_cookie_t present_query_cookie;
xcb_generic_error_t *error;
xcb_screen_iterator_t s;
xcb_screen_t *screen;
const xcb_query_extension_reply_t *extension;
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id);
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_present_id);
extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_dri3_id);
if (!(extension && extension->present))
return EGL_FALSE;
extension = xcb_get_extension_data(dri2_dpy->conn, &xcb_present_id);
if (!(extension && extension->present))
return EGL_FALSE;
dri3_query_cookie = xcb_dri3_query_version(dri2_dpy->conn,
XCB_DRI3_MAJOR_VERSION,
XCB_DRI3_MINOR_VERSION);
present_query_cookie = xcb_present_query_version(dri2_dpy->conn,
XCB_PRESENT_MAJOR_VERSION,
XCB_PRESENT_MINOR_VERSION);
dri3_query =
xcb_dri3_query_version_reply(dri2_dpy->conn, dri3_query_cookie, &error);
if (dri3_query == NULL || error != NULL) {
_eglLog(_EGL_WARNING, "DRI3: failed to query the version");
free(dri3_query);
free(error);
return EGL_FALSE;
}
free(dri3_query);
present_query =
xcb_present_query_version_reply(dri2_dpy->conn,
present_query_cookie, &error);
if (present_query == NULL || error != NULL) {
_eglLog(_EGL_WARNING, "DRI3: failed to query Present version");
free(present_query);
free(error);
return EGL_FALSE;
}
free(present_query);
s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn));
screen = get_xcb_screen(s, dri2_dpy->screen);
if (!screen) {
_eglError(EGL_BAD_NATIVE_WINDOW, "dri3_x11_connect");
return EGL_FALSE;
}
dri2_dpy->fd = loader_dri3_open(dri2_dpy->conn, screen->root, 0);
if (dri2_dpy->fd < 0) {
int conn_error = xcb_connection_has_error(dri2_dpy->conn);
_eglLog(_EGL_WARNING, "DRI3: Screen seems not DRI3 capable");
if (conn_error)
_eglLog(_EGL_WARNING, "DRI3: Failed to initialize");
return EGL_FALSE;
}
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu);
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
if (!dri2_dpy->driver_name) {
_eglLog(_EGL_WARNING, "DRI3: No driver found");
close(dri2_dpy->fd);
return EGL_FALSE;
}
dri2_dpy->device_name = dri3_get_device_name(dri2_dpy->fd);
if (!dri2_dpy->device_name) {
close(dri2_dpy->fd);
return EGL_FALSE;
}
return EGL_TRUE;
}

View file

@ -0,0 +1,41 @@
/*
* Copyright © 2015 Boyan Ding
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifndef EGL_X11_DRI3_INCLUDED
#define EGL_X11_DRI3_INCLUDED
#include "egl_dri2.h"
_EGL_DRIVER_TYPECAST(dri3_egl_surface, _EGLSurface, obj)
struct dri3_egl_surface {
_EGLSurface base;
struct loader_dri3_drawable loader_drawable;
};
extern const __DRIimageLoaderExtension dri3_image_loader_extension;
extern struct dri2_egl_display_vtbl dri3_x11_display_vtbl;
EGLBoolean
dri3_x11_connect(struct dri2_egl_display *dri2_dpy);
#endif

55
src/egl/egl-symbols-check Executable file
View file

@ -0,0 +1,55 @@
#!/bin/bash
FUNCS=$(nm -D --defined-only ${1-.libs/libEGL.so} | grep -o "T .*" | cut -c 3- | while read func; do
( grep -q "^$func$" || echo $func ) <<EOF
eglBindAPI
eglBindTexImage
eglChooseConfig
eglClientWaitSync
eglCopyBuffers
eglCreateContext
eglCreateImage
eglCreatePbufferFromClientBuffer
eglCreatePbufferSurface
eglCreatePixmapSurface
eglCreatePlatformPixmapSurface
eglCreatePlatformWindowSurface
eglCreateSync
eglCreateWindowSurface
eglDestroyContext
eglDestroyImage
eglDestroySurface
eglDestroySync
eglGetConfigAttrib
eglGetConfigs
eglGetCurrentContext
eglGetCurrentDisplay
eglGetCurrentSurface
eglGetDisplay
eglGetError
eglGetPlatformDisplay
eglGetProcAddress
eglGetSyncAttrib
eglInitialize
eglMakeCurrent
eglQueryAPI
eglQueryContext
eglQueryString
eglQuerySurface
eglReleaseTexImage
eglReleaseThread
eglSurfaceAttrib
eglSwapBuffers
eglSwapInterval
eglTerminate
eglWaitClient
eglWaitGL
eglWaitNative
eglWaitSync
_fini
_init
EOF
done)
test ! -n "$FUNCS" || echo $FUNCS
test ! -n "$FUNCS"

View file

@ -27,6 +27,7 @@ GALLIUM_TOP := $(call my-dir)
GALLIUM_COMMON_MK := $(GALLIUM_TOP)/Android.common.mk
SUBDIRS := auxiliary
SUBDIRS += auxiliary/pipe-loader
#
# Gallium drivers and their respective winsys

View file

@ -67,3 +67,9 @@ if HAVE_DRISW
GALLIUM_PIPE_LOADER_WINSYS_LIBS += \
$(top_builddir)/src/gallium/winsys/sw/dri/libswdri.la
endif
if HAVE_DRISW_KMS
GALLIUM_PIPE_LOADER_WINSYS_LIBS += \
$(top_builddir)/src/gallium/winsys/sw/kms-dri/libswkmsdri.la \
$(LIBDRM_LIBS)
endif

View file

@ -5,6 +5,7 @@ SUBDIRS =
##
SUBDIRS += auxiliary
SUBDIRS += auxiliary/pipe-loader
##
## Gallium pipe drivers and their respective winsys'
@ -98,7 +99,7 @@ if HAVE_DRISW
SUBDIRS += winsys/sw/dri
endif
if HAVE_DRI2
if HAVE_DRISW_KMS
SUBDIRS += winsys/sw/kms-dri
endif
@ -120,7 +121,8 @@ EXTRA_DIST = \
## Gallium state trackers and their users (targets)
##
if HAVE_LOADER_GALLIUM
## XXX: Rename the conditional once we have a config switch for static/dynamic pipe-drivers
if HAVE_CLOVER
SUBDIRS += targets/pipe-loader
endif

View file

@ -5,6 +5,7 @@ Import('env')
#
SConscript('auxiliary/SConscript')
SConscript('auxiliary/pipe-loader/SConscript')
#
# Drivers

View file

@ -1,7 +1,3 @@
if HAVE_LOADER_GALLIUM
SUBDIRS := pipe-loader
endif
include Makefile.sources
include $(top_srcdir)/src/gallium/Automake.inc
@ -66,15 +62,7 @@ COMMON_VL_CFLAGS = \
$(AM_CFLAGS) \
$(VL_CFLAGS) \
$(DRI2PROTO_CFLAGS) \
$(LIBDRM_CFLAGS) \
$(GALLIUM_PIPE_LOADER_DEFINES) \
-DPIPE_SEARCH_DIR=\"$(libdir)/gallium-pipe\"
if HAVE_GALLIUM_STATIC_TARGETS
COMMON_VL_CFLAGS += \
-DGALLIUM_STATIC_TARGETS=1
endif # HAVE_GALLIUM_STATIC_TARGETS
$(LIBDRM_CFLAGS)
noinst_LTLIBRARIES += libgalliumvl.la

View file

@ -219,8 +219,6 @@ C_SOURCES := \
util/u_format.h \
util/u_format_etc.c \
util/u_format_etc.h \
util/u_format_fake.c \
util/u_format_fake.h \
util/u_format_latc.c \
util/u_format_latc.h \
util/u_format_other.c \

View file

@ -536,6 +536,15 @@ lp_build_create_jit_compiler_for_module(LLVMExecutionEngineRef *OutJIT,
#if defined(PIPE_ARCH_PPC)
MAttrs.push_back(util_cpu_caps.has_altivec ? "+altivec" : "-altivec");
#if HAVE_LLVM >= 0x0304
/*
* Make sure VSX instructions are disabled
* See LLVM bug https://llvm.org/bugs/show_bug.cgi?id=25503#c7
*/
if (util_cpu_caps.has_altivec) {
MAttrs.push_back("-vsx");
}
#endif
#endif
builder.setMAttrs(MAttrs);

View file

@ -2608,7 +2608,12 @@ emit_fetch_texels( struct lp_build_tgsi_soa_context *bld,
params.type = bld->bld_base.base.type;
params.sample_key = sample_key;
params.texture_index = unit;
params.sampler_index = unit;
/*
* sampler not actually used, set to 0 so it won't exceed PIPE_MAX_SAMPLERS
* and trigger some assertions with d3d10 where the sampler view number
* can exceed this.
*/
params.sampler_index = 0;
params.context_ptr = bld->context_ptr;
params.thread_data_ptr = bld->thread_data_ptr;
params.coords = coords;

View file

@ -33,6 +33,7 @@
* Set GALLIUM_HUD=help for more info.
*/
#include <signal.h>
#include <stdio.h>
#include "hud/hud_context.h"
@ -51,12 +52,15 @@
#include "tgsi/tgsi_text.h"
#include "tgsi/tgsi_dump.h"
/* Control the visibility of all HUD contexts */
static boolean huds_visible = TRUE;
struct hud_context {
struct pipe_context *pipe;
struct cso_context *cso;
struct u_upload_mgr *uploader;
struct hud_batch_query_context *batch_query;
struct list_head pane_list;
/* states */
@ -95,6 +99,13 @@ struct hud_context {
} text, bg, whitelines;
};
#ifdef PIPE_OS_UNIX
static void
signal_visible_handler(int sig, siginfo_t *siginfo, void *context)
{
huds_visible = !huds_visible;
}
#endif
static void
hud_draw_colored_prims(struct hud_context *hud, unsigned prim,
@ -441,6 +452,9 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
struct hud_pane *pane;
struct hud_graph *gr;
if (!huds_visible)
return;
hud->fb_width = tex->width0;
hud->fb_height = tex->height0;
hud->constants.two_div_fb_width = 2.0f / hud->fb_width;
@ -510,6 +524,8 @@ hud_draw(struct hud_context *hud, struct pipe_resource *tex)
hud_alloc_vertices(hud, &hud->text, 4 * 512, 4 * sizeof(float));
/* prepare all graphs */
hud_batch_query_update(hud->batch_query);
LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
gr->query_new_value(gr);
@ -903,17 +919,21 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
}
else if (strcmp(name, "samples-passed") == 0 &&
has_occlusion_query(hud->pipe->screen)) {
hud_pipe_query_install(pane, hud->pipe, "samples-passed",
hud_pipe_query_install(&hud->batch_query, pane, hud->pipe,
"samples-passed",
PIPE_QUERY_OCCLUSION_COUNTER, 0, 0,
PIPE_DRIVER_QUERY_TYPE_UINT64,
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE);
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE,
0);
}
else if (strcmp(name, "primitives-generated") == 0 &&
has_streamout(hud->pipe->screen)) {
hud_pipe_query_install(pane, hud->pipe, "primitives-generated",
hud_pipe_query_install(&hud->batch_query, pane, hud->pipe,
"primitives-generated",
PIPE_QUERY_PRIMITIVES_GENERATED, 0, 0,
PIPE_DRIVER_QUERY_TYPE_UINT64,
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE);
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE,
0);
}
else {
boolean processed = FALSE;
@ -938,17 +958,19 @@ hud_parse_env_var(struct hud_context *hud, const char *env)
if (strcmp(name, pipeline_statistics_names[i]) == 0)
break;
if (i < Elements(pipeline_statistics_names)) {
hud_pipe_query_install(pane, hud->pipe, name,
hud_pipe_query_install(&hud->batch_query, pane, hud->pipe, name,
PIPE_QUERY_PIPELINE_STATISTICS, i,
0, PIPE_DRIVER_QUERY_TYPE_UINT64,
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE);
PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE,
0);
processed = TRUE;
}
}
/* driver queries */
if (!processed) {
if (!hud_driver_query_install(pane, hud->pipe, name)){
if (!hud_driver_query_install(&hud->batch_query, pane, hud->pipe,
name)) {
fprintf(stderr, "gallium_hud: unknown driver query '%s'\n", name);
}
}
@ -1125,6 +1147,12 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
struct pipe_sampler_view view_templ;
unsigned i;
const char *env = debug_get_option("GALLIUM_HUD", NULL);
unsigned signo = debug_get_num_option("GALLIUM_HUD_TOGGLE_SIGNAL", 0);
#ifdef PIPE_OS_UNIX
static boolean sig_handled = FALSE;
struct sigaction action = {};
#endif
huds_visible = debug_get_bool_option("GALLIUM_HUD_VISIBLE", TRUE);
if (!env || !*env)
return NULL;
@ -1267,6 +1295,22 @@ hud_create(struct pipe_context *pipe, struct cso_context *cso)
LIST_INITHEAD(&hud->pane_list);
/* setup sig handler once for all hud contexts */
#ifdef PIPE_OS_UNIX
if (!sig_handled && signo != 0) {
action.sa_sigaction = &signal_visible_handler;
action.sa_flags = SA_SIGINFO;
if (signo >= NSIG)
fprintf(stderr, "gallium_hud: invalid signal %u\n", signo);
else if (sigaction(signo, &action, NULL) < 0)
fprintf(stderr, "gallium_hud: unable to set handler for signal %u\n", signo);
fflush(stderr);
sig_handled = TRUE;
}
#endif
hud_parse_env_var(hud, env);
return hud;
}
@ -1287,6 +1331,7 @@ hud_destroy(struct hud_context *hud)
FREE(pane);
}
hud_batch_query_cleanup(&hud->batch_query);
pipe->delete_fs_state(pipe, hud->fs_color);
pipe->delete_fs_state(pipe, hud->fs_text);
pipe->delete_vs_state(pipe, hud->vs);

View file

@ -34,13 +34,164 @@
#include "hud/hud_private.h"
#include "pipe/p_screen.h"
#include "os/os_time.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include <stdio.h>
// Must be a power of two
#define NUM_QUERIES 8
struct hud_batch_query_context {
struct pipe_context *pipe;
unsigned num_query_types;
unsigned allocated_query_types;
unsigned *query_types;
boolean failed;
struct pipe_query *query[NUM_QUERIES];
union pipe_query_result *result[NUM_QUERIES];
unsigned head, pending, results;
};
void
hud_batch_query_update(struct hud_batch_query_context *bq)
{
struct pipe_context *pipe;
if (!bq || bq->failed)
return;
pipe = bq->pipe;
if (bq->query[bq->head])
pipe->end_query(pipe, bq->query[bq->head]);
bq->results = 0;
while (bq->pending) {
unsigned idx = (bq->head - bq->pending + 1) % NUM_QUERIES;
struct pipe_query *query = bq->query[idx];
if (!bq->result[idx])
bq->result[idx] = MALLOC(sizeof(bq->result[idx]->batch[0]) *
bq->num_query_types);
if (!bq->result[idx]) {
fprintf(stderr, "gallium_hud: out of memory.\n");
bq->failed = TRUE;
return;
}
if (!pipe->get_query_result(pipe, query, FALSE, bq->result[idx]))
break;
++bq->results;
--bq->pending;
}
bq->head = (bq->head + 1) % NUM_QUERIES;
if (bq->pending == NUM_QUERIES) {
fprintf(stderr,
"gallium_hud: all queries busy after %i frames, dropping data.\n",
NUM_QUERIES);
assert(bq->query[bq->head]);
pipe->destroy_query(bq->pipe, bq->query[bq->head]);
bq->query[bq->head] = NULL;
}
++bq->pending;
if (!bq->query[bq->head]) {
bq->query[bq->head] = pipe->create_batch_query(pipe,
bq->num_query_types,
bq->query_types);
if (!bq->query[bq->head]) {
fprintf(stderr,
"gallium_hud: create_batch_query failed. You may have "
"selected too many or incompatible queries.\n");
bq->failed = TRUE;
return;
}
}
if (!pipe->begin_query(pipe, bq->query[bq->head])) {
fprintf(stderr,
"gallium_hud: could not begin batch query. You may have "
"selected too many or incompatible queries.\n");
bq->failed = TRUE;
}
}
static boolean
batch_query_add(struct hud_batch_query_context **pbq,
struct pipe_context *pipe, unsigned query_type,
unsigned *result_index)
{
struct hud_batch_query_context *bq = *pbq;
unsigned i;
if (!bq) {
bq = CALLOC_STRUCT(hud_batch_query_context);
if (!bq)
return false;
bq->pipe = pipe;
*pbq = bq;
}
for (i = 0; i < bq->num_query_types; ++i) {
if (bq->query_types[i] == query_type) {
*result_index = i;
return true;
}
}
if (bq->num_query_types == bq->allocated_query_types) {
unsigned new_alloc = MAX2(16, bq->allocated_query_types * 2);
unsigned *new_query_types
= REALLOC(bq->query_types,
bq->allocated_query_types * sizeof(unsigned),
new_alloc * sizeof(unsigned));
if (!new_query_types)
return false;
bq->query_types = new_query_types;
bq->allocated_query_types = new_alloc;
}
bq->query_types[bq->num_query_types] = query_type;
*result_index = bq->num_query_types++;
return true;
}
void
hud_batch_query_cleanup(struct hud_batch_query_context **pbq)
{
struct hud_batch_query_context *bq = *pbq;
unsigned idx;
if (!bq)
return;
*pbq = NULL;
if (bq->query[bq->head] && !bq->failed)
bq->pipe->end_query(bq->pipe, bq->query[bq->head]);
for (idx = 0; idx < NUM_QUERIES; ++idx) {
if (bq->query[idx])
bq->pipe->destroy_query(bq->pipe, bq->query[idx]);
FREE(bq->result[idx]);
}
FREE(bq->query_types);
FREE(bq);
}
struct query_info {
struct pipe_context *pipe;
struct hud_batch_query_context *batch;
unsigned query_type;
unsigned result_index; /* unit depends on query_type */
enum pipe_driver_query_result_type result_type;
@ -48,7 +199,6 @@ struct query_info {
/* Ring of queries. If a query is busy, we use another slot. */
struct pipe_query *query[NUM_QUERIES];
unsigned head, tail;
unsigned num_queries;
uint64_t last_time;
uint64_t results_cumulative;
@ -56,11 +206,26 @@ struct query_info {
};
static void
query_new_value(struct hud_graph *gr)
query_new_value_batch(struct query_info *info)
{
struct hud_batch_query_context *bq = info->batch;
unsigned result_index = info->result_index;
unsigned idx = (bq->head - bq->pending) % NUM_QUERIES;
unsigned results = bq->results;
while (results) {
info->results_cumulative += bq->result[idx]->batch[result_index].u64;
++info->num_results;
--results;
idx = (idx - 1) % NUM_QUERIES;
}
}
static void
query_new_value_normal(struct query_info *info)
{
struct query_info *info = gr->query_data;
struct pipe_context *pipe = info->pipe;
uint64_t now = os_time_get();
if (info->last_time) {
if (info->query[info->head])
@ -107,30 +272,9 @@ query_new_value(struct hud_graph *gr)
break;
}
}
if (info->num_results && info->last_time + gr->pane->period <= now) {
uint64_t value;
switch (info->result_type) {
default:
case PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE:
value = info->results_cumulative / info->num_results;
break;
case PIPE_DRIVER_QUERY_RESULT_TYPE_CUMULATIVE:
value = info->results_cumulative;
break;
}
hud_graph_add_value(gr, value);
info->last_time = now;
info->results_cumulative = 0;
info->num_results = 0;
}
}
else {
/* initialize */
info->last_time = now;
info->query[info->head] = pipe->create_query(pipe, info->query_type, 0);
}
@ -138,12 +282,50 @@ query_new_value(struct hud_graph *gr)
pipe->begin_query(pipe, info->query[info->head]);
}
static void
query_new_value(struct hud_graph *gr)
{
struct query_info *info = gr->query_data;
uint64_t now = os_time_get();
if (info->batch) {
query_new_value_batch(info);
} else {
query_new_value_normal(info);
}
if (!info->last_time) {
info->last_time = now;
return;
}
if (info->num_results && info->last_time + gr->pane->period <= now) {
uint64_t value;
switch (info->result_type) {
default:
case PIPE_DRIVER_QUERY_RESULT_TYPE_AVERAGE:
value = info->results_cumulative / info->num_results;
break;
case PIPE_DRIVER_QUERY_RESULT_TYPE_CUMULATIVE:
value = info->results_cumulative;
break;
}
hud_graph_add_value(gr, value);
info->last_time = now;
info->results_cumulative = 0;
info->num_results = 0;
}
}
static void
free_query_info(void *ptr)
{
struct query_info *info = ptr;
if (info->last_time) {
if (!info->batch && info->last_time) {
struct pipe_context *pipe = info->pipe;
int i;
@ -159,11 +341,13 @@ free_query_info(void *ptr)
}
void
hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe,
hud_pipe_query_install(struct hud_batch_query_context **pbq,
struct hud_pane *pane, struct pipe_context *pipe,
const char *name, unsigned query_type,
unsigned result_index,
uint64_t max_value, enum pipe_driver_query_type type,
enum pipe_driver_query_result_type result_type)
enum pipe_driver_query_result_type result_type,
unsigned flags)
{
struct hud_graph *gr;
struct query_info *info;
@ -175,28 +359,40 @@ hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe,
strncpy(gr->name, name, sizeof(gr->name));
gr->name[sizeof(gr->name) - 1] = '\0';
gr->query_data = CALLOC_STRUCT(query_info);
if (!gr->query_data) {
FREE(gr);
return;
}
if (!gr->query_data)
goto fail_gr;
gr->query_new_value = query_new_value;
gr->free_query_data = free_query_info;
info = gr->query_data;
info->pipe = pipe;
info->query_type = query_type;
info->result_index = result_index;
info->result_type = result_type;
if (flags & PIPE_DRIVER_QUERY_FLAG_BATCH) {
if (!batch_query_add(pbq, pipe, query_type, &info->result_index))
goto fail_info;
info->batch = *pbq;
} else {
info->query_type = query_type;
info->result_index = result_index;
}
hud_pane_add_graph(pane, gr);
if (pane->max_value < max_value)
hud_pane_set_max_value(pane, max_value);
pane->type = type;
return;
fail_info:
FREE(info);
fail_gr:
FREE(gr);
}
boolean
hud_driver_query_install(struct hud_pane *pane, struct pipe_context *pipe,
hud_driver_query_install(struct hud_batch_query_context **pbq,
struct hud_pane *pane, struct pipe_context *pipe,
const char *name)
{
struct pipe_screen *screen = pipe->screen;
@ -220,8 +416,9 @@ hud_driver_query_install(struct hud_pane *pane, struct pipe_context *pipe,
if (!found)
return FALSE;
hud_pipe_query_install(pane, pipe, query.name, query.query_type, 0,
query.max_value.u64, query.type, query.result_type);
hud_pipe_query_install(pbq, pane, pipe, query.name, query.query_type, 0,
query.max_value.u64, query.type, query.result_type,
query.flags);
return TRUE;
}

View file

@ -80,19 +80,26 @@ void hud_pane_set_max_value(struct hud_pane *pane, uint64_t value);
void hud_graph_add_value(struct hud_graph *gr, uint64_t value);
/* graphs/queries */
struct hud_batch_query_context;
#define ALL_CPUS ~0 /* optionally set as cpu_index */
int hud_get_num_cpus(void);
void hud_fps_graph_install(struct hud_pane *pane);
void hud_cpu_graph_install(struct hud_pane *pane, unsigned cpu_index);
void hud_pipe_query_install(struct hud_pane *pane, struct pipe_context *pipe,
void hud_pipe_query_install(struct hud_batch_query_context **pbq,
struct hud_pane *pane, struct pipe_context *pipe,
const char *name, unsigned query_type,
unsigned result_index,
uint64_t max_value,
enum pipe_driver_query_type type,
enum pipe_driver_query_result_type result_type);
boolean hud_driver_query_install(struct hud_pane *pane,
enum pipe_driver_query_result_type result_type,
unsigned flags);
boolean hud_driver_query_install(struct hud_batch_query_context **pbq,
struct hud_pane *pane,
struct pipe_context *pipe, const char *name);
void hud_batch_query_update(struct hud_batch_query_context *bq);
void hud_batch_query_cleanup(struct hud_batch_query_context **pbq);
#endif

View file

@ -295,7 +295,7 @@ ttn_emit_declaration(struct ttn_compile *c)
type = nir_type_int;
break;
case TGSI_RETURN_TYPE_UINT:
type = nir_type_unsigned;
type = nir_type_uint;
break;
case TGSI_RETURN_TYPE_FLOAT:
default:
@ -1239,6 +1239,11 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
op = nir_texop_tex;
num_srcs = 1;
break;
case TGSI_OPCODE_TEX2:
op = nir_texop_tex;
num_srcs = 1;
samp = 2;
break;
case TGSI_OPCODE_TXP:
op = nir_texop_tex;
num_srcs = 2;
@ -1275,6 +1280,10 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
num_srcs = 3;
samp = 3;
break;
case TGSI_OPCODE_LODQ:
op = nir_texop_lod;
num_srcs = 1;
break;
default:
fprintf(stderr, "unknown TGSI tex op %d\n", tgsi_inst->Instruction.Opcode);
@ -1327,7 +1336,9 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
*/
sview = instr->sampler_index;
if (sview < c->num_samp_types) {
if (op == nir_texop_lod) {
instr->dest_type = nir_type_float;
} else if (sview < c->num_samp_types) {
instr->dest_type = c->samp_types[sview];
} else {
instr->dest_type = nir_type_float;
@ -1394,10 +1405,12 @@ ttn_tex(struct ttn_compile *c, nir_alu_dest dest, nir_ssa_def **src)
}
if (instr->is_shadow) {
if (instr->coord_components < 3)
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], Z));
else
if (instr->coord_components == 4)
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[1], X));
else if (instr->coord_components == 3)
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], W));
else
instr->src[src_number].src = nir_src_for_ssa(ttn_channel(b, src[0], Z));
instr->src[src_number].src_type = nir_tex_src_comparitor;
src_number++;
@ -1641,7 +1654,7 @@ static const nir_op op_trans[TGSI_OPCODE_LAST] = {
[TGSI_OPCODE_UMUL_HI] = nir_op_umul_high,
[TGSI_OPCODE_TG4] = 0,
[TGSI_OPCODE_LODQ] = 0, /* XXX */
[TGSI_OPCODE_LODQ] = 0,
[TGSI_OPCODE_IBFE] = nir_op_ibitfield_extract,
[TGSI_OPCODE_UBFE] = nir_op_ubitfield_extract,
@ -1650,7 +1663,7 @@ static const nir_op op_trans[TGSI_OPCODE_LAST] = {
[TGSI_OPCODE_POPC] = nir_op_bit_count,
[TGSI_OPCODE_LSB] = nir_op_find_lsb,
[TGSI_OPCODE_IMSB] = nir_op_ifind_msb,
[TGSI_OPCODE_UMSB] = nir_op_ifind_msb, /* XXX: signed vs unsigned */
[TGSI_OPCODE_UMSB] = nir_op_ufind_msb,
[TGSI_OPCODE_INTERP_CENTROID] = 0, /* XXX */
[TGSI_OPCODE_INTERP_SAMPLE] = 0, /* XXX */
@ -1803,11 +1816,13 @@ ttn_emit_instruction(struct ttn_compile *c)
case TGSI_OPCODE_TXL:
case TGSI_OPCODE_TXB:
case TGSI_OPCODE_TXD:
case TGSI_OPCODE_TEX2:
case TGSI_OPCODE_TXL2:
case TGSI_OPCODE_TXB2:
case TGSI_OPCODE_TXQ_LZ:
case TGSI_OPCODE_TXF:
case TGSI_OPCODE_TG4:
case TGSI_OPCODE_LODQ:
ttn_tex(c, dest, src);
break;

View file

@ -54,37 +54,48 @@ boolean
os_get_process_name(char *procname, size_t size)
{
const char *name;
/* First, check if the GALLIUM_PROCESS_NAME env var is set to
* override the normal process name query.
*/
name = os_get_option("GALLIUM_PROCESS_NAME");
if (!name) {
/* do normal query */
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
char szProcessPath[MAX_PATH];
char *lpProcessName;
char *lpProcessExt;
char szProcessPath[MAX_PATH];
char *lpProcessName;
char *lpProcessExt;
GetModuleFileNameA(NULL, szProcessPath, Elements(szProcessPath));
GetModuleFileNameA(NULL, szProcessPath, Elements(szProcessPath));
lpProcessName = strrchr(szProcessPath, '\\');
lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
lpProcessName = strrchr(szProcessPath, '\\');
lpProcessName = lpProcessName ? lpProcessName + 1 : szProcessPath;
lpProcessExt = strrchr(lpProcessName, '.');
if (lpProcessExt) {
*lpProcessExt = '\0';
}
lpProcessExt = strrchr(lpProcessName, '.');
if (lpProcessExt) {
*lpProcessExt = '\0';
}
name = lpProcessName;
name = lpProcessName;
#elif defined(__GLIBC__) || defined(__CYGWIN__)
name = program_invocation_short_name;
name = program_invocation_short_name;
#elif defined(PIPE_OS_BSD) || defined(PIPE_OS_APPLE)
/* *BSD and OS X */
name = getprogname();
/* *BSD and OS X */
name = getprogname();
#elif defined(PIPE_OS_HAIKU)
image_info info;
get_image_info(B_CURRENT_TEAM, &info);
name = info.name;
image_info info;
get_image_info(B_CURRENT_TEAM, &info);
name = info.name;
#else
#warning unexpected platform in os_process.c
return FALSE;
return FALSE;
#endif
}
assert(size > 0);
assert(procname);

View file

@ -0,0 +1,49 @@
# Mesa 3-D graphics library
#
# Copyright (C) 2015 Emil Velikov <emil.l.velikov@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
# NOTE: Currently we build only a 'static' pipe-loader
LOCAL_PATH := $(call my-dir)
# get COMMON_SOURCES and DRM_SOURCES
include $(LOCAL_PATH)/Makefile.sources
include $(CLEAR_VARS)
LOCAL_CFLAGS := \
-DHAVE_PIPE_LOADER_DRI \
-DDROP_PIPE_LOADER_MISC \
-DGALLIUM_STATIC_TARGETS
LOCAL_SRC_FILES := $(COMMON_SOURCES)
LOCAL_MODULE := libmesa_pipe_loader
ifneq ($(filter-out swrast,$(MESA_GPU_DRIVERS)),)
LOCAL_CFLAGS += -DHAVE_LIBDRM
LOCAL_SRC_FILES += $(DRM_SOURCES)
LOCAL_SHARED_LIBRARIES := libdrm
LOCAL_STATIC_LIBRARIES := libmesa_loader
endif
include $(GALLIUM_COMMON_MK)
include $(BUILD_STATIC_LIBRARY)

View file

@ -9,20 +9,40 @@ AM_CFLAGS = \
$(GALLIUM_CFLAGS) \
$(VISIBILITY_CFLAGS)
noinst_LTLIBRARIES = libpipe_loader.la
noinst_LTLIBRARIES = \
libpipe_loader_static.la \
libpipe_loader_dynamic.la
libpipe_loader_la_SOURCES = \
libpipe_loader_static_la_CFLAGS = \
$(AM_CFLAGS) \
-DGALLIUM_STATIC_TARGETS=1
libpipe_loader_dynamic_la_CFLAGS = \
$(AM_CFLAGS) \
-DPIPE_SEARCH_DIR=\"$(libdir)/gallium-pipe\"
libpipe_loader_static_la_SOURCES = \
$(COMMON_SOURCES)
if HAVE_DRM_LOADER_GALLIUM
libpipe_loader_dynamic_la_SOURCES = \
$(COMMON_SOURCES)
if HAVE_LIBDRM
AM_CFLAGS += \
$(LIBDRM_CFLAGS)
libpipe_loader_la_SOURCES += \
libpipe_loader_static_la_SOURCES += \
$(DRM_SOURCES)
libpipe_loader_la_LIBADD = \
$(top_builddir)/src/loader/libloader.la
libpipe_loader_dynamic_la_SOURCES += \
$(DRM_SOURCES)
endif
libpipe_loader_static_la_LIBADD = \
$(top_builddir)/src/loader/libloader.la
libpipe_loader_dynamic_la_LIBADD = \
$(top_builddir)/src/loader/libloader.la
EXTRA_DIST = SConscript

View file

@ -0,0 +1,33 @@
Import('*')
env = env.Clone()
env.MSVC2008Compat()
env.Append(CPPPATH = [
'#/src/loader',
'#/src/gallium/winsys',
])
env.Append(CPPDEFINES = [
('HAVE_PIPE_LOADER_DRI', '1'),
('DROP_PIPE_LOADER_MISC', '1'),
('GALLIUM_STATIC_TARGETS', '1'),
])
source = env.ParseSourceList('Makefile.sources', 'COMMON_SOURCES')
if env['HAVE_DRM']:
source += env.ParseSourceList('Makefile.sources', 'DRM_SOURCES')
env.PkgUseModules('DRM')
env.Append(LIBS = [libloader])
pipe_loader = env.ConvenienceLibrary(
target = 'pipe_loader',
source = source,
)
env.Alias('pipe_loader', pipe_loader)
Export('pipe_loader')

View file

@ -32,10 +32,15 @@
#include "util/u_string.h"
#include "util/u_dl.h"
#ifdef _MSC_VER
#include <stdlib.h>
#define PATH_MAX _MAX_PATH
#endif
#define MODULE_PREFIX "pipe_"
static int (*backends[])(struct pipe_loader_device **, int) = {
#ifdef HAVE_PIPE_LOADER_DRM
#ifdef HAVE_LIBDRM
&pipe_loader_drm_probe,
#endif
&pipe_loader_sw_probe
@ -69,10 +74,9 @@ pipe_loader_configuration(struct pipe_loader_device *dev,
}
struct pipe_screen *
pipe_loader_create_screen(struct pipe_loader_device *dev,
const char *library_paths)
pipe_loader_create_screen(struct pipe_loader_device *dev)
{
return dev->ops->create_screen(dev, library_paths);
return dev->ops->create_screen(dev);
}
struct util_dl_library *

View file

@ -82,13 +82,9 @@ pipe_loader_probe(struct pipe_loader_device **devs, int ndev);
* Create a pipe_screen for the specified device.
*
* \param dev Device the screen will be created for.
* \param library_paths Colon-separated list of filesystem paths that
* will be used to look for the pipe driver
* module that handles this device.
*/
struct pipe_screen *
pipe_loader_create_screen(struct pipe_loader_device *dev,
const char *library_paths);
pipe_loader_create_screen(struct pipe_loader_device *dev);
/**
* Query the configuration parameters for the specified device.
@ -112,8 +108,6 @@ pipe_loader_configuration(struct pipe_loader_device *dev,
void
pipe_loader_release(struct pipe_loader_device **devs, int ndev);
#ifdef HAVE_PIPE_LOADER_DRI
/**
* Initialize sw dri device give the drisw_loader_funcs.
*
@ -125,7 +119,15 @@ bool
pipe_loader_sw_probe_dri(struct pipe_loader_device **devs,
struct drisw_loader_funcs *drisw_lf);
#endif
/**
* Initialize a kms backed sw device given an fd.
*
* This function is platform-specific.
*
* \sa pipe_loader_probe
*/
bool
pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd);
/**
* Initialize a null sw device.
@ -158,8 +160,6 @@ boolean
pipe_loader_sw_probe_wrapped(struct pipe_loader_device **dev,
struct pipe_screen *screen);
#ifdef HAVE_PIPE_LOADER_DRM
/**
* Get a list of known DRM devices.
*
@ -180,8 +180,6 @@ pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev);
bool
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -36,6 +36,7 @@
#include <unistd.h>
#include "loader.h"
#include "target-helpers/drm_helper_public.h"
#include "state_tracker/drm_driver.h"
#include "pipe_loader_priv.h"
@ -50,13 +51,123 @@
struct pipe_loader_drm_device {
struct pipe_loader_device base;
const struct drm_driver_descriptor *dd;
#ifndef GALLIUM_STATIC_TARGETS
struct util_dl_library *lib;
#endif
int fd;
};
#define pipe_loader_drm_device(dev) ((struct pipe_loader_drm_device *)dev)
static struct pipe_loader_ops pipe_loader_drm_ops;
static const struct pipe_loader_ops pipe_loader_drm_ops;
#ifdef GALLIUM_STATIC_TARGETS
static const struct drm_conf_ret throttle_ret = {
DRM_CONF_INT,
{2},
};
static const struct drm_conf_ret share_fd_ret = {
DRM_CONF_BOOL,
{true},
};
static inline const struct drm_conf_ret *
configuration_query(enum drm_conf conf)
{
switch (conf) {
case DRM_CONF_THROTTLE:
return &throttle_ret;
case DRM_CONF_SHARE_FD:
return &share_fd_ret;
default:
break;
}
return NULL;
}
static const struct drm_driver_descriptor driver_descriptors[] = {
{
.name = "i915",
.driver_name = "i915",
.create_screen = pipe_i915_create_screen,
.configuration = configuration_query,
},
#ifdef USE_VC4_SIMULATOR
/* VC4 simulator and ILO (i965) are mutually exclusive (error at
* configure). As the latter is unconditionally added, keep this one above
* it.
*/
{
.name = "i965",
.driver_name = "vc4",
.create_screen = pipe_vc4_create_screen,
.configuration = configuration_query,
},
#endif
{
.name = "i965",
.driver_name = "i915",
.create_screen = pipe_ilo_create_screen,
.configuration = configuration_query,
},
{
.name = "nouveau",
.driver_name = "nouveau",
.create_screen = pipe_nouveau_create_screen,
.configuration = configuration_query,
},
{
.name = "r300",
.driver_name = "radeon",
.create_screen = pipe_r300_create_screen,
.configuration = configuration_query,
},
{
.name = "r600",
.driver_name = "radeon",
.create_screen = pipe_r600_create_screen,
.configuration = configuration_query,
},
{
.name = "radeonsi",
.driver_name = "radeon",
.create_screen = pipe_radeonsi_create_screen,
.configuration = configuration_query,
},
{
.name = "vmwgfx",
.driver_name = "vmwgfx",
.create_screen = pipe_vmwgfx_create_screen,
.configuration = configuration_query,
},
{
.name = "kgsl",
.driver_name = "freedreno",
.create_screen = pipe_freedreno_create_screen,
.configuration = configuration_query,
},
{
.name = "msm",
.driver_name = "freedreno",
.create_screen = pipe_freedreno_create_screen,
.configuration = configuration_query,
},
{
.name = "virtio_gpu",
.driver_name = "virtio-gpu",
.create_screen = pipe_virgl_create_screen,
.configuration = configuration_query,
},
{
.name = "vc4",
.driver_name = "vc4",
.create_screen = pipe_vc4_create_screen,
.configuration = configuration_query,
},
};
#endif
bool
pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
@ -81,10 +192,36 @@ pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd)
if (!ddev->base.driver_name)
goto fail;
#ifdef GALLIUM_STATIC_TARGETS
for (int i = 0; i < ARRAY_SIZE(driver_descriptors); i++) {
if (strcmp(driver_descriptors[i].name, ddev->base.driver_name) == 0) {
ddev->dd = &driver_descriptors[i];
break;
}
}
if (!ddev->dd)
goto fail;
#else
ddev->lib = pipe_loader_find_module(&ddev->base, PIPE_SEARCH_DIR);
if (!ddev->lib)
goto fail;
ddev->dd = (const struct drm_driver_descriptor *)
util_dl_get_proc_address(ddev->lib, "driver_descriptor");
/* sanity check on the name */
if (!ddev->dd || strcmp(ddev->dd->name, ddev->base.driver_name) != 0)
goto fail;
#endif
*dev = &ddev->base;
return true;
fail:
#ifndef GALLIUM_STATIC_TARGETS
if (ddev->lib)
util_dl_close(ddev->lib);
#endif
FREE(ddev);
return false;
}
@ -105,8 +242,9 @@ pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev)
for (i = DRM_RENDER_NODE_MIN_MINOR, j = 0;
i <= DRM_RENDER_NODE_MAX_MINOR; i++) {
fd = open_drm_render_node_minor(i);
struct pipe_loader_device *dev;
fd = open_drm_render_node_minor(i);
if (fd < 0)
continue;
@ -132,8 +270,10 @@ pipe_loader_drm_release(struct pipe_loader_device **dev)
{
struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(*dev);
#ifndef GALLIUM_STATIC_TARGETS
if (ddev->lib)
util_dl_close(ddev->lib);
#endif
close(ddev->fd);
FREE(ddev->base.driver_name);
@ -146,47 +286,22 @@ pipe_loader_drm_configuration(struct pipe_loader_device *dev,
enum drm_conf conf)
{
struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);
const struct drm_driver_descriptor *dd;
if (!ddev->lib)
if (!ddev->dd->configuration)
return NULL;
dd = (const struct drm_driver_descriptor *)
util_dl_get_proc_address(ddev->lib, "driver_descriptor");
/* sanity check on the name */
if (!dd || strcmp(dd->name, ddev->base.driver_name) != 0)
return NULL;
if (!dd->configuration)
return NULL;
return dd->configuration(conf);
return ddev->dd->configuration(conf);
}
static struct pipe_screen *
pipe_loader_drm_create_screen(struct pipe_loader_device *dev,
const char *library_paths)
pipe_loader_drm_create_screen(struct pipe_loader_device *dev)
{
struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev);
const struct drm_driver_descriptor *dd;
if (!ddev->lib)
ddev->lib = pipe_loader_find_module(dev, library_paths);
if (!ddev->lib)
return NULL;
dd = (const struct drm_driver_descriptor *)
util_dl_get_proc_address(ddev->lib, "driver_descriptor");
/* sanity check on the name */
if (!dd || strcmp(dd->name, ddev->base.driver_name) != 0)
return NULL;
return dd->create_screen(ddev->fd);
return ddev->dd->create_screen(ddev->fd);
}
static struct pipe_loader_ops pipe_loader_drm_ops = {
static const struct pipe_loader_ops pipe_loader_drm_ops = {
.create_screen = pipe_loader_drm_create_screen,
.configuration = pipe_loader_drm_configuration,
.release = pipe_loader_drm_release

View file

@ -31,8 +31,7 @@
#include "pipe_loader.h"
struct pipe_loader_ops {
struct pipe_screen *(*create_screen)(struct pipe_loader_device *dev,
const char *library_paths);
struct pipe_screen *(*create_screen)(struct pipe_loader_device *dev);
const struct drm_conf_ret *(*configuration)(struct pipe_loader_device *dev,
enum drm_conf conf);

View file

@ -30,45 +30,160 @@
#include "util/u_memory.h"
#include "util/u_dl.h"
#include "sw/dri/dri_sw_winsys.h"
#include "sw/kms-dri/kms_dri_sw_winsys.h"
#include "sw/null/null_sw_winsys.h"
#include "sw/wrapper/wrapper_sw_winsys.h"
#include "target-helpers/inline_sw_helper.h"
#include "state_tracker/drisw_api.h"
#include "state_tracker/sw_driver.h"
struct pipe_loader_sw_device {
struct pipe_loader_device base;
const struct sw_driver_descriptor *dd;
#ifndef GALLIUM_STATIC_TARGETS
struct util_dl_library *lib;
#endif
struct sw_winsys *ws;
};
#define pipe_loader_sw_device(dev) ((struct pipe_loader_sw_device *)dev)
static struct pipe_loader_ops pipe_loader_sw_ops;
static const struct pipe_loader_ops pipe_loader_sw_ops;
static struct sw_winsys *(*backends[])() = {
null_sw_create
#ifdef GALLIUM_STATIC_TARGETS
static const struct sw_driver_descriptor driver_descriptors = {
.create_screen = sw_screen_create,
.winsys = {
#ifdef HAVE_PIPE_LOADER_DRI
{
.name = "dri",
.create_winsys = dri_create_sw_winsys,
},
#endif
#ifdef HAVE_PIPE_LOADER_KMS
{
.name = "kms_dri",
.create_winsys = kms_dri_create_winsys,
},
#endif
/**
* XXX: Do not include these two for non autotools builds.
* They don't have neither opencl nor nine, where these are used.
*/
#ifndef DROP_PIPE_LOADER_MISC
{
.name = "null",
.create_winsys = null_sw_create,
},
{
.name = "wrapped",
.create_winsys = wrapper_sw_winsys_wrap_pipe_screen,
},
#endif
{ 0 },
}
};
#endif
static bool
pipe_loader_sw_probe_init_common(struct pipe_loader_sw_device *sdev)
{
sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;
sdev->base.driver_name = "swrast";
sdev->base.ops = &pipe_loader_sw_ops;
#ifdef GALLIUM_STATIC_TARGETS
sdev->dd = &driver_descriptors;
if (!sdev->dd)
return false;
#else
sdev->lib = pipe_loader_find_module(&sdev->base, PIPE_SEARCH_DIR);
if (!sdev->lib)
return false;
sdev->dd = (const struct sw_driver_descriptor *)
util_dl_get_proc_address(sdev->lib, "swrast_driver_descriptor");
if (!sdev->dd){
util_dl_close(sdev->lib);
sdev->lib = NULL;
return false;
}
#endif
return true;
}
static void
pipe_loader_sw_probe_teardown_common(struct pipe_loader_sw_device *sdev)
{
#ifndef GALLIUM_STATIC_TARGETS
if (sdev->lib)
util_dl_close(sdev->lib);
#endif
}
#ifdef HAVE_PIPE_LOADER_DRI
bool
pipe_loader_sw_probe_dri(struct pipe_loader_device **devs, struct drisw_loader_funcs *drisw_lf)
{
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
int i;
if (!sdev)
return false;
sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;
sdev->base.driver_name = "swrast";
sdev->base.ops = &pipe_loader_sw_ops;
sdev->ws = dri_create_sw_winsys(drisw_lf);
if (!sdev->ws) {
FREE(sdev);
return false;
}
*devs = &sdev->base;
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
for (i = 0; sdev->dd->winsys; i++) {
if (strcmp(sdev->dd->winsys[i].name, "dri") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys(drisw_lf);
break;
}
}
if (!sdev->ws)
goto fail;
*devs = &sdev->base;
return true;
fail:
pipe_loader_sw_probe_teardown_common(sdev);
FREE(sdev);
return false;
}
#endif
#ifdef HAVE_PIPE_LOADER_KMS
bool
pipe_loader_sw_probe_kms(struct pipe_loader_device **devs, int fd)
{
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
int i;
if (!sdev)
return false;
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
for (i = 0; sdev->dd->winsys; i++) {
if (strcmp(sdev->dd->winsys[i].name, "kms_dri") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys(fd);
break;
}
}
if (!sdev->ws)
goto fail;
*devs = &sdev->base;
return true;
fail:
pipe_loader_sw_probe_teardown_common(sdev);
FREE(sdev);
return false;
}
#endif
@ -76,38 +191,40 @@ bool
pipe_loader_sw_probe_null(struct pipe_loader_device **devs)
{
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
int i;
if (!sdev)
return false;
sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;
sdev->base.driver_name = "swrast";
sdev->base.ops = &pipe_loader_sw_ops;
sdev->ws = null_sw_create();
if (!sdev->ws) {
FREE(sdev);
return false;
}
*devs = &sdev->base;
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
for (i = 0; sdev->dd->winsys; i++) {
if (strcmp(sdev->dd->winsys[i].name, "null") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys();
break;
}
}
if (!sdev->ws)
goto fail;
*devs = &sdev->base;
return true;
fail:
pipe_loader_sw_probe_teardown_common(sdev);
FREE(sdev);
return false;
}
int
pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev)
{
int i;
int i = 1;
for (i = 0; i < Elements(backends); i++) {
if (i < ndev) {
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
/* TODO: handle CALLOC_STRUCT failure */
sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;
sdev->base.driver_name = "swrast";
sdev->base.ops = &pipe_loader_sw_ops;
sdev->ws = backends[i]();
devs[i] = &sdev->base;
if (i < ndev) {
if (!pipe_loader_sw_probe_null(devs)) {
i--;
}
}
@ -119,21 +236,30 @@ pipe_loader_sw_probe_wrapped(struct pipe_loader_device **dev,
struct pipe_screen *screen)
{
struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device);
int i;
if (!sdev)
return false;
sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE;
sdev->base.driver_name = "swrast";
sdev->base.ops = &pipe_loader_sw_ops;
sdev->ws = wrapper_sw_winsys_wrap_pipe_screen(screen);
if (!pipe_loader_sw_probe_init_common(sdev))
goto fail;
if (!sdev->ws) {
FREE(sdev);
return false;
for (i = 0; sdev->dd->winsys; i++) {
if (strcmp(sdev->dd->winsys[i].name, "wrapped") == 0) {
sdev->ws = sdev->dd->winsys[i].create_winsys(screen);
break;
}
}
if (!sdev->ws)
goto fail;
*dev = &sdev->base;
return true;
fail:
pipe_loader_sw_probe_teardown_common(sdev);
FREE(sdev);
return false;
}
static void
@ -141,8 +267,10 @@ pipe_loader_sw_release(struct pipe_loader_device **dev)
{
struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(*dev);
#ifndef GALLIUM_STATIC_TARGETS
if (sdev->lib)
util_dl_close(sdev->lib);
#endif
FREE(sdev);
*dev = NULL;
@ -156,28 +284,19 @@ pipe_loader_sw_configuration(struct pipe_loader_device *dev,
}
static struct pipe_screen *
pipe_loader_sw_create_screen(struct pipe_loader_device *dev,
const char *library_paths)
pipe_loader_sw_create_screen(struct pipe_loader_device *dev)
{
struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(dev);
struct pipe_screen *(*init)(struct sw_winsys *);
struct pipe_screen *screen;
if (!sdev->lib)
sdev->lib = pipe_loader_find_module(dev, library_paths);
if (!sdev->lib)
return NULL;
screen = sdev->dd->create_screen(sdev->ws);
if (!screen)
sdev->ws->destroy(sdev->ws);
init = (void *)util_dl_get_proc_address(sdev->lib, "swrast_create_screen");
if (!init){
util_dl_close(sdev->lib);
sdev->lib = NULL;
return NULL;
}
return init(sdev->ws);
return screen;
}
static struct pipe_loader_ops pipe_loader_sw_ops = {
static const struct pipe_loader_ops pipe_loader_sw_ops = {
.create_screen = pipe_loader_sw_create_screen,
.configuration = pipe_loader_sw_configuration,
.release = pipe_loader_sw_release

View file

@ -0,0 +1,275 @@
#ifndef DRM_HELPER_H
#define DRM_HELPER_H
#include <stdio.h>
#include "target-helpers/inline_debug_helper.h"
#include "target-helpers/drm_helper_public.h"
#ifdef GALLIUM_I915
#include "i915/drm/i915_drm_public.h"
#include "i915/i915_public.h"
struct pipe_screen *
pipe_i915_create_screen(int fd)
{
struct i915_winsys *iws;
struct pipe_screen *screen;
iws = i915_drm_winsys_create(fd);
if (!iws)
return NULL;
screen = i915_screen_create(iws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_i915_create_screen(int fd)
{
fprintf(stderr, "i915g: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_ILO
#include "intel/drm/intel_drm_public.h"
#include "ilo/ilo_public.h"
struct pipe_screen *
pipe_ilo_create_screen(int fd)
{
struct intel_winsys *iws;
struct pipe_screen *screen;
iws = intel_winsys_create_for_fd(fd);
if (!iws)
return NULL;
screen = ilo_screen_create(iws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_ilo_create_screen(int fd)
{
fprintf(stderr, "ilo: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_NOUVEAU
#include "nouveau/drm/nouveau_drm_public.h"
struct pipe_screen *
pipe_nouveau_create_screen(int fd)
{
struct pipe_screen *screen;
screen = nouveau_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_nouveau_create_screen(int fd)
{
fprintf(stderr, "nouveau: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_R300
#include "radeon/radeon_winsys.h"
#include "radeon/drm/radeon_drm_public.h"
#include "r300/r300_public.h"
struct pipe_screen *
pipe_r300_create_screen(int fd)
{
struct radeon_winsys *rw;
rw = radeon_drm_winsys_create(fd, r300_screen_create);
return rw ? debug_screen_wrap(rw->screen) : NULL;
}
#else
struct pipe_screen *
pipe_r300_create_screen(int fd)
{
fprintf(stderr, "r300: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_R600
#include "radeon/radeon_winsys.h"
#include "radeon/drm/radeon_drm_public.h"
#include "r600/r600_public.h"
struct pipe_screen *
pipe_r600_create_screen(int fd)
{
struct radeon_winsys *rw;
rw = radeon_drm_winsys_create(fd, r600_screen_create);
return rw ? debug_screen_wrap(rw->screen) : NULL;
}
#else
struct pipe_screen *
pipe_r600_create_screen(int fd)
{
fprintf(stderr, "r600: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_RADEONSI
#include "radeon/radeon_winsys.h"
#include "radeon/drm/radeon_drm_public.h"
#include "amdgpu/drm/amdgpu_public.h"
#include "radeonsi/si_public.h"
struct pipe_screen *
pipe_radeonsi_create_screen(int fd)
{
struct radeon_winsys *rw;
/* First, try amdgpu. */
rw = amdgpu_winsys_create(fd, radeonsi_screen_create);
if (!rw)
rw = radeon_drm_winsys_create(fd, radeonsi_screen_create);
return rw ? debug_screen_wrap(rw->screen) : NULL;
}
#else
struct pipe_screen *
pipe_radeonsi_create_screen(int fd)
{
fprintf(stderr, "radeonsi: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_VMWGFX
#include "svga/drm/svga_drm_public.h"
#include "svga/svga_public.h"
struct pipe_screen *
pipe_vmwgfx_create_screen(int fd)
{
struct svga_winsys_screen *sws;
struct pipe_screen *screen;
sws = svga_drm_winsys_screen_create(fd);
if (!sws)
return NULL;
screen = svga_screen_create(sws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_vmwgfx_create_screen(int fd)
{
fprintf(stderr, "svga: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_FREEDRENO
#include "freedreno/drm/freedreno_drm_public.h"
struct pipe_screen *
pipe_freedreno_create_screen(int fd)
{
struct pipe_screen *screen;
screen = fd_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_freedreno_create_screen(int fd)
{
fprintf(stderr, "freedreno: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_VIRGL
#include "virgl/drm/virgl_drm_public.h"
#include "virgl/virgl_public.h"
struct pipe_screen *
pipe_virgl_create_screen(int fd)
{
struct virgl_winsys *vws;
struct pipe_screen *screen;
vws = virgl_drm_winsys_create(fd);
if (!vws)
return NULL;
screen = virgl_create_screen(vws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_virgl_create_screen(int fd)
{
fprintf(stderr, "virgl: driver missing\n");
return NULL;
}
#endif
#ifdef GALLIUM_VC4
#include "vc4/drm/vc4_drm_public.h"
struct pipe_screen *
pipe_vc4_create_screen(int fd)
{
struct pipe_screen *screen;
screen = vc4_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#else
struct pipe_screen *
pipe_vc4_create_screen(int fd)
{
fprintf(stderr, "vc4: driver missing\n");
return NULL;
}
#endif
#endif /* DRM_HELPER_H */

View file

@ -0,0 +1,37 @@
#ifndef _DRM_HELPER_PUBLIC_H
#define _DRM_HELPER_PUBLIC_H
struct pipe_screen;
struct pipe_screen *
pipe_i915_create_screen(int fd);
struct pipe_screen *
pipe_ilo_create_screen(int fd);
struct pipe_screen *
pipe_nouveau_create_screen(int fd);
struct pipe_screen *
pipe_r300_create_screen(int fd);
struct pipe_screen *
pipe_r600_create_screen(int fd);
struct pipe_screen *
pipe_radeonsi_create_screen(int fd);
struct pipe_screen *
pipe_vmwgfx_create_screen(int fd);
struct pipe_screen *
pipe_freedreno_create_screen(int fd);
struct pipe_screen *
pipe_virgl_create_screen(int fd);
struct pipe_screen *
pipe_vc4_create_screen(int fd);
#endif /* _DRM_HELPER_PUBLIC_H */

View file

@ -1,531 +0,0 @@
#ifndef INLINE_DRM_HELPER_H
#define INLINE_DRM_HELPER_H
#include "state_tracker/drm_driver.h"
#include "target-helpers/inline_debug_helper.h"
#include "loader.h"
#if defined(DRI_TARGET)
#include "dri_screen.h"
#endif
#if GALLIUM_SOFTPIPE
#include "target-helpers/inline_sw_helper.h"
#include "sw/kms-dri/kms_dri_sw_winsys.h"
#endif
#if GALLIUM_I915
#include "i915/drm/i915_drm_public.h"
#include "i915/i915_public.h"
#endif
#if GALLIUM_ILO
#include "intel/drm/intel_drm_public.h"
#include "ilo/ilo_public.h"
#endif
#if GALLIUM_NOUVEAU
#include "nouveau/drm/nouveau_drm_public.h"
#endif
#if GALLIUM_R300
#include "radeon/radeon_winsys.h"
#include "radeon/drm/radeon_drm_public.h"
#include "r300/r300_public.h"
#endif
#if GALLIUM_R600
#include "radeon/radeon_winsys.h"
#include "radeon/drm/radeon_drm_public.h"
#include "r600/r600_public.h"
#endif
#if GALLIUM_RADEONSI
#include "radeon/radeon_winsys.h"
#include "radeon/drm/radeon_drm_public.h"
#include "amdgpu/drm/amdgpu_public.h"
#include "radeonsi/si_public.h"
#endif
#if GALLIUM_VMWGFX
#include "svga/drm/svga_drm_public.h"
#include "svga/svga_public.h"
#endif
#if GALLIUM_FREEDRENO
#include "freedreno/drm/freedreno_drm_public.h"
#endif
#if GALLIUM_VC4
#include "vc4/drm/vc4_drm_public.h"
#endif
#if GALLIUM_VIRGL
#include "virgl/drm/virgl_drm_public.h"
#include "virgl/virgl_public.h"
#endif
static char* driver_name = NULL;
/* XXX: We need to teardown the winsys if *screen_create() fails. */
#if defined(GALLIUM_SOFTPIPE)
#if defined(DRI_TARGET)
#if defined(HAVE_LIBDRM)
const __DRIextension **__driDriverGetExtensions_kms_swrast(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_kms_swrast(void)
{
globalDriverAPI = &dri_kms_driver_api;
return galliumdrm_driver_extensions;
}
struct pipe_screen *
kms_swrast_create_screen(int fd)
{
struct sw_winsys *sws;
struct pipe_screen *screen;
sws = kms_dri_create_winsys(fd);
if (!sws)
return NULL;
screen = sw_screen_create(sws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#endif
#endif
#if defined(GALLIUM_I915)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_i915(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_i915(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_i915_create_screen(int fd)
{
struct i915_winsys *iws;
struct pipe_screen *screen;
iws = i915_drm_winsys_create(fd);
if (!iws)
return NULL;
screen = i915_screen_create(iws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#if defined(GALLIUM_ILO)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_i965(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_ilo_create_screen(int fd)
{
struct intel_winsys *iws;
struct pipe_screen *screen;
iws = intel_winsys_create_for_fd(fd);
if (!iws)
return NULL;
screen = ilo_screen_create(iws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#if defined(GALLIUM_NOUVEAU)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_nouveau(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_nouveau(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_nouveau_create_screen(int fd)
{
struct pipe_screen *screen;
screen = nouveau_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#if defined(GALLIUM_R300)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_r300(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_r300(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_r300_create_screen(int fd)
{
struct radeon_winsys *rw;
rw = radeon_drm_winsys_create(fd, r300_screen_create);
return rw ? debug_screen_wrap(rw->screen) : NULL;
}
#endif
#if defined(GALLIUM_R600)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_r600(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_r600(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_r600_create_screen(int fd)
{
struct radeon_winsys *rw;
rw = radeon_drm_winsys_create(fd, r600_screen_create);
return rw ? debug_screen_wrap(rw->screen) : NULL;
}
#endif
#if defined(GALLIUM_RADEONSI)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_radeonsi(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_radeonsi(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_radeonsi_create_screen(int fd)
{
struct radeon_winsys *rw;
/* First, try amdgpu. */
rw = amdgpu_winsys_create(fd, radeonsi_screen_create);
if (!rw)
rw = radeon_drm_winsys_create(fd, radeonsi_screen_create);
return rw ? debug_screen_wrap(rw->screen) : NULL;
}
#endif
#if defined(GALLIUM_VMWGFX)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_vmwgfx(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_vmwgfx(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_vmwgfx_create_screen(int fd)
{
struct svga_winsys_screen *sws;
struct pipe_screen *screen;
sws = svga_drm_winsys_screen_create(fd);
if (!sws)
return NULL;
screen = svga_screen_create(sws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#if defined(GALLIUM_FREEDRENO)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_msm(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_msm(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
const __DRIextension **__driDriverGetExtensions_kgsl(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_kgsl(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_freedreno_create_screen(int fd)
{
struct pipe_screen *screen;
screen = fd_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#if defined(GALLIUM_VIRGL)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_virtio_gpu(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_virtio_gpu(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
static struct pipe_screen *
pipe_virgl_create_screen(int fd)
{
struct virgl_winsys *vws;
struct pipe_screen *screen;
vws = virgl_drm_winsys_create(fd);
if (!vws)
return NULL;
screen = virgl_create_screen(vws);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
#if defined(GALLIUM_VC4)
#if defined(DRI_TARGET)
const __DRIextension **__driDriverGetExtensions_vc4(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_vc4(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#if defined(USE_VC4_SIMULATOR)
const __DRIextension **__driDriverGetExtensions_i965(void);
/**
* When building using the simulator (on x86), we advertise ourselves as the
* i965 driver so that you can just make a directory with a link from
* i965_dri.so to the built vc4_dri.so, and point LIBGL_DRIVERS_PATH to that
* on your i965-using host to run the driver under simulation.
*
* This is, of course, incompatible with building with the ilo driver, but you
* shouldn't be building that anyway.
*/
PUBLIC const __DRIextension **__driDriverGetExtensions_i965(void)
{
globalDriverAPI = &galliumdrm_driver_api;
return galliumdrm_driver_extensions;
}
#endif
#endif
static struct pipe_screen *
pipe_vc4_create_screen(int fd)
{
struct pipe_screen *screen;
screen = vc4_drm_screen_create(fd);
return screen ? debug_screen_wrap(screen) : NULL;
}
#endif
inline struct pipe_screen *
dd_create_screen(int fd)
{
driver_name = loader_get_driver_for_fd(fd, _LOADER_GALLIUM);
if (!driver_name)
return NULL;
#if defined(GALLIUM_I915)
if (strcmp(driver_name, "i915") == 0)
return pipe_i915_create_screen(fd);
else
#endif
#if defined(GALLIUM_ILO)
if (strcmp(driver_name, "i965") == 0)
return pipe_ilo_create_screen(fd);
else
#endif
#if defined(GALLIUM_NOUVEAU)
if (strcmp(driver_name, "nouveau") == 0)
return pipe_nouveau_create_screen(fd);
else
#endif
#if defined(GALLIUM_R300)
if (strcmp(driver_name, "r300") == 0)
return pipe_r300_create_screen(fd);
else
#endif
#if defined(GALLIUM_R600)
if (strcmp(driver_name, "r600") == 0)
return pipe_r600_create_screen(fd);
else
#endif
#if defined(GALLIUM_RADEONSI)
if (strcmp(driver_name, "radeonsi") == 0)
return pipe_radeonsi_create_screen(fd);
else
#endif
#if defined(GALLIUM_VMWGFX)
if (strcmp(driver_name, "vmwgfx") == 0)
return pipe_vmwgfx_create_screen(fd);
else
#endif
#if defined(GALLIUM_FREEDRENO)
if ((strcmp(driver_name, "kgsl") == 0) || (strcmp(driver_name, "msm") == 0))
return pipe_freedreno_create_screen(fd);
else
#endif
#if defined(GALLIUM_VIRGL)
if ((strcmp(driver_name, "virtio_gpu") == 0))
return pipe_virgl_create_screen(fd);
else
#endif
#if defined(GALLIUM_VC4)
if (strcmp(driver_name, "vc4") == 0)
return pipe_vc4_create_screen(fd);
else
#if defined(USE_VC4_SIMULATOR)
if (strcmp(driver_name, "i965") == 0)
return pipe_vc4_create_screen(fd);
else
#endif
#endif
return NULL;
}
inline const char *
dd_driver_name(void)
{
return driver_name;
}
static const struct drm_conf_ret throttle_ret = {
DRM_CONF_INT,
{2},
};
static const struct drm_conf_ret share_fd_ret = {
DRM_CONF_BOOL,
{true},
};
static inline const struct drm_conf_ret *
configuration_query(enum drm_conf conf)
{
switch (conf) {
case DRM_CONF_THROTTLE:
return &throttle_ret;
case DRM_CONF_SHARE_FD:
return &share_fd_ret;
default:
break;
}
return NULL;
}
inline const struct drm_conf_ret *
dd_configuration(enum drm_conf conf)
{
if (!driver_name)
return NULL;
#if defined(GALLIUM_I915)
if (strcmp(driver_name, "i915") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_ILO)
if (strcmp(driver_name, "i965") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_NOUVEAU)
if (strcmp(driver_name, "nouveau") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_R300)
if (strcmp(driver_name, "r300") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_R600)
if (strcmp(driver_name, "r600") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_RADEONSI)
if (strcmp(driver_name, "radeonsi") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_VMWGFX)
if (strcmp(driver_name, "vmwgfx") == 0)
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_FREEDRENO)
if ((strcmp(driver_name, "kgsl") == 0) || (strcmp(driver_name, "msm") == 0))
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_VIRGL)
if ((strcmp(driver_name, "virtio_gpu") == 0))
return configuration_query(conf);
else
#endif
#if defined(GALLIUM_VC4)
if (strcmp(driver_name, "vc4") == 0)
return configuration_query(conf);
else
#if defined(USE_VC4_SIMULATOR)
if (strcmp(driver_name, "i965") == 0)
return configuration_query(conf);
else
#endif
#endif
return NULL;
}
#endif /* INLINE_DRM_HELPER_H */

View file

@ -69,69 +69,4 @@ sw_screen_create(struct sw_winsys *winsys)
return sw_screen_create_named(winsys, driver);
}
#if defined(GALLIUM_SOFTPIPE)
#if defined(DRI_TARGET)
#include "target-helpers/inline_debug_helper.h"
#include "sw/dri/dri_sw_winsys.h"
#include "dri_screen.h"
const __DRIextension **__driDriverGetExtensions_swrast(void);
PUBLIC const __DRIextension **__driDriverGetExtensions_swrast(void)
{
globalDriverAPI = &galliumsw_driver_api;
return galliumsw_driver_extensions;
}
inline struct pipe_screen *
drisw_create_screen(struct drisw_loader_funcs *lf)
{
struct sw_winsys *winsys = NULL;
struct pipe_screen *screen = NULL;
winsys = dri_create_sw_winsys(lf);
if (winsys == NULL)
return NULL;
screen = sw_screen_create(winsys);
if (screen == NULL) {
winsys->destroy(winsys);
return NULL;
}
screen = debug_screen_wrap(screen);
return screen;
}
#endif // DRI_TARGET
#if defined(NINE_TARGET)
#include "sw/wrapper/wrapper_sw_winsys.h"
#include "target-helpers/inline_debug_helper.h"
extern struct pipe_screen *ninesw_create_screen(struct pipe_screen *screen);
inline struct pipe_screen *
ninesw_create_screen(struct pipe_screen *pscreen)
{
struct sw_winsys *winsys = NULL;
struct pipe_screen *screen = NULL;
winsys = wrapper_sw_winsys_wrap_pipe_screen(pscreen);
if (winsys == NULL)
return NULL;
screen = sw_screen_create(winsys);
if (screen == NULL) {
winsys->destroy(winsys);
return NULL;
}
screen = debug_screen_wrap(screen);
return screen;
}
#endif // NINE_TARGET
#endif // GALLIUM_SOFTPIPE
#endif

View file

@ -45,7 +45,7 @@ struct util_dl_library *
util_dl_open(const char *filename)
{
#if defined(PIPE_OS_UNIX)
return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
#elif defined(PIPE_OS_WINDOWS)
return (struct util_dl_library *)LoadLibraryA(filename);
#else

View file

@ -202,6 +202,36 @@ PIPE_FORMAT_BPTC_SRGBA , bptc, 4, 4, x128, , , , xyzw, sr
PIPE_FORMAT_BPTC_RGB_FLOAT , bptc, 4, 4, x128, , , , xyz1, rgb
PIPE_FORMAT_BPTC_RGB_UFLOAT , bptc, 4, 4, x128, , , , xyz1, rgb
PIPE_FORMAT_ASTC_4x4 , astc, 4, 4, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_5x4 , astc, 5, 4, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_5x5 , astc, 5, 5, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_6x5 , astc, 6, 5, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_6x6 , astc, 6, 6, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_8x5 , astc, 8, 5, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_8x6 , astc, 8, 6, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_8x8 , astc, 8, 8, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_10x5 , astc,10, 5, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_10x6 , astc,10, 6, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_10x8 , astc,10, 8, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_10x10 , astc,10,10, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_12x10 , astc,12,10, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_12x12 , astc,12,12, x128, , , , xyzw, rgb
PIPE_FORMAT_ASTC_4x4_SRGB , astc, 4, 4, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_5x4_SRGB , astc, 5, 4, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_5x5_SRGB , astc, 5, 5, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_6x5_SRGB , astc, 6, 5, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_6x6_SRGB , astc, 6, 6, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_8x5_SRGB , astc, 8, 5, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_8x6_SRGB , astc, 8, 6, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_8x8_SRGB , astc, 8, 8, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_10x5_SRGB , astc,10, 5, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_10x6_SRGB , astc,10, 6, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_10x8_SRGB , astc,10, 8, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_10x10_SRGB , astc,10,10, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_12x10_SRGB , astc,12,10, x128, , , , xyzw, srgb
PIPE_FORMAT_ASTC_12x12_SRGB , astc,12,12, x128, , , , xyzw, srgb
# Straightforward D3D10-like formats (also used for
# vertex buffer element description)
#

Can't render this file because it contains an unexpected character in line 8 and column 3.

View file

@ -83,10 +83,15 @@ enum util_format_layout {
*/
UTIL_FORMAT_LAYOUT_BPTC = 7,
/**
* ASTC
*/
UTIL_FORMAT_LAYOUT_ASTC = 8,
/**
* Everything else that doesn't fit in any of the above layouts.
*/
UTIL_FORMAT_LAYOUT_OTHER = 8
UTIL_FORMAT_LAYOUT_OTHER = 9
};
@ -481,6 +486,7 @@ util_format_is_compressed(enum pipe_format format)
case UTIL_FORMAT_LAYOUT_RGTC:
case UTIL_FORMAT_LAYOUT_ETC:
case UTIL_FORMAT_LAYOUT_BPTC:
case UTIL_FORMAT_LAYOUT_ASTC:
/* XXX add other formats in the future */
return TRUE;
default:
@ -924,6 +930,35 @@ util_format_srgb(enum pipe_format format)
return PIPE_FORMAT_B5G6R5_SRGB;
case PIPE_FORMAT_BPTC_RGBA_UNORM:
return PIPE_FORMAT_BPTC_SRGBA;
case PIPE_FORMAT_ASTC_4x4:
return PIPE_FORMAT_ASTC_4x4_SRGB;
case PIPE_FORMAT_ASTC_5x4:
return PIPE_FORMAT_ASTC_5x4_SRGB;
case PIPE_FORMAT_ASTC_5x5:
return PIPE_FORMAT_ASTC_5x5_SRGB;
case PIPE_FORMAT_ASTC_6x5:
return PIPE_FORMAT_ASTC_6x5_SRGB;
case PIPE_FORMAT_ASTC_6x6:
return PIPE_FORMAT_ASTC_6x6_SRGB;
case PIPE_FORMAT_ASTC_8x5:
return PIPE_FORMAT_ASTC_8x5_SRGB;
case PIPE_FORMAT_ASTC_8x6:
return PIPE_FORMAT_ASTC_8x6_SRGB;
case PIPE_FORMAT_ASTC_8x8:
return PIPE_FORMAT_ASTC_8x8_SRGB;
case PIPE_FORMAT_ASTC_10x5:
return PIPE_FORMAT_ASTC_10x5_SRGB;
case PIPE_FORMAT_ASTC_10x6:
return PIPE_FORMAT_ASTC_10x6_SRGB;
case PIPE_FORMAT_ASTC_10x8:
return PIPE_FORMAT_ASTC_10x8_SRGB;
case PIPE_FORMAT_ASTC_10x10:
return PIPE_FORMAT_ASTC_10x10_SRGB;
case PIPE_FORMAT_ASTC_12x10:
return PIPE_FORMAT_ASTC_12x10_SRGB;
case PIPE_FORMAT_ASTC_12x12:
return PIPE_FORMAT_ASTC_12x12_SRGB;
default:
return PIPE_FORMAT_NONE;
}
@ -971,6 +1006,34 @@ util_format_linear(enum pipe_format format)
return PIPE_FORMAT_B5G6R5_UNORM;
case PIPE_FORMAT_BPTC_SRGBA:
return PIPE_FORMAT_BPTC_RGBA_UNORM;
case PIPE_FORMAT_ASTC_4x4_SRGB:
return PIPE_FORMAT_ASTC_4x4;
case PIPE_FORMAT_ASTC_5x4_SRGB:
return PIPE_FORMAT_ASTC_5x4;
case PIPE_FORMAT_ASTC_5x5_SRGB:
return PIPE_FORMAT_ASTC_5x5;
case PIPE_FORMAT_ASTC_6x5_SRGB:
return PIPE_FORMAT_ASTC_6x5;
case PIPE_FORMAT_ASTC_6x6_SRGB:
return PIPE_FORMAT_ASTC_6x6;
case PIPE_FORMAT_ASTC_8x5_SRGB:
return PIPE_FORMAT_ASTC_8x5;
case PIPE_FORMAT_ASTC_8x6_SRGB:
return PIPE_FORMAT_ASTC_8x6;
case PIPE_FORMAT_ASTC_8x8_SRGB:
return PIPE_FORMAT_ASTC_8x8;
case PIPE_FORMAT_ASTC_10x5_SRGB:
return PIPE_FORMAT_ASTC_10x5;
case PIPE_FORMAT_ASTC_10x6_SRGB:
return PIPE_FORMAT_ASTC_10x6;
case PIPE_FORMAT_ASTC_10x8_SRGB:
return PIPE_FORMAT_ASTC_10x8;
case PIPE_FORMAT_ASTC_10x10_SRGB:
return PIPE_FORMAT_ASTC_10x10;
case PIPE_FORMAT_ASTC_12x10_SRGB:
return PIPE_FORMAT_ASTC_12x10;
case PIPE_FORMAT_ASTC_12x12_SRGB:
return PIPE_FORMAT_ASTC_12x12;
default:
return format;
}

View file

@ -1,37 +0,0 @@
#include "u_format.h"
#include "u_format_fake.h"
#define fake(format) \
void \
util_format_##format##_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) {assert(0);} \
\
void \
util_format_##format##_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) {assert(0);} \
\
void \
util_format_##format##_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) {assert(0);} \
\
void \
util_format_##format##_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) {assert(0);} \
\
void \
util_format_##format##_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) {assert(0);} \
\
void \
util_format_##format##_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) {assert(0);}
fake(bptc_rgba_unorm)
fake(bptc_srgba)
fake(bptc_rgb_float)
fake(bptc_rgb_ufloat)
fake(etc2_rgb8)
fake(etc2_srgb8)
fake(etc2_rgb8a1)
fake(etc2_srgb8a1)
fake(etc2_rgba8)
fake(etc2_srgba8)
fake(etc2_r11_unorm)
fake(etc2_r11_snorm)
fake(etc2_rg11_unorm)
fake(etc2_rg11_snorm)

View file

@ -1,66 +0,0 @@
/**************************************************************************
*
* Copyright 2011 Red Hat Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
**************************************************************************/
#ifndef U_FORMAT_FAKE_H_
#define U_FORMAT_FAKE_H_
#define __format_fake(format) \
void \
util_format_##format##_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); \
\
void \
util_format_##format##_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); \
\
void \
util_format_##format##_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); \
\
void \
util_format_##format##_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); \
\
void \
util_format_##format##_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); \
\
void \
util_format_##format##_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j);
__format_fake(bptc_rgba_unorm)
__format_fake(bptc_srgba)
__format_fake(bptc_rgb_float)
__format_fake(bptc_rgb_ufloat)
__format_fake(etc2_rgb8)
__format_fake(etc2_srgb8)
__format_fake(etc2_rgb8a1)
__format_fake(etc2_srgb8a1)
__format_fake(etc2_rgba8)
__format_fake(etc2_srgba8)
__format_fake(etc2_r11_unorm)
__format_fake(etc2_r11_snorm)
__format_fake(etc2_rg11_unorm)
__format_fake(etc2_rg11_snorm)
#endif

View file

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

View file

@ -90,7 +90,6 @@ def write_format_table(formats):
print '#include "u_format_rgtc.h"'
print '#include "u_format_latc.h"'
print '#include "u_format_etc.h"'
print '#include "u_format_fake.h"'
print
u_format_pack.generate(formats)
@ -139,10 +138,15 @@ def write_format_table(formats):
u_format_pack.print_channels(format, do_channel_array)
u_format_pack.print_channels(format, do_swizzle_array)
print " %s," % (colorspace_map(format.colorspace),)
if format.colorspace != ZS and not format.is_pure_color():
access = True
if format.layout in ('bptc', 'astc'):
access = False
if format.layout == 'etc' and format.short_name() != 'etc1_rgb8':
access = False
if format.colorspace != ZS and not format.is_pure_color() and access:
print " &util_format_%s_unpack_rgba_8unorm," % format.short_name()
print " &util_format_%s_pack_rgba_8unorm," % format.short_name()
if format.layout == 's3tc' or format.layout == 'rgtc' or format.layout == 'bptc':
if format.layout == 's3tc' or format.layout == 'rgtc':
print " &util_format_%s_fetch_rgba_8unorm," % format.short_name()
else:
print " NULL, /* fetch_rgba_8unorm */"

View file

@ -42,34 +42,31 @@ struct pipe_loader_device;
struct vl_screen
{
void (*destroy)(struct vl_screen *vscreen);
struct pipe_resource *
(*texture_from_drawable)(struct vl_screen *vscreen, void *drawable);
struct u_rect *
(*get_dirty_area)(struct vl_screen *vscreen);
uint64_t
(*get_timestamp)(struct vl_screen *vscreen, void *drawable);
void
(*set_next_timestamp)(struct vl_screen *vscreen, uint64_t stamp);
void *
(*get_private)(struct vl_screen *vscreen);
struct pipe_screen *pscreen;
struct pipe_loader_device *dev;
};
struct vl_screen*
vl_screen_create(Display *display, int screen);
struct vl_screen *
vl_dri2_screen_create(Display *display, int screen);
void vl_screen_destroy(struct vl_screen *vscreen);
struct pipe_resource*
vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable);
struct u_rect *
vl_screen_get_dirty_area(struct vl_screen *vscreen);
uint64_t
vl_screen_get_timestamp(struct vl_screen *vscreen, Drawable drawable);
void
vl_screen_set_next_timestamp(struct vl_screen *vscreen, uint64_t stamp);
void*
vl_screen_get_private(struct vl_screen *vscreen);
struct vl_screen*
struct vl_screen *
vl_drm_screen_create(int fd);
void
vl_drm_screen_destroy(struct vl_screen *vscreen);
#endif

View file

@ -73,24 +73,27 @@ struct vl_dri_screen
int64_t last_ust, ns_frame, last_msc, next_msc;
};
static const unsigned int attachments[1] = { XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT };
static const unsigned attachments[1] = { XCB_DRI2_ATTACHMENT_BUFFER_BACK_LEFT };
static void vl_dri2_screen_destroy(struct vl_screen *vscreen);
static void
vl_dri2_handle_stamps(struct vl_dri_screen* scrn,
vl_dri2_handle_stamps(struct vl_dri_screen *scrn,
uint32_t ust_hi, uint32_t ust_lo,
uint32_t msc_hi, uint32_t msc_lo)
{
int64_t ust = ((((uint64_t)ust_hi) << 32) | ust_lo) * 1000;
int64_t msc = (((uint64_t)msc_hi) << 32) | msc_lo;
if (scrn->last_ust && scrn->last_msc && (ust > scrn->last_ust) && (msc > scrn->last_msc))
if (scrn->last_ust && (ust > scrn->last_ust) &&
scrn->last_msc && (msc > scrn->last_msc))
scrn->ns_frame = (ust - scrn->last_ust) / (msc - scrn->last_msc);
scrn->last_ust = ust;
scrn->last_msc = msc;
}
static xcb_dri2_get_buffers_reply_t*
static xcb_dri2_get_buffers_reply_t *
vl_dri2_get_flush_reply(struct vl_dri_screen *scrn)
{
xcb_dri2_wait_sbc_reply_t *wait_sbc_reply;
@ -120,7 +123,7 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
unsigned level, unsigned layer,
void *context_private, struct pipe_box *sub_box)
{
struct vl_dri_screen *scrn = (struct vl_dri_screen*)context_private;
struct vl_dri_screen *scrn = (struct vl_dri_screen *)context_private;
uint32_t msc_hi, msc_lo;
assert(screen);
@ -132,9 +135,11 @@ vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
msc_hi = scrn->next_msc >> 32;
msc_lo = scrn->next_msc & 0xFFFFFFFF;
scrn->swap_cookie = xcb_dri2_swap_buffers_unchecked(scrn->conn, scrn->drawable, msc_hi, msc_lo, 0, 0, 0, 0);
scrn->swap_cookie = xcb_dri2_swap_buffers_unchecked(scrn->conn, scrn->drawable,
msc_hi, msc_lo, 0, 0, 0, 0);
scrn->wait_cookie = xcb_dri2_wait_sbc_unchecked(scrn->conn, scrn->drawable, 0, 0);
scrn->buffers_cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, scrn->drawable, 1, 1, attachments);
scrn->buffers_cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, scrn->drawable,
1, 1, attachments);
scrn->flushed = true;
scrn->current_buffer = !scrn->current_buffer;
@ -170,10 +175,10 @@ vl_dri2_set_drawable(struct vl_dri_screen *scrn, Drawable drawable)
scrn->drawable = drawable;
}
struct pipe_resource*
vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
static struct pipe_resource *
vl_dri2_screen_texture_from_drawable(struct vl_screen *vscreen, void *drawable)
{
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen;
struct winsys_handle dri2_handle;
struct pipe_resource template, *tex;
@ -185,11 +190,12 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
assert(scrn);
vl_dri2_set_drawable(scrn, drawable);
vl_dri2_set_drawable(scrn, (Drawable)drawable);
reply = vl_dri2_get_flush_reply(scrn);
if (!reply) {
xcb_dri2_get_buffers_cookie_t cookie;
cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, drawable, 1, 1, attachments);
cookie = xcb_dri2_get_buffers_unchecked(scrn->conn, (Drawable)drawable,
1, 1, attachments);
reply = xcb_dri2_get_buffers_reply(scrn->conn, cookie, NULL);
}
if (!reply)
@ -241,32 +247,33 @@ vl_screen_texture_from_drawable(struct vl_screen *vscreen, Drawable drawable)
template.bind = PIPE_BIND_RENDER_TARGET;
template.flags = 0;
tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template, &dri2_handle);
tex = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &template,
&dri2_handle);
free(reply);
return tex;
}
struct u_rect *
vl_screen_get_dirty_area(struct vl_screen *vscreen)
static struct u_rect *
vl_dri2_screen_get_dirty_area(struct vl_screen *vscreen)
{
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen;
assert(scrn);
return &scrn->dirty_areas[scrn->current_buffer];
}
uint64_t
vl_screen_get_timestamp(struct vl_screen *vscreen, Drawable drawable)
static uint64_t
vl_dri2_screen_get_timestamp(struct vl_screen *vscreen, void *drawable)
{
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen;
xcb_dri2_get_msc_cookie_t cookie;
xcb_dri2_get_msc_reply_t *reply;
assert(scrn);
vl_dri2_set_drawable(scrn, drawable);
vl_dri2_set_drawable(scrn, (Drawable)drawable);
if (!scrn->last_ust) {
cookie = xcb_dri2_get_msc_unchecked(scrn->conn, drawable);
cookie = xcb_dri2_get_msc_unchecked(scrn->conn, (Drawable)drawable);
reply = xcb_dri2_get_msc_reply(scrn->conn, cookie, NULL);
if (reply) {
@ -278,19 +285,20 @@ vl_screen_get_timestamp(struct vl_screen *vscreen, Drawable drawable)
return scrn->last_ust;
}
void
vl_screen_set_next_timestamp(struct vl_screen *vscreen, uint64_t stamp)
static void
vl_dri2_screen_set_next_timestamp(struct vl_screen *vscreen, uint64_t stamp)
{
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen;
assert(scrn);
if (stamp && scrn->last_ust && scrn->ns_frame && scrn->last_msc)
scrn->next_msc = ((int64_t)stamp - scrn->last_ust + scrn->ns_frame/2) / scrn->ns_frame + scrn->last_msc;
scrn->next_msc = ((int64_t)stamp - scrn->last_ust + scrn->ns_frame/2) /
scrn->ns_frame + scrn->last_msc;
else
scrn->next_msc = 0;
}
void*
vl_screen_get_private(struct vl_screen *vscreen)
static void *
vl_dri2_screen_get_private(struct vl_screen *vscreen)
{
return vscreen;
}
@ -305,8 +313,8 @@ get_xcb_screen(xcb_screen_iterator_t iter, int screen)
return NULL;
}
struct vl_screen*
vl_screen_create(Display *display, int screen)
struct vl_screen *
vl_dri2_screen_create(Display *display, int screen)
{
struct vl_dri_screen *scrn;
const xcb_query_extension_reply_t *extension;
@ -320,7 +328,7 @@ vl_screen_create(Display *display, int screen)
xcb_generic_error_t *error = NULL;
char *device_name;
int fd, device_name_length;
unsigned int driverType;
unsigned driverType;
drm_magic_t magic;
@ -340,7 +348,9 @@ vl_screen_create(Display *display, int screen)
if (!(extension && extension->present))
goto free_screen;
dri2_query_cookie = xcb_dri2_query_version (scrn->conn, XCB_DRI2_MAJOR_VERSION, XCB_DRI2_MINOR_VERSION);
dri2_query_cookie = xcb_dri2_query_version (scrn->conn,
XCB_DRI2_MAJOR_VERSION,
XCB_DRI2_MINOR_VERSION);
dri2_query = xcb_dri2_query_version_reply (scrn->conn, dri2_query_cookie, &error);
if (dri2_query == NULL || error != NULL || dri2_query->minor_version < 2)
goto free_query;
@ -352,7 +362,7 @@ vl_screen_create(Display *display, int screen)
{
char *prime = getenv("DRI_PRIME");
if (prime) {
unsigned int primeid;
unsigned primeid;
errno = 0;
primeid = strtoul(prime, NULL, 0);
if (errno == 0)
@ -362,9 +372,12 @@ vl_screen_create(Display *display, int screen)
}
#endif
connect_cookie = xcb_dri2_connect_unchecked(scrn->conn, get_xcb_screen(s, screen)->root, driverType);
connect_cookie = xcb_dri2_connect_unchecked(scrn->conn,
get_xcb_screen(s, screen)->root,
driverType);
connect = xcb_dri2_connect_reply(scrn->conn, connect_cookie, NULL);
if (connect == NULL || connect->driver_name_length + connect->device_name_length == 0)
if (connect == NULL ||
connect->driver_name_length + connect->device_name_length == 0)
goto free_connect;
device_name_length = xcb_dri2_connect_device_name_length(connect);
@ -381,22 +394,26 @@ vl_screen_create(Display *display, int screen)
if (drmGetMagic(fd, &magic))
goto free_connect;
authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn, get_xcb_screen(s, screen)->root, magic);
authenticate_cookie = xcb_dri2_authenticate_unchecked(scrn->conn,
get_xcb_screen(s, screen)->root,
magic);
authenticate = xcb_dri2_authenticate_reply(scrn->conn, authenticate_cookie, NULL);
if (authenticate == NULL || !authenticate->authenticated)
goto free_authenticate;
#if GALLIUM_STATIC_TARGETS
scrn->base.pscreen = dd_create_screen(fd);
#else
if (pipe_loader_drm_probe_fd(&scrn->base.dev, fd))
scrn->base.pscreen = pipe_loader_create_screen(scrn->base.dev, PIPE_SEARCH_DIR);
#endif // GALLIUM_STATIC_TARGETS
if (pipe_loader_drm_probe_fd(&scrn->base.dev, dup(fd)))
scrn->base.pscreen = pipe_loader_create_screen(scrn->base.dev);
if (!scrn->base.pscreen)
goto release_pipe;
scrn->base.destroy = vl_dri2_screen_destroy;
scrn->base.texture_from_drawable = vl_dri2_screen_texture_from_drawable;
scrn->base.get_dirty_area = vl_dri2_screen_get_dirty_area;
scrn->base.get_timestamp = vl_dri2_screen_get_timestamp;
scrn->base.set_next_timestamp = vl_dri2_screen_set_next_timestamp;
scrn->base.get_private = vl_dri2_screen_get_private;
scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
vl_compositor_reset_dirty_area(&scrn->dirty_areas[0]);
vl_compositor_reset_dirty_area(&scrn->dirty_areas[1]);
@ -409,10 +426,8 @@ vl_screen_create(Display *display, int screen)
return &scrn->base;
release_pipe:
#if !GALLIUM_STATIC_TARGETS
if (scrn->base.dev)
pipe_loader_release(&scrn->base.dev, 1);
#endif // !GALLIUM_STATIC_TARGETS
free_authenticate:
free(authenticate);
free_connect:
@ -426,9 +441,10 @@ free_screen:
return NULL;
}
void vl_screen_destroy(struct vl_screen *vscreen)
static void
vl_dri2_screen_destroy(struct vl_screen *vscreen)
{
struct vl_dri_screen *scrn = (struct vl_dri_screen*)vscreen;
struct vl_dri_screen *scrn = (struct vl_dri_screen *)vscreen;
assert(vscreen);
@ -440,8 +456,6 @@ void vl_screen_destroy(struct vl_screen *vscreen)
vl_dri2_destroy_drawable(scrn);
scrn->base.pscreen->destroy(scrn->base.pscreen);
#if !GALLIUM_STATIC_TARGETS
pipe_loader_release(&scrn->base.dev, 1);
#endif // !GALLIUM_STATIC_TARGETS
FREE(scrn);
}

View file

@ -34,7 +34,10 @@
#include "util/u_memory.h"
#include "vl/vl_winsys.h"
struct vl_screen*
static void
vl_drm_screen_destroy(struct vl_screen *vscreen);
struct vl_screen *
vl_drm_screen_create(int fd)
{
struct vl_screen *vscreen;
@ -43,35 +46,34 @@ vl_drm_screen_create(int fd)
if (!vscreen)
return NULL;
#if GALLIUM_STATIC_TARGETS
vscreen->pscreen = dd_create_screen(fd);
#else
if (pipe_loader_drm_probe_fd(&vscreen->dev, dup(fd))) {
vscreen->pscreen =
pipe_loader_create_screen(vscreen->dev, PIPE_SEARCH_DIR);
if (!vscreen->pscreen)
pipe_loader_release(&vscreen->dev, 1);
}
#endif
if (pipe_loader_drm_probe_fd(&vscreen->dev, dup(fd)))
vscreen->pscreen = pipe_loader_create_screen(vscreen->dev);
if (!vscreen->pscreen) {
FREE(vscreen);
return NULL;
}
if (!vscreen->pscreen)
goto error;
vscreen->destroy = vl_drm_screen_destroy;
vscreen->texture_from_drawable = NULL;
vscreen->get_dirty_area = NULL;
vscreen->get_timestamp = NULL;
vscreen->set_next_timestamp = NULL;
vscreen->get_private = NULL;
return vscreen;
error:
if (vscreen->dev)
pipe_loader_release(&vscreen->dev, 1);
FREE(vscreen);
return NULL;
}
void
static void
vl_drm_screen_destroy(struct vl_screen *vscreen)
{
assert(vscreen);
vscreen->pscreen->destroy(vscreen->pscreen);
#if !GALLIUM_STATIC_TARGETS
pipe_loader_release(&vscreen->dev, 1);
#endif
FREE(vscreen);
}

View file

@ -13,8 +13,8 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63914 bytes, from 2015-10-27 17:13:16)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 68291 bytes, from 2015-11-17 16:39:59)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 64038 bytes, from 2015-11-17 16:37:36)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors:

View file

@ -13,8 +13,8 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63914 bytes, from 2015-10-27 17:13:16)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 68291 bytes, from 2015-11-17 16:39:59)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 64038 bytes, from 2015-11-17 16:37:36)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors:
@ -111,10 +111,14 @@ enum a3xx_vtx_fmt {
VFMT_8_8_SNORM = 53,
VFMT_8_8_8_SNORM = 54,
VFMT_8_8_8_8_SNORM = 55,
VFMT_10_10_10_2_UINT = 60,
VFMT_10_10_10_2_UNORM = 61,
VFMT_10_10_10_2_SINT = 62,
VFMT_10_10_10_2_SNORM = 63,
VFMT_10_10_10_2_UINT = 56,
VFMT_10_10_10_2_UNORM = 57,
VFMT_10_10_10_2_SINT = 58,
VFMT_10_10_10_2_SNORM = 59,
VFMT_2_10_10_10_UINT = 60,
VFMT_2_10_10_10_UNORM = 61,
VFMT_2_10_10_10_SINT = 62,
VFMT_2_10_10_10_SNORM = 63,
};
enum a3xx_tex_fmt {
@ -138,10 +142,12 @@ enum a3xx_tex_fmt {
TFMT_DXT1 = 36,
TFMT_DXT3 = 37,
TFMT_DXT5 = 38,
TFMT_2_10_10_10_UNORM = 40,
TFMT_10_10_10_2_UNORM = 41,
TFMT_9_9_9_E5_FLOAT = 42,
TFMT_11_11_10_FLOAT = 43,
TFMT_A8_UNORM = 44,
TFMT_L8_UNORM = 45,
TFMT_L8_A8_UNORM = 47,
TFMT_8_UNORM = 48,
TFMT_8_8_UNORM = 49,
@ -183,6 +189,8 @@ enum a3xx_tex_fmt {
TFMT_32_SINT = 92,
TFMT_32_32_SINT = 93,
TFMT_32_32_32_32_SINT = 95,
TFMT_2_10_10_10_UINT = 96,
TFMT_10_10_10_2_UINT = 97,
TFMT_ETC2_RG11_SNORM = 112,
TFMT_ETC2_RG11_UNORM = 113,
TFMT_ETC2_R11_SNORM = 114,
@ -215,6 +223,9 @@ enum a3xx_color_fmt {
RB_R8_UINT = 14,
RB_R8_SINT = 15,
RB_R10G10B10A2_UNORM = 16,
RB_A2R10G10B10_UNORM = 17,
RB_R10G10B10A2_UINT = 18,
RB_A2R10G10B10_UINT = 19,
RB_A8_UNORM = 20,
RB_R8_UNORM = 21,
RB_R16_FLOAT = 24,
@ -251,25 +262,6 @@ enum a3xx_sp_perfcounter_select {
SP_ALU_ACTIVE_CYCLES = 29,
};
enum a3xx_rop_code {
ROP_CLEAR = 0,
ROP_NOR = 1,
ROP_AND_INVERTED = 2,
ROP_COPY_INVERTED = 3,
ROP_AND_REVERSE = 4,
ROP_INVERT = 5,
ROP_XOR = 6,
ROP_NAND = 7,
ROP_AND = 8,
ROP_EQUIV = 9,
ROP_NOOP = 10,
ROP_OR_INVERTED = 11,
ROP_COPY = 12,
ROP_OR_REVERSE = 13,
ROP_OR = 14,
ROP_SET = 15,
};
enum a3xx_rb_blend_opcode {
BLEND_DST_PLUS_SRC = 0,
BLEND_SRC_MINUS_DST = 1,
@ -1620,12 +1612,24 @@ static inline uint32_t A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(uint32_t val)
}
#define REG_A3XX_VFD_CONTROL_1 0x00002241
#define A3XX_VFD_CONTROL_1_MAXSTORAGE__MASK 0x0000ffff
#define A3XX_VFD_CONTROL_1_MAXSTORAGE__MASK 0x0000000f
#define A3XX_VFD_CONTROL_1_MAXSTORAGE__SHIFT 0
static inline uint32_t A3XX_VFD_CONTROL_1_MAXSTORAGE(uint32_t val)
{
return ((val) << A3XX_VFD_CONTROL_1_MAXSTORAGE__SHIFT) & A3XX_VFD_CONTROL_1_MAXSTORAGE__MASK;
}
#define A3XX_VFD_CONTROL_1_MAXTHRESHOLD__MASK 0x000000f0
#define A3XX_VFD_CONTROL_1_MAXTHRESHOLD__SHIFT 4
static inline uint32_t A3XX_VFD_CONTROL_1_MAXTHRESHOLD(uint32_t val)
{
return ((val) << A3XX_VFD_CONTROL_1_MAXTHRESHOLD__SHIFT) & A3XX_VFD_CONTROL_1_MAXTHRESHOLD__MASK;
}
#define A3XX_VFD_CONTROL_1_MINTHRESHOLD__MASK 0x00000f00
#define A3XX_VFD_CONTROL_1_MINTHRESHOLD__SHIFT 8
static inline uint32_t A3XX_VFD_CONTROL_1_MINTHRESHOLD(uint32_t val)
{
return ((val) << A3XX_VFD_CONTROL_1_MINTHRESHOLD__SHIFT) & A3XX_VFD_CONTROL_1_MINTHRESHOLD__MASK;
}
#define A3XX_VFD_CONTROL_1_REGID4VTX__MASK 0x00ff0000
#define A3XX_VFD_CONTROL_1_REGID4VTX__SHIFT 16
static inline uint32_t A3XX_VFD_CONTROL_1_REGID4VTX(uint32_t val)

View file

@ -81,7 +81,9 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
info->restart_index : 0xffffffff);
/* points + psize -> spritelist: */
if (ctx->rasterizer->point_size_per_vertex &&
fd3_emit_get_vp(emit)->writes_psize &&
(info->mode == PIPE_PRIM_POINTS))
primtype = DI_PT_POINTLIST_PSIZE;

View file

@ -209,13 +209,19 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
fd3_pipe_sampler_view(tex->textures[i]) :
&dummy_view;
struct fd_resource *rsc = fd_resource(view->base.texture);
unsigned start = fd_sampler_first_level(&view->base);
unsigned end = fd_sampler_last_level(&view->base);;
if (rsc && rsc->base.b.target == PIPE_BUFFER) {
OUT_RELOC(ring, rsc->bo, view->base.u.buf.first_element *
util_format_get_blocksize(view->base.format), 0, 0);
j = 1;
} else {
unsigned start = fd_sampler_first_level(&view->base);
unsigned end = fd_sampler_last_level(&view->base);;
for (j = 0; j < (end - start + 1); j++) {
struct fd_resource_slice *slice =
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);
OUT_RELOC(ring, rsc->bo, slice->offset, 0, 0);
}
}
/* pad the remaining entries w/ null: */
@ -350,7 +356,10 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
unsigned instance_regid = regid(63, 0);
unsigned vtxcnt_regid = regid(63, 0);
/* Note that sysvals come *after* normal inputs: */
for (i = 0; i < vp->inputs_count; i++) {
if (!vp->inputs[i].compmask)
continue;
if (vp->inputs[i].sysval) {
switch(vp->inputs[i].slot) {
case SYSTEM_VALUE_BASE_VERTEX:
@ -369,18 +378,11 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
unreachable("invalid system value");
break;
}
} else if (i < vtx->vtx->num_elements && vp->inputs[i].compmask) {
} else if (i < vtx->vtx->num_elements) {
last = i;
}
}
/* hw doesn't like to be configured for zero vbo's, it seems: */
if ((vtx->vtx->num_elements == 0) &&
(vertex_regid == regid(63, 0)) &&
(instance_regid == regid(63, 0)) &&
(vtxcnt_regid == regid(63, 0)))
return;
for (i = 0, j = 0; i <= last; i++) {
assert(!vp->inputs[i].sysval);
if (vp->inputs[i].compmask) {
@ -424,6 +426,38 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
}
}
/* hw doesn't like to be configured for zero vbo's, it seems: */
if (last < 0) {
/* just recycle the shader bo, we just need to point to *something*
* valid:
*/
struct fd_bo *dummy_vbo = vp->bo;
bool switchnext = (vertex_regid != regid(63, 0)) ||
(instance_regid != regid(63, 0)) ||
(vtxcnt_regid != regid(63, 0));
OUT_PKT0(ring, REG_A3XX_VFD_FETCH(0), 2);
OUT_RING(ring, A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(0) |
A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(0) |
COND(switchnext, A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT) |
A3XX_VFD_FETCH_INSTR_0_INDEXCODE(0) |
A3XX_VFD_FETCH_INSTR_0_STEPRATE(1));
OUT_RELOC(ring, dummy_vbo, 0, 0, 0);
OUT_PKT0(ring, REG_A3XX_VFD_DECODE_INSTR(0), 1);
OUT_RING(ring, A3XX_VFD_DECODE_INSTR_CONSTFILL |
A3XX_VFD_DECODE_INSTR_WRITEMASK(0x1) |
A3XX_VFD_DECODE_INSTR_FORMAT(VFMT_8_UNORM) |
A3XX_VFD_DECODE_INSTR_SWAP(XYZW) |
A3XX_VFD_DECODE_INSTR_REGID(regid(0,0)) |
A3XX_VFD_DECODE_INSTR_SHIFTCNT(1) |
A3XX_VFD_DECODE_INSTR_LASTCOMPVALID |
COND(switchnext, A3XX_VFD_DECODE_INSTR_SWITCHNEXT));
total_in = 1;
j = 1;
}
OUT_PKT0(ring, REG_A3XX_VFD_CONTROL_0, 2);
OUT_RING(ring, A3XX_VFD_CONTROL_0_TOTALATTRTOVS(total_in) |
A3XX_VFD_CONTROL_0_PACKETSIZE(2) |

View file

@ -188,9 +188,13 @@ static struct fd3_format formats[PIPE_FORMAT_COUNT] = {
VT(B10G10R10A2_UNORM, 10_10_10_2_UNORM, R10G10B10A2_UNORM, WXYZ),
_T(B10G10R10X2_UNORM, 10_10_10_2_UNORM, R10G10B10A2_UNORM, WXYZ),
V_(R10G10B10A2_SNORM, 10_10_10_2_SNORM, NONE, WZYX),
V_(B10G10R10A2_SNORM, 10_10_10_2_SNORM, NONE, WXYZ),
V_(R10G10B10A2_UINT, 10_10_10_2_UINT, NONE, WZYX),
V_(B10G10R10A2_UINT, 10_10_10_2_UINT, NONE, WXYZ),
V_(R10G10B10A2_USCALED, 10_10_10_2_UINT, NONE, WZYX),
V_(B10G10R10A2_USCALED, 10_10_10_2_UINT, NONE, WXYZ),
V_(R10G10B10A2_SSCALED, 10_10_10_2_SINT, NONE, WZYX),
V_(B10G10R10A2_SSCALED, 10_10_10_2_SINT, NONE, WXYZ),
_T(R11G11B10_FLOAT, 11_11_10_FLOAT, R11G11B10_FLOAT, WZYX),
_T(R9G9B9E5_FLOAT, 9_9_9_E5_FLOAT, NONE, WZYX),
@ -271,6 +275,16 @@ static struct fd3_format formats[PIPE_FORMAT_COUNT] = {
_T(DXT3_SRGBA, DXT3, NONE, WZYX),
_T(DXT5_RGBA, DXT5, NONE, WZYX),
_T(DXT5_SRGBA, DXT5, NONE, WZYX),
/* faked */
_T(RGTC1_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
_T(RGTC1_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
_T(RGTC2_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
_T(RGTC2_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
_T(LATC1_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
_T(LATC1_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
_T(LATC2_UNORM, 8_8_8_8_UNORM, NONE, WZYX),
_T(LATC2_SNORM, 8_8_8_8_SNORM, NONE, WZYX),
};
enum a3xx_vtx_fmt
@ -310,6 +324,8 @@ fd3_pipe2fetchsize(enum pipe_format format)
{
if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
format = PIPE_FORMAT_Z32_FLOAT;
else if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
format = PIPE_FORMAT_R8G8B8A8_UNORM;
switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) {
case 8: return TFETCH_1_BYTE;
case 16: return TFETCH_2_BYTE;
@ -324,6 +340,14 @@ fd3_pipe2fetchsize(enum pipe_format format)
}
}
unsigned
fd3_pipe2nblocksx(enum pipe_format format, unsigned width)
{
if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
format = PIPE_FORMAT_R8G8B8A8_UNORM;
return util_format_get_nblocksx(format, width);
}
/* we need to special case a bit the depth/stencil restore, because we are
* using the texture sampler to blit into the depth/stencil buffer, *not*
* into a color buffer. Otherwise fd3_tex_swiz() will do the wrong thing,

View file

@ -37,6 +37,7 @@ enum a3xx_color_fmt fd3_pipe2color(enum pipe_format format);
enum pipe_format fd3_gmem_restore_format(enum pipe_format format);
enum a3xx_color_fmt fd3_fs_output_format(enum pipe_format format);
enum a3xx_color_swap fd3_pipe2swap(enum pipe_format format);
unsigned fd3_pipe2nblocksx(enum pipe_format format, unsigned width);
uint32_t fd3_tex_swiz(enum pipe_format format, unsigned swizzle_r,
unsigned swizzle_g, unsigned swizzle_b, unsigned swizzle_a);

View file

@ -211,8 +211,7 @@ 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 lvl = fd_sampler_first_level(cso);
unsigned miplevels = fd_sampler_last_level(cso) - lvl;
unsigned lvl;
uint32_t sz2 = 0;
if (!so)
@ -227,20 +226,34 @@ fd3_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
so->texconst0 =
A3XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) |
A3XX_TEX_CONST_0_FMT(fd3_pipe2tex(cso->format)) |
A3XX_TEX_CONST_0_MIPLVLS(miplevels) |
fd3_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
cso->swizzle_b, cso->swizzle_a);
if (util_format_is_srgb(cso->format))
so->texconst0 |= A3XX_TEX_CONST_0_SRGB;
so->texconst1 =
if (prsc->target == PIPE_BUFFER) {
lvl = 0;
so->texconst1 =
A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
A3XX_TEX_CONST_1_WIDTH(cso->u.buf.last_element -
cso->u.buf.first_element + 1) |
A3XX_TEX_CONST_1_HEIGHT(1);
} else {
unsigned miplevels;
lvl = fd_sampler_first_level(cso);
miplevels = fd_sampler_last_level(cso) - lvl;
so->texconst0 |= A3XX_TEX_CONST_0_MIPLVLS(miplevels);
so->texconst1 =
A3XX_TEX_CONST_1_FETCHSIZE(fd3_pipe2fetchsize(cso->format)) |
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(util_format_get_nblocksx(cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
A3XX_TEX_CONST_2_PITCH(fd3_pipe2nblocksx(cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
switch (prsc->target) {
case PIPE_TEXTURE_1D_ARRAY:
case PIPE_TEXTURE_2D_ARRAY:

View file

@ -13,8 +13,8 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63914 bytes, from 2015-10-27 17:13:16)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 68291 bytes, from 2015-11-17 16:39:59)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 64038 bytes, from 2015-11-17 16:37:36)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors:
@ -47,11 +47,13 @@ enum a4xx_color_fmt {
RB4_R8_UNORM = 2,
RB4_R4G4B4A4_UNORM = 8,
RB4_R5G5B5A1_UNORM = 10,
RB4_R5G6R5_UNORM = 14,
RB4_R5G6B5_UNORM = 14,
RB4_R8G8_UNORM = 15,
RB4_R8G8_SNORM = 16,
RB4_R8G8_UINT = 17,
RB4_R8G8_SINT = 18,
RB4_R16_UNORM = 19,
RB4_R16_SNORM = 20,
RB4_R16_FLOAT = 21,
RB4_R16_UINT = 22,
RB4_R16_SINT = 23,
@ -63,12 +65,16 @@ enum a4xx_color_fmt {
RB4_R10G10B10A2_UNORM = 31,
RB4_R10G10B10A2_UINT = 34,
RB4_R11G11B10_FLOAT = 39,
RB4_R16G16_UNORM = 40,
RB4_R16G16_SNORM = 41,
RB4_R16G16_FLOAT = 42,
RB4_R16G16_UINT = 43,
RB4_R16G16_SINT = 44,
RB4_R32_FLOAT = 45,
RB4_R32_UINT = 46,
RB4_R32_SINT = 47,
RB4_R16G16B16A16_UNORM = 52,
RB4_R16G16B16A16_SNORM = 53,
RB4_R16G16B16A16_FLOAT = 54,
RB4_R16G16B16A16_UINT = 55,
RB4_R16G16B16A16_SINT = 56,
@ -106,6 +112,7 @@ enum a4xx_vtx_fmt {
VFMT4_32_32_FIXED = 10,
VFMT4_32_32_32_FIXED = 11,
VFMT4_32_32_32_32_FIXED = 12,
VFMT4_11_11_10_FLOAT = 13,
VFMT4_16_SINT = 16,
VFMT4_16_16_SINT = 17,
VFMT4_16_16_16_SINT = 18,
@ -146,18 +153,19 @@ enum a4xx_vtx_fmt {
VFMT4_8_8_SNORM = 53,
VFMT4_8_8_8_SNORM = 54,
VFMT4_8_8_8_8_SNORM = 55,
VFMT4_10_10_10_2_UINT = 60,
VFMT4_10_10_10_2_UNORM = 61,
VFMT4_10_10_10_2_SINT = 62,
VFMT4_10_10_10_2_SNORM = 63,
VFMT4_10_10_10_2_UINT = 56,
VFMT4_10_10_10_2_UNORM = 57,
VFMT4_10_10_10_2_SINT = 58,
VFMT4_10_10_10_2_SNORM = 59,
};
enum a4xx_tex_fmt {
TFMT4_5_6_5_UNORM = 11,
TFMT4_5_5_5_1_UNORM = 10,
TFMT4_5_5_5_1_UNORM = 9,
TFMT4_4_4_4_4_UNORM = 8,
TFMT4_X8Z24_UNORM = 71,
TFMT4_10_10_10_2_UNORM = 33,
TFMT4_10_10_10_2_UINT = 34,
TFMT4_A8_UNORM = 3,
TFMT4_L8_A8_UNORM = 13,
TFMT4_8_UNORM = 4,
@ -172,6 +180,12 @@ enum a4xx_tex_fmt {
TFMT4_8_SINT = 7,
TFMT4_8_8_SINT = 17,
TFMT4_8_8_8_8_SINT = 31,
TFMT4_16_UNORM = 18,
TFMT4_16_16_UNORM = 38,
TFMT4_16_16_16_16_UNORM = 51,
TFMT4_16_SNORM = 19,
TFMT4_16_16_SNORM = 39,
TFMT4_16_16_16_16_SNORM = 52,
TFMT4_16_UINT = 21,
TFMT4_16_16_UINT = 41,
TFMT4_16_16_16_16_UINT = 54,
@ -190,8 +204,21 @@ enum a4xx_tex_fmt {
TFMT4_32_FLOAT = 43,
TFMT4_32_32_FLOAT = 56,
TFMT4_32_32_32_32_FLOAT = 63,
TFMT4_32_32_32_FLOAT = 59,
TFMT4_32_32_32_UINT = 60,
TFMT4_32_32_32_SINT = 61,
TFMT4_9_9_9_E5_FLOAT = 32,
TFMT4_11_11_10_FLOAT = 37,
TFMT4_DXT1 = 86,
TFMT4_DXT3 = 87,
TFMT4_DXT5 = 88,
TFMT4_RGTC1_UNORM = 90,
TFMT4_RGTC1_SNORM = 91,
TFMT4_RGTC2_UNORM = 94,
TFMT4_RGTC2_SNORM = 95,
TFMT4_BPTC_UFLOAT = 97,
TFMT4_BPTC_FLOAT = 98,
TFMT4_BPTC = 99,
TFMT4_ATC_RGB = 100,
TFMT4_ATC_RGBA_EXPLICIT = 101,
TFMT4_ATC_RGBA_INTERPOLATED = 102,
@ -400,8 +427,13 @@ static inline uint32_t REG_A4XX_RB_MRT_CONTROL(uint32_t i0) { return 0x000020a4
#define A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE 0x00000008
#define A4XX_RB_MRT_CONTROL_BLEND 0x00000010
#define A4XX_RB_MRT_CONTROL_BLEND2 0x00000020
#define A4XX_RB_MRT_CONTROL_FASTCLEAR 0x00000400
#define A4XX_RB_MRT_CONTROL_B11 0x00000800
#define A4XX_RB_MRT_CONTROL_ROP_ENABLE 0x00000040
#define A4XX_RB_MRT_CONTROL_ROP_CODE__MASK 0x00000f00
#define A4XX_RB_MRT_CONTROL_ROP_CODE__SHIFT 8
static inline uint32_t A4XX_RB_MRT_CONTROL_ROP_CODE(enum a3xx_rop_code val)
{
return ((val) << A4XX_RB_MRT_CONTROL_ROP_CODE__SHIFT) & A4XX_RB_MRT_CONTROL_ROP_CODE__MASK;
}
#define A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK 0x0f000000
#define A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__SHIFT 24
static inline uint32_t A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(uint32_t val)
@ -600,7 +632,7 @@ static inline uint32_t A4XX_RB_FS_OUTPUT_ENABLE_BLEND(uint32_t val)
{
return ((val) << A4XX_RB_FS_OUTPUT_ENABLE_BLEND__SHIFT) & A4XX_RB_FS_OUTPUT_ENABLE_BLEND__MASK;
}
#define A4XX_RB_FS_OUTPUT_FAST_CLEAR 0x00000100
#define A4XX_RB_FS_OUTPUT_INDEPENDENT_BLEND 0x00000100
#define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__MASK 0xffff0000
#define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__SHIFT 16
static inline uint32_t A4XX_RB_FS_OUTPUT_SAMPLE_MASK(uint32_t val)
@ -2056,6 +2088,8 @@ static inline uint32_t A4XX_TPL1_TP_TEX_COUNT_GS(uint32_t val)
#define REG_A4XX_GRAS_PERFCTR_TSE_SEL_3 0x00000c8b
#define REG_A4XX_GRAS_CL_CLIP_CNTL 0x00002000
#define A4XX_GRAS_CL_CLIP_CNTL_CLIP_DISABLE 0x00008000
#define A4XX_GRAS_CL_CLIP_CNTL_ZERO_GB_SCALE_Z 0x00400000
#define REG_A4XX_GRAS_CLEAR_CNTL 0x00002003
#define A4XX_GRAS_CLEAR_CNTL_NOT_FASTCLEAR 0x00000001
@ -2596,7 +2630,20 @@ static inline uint32_t A4XX_PC_PRIM_VTX_CNTL_VAROUT(uint32_t val)
#define A4XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST 0x02000000
#define A4XX_PC_PRIM_VTX_CNTL_PSIZE 0x04000000
#define REG_A4XX_UNKNOWN_21C5 0x000021c5
#define REG_A4XX_PC_PRIM_VTX_CNTL2 0x000021c5
#define A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_FRONT_PTYPE__MASK 0x00000007
#define A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_FRONT_PTYPE__SHIFT 0
static inline uint32_t A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_FRONT_PTYPE(enum adreno_pa_su_sc_draw val)
{
return ((val) << A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_FRONT_PTYPE__SHIFT) & A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_FRONT_PTYPE__MASK;
}
#define A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_BACK_PTYPE__MASK 0x00000038
#define A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_BACK_PTYPE__SHIFT 3
static inline uint32_t A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_BACK_PTYPE(enum adreno_pa_su_sc_draw val)
{
return ((val) << A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_BACK_PTYPE__SHIFT) & A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_BACK_PTYPE__MASK;
}
#define A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_ENABLE 0x00000040
#define REG_A4XX_PC_RESTART_INDEX 0x000021c6
@ -2738,6 +2785,12 @@ static inline uint32_t A4XX_TEX_SAMP_0_ANISO(enum a4xx_tex_aniso val)
{
return ((val) << A4XX_TEX_SAMP_0_ANISO__SHIFT) & A4XX_TEX_SAMP_0_ANISO__MASK;
}
#define A4XX_TEX_SAMP_0_LOD_BIAS__MASK 0xfff80000
#define A4XX_TEX_SAMP_0_LOD_BIAS__SHIFT 19
static inline uint32_t A4XX_TEX_SAMP_0_LOD_BIAS(float val)
{
return ((((int32_t)(val * 256.0))) << A4XX_TEX_SAMP_0_LOD_BIAS__SHIFT) & A4XX_TEX_SAMP_0_LOD_BIAS__MASK;
}
#define REG_A4XX_TEX_SAMP_1 0x00000001
#define A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK 0x0000000e
@ -2746,6 +2799,7 @@ static inline uint32_t A4XX_TEX_SAMP_1_COMPARE_FUNC(enum adreno_compare_func val
{
return ((val) << A4XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT) & A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK;
}
#define A4XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF 0x00000010
#define A4XX_TEX_SAMP_1_UNNORM_COORDS 0x00000020
#define A4XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR 0x00000040
#define A4XX_TEX_SAMP_1_MAX_LOD__MASK 0x000fff00
@ -2814,7 +2868,7 @@ static inline uint32_t A4XX_TEX_CONST_1_HEIGHT(uint32_t val)
{
return ((val) << A4XX_TEX_CONST_1_HEIGHT__SHIFT) & A4XX_TEX_CONST_1_HEIGHT__MASK;
}
#define A4XX_TEX_CONST_1_WIDTH__MASK 0x1fff8000
#define A4XX_TEX_CONST_1_WIDTH__MASK 0x3fff8000
#define A4XX_TEX_CONST_1_WIDTH__SHIFT 15
static inline uint32_t A4XX_TEX_CONST_1_WIDTH(uint32_t val)
{

View file

@ -27,6 +27,7 @@
*/
#include "pipe/p_state.h"
#include "util/u_blend.h"
#include "util/u_string.h"
#include "util/u_memory.h"
@ -59,12 +60,12 @@ fd4_blend_state_create(struct pipe_context *pctx,
const struct pipe_blend_state *cso)
{
struct fd4_blend_stateobj *so;
// enum a3xx_rop_code rop = ROP_COPY;
enum a3xx_rop_code rop = ROP_COPY;
bool reads_dest = false;
unsigned i, mrt_blend = 0;
if (cso->logicop_enable) {
// rop = cso->logicop_func; /* maps 1:1 */
rop = cso->logicop_func; /* maps 1:1 */
switch (cso->logicop_func) {
case PIPE_LOGICOP_NOR:
@ -98,16 +99,25 @@ fd4_blend_state_create(struct pipe_context *pctx,
else
rt = &cso->rt[0];
so->rb_mrt[i].blend_control =
so->rb_mrt[i].blend_control_rgb =
A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(rt->rgb_src_factor)) |
A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor)) |
A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(rt->rgb_dst_factor));
so->rb_mrt[i].blend_control_alpha =
A4XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(fd_blend_factor(rt->alpha_src_factor)) |
A4XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(blend_func(rt->alpha_func)) |
A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(fd_blend_factor(rt->alpha_dst_factor));
so->rb_mrt[i].blend_control_no_alpha_rgb =
A4XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_src_factor))) |
A4XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(blend_func(rt->rgb_func)) |
A4XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(fd_blend_factor(util_blend_dst_alpha_to_one(rt->rgb_dst_factor)));
so->rb_mrt[i].control =
0xc00 | /* XXX ROP_CODE ?? */
A4XX_RB_MRT_CONTROL_ROP_CODE(rop) |
COND(cso->logicop_enable, A4XX_RB_MRT_CONTROL_ROP_ENABLE) |
A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(rt->colormask);
if (rt->blend_enable) {
@ -118,14 +128,17 @@ fd4_blend_state_create(struct pipe_context *pctx,
mrt_blend |= (1 << i);
}
if (reads_dest)
if (reads_dest) {
so->rb_mrt[i].control |= A4XX_RB_MRT_CONTROL_READ_DEST_ENABLE;
mrt_blend |= (1 << i);
}
if (cso->dither)
so->rb_mrt[i].buf_info |= A4XX_RB_MRT_BUF_INFO_DITHER_MODE(DITHER_ALWAYS);
}
so->rb_fs_output = A4XX_RB_FS_OUTPUT_ENABLE_BLEND(mrt_blend);
so->rb_fs_output = A4XX_RB_FS_OUTPUT_ENABLE_BLEND(mrt_blend) |
COND(cso->independent_blend_enable, A4XX_RB_FS_OUTPUT_INDEPENDENT_BLEND);
return so;
}

View file

@ -39,7 +39,12 @@ struct fd4_blend_stateobj {
struct {
uint32_t control;
uint32_t buf_info;
uint32_t blend_control;
/* Blend control bits for color if there is an alpha channel */
uint32_t blend_control_rgb;
/* Blend control bits for color if there is no alpha channel */
uint32_t blend_control_no_alpha_rgb;
/* Blend control bits for alpha channel */
uint32_t blend_control_alpha;
} rb_mrt[A4XX_MAX_RENDER_TARGETS];
uint32_t rb_fs_output;
};

View file

@ -47,6 +47,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
struct fd4_emit *emit)
{
const struct pipe_draw_info *info = emit->info;
enum pc_di_primtype primtype = ctx->primtypes[info->mode];
if (!(fd4_emit_get_vp(emit) && fd4_emit_get_fp(emit)))
return;
@ -64,7 +65,14 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
info->restart_index : 0xffffffff);
/* points + psize -> spritelist: */
if (ctx->rasterizer->point_size_per_vertex &&
fd4_emit_get_vp(emit)->writes_psize &&
(info->mode == PIPE_PRIM_POINTS))
primtype = DI_PT_POINTLIST_PSIZE;
fd4_draw_emit(ctx, ring,
primtype,
emit->key.binning_pass ? IGNORE_VISIBILITY : USE_VISIBILITY,
info);
}
@ -263,8 +271,7 @@ fd4_clear(struct fd_context *ctx, unsigned buffers,
mrt_comp[i] = (buffers & (PIPE_CLEAR_COLOR0 << i)) ? 0xf : 0x0;
OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
OUT_RING(ring, A4XX_RB_MRT_CONTROL_FASTCLEAR |
A4XX_RB_MRT_CONTROL_B11 |
OUT_RING(ring, A4XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY) |
A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);

View file

@ -101,12 +101,12 @@ fd4_size2indextype(unsigned index_size)
}
static inline void
fd4_draw_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
enum pc_di_primtype primtype,
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_primtype primtype = ctx->primtypes[info->mode];
enum a4xx_index_size idx_type;
enum pc_di_src_sel src_sel;
uint32_t idx_size, idx_offset;
@ -127,11 +127,6 @@ fd4_draw_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
src_sel = DI_SRC_SEL_AUTO_INDEX;
}
/* points + psize -> spritelist: */
if (ctx->rasterizer && ctx->rasterizer->point_size_per_vertex &&
(info->mode == PIPE_PRIM_POINTS))
primtype = DI_PT_POINTLIST_PSIZE;
fd4_draw(ctx, ring, primtype, vismode, src_sel,
info->count, info->instance_count,
idx_type, idx_size, idx_offset, idx_bo);

View file

@ -185,7 +185,6 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
const struct fd4_pipe_sampler_view *view = tex->textures[i] ?
fd4_pipe_sampler_view(tex->textures[i]) :
&dummy_view;
unsigned start = fd_sampler_first_level(&view->base);
OUT_RING(ring, view->texconst0);
OUT_RING(ring, view->texconst1);
@ -193,8 +192,7 @@ emit_textures(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, view->texconst3);
if (view->base.texture) {
struct fd_resource *rsc = fd_resource(view->base.texture);
uint32_t offset = fd_resource_offset(rsc, start, 0);
OUT_RELOC(ring, rsc->bo, offset, view->textconst4, 0);
OUT_RELOC(ring, rsc->bo, view->offset, view->texconst4, 0);
} else {
OUT_RING(ring, 0x00000000);
}
@ -286,7 +284,8 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, unsigned nr_bufs,
PIPE_SWIZZLE_BLUE, PIPE_SWIZZLE_ALPHA));
OUT_RING(ring, A4XX_TEX_CONST_1_WIDTH(bufs[i]->width) |
A4XX_TEX_CONST_1_HEIGHT(bufs[i]->height));
OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(slice->pitch * rsc->cpp));
OUT_RING(ring, A4XX_TEX_CONST_2_PITCH(slice->pitch * rsc->cpp) |
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(format)));
OUT_RING(ring, 0x00000000);
OUT_RELOC(ring, rsc->bo, offset, 0, 0);
OUT_RING(ring, 0x00000000);
@ -332,7 +331,10 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit)
unsigned instance_regid = regid(63, 0);
unsigned vtxcnt_regid = regid(63, 0);
/* Note that sysvals come *after* normal inputs: */
for (i = 0; i < vp->inputs_count; i++) {
if (!vp->inputs[i].compmask)
continue;
if (vp->inputs[i].sysval) {
switch(vp->inputs[i].slot) {
case SYSTEM_VALUE_BASE_VERTEX:
@ -351,19 +353,11 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit)
unreachable("invalid system value");
break;
}
} else if (i < vtx->vtx->num_elements && vp->inputs[i].compmask) {
} else if (i < vtx->vtx->num_elements) {
last = i;
}
}
/* hw doesn't like to be configured for zero vbo's, it seems: */
if ((vtx->vtx->num_elements == 0) &&
(vertex_regid == regid(63, 0)) &&
(instance_regid == regid(63, 0)) &&
(vtxcnt_regid == regid(63, 0)))
return;
for (i = 0, j = 0; i <= last; i++) {
assert(!vp->inputs[i].sysval);
if (vp->inputs[i].compmask) {
@ -408,6 +402,38 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit)
}
}
/* hw doesn't like to be configured for zero vbo's, it seems: */
if (last < 0) {
/* just recycle the shader bo, we just need to point to *something*
* valid:
*/
struct fd_bo *dummy_vbo = vp->bo;
bool switchnext = (vertex_regid != regid(63, 0)) ||
(instance_regid != regid(63, 0)) ||
(vtxcnt_regid != regid(63, 0));
OUT_PKT0(ring, REG_A4XX_VFD_FETCH(0), 4);
OUT_RING(ring, A4XX_VFD_FETCH_INSTR_0_FETCHSIZE(0) |
A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(0) |
COND(switchnext, A4XX_VFD_FETCH_INSTR_0_SWITCHNEXT));
OUT_RELOC(ring, dummy_vbo, 0, 0, 0);
OUT_RING(ring, A4XX_VFD_FETCH_INSTR_2_SIZE(1));
OUT_RING(ring, A4XX_VFD_FETCH_INSTR_3_STEPRATE(1));
OUT_PKT0(ring, REG_A4XX_VFD_DECODE_INSTR(0), 1);
OUT_RING(ring, A4XX_VFD_DECODE_INSTR_CONSTFILL |
A4XX_VFD_DECODE_INSTR_WRITEMASK(0x1) |
A4XX_VFD_DECODE_INSTR_FORMAT(VFMT4_8_UNORM) |
A4XX_VFD_DECODE_INSTR_SWAP(XYZW) |
A4XX_VFD_DECODE_INSTR_REGID(regid(0,0)) |
A4XX_VFD_DECODE_INSTR_SHIFTCNT(1) |
A4XX_VFD_DECODE_INSTR_LASTCOMPVALID |
COND(switchnext, A4XX_VFD_DECODE_INSTR_SWITCHNEXT));
total_in = 1;
j = 1;
}
OUT_PKT0(ring, REG_A4XX_VFD_CONTROL_0, 5);
OUT_RING(ring, A4XX_VFD_CONTROL_0_TOTALATTRTOVS(total_in) |
0xa0000 | /* XXX */
@ -470,11 +496,16 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RINGP(ring, val, &fd4_context(ctx)->rbrc_patches);
}
if (dirty & FD_DIRTY_ZSA) {
if (dirty & (FD_DIRTY_ZSA | FD_DIRTY_FRAMEBUFFER)) {
struct fd4_zsa_stateobj *zsa = fd4_zsa_stateobj(ctx->zsa);
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
uint32_t rb_alpha_control = zsa->rb_alpha_control;
if (util_format_is_pure_integer(pipe_surface_format(pfb->cbufs[0])))
rb_alpha_control &= ~A4XX_RB_ALPHA_CONTROL_ALPHA_TEST;
OUT_PKT0(ring, REG_A4XX_RB_ALPHA_CONTROL, 1);
OUT_RING(ring, zsa->rb_alpha_control);
OUT_RING(ring, rb_alpha_control);
OUT_PKT0(ring, REG_A4XX_RB_STENCIL_CONTROL, 2);
OUT_RING(ring, zsa->rb_stencil_control);
@ -535,8 +566,9 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
*/
if (emit->info) {
const struct pipe_draw_info *info = emit->info;
uint32_t val = fd4_rasterizer_stateobj(ctx->rasterizer)
->pc_prim_vtx_cntl;
struct fd4_rasterizer_stateobj *rast =
fd4_rasterizer_stateobj(ctx->rasterizer);
uint32_t val = rast->pc_prim_vtx_cntl;
if (info->indexed && info->primitive_restart)
val |= A4XX_PC_PRIM_VTX_CNTL_PRIMITIVE_RESTART;
@ -552,7 +584,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_PKT0(ring, REG_A4XX_PC_PRIM_VTX_CNTL, 2);
OUT_RING(ring, val);
OUT_RING(ring, 0x12); /* XXX UNKNOWN_21C5 */
OUT_RING(ring, rast->pc_prim_vtx_cntl2);
}
if (dirty & FD_DIRTY_SCISSOR) {
@ -581,7 +613,7 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_RING(ring, A4XX_GRAS_CL_VPORT_ZSCALE_0(ctx->viewport.scale[2]));
}
if (dirty & FD_DIRTY_PROG) {
if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER)) {
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
fd4_program_emit(ring, emit, pfb->nr_cbufs, pfb->cbufs);
}
@ -599,11 +631,30 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
uint32_t i;
for (i = 0; i < A4XX_MAX_RENDER_TARGETS; i++) {
enum pipe_format format = pipe_surface_format(
ctx->framebuffer.cbufs[i]);
bool is_int = util_format_is_pure_integer(format);
bool has_alpha = util_format_has_alpha(format);
uint32_t control = blend->rb_mrt[i].control;
uint32_t blend_control = blend->rb_mrt[i].blend_control_alpha;
if (is_int) {
control &= A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK;
control |= A4XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY);
}
if (has_alpha) {
blend_control |= blend->rb_mrt[i].blend_control_rgb;
} else {
blend_control |= blend->rb_mrt[i].blend_control_no_alpha_rgb;
control &= ~A4XX_RB_MRT_CONTROL_BLEND2;
}
OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
OUT_RING(ring, blend->rb_mrt[i].control);
OUT_RING(ring, control);
OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);
OUT_RING(ring, blend->rb_mrt[i].blend_control);
OUT_RING(ring, blend_control);
}
OUT_PKT0(ring, REG_A4XX_RB_FS_OUTPUT, 1);
@ -611,19 +662,48 @@ fd4_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
A4XX_RB_FS_OUTPUT_SAMPLE_MASK(0xffff));
}
if (dirty & FD_DIRTY_BLEND_COLOR) {
if (dirty & (FD_DIRTY_BLEND_COLOR | FD_DIRTY_FRAMEBUFFER)) {
struct pipe_blend_color *bcolor = &ctx->blend_color;
struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
float factor = 65535.0;
int i;
for (i = 0; i < pfb->nr_cbufs; i++) {
enum pipe_format format = pipe_surface_format(pfb->cbufs[i]);
const struct util_format_description *desc =
util_format_description(format);
int j;
if (desc->is_mixed)
continue;
j = util_format_get_first_non_void_channel(format);
if (j == -1)
continue;
if (desc->channel[j].size > 8 || !desc->channel[j].normalized ||
desc->channel[j].pure_integer)
continue;
/* Just use the first unorm8/snorm8 render buffer. Can't keep
* everyone happy.
*/
if (desc->channel[j].type == UTIL_FORMAT_TYPE_SIGNED)
factor = 32767.0;
break;
}
OUT_PKT0(ring, REG_A4XX_RB_BLEND_RED, 8);
OUT_RING(ring, A4XX_RB_BLEND_RED_UINT(bcolor->color[0] * 65535.0) |
OUT_RING(ring, A4XX_RB_BLEND_RED_UINT(bcolor->color[0] * factor) |
A4XX_RB_BLEND_RED_FLOAT(bcolor->color[0]));
OUT_RING(ring, A4XX_RB_BLEND_RED_F32(bcolor->color[0]));
OUT_RING(ring, A4XX_RB_BLEND_GREEN_UINT(bcolor->color[1] * 65535.0) |
OUT_RING(ring, A4XX_RB_BLEND_GREEN_UINT(bcolor->color[1] * factor) |
A4XX_RB_BLEND_GREEN_FLOAT(bcolor->color[1]));
OUT_RING(ring, A4XX_RB_BLEND_GREEN_F32(bcolor->color[1]));
OUT_RING(ring, A4XX_RB_BLEND_BLUE_UINT(bcolor->color[2] * 65535.0) |
OUT_RING(ring, A4XX_RB_BLEND_BLUE_UINT(bcolor->color[2] * factor) |
A4XX_RB_BLEND_BLUE_FLOAT(bcolor->color[2]));
OUT_RING(ring, A4XX_RB_BLEND_BLUE_F32(bcolor->color[2]));
OUT_RING(ring, A4XX_RB_BLEND_ALPHA_UINT(bcolor->color[3] * 65535.0) |
OUT_RING(ring, A4XX_RB_BLEND_ALPHA_UINT(bcolor->color[3] * factor) |
A4XX_RB_BLEND_ALPHA_FLOAT(bcolor->color[3]));
OUT_RING(ring, A4XX_RB_BLEND_ALPHA_F32(bcolor->color[3]));
}

View file

@ -99,20 +99,26 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
_T(S8_UINT, 8_UINT, R8_UNORM, WZYX),
/* 16-bit */
V_(R16_UNORM, 16_UNORM, NONE, WZYX),
V_(R16_SNORM, 16_SNORM, NONE, WZYX),
VT(R16_UINT, 16_UINT, R16_UINT, WZYX),
VT(R16_SINT, 16_SINT, R16_SINT, WZYX),
V_(R16_USCALED, 16_UINT, NONE, WZYX),
V_(R16_SSCALED, 16_UINT, NONE, WZYX),
VT(R16_FLOAT, 16_FLOAT, R16_FLOAT,WZYX),
VT(R16_UNORM, 16_UNORM, R16_UNORM, WZYX),
VT(R16_SNORM, 16_SNORM, R16_SNORM, WZYX),
VT(R16_UINT, 16_UINT, R16_UINT, WZYX),
VT(R16_SINT, 16_SINT, R16_SINT, WZYX),
V_(R16_USCALED, 16_UINT, NONE, WZYX),
V_(R16_SSCALED, 16_UINT, NONE, WZYX),
VT(R16_FLOAT, 16_FLOAT, R16_FLOAT, WZYX),
_T(A16_UINT, 16_UINT, NONE, WZYX),
_T(A16_SINT, 16_SINT, NONE, WZYX),
_T(L16_UINT, 16_UINT, NONE, WZYX),
_T(L16_SINT, 16_SINT, NONE, WZYX),
_T(I16_UINT, 16_UINT, NONE, WZYX),
_T(I16_SINT, 16_SINT, NONE, WZYX),
_T(A16_UNORM, 16_UNORM, NONE, WZYX),
_T(A16_SNORM, 16_SNORM, NONE, WZYX),
_T(A16_UINT, 16_UINT, NONE, WZYX),
_T(A16_SINT, 16_SINT, NONE, WZYX),
_T(L16_UNORM, 16_UNORM, NONE, WZYX),
_T(L16_SNORM, 16_SNORM, NONE, WZYX),
_T(L16_UINT, 16_UINT, NONE, WZYX),
_T(L16_SINT, 16_SINT, NONE, WZYX),
_T(I16_UNORM, 16_UNORM, NONE, WZYX),
_T(I16_SNORM, 16_SNORM, NONE, WZYX),
_T(I16_UINT, 16_UINT, NONE, WZYX),
_T(I16_SINT, 16_SINT, NONE, WZYX),
VT(R8G8_UNORM, 8_8_UNORM, R8G8_UNORM, WZYX),
VT(R8G8_SNORM, 8_8_SNORM, R8G8_SNORM, WZYX),
@ -124,6 +130,7 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
_T(L8A8_UINT, 8_8_UINT, NONE, WZYX),
_T(L8A8_SINT, 8_8_SINT, NONE, WZYX),
_T(B5G6R5_UNORM, 5_6_5_UNORM, R5G6B5_UNORM, WXYZ),
_T(B5G5R5A1_UNORM, 5_5_5_1_UNORM, R5G5B5A1_UNORM, WXYZ),
_T(B5G5R5X1_UNORM, 5_5_5_1_UNORM, R5G5B5A1_UNORM, WXYZ),
_T(B4G4R4A4_UNORM, 4_4_4_4_UNORM, R4G4B4A4_UNORM, WXYZ),
@ -151,16 +158,18 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
_T(I32_UINT, 32_UINT, NONE, WZYX),
_T(I32_SINT, 32_SINT, NONE, WZYX),
V_(R16G16_UNORM, 16_16_UNORM, NONE, WZYX),
V_(R16G16_SNORM, 16_16_SNORM, NONE, WZYX),
VT(R16G16_UINT, 16_16_UINT, R16G16_UINT, WZYX),
VT(R16G16_SINT, 16_16_SINT, R16G16_SINT, WZYX),
V_(R16G16_USCALED, 16_16_UINT, NONE, WZYX),
V_(R16G16_SSCALED, 16_16_SINT, NONE, WZYX),
VT(R16G16_FLOAT, 16_16_FLOAT, R16G16_FLOAT,WZYX),
VT(R16G16_UNORM, 16_16_UNORM, R16G16_UNORM, WZYX),
VT(R16G16_SNORM, 16_16_SNORM, R16G16_SNORM, WZYX),
VT(R16G16_UINT, 16_16_UINT, R16G16_UINT, WZYX),
VT(R16G16_SINT, 16_16_SINT, R16G16_SINT, WZYX),
V_(R16G16_USCALED, 16_16_UINT, NONE, WZYX),
V_(R16G16_SSCALED, 16_16_SINT, NONE, WZYX),
VT(R16G16_FLOAT, 16_16_FLOAT, R16G16_FLOAT, WZYX),
_T(L16A16_UINT, 16_16_UINT, NONE, WZYX),
_T(L16A16_SINT, 16_16_SINT, NONE, WZYX),
_T(L16A16_UNORM, 16_16_UNORM, NONE, WZYX),
_T(L16A16_SNORM, 16_16_SNORM, NONE, WZYX),
_T(L16A16_UINT, 16_16_UINT, NONE, WZYX),
_T(L16A16_SINT, 16_16_SINT, NONE, WZYX),
VT(R8G8B8A8_UNORM, 8_8_8_8_UNORM, R8G8B8A8_UNORM, WZYX),
_T(R8G8B8X8_UNORM, 8_8_8_8_UNORM, R8G8B8A8_UNORM, WZYX),
@ -191,11 +200,15 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
VT(B10G10R10A2_UNORM, 10_10_10_2_UNORM, R10G10B10A2_UNORM, WXYZ),
_T(B10G10R10X2_UNORM, 10_10_10_2_UNORM, R10G10B10A2_UNORM, WXYZ),
V_(R10G10B10A2_SNORM, 10_10_10_2_SNORM, NONE, WZYX),
V_(R10G10B10A2_UINT, 10_10_10_2_UINT, NONE, WZYX),
V_(B10G10R10A2_SNORM, 10_10_10_2_SNORM, NONE, WXYZ),
VT(R10G10B10A2_UINT, 10_10_10_2_UINT, R10G10B10A2_UINT, WZYX),
VT(B10G10R10A2_UINT, 10_10_10_2_UINT, R10G10B10A2_UINT, WXYZ),
V_(R10G10B10A2_USCALED, 10_10_10_2_UINT, NONE, WZYX),
V_(B10G10R10A2_USCALED, 10_10_10_2_UINT, NONE, WXYZ),
V_(R10G10B10A2_SSCALED, 10_10_10_2_SINT, NONE, WZYX),
V_(B10G10R10A2_SSCALED, 10_10_10_2_SINT, NONE, WXYZ),
_T(R11G11B10_FLOAT, 11_11_10_FLOAT, R11G11B10_FLOAT, WZYX),
VT(R11G11B10_FLOAT, 11_11_10_FLOAT, R11G11B10_FLOAT, WZYX),
_T(R9G9B9E5_FLOAT, 9_9_9_E5_FLOAT, NONE, WZYX),
_T(Z24X8_UNORM, X8Z24_UNORM, R8G8B8A8_UNORM, WZYX),
@ -213,8 +226,10 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
V_(R16G16B16_FLOAT, 16_16_16_FLOAT, NONE, WZYX),
/* 64-bit */
V_(R16G16B16A16_UNORM, 16_16_16_16_UNORM, NONE, WZYX),
V_(R16G16B16A16_SNORM, 16_16_16_16_SNORM, NONE, WZYX),
VT(R16G16B16A16_UNORM, 16_16_16_16_UNORM, R16G16B16A16_UNORM, WZYX),
VT(R16G16B16X16_UNORM, 16_16_16_16_UNORM, R16G16B16A16_UNORM, WZYX),
VT(R16G16B16A16_SNORM, 16_16_16_16_SNORM, R16G16B16A16_SNORM, WZYX),
VT(R16G16B16X16_SNORM, 16_16_16_16_SNORM, R16G16B16A16_SNORM, WZYX),
VT(R16G16B16A16_UINT, 16_16_16_16_UINT, R16G16B16A16_UINT, WZYX),
_T(R16G16B16X16_UINT, 16_16_16_16_UINT, R16G16B16A16_UINT, WZYX),
VT(R16G16B16A16_SINT, 16_16_16_16_SINT, R16G16B16A16_SINT, WZYX),
@ -235,11 +250,11 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
_T(L32A32_SINT, 32_32_SINT, NONE, WZYX),
/* 96-bit */
V_(R32G32B32_UINT, 32_32_32_UINT, NONE, WZYX),
V_(R32G32B32_SINT, 32_32_32_SINT, NONE, WZYX),
VT(R32G32B32_UINT, 32_32_32_UINT, NONE, WZYX),
VT(R32G32B32_SINT, 32_32_32_SINT, NONE, WZYX),
V_(R32G32B32_USCALED, 32_32_32_UINT, NONE, WZYX),
V_(R32G32B32_SSCALED, 32_32_32_SINT, NONE, WZYX),
V_(R32G32B32_FLOAT, 32_32_32_FLOAT, NONE, WZYX),
VT(R32G32B32_FLOAT, 32_32_32_FLOAT, NONE, WZYX),
V_(R32G32B32_FIXED, 32_32_32_FIXED, NONE, WZYX),
/* 128-bit */
@ -252,6 +267,72 @@ static struct fd4_format formats[PIPE_FORMAT_COUNT] = {
VT(R32G32B32A32_FLOAT, 32_32_32_32_FLOAT, R32G32B32A32_FLOAT, WZYX),
_T(R32G32B32X32_FLOAT, 32_32_32_32_FLOAT, R32G32B32A32_FLOAT, WZYX),
V_(R32G32B32A32_FIXED, 32_32_32_32_FIXED, NONE, WZYX),
/* compressed */
_T(ETC1_RGB8, ETC1, NONE, WZYX),
_T(ETC2_RGB8, ETC2_RGB8, NONE, WZYX),
_T(ETC2_SRGB8, ETC2_RGB8, NONE, WZYX),
_T(ETC2_RGB8A1, ETC2_RGB8A1, NONE, WZYX),
_T(ETC2_SRGB8A1, ETC2_RGB8A1, NONE, WZYX),
_T(ETC2_RGBA8, ETC2_RGBA8, NONE, WZYX),
_T(ETC2_SRGBA8, ETC2_RGBA8, NONE, WZYX),
_T(ETC2_R11_UNORM, ETC2_R11_UNORM, NONE, WZYX),
_T(ETC2_R11_SNORM, ETC2_R11_SNORM, NONE, WZYX),
_T(ETC2_RG11_UNORM, ETC2_RG11_UNORM, NONE, WZYX),
_T(ETC2_RG11_SNORM, ETC2_RG11_SNORM, NONE, WZYX),
_T(DXT1_RGB, DXT1, NONE, WZYX),
_T(DXT1_SRGB, DXT1, NONE, WZYX),
_T(DXT1_RGBA, DXT1, NONE, WZYX),
_T(DXT1_SRGBA, DXT1, NONE, WZYX),
_T(DXT3_RGBA, DXT3, NONE, WZYX),
_T(DXT3_SRGBA, DXT3, NONE, WZYX),
_T(DXT5_RGBA, DXT5, NONE, WZYX),
_T(DXT5_SRGBA, DXT5, NONE, WZYX),
_T(BPTC_RGBA_UNORM, BPTC, NONE, WZYX),
_T(BPTC_SRGBA, BPTC, NONE, WZYX),
_T(BPTC_RGB_FLOAT, BPTC_FLOAT, NONE, WZYX),
_T(BPTC_RGB_UFLOAT, BPTC_UFLOAT, NONE, WZYX),
_T(RGTC1_UNORM, RGTC1_UNORM, NONE, WZYX),
_T(RGTC1_SNORM, RGTC1_SNORM, NONE, WZYX),
_T(RGTC2_UNORM, RGTC2_UNORM, NONE, WZYX),
_T(RGTC2_SNORM, RGTC2_SNORM, NONE, WZYX),
_T(LATC1_UNORM, RGTC1_UNORM, NONE, WZYX),
_T(LATC1_SNORM, RGTC1_SNORM, NONE, WZYX),
_T(LATC2_UNORM, RGTC2_UNORM, NONE, WZYX),
_T(LATC2_SNORM, RGTC2_SNORM, NONE, WZYX),
_T(ASTC_4x4, ASTC_4x4, NONE, WZYX),
_T(ASTC_5x4, ASTC_5x4, NONE, WZYX),
_T(ASTC_5x5, ASTC_5x5, NONE, WZYX),
_T(ASTC_6x5, ASTC_6x5, NONE, WZYX),
_T(ASTC_6x6, ASTC_6x6, NONE, WZYX),
_T(ASTC_8x5, ASTC_8x5, NONE, WZYX),
_T(ASTC_8x6, ASTC_8x6, NONE, WZYX),
_T(ASTC_8x8, ASTC_8x8, NONE, WZYX),
_T(ASTC_10x5, ASTC_10x5, NONE, WZYX),
_T(ASTC_10x6, ASTC_10x6, NONE, WZYX),
_T(ASTC_10x8, ASTC_10x8, NONE, WZYX),
_T(ASTC_10x10, ASTC_10x10, NONE, WZYX),
_T(ASTC_12x10, ASTC_12x10, NONE, WZYX),
_T(ASTC_12x12, ASTC_12x12, NONE, WZYX),
_T(ASTC_4x4_SRGB, ASTC_4x4, NONE, WZYX),
_T(ASTC_5x4_SRGB, ASTC_5x4, NONE, WZYX),
_T(ASTC_5x5_SRGB, ASTC_5x5, NONE, WZYX),
_T(ASTC_6x5_SRGB, ASTC_6x5, NONE, WZYX),
_T(ASTC_6x6_SRGB, ASTC_6x6, NONE, WZYX),
_T(ASTC_8x5_SRGB, ASTC_8x5, NONE, WZYX),
_T(ASTC_8x6_SRGB, ASTC_8x6, NONE, WZYX),
_T(ASTC_8x8_SRGB, ASTC_8x8, NONE, WZYX),
_T(ASTC_10x5_SRGB, ASTC_10x5, NONE, WZYX),
_T(ASTC_10x6_SRGB, ASTC_10x6, NONE, WZYX),
_T(ASTC_10x8_SRGB, ASTC_10x8, NONE, WZYX),
_T(ASTC_10x10_SRGB, ASTC_10x10, NONE, WZYX),
_T(ASTC_12x10_SRGB, ASTC_12x10, NONE, WZYX),
_T(ASTC_12x12_SRGB, ASTC_12x12, NONE, WZYX),
};
/* convert pipe format to vertex buffer format: */
@ -295,11 +376,15 @@ fd4_pipe2fetchsize(enum pipe_format format)
if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
format = PIPE_FORMAT_Z32_FLOAT;
switch (util_format_get_blocksizebits(format)) {
if (util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_ASTC)
return TFETCH4_16_BYTE;
switch (util_format_get_blocksizebits(format) / util_format_get_blockwidth(format)) {
case 8: return TFETCH4_1_BYTE;
case 16: return TFETCH4_2_BYTE;
case 32: return TFETCH4_4_BYTE;
case 64: return TFETCH4_8_BYTE;
case 96: return TFETCH4_1_BYTE; /* Does this matter? */
case 128: return TFETCH4_16_BYTE;
default:
debug_printf("Unknown block size for format %s: %d\n",

View file

@ -347,8 +347,7 @@ fd4_emit_tile_mem2gmem(struct fd_context *ctx, struct fd_tile *tile)
mrt_comp[i] = ((i < pfb->nr_cbufs) && pfb->cbufs[i]) ? 0xf : 0;
OUT_PKT0(ring, REG_A4XX_RB_MRT_CONTROL(i), 1);
OUT_RING(ring, A4XX_RB_MRT_CONTROL_FASTCLEAR |
A4XX_RB_MRT_CONTROL_B11 |
OUT_RING(ring, A4XX_RB_MRT_CONTROL_ROP_CODE(ROP_COPY) |
A4XX_RB_MRT_CONTROL_COMPONENT_ENABLE(0xf));
OUT_PKT0(ring, REG_A4XX_RB_MRT_BLEND_CONTROL(i), 1);

View file

@ -245,13 +245,6 @@ fd4_program_emit(struct fd_ringbuffer *ring, struct fd4_emit *emit,
color_regid[7] = ir3_find_output_regid(s[FS].v, FRAG_RESULT_DATA7);
}
/* adjust regids for alpha output formats. there is no alpha render
* format, so it's just treated like red
*/
for (i = 0; i < nr; i++)
if (util_format_is_alpha(pipe_surface_format(bufs[i])))
color_regid[i] += 3;
/* TODO get these dynamically: */
face_regid = s[FS].v->frag_face ? regid(0,0) : regid(63,0);
coord_regid = s[FS].v->frag_coord ? regid(0,0) : regid(63,0);

View file

@ -77,6 +77,13 @@ fd4_rasterizer_state_create(struct pipe_context *pctx,
so->gras_su_mode_control =
A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(cso->line_width/2.0);
so->pc_prim_vtx_cntl2 =
A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_FRONT_PTYPE(fd_polygon_mode(cso->fill_front)) |
A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_BACK_PTYPE(fd_polygon_mode(cso->fill_back));
if (cso->fill_front != PIPE_POLYGON_MODE_FILL ||
cso->fill_back != PIPE_POLYGON_MODE_FILL)
so->pc_prim_vtx_cntl2 |= A4XX_PC_PRIM_VTX_CNTL2_POLYMODE_ENABLE;
if (cso->cull_face & PIPE_FACE_FRONT)
so->gras_su_mode_control |= A4XX_GRAS_SU_MODE_CONTROL_CULL_FRONT;
@ -90,5 +97,10 @@ fd4_rasterizer_state_create(struct pipe_context *pctx,
if (cso->offset_tri)
so->gras_su_mode_control |= A4XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET;
if (!cso->depth_clip)
so->gras_cl_clip_cntl |= A4XX_GRAS_CL_CLIP_CNTL_CLIP_DISABLE;
if (cso->clip_halfz)
so->gras_cl_clip_cntl |= A4XX_GRAS_CL_CLIP_CNTL_ZERO_GB_SCALE_Z;
return so;
}

View file

@ -42,6 +42,7 @@ struct fd4_rasterizer_stateobj {
uint32_t gras_su_mode_control;
uint32_t gras_cl_clip_cntl;
uint32_t pc_prim_vtx_cntl;
uint32_t pc_prim_vtx_cntl2;
};
static inline struct fd4_rasterizer_stateobj *

View file

@ -57,6 +57,8 @@ fd4_screen_is_format_supported(struct pipe_screen *pscreen,
}
if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
(target == PIPE_BUFFER ||
util_format_get_blocksize(format) != 12) &&
(fd4_pipe2tex(format) != ~0)) {
retval |= PIPE_BIND_SAMPLER_VIEW;
}

View file

@ -124,9 +124,11 @@ fd4_sampler_state_create(struct pipe_context *pctx,
so->texsamp1 =
// COND(miplinear, A4XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR) |
COND(!cso->seamless_cube_map, A4XX_TEX_SAMP_1_CUBEMAPSEAMLESSFILTOFF) |
COND(!cso->normalized_coords, A4XX_TEX_SAMP_1_UNNORM_COORDS);
if (cso->min_mip_filter != PIPE_TEX_MIPFILTER_NONE) {
so->texsamp0 |= A4XX_TEX_SAMP_0_LOD_BIAS(cso->lod_bias);
so->texsamp1 |=
A4XX_TEX_SAMP_1_MIN_LOD(cso->min_lod) |
A4XX_TEX_SAMP_1_MAX_LOD(cso->max_lod);
@ -210,8 +212,8 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
{
struct fd4_pipe_sampler_view *so = CALLOC_STRUCT(fd4_pipe_sampler_view);
struct fd_resource *rsc = fd_resource(prsc);
unsigned lvl = fd_sampler_first_level(cso);
unsigned miplevels = fd_sampler_last_level(cso) - lvl;
unsigned lvl, layers;
uint32_t sz2 = 0;
if (!so)
return NULL;
@ -223,39 +225,65 @@ fd4_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
so->base.context = pctx;
so->texconst0 =
A4XX_TEX_CONST_0_TYPE(tex_type(prsc->target)) |
A4XX_TEX_CONST_0_TYPE(tex_type(cso->target)) |
A4XX_TEX_CONST_0_FMT(fd4_pipe2tex(cso->format)) |
A4XX_TEX_CONST_0_MIPLVLS(miplevels) |
fd4_tex_swiz(cso->format, cso->swizzle_r, cso->swizzle_g,
cso->swizzle_b, cso->swizzle_a);
if (util_format_is_srgb(cso->format))
so->texconst0 |= A4XX_TEX_CONST_0_SRGB;
so->texconst1 =
A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
so->texconst2 =
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
A4XX_TEX_CONST_2_PITCH(rsc->slices[lvl].pitch * rsc->cpp);
if (cso->target == PIPE_BUFFER) {
unsigned elements = cso->u.buf.last_element -
cso->u.buf.first_element + 1;
lvl = 0;
so->texconst1 =
A4XX_TEX_CONST_1_WIDTH(elements) |
A4XX_TEX_CONST_1_HEIGHT(1);
so->texconst2 =
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
A4XX_TEX_CONST_2_PITCH(elements * rsc->cpp);
so->offset = cso->u.buf.first_element *
util_format_get_blocksize(cso->format);
} else {
unsigned miplevels;
switch (prsc->target) {
lvl = fd_sampler_first_level(cso);
miplevels = fd_sampler_last_level(cso) - lvl;
layers = cso->u.tex.last_layer - cso->u.tex.first_layer + 1;
so->texconst0 |= A4XX_TEX_CONST_0_MIPLVLS(miplevels);
so->texconst1 =
A4XX_TEX_CONST_1_WIDTH(u_minify(prsc->width0, lvl)) |
A4XX_TEX_CONST_1_HEIGHT(u_minify(prsc->height0, lvl));
so->texconst2 =
A4XX_TEX_CONST_2_FETCHSIZE(fd4_pipe2fetchsize(cso->format)) |
A4XX_TEX_CONST_2_PITCH(
util_format_get_nblocksx(
cso->format, rsc->slices[lvl].pitch) * rsc->cpp);
so->offset = fd_resource_offset(rsc, lvl, cso->u.tex.first_layer);
}
switch (cso->target) {
case PIPE_TEXTURE_1D_ARRAY:
case PIPE_TEXTURE_2D_ARRAY:
so->texconst3 =
A4XX_TEX_CONST_3_DEPTH(prsc->array_size) |
A4XX_TEX_CONST_3_DEPTH(layers) |
A4XX_TEX_CONST_3_LAYERSZ(rsc->layer_size);
break;
case PIPE_TEXTURE_CUBE:
case PIPE_TEXTURE_CUBE_ARRAY:
so->texconst3 =
A4XX_TEX_CONST_3_DEPTH(prsc->array_size / 6) |
A4XX_TEX_CONST_3_DEPTH(layers / 6) |
A4XX_TEX_CONST_3_LAYERSZ(rsc->layer_size);
break;
case PIPE_TEXTURE_3D:
so->texconst3 =
A4XX_TEX_CONST_3_DEPTH(u_minify(prsc->depth0, lvl)) |
A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[0].size0);
A4XX_TEX_CONST_3_LAYERSZ(rsc->slices[lvl].size0);
while (lvl < cso->u.tex.last_level && sz2 != rsc->slices[lvl+1].size0)
sz2 = rsc->slices[++lvl].size0;
so->texconst4 = A4XX_TEX_CONST_4_LAYERSZ(sz2);
break;
default:
so->texconst3 = 0x00000000;

View file

@ -51,7 +51,8 @@ fd4_sampler_stateobj(struct pipe_sampler_state *samp)
struct fd4_pipe_sampler_view {
struct pipe_sampler_view base;
uint32_t texconst0, texconst1, texconst2, texconst3, textconst4;
uint32_t texconst0, texconst1, texconst2, texconst3, texconst4;
uint32_t offset;
};
static inline struct fd4_pipe_sampler_view *

View file

@ -13,8 +13,8 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63914 bytes, from 2015-10-27 17:13:16)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 68291 bytes, from 2015-11-17 16:39:59)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 64038 bytes, from 2015-11-17 16:37:36)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors:
@ -119,6 +119,25 @@ enum adreno_rb_copy_control_mode {
RB_COPY_DEPTH_STENCIL = 5,
};
enum a3xx_rop_code {
ROP_CLEAR = 0,
ROP_NOR = 1,
ROP_AND_INVERTED = 2,
ROP_COPY_INVERTED = 3,
ROP_AND_REVERSE = 4,
ROP_INVERT = 5,
ROP_XOR = 6,
ROP_NAND = 7,
ROP_AND = 8,
ROP_EQUIV = 9,
ROP_NOOP = 10,
ROP_OR_INVERTED = 11,
ROP_COPY = 12,
ROP_OR_REVERSE = 13,
ROP_OR = 14,
ROP_SET = 15,
};
enum a3xx_render_mode {
RB_RENDERING_PASS = 0,
RB_TILING_PASS = 1,

View file

@ -13,8 +13,8 @@ The rules-ng-ng source files this header was generated from are:
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63914 bytes, from 2015-10-27 17:13:16)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 68291 bytes, from 2015-11-17 16:39:59)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 64038 bytes, from 2015-11-17 16:37:36)
- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors:

View file

@ -359,6 +359,10 @@ struct fd_context {
struct fd_streamout_stateobj streamout;
struct pipe_clip_state ucp;
struct pipe_query *cond_query;
bool cond_cond; /* inverted rendering condition */
uint cond_mode;
/* GMEM/tile handling fxns: */
void (*emit_tile_init)(struct fd_context *ctx);
void (*emit_tile_prep)(struct fd_context *ctx, struct fd_tile *tile);

View file

@ -88,6 +88,10 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
return;
}
/* TODO: push down the region versions into the tiles */
if (!fd_render_condition_check(pctx))
return;
/* emulate unsupported primitives: */
if (!fd_supported_prim(ctx, info->mode)) {
if (ctx->streamout.num_targets > 0)
@ -220,6 +224,10 @@ fd_clear(struct pipe_context *pctx, unsigned buffers,
unsigned cleared_buffers;
int i;
/* TODO: push down the region versions into the tiles */
if (!fd_render_condition_check(pctx))
return;
/* 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

View file

@ -81,6 +81,16 @@ fd_get_query_result(struct pipe_context *pctx, struct pipe_query *pq,
return q->funcs->get_query_result(fd_context(pctx), q, wait, result);
}
static void
fd_render_condition(struct pipe_context *pctx, struct pipe_query *pq,
boolean condition, uint mode)
{
struct fd_context *ctx = fd_context(pctx);
ctx->cond_query = pq;
ctx->cond_cond = condition;
ctx->cond_mode = mode;
}
static int
fd_get_driver_query_info(struct pipe_screen *pscreen,
unsigned index, struct pipe_driver_query_info *info)
@ -118,4 +128,5 @@ fd_query_context_init(struct pipe_context *pctx)
pctx->begin_query = fd_begin_query;
pctx->end_query = fd_end_query;
pctx->get_query_result = fd_get_query_result;
pctx->render_condition = fd_render_condition;
}

View file

@ -27,6 +27,7 @@
*/
#include "util/u_format.h"
#include "util/u_format_rgtc.h"
#include "util/u_format_zs.h"
#include "util/u_inlines.h"
#include "util/u_transfer.h"
@ -111,11 +112,19 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
util_range_set_empty(&rsc->valid_buffer_range);
}
/* Currently this is only used for flushing Z32_S8 texture transfers, but
* eventually it should handle everything.
*/
static unsigned
fd_resource_layer_offset(struct fd_resource *rsc,
struct fd_resource_slice *slice,
unsigned layer)
{
if (rsc->layer_first)
return layer * rsc->layer_size;
else
return layer * slice->size0;
}
static void
fd_resource_flush(struct fd_transfer *trans, const struct pipe_box *box)
fd_resource_flush_z32s8(struct fd_transfer *trans, const struct pipe_box *box)
{
struct fd_resource *rsc = fd_resource(trans->base.resource);
struct fd_resource_slice *slice = fd_resource_slice(rsc, trans->base.level);
@ -123,13 +132,12 @@ fd_resource_flush(struct fd_transfer *trans, const struct pipe_box *box)
enum pipe_format format = trans->base.resource->format;
float *depth = fd_bo_map(rsc->bo) + slice->offset +
fd_resource_layer_offset(rsc, slice, trans->base.box.z) +
(trans->base.box.y + box->y) * slice->pitch * 4 + (trans->base.box.x + box->x) * 4;
uint8_t *stencil = fd_bo_map(rsc->stencil->bo) + sslice->offset +
fd_resource_layer_offset(rsc->stencil, sslice, trans->base.box.z) +
(trans->base.box.y + box->y) * sslice->pitch + trans->base.box.x + box->x;
assert(format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ||
format == PIPE_FORMAT_X32_S8X24_UINT);
if (format != PIPE_FORMAT_X32_S8X24_UINT)
util_format_z32_float_s8x24_uint_unpack_z_float(
depth, slice->pitch * 4,
@ -142,6 +150,73 @@ fd_resource_flush(struct fd_transfer *trans, const struct pipe_box *box)
box->width, box->height);
}
static void
fd_resource_flush_rgtc(struct fd_transfer *trans, const struct pipe_box *box)
{
struct fd_resource *rsc = fd_resource(trans->base.resource);
struct fd_resource_slice *slice = fd_resource_slice(rsc, trans->base.level);
enum pipe_format format = trans->base.resource->format;
uint8_t *data = fd_bo_map(rsc->bo) + slice->offset +
fd_resource_layer_offset(rsc, slice, trans->base.box.z) +
((trans->base.box.y + box->y) * slice->pitch +
trans->base.box.x + box->x) * rsc->cpp;
uint8_t *source = trans->staging +
util_format_get_nblocksy(format, box->y) * trans->base.stride +
util_format_get_stride(format, box->x);
switch (format) {
case PIPE_FORMAT_RGTC1_UNORM:
case PIPE_FORMAT_RGTC1_SNORM:
case PIPE_FORMAT_LATC1_UNORM:
case PIPE_FORMAT_LATC1_SNORM:
util_format_rgtc1_unorm_unpack_rgba_8unorm(
data, slice->pitch * rsc->cpp,
source, trans->base.stride,
box->width, box->height);
break;
case PIPE_FORMAT_RGTC2_UNORM:
case PIPE_FORMAT_RGTC2_SNORM:
case PIPE_FORMAT_LATC2_UNORM:
case PIPE_FORMAT_LATC2_SNORM:
util_format_rgtc2_unorm_unpack_rgba_8unorm(
data, slice->pitch * rsc->cpp,
source, trans->base.stride,
box->width, box->height);
break;
default:
assert(!"Unexpected format\n");
break;
}
}
static void
fd_resource_flush(struct fd_transfer *trans, const struct pipe_box *box)
{
enum pipe_format format = trans->base.resource->format;
switch (format) {
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
case PIPE_FORMAT_X32_S8X24_UINT:
fd_resource_flush_z32s8(trans, box);
break;
case PIPE_FORMAT_RGTC1_UNORM:
case PIPE_FORMAT_RGTC1_SNORM:
case PIPE_FORMAT_RGTC2_UNORM:
case PIPE_FORMAT_RGTC2_SNORM:
case PIPE_FORMAT_LATC1_UNORM:
case PIPE_FORMAT_LATC1_SNORM:
case PIPE_FORMAT_LATC2_UNORM:
case PIPE_FORMAT_LATC2_SNORM:
fd_resource_flush_rgtc(trans, box);
break;
default:
assert(!"Unexpected staging transfer type");
break;
}
}
static void fd_resource_transfer_flush_region(struct pipe_context *pctx,
struct pipe_transfer *ptrans,
const struct pipe_box *box)
@ -267,20 +342,15 @@ fd_resource_transfer_map(struct pipe_context *pctx,
return NULL;
}
if (rsc->layer_first) {
offset = slice->offset +
box->y / util_format_get_blockheight(format) * ptrans->stride +
box->x / util_format_get_blockwidth(format) * rsc->cpp +
box->z * rsc->layer_size;
} else {
offset = slice->offset +
box->y / util_format_get_blockheight(format) * ptrans->stride +
box->x / util_format_get_blockwidth(format) * rsc->cpp +
box->z * slice->size0;
}
offset = slice->offset +
box->y / util_format_get_blockheight(format) * ptrans->stride +
box->x / util_format_get_blockwidth(format) * rsc->cpp +
fd_resource_layer_offset(rsc, slice, box->z);
if (prsc->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ||
prsc->format == PIPE_FORMAT_X32_S8X24_UINT) {
assert(trans->base.box.depth == 1);
trans->base.stride = trans->base.box.width * rsc->cpp * 2;
trans->staging = malloc(trans->base.stride * trans->base.box.height);
if (!trans->staging)
@ -298,8 +368,10 @@ fd_resource_transfer_map(struct pipe_context *pctx,
goto fail;
float *depth = (float *)(buf + slice->offset +
fd_resource_layer_offset(rsc, slice, box->z) +
box->y * slice->pitch * 4 + box->x * 4);
uint8_t *stencil = sbuf + sslice->offset +
fd_resource_layer_offset(rsc->stencil, sslice, box->z) +
box->y * sslice->pitch + box->x;
if (format != PIPE_FORMAT_X32_S8X24_UINT)
@ -314,6 +386,54 @@ fd_resource_transfer_map(struct pipe_context *pctx,
box->width, box->height);
}
buf = trans->staging;
offset = 0;
} else if (rsc->internal_format != format &&
util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC) {
assert(trans->base.box.depth == 1);
trans->base.stride = util_format_get_stride(
format, trans->base.box.width);
trans->staging = malloc(
util_format_get_2d_size(format, trans->base.stride,
trans->base.box.height));
if (!trans->staging)
goto fail;
/* if we're not discarding the whole range (or resource), we must copy
* the real data in.
*/
if (!(usage & (PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE |
PIPE_TRANSFER_DISCARD_RANGE))) {
uint8_t *rgba8 = (uint8_t *)buf + slice->offset +
fd_resource_layer_offset(rsc, slice, box->z) +
box->y * slice->pitch * rsc->cpp + box->x * rsc->cpp;
switch (format) {
case PIPE_FORMAT_RGTC1_UNORM:
case PIPE_FORMAT_RGTC1_SNORM:
case PIPE_FORMAT_LATC1_UNORM:
case PIPE_FORMAT_LATC1_SNORM:
util_format_rgtc1_unorm_pack_rgba_8unorm(
trans->staging, trans->base.stride,
rgba8, slice->pitch * rsc->cpp,
box->width, box->height);
break;
case PIPE_FORMAT_RGTC2_UNORM:
case PIPE_FORMAT_RGTC2_SNORM:
case PIPE_FORMAT_LATC2_UNORM:
case PIPE_FORMAT_LATC2_SNORM:
util_format_rgtc2_unorm_pack_rgba_8unorm(
trans->staging, trans->base.stride,
rgba8, slice->pitch * rsc->cpp,
box->width, box->height);
break;
default:
assert(!"Unexpected format");
break;
}
}
buf = trans->staging;
offset = 0;
}
@ -361,9 +481,10 @@ static const struct u_resource_vtbl fd_resource_vtbl = {
};
static uint32_t
setup_slices(struct fd_resource *rsc, uint32_t alignment)
setup_slices(struct fd_resource *rsc, uint32_t alignment, enum pipe_format format)
{
struct pipe_resource *prsc = &rsc->base.b;
enum util_format_layout layout = util_format_description(format)->layout;
uint32_t level, size = 0;
uint32_t width = prsc->width0;
uint32_t height = prsc->height0;
@ -377,9 +498,13 @@ setup_slices(struct fd_resource *rsc, uint32_t alignment)
struct fd_resource_slice *slice = fd_resource_slice(rsc, level);
uint32_t blocks;
slice->pitch = width = align(width, 32);
if (layout == UTIL_FORMAT_LAYOUT_ASTC)
slice->pitch = width =
util_align_npot(width, 32 * util_format_get_blockwidth(format));
else
slice->pitch = width = align(width, 32);
slice->offset = size;
blocks = util_format_get_nblocks(prsc->format, width, height);
blocks = util_format_get_nblocks(format, width, height);
/* 1d array and 2d array textures must all have the same layer size
* for each miplevel on a3xx. 3d textures can have different layer
* sizes for high levels, but the hw auto-sizer is buggy (or at least
@ -430,11 +555,12 @@ fd_resource_create(struct pipe_screen *pscreen,
{
struct fd_resource *rsc = CALLOC_STRUCT(fd_resource);
struct pipe_resource *prsc = &rsc->base.b;
uint32_t size;
enum pipe_format format = tmpl->format;
uint32_t size, alignment;
DBG("target=%d, format=%s, %ux%ux%u, array_size=%u, last_level=%u, "
"nr_samples=%u, usage=%u, bind=%x, flags=%x",
tmpl->target, util_format_name(tmpl->format),
tmpl->target, util_format_name(format),
tmpl->width0, tmpl->height0, tmpl->depth0,
tmpl->array_size, tmpl->last_level, tmpl->nr_samples,
tmpl->usage, tmpl->bind, tmpl->flags);
@ -451,13 +577,18 @@ fd_resource_create(struct pipe_screen *pscreen,
util_range_init(&rsc->valid_buffer_range);
rsc->base.vtbl = &fd_resource_vtbl;
if (tmpl->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
rsc->cpp = util_format_get_blocksize(PIPE_FORMAT_Z32_FLOAT);
else
rsc->cpp = util_format_get_blocksize(tmpl->format);
if (format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT)
format = PIPE_FORMAT_Z32_FLOAT;
else if (fd_screen(pscreen)->gpu_id < 400 &&
util_format_description(format)->layout == UTIL_FORMAT_LAYOUT_RGTC)
format = PIPE_FORMAT_R8G8B8A8_UNORM;
rsc->internal_format = format;
rsc->cpp = util_format_get_blocksize(format);
assert(rsc->cpp);
alignment = slice_alignment(pscreen, tmpl);
if (is_a4xx(fd_screen(pscreen))) {
switch (tmpl->target) {
case PIPE_TEXTURE_3D:
@ -465,11 +596,12 @@ fd_resource_create(struct pipe_screen *pscreen,
break;
default:
rsc->layer_first = true;
alignment = 1;
break;
}
}
size = setup_slices(rsc, slice_alignment(pscreen, tmpl));
size = setup_slices(rsc, alignment, format);
if (rsc->layer_first) {
rsc->layer_size = align(size, 4096);
@ -548,7 +680,7 @@ fail:
return NULL;
}
static void fd_blitter_pipe_begin(struct fd_context *ctx);
static void fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond);
static void fd_blitter_pipe_end(struct fd_context *ctx);
/**
@ -570,7 +702,7 @@ fd_blitter_pipe_copy_region(struct fd_context *ctx,
if (!util_blitter_is_copy_supported(ctx->blitter, dst, src))
return false;
fd_blitter_pipe_begin(ctx);
fd_blitter_pipe_begin(ctx, false);
util_blitter_copy_texture(ctx->blitter,
dst, dst_level, dstx, dsty, dstz,
src, src_level, src_box);
@ -612,6 +744,25 @@ fd_resource_copy_region(struct pipe_context *pctx,
src, src_level, src_box);
}
bool
fd_render_condition_check(struct pipe_context *pctx)
{
struct fd_context *ctx = fd_context(pctx);
if (!ctx->cond_query)
return true;
union pipe_query_result res = { 0 };
bool wait =
ctx->cond_mode != PIPE_RENDER_COND_NO_WAIT &&
ctx->cond_mode != PIPE_RENDER_COND_BY_REGION_NO_WAIT;
if (pctx->get_query_result(pctx, ctx->cond_query, wait, &res))
return (bool)res.u64 != ctx->cond_cond;
return true;
}
/**
* Optimal hardware path for blitting pixels.
* Scaling, format conversion, up- and downsampling (resolve) are allowed.
@ -630,6 +781,9 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
return;
}
if (info.render_condition_enable && !fd_render_condition_check(pctx))
return;
if (util_try_blit_via_copy_region(pctx, &info)) {
return; /* done */
}
@ -646,13 +800,13 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
return;
}
fd_blitter_pipe_begin(ctx);
fd_blitter_pipe_begin(ctx, info.render_condition_enable);
util_blitter_blit(ctx->blitter, &info);
fd_blitter_pipe_end(ctx);
}
static void
fd_blitter_pipe_begin(struct fd_context *ctx)
fd_blitter_pipe_begin(struct fd_context *ctx, bool render_cond)
{
util_blitter_save_vertex_buffer_slot(ctx->blitter, ctx->vtx.vertexbuf.vb);
util_blitter_save_vertex_elements(ctx->blitter, ctx->vtx.vtx);
@ -673,6 +827,9 @@ fd_blitter_pipe_begin(struct fd_context *ctx)
(void **)ctx->fragtex.samplers);
util_blitter_save_fragment_sampler_views(ctx->blitter,
ctx->fragtex.num_textures, ctx->fragtex.textures);
if (!render_cond)
util_blitter_save_render_condition(ctx->blitter,
ctx->cond_query, ctx->cond_cond, ctx->cond_mode);
fd_hw_query_set_stage(ctx, ctx->ring, FD_STAGE_BLIT);
}

View file

@ -73,6 +73,7 @@ struct fd_resource {
struct u_resource base;
struct fd_bo *bo;
uint32_t cpp;
enum pipe_format internal_format;
bool layer_first; /* see above description */
uint32_t layer_size;
struct fd_resource_slice slices[MAX_MIP_LEVELS];
@ -135,4 +136,6 @@ fd_resource_offset(struct fd_resource *rsc, unsigned level, unsigned layer)
void fd_resource_screen_init(struct pipe_screen *pscreen);
void fd_resource_context_init(struct pipe_context *pctx);
bool fd_render_condition_check(struct pipe_context *pctx);
#endif /* FREEDRENO_RESOURCE_H_ */

View file

@ -160,11 +160,9 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_SHADER_STENCIL_EXPORT:
case PIPE_CAP_TGSI_TEXCOORD:
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
case PIPE_CAP_CONDITIONAL_RENDER:
case PIPE_CAP_TEXTURE_MULTISAMPLE:
case PIPE_CAP_TEXTURE_BARRIER:
case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
case PIPE_CAP_START_INSTANCE:
case PIPE_CAP_COMPUTE:
return 0;
@ -176,27 +174,31 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_INDEP_BLEND_FUNC:
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
case PIPE_CAP_CONDITIONAL_RENDER:
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
case PIPE_CAP_FAKE_SW_MSAA:
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
case PIPE_CAP_DEPTH_CLIP_DISABLE:
case PIPE_CAP_CLIP_HALFZ:
return is_a3xx(screen) || is_a4xx(screen);
case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
/* ignoring first/last_element.. but I guess that should be
* easy to add..
*/
if (is_a3xx(screen)) return 16;
if (is_a4xx(screen)) return 32;
return 0;
case PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE:
/* I think 32k on a4xx.. and we could possibly emulate more
* by pretending 2d/rect textures and splitting high bits
* of index into 2nd dimension..
/* We could possibly emulate more by pretending 2d/rect textures and
* splitting high bits of index into 2nd dimension..
*/
return 16383;
case PIPE_CAP_DEPTH_CLIP_DISABLE:
case PIPE_CAP_CLIP_HALFZ:
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
return is_a3xx(screen);
if (is_a3xx(screen)) return 8192;
if (is_a4xx(screen)) return 16384;
return 0;
case PIPE_CAP_TEXTURE_FLOAT_LINEAR:
case PIPE_CAP_CUBE_MAP_ARRAY:
case PIPE_CAP_START_INSTANCE:
case PIPE_CAP_SAMPLER_VIEW_TARGET:
case PIPE_CAP_TEXTURE_QUERY_LOD:
return is_a4xx(screen);
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
@ -205,7 +207,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_GLSL_FEATURE_LEVEL:
if (glsl120)
return 120;
return is_ir3(screen) ? 130 : 120;
return is_ir3(screen) ? 140 : 120;
/* Unsupported features. */
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
@ -220,15 +222,11 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT:
case PIPE_CAP_MAX_TEXTURE_GATHER_COMPONENTS:
case PIPE_CAP_TEXTURE_GATHER_SM5:
case PIPE_CAP_FAKE_SW_MSAA:
case PIPE_CAP_TEXTURE_QUERY_LOD:
case PIPE_CAP_SAMPLE_SHADING:
case PIPE_CAP_TEXTURE_GATHER_OFFSETS:
case PIPE_CAP_TGSI_VS_WINDOW_SPACE_POSITION:
case PIPE_CAP_DRAW_INDIRECT:
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE:
case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
case PIPE_CAP_SAMPLER_VIEW_TARGET:
case PIPE_CAP_POLYGON_OFFSET_CLAMP:
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE:
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY:

View file

@ -197,33 +197,15 @@ fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
continue;
const struct util_format_channel_description *chan =
&desc->channel[desc->swizzle[j]];
int size = chan->size;
/* The Z16 texture format we use seems to look in the
* 32-bit border color slots
*/
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS)
size = 32;
/* Formats like R11G11B10 or RGB9_E5 don't specify
* per-channel sizes properly.
*/
if (desc->layout == UTIL_FORMAT_LAYOUT_OTHER)
size = 16;
if (chan->pure_integer && size > 16)
bcolor32[desc->swizzle[j] + 4] =
sampler->border_color.i[j];
else if (size > 16)
bcolor32[desc->swizzle[j]] =
fui(sampler->border_color.f[j]);
else if (chan->pure_integer)
bcolor[desc->swizzle[j] + 8] =
sampler->border_color.i[j];
else
&desc->channel[desc->swizzle[j]];
if (chan->pure_integer) {
bcolor32[desc->swizzle[j] + 4] = sampler->border_color.i[j];
bcolor[desc->swizzle[j] + 8] = sampler->border_color.i[j];
} else {
bcolor32[desc->swizzle[j]] = fui(sampler->border_color.f[j]);
bcolor[desc->swizzle[j]] =
util_float_to_half(sampler->border_color.f[j]);
util_float_to_half(sampler->border_color.f[j]);
}
}
}
}

View file

@ -1177,6 +1177,33 @@ emit_alu(struct ir3_compile *ctx, nir_alu_instr *alu)
dst[0] = ir3_SEL_B32(b, src[1], 0, ir3_b2n(b, src[0]), 0, src[2], 0);
break;
case nir_op_bit_count:
dst[0] = ir3_CBITS_B(b, src[0], 0);
break;
case nir_op_ifind_msb: {
struct ir3_instruction *cmp;
dst[0] = ir3_CLZ_S(b, src[0], 0);
cmp = ir3_CMPS_S(b, dst[0], 0, create_immed(b, 0), 0);
cmp->cat2.condition = IR3_COND_GE;
dst[0] = ir3_SEL_B32(b,
ir3_SUB_U(b, create_immed(b, 31), 0, dst[0], 0), 0,
cmp, 0, dst[0], 0);
break;
}
case nir_op_ufind_msb:
dst[0] = ir3_CLZ_B(b, src[0], 0);
dst[0] = ir3_SEL_B32(b,
ir3_SUB_U(b, create_immed(b, 31), 0, dst[0], 0), 0,
src[0], 0, dst[0], 0);
break;
case nir_op_find_lsb:
dst[0] = ir3_BFREV_B(b, src[0], 0);
dst[0] = ir3_CLZ_B(b, dst[0], 0);
break;
case nir_op_bitfield_reverse:
dst[0] = ir3_BFREV_B(b, src[0], 0);
break;
default:
compile_error(ctx, "Unhandled ALU op: %s\n",
nir_op_infos[alu->op].name);
@ -1547,10 +1574,10 @@ tex_info(nir_tex_instr *tex, unsigned *flagsp, unsigned *coordsp)
unreachable("bad sampler_dim");
}
if (tex->is_shadow)
if (tex->is_shadow && tex->op != nir_texop_lod)
flags |= IR3_INSTR_S;
if (tex->is_array)
if (tex->is_array && tex->op != nir_texop_lod)
flags |= IR3_INSTR_A;
*flagsp = flags;
@ -1618,12 +1645,13 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
case nir_texop_txl: opc = OPC_SAML; break;
case nir_texop_txd: opc = OPC_SAMGQ; break;
case nir_texop_txf: opc = OPC_ISAML; break;
case nir_texop_lod: opc = OPC_GETLOD; break;
case nir_texop_txf_ms:
case nir_texop_txs:
case nir_texop_lod:
case nir_texop_tg4:
case nir_texop_query_levels:
case nir_texop_texture_samples:
case nir_texop_samples_identical:
compile_error(ctx, "Unhandled NIR tex type: %d\n", tex->op);
return;
}
@ -1665,10 +1693,10 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
src0[nsrc0++] = create_immed(b, fui(0.5));
}
if (tex->is_shadow)
if (tex->is_shadow && tex->op != nir_texop_lod)
src0[nsrc0++] = compare;
if (tex->is_array)
if (tex->is_array && tex->op != nir_texop_lod)
src0[nsrc0++] = coord[coords];
if (has_proj) {
@ -1717,7 +1745,7 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
case nir_type_int:
type = TYPE_S32;
break;
case nir_type_unsigned:
case nir_type_uint:
case nir_type_bool:
type = TYPE_U32;
break;
@ -1725,12 +1753,26 @@ emit_tex(struct ir3_compile *ctx, nir_tex_instr *tex)
unreachable("bad dest_type");
}
if (opc == OPC_GETLOD)
type = TYPE_U32;
sam = ir3_SAM(b, opc, type, TGSI_WRITEMASK_XYZW,
flags, tex->sampler_index, tex->sampler_index,
create_collect(b, src0, nsrc0),
create_collect(b, src1, nsrc1));
split_dest(b, dst, sam, 4);
/* GETLOD returns results in 4.8 fixed point */
if (opc == OPC_GETLOD) {
struct ir3_instruction *factor = create_immed(b, fui(1.0 / 256));
compile_assert(ctx, tex->dest_type == nir_type_float);
for (i = 0; i < 2; i++) {
dst[i] = ir3_MUL_F(b, ir3_COV(b, dst[i], TYPE_U32, TYPE_F32), 0,
factor, 0);
}
}
}
static void
@ -1889,6 +1931,8 @@ emit_instr(struct ir3_compile *ctx, nir_instr *instr)
case nir_texop_query_levels:
emit_tex_query_levels(ctx, tex);
break;
case nir_texop_samples_identical:
unreachable("nir_texop_samples_identical");
default:
emit_tex(ctx, tex);
break;

View file

@ -166,7 +166,9 @@ struct ir3_shader_variant {
} outputs[16 + 2]; /* +POSITION +PSIZE */
bool writes_pos, writes_psize;
/* vertices/inputs: */
/* attributes (VS) / varyings (FS):
* Note that sysval's should come *after* normal inputs.
*/
unsigned inputs_count;
struct {
uint8_t slot;
@ -229,7 +231,7 @@ struct ir3_shader {
struct ir3_compiler *compiler;
struct pipe_context *pctx;
struct pipe_context *pctx; /* TODO replace w/ pipe_screen */
const struct tgsi_token *tokens;
struct pipe_stream_output_info stream_output;

View file

@ -64,6 +64,8 @@ NV50_C_SOURCES := \
nv50/nv50_3ddefs.xml.h \
nv50/nv50_3d.xml.h \
nv50/nv50_blit.h \
nv50/nv50_compute.c \
nv50/nv50_compute.xml.h \
nv50/nv50_context.c \
nv50/nv50_context.h \
nv50/nv50_defs.xml.h \
@ -76,6 +78,10 @@ NV50_C_SOURCES := \
nv50/nv50_query.h \
nv50/nv50_query_hw.c \
nv50/nv50_query_hw.h \
nv50/nv50_query_hw_metric.c \
nv50/nv50_query_hw_metric.h \
nv50/nv50_query_hw_sm.c \
nv50/nv50_query_hw_sm.h \
nv50/nv50_resource.c \
nv50/nv50_resource.h \
nv50/nv50_screen.c \

View file

@ -2357,6 +2357,9 @@ CodeEmitterNVC0::emitInstruction(Instruction *insn)
case OP_PFETCH:
emitPFETCH(insn);
break;
case OP_AFETCH:
emitAFETCH(insn);
break;
case OP_EMIT:
case OP_RESTART:
emitOUT(insn);

View file

@ -1573,10 +1573,28 @@ SpillCodeInserter::spill(Instruction *defi, Value *slot, LValue *lval)
Instruction *st;
if (slot->reg.file == FILE_MEMORY_LOCAL) {
st = new_Instruction(func, OP_STORE, ty);
st->setSrc(0, slot);
st->setSrc(1, lval);
lval->noSpill = 1;
if (ty != TYPE_B96) {
st = new_Instruction(func, OP_STORE, ty);
st->setSrc(0, slot);
st->setSrc(1, lval);
} else {
st = new_Instruction(func, OP_SPLIT, ty);
st->setSrc(0, lval);
for (int d = 0; d < lval->reg.size / 4; ++d)
st->setDef(d, new_LValue(func, FILE_GPR));
for (int d = lval->reg.size / 4 - 1; d >= 0; --d) {
Value *tmp = cloneShallow(func, slot);
tmp->reg.size = 4;
tmp->reg.data.offset += 4 * d;
Instruction *s = new_Instruction(func, OP_STORE, TYPE_U32);
s->setSrc(0, tmp);
s->setSrc(1, st->getDef(d));
defi->bb->insertAfter(defi, s);
}
}
} else {
st = new_Instruction(func, OP_CVT, ty);
st->setDef(0, slot);
@ -1596,7 +1614,27 @@ SpillCodeInserter::unspill(Instruction *usei, LValue *lval, Value *slot)
Instruction *ld;
if (slot->reg.file == FILE_MEMORY_LOCAL) {
lval->noSpill = 1;
ld = new_Instruction(func, OP_LOAD, ty);
if (ty != TYPE_B96) {
ld = new_Instruction(func, OP_LOAD, ty);
} else {
ld = new_Instruction(func, OP_MERGE, ty);
for (int d = 0; d < lval->reg.size / 4; ++d) {
Value *tmp = cloneShallow(func, slot);
LValue *val;
tmp->reg.size = 4;
tmp->reg.data.offset += 4 * d;
Instruction *l = new_Instruction(func, OP_LOAD, TYPE_U32);
l->setDef(0, (val = new_LValue(func, FILE_GPR)));
l->setSrc(0, tmp);
usei->bb->insertBefore(usei, l);
ld->setSrc(d, val);
val->noSpill = 1;
}
ld->setDef(0, lval);
usei->bb->insertBefore(usei, ld);
return lval;
}
} else {
ld = new_Instruction(func, OP_CVT, ty);
}

View file

@ -657,8 +657,8 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
if (buffer->base.flags & (PIPE_RESOURCE_FLAG_MAP_PERSISTENT |
PIPE_RESOURCE_FLAG_MAP_COHERENT)) {
buffer->domain = NOUVEAU_BO_GART;
} else if (buffer->base.bind &
(screen->vidmem_bindings & screen->sysmem_bindings)) {
} else if (buffer->base.bind == 0 || (buffer->base.bind &
(screen->vidmem_bindings & screen->sysmem_bindings))) {
switch (buffer->base.usage) {
case PIPE_USAGE_DEFAULT:
case PIPE_USAGE_IMMUTABLE:
@ -685,6 +685,10 @@ nouveau_buffer_create(struct pipe_screen *pscreen,
if (buffer->base.bind & screen->sysmem_bindings)
buffer->domain = NOUVEAU_BO_GART;
}
/* There can be very special situations where we want non-gpu-mapped
* buffers, but never through this interface.
*/
assert(buffer->domain);
ret = nouveau_buffer_allocate(screen, buffer, buffer->domain);
if (ret == false)

View file

@ -0,0 +1,320 @@
/*
* Copyright 2012 Francisco Jerez
* Copyright 2015 Samuel Pitoiset
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#include "nv50/nv50_context.h"
#include "nv50/nv50_compute.xml.h"
#include "codegen/nv50_ir_driver.h"
int
nv50_screen_compute_setup(struct nv50_screen *screen,
struct nouveau_pushbuf *push)
{
struct nouveau_device *dev = screen->base.device;
struct nouveau_object *chan = screen->base.channel;
struct nv04_fifo *fifo = (struct nv04_fifo *)chan->data;
unsigned obj_class;
int i, ret;
switch (dev->chipset & 0xf0) {
case 0x50:
case 0x80:
case 0x90:
obj_class = NV50_COMPUTE_CLASS;
break;
case 0xa0:
switch (dev->chipset) {
case 0xa3:
case 0xa5:
case 0xa8:
obj_class = NVA3_COMPUTE_CLASS;
break;
default:
obj_class = NV50_COMPUTE_CLASS;
break;
}
break;
default:
NOUVEAU_ERR("unsupported chipset: NV%02x\n", dev->chipset);
return -1;
}
ret = nouveau_object_new(chan, 0xbeef50c0, obj_class, NULL, 0,
&screen->compute);
if (ret)
return ret;
BEGIN_NV04(push, SUBC_COMPUTE(NV01_SUBCHAN_OBJECT), 1);
PUSH_DATA (push, screen->compute->handle);
BEGIN_NV04(push, NV50_COMPUTE(UNK02A0), 1);
PUSH_DATA (push, 1);
BEGIN_NV04(push, NV50_COMPUTE(DMA_STACK), 1);
PUSH_DATA (push, fifo->vram);
BEGIN_NV04(push, NV50_COMPUTE(STACK_ADDRESS_HIGH), 2);
PUSH_DATAh(push, screen->stack_bo->offset);
PUSH_DATA (push, screen->stack_bo->offset);
BEGIN_NV04(push, NV50_COMPUTE(STACK_SIZE_LOG), 1);
PUSH_DATA (push, 4);
BEGIN_NV04(push, NV50_COMPUTE(UNK0290), 1);
PUSH_DATA (push, 1);
BEGIN_NV04(push, NV50_COMPUTE(LANES32_ENABLE), 1);
PUSH_DATA (push, 1);
BEGIN_NV04(push, NV50_COMPUTE(REG_MODE), 1);
PUSH_DATA (push, NV50_COMPUTE_REG_MODE_STRIPED);
BEGIN_NV04(push, NV50_COMPUTE(UNK0384), 1);
PUSH_DATA (push, 0x100);
BEGIN_NV04(push, NV50_COMPUTE(DMA_GLOBAL), 1);
PUSH_DATA (push, fifo->vram);
for (i = 0; i < 15; i++) {
BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_ADDRESS_HIGH(i)), 2);
PUSH_DATA (push, 0);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_LIMIT(i)), 1);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_MODE(i)), 1);
PUSH_DATA (push, NV50_COMPUTE_GLOBAL_MODE_LINEAR);
}
BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_ADDRESS_HIGH(15)), 2);
PUSH_DATA (push, 0);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_LIMIT(15)), 1);
PUSH_DATA (push, ~0);
BEGIN_NV04(push, NV50_COMPUTE(GLOBAL_MODE(15)), 1);
PUSH_DATA (push, NV50_COMPUTE_GLOBAL_MODE_LINEAR);
BEGIN_NV04(push, NV50_COMPUTE(LOCAL_WARPS_LOG_ALLOC), 1);
PUSH_DATA (push, 7);
BEGIN_NV04(push, NV50_COMPUTE(LOCAL_WARPS_NO_CLAMP), 1);
PUSH_DATA (push, 1);
BEGIN_NV04(push, NV50_COMPUTE(STACK_WARPS_LOG_ALLOC), 1);
PUSH_DATA (push, 7);
BEGIN_NV04(push, NV50_COMPUTE(STACK_WARPS_NO_CLAMP), 1);
PUSH_DATA (push, 1);
BEGIN_NV04(push, NV50_COMPUTE(USER_PARAM_COUNT), 1);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_COMPUTE(DMA_TEXTURE), 1);
PUSH_DATA (push, fifo->vram);
BEGIN_NV04(push, NV50_COMPUTE(TEX_LIMITS), 1);
PUSH_DATA (push, 0x54);
BEGIN_NV04(push, NV50_COMPUTE(LINKED_TSC), 1);
PUSH_DATA (push, 0);
BEGIN_NV04(push, NV50_COMPUTE(DMA_TIC), 1);
PUSH_DATA (push, fifo->vram);
BEGIN_NV04(push, NV50_COMPUTE(TIC_ADDRESS_HIGH), 3);
PUSH_DATAh(push, screen->txc->offset);
PUSH_DATA (push, screen->txc->offset);
PUSH_DATA (push, NV50_TIC_MAX_ENTRIES - 1);
BEGIN_NV04(push, NV50_COMPUTE(DMA_TSC), 1);
PUSH_DATA (push, fifo->vram);
BEGIN_NV04(push, NV50_COMPUTE(TSC_ADDRESS_HIGH), 3);
PUSH_DATAh(push, screen->txc->offset + 65536);
PUSH_DATA (push, screen->txc->offset + 65536);
PUSH_DATA (push, NV50_TSC_MAX_ENTRIES - 1);
BEGIN_NV04(push, NV50_COMPUTE(DMA_CODE_CB), 1);
PUSH_DATA (push, fifo->vram);
BEGIN_NV04(push, NV50_COMPUTE(DMA_LOCAL), 1);
PUSH_DATA (push, fifo->vram);
BEGIN_NV04(push, NV50_COMPUTE(LOCAL_ADDRESS_HIGH), 2);
PUSH_DATAh(push, screen->tls_bo->offset + 65536);
PUSH_DATA (push, screen->tls_bo->offset + 65536);
BEGIN_NV04(push, NV50_COMPUTE(LOCAL_SIZE_LOG), 1);
PUSH_DATA (push, util_logbase2((screen->max_tls_space / ONE_TEMP_SIZE) * 2));
return 0;
}
static bool
nv50_compute_validate_program(struct nv50_context *nv50)
{
struct nv50_program *prog = nv50->compprog;
if (prog->mem)
return true;
if (!prog->translated) {
prog->translated = nv50_program_translate(
prog, nv50->screen->base.device->chipset, &nv50->base.debug);
if (!prog->translated)
return false;
}
if (unlikely(!prog->code_size))
return false;
if (likely(prog->code_size)) {
if (nv50_program_upload_code(nv50, prog)) {
struct nouveau_pushbuf *push = nv50->base.pushbuf;
BEGIN_NV04(push, NV50_COMPUTE(CODE_CB_FLUSH), 1);
PUSH_DATA (push, 0);
return true;
}
}
return false;
}
static void
nv50_compute_validate_globals(struct nv50_context *nv50)
{
unsigned i;
for (i = 0; i < nv50->global_residents.size / sizeof(struct pipe_resource *);
++i) {
struct pipe_resource *res = *util_dynarray_element(
&nv50->global_residents, struct pipe_resource *, i);
if (res)
nv50_add_bufctx_resident(nv50->bufctx_cp, NV50_BIND_CP_GLOBAL,
nv04_resource(res), NOUVEAU_BO_RDWR);
}
}
static bool
nv50_compute_state_validate(struct nv50_context *nv50)
{
if (!nv50_compute_validate_program(nv50))
return false;
if (nv50->dirty_cp & NV50_NEW_CP_GLOBALS)
nv50_compute_validate_globals(nv50);
/* TODO: validate textures, samplers, surfaces */
nv50_bufctx_fence(nv50->bufctx_cp, false);
nouveau_pushbuf_bufctx(nv50->base.pushbuf, nv50->bufctx_cp);
if (unlikely(nouveau_pushbuf_validate(nv50->base.pushbuf)))
return false;
if (unlikely(nv50->state.flushed))
nv50_bufctx_fence(nv50->bufctx_cp, true);
return true;
}
static void
nv50_compute_upload_input(struct nv50_context *nv50, const uint32_t *input)
{
struct nv50_screen *screen = nv50->screen;
struct nouveau_pushbuf *push = screen->base.pushbuf;
unsigned size = align(nv50->compprog->parm_size, 0x4);
BEGIN_NV04(push, NV50_COMPUTE(USER_PARAM_COUNT), 1);
PUSH_DATA (push, (size / 4) << 8);
if (size) {
struct nouveau_mm_allocation *mm;
struct nouveau_bo *bo = NULL;
unsigned offset;
mm = nouveau_mm_allocate(screen->base.mm_GART, size, &bo, &offset);
assert(mm);
nouveau_bo_map(bo, 0, screen->base.client);
memcpy(bo->map + offset, input, size);
nouveau_bufctx_refn(nv50->bufctx, 0, bo, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
nouveau_pushbuf_bufctx(push, nv50->bufctx);
nouveau_pushbuf_validate(push);
BEGIN_NV04(push, NV50_COMPUTE(USER_PARAM(0)), size / 4);
nouveau_pushbuf_data(push, bo, offset, size);
nouveau_fence_work(screen->base.fence.current, nouveau_mm_free_work, mm);
nouveau_bo_ref(NULL, &bo);
nouveau_bufctx_reset(nv50->bufctx, 0);
}
}
static uint32_t
nv50_compute_find_symbol(struct nv50_context *nv50, uint32_t label)
{
struct nv50_program *prog = nv50->compprog;
const struct nv50_ir_prog_symbol *syms =
(const struct nv50_ir_prog_symbol *)prog->cp.syms;
unsigned i;
for (i = 0; i < prog->cp.num_syms; ++i) {
if (syms[i].label == label)
return prog->code_base + syms[i].offset;
}
return prog->code_base; /* no symbols or symbol not found */
}
void
nv50_launch_grid(struct pipe_context *pipe,
const uint *block_layout, const uint *grid_layout,
uint32_t label, const void *input)
{
struct nv50_context *nv50 = nv50_context(pipe);
struct nouveau_pushbuf *push = nv50->base.pushbuf;
unsigned block_size = block_layout[0] * block_layout[1] * block_layout[2];
struct nv50_program *cp = nv50->compprog;
bool ret;
ret = !nv50_compute_state_validate(nv50);
if (ret) {
NOUVEAU_ERR("Failed to launch grid !\n");
return;
}
nv50_compute_upload_input(nv50, input);
BEGIN_NV04(push, NV50_COMPUTE(CP_START_ID), 1);
PUSH_DATA (push, nv50_compute_find_symbol(nv50, label));
BEGIN_NV04(push, NV50_COMPUTE(SHARED_SIZE), 1);
PUSH_DATA (push, align(cp->cp.smem_size + cp->parm_size + 0x10, 0x40));
BEGIN_NV04(push, NV50_COMPUTE(CP_REG_ALLOC_TEMP), 1);
PUSH_DATA (push, cp->max_gpr);
/* grid/block setup */
BEGIN_NV04(push, NV50_COMPUTE(BLOCKDIM_XY), 2);
PUSH_DATA (push, block_layout[1] << 16 | block_layout[0]);
PUSH_DATA (push, block_layout[2]);
BEGIN_NV04(push, NV50_COMPUTE(BLOCK_ALLOC), 1);
PUSH_DATA (push, 1 << 16 | block_size);
BEGIN_NV04(push, NV50_COMPUTE(BLOCKDIM_LATCH), 1);
PUSH_DATA (push, 1);
BEGIN_NV04(push, NV50_COMPUTE(GRIDDIM), 1);
PUSH_DATA (push, grid_layout[1] << 16 | grid_layout[0]);
BEGIN_NV04(push, NV50_COMPUTE(GRIDID), 1);
PUSH_DATA (push, 1);
/* kernel launching */
BEGIN_NV04(push, NV50_COMPUTE(LAUNCH), 1);
PUSH_DATA (push, 0);
BEGIN_NV04(push, SUBC_COMPUTE(NV50_GRAPH_SERIALIZE), 1);
PUSH_DATA (push, 0);
/* bind a compute shader clobbers fragment shader state */
nv50->dirty |= NV50_NEW_FRAGPROG;
}

View file

@ -0,0 +1,444 @@
#ifndef NV50_COMPUTE_XML
#define NV50_COMPUTE_XML
/* Autogenerated file, DO NOT EDIT manually!
This file was generated by the rules-ng-ng headergen tool in this git repository:
http://github.com/envytools/envytools/
git clone https://github.com/envytools/envytools.git
The rules-ng-ng source files this header was generated from are:
- rnndb/graph/g80_compute.xml ( 14027 bytes, from 2015-02-14 02:01:36)
- rnndb/copyright.xml ( 6456 bytes, from 2015-02-14 02:01:36)
- rnndb/nvchipsets.xml ( 2833 bytes, from 2015-04-28 16:28:33)
- rnndb/fifo/nv_object.xml ( 15390 bytes, from 2015-04-22 20:36:09)
- rnndb/g80_defs.xml ( 18210 bytes, from 2015-10-19 20:49:59)
Copyright (C) 2006-2015 by the following authors:
- Artur Huillet <arthur.huillet@free.fr> (ahuillet)
- Ben Skeggs (darktama, darktama_)
- B. R. <koala_br@users.sourceforge.net> (koala_br)
- Carlos Martin <carlosmn@users.sf.net> (carlosmn)
- Christoph Bumiller <e0425955@student.tuwien.ac.at> (calim, chrisbmr)
- Dawid Gajownik <gajownik@users.sf.net> (gajownik)
- Dmitry Baryshkov
- Dmitry Eremin-Solenikov <lumag@users.sf.net> (lumag)
- EdB <edb_@users.sf.net> (edb_)
- Erik Waling <erikwailing@users.sf.net> (erikwaling)
- Francisco Jerez <currojerez@riseup.net> (curro)
- Ilia Mirkin <imirkin@alum.mit.edu> (imirkin)
- jb17bsome <jb17bsome@bellsouth.net> (jb17bsome)
- Jeremy Kolb <kjeremy@users.sf.net> (kjeremy)
- Laurent Carlier <lordheavym@gmail.com> (lordheavy)
- Luca Barbieri <luca@luca-barbieri.com> (lb, lb1)
- Maarten Maathuis <madman2003@gmail.com> (stillunknown)
- Marcin Kościelnicki <koriakin@0x04.net> (mwk, koriakin)
- Mark Carey <mark.carey@gmail.com> (careym)
- Matthieu Castet <matthieu.castet@parrot.com> (mat-c)
- nvidiaman <nvidiaman@users.sf.net> (nvidiaman)
- Patrice Mandin <patmandin@gmail.com> (pmandin, pmdata)
- Pekka Paalanen <pq@iki.fi> (pq, ppaalanen)
- Peter Popov <ironpeter@users.sf.net> (ironpeter)
- Richard Hughes <hughsient@users.sf.net> (hughsient)
- Rudi Cilibrasi <cilibrar@users.sf.net> (cilibrar)
- Serge Martin
- Simon Raffeiner
- Stephane Loeuillet <leroutier@users.sf.net> (leroutier)
- Stephane Marchesin <stephane.marchesin@gmail.com> (marcheu)
- sturmflut <sturmflut@users.sf.net> (sturmflut)
- Sylvain Munaut <tnt@246tNt.com>
- Victor Stinner <victor.stinner@haypocalc.com> (haypo)
- Wladmir van der Laan <laanwj@gmail.com> (miathan6)
- Younes Manton <younes.m@gmail.com> (ymanton)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice (including the
next paragraph) shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#define NV50_COMPUTE_DMA_NOTIFY 0x00000180
#define NV50_COMPUTE_DMA_GLOBAL 0x000001a0
#define NV50_COMPUTE_DMA_QUERY 0x000001a4
#define NV50_COMPUTE_DMA_LOCAL 0x000001b8
#define NV50_COMPUTE_DMA_STACK 0x000001bc
#define NV50_COMPUTE_DMA_CODE_CB 0x000001c0
#define NV50_COMPUTE_DMA_TSC 0x000001c4
#define NV50_COMPUTE_DMA_TIC 0x000001c8
#define NV50_COMPUTE_DMA_TEXTURE 0x000001cc
#define NV50_COMPUTE_UNK0200 0x00000200
#define NV50_COMPUTE_UNK0200_UNK1__MASK 0x0000ffff
#define NV50_COMPUTE_UNK0200_UNK1__SHIFT 0
#define NV50_COMPUTE_UNK0200_UNK2__MASK 0x00ff0000
#define NV50_COMPUTE_UNK0200_UNK2__SHIFT 16
#define NV50_COMPUTE_UNK0204 0x00000204
#define NV50_COMPUTE_UNK0208 0x00000208
#define NV50_COMPUTE_UNK020C 0x0000020c
#define NV50_COMPUTE_CP_ADDRESS_HIGH 0x00000210
#define NV50_COMPUTE_CP_ADDRESS_LOW 0x00000214
#define NV50_COMPUTE_STACK_ADDRESS_HIGH 0x00000218
#define NV50_COMPUTE_STACK_ADDRESS_LOW 0x0000021c
#define NV50_COMPUTE_STACK_SIZE_LOG 0x00000220
#define NV50_COMPUTE_CALL_LIMIT_LOG 0x00000224
#define NV50_COMPUTE_UNK0228 0x00000228
#define NV50_COMPUTE_UNK0228_UNK0 0x00000001
#define NV50_COMPUTE_UNK0228_UNK4__MASK 0x00000ff0
#define NV50_COMPUTE_UNK0228_UNK4__SHIFT 4
#define NV50_COMPUTE_UNK0228_UNK12__MASK 0x000ff000
#define NV50_COMPUTE_UNK0228_UNK12__SHIFT 12
#define NV50_COMPUTE_TSC_ADDRESS_HIGH 0x0000022c
#define NV50_COMPUTE_TSC_ADDRESS_LOW 0x00000230
#define NV50_COMPUTE_TSC_ADDRESS_LOW__ALIGN 0x00000020
#define NV50_COMPUTE_TSC_LIMIT 0x00000234
#define NV50_COMPUTE_TSC_LIMIT__MAX 0x00001fff
#define NV50_COMPUTE_CB_ADDR 0x00000238
#define NV50_COMPUTE_CB_ADDR_ID__MASK 0x003fff00
#define NV50_COMPUTE_CB_ADDR_ID__SHIFT 8
#define NV50_COMPUTE_CB_ADDR_BUFFER__MASK 0x0000007f
#define NV50_COMPUTE_CB_ADDR_BUFFER__SHIFT 0
#define NV50_COMPUTE_CB_DATA(i0) (0x0000023c + 0x4*(i0))
#define NV50_COMPUTE_CB_DATA__ESIZE 0x00000004
#define NV50_COMPUTE_CB_DATA__LEN 0x00000010
#define NV50_COMPUTE_TSC_FLUSH 0x0000027c
#define NV50_COMPUTE_TSC_FLUSH_SPECIFIC 0x00000001
#define NV50_COMPUTE_TSC_FLUSH_ENTRY__MASK 0x03fffff0
#define NV50_COMPUTE_TSC_FLUSH_ENTRY__SHIFT 4
#define NV50_COMPUTE_TIC_FLUSH 0x00000280
#define NV50_COMPUTE_TIC_FLUSH_SPECIFIC 0x00000001
#define NV50_COMPUTE_TIC_FLUSH_ENTRY__MASK 0x03fffff0
#define NV50_COMPUTE_TIC_FLUSH_ENTRY__SHIFT 4
#define NV50_COMPUTE_DELAY1 0x00000284
#define NV50_COMPUTE_WATCHDOG_TIMER 0x00000288
#define NV50_COMPUTE_DELAY2 0x0000028c
#define NV50_COMPUTE_UNK0290 0x00000290
#define NV50_COMPUTE_LOCAL_ADDRESS_HIGH 0x00000294
#define NV50_COMPUTE_LOCAL_ADDRESS_LOW 0x00000298
#define NV50_COMPUTE_LOCAL_ADDRESS_LOW__ALIGN 0x00000100
#define NV50_COMPUTE_LOCAL_SIZE_LOG 0x0000029c
#define NV50_COMPUTE_UNK02A0 0x000002a0
#define NV50_COMPUTE_CB_DEF_ADDRESS_HIGH 0x000002a4
#define NV50_COMPUTE_CB_DEF_ADDRESS_LOW 0x000002a8
#define NV50_COMPUTE_CB_DEF_SET 0x000002ac
#define NV50_COMPUTE_CB_DEF_SET_SIZE__MASK 0x0000ffff
#define NV50_COMPUTE_CB_DEF_SET_SIZE__SHIFT 0
#define NV50_COMPUTE_CB_DEF_SET_BUFFER__MASK 0x007f0000
#define NV50_COMPUTE_CB_DEF_SET_BUFFER__SHIFT 16
#define NV50_COMPUTE_UNK02B0 0x000002b0
#define NV50_COMPUTE_BLOCK_ALLOC 0x000002b4
#define NV50_COMPUTE_BLOCK_ALLOC_THREADS__MASK 0x0000ffff
#define NV50_COMPUTE_BLOCK_ALLOC_THREADS__SHIFT 0
#define NV50_COMPUTE_BLOCK_ALLOC_BARRIERS__MASK 0x00ff0000
#define NV50_COMPUTE_BLOCK_ALLOC_BARRIERS__SHIFT 16
#define NV50_COMPUTE_LANES32_ENABLE 0x000002b8
#define NV50_COMPUTE_UNK02BC 0x000002bc
#define NV50_COMPUTE_UNK02BC_UNK1__MASK 0x00000007
#define NV50_COMPUTE_UNK02BC_UNK1__SHIFT 0
#define NV50_COMPUTE_UNK02BC_UNK2__MASK 0x00000070
#define NV50_COMPUTE_UNK02BC_UNK2__SHIFT 4
#define NV50_COMPUTE_CP_REG_ALLOC_TEMP 0x000002c0
#define NV50_COMPUTE_TIC_ADDRESS_HIGH 0x000002c4
#define NV50_COMPUTE_TIC_ADDRESS_LOW 0x000002c8
#define NV50_COMPUTE_TIC_LIMIT 0x000002cc
#define NV50_COMPUTE_MP_PM_SET(i0) (0x000002d0 + 0x4*(i0))
#define NV50_COMPUTE_MP_PM_SET__ESIZE 0x00000004
#define NV50_COMPUTE_MP_PM_SET__LEN 0x00000004
#define NV50_COMPUTE_MP_PM_CONTROL(i0) (0x000002e0 + 0x4*(i0))
#define NV50_COMPUTE_MP_PM_CONTROL__ESIZE 0x00000004
#define NV50_COMPUTE_MP_PM_CONTROL__LEN 0x00000004
#define NV50_COMPUTE_MP_PM_CONTROL_MODE__MASK 0x00000001
#define NV50_COMPUTE_MP_PM_CONTROL_MODE__SHIFT 0
#define NV50_COMPUTE_MP_PM_CONTROL_MODE_LOGOP 0x00000000
#define NV50_COMPUTE_MP_PM_CONTROL_MODE_LOGOP_PULSE 0x00000001
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT__MASK 0x00000070
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT__SHIFT 4
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT_UNK0 0x00000000
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT_UNK1 0x00000010
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT_UNK2 0x00000020
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT_UNK3 0x00000030
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT_UNK4 0x00000040
#define NV50_COMPUTE_MP_PM_CONTROL_UNIT_UNK5 0x00000050
#define NV50_COMPUTE_MP_PM_CONTROL_FUNC__MASK 0x00ffff00
#define NV50_COMPUTE_MP_PM_CONTROL_FUNC__SHIFT 8
#define NV50_COMPUTE_MP_PM_CONTROL_SIG__MASK 0xff000000
#define NV50_COMPUTE_MP_PM_CONTROL_SIG__SHIFT 24
#define NV50_COMPUTE_MP_PM_OVERFLOW_TRAP_ENABLE 0x000002f0
#define NV50_COMPUTE_MP_PM_OVERFLOW_TRAP_ENABLE_0 0x00000001
#define NV50_COMPUTE_MP_PM_OVERFLOW_TRAP_ENABLE_1 0x00000002
#define NV50_COMPUTE_MP_PM_OVERFLOW_TRAP_ENABLE_2 0x00000004
#define NV50_COMPUTE_MP_PM_OVERFLOW_TRAP_ENABLE_3 0x00000008
#define NV50_COMPUTE_UNK02F4 0x000002f4
#define NV50_COMPUTE_BLOCKDIM_LATCH 0x000002f8
#define NV50_COMPUTE_LOCAL_WARPS_LOG_ALLOC 0x000002fc
#define NV50_COMPUTE_LOCAL_WARPS_NO_CLAMP 0x00000300
#define NV50_COMPUTE_STACK_WARPS_LOG_ALLOC 0x00000304
#define NV50_COMPUTE_STACK_WARPS_NO_CLAMP 0x00000308
#define NV50_COMPUTE_UNK030C 0x0000030c
#define NV50_COMPUTE_QUERY_ADDRESS_HIGH 0x00000310
#define NV50_COMPUTE_QUERY_ADDRESS_LOW 0x00000314
#define NV50_COMPUTE_QUERY_SEQUENCE 0x00000318
#define NV50_COMPUTE_QUERY_GET 0x0000031c
#define NV50_COMPUTE_QUERY_GET_INTR 0x00000200
#define NV50_COMPUTE_QUERY_GET_SHORT 0x00008000
#define NV50_COMPUTE_COND_ADDRESS_HIGH 0x00000320
#define NV50_COMPUTE_COND_ADDRESS_LOW 0x00000324
#define NV50_COMPUTE_COND_MODE 0x00000328
#define NV50_COMPUTE_COND_MODE_NEVER 0x00000000
#define NV50_COMPUTE_COND_MODE_ALWAYS 0x00000001
#define NV50_COMPUTE_COND_MODE_RES_NON_ZERO 0x00000002
#define NV50_COMPUTE_COND_MODE_EQUAL 0x00000003
#define NV50_COMPUTE_COND_MODE_NOT_EQUAL 0x00000004
#define NV50_COMPUTE_UNK032C 0x0000032c
#define NV50_COMPUTE_UNK0330 0x00000330
#define NV50_COMPUTE_UNK0334(i0) (0x00000334 + 0x4*(i0))
#define NV50_COMPUTE_UNK0334__ESIZE 0x00000004
#define NV50_COMPUTE_UNK0334__LEN 0x00000003
#define NV50_COMPUTE_UNK0340(i0) (0x00000340 + 0x4*(i0))
#define NV50_COMPUTE_UNK0340__ESIZE 0x00000004
#define NV50_COMPUTE_UNK0340__LEN 0x00000002
#define NV50_COMPUTE_UNK0348(i0) (0x00000348 + 0x4*(i0))
#define NV50_COMPUTE_UNK0348__ESIZE 0x00000004
#define NV50_COMPUTE_UNK0348__LEN 0x00000002
#define NV50_COMPUTE_UNK0350(i0) (0x00000350 + 0x4*(i0))
#define NV50_COMPUTE_UNK0350__ESIZE 0x00000004
#define NV50_COMPUTE_UNK0350__LEN 0x00000002
#define NV50_COMPUTE_UNK0358 0x00000358
#define NV50_COMPUTE_UNK035C 0x0000035c
#define NV50_COMPUTE_UNK0360 0x00000360
#define NV50_COMPUTE_UNK0360_UNK0__MASK 0x000000f0
#define NV50_COMPUTE_UNK0360_UNK0__SHIFT 4
#define NV50_COMPUTE_UNK0360_UNK1__MASK 0x00000f00
#define NV50_COMPUTE_UNK0360_UNK1__SHIFT 8
#define NV50_COMPUTE_UNK0364 0x00000364
#define NV50_COMPUTE_LAUNCH 0x00000368
#define NV50_COMPUTE_UNK036C 0x0000036c
#define NV50_COMPUTE_UNK0370 0x00000370
#define NV50_COMPUTE_USER_PARAM_COUNT 0x00000374
#define NV50_COMPUTE_USER_PARAM_COUNT_UNK0__MASK 0x000000ff
#define NV50_COMPUTE_USER_PARAM_COUNT_UNK0__SHIFT 0
#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT__MASK 0x0000ff00
#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT__SHIFT 8
#define NV50_COMPUTE_USER_PARAM_COUNT_COUNT__MAX 0x00000040
#define NV50_COMPUTE_LINKED_TSC 0x00000378
#define NV50_COMPUTE_UNK037C 0x0000037c
#define NV50_COMPUTE_UNK037C_ALWAYS_DERIV 0x00000001
#define NV50_COMPUTE_UNK037C_UNK16 0x00010000
#define NV50_COMPUTE_CODE_CB_FLUSH 0x00000380
#define NV50_COMPUTE_UNK0384 0x00000384
#define NV50_COMPUTE_GRIDID 0x00000388
#define NV50_COMPUTE_UNK038C(i0) (0x0000038c + 0x4*(i0))
#define NV50_COMPUTE_UNK038C__ESIZE 0x00000004
#define NV50_COMPUTE_UNK038C__LEN 0x00000003
#define NV50_COMPUTE_WRCACHE_FLUSH 0x00000398
#define NV50_COMPUTE_UNK039C(i0) (0x0000039c + 0x4*(i0))
#define NV50_COMPUTE_UNK039C__ESIZE 0x00000004
#define NV50_COMPUTE_UNK039C__LEN 0x00000002
#define NV50_COMPUTE_GRIDDIM 0x000003a4
#define NV50_COMPUTE_GRIDDIM_X__MASK 0x0000ffff
#define NV50_COMPUTE_GRIDDIM_X__SHIFT 0
#define NV50_COMPUTE_GRIDDIM_Y__MASK 0xffff0000
#define NV50_COMPUTE_GRIDDIM_Y__SHIFT 16
#define NV50_COMPUTE_SHARED_SIZE 0x000003a8
#define NV50_COMPUTE_SHARED_SIZE__MAX 0x00004000
#define NV50_COMPUTE_SHARED_SIZE__ALIGN 0x00000040
#define NV50_COMPUTE_BLOCKDIM_XY 0x000003ac
#define NV50_COMPUTE_BLOCKDIM_XY_X__MASK 0x0000ffff
#define NV50_COMPUTE_BLOCKDIM_XY_X__SHIFT 0
#define NV50_COMPUTE_BLOCKDIM_XY_Y__MASK 0xffff0000
#define NV50_COMPUTE_BLOCKDIM_XY_Y__SHIFT 16
#define NV50_COMPUTE_BLOCKDIM_Z 0x000003b0
#define NV50_COMPUTE_BLOCKDIM_Z__MIN 0x00000001
#define NV50_COMPUTE_BLOCKDIM_Z__MAX 0x00000040
#define NV50_COMPUTE_CP_START_ID 0x000003b4
#define NV50_COMPUTE_REG_MODE 0x000003b8
#define NV50_COMPUTE_REG_MODE_PACKED 0x00000001
#define NV50_COMPUTE_REG_MODE_STRIPED 0x00000002
#define NV50_COMPUTE_TEX_LIMITS 0x000003bc
#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2__MASK 0x0000000f
#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2__SHIFT 0
#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2__MIN 0x00000000
#define NV50_COMPUTE_TEX_LIMITS_SAMPLERS_LOG2__MAX 0x00000004
#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2__MASK 0x000000f0
#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2__SHIFT 4
#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2__MIN 0x00000000
#define NV50_COMPUTE_TEX_LIMITS_TEXTURES_LOG2__MAX 0x00000007
#define NV50_COMPUTE_BIND_TSC 0x000003c0
#define NV50_COMPUTE_BIND_TSC_VALID 0x00000001
#define NV50_COMPUTE_BIND_TSC_SAMPLER__MASK 0x000000f0
#define NV50_COMPUTE_BIND_TSC_SAMPLER__SHIFT 4
#define NV50_COMPUTE_BIND_TSC_TSC__MASK 0x001ff000
#define NV50_COMPUTE_BIND_TSC_TSC__SHIFT 12
#define NV50_COMPUTE_BIND_TIC 0x000003c4
#define NV50_COMPUTE_BIND_TIC_VALID 0x00000001
#define NV50_COMPUTE_BIND_TIC_TEXTURE__MASK 0x000001fe
#define NV50_COMPUTE_BIND_TIC_TEXTURE__SHIFT 1
#define NV50_COMPUTE_BIND_TIC_TIC__MASK 0x7ffffe00
#define NV50_COMPUTE_BIND_TIC_TIC__SHIFT 9
#define NV50_COMPUTE_SET_PROGRAM_CB 0x000003c8
#define NV50_COMPUTE_SET_PROGRAM_CB_INDEX__MASK 0x00000f00
#define NV50_COMPUTE_SET_PROGRAM_CB_INDEX__SHIFT 8
#define NV50_COMPUTE_SET_PROGRAM_CB_BUFFER__MASK 0x0007f000
#define NV50_COMPUTE_SET_PROGRAM_CB_BUFFER__SHIFT 12
#define NV50_COMPUTE_SET_PROGRAM_CB_VALID 0x000000ff
#define NV50_COMPUTE_UNK03CC 0x000003cc
#define NV50_COMPUTE_TEX_CACHE_CTL 0x000003d0
#define NV50_COMPUTE_TEX_CACHE_CTL_UNK1__MASK 0x00000030
#define NV50_COMPUTE_TEX_CACHE_CTL_UNK1__SHIFT 4
#define NV50_COMPUTE_UNK03D4 0x000003d4
#define NV50_COMPUTE_UNK03D8 0x000003d8
#define NV50_COMPUTE_UNK03DC 0x000003dc
#define NV50_COMPUTE_UNK03E0 0x000003e0
#define NV50_COMPUTE_UNK03E4 0x000003e4
#define NVA3_COMPUTE_TEX_MISC 0x000003e8
#define NVA3_COMPUTE_TEX_MISC_UNK1 0x00000001
#define NVA3_COMPUTE_TEX_MISC_SEAMLESS_CUBE_MAP 0x00000002
#define NV50_COMPUTE_GLOBAL(i0) (0x00000400 + 0x20*(i0))
#define NV50_COMPUTE_GLOBAL__ESIZE 0x00000020
#define NV50_COMPUTE_GLOBAL__LEN 0x00000010
#define NV50_COMPUTE_GLOBAL_ADDRESS_HIGH(i0) (0x00000400 + 0x20*(i0))
#define NV50_COMPUTE_GLOBAL_ADDRESS_LOW(i0) (0x00000404 + 0x20*(i0))
#define NV50_COMPUTE_GLOBAL_PITCH(i0) (0x00000408 + 0x20*(i0))
#define NV50_COMPUTE_GLOBAL_PITCH__MAX 0x00800000
#define NV50_COMPUTE_GLOBAL_PITCH__ALIGN 0x00000100
#define NV50_COMPUTE_GLOBAL_LIMIT(i0) (0x0000040c + 0x20*(i0))
#define NV50_COMPUTE_GLOBAL_MODE(i0) (0x00000410 + 0x20*(i0))
#define NV50_COMPUTE_GLOBAL_MODE_LINEAR 0x00000001
#define NV50_COMPUTE_GLOBAL_MODE_UNK1__MASK 0x000000f0
#define NV50_COMPUTE_GLOBAL_MODE_UNK1__SHIFT 4
#define NV50_COMPUTE_GLOBAL_MODE_TILE_MODE__MASK 0x00000f00
#define NV50_COMPUTE_GLOBAL_MODE_TILE_MODE__SHIFT 8
#define NV50_COMPUTE_USER_PARAM(i0) (0x00000600 + 0x4*(i0))
#define NV50_COMPUTE_USER_PARAM__ESIZE 0x00000004
#define NV50_COMPUTE_USER_PARAM__LEN 0x00000040
#define NV50_COMPUTE_UNK0700(i0) (0x00000700 + 0x4*(i0))
#define NV50_COMPUTE_UNK0700__ESIZE 0x00000004
#define NV50_COMPUTE_UNK0700__LEN 0x00000010
#endif /* NV50_COMPUTE_XML */

View file

@ -113,6 +113,7 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
nouveau_bufctx_del(&nv50->bufctx_3d);
nouveau_bufctx_del(&nv50->bufctx);
nouveau_bufctx_del(&nv50->bufctx_cp);
util_unreference_framebuffer_state(&nv50->framebuffer);
@ -131,6 +132,14 @@ nv50_context_unreference_resources(struct nv50_context *nv50)
if (!nv50->constbuf[s][i].user)
pipe_resource_reference(&nv50->constbuf[s][i].u.buf, NULL);
}
for (i = 0; i < nv50->global_residents.size / sizeof(struct pipe_resource *);
++i) {
struct pipe_resource **res = util_dynarray_element(
&nv50->global_residents, struct pipe_resource *, i);
pipe_resource_reference(res, NULL);
}
util_dynarray_fini(&nv50->global_residents);
}
static void
@ -159,9 +168,10 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
int ref)
{
struct nv50_context *nv50 = nv50_context(&ctx->pipe);
unsigned bind = res->bind ? res->bind : PIPE_BIND_VERTEX_BUFFER;
unsigned s, i;
if (res->bind & PIPE_BIND_RENDER_TARGET) {
if (bind & PIPE_BIND_RENDER_TARGET) {
assert(nv50->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS);
for (i = 0; i < nv50->framebuffer.nr_cbufs; ++i) {
if (nv50->framebuffer.cbufs[i] &&
@ -173,7 +183,7 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
}
}
}
if (res->bind & PIPE_BIND_DEPTH_STENCIL) {
if (bind & PIPE_BIND_DEPTH_STENCIL) {
if (nv50->framebuffer.zsbuf &&
nv50->framebuffer.zsbuf->texture == res) {
nv50->dirty |= NV50_NEW_FRAMEBUFFER;
@ -183,11 +193,11 @@ nv50_invalidate_resource_storage(struct nouveau_context *ctx,
}
}
if (res->bind & (PIPE_BIND_VERTEX_BUFFER |
PIPE_BIND_INDEX_BUFFER |
PIPE_BIND_CONSTANT_BUFFER |
PIPE_BIND_STREAM_OUTPUT |
PIPE_BIND_SAMPLER_VIEW)) {
if (bind & (PIPE_BIND_VERTEX_BUFFER |
PIPE_BIND_INDEX_BUFFER |
PIPE_BIND_CONSTANT_BUFFER |
PIPE_BIND_STREAM_OUTPUT |
PIPE_BIND_SAMPLER_VIEW)) {
assert(nv50->num_vtxbufs <= PIPE_MAX_ATTRIBS);
for (i = 0; i < nv50->num_vtxbufs; ++i) {
@ -263,10 +273,13 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
nv50->base.pushbuf = screen->base.pushbuf;
nv50->base.client = screen->base.client;
ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_COUNT,
&nv50->bufctx_3d);
ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
if (!ret)
ret = nouveau_bufctx_new(screen->base.client, 2, &nv50->bufctx);
ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_3D_COUNT,
&nv50->bufctx_3d);
if (!ret)
ret = nouveau_bufctx_new(screen->base.client, NV50_BIND_CP_COUNT,
&nv50->bufctx_cp);
if (ret)
goto out_err;
@ -290,6 +303,7 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
pipe->draw_vbo = nv50_draw_vbo;
pipe->clear = nv50_clear;
pipe->launch_grid = nv50_launch_grid;
pipe->flush = nv50_flush;
pipe->texture_barrier = nv50_texture_barrier;
@ -335,19 +349,30 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->uniforms);
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->txc);
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->stack_bo);
if (screen->compute) {
BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->code);
BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->txc);
BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->stack_bo);
}
flags = NOUVEAU_BO_GART | NOUVEAU_BO_WR;
BCTX_REFN_bo(nv50->bufctx_3d, SCREEN, flags, screen->fence.bo);
BCTX_REFN_bo(nv50->bufctx, FENCE, flags, screen->fence.bo);
if (screen->compute)
BCTX_REFN_bo(nv50->bufctx_cp, CP_SCREEN, flags, screen->fence.bo);
nv50->base.scratch.bo_size = 2 << 20;
util_dynarray_init(&nv50->global_residents);
return pipe;
out_err:
if (nv50->bufctx_3d)
nouveau_bufctx_del(&nv50->bufctx_3d);
if (nv50->bufctx_cp)
nouveau_bufctx_del(&nv50->bufctx_cp);
if (nv50->bufctx)
nouveau_bufctx_del(&nv50->bufctx);
FREE(nv50->blit);

View file

@ -49,6 +49,10 @@
#define NV50_NEW_MIN_SAMPLES (1 << 22)
#define NV50_NEW_CONTEXT (1 << 31)
#define NV50_NEW_CP_PROGRAM (1 << 0)
#define NV50_NEW_CP_GLOBALS (1 << 1)
/* 3d bufctx (during draw_vbo, blit_3d) */
#define NV50_BIND_FB 0
#define NV50_BIND_VERTEX 1
#define NV50_BIND_VERTEX_TMP 2
@ -58,7 +62,15 @@
#define NV50_BIND_SO 53
#define NV50_BIND_SCREEN 54
#define NV50_BIND_TLS 55
#define NV50_BIND_COUNT 56
#define NV50_BIND_3D_COUNT 56
/* compute bufctx (during launch_grid) */
#define NV50_BIND_CP_GLOBAL 0
#define NV50_BIND_CP_SCREEN 1
#define NV50_BIND_CP_QUERY 2
#define NV50_BIND_CP_COUNT 3
/* bufctx for other operations */
#define NV50_BIND_2D 0
#define NV50_BIND_M2MF 0
#define NV50_BIND_FENCE 1
@ -101,8 +113,10 @@ struct nv50_context {
struct nouveau_bufctx *bufctx_3d;
struct nouveau_bufctx *bufctx;
struct nouveau_bufctx *bufctx_cp;
uint32_t dirty;
uint32_t dirty_cp; /* dirty flags for compute state */
bool cb_dirty;
struct nv50_graph_state state;
@ -115,6 +129,7 @@ struct nv50_context {
struct nv50_program *vertprog;
struct nv50_program *gmtyprog;
struct nv50_program *fragprog;
struct nv50_program *compprog;
struct nv50_constbuf constbuf[3][NV50_MAX_PIPE_CONSTBUFS];
uint16_t constbuf_dirty[3];
@ -163,6 +178,8 @@ struct nv50_context {
uint32_t cond_condmode; /* the calculated condition */
struct nv50_blitctx *blit;
struct util_dynarray global_residents;
};
static inline struct nv50_context *
@ -302,4 +319,9 @@ struct pipe_video_buffer *
nv98_video_buffer_create(struct pipe_context *pipe,
const struct pipe_video_buffer *template);
/* nv50_compute.c */
void
nv50_launch_grid(struct pipe_context *, const uint *, const uint *,
uint32_t, const void *);
#endif

View file

@ -66,7 +66,6 @@ nv50_vertprog_assign_slots(struct nv50_ir_prog_info *info)
case TGSI_SEMANTIC_VERTEXID:
prog->vp.attrs[2] |= NV50_3D_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID;
prog->vp.attrs[2] |= NV50_3D_VP_GP_BUILTIN_ATTR_EN_VERTEX_ID_DRAW_ARRAYS_ADD_START;
prog->vp.vertexid = 1;
continue;
default:
break;
@ -259,6 +258,8 @@ nv50_program_assign_varying_slots(struct nv50_ir_prog_info *info)
return nv50_vertprog_assign_slots(info);
case PIPE_SHADER_FRAGMENT:
return nv50_fragprog_assign_slots(info);
case PIPE_SHADER_COMPUTE:
return 0;
default:
return -1;
}
@ -355,6 +356,9 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
prog->gp.has_layer = 0;
prog->gp.has_viewport = 0;
if (prog->type == PIPE_SHADER_COMPUTE)
info->prop.cp.inputOffset = 0x10;
info->driverPriv = prog;
#ifdef DEBUG
@ -378,6 +382,8 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
prog->max_gpr = MAX2(4, (info->bin.maxGPR >> 1) + 1);
prog->tls_space = info->bin.tlsSpace;
prog->vp.need_vertex_id = info->io.vertexId < PIPE_MAX_SHADER_INPUTS;
if (prog->type == PIPE_SHADER_FRAGMENT) {
if (info->prop.fp.writesDepth) {
prog->fp.flags[0] |= NV50_3D_FP_CONTROL_EXPORTS_Z;
@ -401,6 +407,10 @@ nv50_program_translate(struct nv50_program *prog, uint16_t chipset,
break;
}
prog->gp.vert_count = info->prop.gp.maxVertices;
} else
if (prog->type == PIPE_SHADER_COMPUTE) {
prog->cp.syms = info->bin.syms;
prog->cp.num_syms = info->bin.numSyms;
}
if (prog->pipe.stream_output.num_outputs)
@ -423,11 +433,13 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
struct nouveau_heap *heap;
int ret;
uint32_t size = align(prog->code_size, 0x40);
uint8_t prog_type;
switch (prog->type) {
case PIPE_SHADER_VERTEX: heap = nv50->screen->vp_code_heap; break;
case PIPE_SHADER_GEOMETRY: heap = nv50->screen->gp_code_heap; break;
case PIPE_SHADER_FRAGMENT: heap = nv50->screen->fp_code_heap; break;
case PIPE_SHADER_COMPUTE: heap = nv50->screen->fp_code_heap; break;
default:
assert(!"invalid program type");
return false;
@ -450,7 +462,14 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
return false;
}
}
prog->code_base = prog->mem->start;
if (prog->type == PIPE_SHADER_COMPUTE) {
/* CP code must be uploaded in FP code segment. */
prog_type = 1;
} else {
prog->code_base = prog->mem->start;
prog_type = prog->type;
}
ret = nv50_tls_realloc(nv50->screen, prog->tls_space);
if (ret < 0) {
@ -468,7 +487,7 @@ nv50_program_upload_code(struct nv50_context *nv50, struct nv50_program *prog)
false /* flatshade */);
nv50_sifc_linear_u8(&nv50->base, nv50->screen->code,
(prog->type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
(prog_type << NV50_CODE_BO_SIZE_LOG2) + prog->code_base,
NOUVEAU_BO_VRAM, prog->code_size, prog->code);
BEGIN_NV04(nv50->base.pushbuf, NV50_3D(CODE_CB_FLUSH), 1);
@ -489,7 +508,7 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
FREE(p->code);
FREE(p->fixups);
FREE(p->interps);
FREE(p->so);
memset(p, 0, sizeof(*p));

View file

@ -76,9 +76,9 @@ struct nv50_program {
ubyte psiz; /* output slot of point size */
ubyte bfc[2]; /* indices into varying for FFC (FP) or BFC (VP) */
ubyte edgeflag;
ubyte vertexid;
ubyte clpd[2]; /* output slot of clip distance[i]'s 1st component */
ubyte clpd_nr;
bool need_vertex_id;
} vp;
struct {
@ -98,6 +98,13 @@ struct nv50_program {
ubyte viewportid; /* hw value of viewport index output */
} gp;
struct {
uint32_t lmem_size; /* local memory (TGSI PRIVATE resource) size */
uint32_t smem_size; /* shared memory (TGSI LOCAL resource) size */
void *syms;
unsigned num_syms;
} cp;
void *fixups; /* relocation records */
void *interps; /* interpolation records */

View file

@ -24,6 +24,10 @@ struct push_context {
struct translate *translate;
bool primitive_restart;
bool need_vertex_id;
int32_t index_bias;
uint32_t prim;
uint32_t restart_index;
uint32_t instance_id;
@ -74,6 +78,11 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count)
size = ctx->vertex_words * nr;
if (unlikely(ctx->need_vertex_id)) {
BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
PUSH_DATA (ctx->push, *elts + ctx->index_bias);
}
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts8(ctx->translate, elts, nr, 0, ctx->instance_id,
@ -107,6 +116,11 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count)
size = ctx->vertex_words * nr;
if (unlikely(ctx->need_vertex_id)) {
BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
PUSH_DATA (ctx->push, *elts + ctx->index_bias);
}
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts16(ctx->translate, elts, nr, 0, ctx->instance_id,
@ -140,6 +154,11 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
size = ctx->vertex_words * nr;
if (unlikely(ctx->need_vertex_id)) {
BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
PUSH_DATA (ctx->push, *elts + ctx->index_bias);
}
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run_elts(ctx->translate, elts, nr, 0, ctx->instance_id,
@ -161,10 +180,18 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count)
static void
emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count)
{
uint32_t elts = 0;
while (count) {
unsigned push = MIN2(count, ctx->packet_vertex_limit);
unsigned size = ctx->vertex_words * push;
if (unlikely(ctx->need_vertex_id)) {
/* For non-indexed draws, gl_VertexID goes up after each vertex. */
BEGIN_NV04(ctx->push, NV84_3D(VERTEX_ID_BASE), 1);
PUSH_DATA (ctx->push, elts++);
}
BEGIN_NI04(ctx->push, NV50_3D(VERTEX_DATA), size);
ctx->translate->run(ctx->translate, start, push, 0, ctx->instance_id,
@ -216,7 +243,14 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
ctx.push = nv50->base.pushbuf;
ctx.translate = nv50->vertex->translate;
ctx.packet_vertex_limit = nv50->vertex->packet_vertex_limit;
ctx.need_vertex_id = nv50->screen->base.class_3d >= NV84_3D_CLASS &&
nv50->vertprog->vp.need_vertex_id && (nv50->vertex->num_elements < 32);
ctx.index_bias = info->index_bias;
/* For indexed draws, gl_VertexID must be emitted for every vertex. */
ctx.packet_vertex_limit =
ctx.need_vertex_id ? 1 : nv50->vertex->packet_vertex_limit;
ctx.vertex_words = nv50->vertex->vertex_size;
assert(nv50->num_vtxbufs <= PIPE_MAX_ATTRIBS);
@ -307,4 +341,10 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info)
ctx.instance_id++;
ctx.prim |= NV50_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT;
}
if (unlikely(ctx.need_vertex_id)) {
/* Reset gl_VertexID to prevent future indexed draws to be confused. */
BEGIN_NV04(ctx.push, NV84_3D(VERTEX_ID_BASE), 1);
PUSH_DATA (ctx.push, nv50->state.index_bias);
}
}

View file

@ -27,6 +27,8 @@
#include "nv50/nv50_context.h"
#include "nv50/nv50_query.h"
#include "nv50/nv50_query_hw.h"
#include "nv50/nv50_query_hw_metric.h"
#include "nv50/nv50_query_hw_sm.h"
static struct pipe_query *
nv50_create_query(struct pipe_context *pipe, unsigned type, unsigned index)
@ -152,4 +154,79 @@ nv50_init_query_functions(struct nv50_context *nv50)
pipe->end_query = nv50_end_query;
pipe->get_query_result = nv50_get_query_result;
pipe->render_condition = nv50_render_condition;
nv50->cond_condmode = NV50_3D_COND_MODE_ALWAYS;
}
int
nv50_screen_get_driver_query_info(struct pipe_screen *pscreen,
unsigned id,
struct pipe_driver_query_info *info)
{
struct nv50_screen *screen = nv50_screen(pscreen);
int num_hw_queries = 0;
num_hw_queries = nv50_hw_get_driver_query_info(screen, 0, NULL);
if (!info)
return num_hw_queries;
/* Init default values. */
info->name = "this_is_not_the_query_you_are_looking_for";
info->query_type = 0xdeadd01d;
info->max_value.u64 = 0;
info->type = PIPE_DRIVER_QUERY_TYPE_UINT64;
info->group_id = -1;
info->flags = 0;
return nv50_hw_get_driver_query_info(screen, id, info);
}
int
nv50_screen_get_driver_query_group_info(struct pipe_screen *pscreen,
unsigned id,
struct pipe_driver_query_group_info *info)
{
struct nv50_screen *screen = nv50_screen(pscreen);
int count = 0;
if (screen->compute)
if (screen->base.class_3d >= NV84_3D_CLASS)
count += 2;
if (!info)
return count;
if (id == NV50_HW_SM_QUERY_GROUP) {
if (screen->compute) {
if (screen->base.class_3d >= NV84_3D_CLASS) {
info->name = "MP counters";
/* Because we can't expose the number of hardware counters needed
* for each different query, we don't want to allow more than one
* active query simultaneously to avoid failure when the maximum
* number of counters is reached. Note that these groups of GPU
* counters are currently only used by AMD_performance_monitor.
*/
info->max_active_queries = 1;
info->num_queries = NV50_HW_SM_QUERY_COUNT;
return 1;
}
}
} else
if (id == NV50_HW_METRIC_QUERY_GROUP) {
if (screen->compute) {
if (screen->base.class_3d >= NV84_3D_CLASS) {
info->name = "Performance metrics";
info->max_active_queries = 1;
info->num_queries = NV50_HW_METRIC_QUERY_COUNT;
return 1;
}
}
}
/* user asked for info about non-existing query group */
info->name = "this_is_not_the_query_group_you_are_looking_for";
info->max_active_queries = 0;
info->num_queries = 0;
return 0;
}

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