/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/Automake.inc |
---|
0,0 → 1,11 |
if HAVE_GALLIUM_I915 |
TARGET_DRIVERS += i915 |
TARGET_CPPFLAGS += -DGALLIUM_I915 |
TARGET_LIB_DEPS += \ |
$(top_builddir)/src/gallium/winsys/i915/drm/libi915drm.la \ |
$(top_builddir)/src/gallium/drivers/i915/libi915.la \ |
$(INTEL_LIBS) \ |
$(LIBDRM_LIBS) |
endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/Makefile.am |
---|
0,0 → 1,33 |
# Copyright © 2012 Intel Corporation |
# |
# Permission is hereby granted, free of charge, to any person obtaining a |
# copy of this software and associated documentation files (the "Software"), |
# to deal in the Software without restriction, including without limitation |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
# and/or sell copies of the Software, and to permit persons to whom the |
# Software is furnished to do so, subject to the following conditions: |
# |
# The above copyright notice and this permission notice (including the next |
# paragraph) shall be included in all copies or substantial portions of the |
# Software. |
# |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
# DEALINGS IN THE SOFTWARE. |
include Makefile.sources |
include $(top_srcdir)/src/gallium/Automake.inc |
AM_CFLAGS = \ |
$(GALLIUM_DRIVER_CFLAGS) |
noinst_LTLIBRARIES = libi915.la |
libi915_la_SOURCES = $(C_SOURCES) |
EXTRA_DIST = TODO |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/Makefile.in |
---|
0,0 → 1,932 |
# Makefile.in generated by automake 1.15 from Makefile.am. |
# @configure_input@ |
# Copyright (C) 1994-2014 Free Software Foundation, Inc. |
# This Makefile.in is free software; the Free Software Foundation |
# gives unlimited permission to copy and/or distribute it, |
# with or without modifications, as long as this notice is preserved. |
# This program is distributed in the hope that it will be useful, |
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without |
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A |
# PARTICULAR PURPOSE. |
@SET_MAKE@ |
# Copyright © 2012 Intel Corporation |
# |
# Permission is hereby granted, free of charge, to any person obtaining a |
# copy of this software and associated documentation files (the "Software"), |
# to deal in the Software without restriction, including without limitation |
# the rights to use, copy, modify, merge, publish, distribute, sublicense, |
# and/or sell copies of the Software, and to permit persons to whom the |
# Software is furnished to do so, subject to the following conditions: |
# |
# The above copyright notice and this permission notice (including the next |
# paragraph) shall be included in all copies or substantial portions of the |
# Software. |
# |
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
# DEALINGS IN THE SOFTWARE. |
VPATH = @srcdir@ |
am__is_gnu_make = { \ |
if test -z '$(MAKELEVEL)'; then \ |
false; \ |
elif test -n '$(MAKE_HOST)'; then \ |
true; \ |
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ |
true; \ |
else \ |
false; \ |
fi; \ |
} |
am__make_running_with_option = \ |
case $${target_option-} in \ |
?) ;; \ |
*) echo "am__make_running_with_option: internal error: invalid" \ |
"target option '$${target_option-}' specified" >&2; \ |
exit 1;; \ |
esac; \ |
has_opt=no; \ |
sane_makeflags=$$MAKEFLAGS; \ |
if $(am__is_gnu_make); then \ |
sane_makeflags=$$MFLAGS; \ |
else \ |
case $$MAKEFLAGS in \ |
*\\[\ \ ]*) \ |
bs=\\; \ |
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ |
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ |
esac; \ |
fi; \ |
skip_next=no; \ |
strip_trailopt () \ |
{ \ |
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ |
}; \ |
for flg in $$sane_makeflags; do \ |
test $$skip_next = yes && { skip_next=no; continue; }; \ |
case $$flg in \ |
*=*|--*) continue;; \ |
-*I) strip_trailopt 'I'; skip_next=yes;; \ |
-*I?*) strip_trailopt 'I';; \ |
-*O) strip_trailopt 'O'; skip_next=yes;; \ |
-*O?*) strip_trailopt 'O';; \ |
-*l) strip_trailopt 'l'; skip_next=yes;; \ |
-*l?*) strip_trailopt 'l';; \ |
-[dEDm]) skip_next=yes;; \ |
-[JT]) skip_next=yes;; \ |
esac; \ |
case $$flg in \ |
*$$target_option*) has_opt=yes; break;; \ |
esac; \ |
done; \ |
test $$has_opt = yes |
am__make_dryrun = (target_option=n; $(am__make_running_with_option)) |
am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) |
pkgdatadir = $(datadir)/@PACKAGE@ |
pkgincludedir = $(includedir)/@PACKAGE@ |
pkglibdir = $(libdir)/@PACKAGE@ |
pkglibexecdir = $(libexecdir)/@PACKAGE@ |
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd |
install_sh_DATA = $(install_sh) -c -m 644 |
install_sh_PROGRAM = $(install_sh) -c |
install_sh_SCRIPT = $(install_sh) -c |
INSTALL_HEADER = $(INSTALL_DATA) |
transform = $(program_transform_name) |
NORMAL_INSTALL = : |
PRE_INSTALL = : |
POST_INSTALL = : |
NORMAL_UNINSTALL = : |
PRE_UNINSTALL = : |
POST_UNINSTALL = : |
build_triplet = @build@ |
host_triplet = @host@ |
target_triplet = @target@ |
@HAVE_DRISW_TRUE@am__append_1 = \ |
@HAVE_DRISW_TRUE@ $(top_builddir)/src/gallium/winsys/sw/dri/libswdri.la |
@NEED_WINSYS_XLIB_TRUE@am__append_2 = \ |
@NEED_WINSYS_XLIB_TRUE@ $(top_builddir)/src/gallium/winsys/sw/xlib/libws_xlib.la \ |
@NEED_WINSYS_XLIB_TRUE@ -lX11 -lXext -lXfixes \ |
@NEED_WINSYS_XLIB_TRUE@ $(LIBDRM_LIBS) |
subdir = src/gallium/drivers/i915 |
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 |
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gnu_make.m4 \ |
$(top_srcdir)/m4/ax_check_python_mako_module.m4 \ |
$(top_srcdir)/m4/ax_gcc_builtin.m4 \ |
$(top_srcdir)/m4/ax_gcc_func_attribute.m4 \ |
$(top_srcdir)/m4/ax_prog_bison.m4 \ |
$(top_srcdir)/m4/ax_prog_flex.m4 \ |
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/libtool.m4 \ |
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ |
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ |
$(top_srcdir)/VERSION $(top_srcdir)/configure.ac |
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ |
$(ACLOCAL_M4) |
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) |
mkinstalldirs = $(install_sh) -d |
CONFIG_CLEAN_FILES = |
CONFIG_CLEAN_VPATH_FILES = |
LTLIBRARIES = $(noinst_LTLIBRARIES) |
libi915_la_LIBADD = |
am__objects_1 = i915_blit.lo i915_clear.lo i915_context.lo \ |
i915_debug.lo i915_debug_fp.lo i915_flush.lo i915_fpc_emit.lo \ |
i915_fpc_optimize.lo i915_fpc_translate.lo i915_prim_emit.lo \ |
i915_prim_vbuf.lo i915_query.lo i915_resource_buffer.lo \ |
i915_resource.lo i915_resource_texture.lo i915_screen.lo \ |
i915_state.lo i915_state_derived.lo i915_state_dynamic.lo \ |
i915_state_emit.lo i915_state_fpc.lo i915_state_immediate.lo \ |
i915_state_sampler.lo i915_state_static.lo i915_surface.lo |
am_libi915_la_OBJECTS = $(am__objects_1) |
libi915_la_OBJECTS = $(am_libi915_la_OBJECTS) |
AM_V_lt = $(am__v_lt_@AM_V@) |
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) |
am__v_lt_0 = --silent |
am__v_lt_1 = |
AM_V_P = $(am__v_P_@AM_V@) |
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) |
am__v_P_0 = false |
am__v_P_1 = : |
AM_V_GEN = $(am__v_GEN_@AM_V@) |
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) |
am__v_GEN_0 = @echo " GEN " $@; |
am__v_GEN_1 = |
AM_V_at = $(am__v_at_@AM_V@) |
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) |
am__v_at_0 = @ |
am__v_at_1 = |
DEFAULT_INCLUDES = -I.@am__isrc@ |
depcomp = $(SHELL) $(top_srcdir)/bin/depcomp |
am__depfiles_maybe = depfiles |
am__mv = mv -f |
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ |
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) |
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ |
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ |
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ |
$(AM_CFLAGS) $(CFLAGS) |
AM_V_CC = $(am__v_CC_@AM_V@) |
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) |
am__v_CC_0 = @echo " CC " $@; |
am__v_CC_1 = |
CCLD = $(CC) |
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ |
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ |
$(AM_LDFLAGS) $(LDFLAGS) -o $@ |
AM_V_CCLD = $(am__v_CCLD_@AM_V@) |
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) |
am__v_CCLD_0 = @echo " CCLD " $@; |
am__v_CCLD_1 = |
SOURCES = $(libi915_la_SOURCES) |
DIST_SOURCES = $(libi915_la_SOURCES) |
am__can_run_installinfo = \ |
case $$AM_UPDATE_INFO_DIR in \ |
n|no|NO) false;; \ |
*) (install-info --version) >/dev/null 2>&1;; \ |
esac |
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) |
# Read a list of newline-separated strings from the standard input, |
# and print each of them once, without duplicates. Input order is |
# *not* preserved. |
am__uniquify_input = $(AWK) '\ |
BEGIN { nonempty = 0; } \ |
{ items[$$0] = 1; nonempty = 1; } \ |
END { if (nonempty) { for (i in items) print i; }; } \ |
' |
# Make sure the list of sources is unique. This is necessary because, |
# e.g., the same source file might be shared among _SOURCES variables |
# for different programs/libraries. |
am__define_uniq_tagged_files = \ |
list='$(am__tagged_files)'; \ |
unique=`for i in $$list; do \ |
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ |
done | $(am__uniquify_input)` |
ETAGS = etags |
CTAGS = ctags |
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.sources \ |
$(top_srcdir)/bin/depcomp \ |
$(top_srcdir)/src/gallium/Automake.inc TODO |
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) |
ACLOCAL = @ACLOCAL@ |
AMTAR = @AMTAR@ |
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ |
AR = @AR@ |
AUTOCONF = @AUTOCONF@ |
AUTOHEADER = @AUTOHEADER@ |
AUTOMAKE = @AUTOMAKE@ |
AWK = @AWK@ |
BSYMBOLIC = @BSYMBOLIC@ |
CC = @CC@ |
CCAS = @CCAS@ |
CCASDEPMODE = @CCASDEPMODE@ |
CCASFLAGS = @CCASFLAGS@ |
CCDEPMODE = @CCDEPMODE@ |
CFLAGS = @CFLAGS@ |
CLANG_RESOURCE_DIR = @CLANG_RESOURCE_DIR@ |
CLOCK_LIB = @CLOCK_LIB@ |
CPP = @CPP@ |
CPPFLAGS = @CPPFLAGS@ |
CXX = @CXX@ |
CXXCPP = @CXXCPP@ |
CXXDEPMODE = @CXXDEPMODE@ |
CXXFLAGS = @CXXFLAGS@ |
CYGPATH_W = @CYGPATH_W@ |
D3D_DRIVER_INSTALL_DIR = @D3D_DRIVER_INSTALL_DIR@ |
DEFINES = @DEFINES@ |
DEFS = @DEFS@ |
DEPDIR = @DEPDIR@ |
DLLTOOL = @DLLTOOL@ |
DLOPEN_LIBS = @DLOPEN_LIBS@ |
DRI2PROTO_CFLAGS = @DRI2PROTO_CFLAGS@ |
DRI2PROTO_LIBS = @DRI2PROTO_LIBS@ |
DRI3PROTO_CFLAGS = @DRI3PROTO_CFLAGS@ |
DRI3PROTO_LIBS = @DRI3PROTO_LIBS@ |
DRIGL_CFLAGS = @DRIGL_CFLAGS@ |
DRIGL_LIBS = @DRIGL_LIBS@ |
DRI_DRIVER_INSTALL_DIR = @DRI_DRIVER_INSTALL_DIR@ |
DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@ |
DRI_LIB_DEPS = @DRI_LIB_DEPS@ |
DRI_PC_REQ_PRIV = @DRI_PC_REQ_PRIV@ |
DSYMUTIL = @DSYMUTIL@ |
DUMPBIN = @DUMPBIN@ |
ECHO_C = @ECHO_C@ |
ECHO_N = @ECHO_N@ |
ECHO_T = @ECHO_T@ |
EGL_CFLAGS = @EGL_CFLAGS@ |
EGL_CLIENT_APIS = @EGL_CLIENT_APIS@ |
EGL_LIB_DEPS = @EGL_LIB_DEPS@ |
EGL_NATIVE_PLATFORM = @EGL_NATIVE_PLATFORM@ |
EGREP = @EGREP@ |
ELF_LIB = @ELF_LIB@ |
EXEEXT = @EXEEXT@ |
EXPAT_CFLAGS = @EXPAT_CFLAGS@ |
EXPAT_LIBS = @EXPAT_LIBS@ |
FGREP = @FGREP@ |
FREEDRENO_CFLAGS = @FREEDRENO_CFLAGS@ |
FREEDRENO_LIBS = @FREEDRENO_LIBS@ |
GALLIUM_PIPE_LOADER_CLIENT_DEFINES = @GALLIUM_PIPE_LOADER_CLIENT_DEFINES@ |
GALLIUM_PIPE_LOADER_CLIENT_LIBS = @GALLIUM_PIPE_LOADER_CLIENT_LIBS@ |
GALLIUM_PIPE_LOADER_DEFINES = @GALLIUM_PIPE_LOADER_DEFINES@ |
GALLIUM_PIPE_LOADER_LIBS = @GALLIUM_PIPE_LOADER_LIBS@ |
GALLIUM_PIPE_LOADER_XCB_CFLAGS = @GALLIUM_PIPE_LOADER_XCB_CFLAGS@ |
GALLIUM_PIPE_LOADER_XCB_LIBS = @GALLIUM_PIPE_LOADER_XCB_LIBS@ |
GBM_PC_LIB_PRIV = @GBM_PC_LIB_PRIV@ |
GBM_PC_REQ_PRIV = @GBM_PC_REQ_PRIV@ |
GC_SECTIONS = @GC_SECTIONS@ |
GLESv1_CM_LIB_DEPS = @GLESv1_CM_LIB_DEPS@ |
GLESv1_CM_PC_LIB_PRIV = @GLESv1_CM_PC_LIB_PRIV@ |
GLESv2_LIB_DEPS = @GLESv2_LIB_DEPS@ |
GLESv2_PC_LIB_PRIV = @GLESv2_PC_LIB_PRIV@ |
GLPROTO_CFLAGS = @GLPROTO_CFLAGS@ |
GLPROTO_LIBS = @GLPROTO_LIBS@ |
GLX_TLS = @GLX_TLS@ |
GL_LIB = @GL_LIB@ |
GL_LIB_DEPS = @GL_LIB_DEPS@ |
GL_PC_CFLAGS = @GL_PC_CFLAGS@ |
GL_PC_LIB_PRIV = @GL_PC_LIB_PRIV@ |
GL_PC_REQ_PRIV = @GL_PC_REQ_PRIV@ |
GREP = @GREP@ |
HAVE_XF86VIDMODE = @HAVE_XF86VIDMODE@ |
INDENT = @INDENT@ |
INDENT_FLAGS = @INDENT_FLAGS@ |
INSTALL = @INSTALL@ |
INSTALL_DATA = @INSTALL_DATA@ |
INSTALL_PROGRAM = @INSTALL_PROGRAM@ |
INSTALL_SCRIPT = @INSTALL_SCRIPT@ |
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ |
INTEL_CFLAGS = @INTEL_CFLAGS@ |
INTEL_LIBS = @INTEL_LIBS@ |
LD = @LD@ |
LDFLAGS = @LDFLAGS@ |
LD_NO_UNDEFINED = @LD_NO_UNDEFINED@ |
LEX = @LEX@ |
LEXLIB = @LEXLIB@ |
LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ |
LIBCLC_INCLUDEDIR = @LIBCLC_INCLUDEDIR@ |
LIBCLC_LIBEXECDIR = @LIBCLC_LIBEXECDIR@ |
LIBDRM_CFLAGS = @LIBDRM_CFLAGS@ |
LIBDRM_LIBS = @LIBDRM_LIBS@ |
LIBOBJS = @LIBOBJS@ |
LIBS = @LIBS@ |
LIBSHA1_CFLAGS = @LIBSHA1_CFLAGS@ |
LIBSHA1_LIBS = @LIBSHA1_LIBS@ |
LIBTOOL = @LIBTOOL@ |
LIBUDEV_CFLAGS = @LIBUDEV_CFLAGS@ |
LIBUDEV_LIBS = @LIBUDEV_LIBS@ |
LIB_DIR = @LIB_DIR@ |
LIB_EXT = @LIB_EXT@ |
LIPO = @LIPO@ |
LLVM_BINDIR = @LLVM_BINDIR@ |
LLVM_CFLAGS = @LLVM_CFLAGS@ |
LLVM_CONFIG = @LLVM_CONFIG@ |
LLVM_CPPFLAGS = @LLVM_CPPFLAGS@ |
LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ |
LLVM_INCLUDEDIR = @LLVM_INCLUDEDIR@ |
LLVM_LDFLAGS = @LLVM_LDFLAGS@ |
LLVM_LIBDIR = @LLVM_LIBDIR@ |
LLVM_LIBS = @LLVM_LIBS@ |
LLVM_VERSION = @LLVM_VERSION@ |
LN_S = @LN_S@ |
LTLIBOBJS = @LTLIBOBJS@ |
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ |
MAKEINFO = @MAKEINFO@ |
MANIFEST_TOOL = @MANIFEST_TOOL@ |
MESA_LLVM = @MESA_LLVM@ |
MKDIR_P = @MKDIR_P@ |
MSVC2008_COMPAT_CFLAGS = @MSVC2008_COMPAT_CFLAGS@ |
MSVC2008_COMPAT_CXXFLAGS = @MSVC2008_COMPAT_CXXFLAGS@ |
MSVC2013_COMPAT_CFLAGS = @MSVC2013_COMPAT_CFLAGS@ |
MSVC2013_COMPAT_CXXFLAGS = @MSVC2013_COMPAT_CXXFLAGS@ |
NINE_MAJOR = @NINE_MAJOR@ |
NINE_MINOR = @NINE_MINOR@ |
NINE_TINY = @NINE_TINY@ |
NINE_VERSION = @NINE_VERSION@ |
NM = @NM@ |
NMEDIT = @NMEDIT@ |
NOUVEAU_CFLAGS = @NOUVEAU_CFLAGS@ |
NOUVEAU_LIBS = @NOUVEAU_LIBS@ |
OBJDUMP = @OBJDUMP@ |
OBJEXT = @OBJEXT@ |
OMX_CFLAGS = @OMX_CFLAGS@ |
OMX_LIBS = @OMX_LIBS@ |
OMX_LIB_INSTALL_DIR = @OMX_LIB_INSTALL_DIR@ |
OPENCL_LIBNAME = @OPENCL_LIBNAME@ |
OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ |
OPENSSL_LIBS = @OPENSSL_LIBS@ |
OSMESA_LIB = @OSMESA_LIB@ |
OSMESA_LIB_DEPS = @OSMESA_LIB_DEPS@ |
OSMESA_PC_LIB_PRIV = @OSMESA_PC_LIB_PRIV@ |
OSMESA_PC_REQ = @OSMESA_PC_REQ@ |
OSMESA_VERSION = @OSMESA_VERSION@ |
OTOOL = @OTOOL@ |
OTOOL64 = @OTOOL64@ |
PACKAGE = @PACKAGE@ |
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ |
PACKAGE_NAME = @PACKAGE_NAME@ |
PACKAGE_STRING = @PACKAGE_STRING@ |
PACKAGE_TARNAME = @PACKAGE_TARNAME@ |
PACKAGE_URL = @PACKAGE_URL@ |
PACKAGE_VERSION = @PACKAGE_VERSION@ |
PATH_SEPARATOR = @PATH_SEPARATOR@ |
PKG_CONFIG = @PKG_CONFIG@ |
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ |
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ |
POSIX_SHELL = @POSIX_SHELL@ |
PRESENTPROTO_CFLAGS = @PRESENTPROTO_CFLAGS@ |
PRESENTPROTO_LIBS = @PRESENTPROTO_LIBS@ |
PTHREAD_CC = @PTHREAD_CC@ |
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ |
PTHREAD_LIBS = @PTHREAD_LIBS@ |
PYTHON2 = @PYTHON2@ |
RADEON_CFLAGS = @RADEON_CFLAGS@ |
RADEON_LIBS = @RADEON_LIBS@ |
RANLIB = @RANLIB@ |
SED = @SED@ |
SELINUX_CFLAGS = @SELINUX_CFLAGS@ |
SELINUX_LIBS = @SELINUX_LIBS@ |
SET_MAKE = @SET_MAKE@ |
SHA1_CFLAGS = @SHA1_CFLAGS@ |
SHA1_LIBS = @SHA1_LIBS@ |
SHELL = @SHELL@ |
SSE41_CFLAGS = @SSE41_CFLAGS@ |
STRIP = @STRIP@ |
VA_CFLAGS = @VA_CFLAGS@ |
VA_LIBS = @VA_LIBS@ |
VA_LIB_INSTALL_DIR = @VA_LIB_INSTALL_DIR@ |
VA_MAJOR = @VA_MAJOR@ |
VA_MINOR = @VA_MINOR@ |
VDPAU_CFLAGS = @VDPAU_CFLAGS@ |
VDPAU_LIBS = @VDPAU_LIBS@ |
VDPAU_LIB_INSTALL_DIR = @VDPAU_LIB_INSTALL_DIR@ |
VDPAU_MAJOR = @VDPAU_MAJOR@ |
VDPAU_MINOR = @VDPAU_MINOR@ |
VERSION = @VERSION@ |
VG_LIB_DEPS = @VG_LIB_DEPS@ |
VISIBILITY_CFLAGS = @VISIBILITY_CFLAGS@ |
VISIBILITY_CXXFLAGS = @VISIBILITY_CXXFLAGS@ |
VL_CFLAGS = @VL_CFLAGS@ |
VL_LIBS = @VL_LIBS@ |
WAYLAND_CFLAGS = @WAYLAND_CFLAGS@ |
WAYLAND_LIBS = @WAYLAND_LIBS@ |
WAYLAND_SCANNER = @WAYLAND_SCANNER@ |
WAYLAND_SCANNER_CFLAGS = @WAYLAND_SCANNER_CFLAGS@ |
WAYLAND_SCANNER_LIBS = @WAYLAND_SCANNER_LIBS@ |
X11_INCLUDES = @X11_INCLUDES@ |
XA_MAJOR = @XA_MAJOR@ |
XA_MINOR = @XA_MINOR@ |
XA_TINY = @XA_TINY@ |
XA_VERSION = @XA_VERSION@ |
XCB_DRI2_CFLAGS = @XCB_DRI2_CFLAGS@ |
XCB_DRI2_LIBS = @XCB_DRI2_LIBS@ |
XF86VIDMODE_CFLAGS = @XF86VIDMODE_CFLAGS@ |
XF86VIDMODE_LIBS = @XF86VIDMODE_LIBS@ |
XLIBGL_CFLAGS = @XLIBGL_CFLAGS@ |
XLIBGL_LIBS = @XLIBGL_LIBS@ |
XVMC_CFLAGS = @XVMC_CFLAGS@ |
XVMC_LIBS = @XVMC_LIBS@ |
XVMC_LIB_INSTALL_DIR = @XVMC_LIB_INSTALL_DIR@ |
XVMC_MAJOR = @XVMC_MAJOR@ |
XVMC_MINOR = @XVMC_MINOR@ |
YACC = @YACC@ |
YFLAGS = @YFLAGS@ |
abs_builddir = @abs_builddir@ |
abs_srcdir = @abs_srcdir@ |
abs_top_builddir = @abs_top_builddir@ |
abs_top_srcdir = @abs_top_srcdir@ |
ac_ct_AR = @ac_ct_AR@ |
ac_ct_CC = @ac_ct_CC@ |
ac_ct_CXX = @ac_ct_CXX@ |
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ |
acv_mako_found = @acv_mako_found@ |
am__include = @am__include@ |
am__leading_dot = @am__leading_dot@ |
am__quote = @am__quote@ |
am__tar = @am__tar@ |
am__untar = @am__untar@ |
ax_pthread_config = @ax_pthread_config@ |
bindir = @bindir@ |
build = @build@ |
build_alias = @build_alias@ |
build_cpu = @build_cpu@ |
build_os = @build_os@ |
build_vendor = @build_vendor@ |
builddir = @builddir@ |
datadir = @datadir@ |
datarootdir = @datarootdir@ |
docdir = @docdir@ |
dvidir = @dvidir@ |
exec_prefix = @exec_prefix@ |
host = @host@ |
host_alias = @host_alias@ |
host_cpu = @host_cpu@ |
host_os = @host_os@ |
host_vendor = @host_vendor@ |
htmldir = @htmldir@ |
ifGNUmake = @ifGNUmake@ |
includedir = @includedir@ |
infodir = @infodir@ |
install_sh = @install_sh@ |
libdir = @libdir@ |
libexecdir = @libexecdir@ |
localedir = @localedir@ |
localstatedir = @localstatedir@ |
mandir = @mandir@ |
mkdir_p = @mkdir_p@ |
oldincludedir = @oldincludedir@ |
pdfdir = @pdfdir@ |
prefix = @prefix@ |
program_transform_name = @program_transform_name@ |
psdir = @psdir@ |
sbindir = @sbindir@ |
sharedstatedir = @sharedstatedir@ |
srcdir = @srcdir@ |
sysconfdir = @sysconfdir@ |
target = @target@ |
target_alias = @target_alias@ |
target_cpu = @target_cpu@ |
target_os = @target_os@ |
target_vendor = @target_vendor@ |
top_build_prefix = @top_build_prefix@ |
top_builddir = @top_builddir@ |
top_srcdir = @top_srcdir@ |
C_SOURCES := \ |
i915_batchbuffer.h \ |
i915_batch.h \ |
i915_blit.c \ |
i915_blit.h \ |
i915_clear.c \ |
i915_context.c \ |
i915_context.h \ |
i915_debug.c \ |
i915_debug_fp.c \ |
i915_debug.h \ |
i915_debug_private.h \ |
i915_flush.c \ |
i915_fpc_emit.c \ |
i915_fpc.h \ |
i915_fpc_optimize.c \ |
i915_fpc_translate.c \ |
i915_prim_emit.c \ |
i915_prim_vbuf.c \ |
i915_public.h \ |
i915_query.c \ |
i915_query.h \ |
i915_reg.h \ |
i915_resource_buffer.c \ |
i915_resource.c \ |
i915_resource.h \ |
i915_resource_texture.c \ |
i915_screen.c \ |
i915_screen.h \ |
i915_state.c \ |
i915_state_derived.c \ |
i915_state_dynamic.c \ |
i915_state_emit.c \ |
i915_state_fpc.c \ |
i915_state.h \ |
i915_state_immediate.c \ |
i915_state_inlines.h \ |
i915_state_sampler.c \ |
i915_state_static.c \ |
i915_surface.c \ |
i915_surface.h \ |
i915_winsys.h |
GALLIUM_CFLAGS = \ |
-I$(top_srcdir)/include \ |
-I$(top_srcdir)/src \ |
-I$(top_srcdir)/src/gallium/include \ |
-I$(top_srcdir)/src/gallium/auxiliary \ |
$(DEFINES) |
# src/gallium/auxiliary must appear before src/gallium/drivers |
# because there are stupidly two rbug_context.h files in |
# different directories, and which one is included by the |
# preprocessor is determined by the ordering of the -I flags. |
GALLIUM_DRIVER_CFLAGS = \ |
-I$(srcdir)/include \ |
-I$(top_srcdir)/src \ |
-I$(top_srcdir)/include \ |
-I$(top_srcdir)/src/gallium/include \ |
-I$(top_srcdir)/src/gallium/auxiliary \ |
-I$(top_srcdir)/src/gallium/drivers \ |
-I$(top_srcdir)/src/gallium/winsys \ |
$(DEFINES) \ |
$(VISIBILITY_CFLAGS) |
GALLIUM_DRIVER_CXXFLAGS = \ |
-I$(srcdir)/include \ |
-I$(top_srcdir)/src \ |
-I$(top_srcdir)/include \ |
-I$(top_srcdir)/src/gallium/include \ |
-I$(top_srcdir)/src/gallium/auxiliary \ |
-I$(top_srcdir)/src/gallium/drivers \ |
-I$(top_srcdir)/src/gallium/winsys \ |
$(DEFINES) \ |
$(VISIBILITY_CXXFLAGS) |
GALLIUM_TARGET_CFLAGS = \ |
-I$(top_srcdir)/src \ |
-I$(top_srcdir)/include \ |
-I$(top_srcdir)/src/loader \ |
-I$(top_srcdir)/src/gallium/include \ |
-I$(top_srcdir)/src/gallium/auxiliary \ |
-I$(top_srcdir)/src/gallium/drivers \ |
-I$(top_srcdir)/src/gallium/winsys \ |
$(DEFINES) \ |
$(PTHREAD_CFLAGS) \ |
$(LIBDRM_CFLAGS) \ |
$(VISIBILITY_CFLAGS) |
GALLIUM_COMMON_LIB_DEPS = \ |
-lm \ |
$(CLOCK_LIB) \ |
$(PTHREAD_LIBS) \ |
$(DLOPEN_LIBS) |
GALLIUM_WINSYS_CFLAGS = \ |
-I$(top_srcdir)/src \ |
-I$(top_srcdir)/include \ |
-I$(top_srcdir)/src/gallium/include \ |
-I$(top_srcdir)/src/gallium/auxiliary \ |
$(DEFINES) \ |
$(VISIBILITY_CFLAGS) |
GALLIUM_PIPE_LOADER_WINSYS_LIBS = \ |
$(top_builddir)/src/gallium/winsys/sw/null/libws_null.la \ |
$(top_builddir)/src/gallium/winsys/sw/wrapper/libwsw.la \ |
$(am__append_1) $(am__append_2) |
AM_CFLAGS = \ |
$(GALLIUM_DRIVER_CFLAGS) |
noinst_LTLIBRARIES = libi915.la |
libi915_la_SOURCES = $(C_SOURCES) |
EXTRA_DIST = TODO |
all: all-am |
.SUFFIXES: |
.SUFFIXES: .c .lo .o .obj |
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/Makefile.sources $(top_srcdir)/src/gallium/Automake.inc $(am__configure_deps) |
@for dep in $?; do \ |
case '$(am__configure_deps)' in \ |
*$$dep*) \ |
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ |
&& { if test -f $@; then exit 0; else break; fi; }; \ |
exit 1;; \ |
esac; \ |
done; \ |
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/gallium/drivers/i915/Makefile'; \ |
$(am__cd) $(top_srcdir) && \ |
$(AUTOMAKE) --foreign src/gallium/drivers/i915/Makefile |
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status |
@case '$?' in \ |
*config.status*) \ |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ |
*) \ |
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ |
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ |
esac; |
$(srcdir)/Makefile.sources $(top_srcdir)/src/gallium/Automake.inc $(am__empty): |
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
$(top_srcdir)/configure: $(am__configure_deps) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
$(ACLOCAL_M4): $(am__aclocal_m4_deps) |
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh |
$(am__aclocal_m4_deps): |
clean-noinstLTLIBRARIES: |
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) |
@list='$(noinst_LTLIBRARIES)'; \ |
locs=`for p in $$list; do echo $$p; done | \ |
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ |
sort -u`; \ |
test -z "$$locs" || { \ |
echo rm -f $${locs}; \ |
rm -f $${locs}; \ |
} |
libi915.la: $(libi915_la_OBJECTS) $(libi915_la_DEPENDENCIES) $(EXTRA_libi915_la_DEPENDENCIES) |
$(AM_V_CCLD)$(LINK) $(libi915_la_OBJECTS) $(libi915_la_LIBADD) $(LIBS) |
mostlyclean-compile: |
-rm -f *.$(OBJEXT) |
distclean-compile: |
-rm -f *.tab.c |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_blit.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_clear.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_context.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_debug.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_debug_fp.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_flush.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_fpc_emit.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_fpc_optimize.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_fpc_translate.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_prim_emit.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_prim_vbuf.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_query.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_resource.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_resource_buffer.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_resource_texture.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_screen.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_derived.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_dynamic.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_emit.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_fpc.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_immediate.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_sampler.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_state_static.Plo@am__quote@ |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/i915_surface.Plo@am__quote@ |
.c.o: |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< |
.c.obj: |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` |
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` |
.c.lo: |
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< |
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ |
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ |
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< |
mostlyclean-libtool: |
-rm -f *.lo |
clean-libtool: |
-rm -rf .libs _libs |
ID: $(am__tagged_files) |
$(am__define_uniq_tagged_files); mkid -fID $$unique |
tags: tags-am |
TAGS: tags |
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) |
set x; \ |
here=`pwd`; \ |
$(am__define_uniq_tagged_files); \ |
shift; \ |
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ |
test -n "$$unique" || unique=$$empty_fix; \ |
if test $$# -gt 0; then \ |
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
"$$@" $$unique; \ |
else \ |
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ |
$$unique; \ |
fi; \ |
fi |
ctags: ctags-am |
CTAGS: ctags |
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) |
$(am__define_uniq_tagged_files); \ |
test -z "$(CTAGS_ARGS)$$unique" \ |
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ |
$$unique |
GTAGS: |
here=`$(am__cd) $(top_builddir) && pwd` \ |
&& $(am__cd) $(top_srcdir) \ |
&& gtags -i $(GTAGS_ARGS) "$$here" |
cscopelist: cscopelist-am |
cscopelist-am: $(am__tagged_files) |
list='$(am__tagged_files)'; \ |
case "$(srcdir)" in \ |
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ |
*) sdir=$(subdir)/$(srcdir) ;; \ |
esac; \ |
for i in $$list; do \ |
if test -f "$$i"; then \ |
echo "$(subdir)/$$i"; \ |
else \ |
echo "$$sdir/$$i"; \ |
fi; \ |
done >> $(top_builddir)/cscope.files |
distclean-tags: |
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags |
distdir: $(DISTFILES) |
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ |
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ |
list='$(DISTFILES)'; \ |
dist_files=`for file in $$list; do echo $$file; done | \ |
sed -e "s|^$$srcdirstrip/||;t" \ |
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ |
case $$dist_files in \ |
*/*) $(MKDIR_P) `echo "$$dist_files" | \ |
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ |
sort -u` ;; \ |
esac; \ |
for file in $$dist_files; do \ |
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ |
if test -d $$d/$$file; then \ |
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ |
if test -d "$(distdir)/$$file"; then \ |
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ |
fi; \ |
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ |
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ |
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ |
fi; \ |
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ |
else \ |
test -f "$(distdir)/$$file" \ |
|| cp -p $$d/$$file "$(distdir)/$$file" \ |
|| exit 1; \ |
fi; \ |
done |
check-am: all-am |
check: check-am |
all-am: Makefile $(LTLIBRARIES) |
installdirs: |
install: install-am |
install-exec: install-exec-am |
install-data: install-data-am |
uninstall: uninstall-am |
install-am: all-am |
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am |
installcheck: installcheck-am |
install-strip: |
if test -z '$(STRIP)'; then \ |
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ |
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ |
install; \ |
else \ |
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ |
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ |
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ |
fi |
mostlyclean-generic: |
clean-generic: |
distclean-generic: |
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) |
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) |
maintainer-clean-generic: |
@echo "This command is intended for maintainers to use" |
@echo "it deletes files that may require special tools to rebuild." |
clean: clean-am |
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ |
mostlyclean-am |
distclean: distclean-am |
-rm -rf ./$(DEPDIR) |
-rm -f Makefile |
distclean-am: clean-am distclean-compile distclean-generic \ |
distclean-tags |
dvi: dvi-am |
dvi-am: |
html: html-am |
html-am: |
info: info-am |
info-am: |
install-data-am: |
install-dvi: install-dvi-am |
install-dvi-am: |
install-exec-am: |
install-html: install-html-am |
install-html-am: |
install-info: install-info-am |
install-info-am: |
install-man: |
install-pdf: install-pdf-am |
install-pdf-am: |
install-ps: install-ps-am |
install-ps-am: |
installcheck-am: |
maintainer-clean: maintainer-clean-am |
-rm -rf ./$(DEPDIR) |
-rm -f Makefile |
maintainer-clean-am: distclean-am maintainer-clean-generic |
mostlyclean: mostlyclean-am |
mostlyclean-am: mostlyclean-compile mostlyclean-generic \ |
mostlyclean-libtool |
pdf: pdf-am |
pdf-am: |
ps: ps-am |
ps-am: |
uninstall-am: |
.MAKE: install-am install-strip |
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ |
clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ |
ctags-am distclean distclean-compile distclean-generic \ |
distclean-libtool distclean-tags distdir dvi dvi-am html \ |
html-am info info-am install install-am install-data \ |
install-data-am install-dvi install-dvi-am install-exec \ |
install-exec-am install-html install-html-am install-info \ |
install-info-am install-man install-pdf install-pdf-am \ |
install-ps install-ps-am install-strip installcheck \ |
installcheck-am installdirs maintainer-clean \ |
maintainer-clean-generic mostlyclean mostlyclean-compile \ |
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ |
tags tags-am uninstall uninstall-am |
.PRECIOUS: Makefile |
# Tell versions [3.59,3.63) of GNU make to not export all variables. |
# Otherwise a system limit (for SysV at least) may be exceeded. |
.NOEXPORT: |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/Makefile.sources |
---|
0,0 → 1,42 |
C_SOURCES := \ |
i915_batchbuffer.h \ |
i915_batch.h \ |
i915_blit.c \ |
i915_blit.h \ |
i915_clear.c \ |
i915_context.c \ |
i915_context.h \ |
i915_debug.c \ |
i915_debug_fp.c \ |
i915_debug.h \ |
i915_debug_private.h \ |
i915_flush.c \ |
i915_fpc_emit.c \ |
i915_fpc.h \ |
i915_fpc_optimize.c \ |
i915_fpc_translate.c \ |
i915_prim_emit.c \ |
i915_prim_vbuf.c \ |
i915_public.h \ |
i915_query.c \ |
i915_query.h \ |
i915_reg.h \ |
i915_resource_buffer.c \ |
i915_resource.c \ |
i915_resource.h \ |
i915_resource_texture.c \ |
i915_screen.c \ |
i915_screen.h \ |
i915_state.c \ |
i915_state_derived.c \ |
i915_state_dynamic.c \ |
i915_state_emit.c \ |
i915_state_fpc.c \ |
i915_state.h \ |
i915_state_immediate.c \ |
i915_state_inlines.h \ |
i915_state_sampler.c \ |
i915_state_static.c \ |
i915_surface.c \ |
i915_surface.h \ |
i915_winsys.h |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/TODO |
---|
0,0 → 1,38 |
Random list of problems with i915g: |
- What does this button do? Figure out LIS7 with regards to depth offset. |
- Dies with BadDrawable on GLXFBconfig changes/destruction. Makes piglit totally |
unusable :( Upgrading xserver helped here, it doesn't crash anymore. Still |
broken, it doesn't update the viewport/get new buffers. |
- Y-tiling is even more fun. i915c doesn't use it, maybe there's a reason? |
Texture sampling from Y-tiled buffers seems to work, though (save above |
problems). |
RESOLVED: Y-tiling works with the render engine, but not with the blitter. |
Use u_blitter and hw clears (PRIM3D_CLEAR_RECT). |
- src/xvmc/i915_structs.h in xf86-video-intel has a few more bits of various |
commands defined. Scavenge them and see what's useful. |
- Do smarter remapping. Right now we send everything onto tex coords 0-7. |
We could also use diffuse/specular and pack two sets of 2D coords in a single |
4D. Is it a big problem though? We're more limited by the # of texture |
indirections and the # of instructions. |
- Finish front/back face. We need to add face support to lp_build_system_values_array and use it in draw_llvm.c. |
- More optimizations, like replacing ADD + MUL with MAD or use DP2ADD. |
- Replace constants and immediates which are 0,1,-1 or a combination of those with a swizzle. |
- Schedule instructions to minimize the number of phases. One way is to replace |
R registers responsible for a boundary with U registers to avoid phase |
boundaries. |
- Continue a previous primitive when there are no state changes |
- Fix fragment discard |
Other bugs can be found here: |
https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_batch.h |
---|
0,0 → 1,60 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_BATCH_H |
#define I915_BATCH_H |
#include "i915_batchbuffer.h" |
#include "i915_context.h" |
#define BEGIN_BATCH(dwords) \ |
(i915_winsys_batchbuffer_check(i915->batch, dwords)) |
#define OUT_BATCH(dword) \ |
i915_winsys_batchbuffer_dword(i915->batch, dword) |
#define OUT_BATCH_F(f) \ |
i915_winsys_batchbuffer_float(i915->batch, f) |
#define OUT_RELOC(buf, usage, offset) \ |
i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, false) |
#define OUT_RELOC_FENCED(buf, usage, offset) \ |
i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, true) |
#define FLUSH_BATCH(fence, flags) \ |
i915_flush(i915, fence, flags) |
/************************************************************************ |
* i915_flush.c |
*/ |
extern void i915_flush(struct i915_context *i915, |
struct pipe_fence_handle **fence, |
unsigned flags); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_batchbuffer.h |
---|
0,0 → 1,103 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_BATCHBUFFER_H |
#define I915_BATCHBUFFER_H |
#include "i915_winsys.h" |
#include "util/u_debug.h" |
struct i915_context; |
static INLINE size_t |
i915_winsys_batchbuffer_space(struct i915_winsys_batchbuffer *batch) |
{ |
return batch->size - (batch->ptr - batch->map); |
} |
static INLINE boolean |
i915_winsys_batchbuffer_check(struct i915_winsys_batchbuffer *batch, |
size_t dwords) |
{ |
return dwords * 4 <= i915_winsys_batchbuffer_space(batch); |
} |
static INLINE void |
i915_winsys_batchbuffer_dword_unchecked(struct i915_winsys_batchbuffer *batch, |
unsigned dword) |
{ |
*(unsigned *)batch->ptr = dword; |
batch->ptr += 4; |
} |
static INLINE void |
i915_winsys_batchbuffer_float(struct i915_winsys_batchbuffer *batch, |
float f) |
{ |
union { float f; unsigned int ui; } uif; |
uif.f = f; |
assert (i915_winsys_batchbuffer_space(batch) >= 4); |
i915_winsys_batchbuffer_dword_unchecked(batch, uif.ui); |
} |
static INLINE void |
i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch, |
unsigned dword) |
{ |
assert (i915_winsys_batchbuffer_space(batch) >= 4); |
i915_winsys_batchbuffer_dword_unchecked(batch, dword); |
} |
static INLINE void |
i915_winsys_batchbuffer_write(struct i915_winsys_batchbuffer *batch, |
void *data, |
size_t size) |
{ |
assert (i915_winsys_batchbuffer_space(batch) >= size); |
memcpy(batch->ptr, data, size); |
batch->ptr += size; |
} |
static INLINE boolean |
i915_winsys_validate_buffers(struct i915_winsys_batchbuffer *batch, |
struct i915_winsys_buffer **buffers, |
int num_of_buffers) |
{ |
return batch->iws->validate_buffers(batch, buffers, num_of_buffers); |
} |
static INLINE int |
i915_winsys_batchbuffer_reloc(struct i915_winsys_batchbuffer *batch, |
struct i915_winsys_buffer *buffer, |
enum i915_winsys_buffer_usage usage, |
size_t offset, boolean fenced) |
{ |
return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset, fenced); |
} |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_blit.c |
---|
0,0 → 1,160 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_blit.h" |
#include "i915_reg.h" |
#include "i915_batch.h" |
#include "i915_debug.h" |
void |
i915_fill_blit(struct i915_context *i915, |
unsigned cpp, |
unsigned rgba_mask, |
unsigned short dst_pitch, |
struct i915_winsys_buffer *dst_buffer, |
unsigned dst_offset, |
short x, short y, |
short w, short h, |
unsigned color) |
{ |
unsigned BR13, CMD; |
I915_DBG(DBG_BLIT, "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", |
__FUNCTION__, dst_buffer, dst_pitch, dst_offset, x, y, w, h); |
if(!i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
assert(i915_winsys_validate_buffers(i915->batch, &dst_buffer, 1)); |
} |
switch (cpp) { |
case 1: |
case 2: |
case 3: |
BR13 = (((int) dst_pitch) & 0xffff) | |
(0xF0 << 16) | (1 << 24); |
CMD = XY_COLOR_BLT_CMD; |
break; |
case 4: |
BR13 = (((int) dst_pitch) & 0xffff) | |
(0xF0 << 16) | (1 << 24) | (1 << 25); |
CMD = (XY_COLOR_BLT_CMD | rgba_mask); |
break; |
default: |
return; |
} |
if (!BEGIN_BATCH(6)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
assert(BEGIN_BATCH(6)); |
} |
OUT_BATCH(CMD); |
OUT_BATCH(BR13); |
OUT_BATCH((y << 16) | x); |
OUT_BATCH(((y + h) << 16) | (x + w)); |
OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset); |
OUT_BATCH(color); |
i915_set_flush_dirty(i915, I915_FLUSH_CACHE); |
} |
void |
i915_copy_blit(struct i915_context *i915, |
unsigned cpp, |
unsigned short src_pitch, |
struct i915_winsys_buffer *src_buffer, |
unsigned src_offset, |
unsigned short dst_pitch, |
struct i915_winsys_buffer *dst_buffer, |
unsigned dst_offset, |
short src_x, short src_y, |
short dst_x, short dst_y, |
short w, short h) |
{ |
unsigned CMD, BR13; |
int dst_y2 = dst_y + h; |
int dst_x2 = dst_x + w; |
struct i915_winsys_buffer *buffers[2] = {src_buffer, dst_buffer}; |
I915_DBG(DBG_BLIT, |
"%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n", |
__FUNCTION__, |
src_buffer, src_pitch, src_offset, src_x, src_y, |
dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h); |
if(!i915_winsys_validate_buffers(i915->batch, buffers, 2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
assert(i915_winsys_validate_buffers(i915->batch, buffers, 2)); |
} |
switch (cpp) { |
case 1: |
case 2: |
case 3: |
BR13 = (((int) dst_pitch) & 0xffff) | |
(0xCC << 16) | (1 << 24); |
CMD = XY_SRC_COPY_BLT_CMD; |
break; |
case 4: |
BR13 = (((int) dst_pitch) & 0xffff) | |
(0xCC << 16) | (1 << 24) | (1 << 25); |
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | |
XY_SRC_COPY_BLT_WRITE_RGB); |
break; |
default: |
return; |
} |
if (dst_y2 < dst_y || dst_x2 < dst_x) { |
return; |
} |
/* Hardware can handle negative pitches but loses the ability to do |
* proper overlapping blits in that case. We don't really have a |
* need for either at this stage. |
*/ |
assert (dst_pitch > 0 && src_pitch > 0); |
if (!BEGIN_BATCH(8)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
assert(BEGIN_BATCH(8)); |
} |
OUT_BATCH(CMD); |
OUT_BATCH(BR13); |
OUT_BATCH((dst_y << 16) | dst_x); |
OUT_BATCH((dst_y2 << 16) | dst_x2); |
OUT_RELOC_FENCED(dst_buffer, I915_USAGE_2D_TARGET, dst_offset); |
OUT_BATCH((src_y << 16) | src_x); |
OUT_BATCH(((int) src_pitch & 0xffff)); |
OUT_RELOC_FENCED(src_buffer, I915_USAGE_2D_SOURCE, src_offset); |
i915_set_flush_dirty(i915, I915_FLUSH_CACHE); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_blit.h |
---|
0,0 → 1,55 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_BLIT_H |
#define I915_BLIT_H |
#include "i915_context.h" |
extern void i915_copy_blit(struct i915_context *i915, |
unsigned cpp, |
unsigned short src_pitch, |
struct i915_winsys_buffer *src_buffer, |
unsigned src_offset, |
unsigned short dst_pitch, |
struct i915_winsys_buffer *dst_buffer, |
unsigned dst_offset, |
short srcx, short srcy, |
short dstx, short dsty, |
short w, short h); |
extern void i915_fill_blit(struct i915_context *i915, |
unsigned cpp, |
unsigned rgba_mask, |
unsigned short dst_pitch, |
struct i915_winsys_buffer *dst_buffer, |
unsigned dst_offset, |
short x, short y, |
short w, short h, unsigned color); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_clear.c |
---|
0,0 → 1,240 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* Authors: |
* Brian Paul |
*/ |
#include "util/u_clear.h" |
#include "util/u_format.h" |
#include "util/u_pack_color.h" |
#include "i915_context.h" |
#include "i915_screen.h" |
#include "i915_reg.h" |
#include "i915_batch.h" |
#include "i915_resource.h" |
#include "i915_state.h" |
void |
i915_clear_emit(struct pipe_context *pipe, unsigned buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil, |
unsigned destx, unsigned desty, unsigned width, unsigned height) |
{ |
struct i915_context *i915 = i915_context(pipe); |
uint32_t clear_params, clear_color, clear_depth, clear_stencil, |
clear_color8888, packed_z_stencil; |
union util_color u_color; |
float f_depth = depth; |
struct i915_texture *cbuf_tex, *depth_tex; |
int depth_clear_bbp, color_clear_bbp; |
cbuf_tex = depth_tex = NULL; |
clear_params = 0; |
depth_clear_bbp = color_clear_bbp = 0; |
if (buffers & PIPE_CLEAR_COLOR) { |
struct pipe_surface *cbuf = i915->framebuffer.cbufs[0]; |
clear_params |= CLEARPARAM_WRITE_COLOR; |
cbuf_tex = i915_texture(cbuf->texture); |
util_pack_color(color->f, cbuf->format, &u_color); |
if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) { |
clear_color = u_color.ui[0]; |
color_clear_bbp = 32; |
} else { |
clear_color = (u_color.ui[0] & 0xffff) | (u_color.ui[0] << 16); |
color_clear_bbp = 16; |
} |
/* correctly swizzle clear value */ |
if (i915->current.target_fixup_format) |
util_pack_color(color->f, cbuf->format, &u_color); |
else |
util_pack_color(color->f, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color); |
clear_color8888 = u_color.ui[0]; |
} else |
clear_color = clear_color8888 = 0; |
clear_depth = clear_stencil = 0; |
if (buffers & PIPE_CLEAR_DEPTH) { |
struct pipe_surface *zbuf = i915->framebuffer.zsbuf; |
clear_params |= CLEARPARAM_WRITE_DEPTH; |
depth_tex = i915_texture(zbuf->texture); |
packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil); |
if (util_format_get_blocksize(depth_tex->b.b.format) == 4) { |
/* Avoid read-modify-write if there's no stencil. */ |
if (buffers & PIPE_CLEAR_STENCIL |
|| depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_UINT) { |
clear_params |= CLEARPARAM_WRITE_STENCIL; |
clear_stencil = packed_z_stencil >> 24; |
} |
clear_depth = packed_z_stencil & 0xffffff; |
depth_clear_bbp = 32; |
} else { |
clear_depth = (packed_z_stencil & 0xffff) | (packed_z_stencil << 16); |
depth_clear_bbp = 16; |
} |
} else if (buffers & PIPE_CLEAR_STENCIL) { |
struct pipe_surface *zbuf = i915->framebuffer.zsbuf; |
clear_params |= CLEARPARAM_WRITE_STENCIL; |
depth_tex = i915_texture(zbuf->texture); |
assert(depth_tex->b.b.format == PIPE_FORMAT_Z24_UNORM_S8_UINT); |
packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil); |
depth_clear_bbp = 32; |
clear_stencil = packed_z_stencil >> 24; |
} |
/* hw can't fastclear both depth and color if their bbp mismatch. */ |
if (color_clear_bbp && depth_clear_bbp |
&& color_clear_bbp != depth_clear_bbp) { |
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
if (!BEGIN_BATCH(1 + 2*(7 + 7))) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
assert(BEGIN_BATCH(1 + 2*(7 + 7))); |
} |
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); |
OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); |
OUT_BATCH(CLEARPARAM_WRITE_COLOR | CLEARPARAM_CLEAR_RECT); |
/* Used for zone init prim */ |
OUT_BATCH(clear_color); |
OUT_BATCH(clear_depth); |
/* Used for clear rect prim */ |
OUT_BATCH(clear_color8888); |
OUT_BATCH_F(f_depth); |
OUT_BATCH(clear_stencil); |
OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); |
OUT_BATCH_F(destx + width); |
OUT_BATCH_F(desty + height); |
OUT_BATCH_F(destx); |
OUT_BATCH_F(desty + height); |
OUT_BATCH_F(destx); |
OUT_BATCH_F(desty); |
OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); |
OUT_BATCH((clear_params & ~CLEARPARAM_WRITE_COLOR) | |
CLEARPARAM_CLEAR_RECT); |
/* Used for zone init prim */ |
OUT_BATCH(clear_color); |
OUT_BATCH(clear_depth); |
/* Used for clear rect prim */ |
OUT_BATCH(clear_color8888); |
OUT_BATCH_F(f_depth); |
OUT_BATCH(clear_stencil); |
OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); |
OUT_BATCH_F(destx + width); |
OUT_BATCH_F(desty + height); |
OUT_BATCH_F(destx); |
OUT_BATCH_F(desty + height); |
OUT_BATCH_F(destx); |
OUT_BATCH_F(desty); |
} else { |
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
if (!BEGIN_BATCH(1 + 7 + 7)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
assert(BEGIN_BATCH(1 + 7 + 7)); |
} |
OUT_BATCH(_3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT); |
OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); |
OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); |
/* Used for zone init prim */ |
OUT_BATCH(clear_color); |
OUT_BATCH(clear_depth); |
/* Used for clear rect prim */ |
OUT_BATCH(clear_color8888); |
OUT_BATCH_F(f_depth); |
OUT_BATCH(clear_stencil); |
OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); |
OUT_BATCH_F(destx + width); |
OUT_BATCH_F(desty + height); |
OUT_BATCH_F(destx); |
OUT_BATCH_F(desty + height); |
OUT_BATCH_F(destx); |
OUT_BATCH_F(desty); |
} |
/* Flush after clear, its expected to be a costly operation. |
* This is not required, just a heuristic, but without the flush we'd need to |
* clobber the SCISSOR_ENABLE dynamic state. */ |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
i915->last_fired_vertices = i915->fired_vertices; |
i915->fired_vertices = 0; |
} |
/** |
* Clear the given buffers to the specified values. |
* No masking, no scissor (clear entire buffer). |
*/ |
void |
i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil) |
{ |
util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, color, depth, |
stencil); |
} |
void |
i915_clear_render(struct pipe_context *pipe, unsigned buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (i915->dirty) |
i915_update_derived(i915); |
i915_clear_emit(pipe, buffers, color, depth, stencil, |
0, 0, i915->framebuffer.width, i915->framebuffer.height); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_context.c |
---|
0,0 → 1,225 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_context.h" |
#include "i915_state.h" |
#include "i915_screen.h" |
#include "i915_surface.h" |
#include "i915_query.h" |
#include "i915_batch.h" |
#include "i915_resource.h" |
#include "draw/draw_context.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_memory.h" |
#include "pipe/p_screen.h" |
DEBUG_GET_ONCE_BOOL_OPTION(i915_no_vbuf, "I915_NO_VBUF", FALSE) |
/* |
* Draw functions |
*/ |
static void |
i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct draw_context *draw = i915->draw; |
const void *mapped_indices = NULL; |
unsigned i; |
/* |
* Ack vs contants here, helps ipers a lot. |
*/ |
i915->dirty &= ~I915_NEW_VS_CONSTANTS; |
if (i915->dirty) |
i915_update_derived(i915); |
/* |
* Map vertex buffers |
*/ |
for (i = 0; i < i915->nr_vertex_buffers; i++) { |
const void *buf = i915->vertex_buffers[i].user_buffer; |
if (!buf) |
buf = i915_buffer(i915->vertex_buffers[i].buffer)->data; |
draw_set_mapped_vertex_buffer(draw, i, buf, ~0); |
} |
/* |
* Map index buffer, if present |
*/ |
if (info->indexed) { |
mapped_indices = i915->index_buffer.user_buffer; |
if (!mapped_indices) |
mapped_indices = i915_buffer(i915->index_buffer.buffer)->data; |
draw_set_indexes(draw, |
(ubyte *) mapped_indices + i915->index_buffer.offset, |
i915->index_buffer.index_size, ~0); |
} |
if (i915->constants[PIPE_SHADER_VERTEX]) |
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, |
i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data, |
(i915->current.num_user_constants[PIPE_SHADER_VERTEX] * |
4 * sizeof(float))); |
else |
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0, NULL, 0); |
if (i915->num_vertex_sampler_views > 0) |
i915_prepare_vertex_sampling(i915); |
/* |
* Do the drawing |
*/ |
draw_vbo(i915->draw, info); |
/* |
* unmap vertex/index buffers |
*/ |
for (i = 0; i < i915->nr_vertex_buffers; i++) { |
draw_set_mapped_vertex_buffer(i915->draw, i, NULL, 0); |
} |
if (mapped_indices) |
draw_set_indexes(draw, NULL, 0, 0); |
if (i915->num_vertex_sampler_views > 0) |
i915_cleanup_vertex_sampling(i915); |
/* |
* Instead of flushing on every state change, we flush once here |
* when we fire the vbo. |
*/ |
draw_flush(i915->draw); |
} |
/* |
* Generic context functions |
*/ |
static void i915_destroy(struct pipe_context *pipe) |
{ |
struct i915_context *i915 = i915_context(pipe); |
int i; |
if (i915->blitter) |
util_blitter_destroy(i915->blitter); |
draw_destroy(i915->draw); |
if(i915->batch) |
i915->iws->batchbuffer_destroy(i915->batch); |
/* unbind framebuffer */ |
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |
pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL); |
} |
pipe_surface_reference(&i915->framebuffer.zsbuf, NULL); |
/* unbind constant buffers */ |
for (i = 0; i < PIPE_SHADER_TYPES; i++) { |
pipe_resource_reference(&i915->constants[i], NULL); |
} |
FREE(i915); |
} |
struct pipe_context * |
i915_create_context(struct pipe_screen *screen, void *priv) |
{ |
struct i915_context *i915; |
i915 = CALLOC_STRUCT(i915_context); |
if (i915 == NULL) |
return NULL; |
i915->iws = i915_screen(screen)->iws; |
i915->base.screen = screen; |
i915->base.priv = priv; |
i915->base.destroy = i915_destroy; |
if (i915_screen(screen)->debug.use_blitter) |
i915->base.clear = i915_clear_blitter; |
else |
i915->base.clear = i915_clear_render; |
i915->base.draw_vbo = i915_draw_vbo; |
/* init this before draw */ |
util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer), |
16, UTIL_SLAB_SINGLETHREADED); |
util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer), |
16, UTIL_SLAB_SINGLETHREADED); |
/* Batch stream debugging is a bit hacked up at the moment: |
*/ |
i915->batch = i915->iws->batchbuffer_create(i915->iws); |
/* |
* Create drawing context and plug our rendering stage into it. |
*/ |
i915->draw = draw_create(&i915->base); |
assert(i915->draw); |
if (!debug_get_option_i915_no_vbuf()) { |
draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915)); |
} else { |
draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915)); |
} |
i915_init_surface_functions(i915); |
i915_init_state_functions(i915); |
i915_init_flush_functions(i915); |
i915_init_resource_functions(i915); |
i915_init_query_functions(i915); |
/* Create blitter. */ |
i915->blitter = util_blitter_create(&i915->base); |
assert(i915->blitter); |
/* must be done before installing Draw stages */ |
util_blitter_cache_all_shaders(i915->blitter); |
draw_install_aaline_stage(i915->draw, &i915->base); |
draw_install_aapoint_stage(i915->draw, &i915->base); |
draw_enable_point_sprites(i915->draw, TRUE); |
i915->dirty = ~0; |
i915->hardware_dirty = ~0; |
i915->immediate_dirty = ~0; |
i915->dynamic_dirty = ~0; |
i915->static_dirty = ~0; |
i915->flush_dirty = 0; |
return &i915->base; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_context.h |
---|
0,0 → 1,418 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_CONTEXT_H |
#define I915_CONTEXT_H |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "pipe/p_state.h" |
#include "draw/draw_vertex.h" |
#include "tgsi/tgsi_scan.h" |
#include "util/u_slab.h" |
#include "util/u_blitter.h" |
struct i915_winsys; |
struct i915_winsys_buffer; |
struct i915_winsys_batchbuffer; |
#define I915_TEX_UNITS 8 |
#define I915_DYNAMIC_MODES4 0 |
#define I915_DYNAMIC_DEPTHSCALE_0 1 /* just the header */ |
#define I915_DYNAMIC_DEPTHSCALE_1 2 |
#define I915_DYNAMIC_IAB 3 |
#define I915_DYNAMIC_BC_0 4 /* just the header */ |
#define I915_DYNAMIC_BC_1 5 |
#define I915_DYNAMIC_BFO_0 6 |
#define I915_DYNAMIC_BFO_1 7 |
#define I915_DYNAMIC_STP_0 8 |
#define I915_DYNAMIC_STP_1 9 |
#define I915_DYNAMIC_SC_ENA_0 10 |
#define I915_DYNAMIC_SC_RECT_0 11 |
#define I915_DYNAMIC_SC_RECT_1 12 |
#define I915_DYNAMIC_SC_RECT_2 13 |
#define I915_MAX_DYNAMIC 14 |
#define I915_IMMEDIATE_S0 0 |
#define I915_IMMEDIATE_S1 1 |
#define I915_IMMEDIATE_S2 2 |
#define I915_IMMEDIATE_S3 3 |
#define I915_IMMEDIATE_S4 4 |
#define I915_IMMEDIATE_S5 5 |
#define I915_IMMEDIATE_S6 6 |
#define I915_IMMEDIATE_S7 7 |
#define I915_MAX_IMMEDIATE 8 |
/* These must mach the order of LI0_STATE_* bits, as they will be used |
* to generate hardware packets: |
*/ |
#define I915_CACHE_STATIC 0 |
#define I915_CACHE_DYNAMIC 1 /* handled specially */ |
#define I915_CACHE_SAMPLER 2 |
#define I915_CACHE_MAP 3 |
#define I915_CACHE_PROGRAM 4 |
#define I915_CACHE_CONSTANTS 5 |
#define I915_MAX_CACHE 6 |
#define I915_MAX_CONSTANT 32 |
/** See constant_flags[] below */ |
#define I915_CONSTFLAG_USER 0x1f |
/** |
* Subclass of pipe_shader_state |
*/ |
struct i915_fragment_shader |
{ |
struct pipe_shader_state state; |
struct tgsi_shader_info info; |
struct draw_fragment_shader *draw_data; |
uint *decl; |
uint decl_len; |
uint *program; |
uint program_len; |
/** |
* constants introduced during translation. |
* These are placed at the end of the constant buffer and grow toward |
* the beginning (eg: slot 31, 30 29, ...) |
* User-provided constants start at 0. |
* This allows both types of constants to co-exist (until there's too many) |
* and doesn't require regenerating/changing the fragment program to |
* shuffle constants around. |
*/ |
uint num_constants; |
float constants[I915_MAX_CONSTANT][4]; |
/** |
* Status of each constant |
* if I915_CONSTFLAG_PARAM, the value must be taken from the corresponding |
* slot of the user's constant buffer. (set by pipe->set_constant_buffer()) |
* Else, the bitmask indicates which components are occupied by immediates. |
*/ |
ubyte constant_flags[I915_MAX_CONSTANT]; |
/** |
* The mapping between generics and hw texture coords. |
* We need to share this between the vertex and fragment stages. |
**/ |
int generic_mapping[I915_TEX_UNITS]; |
}; |
struct i915_cache_context; |
/* Use to calculate differences between state emitted to hardware and |
* current driver-calculated state. |
*/ |
struct i915_state |
{ |
unsigned immediate[I915_MAX_IMMEDIATE]; |
unsigned dynamic[I915_MAX_DYNAMIC]; |
/** number of constants passed in through a constant buffer */ |
uint num_user_constants[PIPE_SHADER_TYPES]; |
/* texture sampler state */ |
unsigned sampler[I915_TEX_UNITS][3]; |
unsigned sampler_enable_flags; |
unsigned sampler_enable_nr; |
/* texture image buffers */ |
unsigned texbuffer[I915_TEX_UNITS][3]; |
/** Describes the current hardware vertex layout */ |
struct vertex_info vertex_info; |
/* static state (dst/depth buffer state) */ |
struct i915_winsys_buffer *cbuf_bo; |
unsigned cbuf_flags; |
struct i915_winsys_buffer *depth_bo; |
unsigned depth_flags; |
unsigned dst_buf_vars; |
uint32_t draw_offset; |
uint32_t draw_size; |
uint32_t target_fixup_format; |
uint32_t fixup_swizzle; |
unsigned id; /* track lost context events */ |
}; |
struct i915_blend_state { |
unsigned iab; |
unsigned modes4; |
unsigned LIS5; |
unsigned LIS6; |
}; |
struct i915_depth_stencil_state { |
unsigned stencil_modes4; |
unsigned bfo[2]; |
unsigned stencil_LIS5; |
unsigned depth_LIS6; |
}; |
struct i915_rasterizer_state { |
struct pipe_rasterizer_state templ; |
unsigned light_twoside : 1; |
unsigned st; |
enum interp_mode color_interp; |
unsigned LIS4; |
unsigned LIS7; |
unsigned sc[1]; |
union { float f; unsigned u; } ds[2]; |
}; |
struct i915_sampler_state { |
struct pipe_sampler_state templ; |
unsigned state[3]; |
unsigned minlod; |
unsigned maxlod; |
}; |
struct i915_velems_state { |
unsigned count; |
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS]; |
}; |
struct i915_context { |
struct pipe_context base; |
struct i915_winsys *iws; |
struct draw_context *draw; |
/* The most recent drawing state as set by the driver: |
*/ |
const struct i915_blend_state *blend; |
const struct i915_sampler_state *fragment_sampler[PIPE_MAX_SAMPLERS]; |
struct pipe_sampler_state *vertex_samplers[PIPE_MAX_SAMPLERS]; |
const struct i915_depth_stencil_state *depth_stencil; |
const struct i915_rasterizer_state *rasterizer; |
struct i915_fragment_shader *fs; |
void *vs; |
struct i915_velems_state *velems; |
unsigned nr_vertex_buffers; |
struct pipe_vertex_buffer vertex_buffers[PIPE_MAX_ATTRIBS]; |
struct pipe_blend_color blend_color; |
struct pipe_stencil_ref stencil_ref; |
struct pipe_clip_state clip; |
struct pipe_resource *constants[PIPE_SHADER_TYPES]; |
struct pipe_framebuffer_state framebuffer; |
struct pipe_poly_stipple poly_stipple; |
struct pipe_scissor_state scissor; |
struct pipe_sampler_view *fragment_sampler_views[PIPE_MAX_SAMPLERS]; |
struct pipe_sampler_view *vertex_sampler_views[PIPE_MAX_SAMPLERS]; |
struct pipe_viewport_state viewport; |
struct pipe_index_buffer index_buffer; |
unsigned dirty; |
struct pipe_resource *mapped_vs_tex[PIPE_MAX_SAMPLERS]; |
struct i915_winsys_buffer* mapped_vs_tex_buffer[PIPE_MAX_SAMPLERS]; |
unsigned num_samplers; |
unsigned num_fragment_sampler_views; |
unsigned num_vertex_samplers; |
unsigned num_vertex_sampler_views; |
struct i915_winsys_batchbuffer *batch; |
/** Vertex buffer */ |
struct i915_winsys_buffer *vbo; |
size_t vbo_offset; |
unsigned vbo_flushed; |
struct i915_state current; |
unsigned hardware_dirty; |
unsigned immediate_dirty : I915_MAX_IMMEDIATE; |
unsigned dynamic_dirty : I915_MAX_DYNAMIC; |
unsigned static_dirty : 4; |
unsigned flush_dirty : 2; |
struct i915_winsys_buffer *validation_buffers[2 + 1 + I915_TEX_UNITS]; |
int num_validation_buffers; |
struct util_slab_mempool transfer_pool; |
struct util_slab_mempool texture_transfer_pool; |
/* state for tracking flushes */ |
int last_fired_vertices; |
int fired_vertices; |
int queued_vertices; |
/** blitter/hw-clear */ |
struct blitter_context* blitter; |
}; |
/* A flag for each state_tracker state object: |
*/ |
#define I915_NEW_VIEWPORT 0x1 |
#define I915_NEW_RASTERIZER 0x2 |
#define I915_NEW_FS 0x4 |
#define I915_NEW_BLEND 0x8 |
#define I915_NEW_CLIP 0x10 |
#define I915_NEW_SCISSOR 0x20 |
#define I915_NEW_STIPPLE 0x40 |
#define I915_NEW_FRAMEBUFFER 0x80 |
#define I915_NEW_ALPHA_TEST 0x100 |
#define I915_NEW_DEPTH_STENCIL 0x200 |
#define I915_NEW_SAMPLER 0x400 |
#define I915_NEW_SAMPLER_VIEW 0x800 |
#define I915_NEW_VS_CONSTANTS 0x1000 |
#define I915_NEW_FS_CONSTANTS 0x2000 |
#define I915_NEW_GS_CONSTANTS 0x4000 |
#define I915_NEW_VBO 0x8000 |
#define I915_NEW_VS 0x10000 |
/* Driver's internally generated state flags: |
*/ |
#define I915_NEW_VERTEX_FORMAT 0x10000 |
/* Dirty flags for hardware emit |
*/ |
#define I915_HW_STATIC (1<<I915_CACHE_STATIC) |
#define I915_HW_DYNAMIC (1<<I915_CACHE_DYNAMIC) |
#define I915_HW_SAMPLER (1<<I915_CACHE_SAMPLER) |
#define I915_HW_MAP (1<<I915_CACHE_MAP) |
#define I915_HW_PROGRAM (1<<I915_CACHE_PROGRAM) |
#define I915_HW_CONSTANTS (1<<I915_CACHE_CONSTANTS) |
#define I915_HW_IMMEDIATE (1<<(I915_MAX_CACHE+0)) |
#define I915_HW_INVARIANT (1<<(I915_MAX_CACHE+1)) |
#define I915_HW_FLUSH (1<<(I915_MAX_CACHE+1)) |
/* hw flush handling */ |
#define I915_FLUSH_CACHE 1 |
#define I915_PIPELINE_FLUSH 2 |
/* split up static state */ |
#define I915_DST_BUF_COLOR 1 |
#define I915_DST_BUF_DEPTH 2 |
#define I915_DST_VARS 4 |
#define I915_DST_RECT 8 |
static INLINE |
void i915_set_flush_dirty(struct i915_context *i915, unsigned flush) |
{ |
i915->hardware_dirty |= I915_HW_FLUSH; |
i915->flush_dirty |= flush; |
} |
/*********************************************************************** |
* i915_prim_emit.c: |
*/ |
struct draw_stage *i915_draw_render_stage( struct i915_context *i915 ); |
/*********************************************************************** |
* i915_prim_vbuf.c: |
*/ |
struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 ); |
/*********************************************************************** |
* i915_state.c: |
*/ |
void i915_prepare_vertex_sampling(struct i915_context *i915); |
void i915_cleanup_vertex_sampling(struct i915_context *i915); |
/*********************************************************************** |
* i915_state_emit.c: |
*/ |
void i915_emit_hardware_state(struct i915_context *i915 ); |
/*********************************************************************** |
* i915_clear.c: |
*/ |
void i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil); |
void i915_clear_render(struct pipe_context *pipe, unsigned buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil); |
void i915_clear_emit(struct pipe_context *pipe, unsigned buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil, |
unsigned destx, unsigned desty, unsigned width, unsigned height); |
/*********************************************************************** |
* |
*/ |
void i915_init_state_functions( struct i915_context *i915 ); |
void i915_init_flush_functions( struct i915_context *i915 ); |
void i915_init_string_functions( struct i915_context *i915 ); |
/************************************************************************ |
* i915_context.c |
*/ |
struct pipe_context *i915_create_context(struct pipe_screen *screen, |
void *priv); |
/*********************************************************************** |
* Inline conversion functions. These are better-typed than the |
* macros used previously: |
*/ |
static INLINE struct i915_context * |
i915_context( struct pipe_context *pipe ) |
{ |
return (struct i915_context *)pipe; |
} |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_debug.c |
---|
0,0 → 1,995 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_reg.h" |
#include "i915_context.h" |
#include "i915_screen.h" |
#include "i915_debug.h" |
#include "i915_debug_private.h" |
#include "i915_batch.h" |
#include "util/u_debug.h" |
static const struct debug_named_value debug_options[] = { |
{"blit", DBG_BLIT, "Print when using the 2d blitter"}, |
{"emit", DBG_EMIT, "State emit information"}, |
{"atoms", DBG_ATOMS, "Print dirty state atoms"}, |
{"flush", DBG_FLUSH, "Flushing information"}, |
{"texture", DBG_TEXTURE, "Texture information"}, |
{"constants", DBG_CONSTANTS, "Constant buffers"}, |
DEBUG_NAMED_VALUE_END |
}; |
unsigned i915_debug = 0; |
DEBUG_GET_ONCE_FLAGS_OPTION(i915_debug, "I915_DEBUG", debug_options, 0) |
DEBUG_GET_ONCE_BOOL_OPTION(i915_no_tiling, "I915_NO_TILING", FALSE) |
DEBUG_GET_ONCE_BOOL_OPTION(i915_lie, "I915_LIE", TRUE) |
DEBUG_GET_ONCE_BOOL_OPTION(i915_use_blitter, "I915_USE_BLITTER", FALSE) |
void i915_debug_init(struct i915_screen *is) |
{ |
i915_debug = debug_get_option_i915_debug(); |
is->debug.tiling = !debug_get_option_i915_no_tiling(); |
is->debug.lie = debug_get_option_i915_lie(); |
is->debug.use_blitter = debug_get_option_i915_use_blitter(); |
} |
/*********************************************************************** |
* Batchbuffer dumping |
*/ |
static void |
PRINTF( |
struct debug_stream *stream, |
const char *fmt, |
... ) |
{ |
va_list args; |
va_start( args, fmt ); |
debug_vprintf( fmt, args ); |
va_end( args ); |
} |
static boolean debug( struct debug_stream *stream, const char *name, unsigned len ) |
{ |
unsigned i; |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
if (len == 0) { |
PRINTF(stream, "Error - zero length packet (0x%08x)\n", stream->ptr[0]); |
assert(0); |
return FALSE; |
} |
if (stream->print_addresses) |
PRINTF(stream, "%08x: ", stream->offset); |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
for (i = 0; i < len; i++) |
PRINTF(stream, "\t0x%08x\n", ptr[i]); |
PRINTF(stream, "\n"); |
stream->offset += len * sizeof(unsigned); |
return TRUE; |
} |
static const char *get_prim_name( unsigned val ) |
{ |
switch (val & PRIM3D_MASK) { |
case PRIM3D_TRILIST: return "TRILIST"; break; |
case PRIM3D_TRISTRIP: return "TRISTRIP"; break; |
case PRIM3D_TRISTRIP_RVRSE: return "TRISTRIP_RVRSE"; break; |
case PRIM3D_TRIFAN: return "TRIFAN"; break; |
case PRIM3D_POLY: return "POLY"; break; |
case PRIM3D_LINELIST: return "LINELIST"; break; |
case PRIM3D_LINESTRIP: return "LINESTRIP"; break; |
case PRIM3D_RECTLIST: return "RECTLIST"; break; |
case PRIM3D_POINTLIST: return "POINTLIST"; break; |
case PRIM3D_DIB: return "DIB"; break; |
case PRIM3D_CLEAR_RECT: return "CLEAR_RECT"; break; |
case PRIM3D_ZONE_INIT: return "ZONE_INIT"; break; |
default: return "????"; break; |
} |
} |
static boolean debug_prim( struct debug_stream *stream, const char *name, |
boolean dump_floats, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
const char *prim = get_prim_name( ptr[0] ); |
unsigned i; |
PRINTF(stream, "%s %s (%d dwords):\n", name, prim, len); |
PRINTF(stream, "\t0x%08x\n", ptr[0]); |
for (i = 1; i < len; i++) { |
if (dump_floats) |
PRINTF(stream, "\t0x%08x // %f\n", ptr[i], *(float *)&ptr[i]); |
else |
PRINTF(stream, "\t0x%08x\n", ptr[i]); |
} |
PRINTF(stream, "\n"); |
stream->offset += len * sizeof(unsigned); |
return TRUE; |
} |
static boolean debug_program( struct debug_stream *stream, const char *name, unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
if (len == 0) { |
PRINTF(stream, "Error - zero length packet (0x%08x)\n", stream->ptr[0]); |
assert(0); |
return FALSE; |
} |
if (stream->print_addresses) |
PRINTF(stream, "%08x: ", stream->offset); |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
i915_disassemble_program( stream, ptr, len ); |
stream->offset += len * sizeof(unsigned); |
return TRUE; |
} |
static boolean debug_chain( struct debug_stream *stream, const char *name, unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
unsigned old_offset = stream->offset + len * sizeof(unsigned); |
unsigned i; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
for (i = 0; i < len; i++) |
PRINTF(stream, "\t0x%08x\n", ptr[i]); |
stream->offset = ptr[1] & ~0x3; |
if (stream->offset < old_offset) |
PRINTF(stream, "\n... skipping backwards from 0x%x --> 0x%x ...\n\n", |
old_offset, stream->offset ); |
else |
PRINTF(stream, "\n... skipping from 0x%x --> 0x%x ...\n\n", |
old_offset, stream->offset ); |
return TRUE; |
} |
static boolean debug_variable_length_prim( struct debug_stream *stream ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
const char *prim = get_prim_name( ptr[0] ); |
unsigned i, len; |
ushort *idx = (ushort *)(ptr+1); |
for (i = 0; idx[i] != 0xffff; i++) |
; |
len = 1+(i+2)/2; |
PRINTF(stream, "3DPRIM, %s variable length %d indicies (%d dwords):\n", prim, i, len); |
for (i = 0; i < len; i++) |
PRINTF(stream, "\t0x%08x\n", ptr[i]); |
PRINTF(stream, "\n"); |
stream->offset += len * sizeof(unsigned); |
return TRUE; |
} |
static void |
BITS( |
struct debug_stream *stream, |
unsigned dw, |
unsigned hi, |
unsigned lo, |
const char *fmt, |
... ) |
{ |
va_list args; |
unsigned himask = 0xFFFFFFFFUL >> (31 - (hi)); |
PRINTF(stream, "\t\t "); |
va_start( args, fmt ); |
debug_vprintf( fmt, args ); |
va_end( args ); |
PRINTF(stream, ": 0x%x\n", ((dw) & himask) >> (lo)); |
} |
#ifdef DEBUG |
#define MBZ( dw, hi, lo) do { \ |
unsigned x = (dw) >> (lo); \ |
unsigned lomask = (1 << (lo)) - 1; \ |
unsigned himask; \ |
himask = (1UL << (hi)) - 1; \ |
assert ((x & himask & ~lomask) == 0); \ |
} while (0) |
#else |
#define MBZ( dw, hi, lo) do { \ |
} while (0) |
#endif |
static void |
FLAG( |
struct debug_stream *stream, |
unsigned dw, |
unsigned bit, |
const char *fmt, |
... ) |
{ |
if (((dw) >> (bit)) & 1) { |
va_list args; |
PRINTF(stream, "\t\t "); |
va_start( args, fmt ); |
debug_vprintf( fmt, args ); |
va_end( args ); |
PRINTF(stream, "\n"); |
} |
} |
static boolean debug_load_immediate( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
unsigned bits = (ptr[0] >> 4) & 0xff; |
unsigned j = 0; |
PRINTF(stream, "%s (%d dwords, flags: %x):\n", name, len, bits); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
if (bits & (1<<0)) { |
PRINTF(stream, "\t LIS0: 0x%08x\n", ptr[j]); |
PRINTF(stream, "\t vb address: 0x%08x\n", (ptr[j] & ~0x3)); |
BITS(stream, ptr[j], 0, 0, "vb invalidate disable"); |
j++; |
} |
if (bits & (1<<1)) { |
PRINTF(stream, "\t LIS1: 0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 29, 24, "vb dword width"); |
BITS(stream, ptr[j], 21, 16, "vb dword pitch"); |
BITS(stream, ptr[j], 15, 0, "vb max index"); |
j++; |
} |
if (bits & (1<<2)) { |
int i; |
PRINTF(stream, "\t LIS2: 0x%08x\n", ptr[j]); |
for (i = 0; i < 8; i++) { |
unsigned tc = (ptr[j] >> (i * 4)) & 0xf; |
if (tc != 0xf) |
BITS(stream, tc, 3, 0, "tex coord %d", i); |
} |
j++; |
} |
if (bits & (1<<3)) { |
PRINTF(stream, "\t LIS3: 0x%08x\n", ptr[j]); |
j++; |
} |
if (bits & (1<<4)) { |
PRINTF(stream, "\t LIS4: 0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 31, 23, "point width"); |
BITS(stream, ptr[j], 22, 19, "line width"); |
FLAG(stream, ptr[j], 18, "alpha flatshade"); |
FLAG(stream, ptr[j], 17, "fog flatshade"); |
FLAG(stream, ptr[j], 16, "spec flatshade"); |
FLAG(stream, ptr[j], 15, "rgb flatshade"); |
BITS(stream, ptr[j], 14, 13, "cull mode"); |
FLAG(stream, ptr[j], 12, "vfmt: point width"); |
FLAG(stream, ptr[j], 11, "vfmt: specular/fog"); |
FLAG(stream, ptr[j], 10, "vfmt: rgba"); |
FLAG(stream, ptr[j], 9, "vfmt: depth offset"); |
BITS(stream, ptr[j], 8, 6, "vfmt: position (2==xyzw)"); |
FLAG(stream, ptr[j], 5, "force dflt diffuse"); |
FLAG(stream, ptr[j], 4, "force dflt specular"); |
FLAG(stream, ptr[j], 3, "local depth offset enable"); |
FLAG(stream, ptr[j], 2, "vfmt: fp32 fog coord"); |
FLAG(stream, ptr[j], 1, "sprite point"); |
FLAG(stream, ptr[j], 0, "antialiasing"); |
j++; |
} |
if (bits & (1<<5)) { |
PRINTF(stream, "\t LIS5: 0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 31, 28, "rgba write disables"); |
FLAG(stream, ptr[j], 27, "force dflt point width"); |
FLAG(stream, ptr[j], 26, "last pixel enable"); |
FLAG(stream, ptr[j], 25, "global z offset enable"); |
FLAG(stream, ptr[j], 24, "fog enable"); |
BITS(stream, ptr[j], 23, 16, "stencil ref"); |
BITS(stream, ptr[j], 15, 13, "stencil test"); |
BITS(stream, ptr[j], 12, 10, "stencil fail op"); |
BITS(stream, ptr[j], 9, 7, "stencil pass z fail op"); |
BITS(stream, ptr[j], 6, 4, "stencil pass z pass op"); |
FLAG(stream, ptr[j], 3, "stencil write enable"); |
FLAG(stream, ptr[j], 2, "stencil test enable"); |
FLAG(stream, ptr[j], 1, "color dither enable"); |
FLAG(stream, ptr[j], 0, "logiop enable"); |
j++; |
} |
if (bits & (1<<6)) { |
PRINTF(stream, "\t LIS6: 0x%08x\n", ptr[j]); |
FLAG(stream, ptr[j], 31, "alpha test enable"); |
BITS(stream, ptr[j], 30, 28, "alpha func"); |
BITS(stream, ptr[j], 27, 20, "alpha ref"); |
FLAG(stream, ptr[j], 19, "depth test enable"); |
BITS(stream, ptr[j], 18, 16, "depth func"); |
FLAG(stream, ptr[j], 15, "blend enable"); |
BITS(stream, ptr[j], 14, 12, "blend func"); |
BITS(stream, ptr[j], 11, 8, "blend src factor"); |
BITS(stream, ptr[j], 7, 4, "blend dst factor"); |
FLAG(stream, ptr[j], 3, "depth write enable"); |
FLAG(stream, ptr[j], 2, "color write enable"); |
BITS(stream, ptr[j], 1, 0, "provoking vertex"); |
j++; |
} |
PRINTF(stream, "\n"); |
assert(j == len); |
stream->offset += len * sizeof(unsigned); |
return TRUE; |
} |
static boolean debug_load_indirect( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
unsigned bits = (ptr[0] >> 8) & 0x3f; |
unsigned i, j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
for (i = 0; i < 6; i++) { |
if (bits & (1<<i)) { |
switch (1<<(8+i)) { |
case LI0_STATE_STATIC_INDIRECT: |
PRINTF(stream, " STATIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
PRINTF(stream, " 0x%08x\n", ptr[j++]); |
break; |
case LI0_STATE_DYNAMIC_INDIRECT: |
PRINTF(stream, " DYNAMIC: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
break; |
case LI0_STATE_SAMPLER: |
PRINTF(stream, " SAMPLER: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
PRINTF(stream, " 0x%08x\n", ptr[j++]); |
break; |
case LI0_STATE_MAP: |
PRINTF(stream, " MAP: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
PRINTF(stream, " 0x%08x\n", ptr[j++]); |
break; |
case LI0_STATE_PROGRAM: |
PRINTF(stream, " PROGRAM: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
PRINTF(stream, " 0x%08x\n", ptr[j++]); |
break; |
case LI0_STATE_CONSTANTS: |
PRINTF(stream, " CONSTANTS: 0x%08x | %x\n", ptr[j]&~3, ptr[j]&3); j++; |
PRINTF(stream, " 0x%08x\n", ptr[j++]); |
break; |
default: |
assert(0); |
break; |
} |
} |
} |
if (bits == 0) { |
PRINTF(stream, "\t DUMMY: 0x%08x\n", ptr[j++]); |
} |
PRINTF(stream, "\n"); |
assert(j == len); |
stream->offset += len * sizeof(unsigned); |
return TRUE; |
} |
static void BR13( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x\n", val); |
FLAG(stream, val, 30, "clipping enable"); |
BITS(stream, val, 25, 24, "color depth (3==32bpp)"); |
BITS(stream, val, 23, 16, "raster op"); |
BITS(stream, val, 15, 0, "dest pitch"); |
} |
static void BR22( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x\n", val); |
BITS(stream, val, 31, 16, "dest y1"); |
BITS(stream, val, 15, 0, "dest x1"); |
} |
static void BR23( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x\n", val); |
BITS(stream, val, 31, 16, "dest y2"); |
BITS(stream, val, 15, 0, "dest x2"); |
} |
static void BR09( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x -- dest address\n", val); |
} |
static void BR26( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x\n", val); |
BITS(stream, val, 31, 16, "src y1"); |
BITS(stream, val, 15, 0, "src x1"); |
} |
static void BR11( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x\n", val); |
BITS(stream, val, 15, 0, "src pitch"); |
} |
static void BR12( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x -- src address\n", val); |
} |
static void BR16( struct debug_stream *stream, |
unsigned val ) |
{ |
PRINTF(stream, "\t0x%08x -- color\n", val); |
} |
static boolean debug_copy_blit( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
int j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
BR13(stream, ptr[j++]); |
BR22(stream, ptr[j++]); |
BR23(stream, ptr[j++]); |
BR09(stream, ptr[j++]); |
BR26(stream, ptr[j++]); |
BR11(stream, ptr[j++]); |
BR12(stream, ptr[j++]); |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean debug_color_blit( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
int j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
BR13(stream, ptr[j++]); |
BR22(stream, ptr[j++]); |
BR23(stream, ptr[j++]); |
BR09(stream, ptr[j++]); |
BR16(stream, ptr[j++]); |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean debug_modes4( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
int j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 21, 18, "logicop func"); |
FLAG(stream, ptr[j], 17, "stencil test mask modify-enable"); |
FLAG(stream, ptr[j], 16, "stencil write mask modify-enable"); |
BITS(stream, ptr[j], 15, 8, "stencil test mask"); |
BITS(stream, ptr[j], 7, 0, "stencil write mask"); |
j++; |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean debug_map_state( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
unsigned j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
{ |
PRINTF(stream, "\t0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 15, 0, "map mask"); |
j++; |
} |
while (j < len) { |
{ |
PRINTF(stream, "\t TMn.0: 0x%08x\n", ptr[j]); |
PRINTF(stream, "\t map address: 0x%08x\n", (ptr[j] & ~0x3)); |
FLAG(stream, ptr[j], 1, "vertical line stride"); |
FLAG(stream, ptr[j], 0, "vertical line stride offset"); |
j++; |
} |
{ |
PRINTF(stream, "\t TMn.1: 0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 31, 21, "height"); |
BITS(stream, ptr[j], 20, 10, "width"); |
BITS(stream, ptr[j], 9, 7, "surface format"); |
BITS(stream, ptr[j], 6, 3, "texel format"); |
FLAG(stream, ptr[j], 2, "use fence regs"); |
FLAG(stream, ptr[j], 1, "tiled surface"); |
FLAG(stream, ptr[j], 0, "tile walk ymajor"); |
j++; |
} |
{ |
PRINTF(stream, "\t TMn.2: 0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 31, 21, "dword pitch"); |
BITS(stream, ptr[j], 20, 15, "cube face enables"); |
BITS(stream, ptr[j], 14, 9, "max lod"); |
FLAG(stream, ptr[j], 8, "mip layout right"); |
BITS(stream, ptr[j], 7, 0, "depth"); |
j++; |
} |
} |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean debug_sampler_state( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
unsigned j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
{ |
PRINTF(stream, "\t0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 15, 0, "sampler mask"); |
j++; |
} |
while (j < len) { |
{ |
PRINTF(stream, "\t TSn.0: 0x%08x\n", ptr[j]); |
FLAG(stream, ptr[j], 31, "reverse gamma"); |
FLAG(stream, ptr[j], 30, "planar to packed"); |
FLAG(stream, ptr[j], 29, "yuv->rgb"); |
BITS(stream, ptr[j], 28, 27, "chromakey index"); |
BITS(stream, ptr[j], 26, 22, "base mip level"); |
BITS(stream, ptr[j], 21, 20, "mip mode filter"); |
BITS(stream, ptr[j], 19, 17, "mag mode filter"); |
BITS(stream, ptr[j], 16, 14, "min mode filter"); |
BITS(stream, ptr[j], 13, 5, "lod bias (s4.4)"); |
FLAG(stream, ptr[j], 4, "shadow enable"); |
FLAG(stream, ptr[j], 3, "max-aniso-4"); |
BITS(stream, ptr[j], 2, 0, "shadow func"); |
j++; |
} |
{ |
PRINTF(stream, "\t TSn.1: 0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 31, 24, "min lod"); |
MBZ( ptr[j], 23, 18 ); |
FLAG(stream, ptr[j], 17, "kill pixel enable"); |
FLAG(stream, ptr[j], 16, "keyed tex filter mode"); |
FLAG(stream, ptr[j], 15, "chromakey enable"); |
BITS(stream, ptr[j], 14, 12, "tcx wrap mode"); |
BITS(stream, ptr[j], 11, 9, "tcy wrap mode"); |
BITS(stream, ptr[j], 8, 6, "tcz wrap mode"); |
FLAG(stream, ptr[j], 5, "normalized coords"); |
BITS(stream, ptr[j], 4, 1, "map (surface) index"); |
FLAG(stream, ptr[j], 0, "EAST deinterlacer enable"); |
j++; |
} |
{ |
PRINTF(stream, "\t TSn.2: 0x%08x (default color)\n", ptr[j]); |
j++; |
} |
} |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean debug_dest_vars( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
int j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
{ |
PRINTF(stream, "\t0x%08x\n", ptr[j]); |
FLAG(stream, ptr[j], 31, "early classic ztest"); |
FLAG(stream, ptr[j], 30, "opengl tex default color"); |
FLAG(stream, ptr[j], 29, "bypass iz"); |
FLAG(stream, ptr[j], 28, "lod preclamp"); |
BITS(stream, ptr[j], 27, 26, "dither pattern"); |
FLAG(stream, ptr[j], 25, "linear gamma blend"); |
FLAG(stream, ptr[j], 24, "debug dither"); |
BITS(stream, ptr[j], 23, 20, "dstorg x"); |
BITS(stream, ptr[j], 19, 16, "dstorg y"); |
MBZ (ptr[j], 15, 15 ); |
BITS(stream, ptr[j], 14, 12, "422 write select"); |
BITS(stream, ptr[j], 11, 8, "cbuf format"); |
BITS(stream, ptr[j], 3, 2, "zbuf format"); |
FLAG(stream, ptr[j], 1, "vert line stride"); |
FLAG(stream, ptr[j], 1, "vert line stride offset"); |
j++; |
} |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean debug_buf_info( struct debug_stream *stream, |
const char *name, |
unsigned len ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
int j = 0; |
PRINTF(stream, "%s (%d dwords):\n", name, len); |
PRINTF(stream, "\t0x%08x\n", ptr[j++]); |
{ |
PRINTF(stream, "\t0x%08x\n", ptr[j]); |
BITS(stream, ptr[j], 28, 28, "aux buffer id"); |
BITS(stream, ptr[j], 27, 24, "buffer id (7=depth, 3=back)"); |
FLAG(stream, ptr[j], 23, "use fence regs"); |
FLAG(stream, ptr[j], 22, "tiled surface"); |
FLAG(stream, ptr[j], 21, "tile walk ymajor"); |
MBZ (ptr[j], 20, 14); |
BITS(stream, ptr[j], 13, 2, "dword pitch"); |
MBZ (ptr[j], 2, 0); |
j++; |
} |
PRINTF(stream, "\t0x%08x -- buffer base address\n", ptr[j++]); |
stream->offset += len * sizeof(unsigned); |
assert(j == len); |
return TRUE; |
} |
static boolean i915_debug_packet( struct debug_stream *stream ) |
{ |
unsigned *ptr = (unsigned *)(stream->ptr + stream->offset); |
unsigned cmd = *ptr; |
switch (((cmd >> 29) & 0x7)) { |
case 0x0: |
switch ((cmd >> 23) & 0x3f) { |
case 0x0: |
return debug(stream, "MI_NOOP", 1); |
case 0x3: |
return debug(stream, "MI_WAIT_FOR_EVENT", 1); |
case 0x4: |
return debug(stream, "MI_FLUSH", 1); |
case 0xA: |
debug(stream, "MI_BATCH_BUFFER_END", 1); |
return FALSE; |
case 0x22: |
return debug(stream, "MI_LOAD_REGISTER_IMM", 3); |
case 0x31: |
return debug_chain(stream, "MI_BATCH_BUFFER_START", 2); |
default: |
(void)debug(stream, "UNKNOWN 0x0 case!", 1); |
assert(0); |
break; |
} |
break; |
case 0x1: |
(void) debug(stream, "UNKNOWN 0x1 case!", 1); |
assert(0); |
break; |
case 0x2: |
switch ((cmd >> 22) & 0xff) { |
case 0x50: |
return debug_color_blit(stream, "XY_COLOR_BLT", (cmd & 0xff) + 2); |
case 0x53: |
return debug_copy_blit(stream, "XY_SRC_COPY_BLT", (cmd & 0xff) + 2); |
default: |
return debug(stream, "blit command", (cmd & 0xff) + 2); |
} |
break; |
case 0x3: |
switch ((cmd >> 24) & 0x1f) { |
case 0x6: |
return debug(stream, "3DSTATE_ANTI_ALIASING", 1); |
case 0x7: |
return debug(stream, "3DSTATE_RASTERIZATION_RULES", 1); |
case 0x8: |
return debug(stream, "3DSTATE_BACKFACE_STENCIL_OPS", 2); |
case 0x9: |
return debug(stream, "3DSTATE_BACKFACE_STENCIL_MASKS", 1); |
case 0xb: |
return debug(stream, "3DSTATE_INDEPENDENT_ALPHA_BLEND", 1); |
case 0xc: |
return debug(stream, "3DSTATE_MODES5", 1); |
case 0xd: |
return debug_modes4(stream, "3DSTATE_MODES4", 1); |
case 0x15: |
return debug(stream, "3DSTATE_FOG_COLOR", 1); |
case 0x16: |
return debug(stream, "3DSTATE_COORD_SET_BINDINGS", 1); |
case 0x1c: |
/* 3DState16NP */ |
switch((cmd >> 19) & 0x1f) { |
case 0x10: |
return debug(stream, "3DSTATE_SCISSOR_ENABLE", 1); |
case 0x11: |
return debug(stream, "3DSTATE_DEPTH_SUBRECTANGLE_DISABLE", 1); |
default: |
(void) debug(stream, "UNKNOWN 0x1c case!", 1); |
assert(0); |
break; |
} |
break; |
case 0x1d: |
/* 3DStateMW */ |
switch ((cmd >> 16) & 0xff) { |
case 0x0: |
return debug_map_state(stream, "3DSTATE_MAP_STATE", (cmd & 0x1f) + 2); |
case 0x1: |
return debug_sampler_state(stream, "3DSTATE_SAMPLER_STATE", (cmd & 0x1f) + 2); |
case 0x4: |
return debug_load_immediate(stream, "3DSTATE_LOAD_STATE_IMMEDIATE", (cmd & 0xf) + 2); |
case 0x5: |
return debug_program(stream, "3DSTATE_PIXEL_SHADER_PROGRAM", (cmd & 0x1ff) + 2); |
case 0x6: |
return debug(stream, "3DSTATE_PIXEL_SHADER_CONSTANTS", (cmd & 0xff) + 2); |
case 0x7: |
return debug_load_indirect(stream, "3DSTATE_LOAD_INDIRECT", (cmd & 0xff) + 2); |
case 0x80: |
return debug(stream, "3DSTATE_DRAWING_RECTANGLE", (cmd & 0xffff) + 2); |
case 0x81: |
return debug(stream, "3DSTATE_SCISSOR_RECTANGLE", (cmd & 0xffff) + 2); |
case 0x83: |
return debug(stream, "3DSTATE_SPAN_STIPPLE", (cmd & 0xffff) + 2); |
case 0x85: |
return debug_dest_vars(stream, "3DSTATE_DEST_BUFFER_VARS", (cmd & 0xffff) + 2); |
case 0x88: |
return debug(stream, "3DSTATE_CONSTANT_BLEND_COLOR", (cmd & 0xffff) + 2); |
case 0x89: |
return debug(stream, "3DSTATE_FOG_MODE", (cmd & 0xffff) + 2); |
case 0x8e: |
return debug_buf_info(stream, "3DSTATE_BUFFER_INFO", (cmd & 0xffff) + 2); |
case 0x97: |
return debug(stream, "3DSTATE_DEPTH_OFFSET_SCALE", (cmd & 0xffff) + 2); |
case 0x98: |
return debug(stream, "3DSTATE_DEFAULT_Z", (cmd & 0xffff) + 2); |
case 0x99: |
return debug(stream, "3DSTATE_DEFAULT_DIFFUSE", (cmd & 0xffff) + 2); |
case 0x9a: |
return debug(stream, "3DSTATE_DEFAULT_SPECULAR", (cmd & 0xffff) + 2); |
case 0x9c: |
return debug(stream, "3DSTATE_CLEAR_PARAMETERS", (cmd & 0xffff) + 2); |
default: |
assert(0); |
return 0; |
} |
break; |
case 0x1e: |
if (cmd & (1 << 23)) |
return debug(stream, "???", (cmd & 0xffff) + 1); |
else |
return debug(stream, "", 1); |
break; |
case 0x1f: |
if ((cmd & (1 << 23)) == 0) |
return debug_prim(stream, "3DPRIM (inline)", 1, (cmd & 0x1ffff) + 2); |
else if (cmd & (1 << 17)) |
{ |
if ((cmd & 0xffff) == 0) |
return debug_variable_length_prim(stream); |
else |
return debug_prim(stream, "3DPRIM (indexed)", 0, (((cmd & 0xffff) + 1) / 2) + 1); |
} |
else |
return debug_prim(stream, "3DPRIM (indirect sequential)", 0, 2); |
break; |
default: |
return debug(stream, "", 0); |
} |
break; |
default: |
assert(0); |
return 0; |
} |
assert(0); |
return 0; |
} |
void |
i915_dump_batchbuffer( struct i915_winsys_batchbuffer *batch ) |
{ |
struct debug_stream stream; |
unsigned *start = (unsigned*)batch->map; |
unsigned *end = (unsigned*)batch->ptr; |
unsigned long bytes = (unsigned long) (end - start) * 4; |
boolean done = FALSE; |
stream.offset = 0; |
stream.ptr = (char *)start; |
stream.print_addresses = 0; |
if (!start || !end) { |
debug_printf( "\n\nBATCH: ???\n"); |
return; |
} |
debug_printf( "\n\nBATCH: (%d)\n", (int)bytes / 4); |
while (!done && |
stream.offset < bytes) |
{ |
if (!i915_debug_packet( &stream )) |
break; |
assert(stream.offset <= bytes); |
} |
debug_printf( "END-BATCH\n\n\n"); |
} |
/*********************************************************************** |
* Dirty state atom dumping |
*/ |
void |
i915_dump_dirty(struct i915_context *i915, const char *func) |
{ |
struct { |
unsigned dirty; |
const char *name; |
} l[] = { |
{I915_NEW_VIEWPORT, "viewport"}, |
{I915_NEW_RASTERIZER, "rasterizer"}, |
{I915_NEW_FS, "fs"}, |
{I915_NEW_BLEND, "blend"}, |
{I915_NEW_CLIP, "clip"}, |
{I915_NEW_SCISSOR, "scissor"}, |
{I915_NEW_STIPPLE, "stipple"}, |
{I915_NEW_FRAMEBUFFER, "framebuffer"}, |
{I915_NEW_ALPHA_TEST, "alpha_test"}, |
{I915_NEW_DEPTH_STENCIL, "depth_stencil"}, |
{I915_NEW_SAMPLER, "sampler"}, |
{I915_NEW_SAMPLER_VIEW, "sampler_view"}, |
{I915_NEW_VS_CONSTANTS, "vs_const"}, |
{I915_NEW_FS_CONSTANTS, "fs_const"}, |
{I915_NEW_VBO, "vbo"}, |
{I915_NEW_VS, "vs"}, |
{0, NULL}, |
}; |
int i; |
debug_printf("%s: ", func); |
for (i = 0; l[i].name; i++) |
if (i915->dirty & l[i].dirty) |
debug_printf("%s ", l[i].name); |
debug_printf("\n"); |
} |
void |
i915_dump_hardware_dirty(struct i915_context *i915, const char *func) |
{ |
struct { |
unsigned dirty; |
const char *name; |
} l[] = { |
{I915_HW_STATIC, "static"}, |
{I915_HW_DYNAMIC, "dynamic"}, |
{I915_HW_SAMPLER, "sampler"}, |
{I915_HW_MAP, "map"}, |
{I915_HW_PROGRAM, "program"}, |
{I915_HW_CONSTANTS, "constants"}, |
{I915_HW_IMMEDIATE, "immediate"}, |
{I915_HW_INVARIANT, "invariant"}, |
{0, NULL}, |
}; |
int i; |
debug_printf("%s: ", func); |
for (i = 0; l[i].name; i++) |
if (i915->hardware_dirty & l[i].dirty) |
debug_printf("%s ", l[i].name); |
debug_printf("\n"); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_debug.h |
---|
0,0 → 1,81 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* Authors: Keith Whitwell <keithw@vmware.com> |
* Jakob Bornecrantz <wallbraker@gmail.com> |
*/ |
#ifndef I915_DEBUG_H |
#define I915_DEBUG_H |
#include "util/u_debug.h" |
struct i915_screen; |
struct i915_context; |
struct i915_winsys_batchbuffer; |
#define DBG_BLIT 0x1 |
#define DBG_EMIT 0x2 |
#define DBG_ATOMS 0x4 |
#define DBG_FLUSH 0x8 |
#define DBG_TEXTURE 0x10 |
#define DBG_CONSTANTS 0x20 |
extern unsigned i915_debug; |
#ifdef DEBUG |
static INLINE boolean |
I915_DBG_ON(unsigned flags) |
{ |
return i915_debug & flags; |
} |
static INLINE void |
I915_DBG(unsigned flags, const char *fmt, ...) |
{ |
if (I915_DBG_ON(flags)) { |
va_list args; |
va_start(args, fmt); |
debug_vprintf(fmt, args); |
va_end(args); |
} |
} |
#else |
#define I915_DBG_ON(flags) (0) |
static INLINE void I915_DBG(unsigned flags, const char *fmt, ...) {} |
#endif |
void i915_debug_init(struct i915_screen *i915); |
void i915_dump_batchbuffer(struct i915_winsys_batchbuffer *i915); |
void i915_dump_dirty(struct i915_context *i915, const char *func); |
void i915_dump_hardware_dirty(struct i915_context *i915, const char *func); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_debug_fp.c |
---|
0,0 → 1,362 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_reg.h" |
#include "i915_debug.h" |
#include "i915_debug_private.h" |
#include "util/u_debug.h" |
static void |
PRINTF( |
struct debug_stream *stream, |
const char *fmt, |
... ) |
{ |
va_list args; |
va_start( args, fmt ); |
debug_vprintf( fmt, args ); |
va_end( args ); |
} |
static const char *opcodes[0x20] = { |
"NOP", |
"ADD", |
"MOV", |
"MUL", |
"MAD", |
"DP2ADD", |
"DP3", |
"DP4", |
"FRC", |
"RCP", |
"RSQ", |
"EXP", |
"LOG", |
"CMP", |
"MIN", |
"MAX", |
"FLR", |
"MOD", |
"TRC", |
"SGE", |
"SLT", |
"TEXLD", |
"TEXLDP", |
"TEXLDB", |
"TEXKILL", |
"DCL", |
"0x1a", |
"0x1b", |
"0x1c", |
"0x1d", |
"0x1e", |
"0x1f", |
}; |
static const int args[0x20] = { |
0, /* 0 nop */ |
2, /* 1 add */ |
1, /* 2 mov */ |
2, /* 3 m ul */ |
3, /* 4 mad */ |
3, /* 5 dp2add */ |
2, /* 6 dp3 */ |
2, /* 7 dp4 */ |
1, /* 8 frc */ |
1, /* 9 rcp */ |
1, /* a rsq */ |
1, /* b exp */ |
1, /* c log */ |
3, /* d cmp */ |
2, /* e min */ |
2, /* f max */ |
1, /* 10 flr */ |
1, /* 11 mod */ |
1, /* 12 trc */ |
2, /* 13 sge */ |
2, /* 14 slt */ |
1, |
1, |
1, |
1, |
0, |
0, |
0, |
0, |
0, |
0, |
0, |
}; |
static const char *regname[0x8] = { |
"R", |
"T", |
"CONST", |
"S", |
"OC", |
"OD", |
"U", |
"UNKNOWN", |
}; |
static void |
print_reg_type_nr(struct debug_stream *stream, unsigned type, unsigned nr) |
{ |
switch (type) { |
case REG_TYPE_T: |
switch (nr) { |
case T_DIFFUSE: |
PRINTF(stream, "T_DIFFUSE"); |
return; |
case T_SPECULAR: |
PRINTF(stream, "T_SPECULAR"); |
return; |
case T_FOG_W: |
PRINTF(stream, "T_FOG_W"); |
return; |
default: |
PRINTF(stream, "T_TEX%d", nr); |
return; |
} |
case REG_TYPE_OC: |
if (nr == 0) { |
PRINTF(stream, "oC"); |
return; |
} |
break; |
case REG_TYPE_OD: |
if (nr == 0) { |
PRINTF(stream, "oD"); |
return; |
} |
break; |
default: |
break; |
} |
PRINTF(stream, "%s[%d]", regname[type], nr); |
} |
#define REG_SWIZZLE_MASK 0x7777 |
#define REG_NEGATE_MASK 0x8888 |
#define REG_SWIZZLE_XYZW ((SRC_X << A2_SRC2_CHANNEL_X_SHIFT) | \ |
(SRC_Y << A2_SRC2_CHANNEL_Y_SHIFT) | \ |
(SRC_Z << A2_SRC2_CHANNEL_Z_SHIFT) | \ |
(SRC_W << A2_SRC2_CHANNEL_W_SHIFT)) |
static void |
print_reg_neg_swizzle(struct debug_stream *stream, unsigned reg) |
{ |
int i; |
if ((reg & REG_SWIZZLE_MASK) == REG_SWIZZLE_XYZW && |
(reg & REG_NEGATE_MASK) == 0) |
return; |
PRINTF(stream, "."); |
for (i = 3; i >= 0; i--) { |
if (reg & (1 << ((i * 4) + 3))) |
PRINTF(stream, "-"); |
switch ((reg >> (i * 4)) & 0x7) { |
case 0: |
PRINTF(stream, "x"); |
break; |
case 1: |
PRINTF(stream, "y"); |
break; |
case 2: |
PRINTF(stream, "z"); |
break; |
case 3: |
PRINTF(stream, "w"); |
break; |
case 4: |
PRINTF(stream, "0"); |
break; |
case 5: |
PRINTF(stream, "1"); |
break; |
default: |
PRINTF(stream, "?"); |
break; |
} |
} |
} |
static void |
print_src_reg(struct debug_stream *stream, unsigned dword) |
{ |
unsigned nr = (dword >> A2_SRC2_NR_SHIFT) & REG_NR_MASK; |
unsigned type = (dword >> A2_SRC2_TYPE_SHIFT) & REG_TYPE_MASK; |
print_reg_type_nr(stream, type, nr); |
print_reg_neg_swizzle(stream, dword); |
} |
static void |
print_dest_reg(struct debug_stream *stream, unsigned dword) |
{ |
unsigned nr = (dword >> A0_DEST_NR_SHIFT) & REG_NR_MASK; |
unsigned type = (dword >> A0_DEST_TYPE_SHIFT) & REG_TYPE_MASK; |
print_reg_type_nr(stream, type, nr); |
if ((dword & A0_DEST_CHANNEL_ALL) == A0_DEST_CHANNEL_ALL) |
return; |
PRINTF(stream, "."); |
if (dword & A0_DEST_CHANNEL_X) |
PRINTF(stream, "x"); |
if (dword & A0_DEST_CHANNEL_Y) |
PRINTF(stream, "y"); |
if (dword & A0_DEST_CHANNEL_Z) |
PRINTF(stream, "z"); |
if (dword & A0_DEST_CHANNEL_W) |
PRINTF(stream, "w"); |
} |
#define GET_SRC0_REG(r0, r1) ((r0<<14)|(r1>>A1_SRC0_CHANNEL_W_SHIFT)) |
#define GET_SRC1_REG(r0, r1) ((r0<<8)|(r1>>A2_SRC1_CHANNEL_W_SHIFT)) |
#define GET_SRC2_REG(r) (r) |
static void |
print_arith_op(struct debug_stream *stream, |
unsigned opcode, const unsigned * program) |
{ |
if (opcode != A0_NOP) { |
print_dest_reg(stream, program[0]); |
if (program[0] & A0_DEST_SATURATE) |
PRINTF(stream, " = SATURATE "); |
else |
PRINTF(stream, " = "); |
} |
PRINTF(stream, "%s ", opcodes[opcode]); |
print_src_reg(stream, GET_SRC0_REG(program[0], program[1])); |
if (args[opcode] == 1) { |
PRINTF(stream, "\n"); |
return; |
} |
PRINTF(stream, ", "); |
print_src_reg(stream, GET_SRC1_REG(program[1], program[2])); |
if (args[opcode] == 2) { |
PRINTF(stream, "\n"); |
return; |
} |
PRINTF(stream, ", "); |
print_src_reg(stream, GET_SRC2_REG(program[2])); |
PRINTF(stream, "\n"); |
return; |
} |
static void |
print_tex_op(struct debug_stream *stream, |
unsigned opcode, const unsigned * program) |
{ |
print_dest_reg(stream, program[0] | A0_DEST_CHANNEL_ALL); |
PRINTF(stream, " = "); |
PRINTF(stream, "%s ", opcodes[opcode]); |
PRINTF(stream, "S[%d],", program[0] & T0_SAMPLER_NR_MASK); |
print_reg_type_nr(stream, |
(program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & |
REG_TYPE_MASK, |
(program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); |
PRINTF(stream, "\n"); |
} |
static void |
print_texkil_op(struct debug_stream *stream, |
unsigned opcode, const unsigned * program) |
{ |
PRINTF(stream, "TEXKIL "); |
print_reg_type_nr(stream, |
(program[1] >> T1_ADDRESS_REG_TYPE_SHIFT) & |
REG_TYPE_MASK, |
(program[1] >> T1_ADDRESS_REG_NR_SHIFT) & REG_NR_MASK); |
PRINTF(stream, "\n"); |
} |
static void |
print_dcl_op(struct debug_stream *stream, |
unsigned opcode, const unsigned * program) |
{ |
PRINTF(stream, "%s ", opcodes[opcode]); |
print_dest_reg(stream, |
program[0] | A0_DEST_CHANNEL_ALL); |
PRINTF(stream, "\n"); |
} |
void |
i915_disassemble_program(struct debug_stream *stream, |
const unsigned * program, unsigned sz) |
{ |
unsigned i; |
PRINTF(stream, "\t\tBEGIN\n"); |
assert((program[0] & 0x1ff) + 2 == sz); |
for (i = 1; i < sz; i += 3, program += 3) { |
unsigned opcode = program[0] & (0x1f << 24); |
PRINTF(stream, "\t\t"); |
if ((int) opcode >= A0_NOP && opcode <= A0_SLT) |
print_arith_op(stream, opcode >> 24, program); |
else if (opcode >= T0_TEXLD && opcode < T0_TEXKILL) |
print_tex_op(stream, opcode >> 24, program); |
else if (opcode == T0_TEXKILL) |
print_texkil_op(stream, opcode >> 24, program); |
else if (opcode == D0_DCL) |
print_dcl_op(stream, opcode >> 24, program); |
else |
PRINTF(stream, "Unknown opcode 0x%x\n", opcode); |
} |
PRINTF(stream, "\t\tEND\n\n"); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_debug_private.h |
---|
0,0 → 1,45 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* Authors: Keith Whitwell <keithw@vmware.com> |
*/ |
#ifndef I915_DEBUG_PRIVATE_H |
#define I915_DEBUG_PRIVATE_H |
struct debug_stream |
{ |
unsigned offset; /* current gtt offset */ |
char *ptr; /* pointer to gtt offset zero */ |
char *end; /* pointer to gtt offset zero */ |
unsigned print_addresses; |
}; |
void i915_disassemble_program(struct debug_stream *stream, |
const unsigned *program, unsigned sz); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_flush.c |
---|
0,0 → 1,91 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* Author: |
* Keith Whitwell <keithw@vmware.com> |
*/ |
#include "pipe/p_defines.h" |
#include "draw/draw_context.h" |
#include "i915_context.h" |
#include "i915_batch.h" |
#include "i915_debug.h" |
#include "i915_reg.h" |
static void i915_flush_pipe( struct pipe_context *pipe, |
struct pipe_fence_handle **fence, |
unsigned flags ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
enum i915_winsys_flush_flags winsys_flags = I915_FLUSH_ASYNC; |
if (!i915->batch) |
return; |
/* Only shortcut this if we have no fence, otherwise we must flush the |
* empty batchbuffer to get our fence back. |
*/ |
if (!fence && (i915->batch->map == i915->batch->ptr)) { |
return; |
} |
if (flags == PIPE_FLUSH_END_OF_FRAME) |
winsys_flags = I915_FLUSH_END_OF_FRAME; |
FLUSH_BATCH(fence, winsys_flags); |
I915_DBG(DBG_FLUSH, "%s: #####\n", __FUNCTION__); |
} |
void i915_init_flush_functions( struct i915_context *i915 ) |
{ |
i915->base.flush = i915_flush_pipe; |
} |
/** |
* Here we handle all the notifications that needs to go out on a flush. |
* XXX might move above function to i915_pipe_flush.c and leave this here. |
*/ |
void i915_flush(struct i915_context *i915, |
struct pipe_fence_handle **fence, |
unsigned flags) |
{ |
struct i915_winsys_batchbuffer *batch = i915->batch; |
batch->iws->batchbuffer_flush(batch, fence, flags); |
i915->vbo_flushed = 1; |
i915->hardware_dirty = ~0; |
i915->immediate_dirty = ~0; |
i915->dynamic_dirty = ~0; |
i915->static_dirty = ~0; |
/* kernel emits flushes in between batchbuffers */ |
i915->flush_dirty = 0; |
i915->fired_vertices += i915->queued_vertices; |
i915->queued_vertices = 0; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_fpc.h |
---|
0,0 → 1,329 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_FPC_H |
#define I915_FPC_H |
#include "i915_context.h" |
#include "i915_reg.h" |
#include "pipe/p_shader_tokens.h" |
#include "tgsi/tgsi_parse.h" |
#define I915_PROGRAM_SIZE 192 |
/* Use those indices for pos/face routing, must be >= num of inputs */ |
#define I915_SEMANTIC_POS 100 |
#define I915_SEMANTIC_FACE 101 |
/** |
* Program translation state |
*/ |
struct i915_fp_compile { |
struct i915_fragment_shader *shader; /* the shader we're compiling */ |
boolean used_constants[I915_MAX_CONSTANT]; |
/** maps TGSI immediate index to constant slot */ |
uint num_immediates; |
uint immediates_map[I915_MAX_CONSTANT]; |
float immediates[I915_MAX_CONSTANT][4]; |
boolean first_instruction; |
uint declarations[I915_PROGRAM_SIZE]; |
uint program[I915_PROGRAM_SIZE]; |
uint *csr; /**< Cursor, points into program. */ |
uint *decl; /**< Cursor, points into declarations. */ |
uint decl_s; /**< flags for which s regs need to be decl'd */ |
uint decl_t; /**< flags for which t regs need to be decl'd */ |
uint temp_flag; /**< Tracks temporary regs which are in use */ |
uint utemp_flag; /**< Tracks TYPE_U temporary regs which are in use */ |
uint register_phases[I915_MAX_TEMPORARY]; |
uint nr_tex_indirect; |
uint nr_tex_insn; |
uint nr_alu_insn; |
uint nr_decl_insn; |
boolean error; /**< Set if i915_program_error() is called */ |
uint NumNativeInstructions; |
uint NumNativeAluInstructions; |
uint NumNativeTexInstructions; |
uint NumNativeTexIndirections; |
}; |
/* Having zero and one in here makes the definition of swizzle a lot |
* easier. |
*/ |
#define UREG_TYPE_SHIFT 29 |
#define UREG_NR_SHIFT 24 |
#define UREG_CHANNEL_X_NEGATE_SHIFT 23 |
#define UREG_CHANNEL_X_SHIFT 20 |
#define UREG_CHANNEL_Y_NEGATE_SHIFT 19 |
#define UREG_CHANNEL_Y_SHIFT 16 |
#define UREG_CHANNEL_Z_NEGATE_SHIFT 15 |
#define UREG_CHANNEL_Z_SHIFT 12 |
#define UREG_CHANNEL_W_NEGATE_SHIFT 11 |
#define UREG_CHANNEL_W_SHIFT 8 |
#define UREG_CHANNEL_ZERO_NEGATE_MBZ 5 |
#define UREG_CHANNEL_ZERO_SHIFT 4 |
#define UREG_CHANNEL_ONE_NEGATE_MBZ 1 |
#define UREG_CHANNEL_ONE_SHIFT 0 |
#define UREG_BAD 0xffffffff /* not a valid ureg */ |
#define X SRC_X |
#define Y SRC_Y |
#define Z SRC_Z |
#define W SRC_W |
#define ZERO SRC_ZERO |
#define ONE SRC_ONE |
/* Construct a ureg: |
*/ |
#define UREG( type, nr ) (((type)<< UREG_TYPE_SHIFT) | \ |
((nr) << UREG_NR_SHIFT) | \ |
(X << UREG_CHANNEL_X_SHIFT) | \ |
(Y << UREG_CHANNEL_Y_SHIFT) | \ |
(Z << UREG_CHANNEL_Z_SHIFT) | \ |
(W << UREG_CHANNEL_W_SHIFT) | \ |
(ZERO << UREG_CHANNEL_ZERO_SHIFT) | \ |
(ONE << UREG_CHANNEL_ONE_SHIFT)) |
#define GET_CHANNEL_SRC( reg, channel ) ((reg<<(channel*4)) & (0xf<<20)) |
#define CHANNEL_SRC( src, channel ) (src>>(channel*4)) |
#define GET_UREG_TYPE(reg) (((reg)>>UREG_TYPE_SHIFT)®_TYPE_MASK) |
#define GET_UREG_NR(reg) (((reg)>>UREG_NR_SHIFT)®_NR_MASK) |
#define UREG_XYZW_CHANNEL_MASK 0x00ffff00 |
/* One neat thing about the UREG representation: |
*/ |
static INLINE int |
swizzle(int reg, uint x, uint y, uint z, uint w) |
{ |
assert(x <= SRC_ONE); |
assert(y <= SRC_ONE); |
assert(z <= SRC_ONE); |
assert(w <= SRC_ONE); |
return ((reg & ~UREG_XYZW_CHANNEL_MASK) | |
CHANNEL_SRC(GET_CHANNEL_SRC(reg, x), 0) | |
CHANNEL_SRC(GET_CHANNEL_SRC(reg, y), 1) | |
CHANNEL_SRC(GET_CHANNEL_SRC(reg, z), 2) | |
CHANNEL_SRC(GET_CHANNEL_SRC(reg, w), 3)); |
} |
#define A0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) |
#define D0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) |
#define T0_DEST( reg ) (((reg)&UREG_TYPE_NR_MASK)>>UREG_A0_DEST_SHIFT_LEFT) |
#define A0_SRC0( reg ) (((reg)&UREG_MASK)>>UREG_A0_SRC0_SHIFT_LEFT) |
#define A1_SRC0( reg ) (((reg)&UREG_MASK)<<UREG_A1_SRC0_SHIFT_RIGHT) |
#define A1_SRC1( reg ) (((reg)&UREG_MASK)>>UREG_A1_SRC1_SHIFT_LEFT) |
#define A2_SRC1( reg ) (((reg)&UREG_MASK)<<UREG_A2_SRC1_SHIFT_RIGHT) |
#define A2_SRC2( reg ) (((reg)&UREG_MASK)>>UREG_A2_SRC2_SHIFT_LEFT) |
/* These are special, and don't have swizzle/negate bits. |
*/ |
#define T0_SAMPLER( reg ) (GET_UREG_NR(reg)<<T0_SAMPLER_NR_SHIFT) |
#define T1_ADDRESS_REG( reg ) ((GET_UREG_NR(reg)<<T1_ADDRESS_REG_NR_SHIFT) | \ |
(GET_UREG_TYPE(reg)<<T1_ADDRESS_REG_TYPE_SHIFT)) |
/* Macros for translating UREG's into the various register fields used |
* by the I915 programmable unit. |
*/ |
#define UREG_A0_DEST_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_DEST_TYPE_SHIFT) |
#define UREG_A0_SRC0_SHIFT_LEFT (UREG_TYPE_SHIFT - A0_SRC0_TYPE_SHIFT) |
#define UREG_A1_SRC0_SHIFT_RIGHT (A1_SRC0_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) |
#define UREG_A1_SRC1_SHIFT_LEFT (UREG_TYPE_SHIFT - A1_SRC1_TYPE_SHIFT) |
#define UREG_A2_SRC1_SHIFT_RIGHT (A2_SRC1_CHANNEL_W_SHIFT - UREG_CHANNEL_W_SHIFT) |
#define UREG_A2_SRC2_SHIFT_LEFT (UREG_TYPE_SHIFT - A2_SRC2_TYPE_SHIFT) |
#define UREG_MASK 0xffffff00 |
#define UREG_TYPE_NR_MASK ((REG_TYPE_MASK << UREG_TYPE_SHIFT) | \ |
(REG_NR_MASK << UREG_NR_SHIFT)) |
/*********************************************************************** |
* Public interface for the compiler |
*/ |
extern void |
i915_translate_fragment_program( struct i915_context *i915, |
struct i915_fragment_shader *fs); |
extern uint i915_get_temp(struct i915_fp_compile *p); |
extern uint i915_get_utemp(struct i915_fp_compile *p); |
extern void i915_release_utemps(struct i915_fp_compile *p); |
extern uint i915_emit_texld(struct i915_fp_compile *p, |
uint dest, |
uint destmask, |
uint sampler, |
uint coord, |
uint op, |
uint num_coord); |
extern uint i915_emit_arith(struct i915_fp_compile *p, |
uint op, |
uint dest, |
uint mask, |
uint saturate, |
uint src0, uint src1, uint src2); |
extern uint i915_emit_decl(struct i915_fp_compile *p, |
uint type, uint nr, uint d0_flags); |
extern uint i915_emit_const1f(struct i915_fp_compile *p, float c0); |
extern uint i915_emit_const2f(struct i915_fp_compile *p, |
float c0, float c1); |
extern uint i915_emit_const4fv(struct i915_fp_compile *p, |
const float * c); |
extern uint i915_emit_const4f(struct i915_fp_compile *p, |
float c0, float c1, |
float c2, float c3); |
/*====================================================================== |
* i915_fpc_translate.c |
*/ |
extern void |
i915_program_error(struct i915_fp_compile *p, const char *msg, ...); |
/*====================================================================== |
* i915_fpc_optimize.c |
*/ |
struct i915_src_register |
{ |
unsigned File : 4; /* TGSI_FILE_ */ |
unsigned Indirect : 1; /* BOOL */ |
unsigned Dimension : 1; /* BOOL */ |
int Index : 16; /* SINT */ |
unsigned SwizzleX : 3; /* TGSI_SWIZZLE_ */ |
unsigned SwizzleY : 3; /* TGSI_SWIZZLE_ */ |
unsigned SwizzleZ : 3; /* TGSI_SWIZZLE_ */ |
unsigned SwizzleW : 3; /* TGSI_SWIZZLE_ */ |
unsigned Absolute : 1; /* BOOL */ |
unsigned Negate : 1; /* BOOL */ |
}; |
/* Additional swizzle supported in i915 */ |
#define TGSI_SWIZZLE_ZERO 4 |
#define TGSI_SWIZZLE_ONE 5 |
struct i915_dst_register |
{ |
unsigned File : 4; /* TGSI_FILE_ */ |
unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */ |
unsigned Indirect : 1; /* BOOL */ |
unsigned Dimension : 1; /* BOOL */ |
int Index : 16; /* SINT */ |
unsigned Padding : 6; |
}; |
struct i915_full_dst_register |
{ |
struct i915_dst_register Register; |
/* |
struct tgsi_ind_register Indirect; |
struct tgsi_dimension Dimension; |
struct tgsi_ind_register DimIndirect; |
*/ |
}; |
struct i915_full_src_register |
{ |
struct i915_src_register Register; |
/* |
struct tgsi_ind_register Indirect; |
struct tgsi_dimension Dimension; |
struct tgsi_ind_register DimIndirect; |
*/ |
}; |
struct i915_full_instruction |
{ |
struct tgsi_instruction Instruction; |
/* |
struct tgsi_instruction_predicate Predicate; |
struct tgsi_instruction_label Label; |
*/ |
struct tgsi_instruction_texture Texture; |
struct i915_full_dst_register Dst[1]; |
struct i915_full_src_register Src[3]; |
}; |
union i915_full_token |
{ |
struct tgsi_token Token; |
struct tgsi_full_declaration FullDeclaration; |
struct tgsi_full_immediate FullImmediate; |
struct i915_full_instruction FullInstruction; |
struct tgsi_full_property FullProperty; |
}; |
struct i915_token_list |
{ |
union i915_full_token* Tokens; |
unsigned NumTokens; |
}; |
extern struct i915_token_list* i915_optimize(const struct tgsi_token *tokens); |
extern void i915_optimize_free(struct i915_token_list *tokens); |
extern uint i915_num_coords(uint tex); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_fpc_emit.c |
---|
0,0 → 1,389 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_reg.h" |
#include "i915_context.h" |
#include "i915_fpc.h" |
#include "util/u_math.h" |
uint |
i915_get_temp(struct i915_fp_compile *p) |
{ |
int bit = ffs(~p->temp_flag); |
if (!bit) { |
i915_program_error(p, "i915_get_temp: out of temporaries"); |
return 0; |
} |
p->temp_flag |= 1 << (bit - 1); |
return bit - 1; |
} |
static void |
i915_release_temp(struct i915_fp_compile *p, int reg) |
{ |
p->temp_flag &= ~(1 << reg); |
} |
/** |
* Get unpreserved temporary, a temp whose value is not preserved between |
* PS program phases. |
*/ |
uint |
i915_get_utemp(struct i915_fp_compile * p) |
{ |
int bit = ffs(~p->utemp_flag); |
if (!bit) { |
i915_program_error(p, "i915_get_utemp: out of temporaries"); |
return 0; |
} |
p->utemp_flag |= 1 << (bit - 1); |
return UREG(REG_TYPE_U, (bit - 1)); |
} |
void |
i915_release_utemps(struct i915_fp_compile *p) |
{ |
p->utemp_flag = ~0x7; |
} |
uint |
i915_emit_decl(struct i915_fp_compile *p, |
uint type, uint nr, uint d0_flags) |
{ |
uint reg = UREG(type, nr); |
if (type == REG_TYPE_T) { |
if (p->decl_t & (1 << nr)) |
return reg; |
p->decl_t |= (1 << nr); |
} |
else if (type == REG_TYPE_S) { |
if (p->decl_s & (1 << nr)) |
return reg; |
p->decl_s |= (1 << nr); |
} |
else |
return reg; |
if (p->decl< p->declarations + I915_PROGRAM_SIZE) { |
*(p->decl++) = (D0_DCL | D0_DEST(reg) | d0_flags); |
*(p->decl++) = D1_MBZ; |
*(p->decl++) = D2_MBZ; |
} |
else |
i915_program_error(p, "Out of declarations"); |
p->nr_decl_insn++; |
return reg; |
} |
uint |
i915_emit_arith(struct i915_fp_compile * p, |
uint op, |
uint dest, |
uint mask, |
uint saturate, uint src0, uint src1, uint src2) |
{ |
uint c[3]; |
uint nr_const = 0; |
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); |
dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest)); |
assert(dest); |
if (GET_UREG_TYPE(src0) == REG_TYPE_CONST) |
c[nr_const++] = 0; |
if (GET_UREG_TYPE(src1) == REG_TYPE_CONST) |
c[nr_const++] = 1; |
if (GET_UREG_TYPE(src2) == REG_TYPE_CONST) |
c[nr_const++] = 2; |
/* Recursively call this function to MOV additional const values |
* into temporary registers. Use utemp registers for this - |
* currently shouldn't be possible to run out, but keep an eye on |
* this. |
*/ |
if (nr_const > 1) { |
uint s[3], first, i, old_utemp_flag; |
s[0] = src0; |
s[1] = src1; |
s[2] = src2; |
old_utemp_flag = p->utemp_flag; |
first = GET_UREG_NR(s[c[0]]); |
for (i = 1; i < nr_const; i++) { |
if (GET_UREG_NR(s[c[i]]) != first) { |
uint tmp = i915_get_utemp(p); |
i915_emit_arith(p, A0_MOV, tmp, A0_DEST_CHANNEL_ALL, 0, |
s[c[i]], 0, 0); |
s[c[i]] = tmp; |
} |
} |
src0 = s[0]; |
src1 = s[1]; |
src2 = s[2]; |
p->utemp_flag = old_utemp_flag; /* restore */ |
} |
if (p->csr< p->program + I915_PROGRAM_SIZE) { |
*(p->csr++) = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0)); |
*(p->csr++) = (A1_SRC0(src0) | A1_SRC1(src1)); |
*(p->csr++) = (A2_SRC1(src1) | A2_SRC2(src2)); |
} |
else |
i915_program_error(p, "Out of instructions"); |
if (GET_UREG_TYPE(dest) == REG_TYPE_R) |
p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect; |
p->nr_alu_insn++; |
return dest; |
} |
/** |
* Emit a texture load or texkill instruction. |
* \param dest the dest i915 register |
* \param destmask the dest register writemask |
* \param sampler the i915 sampler register |
* \param coord the i915 source texcoord operand |
* \param opcode the instruction opcode |
*/ |
uint i915_emit_texld( struct i915_fp_compile *p, |
uint dest, |
uint destmask, |
uint sampler, |
uint coord, |
uint opcode, |
uint num_coord ) |
{ |
const uint k = UREG(GET_UREG_TYPE(coord), GET_UREG_NR(coord)); |
int temp = -1; |
uint ignore = 0; |
/* Eliminate the useless texture coordinates. Otherwise we end up generating |
* a swizzle for no reason below. */ |
switch(num_coord) { |
case 0: |
ignore |= (0xf << UREG_CHANNEL_X_SHIFT); |
/* fall-through */ |
case 1: |
ignore |= (0xf << UREG_CHANNEL_Y_SHIFT); |
/* fall-through */ |
case 2: |
ignore |= (0xf << UREG_CHANNEL_Z_SHIFT); |
/* fall-through */ |
case 3: |
ignore |= (0xf << UREG_CHANNEL_W_SHIFT); |
} |
if ( (coord & ~ignore ) != (k & ~ignore) ) { |
/* texcoord is swizzled or negated. Need to allocate a new temporary |
* register (a utemp / unpreserved temp) won't do. |
*/ |
uint tempReg; |
temp = i915_get_temp(p); /* get temp reg index */ |
tempReg = UREG(REG_TYPE_R, temp); /* make i915 register */ |
i915_emit_arith( p, A0_MOV, |
tempReg, A0_DEST_CHANNEL_ALL, /* dest reg, writemask */ |
0, /* saturate */ |
coord, 0, 0 ); /* src0, src1, src2 */ |
/* new src texcoord is tempReg */ |
coord = tempReg; |
} |
/* Don't worry about saturate as we only support |
*/ |
if (destmask != A0_DEST_CHANNEL_ALL) { |
/* if not writing to XYZW... */ |
uint tmp = i915_get_utemp(p); |
i915_emit_texld( p, tmp, A0_DEST_CHANNEL_ALL, sampler, coord, opcode, num_coord ); |
i915_emit_arith( p, A0_MOV, dest, destmask, 0, tmp, 0, 0 ); |
/* XXX release utemp here? */ |
} |
else { |
assert(GET_UREG_TYPE(dest) != REG_TYPE_CONST); |
assert(dest == UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest))); |
/* Output register being oC or oD defines a phase boundary */ |
if (GET_UREG_TYPE(dest) == REG_TYPE_OC || |
GET_UREG_TYPE(dest) == REG_TYPE_OD) |
p->nr_tex_indirect++; |
/* Reading from an r# register whose contents depend on output of the |
* current phase defines a phase boundary. |
*/ |
if (GET_UREG_TYPE(coord) == REG_TYPE_R && |
p->register_phases[GET_UREG_NR(coord)] == p->nr_tex_indirect) |
p->nr_tex_indirect++; |
if (p->csr< p->program + I915_PROGRAM_SIZE) { |
*(p->csr++) = (opcode | |
T0_DEST( dest ) | |
T0_SAMPLER( sampler )); |
*(p->csr++) = T1_ADDRESS_REG( coord ); |
*(p->csr++) = T2_MBZ; |
} |
else |
i915_program_error(p, "Out of instructions"); |
if (GET_UREG_TYPE(dest) == REG_TYPE_R) |
p->register_phases[GET_UREG_NR(dest)] = p->nr_tex_indirect; |
p->nr_tex_insn++; |
} |
if (temp >= 0) |
i915_release_temp(p, temp); |
return dest; |
} |
uint |
i915_emit_const1f(struct i915_fp_compile * p, float c0) |
{ |
struct i915_fragment_shader *ifs = p->shader; |
unsigned reg, idx; |
if (c0 == 0.0) |
return swizzle(UREG(REG_TYPE_R, 0), ZERO, ZERO, ZERO, ZERO); |
if (c0 == 1.0) |
return swizzle(UREG(REG_TYPE_R, 0), ONE, ONE, ONE, ONE); |
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { |
if (ifs->constant_flags[reg] == I915_CONSTFLAG_USER) |
continue; |
for (idx = 0; idx < 4; idx++) { |
if (!(ifs->constant_flags[reg] & (1 << idx)) || |
ifs->constants[reg][idx] == c0) { |
ifs->constants[reg][idx] = c0; |
ifs->constant_flags[reg] |= 1 << idx; |
if (reg + 1 > ifs->num_constants) |
ifs->num_constants = reg + 1; |
return swizzle(UREG(REG_TYPE_CONST, reg), idx, ZERO, ZERO, ONE); |
} |
} |
} |
i915_program_error(p, "i915_emit_const1f: out of constants"); |
return 0; |
} |
uint |
i915_emit_const2f(struct i915_fp_compile * p, float c0, float c1) |
{ |
struct i915_fragment_shader *ifs = p->shader; |
unsigned reg, idx; |
if (c0 == 0.0) |
return swizzle(i915_emit_const1f(p, c1), ZERO, X, Z, W); |
if (c0 == 1.0) |
return swizzle(i915_emit_const1f(p, c1), ONE, X, Z, W); |
if (c1 == 0.0) |
return swizzle(i915_emit_const1f(p, c0), X, ZERO, Z, W); |
if (c1 == 1.0) |
return swizzle(i915_emit_const1f(p, c0), X, ONE, Z, W); |
// XXX emit swizzle here for 0, 1, -1 and any combination thereof |
// we can use swizzle + neg for that |
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { |
if (ifs->constant_flags[reg] == 0xf || |
ifs->constant_flags[reg] == I915_CONSTFLAG_USER) |
continue; |
for (idx = 0; idx < 3; idx++) { |
if (!(ifs->constant_flags[reg] & (3 << idx))) { |
ifs->constants[reg][idx + 0] = c0; |
ifs->constants[reg][idx + 1] = c1; |
ifs->constant_flags[reg] |= 3 << idx; |
if (reg + 1 > ifs->num_constants) |
ifs->num_constants = reg + 1; |
return swizzle(UREG(REG_TYPE_CONST, reg), idx, idx + 1, ZERO, ONE); |
} |
} |
} |
i915_program_error(p, "i915_emit_const2f: out of constants"); |
return 0; |
} |
uint |
i915_emit_const4f(struct i915_fp_compile * p, |
float c0, float c1, float c2, float c3) |
{ |
struct i915_fragment_shader *ifs = p->shader; |
unsigned reg; |
// XXX emit swizzle here for 0, 1, -1 and any combination thereof |
// we can use swizzle + neg for that |
for (reg = 0; reg < I915_MAX_CONSTANT; reg++) { |
if (ifs->constant_flags[reg] == 0xf && |
ifs->constants[reg][0] == c0 && |
ifs->constants[reg][1] == c1 && |
ifs->constants[reg][2] == c2 && |
ifs->constants[reg][3] == c3) { |
return UREG(REG_TYPE_CONST, reg); |
} |
else if (ifs->constant_flags[reg] == 0) { |
ifs->constants[reg][0] = c0; |
ifs->constants[reg][1] = c1; |
ifs->constants[reg][2] = c2; |
ifs->constants[reg][3] = c3; |
ifs->constant_flags[reg] = 0xf; |
if (reg + 1 > ifs->num_constants) |
ifs->num_constants = reg + 1; |
return UREG(REG_TYPE_CONST, reg); |
} |
} |
i915_program_error(p, "i915_emit_const4f: out of constants"); |
return 0; |
} |
uint |
i915_emit_const4fv(struct i915_fp_compile * p, const float * c) |
{ |
return i915_emit_const4f(p, c[0], c[1], c[2], c[3]); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_fpc_optimize.c |
---|
0,0 → 1,660 |
/************************************************************************** |
* |
* Copyright 2011 The Chromium OS authors. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL GOOGLE 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 "i915_reg.h" |
#include "i915_context.h" |
#include "i915_fpc.h" |
#include "pipe/p_shader_tokens.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_string.h" |
#include "tgsi/tgsi_parse.h" |
#include "tgsi/tgsi_dump.h" |
#include "tgsi/tgsi_exec.h" |
struct i915_optimize_context |
{ |
int first_write[TGSI_EXEC_NUM_TEMPS]; |
int last_read[TGSI_EXEC_NUM_TEMPS]; |
}; |
static boolean same_src_dst_reg(struct i915_full_src_register *s1, struct i915_full_dst_register *d1) |
{ |
return (s1->Register.File == d1->Register.File && |
s1->Register.Indirect == d1->Register.Indirect && |
s1->Register.Dimension == d1->Register.Dimension && |
s1->Register.Index == d1->Register.Index); |
} |
static boolean same_dst_reg(struct i915_full_dst_register *d1, struct i915_full_dst_register *d2) |
{ |
return (d1->Register.File == d2->Register.File && |
d1->Register.Indirect == d2->Register.Indirect && |
d1->Register.Dimension == d2->Register.Dimension && |
d1->Register.Index == d2->Register.Index); |
} |
static boolean same_src_reg(struct i915_full_src_register *d1, struct i915_full_src_register *d2) |
{ |
return (d1->Register.File == d2->Register.File && |
d1->Register.Indirect == d2->Register.Indirect && |
d1->Register.Dimension == d2->Register.Dimension && |
d1->Register.Index == d2->Register.Index && |
d1->Register.Absolute == d2->Register.Absolute && |
d1->Register.Negate == d2->Register.Negate); |
} |
const static struct { |
boolean is_texture; |
boolean commutes; |
unsigned neutral_element; |
unsigned num_dst; |
unsigned num_src; |
} op_table [TGSI_OPCODE_LAST] = { |
[ TGSI_OPCODE_ABS ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_ADD ] = { false, true, TGSI_SWIZZLE_ZERO, 1, 2 }, |
[ TGSI_OPCODE_CEIL ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_CMP ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_COS ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_DDX ] = { false, false, 0, 1, 0 }, |
[ TGSI_OPCODE_DDY ] = { false, false, 0, 1, 0 }, |
[ TGSI_OPCODE_DP2 ] = { false, true, TGSI_SWIZZLE_ONE, 1, 2 }, |
[ TGSI_OPCODE_DP3 ] = { false, true, TGSI_SWIZZLE_ONE, 1, 2 }, |
[ TGSI_OPCODE_DP4 ] = { false, true, TGSI_SWIZZLE_ONE, 1, 2 }, |
[ TGSI_OPCODE_DPH ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_DST ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_END ] = { false, false, 0, 0, 0 }, |
[ TGSI_OPCODE_EX2 ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_FLR ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_FRC ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_KILL_IF ] = { false, false, 0, 0, 1 }, |
[ TGSI_OPCODE_KILL ] = { false, false, 0, 0, 0 }, |
[ TGSI_OPCODE_LG2 ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_LIT ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_LRP ] = { false, false, 0, 1, 3 }, |
[ TGSI_OPCODE_MAX ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_MAD ] = { false, false, 0, 1, 3 }, |
[ TGSI_OPCODE_MIN ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_MOV ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_MUL ] = { false, true, TGSI_SWIZZLE_ONE, 1, 2 }, |
[ TGSI_OPCODE_NOP ] = { false, false, 0, 0, 0 }, |
[ TGSI_OPCODE_POW ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_RCP ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_RET ] = { false, false, 0, 0, 0 }, |
[ TGSI_OPCODE_RSQ ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_SCS ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_SEQ ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_SGE ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_SGT ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_SIN ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_SLE ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_SLT ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_SNE ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_SSG ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_SUB ] = { false, false, 0, 1, 2 }, |
[ TGSI_OPCODE_TEX ] = { true, false, 0, 1, 2 }, |
[ TGSI_OPCODE_TRUNC ] = { false, false, 0, 1, 1 }, |
[ TGSI_OPCODE_TXB ] = { true, false, 0, 1, 2 }, |
[ TGSI_OPCODE_TXP ] = { true, false, 0, 1, 2 }, |
[ TGSI_OPCODE_XPD ] = { false, false, 0, 1, 2 }, |
}; |
static boolean op_has_dst(unsigned opcode) |
{ |
return (op_table[opcode].num_dst > 0); |
} |
static int op_num_dst(unsigned opcode) |
{ |
return op_table[opcode].num_dst; |
} |
static int op_num_src(unsigned opcode) |
{ |
return op_table[opcode].num_src; |
} |
static boolean op_commutes(unsigned opcode) |
{ |
return op_table[opcode].commutes; |
} |
static unsigned mask_for_unswizzled(int num_components) |
{ |
unsigned mask = 0; |
switch(num_components) |
{ |
case 4: |
mask |= TGSI_WRITEMASK_W; |
case 3: |
mask |= TGSI_WRITEMASK_Z; |
case 2: |
mask |= TGSI_WRITEMASK_Y; |
case 1: |
mask |= TGSI_WRITEMASK_X; |
} |
return mask; |
} |
static boolean is_unswizzled(struct i915_full_src_register *r, |
unsigned write_mask) |
{ |
if ( write_mask & TGSI_WRITEMASK_X && r->Register.SwizzleX != TGSI_SWIZZLE_X) |
return FALSE; |
if ( write_mask & TGSI_WRITEMASK_Y && r->Register.SwizzleY != TGSI_SWIZZLE_Y) |
return FALSE; |
if ( write_mask & TGSI_WRITEMASK_Z && r->Register.SwizzleZ != TGSI_SWIZZLE_Z) |
return FALSE; |
if ( write_mask & TGSI_WRITEMASK_W && r->Register.SwizzleW != TGSI_SWIZZLE_W) |
return FALSE; |
return TRUE; |
} |
static boolean op_is_texture(unsigned opcode) |
{ |
return op_table[opcode].is_texture; |
} |
static unsigned op_neutral_element(unsigned opcode) |
{ |
unsigned ne = op_table[opcode].neutral_element; |
if (!ne) { |
debug_printf("No neutral element for opcode %d\n",opcode); |
ne = TGSI_SWIZZLE_ZERO; |
} |
return ne; |
} |
/* |
* Sets the swizzle to the neutral element for the operation for the bits |
* of writemask which are set, swizzle to identity otherwise. |
*/ |
static void set_neutral_element_swizzle(struct i915_full_src_register *r, |
unsigned write_mask, |
unsigned neutral) |
{ |
if ( write_mask & TGSI_WRITEMASK_X ) |
r->Register.SwizzleX = neutral; |
else |
r->Register.SwizzleX = TGSI_SWIZZLE_X; |
if ( write_mask & TGSI_WRITEMASK_Y ) |
r->Register.SwizzleY = neutral; |
else |
r->Register.SwizzleY = TGSI_SWIZZLE_Y; |
if ( write_mask & TGSI_WRITEMASK_Z ) |
r->Register.SwizzleZ = neutral; |
else |
r->Register.SwizzleZ = TGSI_SWIZZLE_Z; |
if ( write_mask & TGSI_WRITEMASK_W ) |
r->Register.SwizzleW = neutral; |
else |
r->Register.SwizzleW = TGSI_SWIZZLE_W; |
} |
static void copy_src_reg(struct i915_src_register *o, const struct tgsi_src_register *i) |
{ |
o->File = i->File; |
o->Indirect = i->Indirect; |
o->Dimension = i->Dimension; |
o->Index = i->Index; |
o->SwizzleX = i->SwizzleX; |
o->SwizzleY = i->SwizzleY; |
o->SwizzleZ = i->SwizzleZ; |
o->SwizzleW = i->SwizzleW; |
o->Absolute = i->Absolute; |
o->Negate = i->Negate; |
} |
static void copy_dst_reg(struct i915_dst_register *o, const struct tgsi_dst_register *i) |
{ |
o->File = i->File; |
o->WriteMask = i->WriteMask; |
o->Indirect = i->Indirect; |
o->Dimension = i->Dimension; |
o->Index = i->Index; |
} |
static void copy_instruction(struct i915_full_instruction *o, const struct tgsi_full_instruction *i) |
{ |
memcpy(&o->Instruction, &i->Instruction, sizeof(o->Instruction)); |
memcpy(&o->Texture, &i->Texture, sizeof(o->Texture)); |
copy_dst_reg(&o->Dst[0].Register, &i->Dst[0].Register); |
copy_src_reg(&o->Src[0].Register, &i->Src[0].Register); |
copy_src_reg(&o->Src[1].Register, &i->Src[1].Register); |
copy_src_reg(&o->Src[2].Register, &i->Src[2].Register); |
} |
static void copy_token(union i915_full_token *o, union tgsi_full_token *i) |
{ |
if (i->Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION) |
memcpy(o, i, sizeof(*o)); |
else |
copy_instruction(&o->FullInstruction, &i->FullInstruction); |
} |
static void liveness_mark_written(struct i915_optimize_context *ctx, |
struct i915_full_dst_register *dst_reg, |
int pos) |
{ |
int dst_reg_index; |
if (dst_reg->Register.File == TGSI_FILE_TEMPORARY) { |
dst_reg_index = dst_reg->Register.Index; |
assert(dst_reg_index < TGSI_EXEC_NUM_TEMPS); |
/* dead -> live transition */ |
if (ctx->first_write[dst_reg_index] != -1) |
ctx->first_write[dst_reg_index] = pos; |
} |
} |
static void liveness_mark_read(struct i915_optimize_context *ctx, |
struct i915_full_src_register *src_reg, |
int pos) |
{ |
int src_reg_index; |
if (src_reg->Register.File == TGSI_FILE_TEMPORARY) { |
src_reg_index = src_reg->Register.Index; |
assert(src_reg_index < TGSI_EXEC_NUM_TEMPS); |
/* live -> dead transition */ |
if (ctx->last_read[src_reg_index] != -1) |
ctx->last_read[src_reg_index] = pos; |
} |
} |
static void liveness_analysis(struct i915_optimize_context *ctx, |
struct i915_token_list *tokens) |
{ |
struct i915_full_dst_register *dst_reg; |
struct i915_full_src_register *src_reg; |
union i915_full_token *current; |
unsigned opcode; |
int num_dst, num_src; |
int i = 0; |
for(i = 0; i < TGSI_EXEC_NUM_TEMPS; i++) |
{ |
ctx->first_write[i] = -1; |
ctx->last_read[i] = -1; |
} |
for(i = 0; i < tokens->NumTokens; i++) |
{ |
current = &tokens->Tokens[i]; |
if (current->Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION) |
continue; |
opcode = current->FullInstruction.Instruction.Opcode; |
num_dst = op_num_dst(opcode); |
switch(num_dst) |
{ |
case 1: |
dst_reg = ¤t->FullInstruction.Dst[0]; |
liveness_mark_written(ctx, dst_reg, i); |
case 0: |
break; |
default: |
debug_printf("Op %d has %d dst regs\n", opcode, num_dst); |
break; |
} |
} |
for(i = tokens->NumTokens - 1; i >= 0; i--) |
{ |
current = &tokens->Tokens[i]; |
if (current->Token.Type != TGSI_TOKEN_TYPE_INSTRUCTION) |
continue; |
opcode = current->FullInstruction.Instruction.Opcode; |
num_src = op_num_src(opcode); |
switch(num_src) |
{ |
case 3: |
src_reg = ¤t->FullInstruction.Src[2]; |
liveness_mark_read(ctx, src_reg, i); |
case 2: |
src_reg = ¤t->FullInstruction.Src[1]; |
liveness_mark_read(ctx, src_reg, i); |
case 1: |
src_reg = ¤t->FullInstruction.Src[0]; |
liveness_mark_read(ctx, src_reg, i); |
case 0: |
break; |
default: |
debug_printf("Op %d has %d src regs\n", opcode, num_src); |
break; |
} |
} |
} |
static int unused_from(struct i915_optimize_context *ctx, struct i915_full_dst_register *dst_reg, int from) |
{ |
int dst_reg_index = dst_reg->Register.Index; |
assert(dst_reg_index < TGSI_EXEC_NUM_TEMPS); |
return (from >= ctx->last_read[dst_reg_index]); |
} |
/* Returns a mask with the components used for a texture access instruction */ |
static unsigned i915_tex_mask(union i915_full_token *instr) |
{ |
unsigned mask; |
/* Get the number of coords */ |
mask = mask_for_unswizzled(i915_num_coords(instr->FullInstruction.Texture.Texture)); |
/* Add the W component if projective */ |
if (instr->FullInstruction.Instruction.Opcode == TGSI_OPCODE_TXP) |
mask |= TGSI_WRITEMASK_W; |
return mask; |
} |
static boolean target_is_texture2d(uint tex) |
{ |
switch (tex) { |
case TGSI_TEXTURE_2D: |
case TGSI_TEXTURE_RECT: |
return true; |
default: |
return false; |
} |
} |
/* |
* Optimize away useless indirect texture reads: |
* MOV TEMP[0].xy, IN[0].xyyy |
* TEX TEMP[1], TEMP[0], SAMP[0], 2D |
* into: |
* TEX TEMP[1], IN[0], SAMP[0], 2D |
* |
* note: this only seems to work on 2D/RECT textures, but not SHAADOW2D/1D/.. |
*/ |
static void i915_fpc_optimize_mov_before_tex(struct i915_optimize_context *ctx, |
struct i915_token_list *tokens, |
int index) |
{ |
union i915_full_token *current = &tokens->Tokens[index - 1]; |
union i915_full_token *next = &tokens->Tokens[index]; |
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
current->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
op_is_texture(next->FullInstruction.Instruction.Opcode) && |
target_is_texture2d(next->FullInstruction.Texture.Texture) && |
same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) && |
is_unswizzled(¤t->FullInstruction.Src[0], i915_tex_mask(next)) && |
unused_from(ctx, ¤t->FullInstruction.Dst[0], index)) |
{ |
memcpy(&next->FullInstruction.Src[0], ¤t->FullInstruction.Src[0], sizeof(struct i915_src_register)); |
current->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; |
} |
} |
/* |
* Optimize away things like: |
* MOV TEMP[0].xy, TEMP[1].xyyy (first write for TEMP[0]) |
* MOV TEMP[0].w, TEMP[1].wwww (last write for TEMP[0]) |
* into: |
* NOP |
* MOV OUT[0].xyw, TEMP[1].xyww |
*/ |
static void i915_fpc_optimize_mov_after_mov(union i915_full_token *current, union i915_full_token *next) |
{ |
struct i915_full_src_register *src_reg1, *src_reg2; |
struct i915_full_dst_register *dst_reg1, *dst_reg2; |
unsigned swizzle_x, swizzle_y, swizzle_z, swizzle_w; |
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
current->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate && |
same_dst_reg(&next->FullInstruction.Dst[0], ¤t->FullInstruction.Dst[0]) && |
same_src_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Src[0]) && |
!same_src_dst_reg(¤t->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) ) |
{ |
src_reg1 = ¤t->FullInstruction.Src[0]; |
dst_reg1 = ¤t->FullInstruction.Dst[0]; |
src_reg2 = &next->FullInstruction.Src[0]; |
dst_reg2 = &next->FullInstruction.Dst[0]; |
/* Start with swizzles from the first mov */ |
swizzle_x = src_reg1->Register.SwizzleX; |
swizzle_y = src_reg1->Register.SwizzleY; |
swizzle_z = src_reg1->Register.SwizzleZ; |
swizzle_w = src_reg1->Register.SwizzleW; |
/* Pile the second mov on top */ |
if (dst_reg2->Register.WriteMask & TGSI_WRITEMASK_X) |
swizzle_x = src_reg2->Register.SwizzleX; |
if (dst_reg2->Register.WriteMask & TGSI_WRITEMASK_Y) |
swizzle_y = src_reg2->Register.SwizzleY; |
if (dst_reg2->Register.WriteMask & TGSI_WRITEMASK_Z) |
swizzle_z = src_reg2->Register.SwizzleZ; |
if (dst_reg2->Register.WriteMask & TGSI_WRITEMASK_W) |
swizzle_w = src_reg2->Register.SwizzleW; |
dst_reg2->Register.WriteMask |= dst_reg1->Register.WriteMask; |
src_reg2->Register.SwizzleX = swizzle_x; |
src_reg2->Register.SwizzleY = swizzle_y; |
src_reg2->Register.SwizzleZ = swizzle_z; |
src_reg2->Register.SwizzleW = swizzle_w; |
current->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; |
return; |
} |
} |
/* |
* Optimize away things like: |
* MUL OUT[0].xyz, TEMP[1], TEMP[2] |
* MOV OUT[0].w, TEMP[2] |
* into: |
* MUL OUT[0].xyzw, TEMP[1].xyz1, TEMP[2] |
* This is useful for optimizing texenv. |
*/ |
static void i915_fpc_optimize_mov_after_alu(union i915_full_token *current, union i915_full_token *next) |
{ |
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
op_commutes(current->FullInstruction.Instruction.Opcode) && |
current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate && |
next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
same_dst_reg(&next->FullInstruction.Dst[0], ¤t->FullInstruction.Dst[0]) && |
same_src_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Src[1]) && |
!same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) && |
is_unswizzled(¤t->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) && |
is_unswizzled(¤t->FullInstruction.Src[1], current->FullInstruction.Dst[0].Register.WriteMask) && |
is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) ) |
{ |
next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; |
set_neutral_element_swizzle(¤t->FullInstruction.Src[1], 0, 0); |
set_neutral_element_swizzle(¤t->FullInstruction.Src[0], |
next->FullInstruction.Dst[0].Register.WriteMask, |
op_neutral_element(current->FullInstruction.Instruction.Opcode)); |
current->FullInstruction.Dst[0].Register.WriteMask = current->FullInstruction.Dst[0].Register.WriteMask | |
next->FullInstruction.Dst[0].Register.WriteMask; |
return; |
} |
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
op_commutes(current->FullInstruction.Instruction.Opcode) && |
current->FullInstruction.Instruction.Saturate == next->FullInstruction.Instruction.Saturate && |
next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
same_dst_reg(&next->FullInstruction.Dst[0], ¤t->FullInstruction.Dst[0]) && |
same_src_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Src[0]) && |
!same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) && |
is_unswizzled(¤t->FullInstruction.Src[0], current->FullInstruction.Dst[0].Register.WriteMask) && |
is_unswizzled(¤t->FullInstruction.Src[1], current->FullInstruction.Dst[0].Register.WriteMask) && |
is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) ) |
{ |
next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; |
set_neutral_element_swizzle(¤t->FullInstruction.Src[0], 0, 0); |
set_neutral_element_swizzle(¤t->FullInstruction.Src[1], |
next->FullInstruction.Dst[0].Register.WriteMask, |
op_neutral_element(current->FullInstruction.Instruction.Opcode)); |
current->FullInstruction.Dst[0].Register.WriteMask = current->FullInstruction.Dst[0].Register.WriteMask | |
next->FullInstruction.Dst[0].Register.WriteMask; |
return; |
} |
} |
/* |
* Optimize away things like: |
* MOV TEMP[0].xyz TEMP[0].xyzx |
* into: |
* NOP |
*/ |
static boolean i915_fpc_useless_mov(union tgsi_full_token *tgsi_current) |
{ |
union i915_full_token current; |
copy_token(¤t , tgsi_current); |
if ( current.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
current.FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
op_has_dst(current.FullInstruction.Instruction.Opcode) && |
current.FullInstruction.Instruction.Saturate == TGSI_SAT_NONE && |
current.FullInstruction.Src[0].Register.Absolute == 0 && |
current.FullInstruction.Src[0].Register.Negate == 0 && |
is_unswizzled(¤t.FullInstruction.Src[0], current.FullInstruction.Dst[0].Register.WriteMask) && |
same_src_dst_reg(¤t.FullInstruction.Src[0], ¤t.FullInstruction.Dst[0]) ) |
{ |
return TRUE; |
} |
return FALSE; |
} |
/* |
* Optimize away things like: |
* *** TEMP[0], TEMP[1], TEMP[2] |
* MOV OUT[0] TEMP[0] |
* into: |
* *** OUT[0], TEMP[1], TEMP[2] |
*/ |
static void i915_fpc_optimize_useless_mov_after_inst(struct i915_optimize_context *ctx, |
struct i915_token_list *tokens, |
int index) |
{ |
union i915_full_token *current = &tokens->Tokens[index - 1]; |
union i915_full_token *next = &tokens->Tokens[index]; |
// &out_tokens->Tokens[i-1], &out_tokens->Tokens[i]); |
if ( current->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
next->Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION && |
next->FullInstruction.Instruction.Opcode == TGSI_OPCODE_MOV && |
op_has_dst(current->FullInstruction.Instruction.Opcode) && |
next->FullInstruction.Instruction.Saturate == TGSI_SAT_NONE && |
next->FullInstruction.Src[0].Register.Absolute == 0 && |
next->FullInstruction.Src[0].Register.Negate == 0 && |
unused_from(ctx, ¤t->FullInstruction.Dst[0], index) && |
current->FullInstruction.Dst[0].Register.WriteMask == TGSI_WRITEMASK_XYZW && |
is_unswizzled(&next->FullInstruction.Src[0], next->FullInstruction.Dst[0].Register.WriteMask) && |
current->FullInstruction.Dst[0].Register.WriteMask == next->FullInstruction.Dst[0].Register.WriteMask && |
same_src_dst_reg(&next->FullInstruction.Src[0], ¤t->FullInstruction.Dst[0]) ) |
{ |
next->FullInstruction.Instruction.Opcode = TGSI_OPCODE_NOP; |
current->FullInstruction.Dst[0] = next->FullInstruction.Dst[0]; |
return; |
} |
} |
struct i915_token_list* i915_optimize(const struct tgsi_token *tokens) |
{ |
struct i915_token_list *out_tokens = MALLOC(sizeof(struct i915_token_list)); |
struct tgsi_parse_context parse; |
struct i915_optimize_context *ctx; |
int i = 0; |
ctx = malloc(sizeof(*ctx)); |
out_tokens->NumTokens = 0; |
/* Count the tokens */ |
tgsi_parse_init( &parse, tokens ); |
while( !tgsi_parse_end_of_tokens( &parse ) ) { |
tgsi_parse_token( &parse ); |
out_tokens->NumTokens++; |
} |
tgsi_parse_free (&parse); |
/* Allocate our tokens */ |
out_tokens->Tokens = MALLOC(sizeof(union i915_full_token) * out_tokens->NumTokens); |
tgsi_parse_init( &parse, tokens ); |
while( !tgsi_parse_end_of_tokens( &parse ) ) { |
tgsi_parse_token( &parse ); |
if (i915_fpc_useless_mov(&parse.FullToken)) { |
out_tokens->NumTokens--; |
continue; |
} |
copy_token(&out_tokens->Tokens[i] , &parse.FullToken); |
i++; |
} |
tgsi_parse_free (&parse); |
liveness_analysis(ctx, out_tokens); |
i = 1; |
while( i < out_tokens->NumTokens) { |
i915_fpc_optimize_useless_mov_after_inst(ctx, out_tokens, i); |
i915_fpc_optimize_mov_after_alu(&out_tokens->Tokens[i-1], &out_tokens->Tokens[i]); |
i915_fpc_optimize_mov_after_mov(&out_tokens->Tokens[i-1], &out_tokens->Tokens[i]); |
i915_fpc_optimize_mov_before_tex(ctx, out_tokens, i); |
i++; |
} |
free(ctx); |
return out_tokens; |
} |
void i915_optimize_free(struct i915_token_list *tokens) |
{ |
free(tokens->Tokens); |
free(tokens); |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_fpc_translate.c |
---|
0,0 → 1,1376 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include <stdarg.h> |
#include "i915_reg.h" |
#include "i915_context.h" |
#include "i915_fpc.h" |
#include "i915_debug_private.h" |
#include "pipe/p_shader_tokens.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_string.h" |
#include "tgsi/tgsi_parse.h" |
#include "tgsi/tgsi_dump.h" |
#include "draw/draw_vertex.h" |
#ifndef M_PI |
#define M_PI 3.14159265358979323846 |
#endif |
/** |
* Simple pass-through fragment shader to use when we don't have |
* a real shader (or it fails to compile for some reason). |
*/ |
static unsigned passthrough_decl[] = |
{ |
_3DSTATE_PIXEL_SHADER_PROGRAM | ((2*3)-1), |
/* declare input color: |
*/ |
(D0_DCL | |
(REG_TYPE_T << D0_TYPE_SHIFT) | |
(T_DIFFUSE << D0_NR_SHIFT) | |
D0_CHANNEL_ALL), |
0, |
0, |
}; |
static unsigned passthrough_program[] = |
{ |
/* move to output color: |
*/ |
(A0_MOV | |
(REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | |
A0_DEST_CHANNEL_ALL | |
(REG_TYPE_T << A0_SRC0_TYPE_SHIFT) | |
(T_DIFFUSE << A0_SRC0_NR_SHIFT)), |
0x01230000, /* .xyzw */ |
0 |
}; |
/* 1, -1/3!, 1/5!, -1/7! */ |
static const float scs_sin_constants[4] = { 1.0, |
-1.0f / (3 * 2 * 1), |
1.0f / (5 * 4 * 3 * 2 * 1), |
-1.0f / (7 * 6 * 5 * 4 * 3 * 2 * 1) |
}; |
/* 1, -1/2!, 1/4!, -1/6! */ |
static const float scs_cos_constants[4] = { 1.0, |
-1.0f / (2 * 1), |
1.0f / (4 * 3 * 2 * 1), |
-1.0f / (6 * 5 * 4 * 3 * 2 * 1) |
}; |
/* 2*pi, -(2*pi)^3/3!, (2*pi)^5/5!, -(2*pi)^7/7! */ |
static const float sin_constants[4] = { 2.0 * M_PI, |
-8.0f * M_PI * M_PI * M_PI / (3 * 2 * 1), |
32.0f * M_PI * M_PI * M_PI * M_PI * M_PI / (5 * 4 * 3 * 2 * 1), |
-128.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (7 * 6 * 5 * 4 * 3 * 2 * 1) |
}; |
/* 1, -(2*pi)^2/2!, (2*pi)^4/4!, -(2*pi)^6/6! */ |
static const float cos_constants[4] = { 1.0, |
-4.0f * M_PI * M_PI / (2 * 1), |
16.0f * M_PI * M_PI * M_PI * M_PI / (4 * 3 * 2 * 1), |
-64.0f * M_PI * M_PI * M_PI * M_PI * M_PI * M_PI / (6 * 5 * 4 * 3 * 2 * 1) |
}; |
/** |
* component-wise negation of ureg |
*/ |
static INLINE int |
negate(int reg, int x, int y, int z, int w) |
{ |
/* Another neat thing about the UREG representation */ |
return reg ^ (((x & 1) << UREG_CHANNEL_X_NEGATE_SHIFT) | |
((y & 1) << UREG_CHANNEL_Y_NEGATE_SHIFT) | |
((z & 1) << UREG_CHANNEL_Z_NEGATE_SHIFT) | |
((w & 1) << UREG_CHANNEL_W_NEGATE_SHIFT)); |
} |
/** |
* In the event of a translation failure, we'll generate a simple color |
* pass-through program. |
*/ |
static void |
i915_use_passthrough_shader(struct i915_fragment_shader *fs) |
{ |
fs->program = (uint *) MALLOC(sizeof(passthrough_program)); |
fs->decl = (uint *) MALLOC(sizeof(passthrough_decl)); |
if (fs->program) { |
memcpy(fs->program, passthrough_program, sizeof(passthrough_program)); |
memcpy(fs->decl, passthrough_decl, sizeof(passthrough_decl)); |
fs->program_len = Elements(passthrough_program); |
fs->decl_len = Elements(passthrough_decl); |
} |
fs->num_constants = 0; |
} |
void |
i915_program_error(struct i915_fp_compile *p, const char *msg, ...) |
{ |
va_list args; |
char buffer[1024]; |
debug_printf("i915_program_error: "); |
va_start( args, msg ); |
util_vsnprintf( buffer, sizeof(buffer), msg, args ); |
va_end( args ); |
debug_printf("%s", buffer); |
debug_printf("\n"); |
p->error = 1; |
} |
static uint get_mapping(struct i915_fragment_shader* fs, int unit) |
{ |
int i; |
for (i = 0; i < I915_TEX_UNITS; i++) |
{ |
if (fs->generic_mapping[i] == -1) { |
fs->generic_mapping[i] = unit; |
return i; |
} |
if (fs->generic_mapping[i] == unit) |
return i; |
} |
debug_printf("Exceeded max generics\n"); |
return 0; |
} |
/** |
* Construct a ureg for the given source register. Will emit |
* constants, apply swizzling and negation as needed. |
*/ |
static uint |
src_vector(struct i915_fp_compile *p, |
const struct i915_full_src_register *source, |
struct i915_fragment_shader *fs) |
{ |
uint index = source->Register.Index; |
uint src = 0, sem_name, sem_ind; |
switch (source->Register.File) { |
case TGSI_FILE_TEMPORARY: |
if (source->Register.Index >= I915_MAX_TEMPORARY) { |
i915_program_error(p, "Exceeded max temporary reg"); |
return 0; |
} |
src = UREG(REG_TYPE_R, index); |
break; |
case TGSI_FILE_INPUT: |
/* XXX: Packing COL1, FOGC into a single attribute works for |
* texenv programs, but will fail for real fragment programs |
* that use these attributes and expect them to be a full 4 |
* components wide. Could use a texcoord to pass these |
* attributes if necessary, but that won't work in the general |
* case. |
* |
* We also use a texture coordinate to pass wpos when possible. |
*/ |
sem_name = p->shader->info.input_semantic_name[index]; |
sem_ind = p->shader->info.input_semantic_index[index]; |
switch (sem_name) { |
case TGSI_SEMANTIC_POSITION: |
{ |
/* for fragcoord */ |
int real_tex_unit = get_mapping(fs, I915_SEMANTIC_POS); |
src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL); |
break; |
} |
case TGSI_SEMANTIC_COLOR: |
if (sem_ind == 0) { |
src = i915_emit_decl(p, REG_TYPE_T, T_DIFFUSE, D0_CHANNEL_ALL); |
} |
else { |
/* secondary color */ |
assert(sem_ind == 1); |
src = i915_emit_decl(p, REG_TYPE_T, T_SPECULAR, D0_CHANNEL_XYZ); |
src = swizzle(src, X, Y, Z, ONE); |
} |
break; |
case TGSI_SEMANTIC_FOG: |
src = i915_emit_decl(p, REG_TYPE_T, T_FOG_W, D0_CHANNEL_W); |
src = swizzle(src, W, W, W, W); |
break; |
case TGSI_SEMANTIC_GENERIC: |
{ |
int real_tex_unit = get_mapping(fs, sem_ind); |
src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_ALL); |
break; |
} |
case TGSI_SEMANTIC_FACE: |
{ |
/* for back/front faces */ |
int real_tex_unit = get_mapping(fs, I915_SEMANTIC_FACE); |
src = i915_emit_decl(p, REG_TYPE_T, T_TEX0 + real_tex_unit, D0_CHANNEL_X); |
break; |
} |
default: |
i915_program_error(p, "Bad source->Index"); |
return 0; |
} |
break; |
case TGSI_FILE_IMMEDIATE: |
assert(index < p->num_immediates); |
index = p->immediates_map[index]; |
/* fall-through */ |
case TGSI_FILE_CONSTANT: |
src = UREG(REG_TYPE_CONST, index); |
break; |
default: |
i915_program_error(p, "Bad source->File"); |
return 0; |
} |
src = swizzle(src, |
source->Register.SwizzleX, |
source->Register.SwizzleY, |
source->Register.SwizzleZ, |
source->Register.SwizzleW); |
/* There's both negate-all-components and per-component negation. |
* Try to handle both here. |
*/ |
{ |
int n = source->Register.Negate; |
src = negate(src, n, n, n, n); |
} |
/* no abs() */ |
#if 0 |
/* XXX assertions disabled to allow arbfplight.c to run */ |
/* XXX enable these assertions, or fix things */ |
assert(!source->Register.Absolute); |
#endif |
if (source->Register.Absolute) |
debug_printf("Unhandled absolute value\n"); |
return src; |
} |
/** |
* Construct a ureg for a destination register. |
*/ |
static uint |
get_result_vector(struct i915_fp_compile *p, |
const struct i915_full_dst_register *dest) |
{ |
switch (dest->Register.File) { |
case TGSI_FILE_OUTPUT: |
{ |
uint sem_name = p->shader->info.output_semantic_name[dest->Register.Index]; |
switch (sem_name) { |
case TGSI_SEMANTIC_POSITION: |
return UREG(REG_TYPE_OD, 0); |
case TGSI_SEMANTIC_COLOR: |
return UREG(REG_TYPE_OC, 0); |
default: |
i915_program_error(p, "Bad inst->DstReg.Index/semantics"); |
return 0; |
} |
} |
case TGSI_FILE_TEMPORARY: |
return UREG(REG_TYPE_R, dest->Register.Index); |
default: |
i915_program_error(p, "Bad inst->DstReg.File"); |
return 0; |
} |
} |
/** |
* Compute flags for saturation and writemask. |
*/ |
static uint |
get_result_flags(const struct i915_full_instruction *inst) |
{ |
const uint writeMask |
= inst->Dst[0].Register.WriteMask; |
uint flags = 0x0; |
if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) |
flags |= A0_DEST_SATURATE; |
if (writeMask & TGSI_WRITEMASK_X) |
flags |= A0_DEST_CHANNEL_X; |
if (writeMask & TGSI_WRITEMASK_Y) |
flags |= A0_DEST_CHANNEL_Y; |
if (writeMask & TGSI_WRITEMASK_Z) |
flags |= A0_DEST_CHANNEL_Z; |
if (writeMask & TGSI_WRITEMASK_W) |
flags |= A0_DEST_CHANNEL_W; |
return flags; |
} |
/** |
* Convert TGSI_TEXTURE_x token to DO_SAMPLE_TYPE_x token |
*/ |
static uint |
translate_tex_src_target(struct i915_fp_compile *p, uint tex) |
{ |
switch (tex) { |
case TGSI_TEXTURE_SHADOW1D: |
/* fall-through */ |
case TGSI_TEXTURE_1D: |
return D0_SAMPLE_TYPE_2D; |
case TGSI_TEXTURE_SHADOW2D: |
/* fall-through */ |
case TGSI_TEXTURE_2D: |
return D0_SAMPLE_TYPE_2D; |
case TGSI_TEXTURE_SHADOWRECT: |
/* fall-through */ |
case TGSI_TEXTURE_RECT: |
return D0_SAMPLE_TYPE_2D; |
case TGSI_TEXTURE_3D: |
return D0_SAMPLE_TYPE_VOLUME; |
case TGSI_TEXTURE_CUBE: |
return D0_SAMPLE_TYPE_CUBE; |
default: |
i915_program_error(p, "TexSrc type"); |
return 0; |
} |
} |
/** |
* Return the number of coords needed to access a given TGSI_TEXTURE_* |
*/ |
uint |
i915_num_coords(uint tex) |
{ |
switch (tex) { |
case TGSI_TEXTURE_SHADOW1D: |
case TGSI_TEXTURE_1D: |
return 1; |
case TGSI_TEXTURE_SHADOW2D: |
case TGSI_TEXTURE_2D: |
case TGSI_TEXTURE_SHADOWRECT: |
case TGSI_TEXTURE_RECT: |
return 2; |
case TGSI_TEXTURE_3D: |
case TGSI_TEXTURE_CUBE: |
return 3; |
default: |
debug_printf("Unknown texture target for num coords"); |
return 2; |
} |
} |
/** |
* Generate texel lookup instruction. |
*/ |
static void |
emit_tex(struct i915_fp_compile *p, |
const struct i915_full_instruction *inst, |
uint opcode, |
struct i915_fragment_shader* fs) |
{ |
uint texture = inst->Texture.Texture; |
uint unit = inst->Src[1].Register.Index; |
uint tex = translate_tex_src_target( p, texture ); |
uint sampler = i915_emit_decl(p, REG_TYPE_S, unit, tex); |
uint coord = src_vector( p, &inst->Src[0], fs); |
i915_emit_texld( p, |
get_result_vector( p, &inst->Dst[0] ), |
get_result_flags( inst ), |
sampler, |
coord, |
opcode, |
i915_num_coords(texture) ); |
} |
/** |
* Generate a simple arithmetic instruction |
* \param opcode the i915 opcode |
* \param numArgs the number of input/src arguments |
*/ |
static void |
emit_simple_arith(struct i915_fp_compile *p, |
const struct i915_full_instruction *inst, |
uint opcode, uint numArgs, |
struct i915_fragment_shader *fs) |
{ |
uint arg1, arg2, arg3; |
assert(numArgs <= 3); |
arg1 = (numArgs < 1) ? 0 : src_vector( p, &inst->Src[0], fs ); |
arg2 = (numArgs < 2) ? 0 : src_vector( p, &inst->Src[1], fs ); |
arg3 = (numArgs < 3) ? 0 : src_vector( p, &inst->Src[2], fs ); |
i915_emit_arith( p, |
opcode, |
get_result_vector( p, &inst->Dst[0]), |
get_result_flags( inst ), 0, |
arg1, |
arg2, |
arg3 ); |
} |
/** As above, but swap the first two src regs */ |
static void |
emit_simple_arith_swap2(struct i915_fp_compile *p, |
const struct i915_full_instruction *inst, |
uint opcode, uint numArgs, |
struct i915_fragment_shader *fs) |
{ |
struct i915_full_instruction inst2; |
assert(numArgs == 2); |
/* transpose first two registers */ |
inst2 = *inst; |
inst2.Src[0] = inst->Src[1]; |
inst2.Src[1] = inst->Src[0]; |
emit_simple_arith(p, &inst2, opcode, numArgs, fs); |
} |
/* |
* Translate TGSI instruction to i915 instruction. |
* |
* Possible concerns: |
* |
* DDX, DDY -- return 0 |
* SIN, COS -- could use another taylor step? |
* LIT -- results seem a little different to sw mesa |
* LOG -- different to mesa on negative numbers, but this is conformant. |
*/ |
static void |
i915_translate_instruction(struct i915_fp_compile *p, |
const struct i915_full_instruction *inst, |
struct i915_fragment_shader *fs) |
{ |
uint writemask; |
uint src0, src1, src2, flags; |
uint tmp = 0; |
switch (inst->Instruction.Opcode) { |
case TGSI_OPCODE_ABS: |
src0 = src_vector(p, &inst->Src[0], fs); |
i915_emit_arith(p, |
A0_MAX, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
src0, negate(src0, 1, 1, 1, 1), 0); |
break; |
case TGSI_OPCODE_ADD: |
emit_simple_arith(p, inst, A0_ADD, 2, fs); |
break; |
case TGSI_OPCODE_CEIL: |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
flags = get_result_flags(inst); |
i915_emit_arith(p, |
A0_FLR, |
tmp, |
flags & A0_DEST_CHANNEL_ALL, 0, |
negate(src0, 1, 1, 1, 1), 0, 0); |
i915_emit_arith(p, |
A0_MOV, |
get_result_vector(p, &inst->Dst[0]), |
flags, 0, |
negate(tmp, 1, 1, 1, 1), 0, 0); |
break; |
case TGSI_OPCODE_CMP: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
src2 = src_vector(p, &inst->Src[2], fs); |
i915_emit_arith(p, A0_CMP, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), |
0, src0, src2, src1); /* NOTE: order of src2, src1 */ |
break; |
case TGSI_OPCODE_COS: |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_X, 0, |
src0, i915_emit_const1f(p, 1.0f / (float) (M_PI * 2.0)), 0); |
i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); |
/* |
* t0.xy = MUL x.xx11, x.x111 ; x^2, x, 1, 1 |
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, 1 |
* t0 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 |
* result = DP4 t0, cos_constants |
*/ |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_XY, 0, |
swizzle(tmp, X, X, ONE, ONE), |
swizzle(tmp, X, ONE, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_XYZ, 0, |
swizzle(tmp, X, Y, X, ONE), |
swizzle(tmp, X, X, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_XYZ, 0, |
swizzle(tmp, X, X, Z, ONE), |
swizzle(tmp, Z, ONE, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_DP4, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(tmp, ONE, Z, Y, X), |
i915_emit_const4fv(p, cos_constants), 0); |
break; |
case TGSI_OPCODE_DDX: |
case TGSI_OPCODE_DDY: |
/* XXX We just output 0 here */ |
debug_printf("Punting DDX/DDX\n"); |
src0 = get_result_vector(p, &inst->Dst[0]); |
i915_emit_arith(p, |
A0_MOV, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0, 0); |
break; |
case TGSI_OPCODE_DP2: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
i915_emit_arith(p, |
A0_DP3, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, X, Y, ZERO, ZERO), src1, 0); |
break; |
case TGSI_OPCODE_DP3: |
emit_simple_arith(p, inst, A0_DP3, 2, fs); |
break; |
case TGSI_OPCODE_DP4: |
emit_simple_arith(p, inst, A0_DP4, 2, fs); |
break; |
case TGSI_OPCODE_DPH: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
i915_emit_arith(p, |
A0_DP4, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, X, Y, Z, ONE), src1, 0); |
break; |
case TGSI_OPCODE_DST: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
/* result[0] = 1 * 1; |
* result[1] = a[1] * b[1]; |
* result[2] = a[2] * 1; |
* result[3] = 1 * b[3]; |
*/ |
i915_emit_arith(p, |
A0_MUL, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, ONE, Y, Z, ONE), |
swizzle(src1, ONE, Y, ONE, W), 0); |
break; |
case TGSI_OPCODE_END: |
/* no-op */ |
break; |
case TGSI_OPCODE_EX2: |
src0 = src_vector(p, &inst->Src[0], fs); |
i915_emit_arith(p, |
A0_EXP, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, X, X, X, X), 0, 0); |
break; |
case TGSI_OPCODE_FLR: |
emit_simple_arith(p, inst, A0_FLR, 1, fs); |
break; |
case TGSI_OPCODE_FRC: |
emit_simple_arith(p, inst, A0_FRC, 1, fs); |
break; |
case TGSI_OPCODE_KILL_IF: |
/* kill if src[0].x < 0 || src[0].y < 0 ... */ |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
i915_emit_texld(p, |
tmp, /* dest reg: a dummy reg */ |
A0_DEST_CHANNEL_ALL, /* dest writemask */ |
0, /* sampler */ |
src0, /* coord*/ |
T0_TEXKILL, /* opcode */ |
1); /* num_coord */ |
break; |
case TGSI_OPCODE_KILL: |
/* unconditional kill */ |
tmp = i915_get_utemp(p); |
i915_emit_texld(p, |
tmp, /* dest reg: a dummy reg */ |
A0_DEST_CHANNEL_ALL, /* dest writemask */ |
0, /* sampler */ |
negate(swizzle(0, ONE, ONE, ONE, ONE), 1, 1, 1, 1), /* coord */ |
T0_TEXKILL, /* opcode */ |
1); /* num_coord */ |
break; |
case TGSI_OPCODE_LG2: |
src0 = src_vector(p, &inst->Src[0], fs); |
i915_emit_arith(p, |
A0_LOG, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, X, X, X, X), 0, 0); |
break; |
case TGSI_OPCODE_LIT: |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
/* tmp = max( a.xyzw, a.00zw ) |
* XXX: Clamp tmp.w to -128..128 |
* tmp.y = log(tmp.y) |
* tmp.y = tmp.w * tmp.y |
* tmp.y = exp(tmp.y) |
* result = cmp (a.11-x1, a.1x01, a.1xy1 ) |
*/ |
i915_emit_arith(p, A0_MAX, tmp, A0_DEST_CHANNEL_ALL, 0, |
src0, swizzle(src0, ZERO, ZERO, Z, W), 0); |
i915_emit_arith(p, A0_LOG, tmp, A0_DEST_CHANNEL_Y, 0, |
swizzle(tmp, Y, Y, Y, Y), 0, 0); |
i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_Y, 0, |
swizzle(tmp, ZERO, Y, ZERO, ZERO), |
swizzle(tmp, ZERO, W, ZERO, ZERO), 0); |
i915_emit_arith(p, A0_EXP, tmp, A0_DEST_CHANNEL_Y, 0, |
swizzle(tmp, Y, Y, Y, Y), 0, 0); |
i915_emit_arith(p, A0_CMP, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
negate(swizzle(tmp, ONE, ONE, X, ONE), 0, 0, 1, 0), |
swizzle(tmp, ONE, X, ZERO, ONE), |
swizzle(tmp, ONE, X, Y, ONE)); |
break; |
case TGSI_OPCODE_LRP: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
src2 = src_vector(p, &inst->Src[2], fs); |
flags = get_result_flags(inst); |
tmp = i915_get_utemp(p); |
/* b*a + c*(1-a) |
* |
* b*a + c - ca |
* |
* tmp = b*a + c, |
* result = (-c)*a + tmp |
*/ |
i915_emit_arith(p, A0_MAD, tmp, |
flags & A0_DEST_CHANNEL_ALL, 0, src1, src0, src2); |
i915_emit_arith(p, A0_MAD, |
get_result_vector(p, &inst->Dst[0]), |
flags, 0, negate(src2, 1, 1, 1, 1), src0, tmp); |
break; |
case TGSI_OPCODE_MAD: |
emit_simple_arith(p, inst, A0_MAD, 3, fs); |
break; |
case TGSI_OPCODE_MAX: |
emit_simple_arith(p, inst, A0_MAX, 2, fs); |
break; |
case TGSI_OPCODE_MIN: |
emit_simple_arith(p, inst, A0_MIN, 2, fs); |
break; |
case TGSI_OPCODE_MOV: |
emit_simple_arith(p, inst, A0_MOV, 1, fs); |
break; |
case TGSI_OPCODE_MUL: |
emit_simple_arith(p, inst, A0_MUL, 2, fs); |
break; |
case TGSI_OPCODE_NOP: |
break; |
case TGSI_OPCODE_POW: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
tmp = i915_get_utemp(p); |
flags = get_result_flags(inst); |
/* XXX: masking on intermediate values, here and elsewhere. |
*/ |
i915_emit_arith(p, |
A0_LOG, |
tmp, A0_DEST_CHANNEL_X, 0, |
swizzle(src0, X, X, X, X), 0, 0); |
i915_emit_arith(p, A0_MUL, tmp, A0_DEST_CHANNEL_X, 0, tmp, src1, 0); |
i915_emit_arith(p, |
A0_EXP, |
get_result_vector(p, &inst->Dst[0]), |
flags, 0, swizzle(tmp, X, X, X, X), 0, 0); |
break; |
case TGSI_OPCODE_RET: |
/* XXX: no-op? */ |
break; |
case TGSI_OPCODE_RCP: |
src0 = src_vector(p, &inst->Src[0], fs); |
i915_emit_arith(p, |
A0_RCP, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, X, X, X, X), 0, 0); |
break; |
case TGSI_OPCODE_RSQ: |
src0 = src_vector(p, &inst->Src[0], fs); |
i915_emit_arith(p, |
A0_RSQ, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, X, X, X, X), 0, 0); |
break; |
case TGSI_OPCODE_SCS: |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
/* |
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 |
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x |
* t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x |
* scs.x = DP4 t1, scs_sin_constants |
* t1 = MUL t0.xxz1 t0.z111 ; x^6 x^4 x^2 1 |
* scs.y = DP4 t1, scs_cos_constants |
*/ |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_XY, 0, |
swizzle(src0, X, X, ONE, ONE), |
swizzle(src0, X, ONE, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_ALL, 0, |
swizzle(tmp, X, Y, X, Y), |
swizzle(tmp, X, X, ONE, ONE), 0); |
writemask = inst->Dst[0].Register.WriteMask; |
if (writemask & TGSI_WRITEMASK_Y) { |
uint tmp1; |
if (writemask & TGSI_WRITEMASK_X) |
tmp1 = i915_get_utemp(p); |
else |
tmp1 = tmp; |
i915_emit_arith(p, |
A0_MUL, |
tmp1, A0_DEST_CHANNEL_ALL, 0, |
swizzle(tmp, X, Y, Y, W), |
swizzle(tmp, X, Z, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_DP4, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_Y, 0, |
swizzle(tmp1, W, Z, Y, X), |
i915_emit_const4fv(p, scs_sin_constants), 0); |
} |
if (writemask & TGSI_WRITEMASK_X) { |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_XYZ, 0, |
swizzle(tmp, X, X, Z, ONE), |
swizzle(tmp, Z, ONE, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_DP4, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_X, 0, |
swizzle(tmp, ONE, Z, Y, X), |
i915_emit_const4fv(p, scs_cos_constants), 0); |
} |
break; |
case TGSI_OPCODE_SEQ: |
/* if we're both >= and <= then we're == */ |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
tmp = i915_get_utemp(p); |
i915_emit_arith(p, |
A0_SGE, |
tmp, A0_DEST_CHANNEL_ALL, 0, |
src0, |
src1, 0); |
i915_emit_arith(p, |
A0_SGE, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_ALL, 0, |
src1, |
src0, 0); |
i915_emit_arith(p, |
A0_MUL, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_ALL, 0, |
get_result_vector(p, &inst->Dst[0]), |
tmp, 0); |
break; |
case TGSI_OPCODE_SGE: |
emit_simple_arith(p, inst, A0_SGE, 2, fs); |
break; |
case TGSI_OPCODE_SIN: |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_X, 0, |
src0, i915_emit_const1f(p, 1.0f / (float) (M_PI * 2.0)), 0); |
i915_emit_arith(p, A0_MOD, tmp, A0_DEST_CHANNEL_X, 0, tmp, 0, 0); |
/* |
* t0.xy = MUL x.xx11, x.x1111 ; x^2, x, 1, 1 |
* t0 = MUL t0.xyxy t0.xx11 ; x^4, x^3, x^2, x |
* t1 = MUL t0.xyyw t0.yz11 ; x^7 x^5 x^3 x |
* result = DP4 t1.wzyx, sin_constants |
*/ |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_XY, 0, |
swizzle(tmp, X, X, ONE, ONE), |
swizzle(tmp, X, ONE, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_ALL, 0, |
swizzle(tmp, X, Y, X, Y), |
swizzle(tmp, X, X, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_ALL, 0, |
swizzle(tmp, X, Y, Y, W), |
swizzle(tmp, X, Z, ONE, ONE), 0); |
i915_emit_arith(p, |
A0_DP4, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(tmp, W, Z, Y, X), |
i915_emit_const4fv(p, sin_constants), 0); |
break; |
case TGSI_OPCODE_SLE: |
/* like SGE, but swap reg0, reg1 */ |
emit_simple_arith_swap2(p, inst, A0_SGE, 2, fs); |
break; |
case TGSI_OPCODE_SLT: |
emit_simple_arith(p, inst, A0_SLT, 2, fs); |
break; |
case TGSI_OPCODE_SGT: |
/* like SLT, but swap reg0, reg1 */ |
emit_simple_arith_swap2(p, inst, A0_SLT, 2, fs); |
break; |
case TGSI_OPCODE_SNE: |
/* if we're < or > then we're != */ |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
tmp = i915_get_utemp(p); |
i915_emit_arith(p, |
A0_SLT, |
tmp, |
A0_DEST_CHANNEL_ALL, 0, |
src0, |
src1, 0); |
i915_emit_arith(p, |
A0_SLT, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_ALL, 0, |
src1, |
src0, 0); |
i915_emit_arith(p, |
A0_ADD, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_ALL, 0, |
get_result_vector(p, &inst->Dst[0]), |
tmp, 0); |
break; |
case TGSI_OPCODE_SSG: |
/* compute (src>0) - (src<0) */ |
src0 = src_vector(p, &inst->Src[0], fs); |
tmp = i915_get_utemp(p); |
i915_emit_arith(p, |
A0_SLT, |
tmp, |
A0_DEST_CHANNEL_ALL, 0, |
src0, |
swizzle(src0, ZERO, ZERO, ZERO, ZERO), 0); |
i915_emit_arith(p, |
A0_SLT, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_ALL, 0, |
swizzle(src0, ZERO, ZERO, ZERO, ZERO), |
src0, 0); |
i915_emit_arith(p, |
A0_ADD, |
get_result_vector(p, &inst->Dst[0]), |
A0_DEST_CHANNEL_ALL, 0, |
get_result_vector(p, &inst->Dst[0]), |
negate(tmp, 1, 1, 1, 1), 0); |
break; |
case TGSI_OPCODE_SUB: |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
i915_emit_arith(p, |
A0_ADD, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
src0, negate(src1, 1, 1, 1, 1), 0); |
break; |
case TGSI_OPCODE_TEX: |
emit_tex(p, inst, T0_TEXLD, fs); |
break; |
case TGSI_OPCODE_TRUNC: |
emit_simple_arith(p, inst, A0_TRC, 1, fs); |
break; |
case TGSI_OPCODE_TXB: |
emit_tex(p, inst, T0_TEXLDB, fs); |
break; |
case TGSI_OPCODE_TXP: |
emit_tex(p, inst, T0_TEXLDP, fs); |
break; |
case TGSI_OPCODE_XPD: |
/* Cross product: |
* result.x = src0.y * src1.z - src0.z * src1.y; |
* result.y = src0.z * src1.x - src0.x * src1.z; |
* result.z = src0.x * src1.y - src0.y * src1.x; |
* result.w = undef; |
*/ |
src0 = src_vector(p, &inst->Src[0], fs); |
src1 = src_vector(p, &inst->Src[1], fs); |
tmp = i915_get_utemp(p); |
i915_emit_arith(p, |
A0_MUL, |
tmp, A0_DEST_CHANNEL_ALL, 0, |
swizzle(src0, Z, X, Y, ONE), |
swizzle(src1, Y, Z, X, ONE), 0); |
i915_emit_arith(p, |
A0_MAD, |
get_result_vector(p, &inst->Dst[0]), |
get_result_flags(inst), 0, |
swizzle(src0, Y, Z, X, ONE), |
swizzle(src1, Z, X, Y, ONE), |
negate(tmp, 1, 1, 1, 0)); |
break; |
default: |
i915_program_error(p, "bad opcode %d", inst->Instruction.Opcode); |
p->error = 1; |
return; |
} |
i915_release_utemps(p); |
} |
static void i915_translate_token(struct i915_fp_compile *p, |
const union i915_full_token *token, |
struct i915_fragment_shader *fs) |
{ |
struct i915_fragment_shader *ifs = p->shader; |
switch( token->Token.Type ) { |
case TGSI_TOKEN_TYPE_PROPERTY: |
/* |
* We only support one cbuf, but we still need to ignore the property |
* correctly so we don't hit the assert at the end of the switch case. |
*/ |
assert(token->FullProperty.Property.PropertyName == |
TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS); |
break; |
case TGSI_TOKEN_TYPE_DECLARATION: |
if (token->FullDeclaration.Declaration.File |
== TGSI_FILE_CONSTANT) { |
uint i; |
for (i = token->FullDeclaration.Range.First; |
i <= MIN2(token->FullDeclaration.Range.Last, I915_MAX_CONSTANT - 1); |
i++) { |
assert(ifs->constant_flags[i] == 0x0); |
ifs->constant_flags[i] = I915_CONSTFLAG_USER; |
ifs->num_constants = MAX2(ifs->num_constants, i + 1); |
} |
} |
else if (token->FullDeclaration.Declaration.File |
== TGSI_FILE_TEMPORARY) { |
uint i; |
for (i = token->FullDeclaration.Range.First; |
i <= token->FullDeclaration.Range.Last; |
i++) { |
if (i >= I915_MAX_TEMPORARY) |
debug_printf("Too many temps (%d)\n",i); |
else |
/* XXX just use shader->info->file_mask[TGSI_FILE_TEMPORARY] */ |
p->temp_flag |= (1 << i); /* mark temp as used */ |
} |
} |
break; |
case TGSI_TOKEN_TYPE_IMMEDIATE: |
{ |
const struct tgsi_full_immediate *imm |
= &token->FullImmediate; |
const uint pos = p->num_immediates++; |
uint j; |
assert( imm->Immediate.NrTokens <= 4 + 1 ); |
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) { |
p->immediates[pos][j] = imm->u[j].Float; |
} |
} |
break; |
case TGSI_TOKEN_TYPE_INSTRUCTION: |
if (p->first_instruction) { |
/* resolve location of immediates */ |
uint i, j; |
for (i = 0; i < p->num_immediates; i++) { |
/* find constant slot for this immediate */ |
for (j = 0; j < I915_MAX_CONSTANT; j++) { |
if (ifs->constant_flags[j] == 0x0) { |
memcpy(ifs->constants[j], |
p->immediates[i], |
4 * sizeof(float)); |
/*printf("immediate %d maps to const %d\n", i, j);*/ |
ifs->constant_flags[j] = 0xf; /* all four comps used */ |
p->immediates_map[i] = j; |
ifs->num_constants = MAX2(ifs->num_constants, j + 1); |
break; |
} |
} |
} |
p->first_instruction = FALSE; |
} |
i915_translate_instruction(p, &token->FullInstruction, fs); |
break; |
default: |
assert( 0 ); |
} |
} |
/** |
* Translate TGSI fragment shader into i915 hardware instructions. |
* \param p the translation state |
* \param tokens the TGSI token array |
*/ |
static void |
i915_translate_instructions(struct i915_fp_compile *p, |
const struct i915_token_list *tokens, |
struct i915_fragment_shader *fs) |
{ |
int i; |
for(i = 0; i<tokens->NumTokens; i++) { |
i915_translate_token(p, &tokens->Tokens[i], fs); |
} |
} |
static struct i915_fp_compile * |
i915_init_compile(struct i915_context *i915, |
struct i915_fragment_shader *ifs) |
{ |
struct i915_fp_compile *p = CALLOC_STRUCT(i915_fp_compile); |
int i; |
p->shader = ifs; |
/* Put new constants at end of const buffer, growing downward. |
* The problem is we don't know how many user-defined constants might |
* be specified with pipe->set_constant_buffer(). |
* Should pre-scan the user's program to determine the highest-numbered |
* constant referenced. |
*/ |
ifs->num_constants = 0; |
memset(ifs->constant_flags, 0, sizeof(ifs->constant_flags)); |
memset(&p->register_phases, 0, sizeof(p->register_phases)); |
for (i = 0; i < I915_TEX_UNITS; i++) |
ifs->generic_mapping[i] = -1; |
p->first_instruction = TRUE; |
p->nr_tex_indirect = 1; /* correct? */ |
p->nr_tex_insn = 0; |
p->nr_alu_insn = 0; |
p->nr_decl_insn = 0; |
p->csr = p->program; |
p->decl = p->declarations; |
p->decl_s = 0; |
p->decl_t = 0; |
p->temp_flag = ~0x0 << I915_MAX_TEMPORARY; |
p->utemp_flag = ~0x7; |
/* initialize the first program word */ |
*(p->decl++) = _3DSTATE_PIXEL_SHADER_PROGRAM; |
return p; |
} |
/* Copy compile results to the fragment program struct and destroy the |
* compilation context. |
*/ |
static void |
i915_fini_compile(struct i915_context *i915, struct i915_fp_compile *p) |
{ |
struct i915_fragment_shader *ifs = p->shader; |
unsigned long program_size = (unsigned long) (p->csr - p->program); |
unsigned long decl_size = (unsigned long) (p->decl - p->declarations); |
if (p->nr_tex_indirect > I915_MAX_TEX_INDIRECT) |
debug_printf("Exceeded max nr indirect texture lookups\n"); |
if (p->nr_tex_insn > I915_MAX_TEX_INSN) |
i915_program_error(p, "Exceeded max TEX instructions"); |
if (p->nr_alu_insn > I915_MAX_ALU_INSN) |
i915_program_error(p, "Exceeded max ALU instructions"); |
if (p->nr_decl_insn > I915_MAX_DECL_INSN) |
i915_program_error(p, "Exceeded max DECL instructions"); |
if (p->error) { |
p->NumNativeInstructions = 0; |
p->NumNativeAluInstructions = 0; |
p->NumNativeTexInstructions = 0; |
p->NumNativeTexIndirections = 0; |
i915_use_passthrough_shader(ifs); |
} |
else { |
p->NumNativeInstructions |
= p->nr_alu_insn + p->nr_tex_insn + p->nr_decl_insn; |
p->NumNativeAluInstructions = p->nr_alu_insn; |
p->NumNativeTexInstructions = p->nr_tex_insn; |
p->NumNativeTexIndirections = p->nr_tex_indirect; |
/* patch in the program length */ |
p->declarations[0] |= program_size + decl_size - 2; |
/* Copy compilation results to fragment program struct: |
*/ |
assert(!ifs->decl); |
assert(!ifs->program); |
ifs->decl |
= (uint *) MALLOC(decl_size * sizeof(uint)); |
ifs->program |
= (uint *) MALLOC(program_size * sizeof(uint)); |
if (ifs->decl) { |
ifs->decl_len = decl_size; |
memcpy(ifs->decl, |
p->declarations, |
decl_size * sizeof(uint)); |
} |
if (ifs->program) { |
ifs->program_len = program_size; |
memcpy(ifs->program, |
p->program, |
program_size * sizeof(uint)); |
} |
} |
/* Release the compilation struct: |
*/ |
FREE(p); |
} |
/** |
* Rather than trying to intercept and jiggle depth writes during |
* emit, just move the value into its correct position at the end of |
* the program: |
*/ |
static void |
i915_fixup_depth_write(struct i915_fp_compile *p) |
{ |
/* XXX assuming pos/depth is always in output[0] */ |
if (p->shader->info.output_semantic_name[0] == TGSI_SEMANTIC_POSITION) { |
const uint depth = UREG(REG_TYPE_OD, 0); |
i915_emit_arith(p, |
A0_MOV, /* opcode */ |
depth, /* dest reg */ |
A0_DEST_CHANNEL_W, /* write mask */ |
0, /* saturate? */ |
swizzle(depth, X, Y, Z, Z), /* src0 */ |
0, 0 /* src1, src2 */); |
} |
} |
void |
i915_translate_fragment_program( struct i915_context *i915, |
struct i915_fragment_shader *fs) |
{ |
struct i915_fp_compile *p; |
const struct tgsi_token *tokens = fs->state.tokens; |
struct i915_token_list* i_tokens; |
#if 0 |
tgsi_dump(tokens, 0); |
#endif |
/* hw doesn't seem to like empty frag programs, even when the depth write |
* fixup gets emitted below - may that one is fishy, too? */ |
if (fs->info.num_instructions == 1) { |
i915_use_passthrough_shader(fs); |
return; |
} |
p = i915_init_compile(i915, fs); |
i_tokens = i915_optimize(tokens); |
i915_translate_instructions(p, i_tokens, fs); |
i915_fixup_depth_write(p); |
i915_fini_compile(i915, p); |
i915_optimize_free(i_tokens); |
#if 0 |
i915_disassemble_program(NULL, fs->program, fs->program_len); |
#endif |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_prim_emit.c |
---|
0,0 → 1,225 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "draw/draw_pipe.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_pack_color.h" |
#include "i915_context.h" |
#include "i915_reg.h" |
#include "i915_state.h" |
#include "i915_batch.h" |
/** |
* Primitive emit to hardware. No support for vertex buffers or any |
* nice fast paths. |
*/ |
struct setup_stage { |
struct draw_stage stage; /**< This must be first (base class) */ |
struct i915_context *i915; |
}; |
/** |
* Basically a cast wrapper. |
*/ |
static INLINE struct setup_stage *setup_stage( struct draw_stage *stage ) |
{ |
return (struct setup_stage *)stage; |
} |
/** |
* Extract the needed fields from vertex_header and emit i915 dwords. |
* Recall that the vertices are constructed by the 'draw' module and |
* have a couple of slots at the beginning (1-dword header, 4-dword |
* clip pos) that we ignore here. |
*/ |
static INLINE void |
emit_hw_vertex( struct i915_context *i915, |
const struct vertex_header *vertex) |
{ |
const struct vertex_info *vinfo = &i915->current.vertex_info; |
uint i; |
uint count = 0; /* for debug/sanity */ |
assert(!i915->dirty); |
for (i = 0; i < vinfo->num_attribs; i++) { |
const uint j = vinfo->attrib[i].src_index; |
const float *attrib = vertex->data[j]; |
switch (vinfo->attrib[i].emit) { |
case EMIT_1F: |
OUT_BATCH( fui(attrib[0]) ); |
count++; |
break; |
case EMIT_2F: |
OUT_BATCH( fui(attrib[0]) ); |
OUT_BATCH( fui(attrib[1]) ); |
count += 2; |
break; |
case EMIT_3F: |
OUT_BATCH( fui(attrib[0]) ); |
OUT_BATCH( fui(attrib[1]) ); |
OUT_BATCH( fui(attrib[2]) ); |
count += 3; |
break; |
case EMIT_4F: |
OUT_BATCH( fui(attrib[0]) ); |
OUT_BATCH( fui(attrib[1]) ); |
OUT_BATCH( fui(attrib[2]) ); |
OUT_BATCH( fui(attrib[3]) ); |
count += 4; |
break; |
case EMIT_4UB: |
OUT_BATCH( pack_ub4(float_to_ubyte( attrib[0] ), |
float_to_ubyte( attrib[1] ), |
float_to_ubyte( attrib[2] ), |
float_to_ubyte( attrib[3] )) ); |
count += 1; |
break; |
case EMIT_4UB_BGRA: |
OUT_BATCH( pack_ub4(float_to_ubyte( attrib[2] ), |
float_to_ubyte( attrib[1] ), |
float_to_ubyte( attrib[0] ), |
float_to_ubyte( attrib[3] )) ); |
count += 1; |
break; |
default: |
assert(0); |
} |
} |
assert(count == vinfo->size); |
} |
static INLINE void |
emit_prim( struct draw_stage *stage, |
struct prim_header *prim, |
unsigned hwprim, |
unsigned nr ) |
{ |
struct i915_context *i915 = setup_stage(stage)->i915; |
unsigned vertex_size; |
unsigned i; |
if (i915->dirty) |
i915_update_derived( i915 ); |
if (i915->hardware_dirty) |
i915_emit_hardware_state( i915 ); |
/* need to do this after validation! */ |
vertex_size = i915->current.vertex_info.size * 4; /* in bytes */ |
assert(vertex_size >= 12); /* never smaller than 12 bytes */ |
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state( i915 ); |
if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) { |
assert(0); |
return; |
} |
} |
/* Emit each triangle as a single primitive. I told you this was |
* simple. |
*/ |
OUT_BATCH(_3DPRIMITIVE | |
hwprim | |
((4 + vertex_size * nr)/4 - 2)); |
for (i = 0; i < nr; i++) |
emit_hw_vertex(i915, prim->v[i]); |
} |
static void |
setup_tri( struct draw_stage *stage, struct prim_header *prim ) |
{ |
emit_prim( stage, prim, PRIM3D_TRILIST, 3 ); |
} |
static void |
setup_line(struct draw_stage *stage, struct prim_header *prim) |
{ |
emit_prim( stage, prim, PRIM3D_LINELIST, 2 ); |
} |
static void |
setup_point(struct draw_stage *stage, struct prim_header *prim) |
{ |
emit_prim( stage, prim, PRIM3D_POINTLIST, 1 ); |
} |
static void setup_flush( struct draw_stage *stage, unsigned flags ) |
{ |
} |
static void reset_stipple_counter( struct draw_stage *stage ) |
{ |
} |
static void render_destroy( struct draw_stage *stage ) |
{ |
FREE( stage ); |
} |
/** |
* Create a new primitive setup/render stage. This gets plugged into |
* the 'draw' module's pipeline. |
*/ |
struct draw_stage *i915_draw_render_stage( struct i915_context *i915 ) |
{ |
struct setup_stage *setup = CALLOC_STRUCT(setup_stage); |
setup->i915 = i915; |
setup->stage.draw = i915->draw; |
setup->stage.point = setup_point; |
setup->stage.line = setup_line; |
setup->stage.tri = setup_tri; |
setup->stage.flush = setup_flush; |
setup->stage.reset_stipple_counter = reset_stipple_counter; |
setup->stage.destroy = render_destroy; |
return &setup->stage; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_prim_vbuf.c |
---|
0,0 → 1,776 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/** |
* \file |
* Build post-transformation, post-clipping vertex buffers and element |
* lists by hooking into the end of the primitive pipeline and |
* manipulating the vertex_id field in the vertex headers. |
* |
* XXX: work in progress |
* |
* \author José Fonseca <jfonseca@vmware.com> |
* \author Keith Whitwell <keithw@vmware.com> |
*/ |
#include "draw/draw_context.h" |
#include "draw/draw_vbuf.h" |
#include "util/u_debug.h" |
#include "util/u_inlines.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_fifo.h" |
#include "i915_context.h" |
#include "i915_reg.h" |
#include "i915_batch.h" |
#include "i915_state.h" |
#define VBUF_MAP_BUFFER |
/** |
* Primitive renderer for i915. |
*/ |
struct i915_vbuf_render { |
struct vbuf_render base; |
struct i915_context *i915; |
/** Vertex size in bytes */ |
size_t vertex_size; |
/** Software primitive */ |
unsigned prim; |
/** Hardware primitive */ |
unsigned hwprim; |
/** Genereate a vertex list */ |
unsigned fallback; |
/* Stuff for the vbo */ |
struct i915_winsys_buffer *vbo; |
size_t vbo_size; /**< current size of allocated buffer */ |
size_t vbo_alloc_size; /**< minimum buffer size to allocate */ |
size_t vbo_hw_offset; /**< offset that we program the hardware with */ |
size_t vbo_sw_offset; /**< offset that we work with */ |
size_t vbo_index; /**< index offset to be added to all indices */ |
void *vbo_ptr; |
size_t vbo_max_used; |
size_t vbo_max_index; /**< index offset to be added to all indices */ |
#ifndef VBUF_MAP_BUFFER |
size_t map_used_start; |
size_t map_used_end; |
size_t map_size; |
#endif |
}; |
/** |
* Basically a cast wrapper. |
*/ |
static INLINE struct i915_vbuf_render * |
i915_vbuf_render(struct vbuf_render *render) |
{ |
assert(render); |
return (struct i915_vbuf_render *)render; |
} |
/** |
* If vbo state differs between renderer and context |
* push state to the context. This function pushes |
* hw_offset to i915->vbo_offset and vbo to i915->vbo. |
* |
* Side effects: |
* May updates context vbo_offset and vbo fields. |
*/ |
static void |
i915_vbuf_update_vbo_state(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
if (i915->vbo != i915_render->vbo || |
i915->vbo_offset != i915_render->vbo_hw_offset) { |
i915->vbo = i915_render->vbo; |
i915->vbo_offset = i915_render->vbo_hw_offset; |
i915->dirty |= I915_NEW_VBO; |
} |
} |
/** |
* Callback exported to the draw module. |
* Returns the current vertex_info. |
* |
* Side effects: |
* If state is dirty update derived state. |
*/ |
static const struct vertex_info * |
i915_vbuf_render_get_vertex_info(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
if (i915->dirty) { |
/* make sure we have up to date vertex layout */ |
i915_update_derived(i915); |
} |
return &i915->current.vertex_info; |
} |
/** |
* Reserve space in the vbo for vertices. |
* |
* Side effects: |
* None. |
*/ |
static boolean |
i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size) |
{ |
struct i915_context *i915 = i915_render->i915; |
if (i915_render->vbo_size < size + i915_render->vbo_sw_offset) |
return FALSE; |
if (i915->vbo_flushed) |
return FALSE; |
return TRUE; |
} |
/** |
* Allocate a new vbo buffer should there not be enough space for |
* the requested number of vertices by the draw module. |
* |
* Side effects: |
* Updates hw_offset, sw_offset, index and allocates a new buffer. |
* Will set i915->vbo to null on buffer allocation. |
*/ |
static void |
i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size) |
{ |
struct i915_context *i915 = i915_render->i915; |
struct i915_winsys *iws = i915->iws; |
if (i915_render->vbo) { |
iws->buffer_unmap(iws, i915_render->vbo); |
iws->buffer_destroy(iws, i915_render->vbo); |
/* |
* XXX If buffers where referenced then this should be done in |
* update_vbo_state but since they arn't and malloc likes to reuse |
* memory we need to set it to null |
*/ |
i915->vbo = NULL; |
i915_render->vbo = NULL; |
} |
i915->vbo_flushed = 0; |
i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size); |
i915_render->vbo_hw_offset = 0; |
i915_render->vbo_sw_offset = 0; |
i915_render->vbo_index = 0; |
#ifndef VBUF_MAP_BUFFER |
if (i915_render->vbo_size > i915_render->map_size) { |
i915_render->map_size = i915_render->vbo_size; |
FREE(i915_render->vbo_ptr); |
i915_render->vbo_ptr = MALLOC(i915_render->map_size); |
} |
#endif |
i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, |
I915_NEW_VERTEX); |
i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE); |
} |
/** |
* Callback exported to the draw module. |
* |
* Side effects: |
* Updates hw_offset, sw_offset, index and may allocate |
* a new buffer. Also updates may update the vbo state |
* on the i915 context. |
*/ |
static boolean |
i915_vbuf_render_allocate_vertices(struct vbuf_render *render, |
ushort vertex_size, |
ushort nr_vertices) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
size_t size = (size_t)vertex_size * (size_t)nr_vertices; |
size_t offset; |
/* |
* Align sw_offset with first multiple of vertex size from hw_offset. |
* Set index to be the multiples from from hw_offset to sw_offset. |
* i915_vbuf_render_new_buf will reset index, sw_offset, hw_offset |
* when it allocates a new buffer this is correct. |
*/ |
{ |
offset = i915_render->vbo_sw_offset - i915_render->vbo_hw_offset; |
offset = util_align_npot(offset, vertex_size); |
i915_render->vbo_sw_offset = i915_render->vbo_hw_offset + offset; |
i915_render->vbo_index = offset / vertex_size; |
} |
if (!i915_vbuf_render_reserve(i915_render, size)) |
i915_vbuf_render_new_buf(i915_render, size); |
/* |
* If a new buffer has been alocated sw_offset, |
* hw_offset & index will be reset by new_buf |
*/ |
i915_render->vertex_size = vertex_size; |
i915_vbuf_update_vbo_state(render); |
if (!i915_render->vbo) |
return FALSE; |
return TRUE; |
} |
static void * |
i915_vbuf_render_map_vertices(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
if (i915->vbo_flushed) |
debug_printf("%s bad vbo flush occurred stalling on hw\n", __FUNCTION__); |
#ifdef VBUF_MAP_BUFFER |
return (unsigned char *)i915_render->vbo_ptr + i915_render->vbo_sw_offset; |
#else |
return (unsigned char *)i915_render->vbo_ptr; |
#endif |
} |
static void |
i915_vbuf_render_unmap_vertices(struct vbuf_render *render, |
ushort min_index, |
ushort max_index) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
struct i915_winsys *iws = i915->iws; |
i915_render->vbo_max_index = max_index; |
i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1)); |
#ifdef VBUF_MAP_BUFFER |
(void)iws; |
#else |
i915_render->map_used_start = i915_render->vertex_size * min_index; |
i915_render->map_used_end = i915_render->vertex_size * (max_index + 1); |
iws->buffer_write(iws, i915_render->vbo, |
i915_render->map_used_start + i915_render->vbo_sw_offset, |
i915_render->map_used_end - i915_render->map_used_start, |
(unsigned char *)i915_render->vbo_ptr + i915_render->map_used_start); |
#endif |
} |
/** |
* Ensure that the given max_index given is not larger ushort max. |
* If it is larger then ushort max it advanced the hw_offset to the |
* same position in the vbo as sw_offset and set index to zero. |
* |
* Side effects: |
* On failure update hw_offset and index. |
*/ |
static void |
i915_vbuf_ensure_index_bounds(struct vbuf_render *render, |
unsigned max_index) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
if (max_index + i915_render->vbo_index < ((1 << 17) - 1)) |
return; |
i915_render->vbo_hw_offset = i915_render->vbo_sw_offset; |
i915_render->vbo_index = 0; |
i915_vbuf_update_vbo_state(render); |
} |
static void |
i915_vbuf_render_set_primitive(struct vbuf_render *render, |
unsigned prim) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
i915_render->prim = prim; |
switch(prim) { |
case PIPE_PRIM_POINTS: |
i915_render->hwprim = PRIM3D_POINTLIST; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_LINES: |
i915_render->hwprim = PRIM3D_LINELIST; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_LINE_LOOP: |
i915_render->hwprim = PRIM3D_LINELIST; |
i915_render->fallback = PIPE_PRIM_LINE_LOOP; |
break; |
case PIPE_PRIM_LINE_STRIP: |
i915_render->hwprim = PRIM3D_LINESTRIP; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_TRIANGLES: |
i915_render->hwprim = PRIM3D_TRILIST; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_TRIANGLE_STRIP: |
i915_render->hwprim = PRIM3D_TRISTRIP; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_TRIANGLE_FAN: |
i915_render->hwprim = PRIM3D_TRIFAN; |
i915_render->fallback = 0; |
break; |
case PIPE_PRIM_QUADS: |
i915_render->hwprim = PRIM3D_TRILIST; |
i915_render->fallback = PIPE_PRIM_QUADS; |
break; |
case PIPE_PRIM_QUAD_STRIP: |
i915_render->hwprim = PRIM3D_TRILIST; |
i915_render->fallback = PIPE_PRIM_QUAD_STRIP; |
break; |
case PIPE_PRIM_POLYGON: |
i915_render->hwprim = PRIM3D_POLY; |
i915_render->fallback = 0; |
break; |
default: |
/* FIXME: Actually, can handle a lot more just fine... */ |
assert(0 && "unexpected prim in i915_vbuf_render_set_primitive()"); |
} |
} |
/** |
* Used for fallbacks in draw_arrays |
*/ |
static void |
draw_arrays_generate_indices(struct vbuf_render *render, |
unsigned start, uint nr, |
unsigned type) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
unsigned i; |
unsigned end = start + nr + i915_render->vbo_index; |
start += i915_render->vbo_index; |
switch(type) { |
case 0: |
for (i = start; i+1 < end; i += 2) |
OUT_BATCH((i+0) | (i+1) << 16); |
if (i < end) |
OUT_BATCH(i); |
break; |
case PIPE_PRIM_LINE_LOOP: |
if (nr >= 2) { |
for (i = start + 1; i < end; i++) |
OUT_BATCH((i-1) | (i+0) << 16); |
OUT_BATCH((i-1) | ( start) << 16); |
} |
break; |
case PIPE_PRIM_QUADS: |
for (i = start; i + 3 < end; i += 4) { |
OUT_BATCH((i+0) | (i+1) << 16); |
OUT_BATCH((i+3) | (i+1) << 16); |
OUT_BATCH((i+2) | (i+3) << 16); |
} |
break; |
case PIPE_PRIM_QUAD_STRIP: |
for (i = start; i + 3 < end; i += 2) { |
OUT_BATCH((i+0) | (i+1) << 16); |
OUT_BATCH((i+3) | (i+2) << 16); |
OUT_BATCH((i+0) | (i+3) << 16); |
} |
break; |
default: |
assert(0); |
} |
} |
static unsigned |
draw_arrays_calc_nr_indices(uint nr, unsigned type) |
{ |
switch (type) { |
case 0: |
return nr; |
case PIPE_PRIM_LINE_LOOP: |
if (nr >= 2) |
return nr * 2; |
else |
return 0; |
case PIPE_PRIM_QUADS: |
return (nr / 4) * 6; |
case PIPE_PRIM_QUAD_STRIP: |
return ((nr - 2) / 2) * 6; |
default: |
assert(0); |
return 0; |
} |
} |
static void |
draw_arrays_fallback(struct vbuf_render *render, |
unsigned start, |
uint nr) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
unsigned nr_indices; |
nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback); |
if (!nr_indices) |
return; |
i915_vbuf_ensure_index_bounds(render, start + nr_indices); |
if (i915->dirty) |
i915_update_derived(i915); |
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
assert(0); |
goto out; |
} |
} |
OUT_BATCH(_3DPRIMITIVE | |
PRIM_INDIRECT | |
i915_render->hwprim | |
PRIM_INDIRECT_ELTS | |
nr_indices); |
draw_arrays_generate_indices(render, start, nr, i915_render->fallback); |
out: |
return; |
} |
static void |
i915_vbuf_render_draw_arrays(struct vbuf_render *render, |
unsigned start, |
uint nr) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
if (i915_render->fallback) { |
draw_arrays_fallback(render, start, nr); |
return; |
} |
i915_vbuf_ensure_index_bounds(render, start + nr); |
start += i915_render->vbo_index; |
if (i915->dirty) |
i915_update_derived(i915); |
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
if (!BEGIN_BATCH(2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
if (!BEGIN_BATCH(2)) { |
assert(0); |
goto out; |
} |
} |
OUT_BATCH(_3DPRIMITIVE | |
PRIM_INDIRECT | |
PRIM_INDIRECT_SEQUENTIAL | |
i915_render->hwprim | |
nr); |
OUT_BATCH(start); /* Beginning vertex index */ |
out: |
return; |
} |
/** |
* Used for normal and fallback emitting of indices |
* If type is zero normal operation assumed. |
*/ |
static void |
draw_generate_indices(struct vbuf_render *render, |
const ushort *indices, |
uint nr_indices, |
unsigned type) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
unsigned i; |
unsigned o = i915_render->vbo_index; |
switch(type) { |
case 0: |
for (i = 0; i + 1 < nr_indices; i += 2) { |
OUT_BATCH((o+indices[i]) | (o+indices[i+1]) << 16); |
} |
if (i < nr_indices) { |
OUT_BATCH((o+indices[i])); |
} |
break; |
case PIPE_PRIM_LINE_LOOP: |
if (nr_indices >= 2) { |
for (i = 1; i < nr_indices; i++) |
OUT_BATCH((o+indices[i-1]) | (o+indices[i]) << 16); |
OUT_BATCH((o+indices[i-1]) | (o+indices[0]) << 16); |
} |
break; |
case PIPE_PRIM_QUADS: |
for (i = 0; i + 3 < nr_indices; i += 4) { |
OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16); |
OUT_BATCH((o+indices[i+3]) | (o+indices[i+1]) << 16); |
OUT_BATCH((o+indices[i+2]) | (o+indices[i+3]) << 16); |
} |
break; |
case PIPE_PRIM_QUAD_STRIP: |
for (i = 0; i + 3 < nr_indices; i += 2) { |
OUT_BATCH((o+indices[i+0]) | (o+indices[i+1]) << 16); |
OUT_BATCH((o+indices[i+3]) | (o+indices[i+2]) << 16); |
OUT_BATCH((o+indices[i+0]) | (o+indices[i+3]) << 16); |
} |
break; |
default: |
assert(0); |
break; |
} |
} |
static unsigned |
draw_calc_nr_indices(uint nr_indices, unsigned type) |
{ |
switch (type) { |
case 0: |
return nr_indices; |
case PIPE_PRIM_LINE_LOOP: |
if (nr_indices >= 2) |
return nr_indices * 2; |
else |
return 0; |
case PIPE_PRIM_QUADS: |
return (nr_indices / 4) * 6; |
case PIPE_PRIM_QUAD_STRIP: |
return ((nr_indices - 2) / 2) * 6; |
default: |
assert(0); |
return 0; |
} |
} |
static void |
i915_vbuf_render_draw_elements(struct vbuf_render *render, |
const ushort *indices, |
uint nr_indices) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
unsigned save_nr_indices; |
save_nr_indices = nr_indices; |
nr_indices = draw_calc_nr_indices(nr_indices, i915_render->fallback); |
if (!nr_indices) |
return; |
i915_vbuf_ensure_index_bounds(render, i915_render->vbo_max_index); |
if (i915->dirty) |
i915_update_derived(i915); |
if (i915->hardware_dirty) |
i915_emit_hardware_state(i915); |
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
/* Make sure state is re-emitted after a flush: |
*/ |
i915_emit_hardware_state(i915); |
i915->vbo_flushed = 1; |
if (!BEGIN_BATCH(1 + (nr_indices + 1)/2)) { |
assert(0); |
goto out; |
} |
} |
OUT_BATCH(_3DPRIMITIVE | |
PRIM_INDIRECT | |
i915_render->hwprim | |
PRIM_INDIRECT_ELTS | |
nr_indices); |
draw_generate_indices(render, |
indices, |
save_nr_indices, |
i915_render->fallback); |
out: |
return; |
} |
static void |
i915_vbuf_render_release_vertices(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
i915_render->vbo_sw_offset += i915_render->vbo_max_used; |
i915_render->vbo_max_used = 0; |
/* |
* Micro optimization, by calling update here we the offset change |
* will be picked up on the next pipe_context::draw_*. |
*/ |
i915_vbuf_update_vbo_state(render); |
} |
static void |
i915_vbuf_render_destroy(struct vbuf_render *render) |
{ |
struct i915_vbuf_render *i915_render = i915_vbuf_render(render); |
struct i915_context *i915 = i915_render->i915; |
struct i915_winsys *iws = i915->iws; |
if (i915_render->vbo) { |
i915->vbo = NULL; |
iws->buffer_unmap(iws, i915_render->vbo); |
iws->buffer_destroy(iws, i915_render->vbo); |
} |
FREE(i915_render); |
} |
/** |
* Create a new primitive render. |
*/ |
static struct vbuf_render * |
i915_vbuf_render_create(struct i915_context *i915) |
{ |
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render); |
struct i915_winsys *iws = i915->iws; |
int i; |
i915_render->i915 = i915; |
i915_render->base.max_vertex_buffer_bytes = 4*4096; |
/* NOTE: it must be such that state and vertices indices fit in a single |
* batch buffer. 4096 is one batch buffer and 430 is the max amount of |
* state in dwords. The result is the number of 16-bit indices which can |
* fit in a single batch buffer. |
*/ |
i915_render->base.max_indices = (4096 - 430 * 4) / 2; |
i915_render->base.get_vertex_info = i915_vbuf_render_get_vertex_info; |
i915_render->base.allocate_vertices = i915_vbuf_render_allocate_vertices; |
i915_render->base.map_vertices = i915_vbuf_render_map_vertices; |
i915_render->base.unmap_vertices = i915_vbuf_render_unmap_vertices; |
i915_render->base.set_primitive = i915_vbuf_render_set_primitive; |
i915_render->base.draw_elements = i915_vbuf_render_draw_elements; |
i915_render->base.draw_arrays = i915_vbuf_render_draw_arrays; |
i915_render->base.release_vertices = i915_vbuf_render_release_vertices; |
i915_render->base.destroy = i915_vbuf_render_destroy; |
#ifndef VBUF_MAP_BUFFER |
i915_render->map_size = 0; |
i915_render->map_used_start = 0; |
i915_render->map_used_end = 0; |
#endif |
i915_render->vbo = NULL; |
i915_render->vbo_ptr = NULL; |
i915_render->vbo_size = 0; |
i915_render->vbo_hw_offset = 0; |
i915_render->vbo_sw_offset = 0; |
i915_render->vbo_alloc_size = i915_render->base.max_vertex_buffer_bytes * 4; |
#ifdef VBUF_USE_POOL |
i915_render->pool_used = FALSE; |
i915_render->pool_buffer_size = i915_render->vbo_alloc_size; |
i915_render->pool_fifo = u_fifo_create(6); |
for (i = 0; i < 6; i++) |
u_fifo_add(i915_render->pool_fifo, |
iws->buffer_create(iws, i915_render->pool_buffer_size, |
I915_NEW_VERTEX)); |
#else |
(void)i; |
(void)iws; |
#endif |
return &i915_render->base; |
} |
/** |
* Create a new primitive vbuf/render stage. |
*/ |
struct draw_stage *i915_draw_vbuf_stage(struct i915_context *i915) |
{ |
struct vbuf_render *render; |
struct draw_stage *stage; |
render = i915_vbuf_render_create(i915); |
if(!render) |
return NULL; |
stage = draw_vbuf_stage(i915->draw, render); |
if(!stage) { |
render->destroy(render); |
return NULL; |
} |
/** TODO JB: this shouldn't be here */ |
draw_set_render(i915->draw, render); |
return stage; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_public.h |
---|
0,0 → 1,13 |
#ifndef I915_PUBLIC_H |
#define I915_PUBLIC_H |
struct i915_winsys; |
struct pipe_screen; |
/** |
* Create i915 pipe_screen. |
*/ |
struct pipe_screen * i915_screen_create(struct i915_winsys *iws); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_query.c |
---|
0,0 → 1,88 |
/************************************************************************** |
* |
* Copyright 2011 The Chromium OS authors. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL GOOGLE 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. |
* |
**************************************************************************/ |
/* Fake occlusion queries which return 0, it's better than crashing */ |
#include "pipe/p_compiler.h" |
#include "util/u_memory.h" |
#include "i915_context.h" |
#include "i915_query.h" |
struct i915_query |
{ |
unsigned query; |
}; |
static struct pipe_query *i915_create_query(struct pipe_context *ctx, |
unsigned query_type, |
unsigned index) |
{ |
struct i915_query *query = CALLOC_STRUCT( i915_query ); |
return (struct pipe_query *)query; |
} |
static void i915_destroy_query(struct pipe_context *ctx, |
struct pipe_query *query) |
{ |
FREE(query); |
} |
static boolean i915_begin_query(struct pipe_context *ctx, |
struct pipe_query *query) |
{ |
return true; |
} |
static void i915_end_query(struct pipe_context *ctx, struct pipe_query *query) |
{ |
} |
static boolean i915_get_query_result(struct pipe_context *ctx, |
struct pipe_query *query, |
boolean wait, |
union pipe_query_result *vresult) |
{ |
uint64_t *result = (uint64_t*)vresult; |
/* 2* viewport Max */ |
*result = 512*1024*1024; |
return TRUE; |
} |
void |
i915_init_query_functions(struct i915_context *i915) |
{ |
i915->base.create_query = i915_create_query; |
i915->base.destroy_query = i915_destroy_query; |
i915->base.begin_query = i915_begin_query; |
i915->base.end_query = i915_end_query; |
i915->base.get_query_result = i915_get_query_result; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_query.h |
---|
0,0 → 1,36 |
/************************************************************************** |
* |
* Copyright 2011 The Chromium OS authors. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL GOOGLE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_QUERY_H |
#define I915_QUERY_H |
struct i915_context; |
struct pipe_context; |
void i915_init_query_functions( struct i915_context *i915 ); |
#endif /* I915_QUERY_H */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_reg.h |
---|
0,0 → 1,991 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_REG_H |
#define I915_REG_H |
#define I915_SET_FIELD( var, mask, value ) (var &= ~(mask), var |= value) |
#define CMD_3D (0x3<<29) |
#define PRIM3D_INLINE (CMD_3D | (0x1f<<24)) |
#define PRIM3D_TRILIST (0x0<<18) |
#define PRIM3D_TRISTRIP (0x1<<18) |
#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) |
#define PRIM3D_TRIFAN (0x3<<18) |
#define PRIM3D_POLY (0x4<<18) |
#define PRIM3D_LINELIST (0x5<<18) |
#define PRIM3D_LINESTRIP (0x6<<18) |
#define PRIM3D_RECTLIST (0x7<<18) |
#define PRIM3D_POINTLIST (0x8<<18) |
#define PRIM3D_DIB (0x9<<18) |
#define PRIM3D_CLEAR_RECT (0xa<<18) |
#define PRIM3D_ZONE_INIT (0xd<<18) |
#define PRIM3D_MASK (0x1f<<18) |
/* p137 */ |
#define _3DSTATE_AA_CMD (CMD_3D | (0x06<<24)) |
#define AA_LINE_ECAAR_WIDTH_ENABLE (1<<16) |
#define AA_LINE_ECAAR_WIDTH_0_5 0 |
#define AA_LINE_ECAAR_WIDTH_1_0 (1<<14) |
#define AA_LINE_ECAAR_WIDTH_2_0 (2<<14) |
#define AA_LINE_ECAAR_WIDTH_4_0 (3<<14) |
#define AA_LINE_REGION_WIDTH_ENABLE (1<<8) |
#define AA_LINE_REGION_WIDTH_0_5 0 |
#define AA_LINE_REGION_WIDTH_1_0 (1<<6) |
#define AA_LINE_REGION_WIDTH_2_0 (2<<6) |
#define AA_LINE_REGION_WIDTH_4_0 (3<<6) |
/* 3DSTATE_BACKFACE_STENCIL_OPS, p138*/ |
#define _3DSTATE_BACKFACE_STENCIL_OPS (CMD_3D | (0x8<<24)) |
#define BFO_ENABLE_STENCIL_REF (1<<23) |
#define BFO_STENCIL_REF_SHIFT 15 |
#define BFO_STENCIL_REF_MASK (0xff<<15) |
#define BFO_ENABLE_STENCIL_FUNCS (1<<14) |
#define BFO_STENCIL_TEST_SHIFT 11 |
#define BFO_STENCIL_TEST_MASK (0x7<<11) |
#define BFO_STENCIL_FAIL_SHIFT 8 |
#define BFO_STENCIL_FAIL_MASK (0x7<<8) |
#define BFO_STENCIL_PASS_Z_FAIL_SHIFT 5 |
#define BFO_STENCIL_PASS_Z_FAIL_MASK (0x7<<5) |
#define BFO_STENCIL_PASS_Z_PASS_SHIFT 2 |
#define BFO_STENCIL_PASS_Z_PASS_MASK (0x7<<2) |
#define BFO_ENABLE_STENCIL_TWO_SIDE (1<<1) |
#define BFO_STENCIL_TWO_SIDE (1<<0) |
/* 3DSTATE_BACKFACE_STENCIL_MASKS, p140 */ |
#define _3DSTATE_BACKFACE_STENCIL_MASKS (CMD_3D | (0x9<<24)) |
#define BFM_ENABLE_STENCIL_TEST_MASK (1<<17) |
#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16) |
#define BFM_STENCIL_TEST_MASK_SHIFT 8 |
#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8) |
#define BFM_STENCIL_WRITE_MASK_SHIFT 0 |
#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0) |
/* 3DSTATE_BIN_CONTROL p141 */ |
/* p143 */ |
#define _3DSTATE_BUF_INFO_CMD (CMD_3D | (0x1d<<24) | (0x8e<<16) | 1) |
/* Dword 1 */ |
#define BUF_3D_ID_COLOR_BACK (0x3<<24) |
#define BUF_3D_ID_DEPTH (0x7<<24) |
#define BUF_3D_USE_FENCE (1<<23) |
#define BUF_3D_TILED_SURFACE (1<<22) |
#define BUF_3D_TILE_WALK_X 0 |
#define BUF_3D_TILE_WALK_Y (1<<21) |
#define BUF_3D_PITCH(x) (((x)/4)<<2) |
/* Dword 2 */ |
#define BUF_3D_ADDR(x) ((x) & ~0x3) |
/* 3DSTATE_CHROMA_KEY */ |
/* 3DSTATE_CLEAR_PARAMETERS, p150 */ |
#define _3DSTATE_CLEAR_PARAMETERS (CMD_3D | (0x1d<<24) | (0x9c<<16) | 5) |
/* Dword 1 */ |
#define CLEARPARAM_CLEAR_RECT (1 << 16) |
#define CLEARPARAM_ZONE_INIT (0 << 16) |
#define CLEARPARAM_WRITE_COLOR (1 << 2) |
#define CLEARPARAM_WRITE_DEPTH (1 << 1) |
#define CLEARPARAM_WRITE_STENCIL (1 << 0) |
/* 3DSTATE_CONSTANT_BLEND_COLOR, p153 */ |
#define _3DSTATE_CONST_BLEND_COLOR_CMD (CMD_3D | (0x1d<<24) | (0x88<<16)) |
/* 3DSTATE_COORD_SET_BINDINGS, p154 */ |
#define _3DSTATE_COORD_SET_BINDINGS (CMD_3D | (0x16<<24)) |
#define CSB_TCB(iunit, eunit) ((eunit)<<(iunit*3)) |
/* p156 */ |
#define _3DSTATE_DFLT_DIFFUSE_CMD (CMD_3D | (0x1d<<24) | (0x99<<16)) |
/* p157 */ |
#define _3DSTATE_DFLT_SPEC_CMD (CMD_3D | (0x1d<<24) | (0x9a<<16)) |
/* p158 */ |
#define _3DSTATE_DFLT_Z_CMD (CMD_3D | (0x1d<<24) | (0x98<<16)) |
/* 3DSTATE_DEPTH_OFFSET_SCALE, p159 */ |
#define _3DSTATE_DEPTH_OFFSET_SCALE (CMD_3D | (0x1d<<24) | (0x97<<16)) |
/* scale in dword 1 */ |
/* 3DSTATE_DEPTH_SUBRECT_DISABLE, p160 */ |
#define _3DSTATE_DEPTH_SUBRECT_DISABLE (CMD_3D | (0x1c<<24) | (0x11<<19) | 0x2) |
/* p161 */ |
#define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) |
/* Dword 1 */ |
#define CLASSIC_EARLY_DEPTH (1<<31) |
#define TEX_DEFAULT_COLOR_OGL (0<<30) |
#define TEX_DEFAULT_COLOR_D3D (1<<30) |
#define ZR_EARLY_DEPTH (1<<29) |
#define LOD_PRECLAMP_OGL (1<<28) |
#define LOD_PRECLAMP_D3D (0<<28) |
#define DITHER_FULL_ALWAYS (0<<26) |
#define DITHER_FULL_ON_FB_BLEND (1<<26) |
#define DITHER_CLAMPED_ALWAYS (2<<26) |
#define LINEAR_GAMMA_BLEND_32BPP (1<<25) |
#define DEBUG_DISABLE_ENH_DITHER (1<<24) |
#define DSTORG_HORT_BIAS(x) ((x)<<20) |
#define DSTORG_VERT_BIAS(x) ((x)<<16) |
#define COLOR_4_2_2_CHNL_WRT_ALL 0 |
#define COLOR_4_2_2_CHNL_WRT_Y (1<<12) |
#define COLOR_4_2_2_CHNL_WRT_CR (2<<12) |
#define COLOR_4_2_2_CHNL_WRT_CB (3<<12) |
#define COLOR_4_2_2_CHNL_WRT_CRCB (4<<12) |
#define COLOR_BUF_8BIT 0 |
#define COLOR_BUF_RGB555 (1<<8) |
#define COLOR_BUF_RGB565 (2<<8) |
#define COLOR_BUF_ARGB8888 (3<<8) |
#define COLOR_BUF_YCRCB_SWAP (4<<8) |
#define COLOR_BUF_YCRCB_NORMAL (5<<8) |
#define COLOR_BUF_YCRCB_SWAPUV (6<<8) |
#define COLOR_BUF_YCRCB_SWAPUVY (7<<8) |
#define COLOR_BUF_ARGB4444 (8<<8) |
#define COLOR_BUF_ARGB1555 (9<<8) |
#define COLOR_BUF_ARGB2101010 (10<<8) |
#define DEPTH_FRMT_16_FIXED 0 |
#define DEPTH_FRMT_16_FLOAT (1<<2) |
#define DEPTH_FRMT_24_FIXED_8_OTHER (2<<2) |
#define VERT_LINE_STRIDE_1 (1<<1) |
#define VERT_LINE_STRIDE_0 (0<<1) |
#define VERT_LINE_STRIDE_OFS_1 1 |
#define VERT_LINE_STRIDE_OFS_0 0 |
/* p166 */ |
#define _3DSTATE_DRAW_RECT_CMD (CMD_3D|(0x1d<<24)|(0x80<<16)|3) |
/* Dword 1 */ |
#define DRAW_RECT_DIS_DEPTH_OFS (1<<30) |
#define DRAW_DITHER_OFS_X(x) ((x)<<26) |
#define DRAW_DITHER_OFS_Y(x) ((x)<<24) |
/* Dword 2 */ |
#define DRAW_YMIN(x) ((x)<<16) |
#define DRAW_XMIN(x) (x) |
/* Dword 3 */ |
#define DRAW_YMAX(x) ((x)<<16) |
#define DRAW_XMAX(x) (x) |
/* Dword 4 */ |
#define DRAW_YORG(x) ((x)<<16) |
#define DRAW_XORG(x) (x) |
/* 3DSTATE_FILTER_COEFFICIENTS_4X4, p170 */ |
/* 3DSTATE_FILTER_COEFFICIENTS_6X5, p172 */ |
/* _3DSTATE_FOG_COLOR, p173 */ |
#define _3DSTATE_FOG_COLOR_CMD (CMD_3D|(0x15<<24)) |
#define FOG_COLOR_RED(x) ((x)<<16) |
#define FOG_COLOR_GREEN(x) ((x)<<8) |
#define FOG_COLOR_BLUE(x) (x) |
/* _3DSTATE_FOG_MODE, p174 */ |
#define _3DSTATE_FOG_MODE_CMD (CMD_3D|(0x1d<<24)|(0x89<<16)|2) |
/* Dword 1 */ |
#define FMC1_FOGFUNC_MODIFY_ENABLE (1<<31) |
#define FMC1_FOGFUNC_VERTEX (0<<28) |
#define FMC1_FOGFUNC_PIXEL_EXP (1<<28) |
#define FMC1_FOGFUNC_PIXEL_EXP2 (2<<28) |
#define FMC1_FOGFUNC_PIXEL_LINEAR (3<<28) |
#define FMC1_FOGFUNC_MASK (3<<28) |
#define FMC1_FOGINDEX_MODIFY_ENABLE (1<<27) |
#define FMC1_FOGINDEX_Z (0<<25) |
#define FMC1_FOGINDEX_W (1<<25) |
#define FMC1_C1_C2_MODIFY_ENABLE (1<<24) |
#define FMC1_DENSITY_MODIFY_ENABLE (1<<23) |
#define FMC1_C1_ONE (1<<13) |
#define FMC1_C1_MASK (0xffff<<4) |
/* Dword 2 */ |
#define FMC2_C2_ONE (1<<16) |
/* Dword 3 */ |
#define FMC3_D_ONE (1<<16) |
/* _3DSTATE_INDEPENDENT_ALPHA_BLEND, p177 */ |
#define _3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD (CMD_3D|(0x0b<<24)) |
#define IAB_MODIFY_ENABLE (1<<23) |
#define IAB_ENABLE (1<<22) |
#define IAB_MODIFY_FUNC (1<<21) |
#define IAB_FUNC_SHIFT 16 |
#define IAB_MODIFY_SRC_FACTOR (1<<11) |
#define IAB_SRC_FACTOR_SHIFT 6 |
#define IAB_SRC_FACTOR_MASK (BLENDFACT_MASK<<6) |
#define IAB_MODIFY_DST_FACTOR (1<<5) |
#define IAB_DST_FACTOR_SHIFT 0 |
#define IAB_DST_FACTOR_MASK (BLENDFACT_MASK<<0) |
#define BLENDFUNC_ADD 0x0 |
#define BLENDFUNC_SUBTRACT 0x1 |
#define BLENDFUNC_REVERSE_SUBTRACT 0x2 |
#define BLENDFUNC_MIN 0x3 |
#define BLENDFUNC_MAX 0x4 |
#define BLENDFUNC_MASK 0x7 |
/* 3DSTATE_LOAD_INDIRECT, p180 */ |
#define _3DSTATE_LOAD_INDIRECT (CMD_3D|(0x1d<<24)|(0x7<<16)) |
#define LI0_STATE_STATIC_INDIRECT (0x01<<8) |
#define LI0_STATE_DYNAMIC_INDIRECT (0x02<<8) |
#define LI0_STATE_SAMPLER (0x04<<8) |
#define LI0_STATE_MAP (0x08<<8) |
#define LI0_STATE_PROGRAM (0x10<<8) |
#define LI0_STATE_CONSTANTS (0x20<<8) |
#define SIS0_BUFFER_ADDRESS(x) ((x)&~0x3) |
#define SIS0_FORCE_LOAD (1<<1) |
#define SIS0_BUFFER_VALID (1<<0) |
#define SIS1_BUFFER_LENGTH(x) ((x)&0xff) |
#define DIS0_BUFFER_ADDRESS(x) ((x)&~0x3) |
#define DIS0_BUFFER_RESET (1<<1) |
#define DIS0_BUFFER_VALID (1<<0) |
#define SSB0_BUFFER_ADDRESS(x) ((x)&~0x3) |
#define SSB0_FORCE_LOAD (1<<1) |
#define SSB0_BUFFER_VALID (1<<0) |
#define SSB1_BUFFER_LENGTH(x) ((x)&0xff) |
#define MSB0_BUFFER_ADDRESS(x) ((x)&~0x3) |
#define MSB0_FORCE_LOAD (1<<1) |
#define MSB0_BUFFER_VALID (1<<0) |
#define MSB1_BUFFER_LENGTH(x) ((x)&0xff) |
#define PSP0_BUFFER_ADDRESS(x) ((x)&~0x3) |
#define PSP0_FORCE_LOAD (1<<1) |
#define PSP0_BUFFER_VALID (1<<0) |
#define PSP1_BUFFER_LENGTH(x) ((x)&0xff) |
#define PSC0_BUFFER_ADDRESS(x) ((x)&~0x3) |
#define PSC0_FORCE_LOAD (1<<1) |
#define PSC0_BUFFER_VALID (1<<0) |
#define PSC1_BUFFER_LENGTH(x) ((x)&0xff) |
/* _3DSTATE_RASTERIZATION_RULES */ |
#define _3DSTATE_RASTER_RULES_CMD (CMD_3D|(0x07<<24)) |
#define ENABLE_POINT_RASTER_RULE (1<<15) |
#define OGL_POINT_RASTER_RULE (1<<13) |
#define ENABLE_TEXKILL_3D_4D (1<<10) |
#define TEXKILL_3D (0<<9) |
#define TEXKILL_4D (1<<9) |
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8) |
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5) |
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6) |
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3) |
/* _3DSTATE_SCISSOR_ENABLE, p256 */ |
#define _3DSTATE_SCISSOR_ENABLE_CMD (CMD_3D|(0x1c<<24)|(0x10<<19)) |
#define ENABLE_SCISSOR_RECT ((1<<1) | 1) |
#define DISABLE_SCISSOR_RECT (1<<1) |
/* _3DSTATE_SCISSOR_RECTANGLE_0, p257 */ |
#define _3DSTATE_SCISSOR_RECT_0_CMD (CMD_3D|(0x1d<<24)|(0x81<<16)|1) |
/* Dword 1 */ |
#define SCISSOR_RECT_0_YMIN(x) ((x)<<16) |
#define SCISSOR_RECT_0_XMIN(x) (x) |
/* Dword 2 */ |
#define SCISSOR_RECT_0_YMAX(x) ((x)<<16) |
#define SCISSOR_RECT_0_XMAX(x) (x) |
/* p189 */ |
#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 ((0x3<<29)|(0x1d<<24)|(0x04<<16)) |
#define I1_LOAD_S(n) (1<<(4+n)) |
#define S0_VB_OFFSET_MASK 0xffffffc |
#define S0_AUTO_CACHE_INV_DISABLE (1<<0) |
#define S1_VERTEX_WIDTH_SHIFT 24 |
#define S1_VERTEX_WIDTH_MASK (0x3f<<24) |
#define S1_VERTEX_PITCH_SHIFT 16 |
#define S1_VERTEX_PITCH_MASK (0x3f<<16) |
#define TEXCOORDFMT_2D 0x0 |
#define TEXCOORDFMT_3D 0x1 |
#define TEXCOORDFMT_4D 0x2 |
#define TEXCOORDFMT_1D 0x3 |
#define TEXCOORDFMT_2D_16 0x4 |
#define TEXCOORDFMT_4D_16 0x5 |
#define TEXCOORDFMT_NOT_PRESENT 0xf |
#define S2_TEXCOORD_FMT0_MASK 0xf |
#define S2_TEXCOORD_FMT1_SHIFT 4 |
#define S2_TEXCOORD_FMT(unit, type) ((type)<<(unit*4)) |
#define S2_TEXCOORD_NONE (~0) |
/* S3 not interesting */ |
#define S4_POINT_WIDTH_SHIFT 23 |
#define S4_POINT_WIDTH_MASK (0x1ff<<23) |
#define S4_LINE_WIDTH_SHIFT 19 |
#define S4_LINE_WIDTH_ONE (0x2<<19) |
#define S4_LINE_WIDTH_MASK (0xf<<19) |
#define S4_FLATSHADE_ALPHA (1<<18) |
#define S4_FLATSHADE_FOG (1<<17) |
#define S4_FLATSHADE_SPECULAR (1<<16) |
#define S4_FLATSHADE_COLOR (1<<15) |
#define S4_CULLMODE_BOTH (0<<13) |
#define S4_CULLMODE_NONE (1<<13) |
#define S4_CULLMODE_CW (2<<13) |
#define S4_CULLMODE_CCW (3<<13) |
#define S4_CULLMODE_MASK (3<<13) |
#define S4_VFMT_POINT_WIDTH (1<<12) |
#define S4_VFMT_SPEC_FOG (1<<11) |
#define S4_VFMT_COLOR (1<<10) |
#define S4_VFMT_DEPTH_OFFSET (1<<9) |
#define S4_VFMT_XYZ (1<<6) |
#define S4_VFMT_XYZW (2<<6) |
#define S4_VFMT_XY (3<<6) |
#define S4_VFMT_XYW (4<<6) |
#define S4_VFMT_XYZW_MASK (7<<6) |
#define S4_FORCE_DEFAULT_DIFFUSE (1<<5) |
#define S4_FORCE_DEFAULT_SPECULAR (1<<4) |
#define S4_LOCAL_DEPTH_OFFSET_ENABLE (1<<3) |
#define S4_VFMT_FOG_PARAM (1<<2) |
#define S4_SPRITE_POINT_ENABLE (1<<1) |
#define S4_LINE_ANTIALIAS_ENABLE (1<<0) |
#define S4_VFMT_MASK (S4_VFMT_POINT_WIDTH | \ |
S4_VFMT_SPEC_FOG | \ |
S4_VFMT_COLOR | \ |
S4_VFMT_DEPTH_OFFSET | \ |
S4_VFMT_XYZW_MASK | \ |
S4_VFMT_FOG_PARAM) |
#define S5_WRITEDISABLE_ALPHA (1<<31) |
#define S5_WRITEDISABLE_RED (1<<30) |
#define S5_WRITEDISABLE_GREEN (1<<29) |
#define S5_WRITEDISABLE_BLUE (1<<28) |
#define S5_WRITEDISABLE_MASK (0xf<<28) |
#define S5_FORCE_DEFAULT_POINT_SIZE (1<<27) |
#define S5_LAST_PIXEL_ENABLE (1<<26) |
#define S5_GLOBAL_DEPTH_OFFSET_ENABLE (1<<25) |
#define S5_FOG_ENABLE (1<<24) |
#define S5_STENCIL_REF_SHIFT 16 |
#define S5_STENCIL_REF_MASK (0xff<<16) |
#define S5_STENCIL_TEST_FUNC_SHIFT 13 |
#define S5_STENCIL_TEST_FUNC_MASK (0x7<<13) |
#define S5_STENCIL_FAIL_SHIFT 10 |
#define S5_STENCIL_FAIL_MASK (0x7<<10) |
#define S5_STENCIL_PASS_Z_FAIL_SHIFT 7 |
#define S5_STENCIL_PASS_Z_FAIL_MASK (0x7<<7) |
#define S5_STENCIL_PASS_Z_PASS_SHIFT 4 |
#define S5_STENCIL_PASS_Z_PASS_MASK (0x7<<4) |
#define S5_STENCIL_WRITE_ENABLE (1<<3) |
#define S5_STENCIL_TEST_ENABLE (1<<2) |
#define S5_COLOR_DITHER_ENABLE (1<<1) |
#define S5_LOGICOP_ENABLE (1<<0) |
#define S6_ALPHA_TEST_ENABLE (1<<31) |
#define S6_ALPHA_TEST_FUNC_SHIFT 28 |
#define S6_ALPHA_TEST_FUNC_MASK (0x7<<28) |
#define S6_ALPHA_REF_SHIFT 20 |
#define S6_ALPHA_REF_MASK (0xff<<20) |
#define S6_DEPTH_TEST_ENABLE (1<<19) |
#define S6_DEPTH_TEST_FUNC_SHIFT 16 |
#define S6_DEPTH_TEST_FUNC_MASK (0x7<<16) |
#define S6_CBUF_BLEND_ENABLE (1<<15) |
#define S6_CBUF_BLEND_FUNC_SHIFT 12 |
#define S6_CBUF_BLEND_FUNC_MASK (0x7<<12) |
#define S6_CBUF_SRC_BLEND_FACT_SHIFT 8 |
#define S6_CBUF_SRC_BLEND_FACT_MASK (0xf<<8) |
#define S6_CBUF_DST_BLEND_FACT_SHIFT 4 |
#define S6_CBUF_DST_BLEND_FACT_MASK (0xf<<4) |
#define S6_DEPTH_WRITE_ENABLE (1<<3) |
#define S6_COLOR_WRITE_ENABLE (1<<2) |
#define S6_TRISTRIP_PV_SHIFT 0 |
#define S6_TRISTRIP_PV_MASK (0x3<<0) |
#define S7_DEPTH_OFFSET_CONST_MASK ~0 |
#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT) |
#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT) |
#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT) |
#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT) |
/* 3DSTATE_MAP_DEINTERLACER_PARAMETERS */ |
/* 3DSTATE_MAP_PALETTE_LOAD_32, p206 */ |
#define _3DSTATE_MAP_PALETTE_LOAD_32 (CMD_3D|(0x1d<<24)|(0x8f<<16)) |
/* subsequent dwords up to length (max 16) are ARGB8888 color values */ |
/* _3DSTATE_MODES_4, p218 */ |
#define _3DSTATE_MODES_4_CMD (CMD_3D|(0x0d<<24)) |
#define ENABLE_LOGIC_OP_FUNC (1<<23) |
#define LOGIC_OP_FUNC(x) ((x)<<18) |
#define LOGICOP_MASK (0xf<<18) |
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00)) |
#define ENABLE_STENCIL_TEST_MASK (1<<17) |
#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8) |
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff)) |
#define ENABLE_STENCIL_WRITE_MASK (1<<16) |
#define STENCIL_WRITE_MASK(x) ((x)&0xff) |
/* _3DSTATE_MODES_5, p220 */ |
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24)) |
#define PIPELINE_FLUSH_RENDER_CACHE (1<<18) |
#define PIPELINE_FLUSH_TEXTURE_CACHE (1<<16) |
/* p221 */ |
#define _3DSTATE_PIXEL_SHADER_CONSTANTS (CMD_3D|(0x1d<<24)|(0x6<<16)) |
#define PS1_REG(n) (1<<(n)) |
#define PS2_CONST_X(n) (n) |
#define PS3_CONST_Y(n) (n) |
#define PS4_CONST_Z(n) (n) |
#define PS5_CONST_W(n) (n) |
/* p222 */ |
#define I915_MAX_TEX_INDIRECT 4 |
#define I915_MAX_TEX_INSN 32 |
#define I915_MAX_ALU_INSN 64 |
#define I915_MAX_DECL_INSN 27 |
#define I915_MAX_TEMPORARY 16 |
/* Each instruction is 3 dwords long, though most don't require all |
* this space. Maximum of 123 instructions. Smaller maxes per insn |
* type. |
*/ |
#define _3DSTATE_PIXEL_SHADER_PROGRAM (CMD_3D|(0x1d<<24)|(0x5<<16)) |
#define REG_TYPE_R 0 /* temporary regs, no need to |
* dcl, must be written before |
* read -- Preserved between |
* phases. |
*/ |
#define REG_TYPE_T 1 /* Interpolated values, must be |
* dcl'ed before use. |
* |
* 0..7: texture coord, |
* 8: diffuse spec, |
* 9: specular color, |
* 10: fog parameter in w. |
*/ |
#define REG_TYPE_CONST 2 /* Restriction: only one const |
* can be referenced per |
* instruction, though it may be |
* selected for multiple inputs. |
* Constants not initialized |
* default to zero. |
*/ |
#define REG_TYPE_S 3 /* sampler */ |
#define REG_TYPE_OC 4 /* output color (rgba) */ |
#define REG_TYPE_OD 5 /* output depth (w), xyz are |
* temporaries. If not written, |
* interpolated depth is used? |
*/ |
#define REG_TYPE_U 6 /* unpreserved temporaries */ |
#define REG_TYPE_MASK 0x7 |
#define REG_NR_MASK 0xf |
/* REG_TYPE_T: |
*/ |
#define T_TEX0 0 |
#define T_TEX1 1 |
#define T_TEX2 2 |
#define T_TEX3 3 |
#define T_TEX4 4 |
#define T_TEX5 5 |
#define T_TEX6 6 |
#define T_TEX7 7 |
#define T_DIFFUSE 8 |
#define T_SPECULAR 9 |
#define T_FOG_W 10 /* interpolated fog is in W coord */ |
/* Arithmetic instructions */ |
/* .replicate_swizzle == selection and replication of a particular |
* scalar channel, ie., .xxxx, .yyyy, .zzzz or .wwww |
*/ |
#define A0_NOP (0x0<<24) /* no operation */ |
#define A0_ADD (0x1<<24) /* dst = src0 + src1 */ |
#define A0_MOV (0x2<<24) /* dst = src0 */ |
#define A0_MUL (0x3<<24) /* dst = src0 * src1 */ |
#define A0_MAD (0x4<<24) /* dst = src0 * src1 + src2 */ |
#define A0_DP2ADD (0x5<<24) /* dst.xyzw = src0.xy dot src1.xy + src2.replicate_swizzle */ |
#define A0_DP3 (0x6<<24) /* dst.xyzw = src0.xyz dot src1.xyz */ |
#define A0_DP4 (0x7<<24) /* dst.xyzw = src0.xyzw dot src1.xyzw */ |
#define A0_FRC (0x8<<24) /* dst = src0 - floor(src0) */ |
#define A0_RCP (0x9<<24) /* dst.xyzw = 1/(src0.replicate_swizzle) */ |
#define A0_RSQ (0xa<<24) /* dst.xyzw = 1/(sqrt(abs(src0.replicate_swizzle))) */ |
#define A0_EXP (0xb<<24) /* dst.xyzw = exp2(src0.replicate_swizzle) */ |
#define A0_LOG (0xc<<24) /* dst.xyzw = log2(abs(src0.replicate_swizzle)) */ |
#define A0_CMP (0xd<<24) /* dst = (src0 >= 0.0) ? src1 : src2 */ |
#define A0_MIN (0xe<<24) /* dst = (src0 < src1) ? src0 : src1 */ |
#define A0_MAX (0xf<<24) /* dst = (src0 >= src1) ? src0 : src1 */ |
#define A0_FLR (0x10<<24) /* dst = floor(src0) */ |
#define A0_MOD (0x11<<24) /* dst = src0 fmod 1.0 */ |
#define A0_TRC (0x12<<24) /* dst = int(src0) */ |
#define A0_SGE (0x13<<24) /* dst = src0 >= src1 ? 1.0 : 0.0 */ |
#define A0_SLT (0x14<<24) /* dst = src0 < src1 ? 1.0 : 0.0 */ |
#define A0_DEST_SATURATE (1<<22) |
#define A0_DEST_TYPE_SHIFT 19 |
/* Allow: R, OC, OD, U */ |
#define A0_DEST_NR_SHIFT 14 |
/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ |
#define A0_DEST_CHANNEL_X (1<<10) |
#define A0_DEST_CHANNEL_Y (2<<10) |
#define A0_DEST_CHANNEL_Z (4<<10) |
#define A0_DEST_CHANNEL_W (8<<10) |
#define A0_DEST_CHANNEL_ALL (0xf<<10) |
#define A0_DEST_CHANNEL_SHIFT 10 |
#define A0_SRC0_TYPE_SHIFT 7 |
#define A0_SRC0_NR_SHIFT 2 |
#define A0_DEST_CHANNEL_XY (A0_DEST_CHANNEL_X|A0_DEST_CHANNEL_Y) |
#define A0_DEST_CHANNEL_XYZ (A0_DEST_CHANNEL_XY|A0_DEST_CHANNEL_Z) |
#define SRC_X 0 |
#define SRC_Y 1 |
#define SRC_Z 2 |
#define SRC_W 3 |
#define SRC_ZERO 4 |
#define SRC_ONE 5 |
#define A1_SRC0_CHANNEL_X_NEGATE (1<<31) |
#define A1_SRC0_CHANNEL_X_SHIFT 28 |
#define A1_SRC0_CHANNEL_Y_NEGATE (1<<27) |
#define A1_SRC0_CHANNEL_Y_SHIFT 24 |
#define A1_SRC0_CHANNEL_Z_NEGATE (1<<23) |
#define A1_SRC0_CHANNEL_Z_SHIFT 20 |
#define A1_SRC0_CHANNEL_W_NEGATE (1<<19) |
#define A1_SRC0_CHANNEL_W_SHIFT 16 |
#define A1_SRC1_TYPE_SHIFT 13 |
#define A1_SRC1_NR_SHIFT 8 |
#define A1_SRC1_CHANNEL_X_NEGATE (1<<7) |
#define A1_SRC1_CHANNEL_X_SHIFT 4 |
#define A1_SRC1_CHANNEL_Y_NEGATE (1<<3) |
#define A1_SRC1_CHANNEL_Y_SHIFT 0 |
#define A2_SRC1_CHANNEL_Z_NEGATE (1<<31) |
#define A2_SRC1_CHANNEL_Z_SHIFT 28 |
#define A2_SRC1_CHANNEL_W_NEGATE (1<<27) |
#define A2_SRC1_CHANNEL_W_SHIFT 24 |
#define A2_SRC2_TYPE_SHIFT 21 |
#define A2_SRC2_NR_SHIFT 16 |
#define A2_SRC2_CHANNEL_X_NEGATE (1<<15) |
#define A2_SRC2_CHANNEL_X_SHIFT 12 |
#define A2_SRC2_CHANNEL_Y_NEGATE (1<<11) |
#define A2_SRC2_CHANNEL_Y_SHIFT 8 |
#define A2_SRC2_CHANNEL_Z_NEGATE (1<<7) |
#define A2_SRC2_CHANNEL_Z_SHIFT 4 |
#define A2_SRC2_CHANNEL_W_NEGATE (1<<3) |
#define A2_SRC2_CHANNEL_W_SHIFT 0 |
/* Texture instructions */ |
#define T0_TEXLD (0x15<<24) /* Sample texture using predeclared |
* sampler and address, and output |
* filtered texel data to destination |
* register */ |
#define T0_TEXLDP (0x16<<24) /* Same as texld but performs a |
* perspective divide of the texture |
* coordinate .xyz values by .w before |
* sampling. */ |
#define T0_TEXLDB (0x17<<24) /* Same as texld but biases the |
* computed LOD by w. Only S4.6 two's |
* comp is used. This implies that a |
* float to fixed conversion is |
* done. */ |
#define T0_TEXKILL (0x18<<24) /* Does not perform a sampling |
* operation. Simply kills the pixel |
* if any channel of the address |
* register is < 0.0. */ |
#define T0_DEST_TYPE_SHIFT 19 |
/* Allow: R, OC, OD, U */ |
/* Note: U (unpreserved) regs do not retain their values between |
* phases (cannot be used for feedback) |
* |
* Note: oC and OD registers can only be used as the destination of a |
* texture instruction once per phase (this is an implementation |
* restriction). |
*/ |
#define T0_DEST_NR_SHIFT 14 |
/* Allow R: 0..15, OC,OD: 0..0, U: 0..2 */ |
#define T0_SAMPLER_NR_SHIFT 0 /* This field ignored for TEXKILL */ |
#define T0_SAMPLER_NR_MASK (0xf<<0) |
#define T1_ADDRESS_REG_TYPE_SHIFT 24 /* Reg to use as texture coord */ |
/* Allow R, T, OC, OD -- R, OC, OD are 'dependent' reads, new program phase */ |
#define T1_ADDRESS_REG_NR_SHIFT 17 |
#define T2_MBZ 0 |
/* Declaration instructions */ |
#define D0_DCL (0x19<<24) /* Declare a t (interpolated attrib) |
* register or an s (sampler) |
* register. */ |
#define D0_SAMPLE_TYPE_SHIFT 22 |
#define D0_SAMPLE_TYPE_2D (0x0<<22) |
#define D0_SAMPLE_TYPE_CUBE (0x1<<22) |
#define D0_SAMPLE_TYPE_VOLUME (0x2<<22) |
#define D0_SAMPLE_TYPE_MASK (0x3<<22) |
#define D0_TYPE_SHIFT 19 |
/* Allow: T, S */ |
#define D0_NR_SHIFT 14 |
/* Allow T: 0..10, S: 0..15 */ |
#define D0_CHANNEL_X (1<<10) |
#define D0_CHANNEL_Y (2<<10) |
#define D0_CHANNEL_Z (4<<10) |
#define D0_CHANNEL_W (8<<10) |
#define D0_CHANNEL_ALL (0xf<<10) |
#define D0_CHANNEL_NONE (0<<10) |
#define D0_CHANNEL_XY (D0_CHANNEL_X|D0_CHANNEL_Y) |
#define D0_CHANNEL_XYZ (D0_CHANNEL_XY|D0_CHANNEL_Z) |
/* I915 Errata: Do not allow (xz), (xw), (xzw) combinations for diffuse |
* or specular declarations. |
* |
* For T dcls, only allow: (x), (xy), (xyz), (w), (xyzw) |
* |
* Must be zero for S (sampler) dcls |
*/ |
#define D1_MBZ 0 |
#define D2_MBZ 0 |
/* p207 */ |
#define _3DSTATE_MAP_STATE (CMD_3D|(0x1d<<24)|(0x0<<16)) |
#define MS1_MAPMASK_SHIFT 0 |
#define MS1_MAPMASK_MASK (0x8fff<<0) |
#define MS2_UNTRUSTED_SURFACE (1<<31) |
#define MS2_ADDRESS_MASK 0xfffffffc |
#define MS2_VERTICAL_LINE_STRIDE (1<<1) |
#define MS2_VERTICAL_OFFSET (1<<1) |
#define MS3_HEIGHT_SHIFT 21 |
#define MS3_WIDTH_SHIFT 10 |
#define MS3_PALETTE_SELECT (1<<9) |
#define MS3_MAPSURF_FORMAT_SHIFT 7 |
#define MS3_MAPSURF_FORMAT_MASK (0x7<<7) |
#define MAPSURF_8BIT (1<<7) |
#define MAPSURF_16BIT (2<<7) |
#define MAPSURF_32BIT (3<<7) |
#define MAPSURF_422 (5<<7) |
#define MAPSURF_COMPRESSED (6<<7) |
#define MAPSURF_4BIT_INDEXED (7<<7) |
#define MS3_MT_FORMAT_MASK (0x7 << 3) |
#define MS3_MT_FORMAT_SHIFT 3 |
#define MT_4BIT_P4 (7<<3) /* SURFACE_4BIT_INDEXED */ |
#define MT_8BIT_I8 (0<<3) /* SURFACE_8BIT */ |
#define MT_8BIT_L8 (1<<3) |
#define MT_8BIT_A4P4 (2<<3) |
#define MT_8BIT_P4A4 (3<<3) |
#define MT_8BIT_A8 (4<<3) |
#define MT_8BIT_MONO8 (5<<3) |
#define MT_16BIT_RGB565 (0<<3) /* SURFACE_16BIT */ |
#define MT_16BIT_ARGB1555 (1<<3) |
#define MT_16BIT_ARGB4444 (2<<3) |
#define MT_16BIT_AY88 (3<<3) |
#define MT_16BIT_88DVDU (5<<3) |
#define MT_16BIT_BUMP_655LDVDU (6<<3) |
#define MT_16BIT_I16 (7<<3) |
#define MT_16BIT_L16 (8<<3) |
#define MT_16BIT_A16 (9<<3) |
#define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ |
#define MT_32BIT_ABGR8888 (1<<3) |
#define MT_32BIT_XRGB8888 (2<<3) |
#define MT_32BIT_XBGR8888 (3<<3) |
#define MT_32BIT_QWVU8888 (4<<3) |
#define MT_32BIT_AXVU8888 (5<<3) |
#define MT_32BIT_LXVU8888 (6<<3) |
#define MT_32BIT_XLVU8888 (7<<3) |
#define MT_32BIT_ARGB2101010 (8<<3) |
#define MT_32BIT_ABGR2101010 (9<<3) |
#define MT_32BIT_AWVU2101010 (0xA<<3) |
#define MT_32BIT_GR1616 (0xB<<3) |
#define MT_32BIT_VU1616 (0xC<<3) |
#define MT_32BIT_xI824 (0xD<<3) |
#define MT_32BIT_xA824 (0xE<<3) |
#define MT_32BIT_xL824 (0xF<<3) |
#define MT_422_YCRCB_SWAPY (0<<3) /* SURFACE_422 */ |
#define MT_422_YCRCB_NORMAL (1<<3) |
#define MT_422_YCRCB_SWAPUV (2<<3) |
#define MT_422_YCRCB_SWAPUVY (3<<3) |
#define MT_COMPRESS_DXT1 (0<<3) /* SURFACE_COMPRESSED */ |
#define MT_COMPRESS_DXT2_3 (1<<3) |
#define MT_COMPRESS_DXT4_5 (2<<3) |
#define MT_COMPRESS_FXT1 (3<<3) |
#define MT_COMPRESS_DXT1_RGB (4<<3) |
#define MS3_USE_FENCE_REGS (1<<2) |
#define MS3_TILED_SURFACE (1<<1) |
#define MS3_TILE_WALK_Y (1<<0) |
#define MS4_PITCH_SHIFT 21 |
#define MS4_CUBE_FACE_ENA_NEGX (1<<20) |
#define MS4_CUBE_FACE_ENA_POSX (1<<19) |
#define MS4_CUBE_FACE_ENA_NEGY (1<<18) |
#define MS4_CUBE_FACE_ENA_POSY (1<<17) |
#define MS4_CUBE_FACE_ENA_NEGZ (1<<16) |
#define MS4_CUBE_FACE_ENA_POSZ (1<<15) |
#define MS4_CUBE_FACE_ENA_MASK (0x3f<<15) |
#define MS4_MAX_LOD_SHIFT 9 |
#define MS4_MAX_LOD_MASK (0x3f<<9) |
#define MS4_MIP_LAYOUT_LEGACY (0<<8) |
#define MS4_MIP_LAYOUT_BELOW_LPT (0<<8) |
#define MS4_MIP_LAYOUT_RIGHT_LPT (1<<8) |
#define MS4_VOLUME_DEPTH_SHIFT 0 |
#define MS4_VOLUME_DEPTH_MASK (0xff<<0) |
/* p244 */ |
#define _3DSTATE_SAMPLER_STATE (CMD_3D|(0x1d<<24)|(0x1<<16)) |
#define SS1_MAPMASK_SHIFT 0 |
#define SS1_MAPMASK_MASK (0x8fff<<0) |
#define SS2_REVERSE_GAMMA_ENABLE (1<<31) |
#define SS2_PACKED_TO_PLANAR_ENABLE (1<<30) |
#define SS2_COLORSPACE_CONVERSION (1<<29) |
#define SS2_CHROMAKEY_SHIFT 27 |
#define SS2_BASE_MIP_LEVEL_SHIFT 22 |
#define SS2_BASE_MIP_LEVEL_MASK (0x1f<<22) |
#define SS2_MIP_FILTER_SHIFT 20 |
#define SS2_MIP_FILTER_MASK (0x3<<20) |
#define MIPFILTER_NONE 0 |
#define MIPFILTER_NEAREST 1 |
#define MIPFILTER_LINEAR 3 |
#define SS2_MAG_FILTER_SHIFT 17 |
#define SS2_MAG_FILTER_MASK (0x7<<17) |
#define FILTER_NEAREST 0 |
#define FILTER_LINEAR 1 |
#define FILTER_ANISOTROPIC 2 |
#define FILTER_4X4_1 3 |
#define FILTER_4X4_2 4 |
#define FILTER_4X4_FLAT 5 |
#define FILTER_6X5_MONO 6 /* XXX - check */ |
#define SS2_MIN_FILTER_SHIFT 14 |
#define SS2_MIN_FILTER_MASK (0x7<<14) |
#define SS2_LOD_BIAS_SHIFT 5 |
#define SS2_LOD_BIAS_ONE (0x10<<5) |
#define SS2_LOD_BIAS_MASK (0x1ff<<5) |
/* Shadow requires: |
* MT_X8{I,L,A}24 or MT_{I,L,A}16 texture format |
* FILTER_4X4_x MIN and MAG filters |
*/ |
#define SS2_SHADOW_ENABLE (1<<4) |
#define SS2_MAX_ANISO_MASK (1<<3) |
#define SS2_MAX_ANISO_2 (0<<3) |
#define SS2_MAX_ANISO_4 (1<<3) |
#define SS2_SHADOW_FUNC_SHIFT 0 |
#define SS2_SHADOW_FUNC_MASK (0x7<<0) |
/* SS2_SHADOW_FUNC values: see COMPAREFUNC_* */ |
#define SS3_MIN_LOD_SHIFT 24 |
#define SS3_MIN_LOD_ONE (0x10<<24) |
#define SS3_MIN_LOD_MASK (0xff<<24) |
#define SS3_KILL_PIXEL_ENABLE (1<<17) |
#define SS3_TCX_ADDR_MODE_SHIFT 12 |
#define SS3_TCX_ADDR_MODE_MASK (0x7<<12) |
#define TEXCOORDMODE_WRAP 0 |
#define TEXCOORDMODE_MIRROR 1 |
#define TEXCOORDMODE_CLAMP_EDGE 2 |
#define TEXCOORDMODE_CUBE 3 |
#define TEXCOORDMODE_CLAMP_BORDER 4 |
#define TEXCOORDMODE_MIRROR_ONCE 5 |
#define SS3_TCY_ADDR_MODE_SHIFT 9 |
#define SS3_TCY_ADDR_MODE_MASK (0x7<<9) |
#define SS3_TCZ_ADDR_MODE_SHIFT 6 |
#define SS3_TCZ_ADDR_MODE_MASK (0x7<<6) |
#define SS3_NORMALIZED_COORDS (1<<5) |
#define SS3_TEXTUREMAP_INDEX_SHIFT 1 |
#define SS3_TEXTUREMAP_INDEX_MASK (0xf<<1) |
#define SS3_DEINTERLACER_ENABLE (1<<0) |
#define SS4_BORDER_COLOR_MASK (~0) |
/* 3DSTATE_SPAN_STIPPLE, p258 |
*/ |
#define _3DSTATE_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) |
#define ST1_ENABLE (1<<16) |
#define ST1_MASK (0xffff) |
#define _3DSTATE_DEFAULT_Z ((0x3<<29)|(0x1d<<24)|(0x98<<16)) |
#define _3DSTATE_DEFAULT_DIFFUSE ((0x3<<29)|(0x1d<<24)|(0x99<<16)) |
#define _3DSTATE_DEFAULT_SPECULAR ((0x3<<29)|(0x1d<<24)|(0x9a<<16)) |
#define MI_FLUSH ((0<<29)|(4<<23)) |
#define FLUSH_MAP_CACHE (1<<0) |
#define INHIBIT_FLUSH_RENDER_CACHE (1<<2) |
#define MI_NOOP 0 |
#define CMD_3D (0x3<<29) |
#define _3DPRIMITIVE ((0x3<<29)|(0x1f<<24)) |
#define PRIM_INDIRECT (1<<23) |
#define PRIM_INLINE (0<<23) |
#define PRIM_INDIRECT_SEQUENTIAL (0<<17) |
#define PRIM_INDIRECT_ELTS (1<<17) |
#define PRIM3D_TRILIST (0x0<<18) |
#define PRIM3D_TRISTRIP (0x1<<18) |
#define PRIM3D_TRISTRIP_RVRSE (0x2<<18) |
#define PRIM3D_TRIFAN (0x3<<18) |
#define PRIM3D_POLY (0x4<<18) |
#define PRIM3D_LINELIST (0x5<<18) |
#define PRIM3D_LINESTRIP (0x6<<18) |
#define PRIM3D_RECTLIST (0x7<<18) |
#define PRIM3D_POINTLIST (0x8<<18) |
#define PRIM3D_DIB (0x9<<18) |
#define PRIM3D_MASK (0x1f<<18) |
#define I915PACKCOLOR4444(r,g,b,a) \ |
((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) |
#define I915PACKCOLOR1555(r,g,b,a) \ |
((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ |
((a) ? 0x8000 : 0)) |
#define I915PACKCOLOR565(r,g,b) \ |
((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) |
#define I915PACKCOLOR8888(r,g,b,a) \ |
((a<<24) | (r<<16) | (g<<8) | b) |
#define BR00_BITBLT_CLIENT 0x40000000 |
#define BR00_OP_COLOR_BLT 0x10000000 |
#define BR00_OP_SRC_COPY_BLT 0x10C00000 |
#define BR13_SOLID_PATTERN 0x80000000 |
#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4) |
#define XY_COLOR_BLT_WRITE_ALPHA (1<<21) |
#define XY_COLOR_BLT_WRITE_RGB (1<<20) |
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) |
#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21) |
#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20) |
#define MI_WAIT_FOR_EVENT ((0x3<<23)) |
#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6) |
#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2) |
#define MI_BATCH_BUFFER (0x30<<23) |
#define MI_BATCH_BUFFER_START (0x31<<23) |
#define MI_BATCH_BUFFER_END (0xa<<23) |
#define COMPAREFUNC_ALWAYS 0 |
#define COMPAREFUNC_NEVER 0x1 |
#define COMPAREFUNC_LESS 0x2 |
#define COMPAREFUNC_EQUAL 0x3 |
#define COMPAREFUNC_LEQUAL 0x4 |
#define COMPAREFUNC_GREATER 0x5 |
#define COMPAREFUNC_NOTEQUAL 0x6 |
#define COMPAREFUNC_GEQUAL 0x7 |
#define STENCILOP_KEEP 0 |
#define STENCILOP_ZERO 0x1 |
#define STENCILOP_REPLACE 0x2 |
#define STENCILOP_INCRSAT 0x3 |
#define STENCILOP_DECRSAT 0x4 |
#define STENCILOP_INCR 0x5 |
#define STENCILOP_DECR 0x6 |
#define STENCILOP_INVERT 0x7 |
#define LOGICOP_CLEAR 0 |
#define LOGICOP_NOR 0x1 |
#define LOGICOP_AND_INV 0x2 |
#define LOGICOP_COPY_INV 0x3 |
#define LOGICOP_AND_RVRSE 0x4 |
#define LOGICOP_INV 0x5 |
#define LOGICOP_XOR 0x6 |
#define LOGICOP_NAND 0x7 |
#define LOGICOP_AND 0x8 |
#define LOGICOP_EQUIV 0x9 |
#define LOGICOP_NOOP 0xa |
#define LOGICOP_OR_INV 0xb |
#define LOGICOP_COPY 0xc |
#define LOGICOP_OR_RVRSE 0xd |
#define LOGICOP_OR 0xe |
#define LOGICOP_SET 0xf |
#define BLENDFACT_ZERO 0x01 |
#define BLENDFACT_ONE 0x02 |
#define BLENDFACT_SRC_COLR 0x03 |
#define BLENDFACT_INV_SRC_COLR 0x04 |
#define BLENDFACT_SRC_ALPHA 0x05 |
#define BLENDFACT_INV_SRC_ALPHA 0x06 |
#define BLENDFACT_DST_ALPHA 0x07 |
#define BLENDFACT_INV_DST_ALPHA 0x08 |
#define BLENDFACT_DST_COLR 0x09 |
#define BLENDFACT_INV_DST_COLR 0x0a |
#define BLENDFACT_SRC_ALPHA_SATURATE 0x0b |
#define BLENDFACT_CONST_COLOR 0x0c |
#define BLENDFACT_INV_CONST_COLOR 0x0d |
#define BLENDFACT_CONST_ALPHA 0x0e |
#define BLENDFACT_INV_CONST_ALPHA 0x0f |
#define BLENDFACT_MASK 0x0f |
#define PCI_CHIP_I915_G 0x2582 |
#define PCI_CHIP_I915_GM 0x2592 |
#define PCI_CHIP_I945_G 0x2772 |
#define PCI_CHIP_I945_GM 0x27A2 |
#define PCI_CHIP_I945_GME 0x27AE |
#define PCI_CHIP_G33_G 0x29C2 |
#define PCI_CHIP_Q35_G 0x29B2 |
#define PCI_CHIP_Q33_G 0x29D2 |
#define PCI_CHIP_PINEVIEW_G 0xA001 |
#define PCI_CHIP_PINEVIEW_M 0xA011 |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_resource.c |
---|
0,0 → 1,51 |
#include "util/u_debug.h" |
#include "i915_resource.h" |
#include "i915_context.h" |
#include "i915_screen.h" |
static struct pipe_resource * |
i915_resource_create(struct pipe_screen *screen, |
const struct pipe_resource *template) |
{ |
if (template->target == PIPE_BUFFER) |
return i915_buffer_create(screen, template); |
else |
{ |
if (!(template->bind & PIPE_BIND_LINEAR)) |
return i915_texture_create(screen, template, FALSE); |
else |
return i915_texture_create(screen, template, TRUE); |
} |
} |
static struct pipe_resource * |
i915_resource_from_handle(struct pipe_screen * screen, |
const struct pipe_resource *template, |
struct winsys_handle *whandle) |
{ |
if (template->target == PIPE_BUFFER) |
return NULL; |
else |
return i915_texture_from_handle(screen, template, whandle); |
} |
void |
i915_init_resource_functions(struct i915_context *i915 ) |
{ |
i915->base.transfer_map = u_transfer_map_vtbl; |
i915->base.transfer_flush_region = u_transfer_flush_region_vtbl; |
i915->base.transfer_unmap = u_transfer_unmap_vtbl; |
i915->base.transfer_inline_write = u_transfer_inline_write_vtbl; |
} |
void |
i915_init_screen_resource_functions(struct i915_screen *is) |
{ |
is->base.resource_create = i915_resource_create; |
is->base.resource_from_handle = i915_resource_from_handle; |
is->base.resource_get_handle = u_resource_get_handle_vtbl; |
is->base.resource_destroy = u_resource_destroy_vtbl; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_resource.h |
---|
0,0 → 1,132 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_RESOURCE_H |
#define I915_RESOURCE_H |
struct i915_screen; |
#include "util/u_transfer.h" |
#include "util/u_debug.h" |
#include "i915_winsys.h" |
struct i915_context; |
struct i915_screen; |
struct i915_buffer { |
struct u_resource b; |
uint8_t *data; |
boolean free_on_destroy; |
}; |
/* Texture transfer. */ |
struct i915_transfer { |
/* Base class. */ |
struct pipe_transfer b; |
struct pipe_resource *staging_texture; |
}; |
#define I915_MAX_TEXTURE_2D_LEVELS 12 /* max 2048x2048 */ |
#define I915_MAX_TEXTURE_3D_LEVELS 9 /* max 256x256x256 */ |
struct offset_pair { |
unsigned short nblocksx; |
unsigned short nblocksy; |
}; |
struct i915_texture { |
struct u_resource b; |
/* tiling flags */ |
enum i915_winsys_buffer_tile tiling; |
unsigned stride; |
unsigned depth_stride; /* per-image on i945? */ |
unsigned total_nblocksy; |
unsigned nr_images[I915_MAX_TEXTURE_2D_LEVELS]; |
/* Explicitly store the offset of each image for each cube face or |
* depth value. |
* |
* Array [depth] off offsets. |
*/ |
struct offset_pair *image_offset[I915_MAX_TEXTURE_2D_LEVELS]; |
/* The data is held here: |
*/ |
struct i915_winsys_buffer *buffer; |
}; |
unsigned i915_texture_offset(const struct i915_texture *tex, |
unsigned level, unsigned layer); |
void i915_init_screen_resource_functions(struct i915_screen *is); |
void i915_init_resource_functions(struct i915_context *i915); |
extern struct u_resource_vtbl i915_buffer_vtbl; |
extern struct u_resource_vtbl i915_texture_vtbl; |
static INLINE struct i915_texture *i915_texture(struct pipe_resource *resource) |
{ |
struct i915_texture *tex = (struct i915_texture *)resource; |
assert(tex->b.vtbl == &i915_texture_vtbl); |
return tex; |
} |
static INLINE struct i915_buffer *i915_buffer(struct pipe_resource *resource) |
{ |
struct i915_buffer *tex = (struct i915_buffer *)resource; |
assert(tex->b.vtbl == &i915_buffer_vtbl); |
return tex; |
} |
struct pipe_resource * |
i915_texture_create(struct pipe_screen *screen, |
const struct pipe_resource *template, |
boolean force_untiled); |
struct pipe_resource * |
i915_texture_from_handle(struct pipe_screen * screen, |
const struct pipe_resource *template, |
struct winsys_handle *whandle); |
struct pipe_resource * |
i915_user_buffer_create(struct pipe_screen *screen, |
void *ptr, |
unsigned bytes, |
unsigned usage); |
struct pipe_resource * |
i915_buffer_create(struct pipe_screen *screen, |
const struct pipe_resource *template); |
#endif /* I915_RESOURCE_H */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_resource_buffer.c |
---|
0,0 → 1,180 |
/************************************************************************** |
* |
* Copyright 2006 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* |
* Authors: |
* Keith Whitwell <keithw@vmware.com> |
* Michel Dänzer <daenzer@vmware.com> |
*/ |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "i915_context.h" |
#include "i915_resource.h" |
static boolean |
i915_buffer_get_handle(struct pipe_screen *screen, |
struct pipe_resource *resource, |
struct winsys_handle *handle) |
{ |
return FALSE; |
} |
static void |
i915_buffer_destroy(struct pipe_screen *screen, |
struct pipe_resource *resource) |
{ |
struct i915_buffer *buffer = i915_buffer(resource); |
if (buffer->free_on_destroy) |
align_free(buffer->data); |
FREE(buffer); |
} |
static void * |
i915_buffer_transfer_map(struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
struct pipe_transfer **ptransfer) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct i915_buffer *buffer = i915_buffer(resource); |
struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool); |
if (transfer == NULL) |
return NULL; |
transfer->resource = resource; |
transfer->level = level; |
transfer->usage = usage; |
transfer->box = *box; |
*ptransfer = transfer; |
return buffer->data + transfer->box.x; |
} |
static void |
i915_buffer_transfer_unmap(struct pipe_context *pipe, |
struct pipe_transfer *transfer) |
{ |
struct i915_context *i915 = i915_context(pipe); |
util_slab_free(&i915->transfer_pool, transfer); |
} |
static void |
i915_buffer_transfer_inline_write( struct pipe_context *rm_ctx, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride) |
{ |
struct i915_buffer *buffer = i915_buffer(resource); |
memcpy(buffer->data + box->x, |
data, |
box->width); |
} |
struct u_resource_vtbl i915_buffer_vtbl = |
{ |
i915_buffer_get_handle, /* get_handle */ |
i915_buffer_destroy, /* resource_destroy */ |
i915_buffer_transfer_map, /* transfer_map */ |
u_default_transfer_flush_region, /* transfer_flush_region */ |
i915_buffer_transfer_unmap, /* transfer_unmap */ |
i915_buffer_transfer_inline_write /* transfer_inline_write */ |
}; |
struct pipe_resource * |
i915_buffer_create(struct pipe_screen *screen, |
const struct pipe_resource *template) |
{ |
struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); |
if (!buf) |
return NULL; |
buf->b.b = *template; |
buf->b.vtbl = &i915_buffer_vtbl; |
pipe_reference_init(&buf->b.b.reference, 1); |
buf->b.b.screen = screen; |
buf->data = align_malloc(template->width0, 64); |
buf->free_on_destroy = TRUE; |
if (!buf->data) |
goto err; |
return &buf->b.b; |
err: |
FREE(buf); |
return NULL; |
} |
struct pipe_resource * |
i915_user_buffer_create(struct pipe_screen *screen, |
void *ptr, |
unsigned bytes, |
unsigned bind) |
{ |
struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer); |
if (!buf) |
return NULL; |
pipe_reference_init(&buf->b.b.reference, 1); |
buf->b.vtbl = &i915_buffer_vtbl; |
buf->b.b.screen = screen; |
buf->b.b.format = PIPE_FORMAT_R8_UNORM; /* ?? */ |
buf->b.b.usage = PIPE_USAGE_IMMUTABLE; |
buf->b.b.bind = bind; |
buf->b.b.flags = 0; |
buf->b.b.width0 = bytes; |
buf->b.b.height0 = 1; |
buf->b.b.depth0 = 1; |
buf->b.b.array_size = 1; |
buf->data = ptr; |
buf->free_on_destroy = FALSE; |
return &buf->b.b; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_resource_texture.c |
---|
0,0 → 1,1027 |
/************************************************************************** |
* |
* Copyright 2006 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* |
* Authors: |
* Keith Whitwell <keithw@vmware.com> |
* Michel Dänzer <daenzer@vmware.com> |
*/ |
#include "pipe/p_state.h" |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_format.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_rect.h" |
#include "i915_context.h" |
#include "i915_resource.h" |
#include "i915_screen.h" |
#include "i915_winsys.h" |
#include "i915_debug.h" |
#define DEBUG_TEXTURES 0 |
/* |
* Helper function and arrays |
*/ |
/** |
* Initial offset for Cube map. |
*/ |
static const int initial_offsets[6][2] = { |
[PIPE_TEX_FACE_POS_X] = {0, 0}, |
[PIPE_TEX_FACE_POS_Y] = {1, 0}, |
[PIPE_TEX_FACE_POS_Z] = {1, 1}, |
[PIPE_TEX_FACE_NEG_X] = {0, 2}, |
[PIPE_TEX_FACE_NEG_Y] = {1, 2}, |
[PIPE_TEX_FACE_NEG_Z] = {1, 3}, |
}; |
/** |
* Step offsets for Cube map. |
*/ |
static const int step_offsets[6][2] = { |
[PIPE_TEX_FACE_POS_X] = { 0, 2}, |
[PIPE_TEX_FACE_POS_Y] = {-1, 2}, |
[PIPE_TEX_FACE_POS_Z] = {-1, 1}, |
[PIPE_TEX_FACE_NEG_X] = { 0, 2}, |
[PIPE_TEX_FACE_NEG_Y] = {-1, 2}, |
[PIPE_TEX_FACE_NEG_Z] = {-1, 1}, |
}; |
/** |
* For compressed level 2 |
*/ |
static const int bottom_offsets[6] = { |
[PIPE_TEX_FACE_POS_X] = 16 + 0 * 8, |
[PIPE_TEX_FACE_POS_Y] = 16 + 1 * 8, |
[PIPE_TEX_FACE_POS_Z] = 16 + 2 * 8, |
[PIPE_TEX_FACE_NEG_X] = 16 + 3 * 8, |
[PIPE_TEX_FACE_NEG_Y] = 16 + 4 * 8, |
[PIPE_TEX_FACE_NEG_Z] = 16 + 5 * 8, |
}; |
static INLINE unsigned |
align_nblocksx(enum pipe_format format, unsigned width, unsigned align_to) |
{ |
return align(util_format_get_nblocksx(format, width), align_to); |
} |
static INLINE unsigned |
align_nblocksy(enum pipe_format format, unsigned width, unsigned align_to) |
{ |
return align(util_format_get_nblocksy(format, width), align_to); |
} |
static INLINE unsigned |
get_pot_stride(enum pipe_format format, unsigned width) |
{ |
return util_next_power_of_two(util_format_get_stride(format, width)); |
} |
static INLINE const char* |
get_tiling_string(enum i915_winsys_buffer_tile tile) |
{ |
switch(tile) { |
case I915_TILE_NONE: |
return "none"; |
case I915_TILE_X: |
return "x"; |
case I915_TILE_Y: |
return "y"; |
default: |
assert(FALSE); |
return "?"; |
} |
} |
/* |
* More advanced helper funcs |
*/ |
static void |
i915_texture_set_level_info(struct i915_texture *tex, |
unsigned level, unsigned nr_images) |
{ |
assert(level < Elements(tex->nr_images)); |
assert(nr_images); |
assert(!tex->image_offset[level]); |
tex->nr_images[level] = nr_images; |
tex->image_offset[level] = MALLOC(nr_images * sizeof(struct offset_pair)); |
tex->image_offset[level][0].nblocksx = 0; |
tex->image_offset[level][0].nblocksy = 0; |
} |
unsigned i915_texture_offset(const struct i915_texture *tex, |
unsigned level, unsigned layer) |
{ |
unsigned x, y; |
x = tex->image_offset[level][layer].nblocksx |
* util_format_get_blocksize(tex->b.b.format); |
y = tex->image_offset[level][layer].nblocksy; |
return y * tex->stride + x; |
} |
static void |
i915_texture_set_image_offset(struct i915_texture *tex, |
unsigned level, unsigned img, |
unsigned nblocksx, unsigned nblocksy) |
{ |
/* for the first image and level make sure offset is zero */ |
assert(!(img == 0 && level == 0) || (nblocksx == 0 && nblocksy == 0)); |
assert(img < tex->nr_images[level]); |
tex->image_offset[level][img].nblocksx = nblocksx; |
tex->image_offset[level][img].nblocksy = nblocksy; |
#if DEBUG_TEXTURES |
debug_printf("%s: %p level %u, img %u (%u, %u)\n", __FUNCTION__, |
tex, level, img, x, y); |
#endif |
} |
static enum i915_winsys_buffer_tile |
i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex) |
{ |
if (!is->debug.tiling) |
return I915_TILE_NONE; |
if (tex->b.b.target == PIPE_TEXTURE_1D) |
return I915_TILE_NONE; |
if (util_format_is_s3tc(tex->b.b.format)) |
return I915_TILE_X; |
if (is->debug.use_blitter) |
return I915_TILE_X; |
else |
return I915_TILE_Y; |
} |
/* |
* Shared layout functions |
*/ |
/** |
* Special case to deal with scanout textures. |
*/ |
static boolean |
i9x5_scanout_layout(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4) |
return FALSE; |
i915_texture_set_level_info(tex, 0, 1); |
i915_texture_set_image_offset(tex, 0, 0, 0, 0); |
if (pt->width0 >= 240) { |
tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64); |
tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8); |
tex->tiling = I915_TILE_X; |
/* special case for cursors */ |
} else if (pt->width0 == 64 && pt->height0 == 64) { |
tex->stride = get_pot_stride(pt->format, pt->width0); |
tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8); |
} else { |
return FALSE; |
} |
#if DEBUG_TEXTURE |
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, |
pt->width0, pt->height0, util_format_get_blocksize(pt->format), |
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); |
#endif |
return TRUE; |
} |
/** |
* Special case to deal with shared textures. |
*/ |
static boolean |
i9x5_display_target_layout(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
if (pt->last_level > 0 || util_format_get_blocksize(pt->format) != 4) |
return FALSE; |
/* fallback to normal textures for small textures */ |
if (pt->width0 < 240) |
return FALSE; |
i915_texture_set_level_info(tex, 0, 1); |
i915_texture_set_image_offset(tex, 0, 0, 0, 0); |
tex->stride = align(util_format_get_stride(pt->format, pt->width0), 64); |
tex->total_nblocksy = align_nblocksy(pt->format, pt->height0, 8); |
tex->tiling = I915_TILE_X; |
#if DEBUG_TEXTURE |
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__, |
pt->width0, pt->height0, util_format_get_blocksize(pt->format), |
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy); |
#endif |
return TRUE; |
} |
/** |
* Helper function for special layouts |
*/ |
static boolean |
i9x5_special_layout(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
/* Scanouts needs special care */ |
if (pt->bind & PIPE_BIND_SCANOUT) |
if (i9x5_scanout_layout(tex)) |
return TRUE; |
/* Shared buffers needs to be compatible with X servers |
* |
* XXX: need a better name than shared for this if it is to be part |
* of core gallium, and probably move the flag to resource.flags, |
* rather than bindings. |
*/ |
if (pt->bind & (PIPE_BIND_SHARED | PIPE_BIND_DISPLAY_TARGET)) |
if (i9x5_display_target_layout(tex)) |
return TRUE; |
return FALSE; |
} |
/** |
* Cube layout used on i915 and for non-compressed textures on i945. |
*/ |
static void |
i9x5_texture_layout_cube(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
unsigned width = util_next_power_of_two(pt->width0); |
const unsigned nblocks = util_format_get_nblocksx(pt->format, width); |
unsigned level; |
unsigned face; |
assert(pt->width0 == pt->height0); /* cubemap images are square */ |
/* double pitch for cube layouts */ |
tex->stride = align(nblocks * util_format_get_blocksize(pt->format) * 2, 4); |
tex->total_nblocksy = nblocks * 4; |
for (level = 0; level <= pt->last_level; level++) |
i915_texture_set_level_info(tex, level, 6); |
for (face = 0; face < 6; face++) { |
unsigned x = initial_offsets[face][0] * nblocks; |
unsigned y = initial_offsets[face][1] * nblocks; |
unsigned d = nblocks; |
for (level = 0; level <= pt->last_level; level++) { |
i915_texture_set_image_offset(tex, level, face, x, y); |
d >>= 1; |
x += step_offsets[face][0] * d; |
y += step_offsets[face][1] * d; |
} |
} |
} |
/* |
* i915 layout functions |
*/ |
static void |
i915_texture_layout_2d(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
unsigned level; |
unsigned width = util_next_power_of_two(pt->width0); |
unsigned height = util_next_power_of_two(pt->height0); |
unsigned nblocksy = util_format_get_nblocksy(pt->format, width); |
unsigned align_y = 2; |
if (util_format_is_s3tc(pt->format)) |
align_y = 1; |
tex->stride = align(util_format_get_stride(pt->format, width), 4); |
tex->total_nblocksy = 0; |
for (level = 0; level <= pt->last_level; level++) { |
i915_texture_set_level_info(tex, level, 1); |
i915_texture_set_image_offset(tex, level, 0, 0, tex->total_nblocksy); |
tex->total_nblocksy += nblocksy; |
width = u_minify(width, 1); |
height = u_minify(height, 1); |
nblocksy = align_nblocksy(pt->format, height, align_y); |
} |
} |
static void |
i915_texture_layout_3d(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
unsigned level; |
unsigned width = util_next_power_of_two(pt->width0); |
unsigned height = util_next_power_of_two(pt->height0); |
unsigned depth = util_next_power_of_two(pt->depth0); |
unsigned nblocksy = util_format_get_nblocksy(pt->format, height); |
unsigned stack_nblocksy = 0; |
/* Calculate the size of a single slice. |
*/ |
tex->stride = align(util_format_get_stride(pt->format, width), 4); |
/* XXX: hardware expects/requires 9 levels at minimum. |
*/ |
for (level = 0; level <= MAX2(8, pt->last_level); level++) { |
i915_texture_set_level_info(tex, level, depth); |
stack_nblocksy += MAX2(2, nblocksy); |
width = u_minify(width, 1); |
height = u_minify(height, 1); |
nblocksy = util_format_get_nblocksy(pt->format, height); |
} |
/* Fixup depth image_offsets: |
*/ |
for (level = 0; level <= pt->last_level; level++) { |
unsigned i; |
for (i = 0; i < depth; i++) |
i915_texture_set_image_offset(tex, level, i, 0, i * stack_nblocksy); |
depth = u_minify(depth, 1); |
} |
/* Multiply slice size by texture depth for total size. It's |
* remarkable how wasteful of memory the i915 texture layouts |
* are. They are largely fixed in the i945. |
*/ |
tex->total_nblocksy = stack_nblocksy * util_next_power_of_two(pt->depth0); |
} |
static boolean |
i915_texture_layout(struct i915_texture * tex) |
{ |
switch (tex->b.b.target) { |
case PIPE_TEXTURE_1D: |
case PIPE_TEXTURE_2D: |
case PIPE_TEXTURE_RECT: |
if (!i9x5_special_layout(tex)) |
i915_texture_layout_2d(tex); |
break; |
case PIPE_TEXTURE_3D: |
i915_texture_layout_3d(tex); |
break; |
case PIPE_TEXTURE_CUBE: |
i9x5_texture_layout_cube(tex); |
break; |
default: |
assert(0); |
return FALSE; |
} |
return TRUE; |
} |
/* |
* i945 layout functions |
*/ |
static void |
i945_texture_layout_2d(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
int align_x = 4, align_y = 2; |
unsigned level; |
unsigned x = 0; |
unsigned y = 0; |
unsigned width = util_next_power_of_two(pt->width0); |
unsigned height = util_next_power_of_two(pt->height0); |
unsigned nblocksx = util_format_get_nblocksx(pt->format, width); |
unsigned nblocksy = util_format_get_nblocksy(pt->format, height); |
if (util_format_is_s3tc(pt->format)) { |
align_x = 1; |
align_y = 1; |
} |
tex->stride = align(util_format_get_stride(pt->format, width), 4); |
/* May need to adjust pitch to accommodate the placement of |
* the 2nd mipmap level. This occurs when the alignment |
* constraints of mipmap placement push the right edge of the |
* 2nd mipmap level out past the width of its parent. |
*/ |
if (pt->last_level > 0) { |
unsigned mip1_nblocksx = |
align_nblocksx(pt->format, u_minify(width, 1), align_x) + |
util_format_get_nblocksx(pt->format, u_minify(width, 2)); |
if (mip1_nblocksx > nblocksx) |
tex->stride = mip1_nblocksx * util_format_get_blocksize(pt->format); |
} |
/* Pitch must be a whole number of dwords |
*/ |
tex->stride = align(tex->stride, 64); |
tex->total_nblocksy = 0; |
for (level = 0; level <= pt->last_level; level++) { |
i915_texture_set_level_info(tex, level, 1); |
i915_texture_set_image_offset(tex, level, 0, x, y); |
/* Because the images are packed better, the final offset |
* might not be the maximal one: |
*/ |
tex->total_nblocksy = MAX2(tex->total_nblocksy, y + nblocksy); |
/* Layout_below: step right after second mipmap level. |
*/ |
if (level == 1) { |
x += nblocksx; |
} else { |
y += nblocksy; |
} |
width = u_minify(width, 1); |
height = u_minify(height, 1); |
nblocksx = align_nblocksx(pt->format, width, align_x); |
nblocksy = align_nblocksy(pt->format, height, align_y); |
} |
} |
static void |
i945_texture_layout_3d(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
unsigned width = util_next_power_of_two(pt->width0); |
unsigned height = util_next_power_of_two(pt->height0); |
unsigned depth = util_next_power_of_two(pt->depth0); |
unsigned nblocksy = util_format_get_nblocksy(pt->format, width); |
unsigned pack_x_pitch, pack_x_nr; |
unsigned pack_y_pitch; |
unsigned level; |
tex->stride = align(util_format_get_stride(pt->format, width), 4); |
tex->total_nblocksy = 0; |
pack_y_pitch = MAX2(nblocksy, 2); |
pack_x_pitch = tex->stride / util_format_get_blocksize(pt->format); |
pack_x_nr = 1; |
for (level = 0; level <= pt->last_level; level++) { |
int x = 0; |
int y = 0; |
unsigned q, j; |
i915_texture_set_level_info(tex, level, depth); |
for (q = 0; q < depth;) { |
for (j = 0; j < pack_x_nr && q < depth; j++, q++) { |
i915_texture_set_image_offset(tex, level, q, x, y + tex->total_nblocksy); |
x += pack_x_pitch; |
} |
x = 0; |
y += pack_y_pitch; |
} |
tex->total_nblocksy += y; |
if (pack_x_pitch > 4) { |
pack_x_pitch >>= 1; |
pack_x_nr <<= 1; |
assert(pack_x_pitch * pack_x_nr * util_format_get_blocksize(pt->format) <= tex->stride); |
} |
if (pack_y_pitch > 2) { |
pack_y_pitch >>= 1; |
} |
width = u_minify(width, 1); |
height = u_minify(height, 1); |
depth = u_minify(depth, 1); |
nblocksy = util_format_get_nblocksy(pt->format, height); |
} |
} |
static void |
i945_texture_layout_cube(struct i915_texture *tex) |
{ |
struct pipe_resource *pt = &tex->b.b; |
unsigned width = util_next_power_of_two(pt->width0); |
const unsigned nblocks = util_format_get_nblocksx(pt->format, width); |
const unsigned dim = width; |
unsigned level; |
unsigned face; |
assert(pt->width0 == pt->height0); /* cubemap images are square */ |
assert(util_format_is_s3tc(pt->format)); /* compressed only */ |
/* |
* Depending on the size of the largest images, pitch can be |
* determined either by the old-style packing of cubemap faces, |
* or the final row of 4x4, 2x2 and 1x1 faces below this. |
* |
* 64 * 2 / 4 = 32 |
* 14 * 2 = 28 |
*/ |
if (width >= 64) |
tex->stride = nblocks * 2 * util_format_get_blocksize(pt->format); |
else |
tex->stride = 14 * 2 * util_format_get_blocksize(pt->format); |
/* |
* Something similary apply for height as well. |
*/ |
if (width >= 4) |
tex->total_nblocksy = nblocks * 4 + 1; |
else |
tex->total_nblocksy = 1; |
/* Set all the levels to effectively occupy the whole rectangular region */ |
for (level = 0; level <= pt->last_level; level++) |
i915_texture_set_level_info(tex, level, 6); |
for (face = 0; face < 6; face++) { |
/* all calculations in pixels */ |
unsigned total_height = tex->total_nblocksy * 4; |
unsigned x = initial_offsets[face][0] * dim; |
unsigned y = initial_offsets[face][1] * dim; |
unsigned d = dim; |
if (dim == 4 && face >= 4) { |
x = (face - 4) * 8; |
y = tex->total_nblocksy * 4 - 4; /* 4 = 1 block */ |
} else if (dim < 4 && (face > 0)) { |
x = face * 8; |
y = total_height - 4; |
} |
for (level = 0; level <= pt->last_level; level++) { |
i915_texture_set_image_offset(tex, level, face, |
util_format_get_nblocksx(pt->format, x), |
util_format_get_nblocksy(pt->format, y)); |
d >>= 1; |
switch (d) { |
case 4: |
switch (face) { |
case PIPE_TEX_FACE_POS_X: |
case PIPE_TEX_FACE_NEG_X: |
x += step_offsets[face][0] * d; |
y += step_offsets[face][1] * d; |
break; |
case PIPE_TEX_FACE_POS_Y: |
case PIPE_TEX_FACE_NEG_Y: |
y += 12; |
x -= 8; |
break; |
case PIPE_TEX_FACE_POS_Z: |
case PIPE_TEX_FACE_NEG_Z: |
y = total_height - 4; |
x = (face - 4) * 8; |
break; |
} |
break; |
case 2: |
y = total_height - 4; |
x = bottom_offsets[face]; |
break; |
case 1: |
x += 48; |
break; |
default: |
x += step_offsets[face][0] * d; |
y += step_offsets[face][1] * d; |
break; |
} |
} |
} |
} |
static boolean |
i945_texture_layout(struct i915_texture * tex) |
{ |
switch (tex->b.b.target) { |
case PIPE_TEXTURE_1D: |
case PIPE_TEXTURE_2D: |
case PIPE_TEXTURE_RECT: |
if (!i9x5_special_layout(tex)) |
i945_texture_layout_2d(tex); |
break; |
case PIPE_TEXTURE_3D: |
i945_texture_layout_3d(tex); |
break; |
case PIPE_TEXTURE_CUBE: |
if (!util_format_is_s3tc(tex->b.b.format)) |
i9x5_texture_layout_cube(tex); |
else |
i945_texture_layout_cube(tex); |
break; |
default: |
assert(0); |
return FALSE; |
} |
return TRUE; |
} |
/* |
* Screen texture functions |
*/ |
static boolean |
i915_texture_get_handle(struct pipe_screen * screen, |
struct pipe_resource *texture, |
struct winsys_handle *whandle) |
{ |
struct i915_screen *is = i915_screen(screen); |
struct i915_texture *tex = i915_texture(texture); |
struct i915_winsys *iws = is->iws; |
return iws->buffer_get_handle(iws, tex->buffer, whandle, tex->stride); |
} |
static void |
i915_texture_destroy(struct pipe_screen *screen, |
struct pipe_resource *pt) |
{ |
struct i915_texture *tex = i915_texture(pt); |
struct i915_winsys *iws = i915_screen(screen)->iws; |
uint i; |
if (tex->buffer) |
iws->buffer_destroy(iws, tex->buffer); |
for (i = 0; i < Elements(tex->image_offset); i++) |
FREE(tex->image_offset[i]); |
FREE(tex); |
} |
static void * |
i915_texture_transfer_map(struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
struct pipe_transfer **ptransfer) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct i915_texture *tex = i915_texture(resource); |
struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool); |
boolean use_staging_texture = FALSE; |
struct i915_winsys *iws = i915_screen(pipe->screen)->iws; |
enum pipe_format format = resource->format; |
unsigned offset; |
char *map; |
if (transfer == NULL) |
return NULL; |
transfer->b.resource = resource; |
transfer->b.level = level; |
transfer->b.usage = usage; |
transfer->b.box = *box; |
transfer->b.stride = tex->stride; |
transfer->staging_texture = NULL; |
/* XXX: handle depth textures everyhwere*/ |
transfer->b.layer_stride = 0; |
/* if we use staging transfers, only support textures we can render to, |
* because we need that for u_blitter */ |
if (i915->blitter && |
util_blitter_is_copy_supported(i915->blitter, resource, resource) && |
(usage & PIPE_TRANSFER_WRITE) && |
!(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED))) |
use_staging_texture = TRUE; |
use_staging_texture = FALSE; |
if (use_staging_texture) { |
/* |
* Allocate the untiled staging texture. |
* If the alloc fails, transfer->staging_texture is NULL and we fallback to a map() |
*/ |
transfer->staging_texture = i915_texture_create(pipe->screen, resource, TRUE); |
} |
if (resource->target != PIPE_TEXTURE_3D && |
resource->target != PIPE_TEXTURE_CUBE) |
assert(box->z == 0); |
if (transfer->staging_texture) { |
tex = i915_texture(transfer->staging_texture); |
} else { |
/* TODO this is a sledgehammer */ |
tex = i915_texture(resource); |
pipe->flush(pipe, NULL, 0); |
} |
offset = i915_texture_offset(tex, transfer->b.level, box->z); |
map = iws->buffer_map(iws, tex->buffer, |
(transfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE); |
if (map == NULL) { |
pipe_resource_reference(&transfer->staging_texture, NULL); |
FREE(transfer); |
return NULL; |
} |
*ptransfer = &transfer->b; |
return map + offset + |
box->y / util_format_get_blockheight(format) * transfer->b.stride + |
box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); |
} |
static void |
i915_texture_transfer_unmap(struct pipe_context *pipe, |
struct pipe_transfer *transfer) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct i915_transfer *itransfer = (struct i915_transfer*)transfer; |
struct i915_texture *tex = i915_texture(itransfer->b.resource); |
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws; |
if (itransfer->staging_texture) |
tex = i915_texture(itransfer->staging_texture); |
iws->buffer_unmap(iws, tex->buffer); |
if ((itransfer->staging_texture) && |
(transfer->usage & PIPE_TRANSFER_WRITE)) { |
struct pipe_box sbox; |
u_box_origin_2d(itransfer->b.box.width, itransfer->b.box.height, &sbox); |
pipe->resource_copy_region(pipe, itransfer->b.resource, itransfer->b.level, |
itransfer->b.box.x, itransfer->b.box.y, itransfer->b.box.z, |
itransfer->staging_texture, |
0, &sbox); |
pipe->flush(pipe, NULL, 0); |
pipe_resource_reference(&itransfer->staging_texture, NULL); |
} |
util_slab_free(&i915->texture_transfer_pool, itransfer); |
} |
#if 0 |
static void i915_transfer_inline_write( struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride) |
{ |
struct pipe_transfer *transfer = NULL; |
struct i915_transfer *itransfer = NULL; |
const uint8_t *src_data = data; |
unsigned i; |
transfer = pipe->transfer_get(pipe, |
resource, |
level, |
usage, |
box ); |
if (transfer == NULL) |
goto out; |
itransfer = (struct i915_transfer*)transfer; |
if (itransfer->staging_texture) { |
struct i915_texture *tex = i915_texture(itransfer->staging_texture); |
enum pipe_format format = tex->b.b.format; |
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws; |
size_t offset; |
size_t size; |
offset = i915_texture_offset(tex, transfer->level, transfer->box.z); |
for (i = 0; i < box->depth; i++) { |
if (!tex->b.b.last_level && |
tex->b.b.width0 == transfer->box.width) { |
unsigned nby = util_format_get_nblocksy(format, transfer->box.y); |
assert(!offset); |
assert(!transfer->box.x); |
assert(tex->stride == transfer->stride); |
offset += tex->stride * nby; |
size = util_format_get_2d_size(format, transfer->stride, |
transfer->box.height); |
iws->buffer_write(iws, tex->buffer, offset, size, transfer->data); |
} else { |
unsigned nby = util_format_get_nblocksy(format, transfer->box.y); |
int i; |
offset += util_format_get_stride(format, transfer->box.x); |
size = transfer->stride; |
for (i = 0; i < nby; i++) { |
iws->buffer_write(iws, tex->buffer, offset, size, transfer->data); |
offset += tex->stride; |
} |
} |
offset += layer_stride; |
} |
} else { |
uint8_t *map = pipe_transfer_map(pipe, &itransfer->b); |
if (map == NULL) |
goto nomap; |
for (i = 0; i < box->depth; i++) { |
util_copy_rect(map, |
resource->format, |
itransfer->b.stride, /* bytes */ |
0, 0, |
box->width, |
box->height, |
src_data, |
stride, /* bytes */ |
0, 0); |
map += itransfer->b.layer_stride; |
src_data += layer_stride; |
} |
nomap: |
if (map) |
pipe_transfer_unmap(pipe, &itransfer->b); |
} |
out: |
if (itransfer) |
pipe_transfer_destroy(pipe, &itransfer->b); |
} |
#endif |
struct u_resource_vtbl i915_texture_vtbl = |
{ |
i915_texture_get_handle, /* get_handle */ |
i915_texture_destroy, /* resource_destroy */ |
i915_texture_transfer_map, /* transfer_map */ |
u_default_transfer_flush_region, /* transfer_flush_region */ |
i915_texture_transfer_unmap, /* transfer_unmap */ |
u_default_transfer_inline_write /* transfer_inline_write */ |
}; |
struct pipe_resource * |
i915_texture_create(struct pipe_screen *screen, |
const struct pipe_resource *template, |
boolean force_untiled) |
{ |
struct i915_screen *is = i915_screen(screen); |
struct i915_winsys *iws = is->iws; |
struct i915_texture *tex = CALLOC_STRUCT(i915_texture); |
unsigned buf_usage = 0; |
if (!tex) |
return NULL; |
tex->b.b = *template; |
tex->b.vtbl = &i915_texture_vtbl; |
pipe_reference_init(&tex->b.b.reference, 1); |
tex->b.b.screen = screen; |
if ( (force_untiled) || (template->usage == PIPE_USAGE_STREAM) ) |
tex->tiling = I915_TILE_NONE; |
else |
tex->tiling = i915_texture_tiling(is, tex); |
if (is->is_i945) { |
if (!i945_texture_layout(tex)) |
goto fail; |
} else { |
if (!i915_texture_layout(tex)) |
goto fail; |
} |
/* for scanouts and cursors, cursors arn't scanouts */ |
/* XXX: use a custom flag for cursors, don't rely on magically |
* guessing that this is Xorg asking for a cursor |
*/ |
if ((template->bind & PIPE_BIND_SCANOUT) && template->width0 != 64) |
buf_usage = I915_NEW_SCANOUT; |
else |
buf_usage = I915_NEW_TEXTURE; |
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy, |
&tex->tiling, buf_usage); |
if (!tex->buffer) |
goto fail; |
I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u) tiling %s\n", __func__, |
tex, tex->stride, |
tex->stride / util_format_get_blocksize(tex->b.b.format), |
tex->total_nblocksy, get_tiling_string(tex->tiling)); |
return &tex->b.b; |
fail: |
FREE(tex); |
return NULL; |
} |
struct pipe_resource * |
i915_texture_from_handle(struct pipe_screen * screen, |
const struct pipe_resource *template, |
struct winsys_handle *whandle) |
{ |
struct i915_screen *is = i915_screen(screen); |
struct i915_texture *tex; |
struct i915_winsys *iws = is->iws; |
struct i915_winsys_buffer *buffer; |
unsigned stride; |
enum i915_winsys_buffer_tile tiling; |
assert(screen); |
buffer = iws->buffer_from_handle(iws, whandle, template->height0, &tiling, &stride); |
/* Only supports one type */ |
if ((template->target != PIPE_TEXTURE_2D && |
template->target != PIPE_TEXTURE_RECT) || |
template->last_level != 0 || |
template->depth0 != 1) { |
return NULL; |
} |
tex = CALLOC_STRUCT(i915_texture); |
if (!tex) |
return NULL; |
tex->b.b = *template; |
tex->b.vtbl = &i915_texture_vtbl; |
pipe_reference_init(&tex->b.b.reference, 1); |
tex->b.b.screen = screen; |
tex->stride = stride; |
tex->tiling = tiling; |
tex->total_nblocksy = align_nblocksy(tex->b.b.format, tex->b.b.height0, 8); |
i915_texture_set_level_info(tex, 0, 1); |
i915_texture_set_image_offset(tex, 0, 0, 0, 0); |
tex->buffer = buffer; |
I915_DBG(DBG_TEXTURE, "%s: %p stride %u, blocks (%u, %u) tiling %s\n", __func__, |
tex, tex->stride, |
tex->stride / util_format_get_blocksize(tex->b.b.format), |
tex->total_nblocksy, get_tiling_string(tex->tiling)); |
return &tex->b.b; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_screen.c |
---|
0,0 → 1,577 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "draw/draw_context.h" |
#include "os/os_misc.h" |
#include "util/u_format.h" |
#include "util/u_format_s3tc.h" |
#include "util/u_inlines.h" |
#include "util/u_memory.h" |
#include "util/u_string.h" |
#include "i915_reg.h" |
#include "i915_debug.h" |
#include "i915_context.h" |
#include "i915_screen.h" |
#include "i915_resource.h" |
#include "i915_winsys.h" |
#include "i915_public.h" |
/* |
* Probe functions |
*/ |
static const char * |
i915_get_vendor(struct pipe_screen *screen) |
{ |
return "Mesa Project"; |
} |
static const char * |
i915_get_device_vendor(struct pipe_screen *screen) |
{ |
return "Intel"; |
} |
static const char * |
i915_get_name(struct pipe_screen *screen) |
{ |
static char buffer[128]; |
const char *chipset; |
switch (i915_screen(screen)->iws->pci_id) { |
case PCI_CHIP_I915_G: |
chipset = "915G"; |
break; |
case PCI_CHIP_I915_GM: |
chipset = "915GM"; |
break; |
case PCI_CHIP_I945_G: |
chipset = "945G"; |
break; |
case PCI_CHIP_I945_GM: |
chipset = "945GM"; |
break; |
case PCI_CHIP_I945_GME: |
chipset = "945GME"; |
break; |
case PCI_CHIP_G33_G: |
chipset = "G33"; |
break; |
case PCI_CHIP_Q35_G: |
chipset = "Q35"; |
break; |
case PCI_CHIP_Q33_G: |
chipset = "Q33"; |
break; |
case PCI_CHIP_PINEVIEW_G: |
chipset = "Pineview G"; |
break; |
case PCI_CHIP_PINEVIEW_M: |
chipset = "Pineview M"; |
break; |
default: |
chipset = "unknown"; |
break; |
} |
util_snprintf(buffer, sizeof(buffer), "i915 (chipset: %s)", chipset); |
return buffer; |
} |
static int |
i915_get_shader_param(struct pipe_screen *screen, unsigned shader, enum pipe_shader_cap cap) |
{ |
switch(shader) { |
case PIPE_SHADER_VERTEX: |
switch (cap) { |
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: |
if (debug_get_bool_option("DRAW_USE_LLVM", TRUE)) |
return PIPE_MAX_SAMPLERS; |
else |
return 0; |
default: |
return draw_get_shader_param(shader, cap); |
} |
case PIPE_SHADER_FRAGMENT: |
/* XXX: some of these are just shader model 2.0 values, fix this! */ |
switch(cap) { |
case PIPE_SHADER_CAP_MAX_INSTRUCTIONS: |
return I915_MAX_ALU_INSN + I915_MAX_TEX_INSN; |
case PIPE_SHADER_CAP_MAX_ALU_INSTRUCTIONS: |
return I915_MAX_ALU_INSN; |
case PIPE_SHADER_CAP_MAX_TEX_INSTRUCTIONS: |
return I915_MAX_TEX_INSN; |
case PIPE_SHADER_CAP_MAX_TEX_INDIRECTIONS: |
return 8; |
case PIPE_SHADER_CAP_MAX_CONTROL_FLOW_DEPTH: |
return 0; |
case PIPE_SHADER_CAP_MAX_INPUTS: |
return 10; |
case PIPE_SHADER_CAP_MAX_OUTPUTS: |
return 1; |
case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE: |
return 32 * sizeof(float[4]); |
case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: |
return 1; |
case PIPE_SHADER_CAP_MAX_TEMPS: |
return 12; /* XXX: 12 -> 32 ? */ |
case PIPE_SHADER_CAP_MAX_PREDS: |
return 0; |
case PIPE_SHADER_CAP_TGSI_CONT_SUPPORTED: |
case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED: |
return 0; |
case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: |
case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: |
case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: |
case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: |
return 1; |
case PIPE_SHADER_CAP_SUBROUTINES: |
return 0; |
case PIPE_SHADER_CAP_INTEGERS: |
return 0; |
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS: |
case PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS: |
return I915_TEX_UNITS; |
case PIPE_SHADER_CAP_DOUBLES: |
case PIPE_SHADER_CAP_TGSI_DROUND_SUPPORTED: |
case PIPE_SHADER_CAP_TGSI_DFRACEXP_DLDEXP_SUPPORTED: |
case PIPE_SHADER_CAP_TGSI_FMA_SUPPORTED: |
return 0; |
default: |
debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); |
return 0; |
} |
break; |
default: |
return 0; |
} |
} |
static int |
i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) |
{ |
struct i915_screen *is = i915_screen(screen); |
switch (cap) { |
/* Supported features (boolean caps). */ |
case PIPE_CAP_ANISOTROPIC_FILTER: |
case PIPE_CAP_NPOT_TEXTURES: |
case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES: |
case PIPE_CAP_POINT_SPRITE: |
case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ |
case PIPE_CAP_TEXTURE_SHADOW_MAP: |
case PIPE_CAP_TWO_SIDED_STENCIL: |
case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: |
case PIPE_CAP_BLEND_EQUATION_SEPARATE: |
case PIPE_CAP_TGSI_INSTANCEID: |
case PIPE_CAP_VERTEX_COLOR_CLAMPED: |
case PIPE_CAP_USER_VERTEX_BUFFERS: |
case PIPE_CAP_USER_INDEX_BUFFERS: |
case PIPE_CAP_USER_CONSTANT_BUFFERS: |
return 1; |
/* Unsupported features (boolean caps). */ |
case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: |
case PIPE_CAP_DEPTH_CLIP_DISABLE: |
case PIPE_CAP_INDEP_BLEND_ENABLE: |
case PIPE_CAP_INDEP_BLEND_FUNC: |
case PIPE_CAP_SHADER_STENCIL_EXPORT: |
case PIPE_CAP_TEXTURE_MIRROR_CLAMP: |
case PIPE_CAP_TEXTURE_SWIZZLE: |
case PIPE_CAP_QUERY_TIME_ELAPSED: |
case PIPE_CAP_SM3: |
case PIPE_CAP_SEAMLESS_CUBE_MAP: |
case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE: |
case PIPE_CAP_FRAGMENT_COLOR_CLAMPED: |
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS: |
case PIPE_CAP_CONDITIONAL_RENDER: |
case PIPE_CAP_TEXTURE_BARRIER: |
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS: |
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED: |
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION: |
case PIPE_CAP_START_INSTANCE: |
case PIPE_CAP_QUERY_TIMESTAMP: |
case PIPE_CAP_QUERY_PIPELINE_STATISTICS: |
case PIPE_CAP_TEXTURE_MULTISAMPLE: |
case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK: |
case PIPE_CAP_CUBE_MAP_ARRAY: |
case PIPE_CAP_TEXTURE_BUFFER_OBJECTS: |
case PIPE_CAP_TGSI_TEXCOORD: |
case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER: |
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_CONDITIONAL_RENDER_INVERTED: |
case PIPE_CAP_CLIP_HALFZ: |
case PIPE_CAP_VERTEXID_NOBASE: |
case PIPE_CAP_POLYGON_OFFSET_CLAMP: |
case PIPE_CAP_MULTISAMPLE_Z_RESOLVE: |
case PIPE_CAP_RESOURCE_FROM_USER_MEMORY: |
case PIPE_CAP_DEVICE_RESET_STATUS_QUERY: |
return 0; |
case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: |
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME: |
case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY: |
case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY: |
case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY: |
case PIPE_CAP_TGSI_VS_LAYER_VIEWPORT: |
case PIPE_CAP_BUFFER_MAP_PERSISTENT_COHERENT: |
case PIPE_CAP_DRAW_INDIRECT: |
case PIPE_CAP_TGSI_FS_FINE_DERIVATIVE: |
case PIPE_CAP_SAMPLER_VIEW_TARGET: |
return 0; |
case PIPE_CAP_MAX_VIEWPORTS: |
return 1; |
case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT: |
return 64; |
case PIPE_CAP_GLSL_FEATURE_LEVEL: |
return 120; |
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT: |
return 16; |
/* Features we can lie about (boolean caps). */ |
case PIPE_CAP_OCCLUSION_QUERY: |
return is->debug.lie ? 1 : 0; |
/* Texturing. */ |
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: |
return I915_MAX_TEXTURE_2D_LEVELS; |
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: |
return I915_MAX_TEXTURE_3D_LEVELS; |
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: |
return I915_MAX_TEXTURE_2D_LEVELS; |
case PIPE_CAP_MIN_TEXEL_OFFSET: |
case PIPE_CAP_MAX_TEXEL_OFFSET: |
case PIPE_CAP_MIN_TEXTURE_GATHER_OFFSET: |
case PIPE_CAP_MAX_TEXTURE_GATHER_OFFSET: |
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS: |
case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS: |
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS: |
return 0; |
/* Render targets. */ |
case PIPE_CAP_MAX_RENDER_TARGETS: |
return 1; |
/* Geometry shader output, unsupported. */ |
case PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES: |
case PIPE_CAP_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: |
case PIPE_CAP_MAX_VERTEX_STREAMS: |
return 0; |
case PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE: |
return 2048; |
/* Fragment coordinate conventions. */ |
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: |
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: |
return 1; |
case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT: |
case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: |
return 0; |
case PIPE_CAP_ENDIANNESS: |
return PIPE_ENDIAN_LITTLE; |
case PIPE_CAP_VENDOR_ID: |
return 0x8086; |
case PIPE_CAP_DEVICE_ID: |
return is->iws->pci_id; |
case PIPE_CAP_ACCELERATED: |
return 1; |
case PIPE_CAP_VIDEO_MEMORY: { |
/* Once a batch uses more than 75% of the maximum mappable size, we |
* assume that there's some fragmentation, and we start doing extra |
* flushing, etc. That's the big cliff apps will care about. |
*/ |
const int gpu_mappable_megabytes = is->iws->aperture_size(is->iws) * 3 / 4; |
uint64_t system_memory; |
if (!os_get_total_physical_memory(&system_memory)) |
return 0; |
return MIN2(gpu_mappable_megabytes, (int)(system_memory >> 20)); |
} |
case PIPE_CAP_UMA: |
return 1; |
default: |
debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); |
return 0; |
} |
} |
static float |
i915_get_paramf(struct pipe_screen *screen, enum pipe_capf cap) |
{ |
switch(cap) { |
case PIPE_CAPF_MAX_LINE_WIDTH: |
/* fall-through */ |
case PIPE_CAPF_MAX_LINE_WIDTH_AA: |
return 7.5; |
case PIPE_CAPF_MAX_POINT_WIDTH: |
/* fall-through */ |
case PIPE_CAPF_MAX_POINT_WIDTH_AA: |
return 255.0; |
case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: |
return 4.0; |
case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: |
return 16.0; |
default: |
debug_printf("%s: Unknown cap %u.\n", __FUNCTION__, cap); |
return 0; |
} |
} |
boolean |
i915_is_format_supported(struct pipe_screen *screen, |
enum pipe_format format, |
enum pipe_texture_target target, |
unsigned sample_count, |
unsigned tex_usage) |
{ |
static const enum pipe_format tex_supported[] = { |
PIPE_FORMAT_B8G8R8A8_UNORM, |
PIPE_FORMAT_B8G8R8A8_SRGB, |
PIPE_FORMAT_B8G8R8X8_UNORM, |
PIPE_FORMAT_R8G8B8A8_UNORM, |
PIPE_FORMAT_R8G8B8X8_UNORM, |
PIPE_FORMAT_B4G4R4A4_UNORM, |
PIPE_FORMAT_B5G6R5_UNORM, |
PIPE_FORMAT_B5G5R5A1_UNORM, |
PIPE_FORMAT_B10G10R10A2_UNORM, |
PIPE_FORMAT_L8_UNORM, |
PIPE_FORMAT_A8_UNORM, |
PIPE_FORMAT_I8_UNORM, |
PIPE_FORMAT_L8A8_UNORM, |
PIPE_FORMAT_UYVY, |
PIPE_FORMAT_YUYV, |
/* XXX why not? |
PIPE_FORMAT_Z16_UNORM, */ |
PIPE_FORMAT_DXT1_RGB, |
PIPE_FORMAT_DXT1_RGBA, |
PIPE_FORMAT_DXT3_RGBA, |
PIPE_FORMAT_DXT5_RGBA, |
PIPE_FORMAT_Z24X8_UNORM, |
PIPE_FORMAT_Z24_UNORM_S8_UINT, |
PIPE_FORMAT_NONE /* list terminator */ |
}; |
static const enum pipe_format render_supported[] = { |
PIPE_FORMAT_B8G8R8A8_UNORM, |
PIPE_FORMAT_B8G8R8X8_UNORM, |
PIPE_FORMAT_R8G8B8A8_UNORM, |
PIPE_FORMAT_R8G8B8X8_UNORM, |
PIPE_FORMAT_B5G6R5_UNORM, |
PIPE_FORMAT_B5G5R5A1_UNORM, |
PIPE_FORMAT_B4G4R4A4_UNORM, |
PIPE_FORMAT_B10G10R10A2_UNORM, |
PIPE_FORMAT_L8_UNORM, |
PIPE_FORMAT_A8_UNORM, |
PIPE_FORMAT_I8_UNORM, |
PIPE_FORMAT_NONE /* list terminator */ |
}; |
static const enum pipe_format depth_supported[] = { |
/* XXX why not? |
PIPE_FORMAT_Z16_UNORM, */ |
PIPE_FORMAT_Z24X8_UNORM, |
PIPE_FORMAT_Z24_UNORM_S8_UINT, |
PIPE_FORMAT_NONE /* list terminator */ |
}; |
const enum pipe_format *list; |
uint i; |
if (!util_format_is_supported(format, tex_usage)) |
return FALSE; |
if (sample_count > 1) |
return FALSE; |
if(tex_usage & PIPE_BIND_DEPTH_STENCIL) |
list = depth_supported; |
else if (tex_usage & PIPE_BIND_RENDER_TARGET) |
list = render_supported; |
else if (tex_usage & PIPE_BIND_SAMPLER_VIEW) |
list = tex_supported; |
else |
return TRUE; /* PIPE_BIND_{VERTEX,INDEX}_BUFFER */ |
for (i = 0; list[i] != PIPE_FORMAT_NONE; i++) { |
if (list[i] == format) |
return TRUE; |
} |
return FALSE; |
} |
/* |
* Fence functions |
*/ |
static void |
i915_fence_reference(struct pipe_screen *screen, |
struct pipe_fence_handle **ptr, |
struct pipe_fence_handle *fence) |
{ |
struct i915_screen *is = i915_screen(screen); |
is->iws->fence_reference(is->iws, ptr, fence); |
} |
static boolean |
i915_fence_signalled(struct pipe_screen *screen, |
struct pipe_fence_handle *fence) |
{ |
struct i915_screen *is = i915_screen(screen); |
return is->iws->fence_signalled(is->iws, fence) == 1; |
} |
static boolean |
i915_fence_finish(struct pipe_screen *screen, |
struct pipe_fence_handle *fence, |
uint64_t timeout) |
{ |
struct i915_screen *is = i915_screen(screen); |
return is->iws->fence_finish(is->iws, fence) == 1; |
} |
/* |
* Generic functions |
*/ |
static void |
i915_flush_frontbuffer(struct pipe_screen *screen, |
struct pipe_resource *resource, |
unsigned level, unsigned layer, |
void *winsys_drawable_handle, |
struct pipe_box *sub_box) |
{ |
/* XXX: Dummy right now. */ |
(void)screen; |
(void)resource; |
(void)level; |
(void)layer; |
(void)winsys_drawable_handle; |
(void)sub_box; |
} |
static void |
i915_destroy_screen(struct pipe_screen *screen) |
{ |
struct i915_screen *is = i915_screen(screen); |
if (is->iws) |
is->iws->destroy(is->iws); |
FREE(is); |
} |
/** |
* Create a new i915_screen object |
*/ |
struct pipe_screen * |
i915_screen_create(struct i915_winsys *iws) |
{ |
struct i915_screen *is = CALLOC_STRUCT(i915_screen); |
if (!is) |
return NULL; |
switch (iws->pci_id) { |
case PCI_CHIP_I915_G: |
case PCI_CHIP_I915_GM: |
is->is_i945 = FALSE; |
break; |
case PCI_CHIP_I945_G: |
case PCI_CHIP_I945_GM: |
case PCI_CHIP_I945_GME: |
case PCI_CHIP_G33_G: |
case PCI_CHIP_Q33_G: |
case PCI_CHIP_Q35_G: |
case PCI_CHIP_PINEVIEW_G: |
case PCI_CHIP_PINEVIEW_M: |
is->is_i945 = TRUE; |
break; |
default: |
debug_printf("%s: unknown pci id 0x%x, cannot create screen\n", |
__FUNCTION__, iws->pci_id); |
FREE(is); |
return NULL; |
} |
is->iws = iws; |
is->base.destroy = i915_destroy_screen; |
is->base.flush_frontbuffer = i915_flush_frontbuffer; |
is->base.get_name = i915_get_name; |
is->base.get_vendor = i915_get_vendor; |
is->base.get_device_vendor = i915_get_device_vendor; |
is->base.get_param = i915_get_param; |
is->base.get_shader_param = i915_get_shader_param; |
is->base.get_paramf = i915_get_paramf; |
is->base.is_format_supported = i915_is_format_supported; |
is->base.context_create = i915_create_context; |
is->base.fence_reference = i915_fence_reference; |
is->base.fence_signalled = i915_fence_signalled; |
is->base.fence_finish = i915_fence_finish; |
i915_init_screen_resource_functions(is); |
i915_debug_init(is); |
util_format_s3tc_init(); |
return &is->base; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_screen.h |
---|
0,0 → 1,75 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_SCREEN_H |
#define I915_SCREEN_H |
#include "pipe/p_state.h" |
#include "pipe/p_screen.h" |
struct i915_winsys; |
/** |
* Subclass of pipe_screen |
*/ |
struct i915_screen |
{ |
struct pipe_screen base; |
struct i915_winsys *iws; |
boolean is_i945; |
struct { |
boolean tiling; |
boolean lie; |
boolean use_blitter; |
} debug; |
}; |
/* |
* Cast wrappers |
*/ |
static INLINE struct i915_screen * |
i915_screen(struct pipe_screen *pscreen) |
{ |
return (struct i915_screen *) pscreen; |
} |
boolean |
i915_is_format_supported(struct pipe_screen *screen, |
enum pipe_format format, |
enum pipe_texture_target target, |
unsigned sample_count, |
unsigned tex_usage); |
#endif /* I915_SCREEN_H */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state.c |
---|
0,0 → 1,1123 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* Authors: Keith Whitwell <keithw@vmware.com> |
*/ |
#include "draw/draw_context.h" |
#include "util/u_helpers.h" |
#include "util/u_inlines.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_transfer.h" |
#include "tgsi/tgsi_parse.h" |
#include "i915_context.h" |
#include "i915_reg.h" |
#include "i915_state_inlines.h" |
#include "i915_fpc.h" |
#include "i915_resource.h" |
#include "i915_state.h" |
/* The i915 (and related graphics cores) do not support GL_CLAMP. The |
* Intel drivers for "other operating systems" implement GL_CLAMP as |
* GL_CLAMP_TO_EDGE, so the same is done here. |
*/ |
static unsigned |
translate_wrap_mode(unsigned wrap) |
{ |
switch (wrap) { |
case PIPE_TEX_WRAP_REPEAT: |
return TEXCOORDMODE_WRAP; |
case PIPE_TEX_WRAP_CLAMP: |
return TEXCOORDMODE_CLAMP_EDGE; /* not quite correct */ |
case PIPE_TEX_WRAP_CLAMP_TO_EDGE: |
return TEXCOORDMODE_CLAMP_EDGE; |
case PIPE_TEX_WRAP_CLAMP_TO_BORDER: |
return TEXCOORDMODE_CLAMP_BORDER; |
case PIPE_TEX_WRAP_MIRROR_REPEAT: |
return TEXCOORDMODE_MIRROR; |
default: |
return TEXCOORDMODE_WRAP; |
} |
} |
static unsigned translate_img_filter( unsigned filter ) |
{ |
switch (filter) { |
case PIPE_TEX_FILTER_NEAREST: |
return FILTER_NEAREST; |
case PIPE_TEX_FILTER_LINEAR: |
return FILTER_LINEAR; |
default: |
assert(0); |
return FILTER_NEAREST; |
} |
} |
static unsigned translate_mip_filter( unsigned filter ) |
{ |
switch (filter) { |
case PIPE_TEX_MIPFILTER_NONE: |
return MIPFILTER_NONE; |
case PIPE_TEX_MIPFILTER_NEAREST: |
return MIPFILTER_NEAREST; |
case PIPE_TEX_MIPFILTER_LINEAR: |
return MIPFILTER_LINEAR; |
default: |
assert(0); |
return MIPFILTER_NONE; |
} |
} |
/* None of this state is actually used for anything yet. |
*/ |
static void * |
i915_create_blend_state(struct pipe_context *pipe, |
const struct pipe_blend_state *blend) |
{ |
struct i915_blend_state *cso_data = CALLOC_STRUCT( i915_blend_state ); |
{ |
unsigned eqRGB = blend->rt[0].rgb_func; |
unsigned srcRGB = blend->rt[0].rgb_src_factor; |
unsigned dstRGB = blend->rt[0].rgb_dst_factor; |
unsigned eqA = blend->rt[0].alpha_func; |
unsigned srcA = blend->rt[0].alpha_src_factor; |
unsigned dstA = blend->rt[0].alpha_dst_factor; |
/* Special handling for MIN/MAX filter modes handled at |
* state_tracker level. |
*/ |
if (srcA != srcRGB || |
dstA != dstRGB || |
eqA != eqRGB) { |
cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | |
IAB_MODIFY_ENABLE | |
IAB_ENABLE | |
IAB_MODIFY_FUNC | |
IAB_MODIFY_SRC_FACTOR | |
IAB_MODIFY_DST_FACTOR | |
SRC_ABLND_FACT(i915_translate_blend_factor(srcA)) | |
DST_ABLND_FACT(i915_translate_blend_factor(dstA)) | |
(i915_translate_blend_func(eqA) << IAB_FUNC_SHIFT)); |
} |
else { |
cso_data->iab = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD | |
IAB_MODIFY_ENABLE | |
0); |
} |
} |
cso_data->modes4 |= (_3DSTATE_MODES_4_CMD | |
ENABLE_LOGIC_OP_FUNC | |
LOGIC_OP_FUNC(i915_translate_logic_op(blend->logicop_func))); |
if (blend->logicop_enable) |
cso_data->LIS5 |= S5_LOGICOP_ENABLE; |
if (blend->dither) |
cso_data->LIS5 |= S5_COLOR_DITHER_ENABLE; |
/* We potentially do some fixup at emission for non-BGRA targets */ |
if ((blend->rt[0].colormask & PIPE_MASK_R) == 0) |
cso_data->LIS5 |= S5_WRITEDISABLE_RED; |
if ((blend->rt[0].colormask & PIPE_MASK_G) == 0) |
cso_data->LIS5 |= S5_WRITEDISABLE_GREEN; |
if ((blend->rt[0].colormask & PIPE_MASK_B) == 0) |
cso_data->LIS5 |= S5_WRITEDISABLE_BLUE; |
if ((blend->rt[0].colormask & PIPE_MASK_A) == 0) |
cso_data->LIS5 |= S5_WRITEDISABLE_ALPHA; |
if (blend->rt[0].blend_enable) { |
unsigned funcRGB = blend->rt[0].rgb_func; |
unsigned srcRGB = blend->rt[0].rgb_src_factor; |
unsigned dstRGB = blend->rt[0].rgb_dst_factor; |
cso_data->LIS6 |= (S6_CBUF_BLEND_ENABLE | |
SRC_BLND_FACT(i915_translate_blend_factor(srcRGB)) | |
DST_BLND_FACT(i915_translate_blend_factor(dstRGB)) | |
(i915_translate_blend_func(funcRGB) << S6_CBUF_BLEND_FUNC_SHIFT)); |
} |
return cso_data; |
} |
static void i915_bind_blend_state(struct pipe_context *pipe, |
void *blend) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (i915->blend == blend) |
return; |
i915->blend = (struct i915_blend_state*)blend; |
i915->dirty |= I915_NEW_BLEND; |
} |
static void i915_delete_blend_state(struct pipe_context *pipe, void *blend) |
{ |
FREE(blend); |
} |
static void i915_set_blend_color( struct pipe_context *pipe, |
const struct pipe_blend_color *blend_color ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (!blend_color) |
return; |
i915->blend_color = *blend_color; |
i915->dirty |= I915_NEW_BLEND; |
} |
static void i915_set_stencil_ref( struct pipe_context *pipe, |
const struct pipe_stencil_ref *stencil_ref ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
i915->stencil_ref = *stencil_ref; |
i915->dirty |= I915_NEW_DEPTH_STENCIL; |
} |
static void * |
i915_create_sampler_state(struct pipe_context *pipe, |
const struct pipe_sampler_state *sampler) |
{ |
struct i915_sampler_state *cso = CALLOC_STRUCT( i915_sampler_state ); |
const unsigned ws = sampler->wrap_s; |
const unsigned wt = sampler->wrap_t; |
const unsigned wr = sampler->wrap_r; |
unsigned minFilt, magFilt; |
unsigned mipFilt; |
cso->templ = *sampler; |
mipFilt = translate_mip_filter(sampler->min_mip_filter); |
minFilt = translate_img_filter( sampler->min_img_filter ); |
magFilt = translate_img_filter( sampler->mag_img_filter ); |
if (sampler->max_anisotropy > 1) |
minFilt = magFilt = FILTER_ANISOTROPIC; |
if (sampler->max_anisotropy > 2) { |
cso->state[0] |= SS2_MAX_ANISO_4; |
} |
{ |
int b = (int) (sampler->lod_bias * 16.0); |
b = CLAMP(b, -256, 255); |
cso->state[0] |= ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK); |
} |
/* Shadow: |
*/ |
if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) |
{ |
cso->state[0] |= (SS2_SHADOW_ENABLE | |
i915_translate_shadow_compare_func(sampler->compare_func)); |
minFilt = FILTER_4X4_FLAT; |
magFilt = FILTER_4X4_FLAT; |
} |
cso->state[0] |= ((minFilt << SS2_MIN_FILTER_SHIFT) | |
(mipFilt << SS2_MIP_FILTER_SHIFT) | |
(magFilt << SS2_MAG_FILTER_SHIFT)); |
cso->state[1] |= |
((translate_wrap_mode(ws) << SS3_TCX_ADDR_MODE_SHIFT) | |
(translate_wrap_mode(wt) << SS3_TCY_ADDR_MODE_SHIFT) | |
(translate_wrap_mode(wr) << SS3_TCZ_ADDR_MODE_SHIFT)); |
if (sampler->normalized_coords) |
cso->state[1] |= SS3_NORMALIZED_COORDS; |
{ |
int minlod = (int) (16.0 * sampler->min_lod); |
int maxlod = (int) (16.0 * sampler->max_lod); |
minlod = CLAMP(minlod, 0, 16 * 11); |
maxlod = CLAMP(maxlod, 0, 16 * 11); |
if (minlod > maxlod) |
maxlod = minlod; |
cso->minlod = minlod; |
cso->maxlod = maxlod; |
} |
{ |
ubyte r = float_to_ubyte(sampler->border_color.f[0]); |
ubyte g = float_to_ubyte(sampler->border_color.f[1]); |
ubyte b = float_to_ubyte(sampler->border_color.f[2]); |
ubyte a = float_to_ubyte(sampler->border_color.f[3]); |
cso->state[2] = I915PACKCOLOR8888(r, g, b, a); |
} |
return cso; |
} |
static void |
i915_bind_vertex_sampler_states(struct pipe_context *pipe, |
unsigned start, |
unsigned num, |
void **samplers) |
{ |
struct i915_context *i915 = i915_context(pipe); |
unsigned i; |
assert(start + num <= Elements(i915->vertex_samplers)); |
/* Check for no-op */ |
if (num == i915->num_vertex_samplers && |
!memcmp(i915->vertex_samplers + start, samplers, |
num * sizeof(void *))) |
return; |
for (i = 0; i < num; ++i) |
i915->vertex_samplers[i + start] = samplers[i]; |
/* find highest non-null samplers[] entry */ |
{ |
unsigned j = MAX2(i915->num_vertex_samplers, start + num); |
while (j > 0 && i915->vertex_samplers[j - 1] == NULL) |
j--; |
i915->num_vertex_samplers = j; |
} |
draw_set_samplers(i915->draw, |
PIPE_SHADER_VERTEX, |
i915->vertex_samplers, |
i915->num_vertex_samplers); |
} |
static void i915_bind_fragment_sampler_states(struct pipe_context *pipe, |
unsigned start, |
unsigned num, |
void **samplers) |
{ |
struct i915_context *i915 = i915_context(pipe); |
unsigned i; |
/* Check for no-op */ |
if (num == i915->num_samplers && |
!memcmp(i915->fragment_sampler + start, samplers, |
num * sizeof(void *))) |
return; |
for (i = 0; i < num; ++i) |
i915->fragment_sampler[i + start] = samplers[i]; |
/* find highest non-null samplers[] entry */ |
{ |
unsigned j = MAX2(i915->num_samplers, start + num); |
while (j > 0 && i915->fragment_sampler[j - 1] == NULL) |
j--; |
i915->num_samplers = j; |
} |
i915->dirty |= I915_NEW_SAMPLER; |
} |
static void |
i915_bind_sampler_states(struct pipe_context *pipe, unsigned shader, |
unsigned start, unsigned num_samplers, |
void **samplers) |
{ |
switch (shader) { |
case PIPE_SHADER_VERTEX: |
i915_bind_vertex_sampler_states(pipe, start, num_samplers, samplers); |
break; |
case PIPE_SHADER_FRAGMENT: |
i915_bind_fragment_sampler_states(pipe, start, num_samplers, samplers); |
break; |
default: |
; |
} |
} |
static void i915_delete_sampler_state(struct pipe_context *pipe, |
void *sampler) |
{ |
FREE(sampler); |
} |
/** |
* Called before drawing VBO to map vertex samplers and hand them to draw |
*/ |
void |
i915_prepare_vertex_sampling(struct i915_context *i915) |
{ |
struct i915_winsys *iws = i915->iws; |
unsigned i,j; |
uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS]; |
uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS]; |
uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS]; |
unsigned num = i915->num_vertex_sampler_views; |
struct pipe_sampler_view **views = i915->vertex_sampler_views; |
assert(num <= PIPE_MAX_SAMPLERS); |
if (!num) |
return; |
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { |
struct pipe_sampler_view *view = i < num ? views[i] : NULL; |
if (view) { |
struct pipe_resource *tex = view->texture; |
struct i915_texture *i915_tex = i915_texture(tex); |
ubyte *addr; |
/* We're referencing the texture's internal data, so save a |
* reference to it. |
*/ |
pipe_resource_reference(&i915->mapped_vs_tex[i], tex); |
i915->mapped_vs_tex_buffer[i] = i915_tex->buffer; |
addr = iws->buffer_map(iws, |
i915_tex->buffer, |
FALSE /* read only */); |
/* Setup array of mipmap level pointers */ |
/* FIXME: handle 3D textures? */ |
for (j = view->u.tex.first_level; j <= tex->last_level; j++) { |
mip_offsets[j] = i915_texture_offset(i915_tex, j , 0 /* FIXME depth */); |
row_stride[j] = i915_tex->stride; |
img_stride[j] = 0; /* FIXME */; |
} |
draw_set_mapped_texture(i915->draw, |
PIPE_SHADER_VERTEX, |
i, |
tex->width0, tex->height0, tex->depth0, |
view->u.tex.first_level, tex->last_level, |
addr, |
row_stride, img_stride, mip_offsets); |
} else |
i915->mapped_vs_tex[i] = NULL; |
} |
} |
void |
i915_cleanup_vertex_sampling(struct i915_context *i915) |
{ |
struct i915_winsys *iws = i915->iws; |
unsigned i; |
for (i = 0; i < Elements(i915->mapped_vs_tex); i++) { |
if (i915->mapped_vs_tex_buffer[i]) { |
iws->buffer_unmap(iws, i915->mapped_vs_tex_buffer[i]); |
pipe_resource_reference(&i915->mapped_vs_tex[i], NULL); |
} |
} |
} |
/** XXX move someday? Or consolidate all these simple state setters |
* into one file. |
*/ |
static void * |
i915_create_depth_stencil_state(struct pipe_context *pipe, |
const struct pipe_depth_stencil_alpha_state *depth_stencil) |
{ |
struct i915_depth_stencil_state *cso = CALLOC_STRUCT( i915_depth_stencil_state ); |
{ |
int testmask = depth_stencil->stencil[0].valuemask & 0xff; |
int writemask = depth_stencil->stencil[0].writemask & 0xff; |
cso->stencil_modes4 |= (_3DSTATE_MODES_4_CMD | |
ENABLE_STENCIL_TEST_MASK | |
STENCIL_TEST_MASK(testmask) | |
ENABLE_STENCIL_WRITE_MASK | |
STENCIL_WRITE_MASK(writemask)); |
} |
if (depth_stencil->stencil[0].enabled) { |
int test = i915_translate_compare_func(depth_stencil->stencil[0].func); |
int fop = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op); |
int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op); |
int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op); |
cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE | |
S5_STENCIL_WRITE_ENABLE | |
(test << S5_STENCIL_TEST_FUNC_SHIFT) | |
(fop << S5_STENCIL_FAIL_SHIFT) | |
(dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | |
(dpop << S5_STENCIL_PASS_Z_PASS_SHIFT)); |
} |
if (depth_stencil->stencil[1].enabled) { |
int test = i915_translate_compare_func(depth_stencil->stencil[1].func); |
int fop = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op); |
int dfop = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op); |
int dpop = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op); |
int tmask = depth_stencil->stencil[1].valuemask & 0xff; |
int wmask = depth_stencil->stencil[1].writemask & 0xff; |
cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS | |
BFO_ENABLE_STENCIL_FUNCS | |
BFO_ENABLE_STENCIL_TWO_SIDE | |
BFO_ENABLE_STENCIL_REF | |
BFO_STENCIL_TWO_SIDE | |
(test << BFO_STENCIL_TEST_SHIFT) | |
(fop << BFO_STENCIL_FAIL_SHIFT) | |
(dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) | |
(dpop << BFO_STENCIL_PASS_Z_PASS_SHIFT)); |
cso->bfo[1] = (_3DSTATE_BACKFACE_STENCIL_MASKS | |
BFM_ENABLE_STENCIL_TEST_MASK | |
BFM_ENABLE_STENCIL_WRITE_MASK | |
(tmask << BFM_STENCIL_TEST_MASK_SHIFT) | |
(wmask << BFM_STENCIL_WRITE_MASK_SHIFT)); |
} |
else { |
/* This actually disables two-side stencil: The bit set is a |
* modify-enable bit to indicate we are changing the two-side |
* setting. Then there is a symbolic zero to show that we are |
* setting the flag to zero/off. |
*/ |
cso->bfo[0] = (_3DSTATE_BACKFACE_STENCIL_OPS | |
BFO_ENABLE_STENCIL_TWO_SIDE | |
0); |
cso->bfo[1] = 0; |
} |
if (depth_stencil->depth.enabled) { |
int func = i915_translate_compare_func(depth_stencil->depth.func); |
cso->depth_LIS6 |= (S6_DEPTH_TEST_ENABLE | |
(func << S6_DEPTH_TEST_FUNC_SHIFT)); |
if (depth_stencil->depth.writemask) |
cso->depth_LIS6 |= S6_DEPTH_WRITE_ENABLE; |
} |
if (depth_stencil->alpha.enabled) { |
int test = i915_translate_compare_func(depth_stencil->alpha.func); |
ubyte refByte = float_to_ubyte(depth_stencil->alpha.ref_value); |
cso->depth_LIS6 |= (S6_ALPHA_TEST_ENABLE | |
(test << S6_ALPHA_TEST_FUNC_SHIFT) | |
(((unsigned) refByte) << S6_ALPHA_REF_SHIFT)); |
} |
return cso; |
} |
static void i915_bind_depth_stencil_state(struct pipe_context *pipe, |
void *depth_stencil) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (i915->depth_stencil == depth_stencil) |
return; |
i915->depth_stencil = (const struct i915_depth_stencil_state *)depth_stencil; |
i915->dirty |= I915_NEW_DEPTH_STENCIL; |
} |
static void i915_delete_depth_stencil_state(struct pipe_context *pipe, |
void *depth_stencil) |
{ |
FREE(depth_stencil); |
} |
static void i915_set_scissor_states( struct pipe_context *pipe, |
unsigned start_slot, |
unsigned num_scissors, |
const struct pipe_scissor_state *scissor ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
memcpy( &i915->scissor, scissor, sizeof(*scissor) ); |
i915->dirty |= I915_NEW_SCISSOR; |
} |
static void i915_set_polygon_stipple( struct pipe_context *pipe, |
const struct pipe_poly_stipple *stipple ) |
{ |
} |
static void * |
i915_create_fs_state(struct pipe_context *pipe, |
const struct pipe_shader_state *templ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct i915_fragment_shader *ifs = CALLOC_STRUCT(i915_fragment_shader); |
if (!ifs) |
return NULL; |
ifs->draw_data = draw_create_fragment_shader(i915->draw, templ); |
ifs->state.tokens = tgsi_dup_tokens(templ->tokens); |
tgsi_scan_shader(templ->tokens, &ifs->info); |
/* The shader's compiled to i915 instructions here */ |
i915_translate_fragment_program(i915, ifs); |
return ifs; |
} |
static void |
i915_bind_fs_state(struct pipe_context *pipe, void *shader) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (i915->fs == shader) |
return; |
i915->fs = (struct i915_fragment_shader*) shader; |
draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL)); |
i915->dirty |= I915_NEW_FS; |
} |
static |
void i915_delete_fs_state(struct pipe_context *pipe, void *shader) |
{ |
struct i915_fragment_shader *ifs = (struct i915_fragment_shader *) shader; |
FREE(ifs->decl); |
ifs->decl = NULL; |
FREE(ifs->program); |
ifs->program = NULL; |
FREE((struct tgsi_token *)ifs->state.tokens); |
ifs->state.tokens = NULL; |
ifs->program_len = 0; |
ifs->decl_len = 0; |
FREE(ifs); |
} |
static void * |
i915_create_vs_state(struct pipe_context *pipe, |
const struct pipe_shader_state *templ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
/* just pass-through to draw module */ |
return draw_create_vertex_shader(i915->draw, templ); |
} |
static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (i915->vs == shader) |
return; |
i915->vs = shader; |
/* just pass-through to draw module */ |
draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); |
i915->dirty |= I915_NEW_VS; |
} |
static void i915_delete_vs_state(struct pipe_context *pipe, void *shader) |
{ |
struct i915_context *i915 = i915_context(pipe); |
/* just pass-through to draw module */ |
draw_delete_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); |
} |
static void i915_set_constant_buffer(struct pipe_context *pipe, |
uint shader, uint index, |
struct pipe_constant_buffer *cb) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct pipe_resource *buf = cb ? cb->buffer : NULL; |
unsigned new_num = 0; |
boolean diff = TRUE; |
/* XXX don't support geom shaders now */ |
if (shader == PIPE_SHADER_GEOMETRY) |
return; |
if (cb && cb->user_buffer) { |
buf = i915_user_buffer_create(pipe->screen, (void *) cb->user_buffer, |
cb->buffer_size, |
PIPE_BIND_CONSTANT_BUFFER); |
} |
/* if we have a new buffer compare it with the old one */ |
if (buf) { |
struct i915_buffer *ibuf = i915_buffer(buf); |
struct pipe_resource *old_buf = i915->constants[shader]; |
struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL; |
unsigned old_num = i915->current.num_user_constants[shader]; |
new_num = ibuf->b.b.width0 / 4 * sizeof(float); |
if (old_num == new_num) { |
if (old_num == 0) |
diff = FALSE; |
#if 0 |
/* XXX no point in running this code since st/mesa only uses user buffers */ |
/* Can't compare the buffer data since they are userbuffers */ |
else if (old && old->free_on_destroy) |
diff = memcmp(old->data, ibuf->data, ibuf->b.b.width0); |
#else |
(void)old; |
#endif |
} |
} else { |
diff = i915->current.num_user_constants[shader] != 0; |
} |
pipe_resource_reference(&i915->constants[shader], buf); |
i915->current.num_user_constants[shader] = new_num; |
if (diff) |
i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; |
if (cb && cb->user_buffer) { |
pipe_resource_reference(&buf, NULL); |
} |
} |
static void i915_set_fragment_sampler_views(struct pipe_context *pipe, |
unsigned num, |
struct pipe_sampler_view **views) |
{ |
struct i915_context *i915 = i915_context(pipe); |
uint i; |
assert(num <= PIPE_MAX_SAMPLERS); |
/* Check for no-op */ |
if (num == i915->num_fragment_sampler_views && |
!memcmp(i915->fragment_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) |
return; |
for (i = 0; i < num; i++) { |
/* Note: we're using pipe_sampler_view_release() here to work around |
* a possible crash when the old view belongs to another context that |
* was already destroyed. |
*/ |
pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]); |
pipe_sampler_view_reference(&i915->fragment_sampler_views[i], |
views[i]); |
} |
for (i = num; i < i915->num_fragment_sampler_views; i++) |
pipe_sampler_view_release(pipe, &i915->fragment_sampler_views[i]); |
i915->num_fragment_sampler_views = num; |
i915->dirty |= I915_NEW_SAMPLER_VIEW; |
} |
static void |
i915_set_vertex_sampler_views(struct pipe_context *pipe, |
unsigned num, |
struct pipe_sampler_view **views) |
{ |
struct i915_context *i915 = i915_context(pipe); |
uint i; |
assert(num <= Elements(i915->vertex_sampler_views)); |
/* Check for no-op */ |
if (num == i915->num_vertex_sampler_views && |
!memcmp(i915->vertex_sampler_views, views, num * sizeof(struct pipe_sampler_view *))) { |
return; |
} |
for (i = 0; i < Elements(i915->vertex_sampler_views); i++) { |
struct pipe_sampler_view *view = i < num ? views[i] : NULL; |
pipe_sampler_view_reference(&i915->vertex_sampler_views[i], view); |
} |
i915->num_vertex_sampler_views = num; |
draw_set_sampler_views(i915->draw, |
PIPE_SHADER_VERTEX, |
i915->vertex_sampler_views, |
i915->num_vertex_sampler_views); |
} |
static void |
i915_set_sampler_views(struct pipe_context *pipe, unsigned shader, |
unsigned start, unsigned num, |
struct pipe_sampler_view **views) |
{ |
assert(start == 0); |
switch (shader) { |
case PIPE_SHADER_FRAGMENT: |
i915_set_fragment_sampler_views(pipe, num, views); |
break; |
case PIPE_SHADER_VERTEX: |
i915_set_vertex_sampler_views(pipe, num, views); |
break; |
default: |
; |
} |
} |
struct pipe_sampler_view * |
i915_create_sampler_view_custom(struct pipe_context *pipe, |
struct pipe_resource *texture, |
const struct pipe_sampler_view *templ, |
unsigned width0, |
unsigned height0) |
{ |
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); |
if (view) { |
*view = *templ; |
view->reference.count = 1; |
view->texture = NULL; |
pipe_resource_reference(&view->texture, texture); |
view->context = pipe; |
} |
return view; |
} |
static struct pipe_sampler_view * |
i915_create_sampler_view(struct pipe_context *pipe, |
struct pipe_resource *texture, |
const struct pipe_sampler_view *templ) |
{ |
struct pipe_sampler_view *view = CALLOC_STRUCT(pipe_sampler_view); |
if (view) { |
*view = *templ; |
view->reference.count = 1; |
view->texture = NULL; |
pipe_resource_reference(&view->texture, texture); |
view->context = pipe; |
} |
return view; |
} |
static void |
i915_sampler_view_destroy(struct pipe_context *pipe, |
struct pipe_sampler_view *view) |
{ |
pipe_resource_reference(&view->texture, NULL); |
FREE(view); |
} |
static void i915_set_framebuffer_state(struct pipe_context *pipe, |
const struct pipe_framebuffer_state *fb) |
{ |
struct i915_context *i915 = i915_context(pipe); |
int i; |
i915->framebuffer.width = fb->width; |
i915->framebuffer.height = fb->height; |
i915->framebuffer.nr_cbufs = fb->nr_cbufs; |
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { |
pipe_surface_reference(&i915->framebuffer.cbufs[i], |
i < fb->nr_cbufs ? fb->cbufs[i] : NULL); |
} |
pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf); |
i915->dirty |= I915_NEW_FRAMEBUFFER; |
} |
static void i915_set_clip_state( struct pipe_context *pipe, |
const struct pipe_clip_state *clip ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
i915->clip = *clip; |
draw_set_clip_state(i915->draw, clip); |
i915->dirty |= I915_NEW_CLIP; |
} |
/* Called when driver state tracker notices changes to the viewport |
* matrix: |
*/ |
static void i915_set_viewport_states( struct pipe_context *pipe, |
unsigned start_slot, |
unsigned num_viewports, |
const struct pipe_viewport_state *viewport ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
i915->viewport = *viewport; /* struct copy */ |
/* pass the viewport info to the draw module */ |
draw_set_viewport_states(i915->draw, start_slot, num_viewports, |
&i915->viewport); |
i915->dirty |= I915_NEW_VIEWPORT; |
} |
static void * |
i915_create_rasterizer_state(struct pipe_context *pipe, |
const struct pipe_rasterizer_state *rasterizer) |
{ |
struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state ); |
cso->templ = *rasterizer; |
cso->color_interp = rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; |
cso->light_twoside = rasterizer->light_twoside; |
cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE; |
cso->ds[1].f = rasterizer->offset_scale; |
if (rasterizer->poly_stipple_enable) { |
cso->st |= ST1_ENABLE; |
} |
if (rasterizer->scissor) |
cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | ENABLE_SCISSOR_RECT; |
else |
cso->sc[0] = _3DSTATE_SCISSOR_ENABLE_CMD | DISABLE_SCISSOR_RECT; |
switch (rasterizer->cull_face) { |
case PIPE_FACE_NONE: |
cso->LIS4 |= S4_CULLMODE_NONE; |
break; |
case PIPE_FACE_FRONT: |
if (rasterizer->front_ccw) |
cso->LIS4 |= S4_CULLMODE_CCW; |
else |
cso->LIS4 |= S4_CULLMODE_CW; |
break; |
case PIPE_FACE_BACK: |
if (rasterizer->front_ccw) |
cso->LIS4 |= S4_CULLMODE_CW; |
else |
cso->LIS4 |= S4_CULLMODE_CCW; |
break; |
case PIPE_FACE_FRONT_AND_BACK: |
cso->LIS4 |= S4_CULLMODE_BOTH; |
break; |
} |
{ |
int line_width = CLAMP((int)(rasterizer->line_width * 2), 1, 0xf); |
cso->LIS4 |= line_width << S4_LINE_WIDTH_SHIFT; |
if (rasterizer->line_smooth) |
cso->LIS4 |= S4_LINE_ANTIALIAS_ENABLE; |
} |
{ |
int point_size = CLAMP((int) rasterizer->point_size, 1, 0xff); |
cso->LIS4 |= point_size << S4_POINT_WIDTH_SHIFT; |
} |
if (rasterizer->flatshade) { |
cso->LIS4 |= (S4_FLATSHADE_ALPHA | |
S4_FLATSHADE_COLOR | |
S4_FLATSHADE_SPECULAR); |
} |
cso->LIS7 = fui( rasterizer->offset_units ); |
return cso; |
} |
static void i915_bind_rasterizer_state( struct pipe_context *pipe, |
void *raster ) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (i915->rasterizer == raster) |
return; |
i915->rasterizer = (struct i915_rasterizer_state *)raster; |
/* pass-through to draw module */ |
draw_set_rasterizer_state(i915->draw, |
(i915->rasterizer ? &(i915->rasterizer->templ) : NULL), |
raster); |
i915->dirty |= I915_NEW_RASTERIZER; |
} |
static void i915_delete_rasterizer_state(struct pipe_context *pipe, |
void *raster) |
{ |
FREE(raster); |
} |
static void i915_set_vertex_buffers(struct pipe_context *pipe, |
unsigned start_slot, unsigned count, |
const struct pipe_vertex_buffer *buffers) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct draw_context *draw = i915->draw; |
util_set_vertex_buffers_count(i915->vertex_buffers, |
&i915->nr_vertex_buffers, |
buffers, start_slot, count); |
/* pass-through to draw module */ |
draw_set_vertex_buffers(draw, start_slot, count, buffers); |
} |
static void * |
i915_create_vertex_elements_state(struct pipe_context *pipe, |
unsigned count, |
const struct pipe_vertex_element *attribs) |
{ |
struct i915_velems_state *velems; |
assert(count <= PIPE_MAX_ATTRIBS); |
velems = (struct i915_velems_state *) MALLOC(sizeof(struct i915_velems_state)); |
if (velems) { |
velems->count = count; |
memcpy(velems->velem, attribs, sizeof(*attribs) * count); |
} |
return velems; |
} |
static void |
i915_bind_vertex_elements_state(struct pipe_context *pipe, |
void *velems) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems; |
if (i915->velems == velems) |
return; |
i915->velems = velems; |
/* pass-through to draw module */ |
if (i915_velems) { |
draw_set_vertex_elements(i915->draw, |
i915_velems->count, i915_velems->velem); |
} |
} |
static void |
i915_delete_vertex_elements_state(struct pipe_context *pipe, void *velems) |
{ |
FREE( velems ); |
} |
static void i915_set_index_buffer(struct pipe_context *pipe, |
const struct pipe_index_buffer *ib) |
{ |
struct i915_context *i915 = i915_context(pipe); |
if (ib) |
memcpy(&i915->index_buffer, ib, sizeof(i915->index_buffer)); |
else |
memset(&i915->index_buffer, 0, sizeof(i915->index_buffer)); |
} |
static void |
i915_set_sample_mask(struct pipe_context *pipe, |
unsigned sample_mask) |
{ |
} |
void |
i915_init_state_functions( struct i915_context *i915 ) |
{ |
i915->base.create_blend_state = i915_create_blend_state; |
i915->base.bind_blend_state = i915_bind_blend_state; |
i915->base.delete_blend_state = i915_delete_blend_state; |
i915->base.create_sampler_state = i915_create_sampler_state; |
i915->base.bind_sampler_states = i915_bind_sampler_states; |
i915->base.delete_sampler_state = i915_delete_sampler_state; |
i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state; |
i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state; |
i915->base.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state; |
i915->base.create_rasterizer_state = i915_create_rasterizer_state; |
i915->base.bind_rasterizer_state = i915_bind_rasterizer_state; |
i915->base.delete_rasterizer_state = i915_delete_rasterizer_state; |
i915->base.create_fs_state = i915_create_fs_state; |
i915->base.bind_fs_state = i915_bind_fs_state; |
i915->base.delete_fs_state = i915_delete_fs_state; |
i915->base.create_vs_state = i915_create_vs_state; |
i915->base.bind_vs_state = i915_bind_vs_state; |
i915->base.delete_vs_state = i915_delete_vs_state; |
i915->base.create_vertex_elements_state = i915_create_vertex_elements_state; |
i915->base.bind_vertex_elements_state = i915_bind_vertex_elements_state; |
i915->base.delete_vertex_elements_state = i915_delete_vertex_elements_state; |
i915->base.set_blend_color = i915_set_blend_color; |
i915->base.set_stencil_ref = i915_set_stencil_ref; |
i915->base.set_clip_state = i915_set_clip_state; |
i915->base.set_sample_mask = i915_set_sample_mask; |
i915->base.set_constant_buffer = i915_set_constant_buffer; |
i915->base.set_framebuffer_state = i915_set_framebuffer_state; |
i915->base.set_polygon_stipple = i915_set_polygon_stipple; |
i915->base.set_scissor_states = i915_set_scissor_states; |
i915->base.set_sampler_views = i915_set_sampler_views; |
i915->base.create_sampler_view = i915_create_sampler_view; |
i915->base.sampler_view_destroy = i915_sampler_view_destroy; |
i915->base.set_viewport_states = i915_set_viewport_states; |
i915->base.set_vertex_buffers = i915_set_vertex_buffers; |
i915->base.set_index_buffer = i915_set_index_buffer; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state.h |
---|
0,0 → 1,63 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* Authors: Keith Whitwell <keithw@vmware.com> |
*/ |
#ifndef I915_STATE_H |
#define I915_STATE_H |
struct i915_context; |
struct i915_tracked_state { |
const char *name; |
void (*update)(struct i915_context *); |
unsigned dirty; |
}; |
extern struct i915_tracked_state i915_update_vertex_layout; |
extern struct i915_tracked_state i915_hw_samplers; |
extern struct i915_tracked_state i915_hw_sampler_views; |
extern struct i915_tracked_state i915_hw_immediate; |
extern struct i915_tracked_state i915_hw_dynamic; |
extern struct i915_tracked_state i915_hw_fs; |
extern struct i915_tracked_state i915_hw_framebuffer; |
extern struct i915_tracked_state i915_hw_dst_buf_vars; |
extern struct i915_tracked_state i915_hw_constants; |
void i915_update_derived(struct i915_context *i915); |
void i915_emit_hardware_state(struct i915_context *i915); |
struct pipe_sampler_view * |
i915_create_sampler_view_custom(struct pipe_context *pipe, |
struct pipe_resource *texture, |
const struct pipe_sampler_view *templ, |
unsigned width0, |
unsigned height0); |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_derived.c |
---|
0,0 → 1,220 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "util/u_memory.h" |
#include "pipe/p_shader_tokens.h" |
#include "draw/draw_context.h" |
#include "draw/draw_vertex.h" |
#include "i915_context.h" |
#include "i915_state.h" |
#include "i915_debug.h" |
#include "i915_fpc.h" |
#include "i915_reg.h" |
static uint find_mapping(const struct i915_fragment_shader* fs, int unit) |
{ |
int i; |
for (i = 0; i < I915_TEX_UNITS ; i++) |
{ |
if (fs->generic_mapping[i] == unit) |
return i; |
} |
debug_printf("Mapping not found\n"); |
return 0; |
} |
/*********************************************************************** |
* Determine the hardware vertex layout. |
* Depends on vertex/fragment shader state. |
*/ |
static void calculate_vertex_layout(struct i915_context *i915) |
{ |
const struct i915_fragment_shader *fs = i915->fs; |
const enum interp_mode colorInterp = i915->rasterizer->color_interp; |
struct vertex_info vinfo; |
boolean texCoords[I915_TEX_UNITS], colors[2], fog, needW, face; |
uint i; |
int src; |
memset(texCoords, 0, sizeof(texCoords)); |
colors[0] = colors[1] = fog = needW = face = FALSE; |
memset(&vinfo, 0, sizeof(vinfo)); |
/* Determine which fragment program inputs are needed. Setup HW vertex |
* layout below, in the HW-specific attribute order. |
*/ |
for (i = 0; i < fs->info.num_inputs; i++) { |
switch (fs->info.input_semantic_name[i]) { |
case TGSI_SEMANTIC_POSITION: |
{ |
uint unit = I915_SEMANTIC_POS; |
texCoords[find_mapping(fs, unit)] = TRUE; |
} |
break; |
case TGSI_SEMANTIC_COLOR: |
assert(fs->info.input_semantic_index[i] < 2); |
colors[fs->info.input_semantic_index[i]] = TRUE; |
break; |
case TGSI_SEMANTIC_GENERIC: |
{ |
/* texcoords/varyings/other generic */ |
uint unit = fs->info.input_semantic_index[i]; |
texCoords[find_mapping(fs, unit)] = TRUE; |
needW = TRUE; |
} |
break; |
case TGSI_SEMANTIC_FOG: |
fog = TRUE; |
break; |
case TGSI_SEMANTIC_FACE: |
face = TRUE; |
break; |
default: |
debug_printf("Unknown input type %d\n", fs->info.input_semantic_name[i]); |
assert(0); |
} |
} |
/* pos */ |
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_POSITION, 0); |
if (needW) { |
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_LINEAR, src); |
vinfo.hwfmt[0] |= S4_VFMT_XYZW; |
vinfo.attrib[0].emit = EMIT_4F; |
} |
else { |
draw_emit_vertex_attr(&vinfo, EMIT_3F, INTERP_LINEAR, src); |
vinfo.hwfmt[0] |= S4_VFMT_XYZ; |
vinfo.attrib[0].emit = EMIT_3F; |
} |
/* hardware point size */ |
/* XXX todo */ |
/* primary color */ |
if (colors[0]) { |
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 0); |
draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src); |
vinfo.hwfmt[0] |= S4_VFMT_COLOR; |
} |
/* secondary color */ |
if (colors[1]) { |
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_COLOR, 1); |
draw_emit_vertex_attr(&vinfo, EMIT_4UB_BGRA, colorInterp, src); |
vinfo.hwfmt[0] |= S4_VFMT_SPEC_FOG; |
} |
/* fog coord, not fog blend factor */ |
if (fog) { |
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FOG, 0); |
draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_PERSPECTIVE, src); |
vinfo.hwfmt[0] |= S4_VFMT_FOG_PARAM; |
} |
/* texcoords/varyings */ |
for (i = 0; i < I915_TEX_UNITS; i++) { |
uint hwtc; |
if (texCoords[i]) { |
hwtc = TEXCOORDFMT_4D; |
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_GENERIC, fs->generic_mapping[i]); |
draw_emit_vertex_attr(&vinfo, EMIT_4F, INTERP_PERSPECTIVE, src); |
} |
else { |
hwtc = TEXCOORDFMT_NOT_PRESENT; |
} |
vinfo.hwfmt[1] |= hwtc << (i * 4); |
} |
/* front/back face */ |
if (face) { |
uint slot = find_mapping(fs, I915_SEMANTIC_FACE); |
debug_printf("Front/back face is broken\n"); |
/* XXX Because of limitations in the draw module, currently src will be 0 |
* for SEMANTIC_FACE, so this aliases to POS. We need to fix in the draw |
* module by adding an extra shader output. |
*/ |
src = draw_find_shader_output(i915->draw, TGSI_SEMANTIC_FACE, 0); |
draw_emit_vertex_attr(&vinfo, EMIT_1F, INTERP_CONSTANT, src); |
vinfo.hwfmt[1] &= ~(TEXCOORDFMT_NOT_PRESENT << (slot * 4)); |
vinfo.hwfmt[1] |= TEXCOORDFMT_1D << (slot * 4); |
} |
draw_compute_vertex_size(&vinfo); |
if (memcmp(&i915->current.vertex_info, &vinfo, sizeof(vinfo))) { |
/* Need to set this flag so that the LIS2/4 registers get set. |
* It also means the i915_update_immediate() function must be called |
* after this one, in i915_update_derived(). |
*/ |
i915->dirty |= I915_NEW_VERTEX_FORMAT; |
memcpy(&i915->current.vertex_info, &vinfo, sizeof(vinfo)); |
} |
} |
struct i915_tracked_state i915_update_vertex_layout = { |
"vertex_layout", |
calculate_vertex_layout, |
I915_NEW_RASTERIZER | I915_NEW_FS | I915_NEW_VS |
}; |
/*********************************************************************** |
*/ |
static struct i915_tracked_state *atoms[] = { |
&i915_update_vertex_layout, |
&i915_hw_samplers, |
&i915_hw_sampler_views, |
&i915_hw_immediate, |
&i915_hw_dynamic, |
&i915_hw_fs, |
&i915_hw_framebuffer, |
&i915_hw_dst_buf_vars, |
&i915_hw_constants, |
NULL, |
}; |
void i915_update_derived(struct i915_context *i915) |
{ |
int i; |
if (I915_DBG_ON(DBG_ATOMS)) |
i915_dump_dirty(i915, __FUNCTION__); |
for (i = 0; atoms[i]; i++) |
if (atoms[i]->dirty & i915->dirty) |
atoms[i]->update(i915); |
i915->dirty = 0; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_dynamic.c |
---|
0,0 → 1,319 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_batch.h" |
#include "i915_state_inlines.h" |
#include "i915_context.h" |
#include "i915_reg.h" |
#include "i915_state.h" |
#include "util/u_memory.h" |
#include "util/u_pack_color.h" |
/* State that we have chosen to store in the DYNAMIC segment of the |
* i915 indirect state mechanism. |
* |
* Can't cache these in the way we do the static state, as there is no |
* start/size in the command packet, instead an 'end' value that gets |
* incremented. |
* |
* Additionally, there seems to be a requirement to re-issue the full |
* (active) state every time a 4kb boundary is crossed. |
*/ |
static INLINE void set_dynamic(struct i915_context *i915, |
unsigned offset, |
const unsigned state) |
{ |
if (i915->current.dynamic[offset] == state) |
return; |
i915->current.dynamic[offset] = state; |
i915->dynamic_dirty |= 1 << offset; |
i915->hardware_dirty |= I915_HW_DYNAMIC; |
} |
static INLINE void set_dynamic_array(struct i915_context *i915, |
unsigned offset, |
const unsigned *src, |
unsigned dwords) |
{ |
unsigned i; |
if (!memcmp(src, &i915->current.dynamic[offset], dwords * 4)) |
return; |
for (i = 0; i < dwords; i++) { |
i915->current.dynamic[offset + i] = src[i]; |
i915->dynamic_dirty |= 1 << (offset + i); |
} |
i915->hardware_dirty |= I915_HW_DYNAMIC; |
} |
/*********************************************************************** |
* Modes4: stencil masks and logicop |
*/ |
static void upload_MODES4(struct i915_context *i915) |
{ |
unsigned modes4 = 0; |
/* I915_NEW_STENCIL |
*/ |
modes4 |= i915->depth_stencil->stencil_modes4; |
/* I915_NEW_BLEND |
*/ |
modes4 |= i915->blend->modes4; |
set_dynamic(i915, I915_DYNAMIC_MODES4, modes4); |
} |
const struct i915_tracked_state i915_upload_MODES4 = { |
"MODES4", |
upload_MODES4, |
I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL |
}; |
/*********************************************************************** |
*/ |
static void upload_BFO(struct i915_context *i915) |
{ |
unsigned bfo[2]; |
bfo[0] = i915->depth_stencil->bfo[0]; |
bfo[1] = i915->depth_stencil->bfo[1]; |
/* I don't get it only allowed to set a ref mask when the enable bit is set? */ |
if (bfo[0] & BFO_ENABLE_STENCIL_REF) { |
bfo[0] |= i915->stencil_ref.ref_value[1] << BFO_STENCIL_REF_SHIFT; |
} |
set_dynamic_array(i915, I915_DYNAMIC_BFO_0, bfo, 2); |
} |
const struct i915_tracked_state i915_upload_BFO = { |
"BFO", |
upload_BFO, |
I915_NEW_DEPTH_STENCIL |
}; |
/*********************************************************************** |
*/ |
static void upload_BLENDCOLOR(struct i915_context *i915) |
{ |
unsigned bc[2]; |
memset(bc, 0, sizeof(bc)); |
/* I915_NEW_BLEND |
*/ |
{ |
const float *color = i915->blend_color.color; |
bc[0] = _3DSTATE_CONST_BLEND_COLOR_CMD; |
bc[1] = pack_ui32_float4(color[0], |
color[1], |
color[2], |
color[3]); |
} |
set_dynamic_array(i915, I915_DYNAMIC_BC_0, bc, 2); |
} |
const struct i915_tracked_state i915_upload_BLENDCOLOR = { |
"BLENDCOLOR", |
upload_BLENDCOLOR, |
I915_NEW_BLEND |
}; |
/*********************************************************************** |
*/ |
static void upload_IAB(struct i915_context *i915) |
{ |
unsigned iab = i915->blend->iab; |
set_dynamic(i915, I915_DYNAMIC_IAB, iab); |
} |
const struct i915_tracked_state i915_upload_IAB = { |
"IAB", |
upload_IAB, |
I915_NEW_BLEND |
}; |
/*********************************************************************** |
*/ |
static void upload_DEPTHSCALE(struct i915_context *i915) |
{ |
set_dynamic_array(i915, I915_DYNAMIC_DEPTHSCALE_0, |
&i915->rasterizer->ds[0].u, 2); |
} |
const struct i915_tracked_state i915_upload_DEPTHSCALE = { |
"DEPTHSCALE", |
upload_DEPTHSCALE, |
I915_NEW_RASTERIZER |
}; |
/*********************************************************************** |
* Polygon stipple |
* |
* The i915 supports a 4x4 stipple natively, GL wants 32x32. |
* Fortunately stipple is usually a repeating pattern. |
* |
* XXX: does stipple pattern need to be adjusted according to |
* the window position? |
* |
* XXX: possibly need workaround for conform paths test. |
*/ |
static void upload_STIPPLE(struct i915_context *i915) |
{ |
unsigned st[2]; |
st[0] = _3DSTATE_STIPPLE; |
st[1] = 0; |
/* I915_NEW_RASTERIZER |
*/ |
st[1] |= i915->rasterizer->st; |
/* I915_NEW_STIPPLE |
*/ |
{ |
const ubyte *mask = (const ubyte *)i915->poly_stipple.stipple; |
ubyte p[4]; |
p[0] = mask[12] & 0xf; |
p[1] = mask[8] & 0xf; |
p[2] = mask[4] & 0xf; |
p[3] = mask[0] & 0xf; |
/* Not sure what to do about fallbacks, so for now just dont: |
*/ |
st[1] |= ((p[0] << 0) | |
(p[1] << 4) | |
(p[2] << 8) | |
(p[3] << 12)); |
} |
set_dynamic_array(i915, I915_DYNAMIC_STP_0, st, 2); |
} |
const struct i915_tracked_state i915_upload_STIPPLE = { |
"STIPPLE", |
upload_STIPPLE, |
I915_NEW_RASTERIZER | I915_NEW_STIPPLE |
}; |
/*********************************************************************** |
* Scissor enable |
*/ |
static void upload_SCISSOR_ENABLE( struct i915_context *i915 ) |
{ |
set_dynamic(i915, I915_DYNAMIC_SC_ENA_0, i915->rasterizer->sc[0]); |
} |
const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = { |
"SCISSOR ENABLE", |
upload_SCISSOR_ENABLE, |
I915_NEW_RASTERIZER |
}; |
/*********************************************************************** |
* Scissor rect |
*/ |
static void upload_SCISSOR_RECT(struct i915_context *i915) |
{ |
unsigned x1 = i915->scissor.minx; |
unsigned y1 = i915->scissor.miny; |
unsigned x2 = i915->scissor.maxx - 1; |
unsigned y2 = i915->scissor.maxy - 1; |
unsigned sc[3]; |
sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD; |
sc[1] = (y1 << 16) | (x1 & 0xffff); |
sc[2] = (y2 << 16) | (x2 & 0xffff); |
set_dynamic_array(i915, I915_DYNAMIC_SC_RECT_0, sc, 3); |
} |
const struct i915_tracked_state i915_upload_SCISSOR_RECT = { |
"SCISSOR RECT", |
upload_SCISSOR_RECT, |
I915_NEW_SCISSOR |
}; |
/*********************************************************************** |
*/ |
static const struct i915_tracked_state *atoms[] = { |
&i915_upload_MODES4, |
&i915_upload_BFO, |
&i915_upload_BLENDCOLOR, |
&i915_upload_IAB, |
&i915_upload_DEPTHSCALE, |
&i915_upload_STIPPLE, |
&i915_upload_SCISSOR_ENABLE, |
&i915_upload_SCISSOR_RECT |
}; |
/* These will be dynamic indirect state commands, but for now just end |
* up on the batch buffer with everything else. |
*/ |
static void update_dynamic(struct i915_context *i915) |
{ |
int i; |
for (i = 0; i < Elements(atoms); i++) |
if (i915->dirty & atoms[i]->dirty) |
atoms[i]->update(i915); |
} |
struct i915_tracked_state i915_hw_dynamic = { |
"dynamic", |
update_dynamic, |
~0 /* all state atoms, because we do internal checking */ |
}; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_emit.c |
---|
0,0 → 1,589 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_reg.h" |
#include "i915_context.h" |
#include "i915_batch.h" |
#include "i915_debug.h" |
#include "i915_fpc.h" |
#include "i915_resource.h" |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "pipe/p_format.h" |
#include "util/u_format.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
struct i915_tracked_hw_state { |
const char *name; |
void (*validate)(struct i915_context *, unsigned *batch_space); |
void (*emit)(struct i915_context *); |
unsigned dirty, batch_space; |
}; |
static void |
validate_flush(struct i915_context *i915, unsigned *batch_space) |
{ |
*batch_space = i915->flush_dirty ? 1 : 0; |
} |
static void |
emit_flush(struct i915_context *i915) |
{ |
/* Cache handling is very cheap atm. State handling can request to flushes: |
* - I915_FLUSH_CACHE which is a flush everything request and |
* - I915_PIPELINE_FLUSH which is specifically for the draw_offset flush. |
* Because the cache handling is so dumb, no explicit "invalidate map cache". |
* Also, the first is a strict superset of the latter, so the following logic |
* works. */ |
if (i915->flush_dirty & I915_FLUSH_CACHE) |
OUT_BATCH(MI_FLUSH | FLUSH_MAP_CACHE); |
else if (i915->flush_dirty & I915_PIPELINE_FLUSH) |
OUT_BATCH(MI_FLUSH | INHIBIT_FLUSH_RENDER_CACHE); |
} |
uint32_t invariant_state[] = { |
_3DSTATE_AA_CMD | AA_LINE_ECAAR_WIDTH_ENABLE | AA_LINE_ECAAR_WIDTH_1_0 | |
AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0, |
_3DSTATE_DFLT_DIFFUSE_CMD, 0, |
_3DSTATE_DFLT_SPEC_CMD, 0, |
_3DSTATE_DFLT_Z_CMD, 0, |
_3DSTATE_COORD_SET_BINDINGS | |
CSB_TCB(0, 0) | |
CSB_TCB(1, 1) | |
CSB_TCB(2, 2) | |
CSB_TCB(3, 3) | |
CSB_TCB(4, 4) | |
CSB_TCB(5, 5) | |
CSB_TCB(6, 6) | |
CSB_TCB(7, 7), |
_3DSTATE_RASTER_RULES_CMD | |
ENABLE_POINT_RASTER_RULE | |
OGL_POINT_RASTER_RULE | |
ENABLE_LINE_STRIP_PROVOKE_VRTX | |
ENABLE_TRI_FAN_PROVOKE_VRTX | |
LINE_STRIP_PROVOKE_VRTX(1) | |
TRI_FAN_PROVOKE_VRTX(2) | |
ENABLE_TEXKILL_3D_4D | |
TEXKILL_4D, |
_3DSTATE_DEPTH_SUBRECT_DISABLE, |
/* disable indirect state for now |
*/ |
_3DSTATE_LOAD_INDIRECT | 0, 0}; |
static void |
emit_invariant(struct i915_context *i915) |
{ |
i915_winsys_batchbuffer_write(i915->batch, invariant_state, |
Elements(invariant_state)*sizeof(uint32_t)); |
} |
static void |
validate_immediate(struct i915_context *i915, unsigned *batch_space) |
{ |
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 | |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 | |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 | |
1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) & |
i915->immediate_dirty; |
if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0) && i915->vbo) |
i915->validation_buffers[i915->num_validation_buffers++] = i915->vbo; |
*batch_space = 1 + util_bitcount(dirty); |
} |
static uint target_fixup(struct pipe_surface *p, int component) |
{ |
const struct |
{ |
enum pipe_format format; |
uint hw_mask[4]; |
} fixup_mask[] = { |
{ PIPE_FORMAT_R8G8B8A8_UNORM, { S5_WRITEDISABLE_BLUE, S5_WRITEDISABLE_GREEN, S5_WRITEDISABLE_RED, S5_WRITEDISABLE_ALPHA}}, |
{ PIPE_FORMAT_R8G8B8X8_UNORM, { S5_WRITEDISABLE_BLUE, S5_WRITEDISABLE_GREEN, S5_WRITEDISABLE_RED, S5_WRITEDISABLE_ALPHA}}, |
{ PIPE_FORMAT_L8_UNORM, { S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE, 0, 0, S5_WRITEDISABLE_ALPHA}}, |
{ PIPE_FORMAT_I8_UNORM, { S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE, 0, 0, S5_WRITEDISABLE_ALPHA}}, |
{ PIPE_FORMAT_A8_UNORM, { 0, 0, 0, S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA}}, |
{ 0, { S5_WRITEDISABLE_RED, S5_WRITEDISABLE_GREEN, S5_WRITEDISABLE_BLUE, S5_WRITEDISABLE_ALPHA}} |
}; |
int i = sizeof(fixup_mask) / sizeof(*fixup_mask) - 1; |
if (p) |
for(i = 0; fixup_mask[i].format != 0; i++) |
if (p->format == fixup_mask[i].format) |
return fixup_mask[i].hw_mask[component]; |
/* Just return default masks */ |
return fixup_mask[i].hw_mask[component]; |
} |
static void emit_immediate_s5(struct i915_context *i915, uint imm) |
{ |
/* Fixup write mask for non-BGRA render targets */ |
uint fixup_imm = imm & ~( S5_WRITEDISABLE_RED | S5_WRITEDISABLE_GREEN | |
S5_WRITEDISABLE_BLUE | S5_WRITEDISABLE_ALPHA ); |
struct pipe_surface *surf = i915->framebuffer.cbufs[0]; |
if (imm & S5_WRITEDISABLE_RED) |
fixup_imm |= target_fixup(surf, 0); |
if (imm & S5_WRITEDISABLE_GREEN) |
fixup_imm |= target_fixup(surf, 1); |
if (imm & S5_WRITEDISABLE_BLUE) |
fixup_imm |= target_fixup(surf, 2); |
if (imm & S5_WRITEDISABLE_ALPHA) |
fixup_imm |= target_fixup(surf, 3); |
OUT_BATCH(fixup_imm); |
} |
static void emit_immediate_s6(struct i915_context *i915, uint imm) |
{ |
/* Fixup blend function for A8 dst buffers. |
* When we blend to an A8 buffer, the GPU thinks it's a G8 buffer, |
* and therefore we need to use the color factor for alphas. */ |
uint srcRGB; |
if (i915->current.target_fixup_format == PIPE_FORMAT_A8_UNORM) { |
srcRGB = (imm >> S6_CBUF_SRC_BLEND_FACT_SHIFT) & BLENDFACT_MASK; |
if (srcRGB == BLENDFACT_DST_ALPHA) |
srcRGB = BLENDFACT_DST_COLR; |
else if (srcRGB == BLENDFACT_INV_DST_ALPHA) |
srcRGB = BLENDFACT_INV_DST_COLR; |
imm &= ~SRC_BLND_FACT(BLENDFACT_MASK); |
imm |= SRC_BLND_FACT(srcRGB); |
} |
OUT_BATCH(imm); |
} |
static void |
emit_immediate(struct i915_context *i915) |
{ |
/* remove unwanted bits and S7 */ |
unsigned dirty = (1 << I915_IMMEDIATE_S0 | 1 << I915_IMMEDIATE_S1 | |
1 << I915_IMMEDIATE_S2 | 1 << I915_IMMEDIATE_S3 | |
1 << I915_IMMEDIATE_S3 | 1 << I915_IMMEDIATE_S4 | |
1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) & |
i915->immediate_dirty; |
int i, num = util_bitcount(dirty); |
assert(num && num <= I915_MAX_IMMEDIATE); |
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | |
dirty << 4 | (num - 1)); |
if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0)) { |
if (i915->vbo) |
OUT_RELOC(i915->vbo, I915_USAGE_VERTEX, |
i915->current.immediate[I915_IMMEDIATE_S0]); |
else |
OUT_BATCH(0); |
} |
for (i = 1; i < I915_MAX_IMMEDIATE; i++) { |
if (dirty & (1 << i)) { |
if (i == I915_IMMEDIATE_S5) |
emit_immediate_s5(i915, i915->current.immediate[i]); |
else if (i == I915_IMMEDIATE_S6) |
emit_immediate_s6(i915, i915->current.immediate[i]); |
else |
OUT_BATCH(i915->current.immediate[i]); |
} |
} |
} |
static void |
validate_dynamic(struct i915_context *i915, unsigned *batch_space) |
{ |
*batch_space = util_bitcount(i915->dynamic_dirty & ((1 << I915_MAX_DYNAMIC) - 1)); |
} |
static void |
emit_dynamic(struct i915_context *i915) |
{ |
int i; |
for (i = 0; i < I915_MAX_DYNAMIC; i++) { |
if (i915->dynamic_dirty & (1 << i)) |
OUT_BATCH(i915->current.dynamic[i]); |
} |
} |
static void |
validate_static(struct i915_context *i915, unsigned *batch_space) |
{ |
*batch_space = 0; |
if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { |
i915->validation_buffers[i915->num_validation_buffers++] |
= i915->current.cbuf_bo; |
*batch_space += 3; |
} |
if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) { |
i915->validation_buffers[i915->num_validation_buffers++] |
= i915->current.depth_bo; |
*batch_space += 3; |
} |
if (i915->static_dirty & I915_DST_VARS) |
*batch_space += 2; |
if (i915->static_dirty & I915_DST_RECT) |
*batch_space += 5; |
} |
static void |
emit_static(struct i915_context *i915) |
{ |
if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { |
OUT_BATCH(_3DSTATE_BUF_INFO_CMD); |
OUT_BATCH(i915->current.cbuf_flags); |
OUT_RELOC(i915->current.cbuf_bo, |
I915_USAGE_RENDER, |
0); |
} |
/* What happens if no zbuf?? |
*/ |
if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) { |
OUT_BATCH(_3DSTATE_BUF_INFO_CMD); |
OUT_BATCH(i915->current.depth_flags); |
OUT_RELOC(i915->current.depth_bo, |
I915_USAGE_RENDER, |
0); |
} |
if (i915->static_dirty & I915_DST_VARS) { |
OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); |
OUT_BATCH(i915->current.dst_buf_vars); |
} |
} |
static void |
validate_map(struct i915_context *i915, unsigned *batch_space) |
{ |
const uint enabled = i915->current.sampler_enable_flags; |
uint unit; |
struct i915_texture *tex; |
*batch_space = i915->current.sampler_enable_nr ? |
2 + 3*i915->current.sampler_enable_nr : 0; |
for (unit = 0; unit < I915_TEX_UNITS; unit++) { |
if (enabled & (1 << unit)) { |
tex = i915_texture(i915->fragment_sampler_views[unit]->texture); |
i915->validation_buffers[i915->num_validation_buffers++] = tex->buffer; |
} |
} |
} |
static void |
emit_map(struct i915_context *i915) |
{ |
const uint nr = i915->current.sampler_enable_nr; |
if (nr) { |
const uint enabled = i915->current.sampler_enable_flags; |
uint unit; |
uint count = 0; |
OUT_BATCH(_3DSTATE_MAP_STATE | (3 * nr)); |
OUT_BATCH(enabled); |
for (unit = 0; unit < I915_TEX_UNITS; unit++) { |
if (enabled & (1 << unit)) { |
struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); |
struct i915_winsys_buffer *buf = texture->buffer; |
unsigned offset = i915->current.texbuffer[unit][2]; |
assert(buf); |
count++; |
OUT_RELOC(buf, I915_USAGE_SAMPLER, offset); |
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */ |
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */ |
} |
} |
assert(count == nr); |
} |
} |
static void |
validate_sampler(struct i915_context *i915, unsigned *batch_space) |
{ |
*batch_space = i915->current.sampler_enable_nr ? |
2 + 3*i915->current.sampler_enable_nr : 0; |
} |
static void |
emit_sampler(struct i915_context *i915) |
{ |
if (i915->current.sampler_enable_nr) { |
int i; |
OUT_BATCH( _3DSTATE_SAMPLER_STATE | |
(3 * i915->current.sampler_enable_nr) ); |
OUT_BATCH( i915->current.sampler_enable_flags ); |
for (i = 0; i < I915_TEX_UNITS; i++) { |
if (i915->current.sampler_enable_flags & (1<<i)) { |
OUT_BATCH( i915->current.sampler[i][0] ); |
OUT_BATCH( i915->current.sampler[i][1] ); |
OUT_BATCH( i915->current.sampler[i][2] ); |
} |
} |
} |
} |
static void |
validate_constants(struct i915_context *i915, unsigned *batch_space) |
{ |
int nr = i915->fs->num_constants ? |
2 + 4*i915->fs->num_constants : 0; |
*batch_space = nr; |
} |
static void |
emit_constants(struct i915_context *i915) |
{ |
/* Collate the user-defined constants with the fragment shader's |
* immediates according to the constant_flags[] array. |
*/ |
const uint nr = i915->fs->num_constants; |
assert(nr < I915_MAX_CONSTANT); |
if (nr) { |
uint i; |
OUT_BATCH( _3DSTATE_PIXEL_SHADER_CONSTANTS | (nr * 4) ); |
OUT_BATCH((1 << nr) - 1); |
for (i = 0; i < nr; i++) { |
const uint *c; |
if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) { |
/* grab user-defined constant */ |
c = (uint *) i915_buffer(i915->constants[PIPE_SHADER_FRAGMENT])->data; |
c += 4 * i; |
} |
else { |
/* emit program constant */ |
c = (uint *) i915->fs->constants[i]; |
} |
#if 0 /* debug */ |
{ |
float *f = (float *) c; |
printf("Const %2d: %f %f %f %f %s\n", i, f[0], f[1], f[2], f[3], |
(i915->fs->constant_flags[i] == I915_CONSTFLAG_USER |
? "user" : "immediate")); |
} |
#endif |
OUT_BATCH(*c++); |
OUT_BATCH(*c++); |
OUT_BATCH(*c++); |
OUT_BATCH(*c++); |
} |
} |
} |
static void |
validate_program(struct i915_context *i915, unsigned *batch_space) |
{ |
uint additional_size = 0; |
additional_size += i915->current.target_fixup_format ? 3 : 0; |
/* we need more batch space if we want to emulate rgba framebuffers */ |
*batch_space = i915->fs->decl_len + i915->fs->program_len + additional_size; |
} |
static void |
emit_program(struct i915_context *i915) |
{ |
uint additional_size = 0; |
uint i; |
/* count how much additional space we'll need */ |
validate_program(i915, &additional_size); |
additional_size -= i915->fs->decl_len + i915->fs->program_len; |
/* we should always have, at least, a pass-through program */ |
assert(i915->fs->program_len > 0); |
/* output the declarations */ |
{ |
/* first word has the size, we have to adjust that */ |
uint size = (i915->fs->decl[0]); |
size += additional_size; |
OUT_BATCH(size); |
} |
for (i = 1 ; i < i915->fs->decl_len; i++) |
OUT_BATCH(i915->fs->decl[i]); |
/* output the program */ |
assert(i915->fs->program_len % 3 == 0); |
for (i = 0 ; i < i915->fs->program_len; i+=3) { |
OUT_BATCH(i915->fs->program[i]); |
OUT_BATCH(i915->fs->program[i+1]); |
OUT_BATCH(i915->fs->program[i+2]); |
} |
/* we emit an additional mov with swizzle to fake RGBA framebuffers */ |
if (i915->current.target_fixup_format) { |
/* mov out_color, out_color.zyxw */ |
OUT_BATCH(A0_MOV | |
(REG_TYPE_OC << A0_DEST_TYPE_SHIFT) | |
A0_DEST_CHANNEL_ALL | |
(REG_TYPE_OC << A0_SRC0_TYPE_SHIFT) | |
(T_DIFFUSE << A0_SRC0_NR_SHIFT)); |
OUT_BATCH(i915->current.fixup_swizzle); |
OUT_BATCH(0); |
} |
} |
static void |
emit_draw_rect(struct i915_context *i915) |
{ |
if (i915->static_dirty & I915_DST_RECT) { |
OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); |
OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS); |
OUT_BATCH(i915->current.draw_offset); |
OUT_BATCH(i915->current.draw_size); |
OUT_BATCH(i915->current.draw_offset); |
} |
} |
static boolean |
i915_validate_state(struct i915_context *i915, unsigned *batch_space) |
{ |
unsigned tmp; |
i915->num_validation_buffers = 0; |
if (i915->hardware_dirty & I915_HW_INVARIANT) |
*batch_space = Elements(invariant_state); |
else |
*batch_space = 0; |
#if 0 |
static int counter_total = 0; |
#define VALIDATE_ATOM(atom, hw_dirty) \ |
if (i915->hardware_dirty & hw_dirty) { \ |
static int counter_##atom = 0;\ |
validate_##atom(i915, &tmp); \ |
*batch_space += tmp;\ |
counter_##atom += tmp;\ |
counter_total += tmp;\ |
printf("%s: \t%d/%d \t%2.2f\n",#atom, counter_##atom, counter_total, counter_##atom*100.f/counter_total);} |
#else |
#define VALIDATE_ATOM(atom, hw_dirty) \ |
if (i915->hardware_dirty & hw_dirty) { \ |
validate_##atom(i915, &tmp); \ |
*batch_space += tmp; } |
#endif |
VALIDATE_ATOM(flush, I915_HW_FLUSH); |
VALIDATE_ATOM(immediate, I915_HW_IMMEDIATE); |
VALIDATE_ATOM(dynamic, I915_HW_DYNAMIC); |
VALIDATE_ATOM(static, I915_HW_STATIC); |
VALIDATE_ATOM(map, I915_HW_MAP); |
VALIDATE_ATOM(sampler, I915_HW_SAMPLER); |
VALIDATE_ATOM(constants, I915_HW_CONSTANTS); |
VALIDATE_ATOM(program, I915_HW_PROGRAM); |
#undef VALIDATE_ATOM |
if (i915->num_validation_buffers == 0) |
return TRUE; |
if (!i915_winsys_validate_buffers(i915->batch, i915->validation_buffers, |
i915->num_validation_buffers)) |
return FALSE; |
return TRUE; |
} |
/* Push the state into the sarea and/or texture memory. |
*/ |
void |
i915_emit_hardware_state(struct i915_context *i915 ) |
{ |
unsigned batch_space; |
uintptr_t save_ptr; |
assert(i915->dirty == 0); |
if (I915_DBG_ON(DBG_ATOMS)) |
i915_dump_hardware_dirty(i915, __FUNCTION__); |
if (!i915_validate_state(i915, &batch_space)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
assert(i915_validate_state(i915, &batch_space)); |
} |
if(!BEGIN_BATCH(batch_space)) { |
FLUSH_BATCH(NULL, I915_FLUSH_ASYNC); |
assert(i915_validate_state(i915, &batch_space)); |
assert(BEGIN_BATCH(batch_space)); |
} |
save_ptr = (uintptr_t)i915->batch->ptr; |
#define EMIT_ATOM(atom, hw_dirty) \ |
if (i915->hardware_dirty & hw_dirty) \ |
emit_##atom(i915); |
EMIT_ATOM(flush, I915_HW_FLUSH); |
EMIT_ATOM(invariant, I915_HW_INVARIANT); |
EMIT_ATOM(immediate, I915_HW_IMMEDIATE); |
EMIT_ATOM(dynamic, I915_HW_DYNAMIC); |
EMIT_ATOM(static, I915_HW_STATIC); |
EMIT_ATOM(map, I915_HW_MAP); |
EMIT_ATOM(sampler, I915_HW_SAMPLER); |
EMIT_ATOM(constants, I915_HW_CONSTANTS); |
EMIT_ATOM(program, I915_HW_PROGRAM); |
EMIT_ATOM(draw_rect, I915_HW_STATIC); |
#undef EMIT_ATOM |
I915_DBG(DBG_EMIT, "%s: used %d dwords, %d dwords reserved\n", __FUNCTION__, |
((uintptr_t)i915->batch->ptr - save_ptr) / 4, |
batch_space); |
assert(((uintptr_t)i915->batch->ptr - save_ptr) / 4 == batch_space); |
i915->hardware_dirty = 0; |
i915->immediate_dirty = 0; |
i915->dynamic_dirty = 0; |
i915->static_dirty = 0; |
i915->flush_dirty = 0; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_fpc.c |
---|
0,0 → 1,59 |
/************************************************************************** |
* |
* Copyright © 2010 Jakob Bornecrantz |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_reg.h" |
#include "i915_context.h" |
#include "i915_state.h" |
/*********************************************************************** |
*/ |
static void update_hw_constants(struct i915_context *i915) |
{ |
i915->hardware_dirty |= I915_HW_CONSTANTS; |
} |
struct i915_tracked_state i915_hw_constants = { |
"hw_constants", |
update_hw_constants, |
I915_NEW_FS_CONSTANTS | I915_NEW_FS |
}; |
/*********************************************************************** |
*/ |
static void update_fs(struct i915_context *i915) |
{ |
i915->hardware_dirty |= I915_HW_PROGRAM; |
} |
struct i915_tracked_state i915_hw_fs = { |
"fs", |
update_fs, |
I915_NEW_FS |
}; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_immediate.c |
---|
0,0 → 1,234 |
/************************************************************************** |
* |
* Copyright 2007 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
/* |
* Authors: |
* Keith Whitwell <keithw@vmware.com> |
*/ |
#include "i915_state_inlines.h" |
#include "i915_context.h" |
#include "i915_state.h" |
#include "i915_reg.h" |
#include "util/u_memory.h" |
/* Convinience function to check immediate state. |
*/ |
static INLINE void set_immediate(struct i915_context *i915, |
unsigned offset, |
const unsigned state) |
{ |
if (i915->current.immediate[offset] == state) |
return; |
i915->current.immediate[offset] = state; |
i915->immediate_dirty |= 1 << offset; |
i915->hardware_dirty |= I915_HW_IMMEDIATE; |
} |
/*********************************************************************** |
* S0,S1: Vertex buffer state. |
*/ |
static void upload_S0S1(struct i915_context *i915) |
{ |
unsigned LIS0, LIS1; |
/* I915_NEW_VBO |
*/ |
LIS0 = i915->vbo_offset; |
/* Need to force this */ |
if (i915->dirty & I915_NEW_VBO) { |
i915->immediate_dirty |= 1 << I915_IMMEDIATE_S0; |
i915->hardware_dirty |= I915_HW_IMMEDIATE; |
} |
/* I915_NEW_VERTEX_SIZE |
*/ |
{ |
unsigned vertex_size = i915->current.vertex_info.size; |
LIS1 = ((vertex_size << 24) | |
(vertex_size << 16)); |
} |
set_immediate(i915, I915_IMMEDIATE_S0, LIS0); |
set_immediate(i915, I915_IMMEDIATE_S1, LIS1); |
} |
const struct i915_tracked_state i915_upload_S0S1 = { |
"imm S0 S1", |
upload_S0S1, |
I915_NEW_VBO | I915_NEW_VERTEX_FORMAT |
}; |
/*********************************************************************** |
* S4: Vertex format, rasterization state |
*/ |
static void upload_S2S4(struct i915_context *i915) |
{ |
unsigned LIS2, LIS4; |
/* I915_NEW_VERTEX_FORMAT |
*/ |
{ |
LIS2 = i915->current.vertex_info.hwfmt[1]; |
LIS4 = i915->current.vertex_info.hwfmt[0]; |
assert(LIS4); /* should never be zero? */ |
} |
LIS4 |= i915->rasterizer->LIS4; |
set_immediate(i915, I915_IMMEDIATE_S2, LIS2); |
set_immediate(i915, I915_IMMEDIATE_S4, LIS4); |
} |
const struct i915_tracked_state i915_upload_S2S4 = { |
"imm S2 S4", |
upload_S2S4, |
I915_NEW_RASTERIZER | I915_NEW_VERTEX_FORMAT |
}; |
/*********************************************************************** |
*/ |
static void upload_S5(struct i915_context *i915) |
{ |
unsigned LIS5 = 0; |
/* I915_NEW_DEPTH_STENCIL |
*/ |
LIS5 |= i915->depth_stencil->stencil_LIS5; |
/* hope it's safe to set stencil ref value even if stencil test is disabled? */ |
LIS5 |= i915->stencil_ref.ref_value[0] << S5_STENCIL_REF_SHIFT; |
/* I915_NEW_BLEND |
*/ |
LIS5 |= i915->blend->LIS5; |
#if 0 |
/* I915_NEW_RASTERIZER |
*/ |
if (i915->rasterizer->LIS7) { |
LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE; |
} |
#endif |
set_immediate(i915, I915_IMMEDIATE_S5, LIS5); |
} |
const struct i915_tracked_state i915_upload_S5 = { |
"imm S5", |
upload_S5, |
I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_RASTERIZER |
}; |
/*********************************************************************** |
*/ |
static void upload_S6(struct i915_context *i915) |
{ |
unsigned LIS6 = (2 << S6_TRISTRIP_PV_SHIFT); |
/* I915_NEW_FRAMEBUFFER |
*/ |
if (i915->framebuffer.cbufs[0]) |
LIS6 |= S6_COLOR_WRITE_ENABLE; |
/* I915_NEW_BLEND |
*/ |
LIS6 |= i915->blend->LIS6; |
/* I915_NEW_DEPTH |
*/ |
LIS6 |= i915->depth_stencil->depth_LIS6; |
set_immediate(i915, I915_IMMEDIATE_S6, LIS6); |
} |
const struct i915_tracked_state i915_upload_S6 = { |
"imm S6", |
upload_S6, |
I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL | I915_NEW_FRAMEBUFFER |
}; |
/*********************************************************************** |
*/ |
static void upload_S7(struct i915_context *i915) |
{ |
#if 0 |
unsigned LIS7; |
/* I915_NEW_RASTERIZER |
*/ |
LIS7 = i915->rasterizer->LIS7; |
set_immediate(i915, I915_IMMEDIATE_S7, LIS7); |
#endif |
} |
const struct i915_tracked_state i915_upload_S7 = { |
"imm S7", |
upload_S7, |
I915_NEW_RASTERIZER |
}; |
/*********************************************************************** |
*/ |
static const struct i915_tracked_state *atoms[] = { |
&i915_upload_S0S1, |
&i915_upload_S2S4, |
&i915_upload_S5, |
&i915_upload_S6, |
&i915_upload_S7 |
}; |
static void update_immediate(struct i915_context *i915) |
{ |
int i; |
for (i = 0; i < Elements(atoms); i++) |
if (i915->dirty & atoms[i]->dirty) |
atoms[i]->update(i915); |
} |
struct i915_tracked_state i915_hw_immediate = { |
"immediate", |
update_immediate, |
~0 /* all state atoms, because we do internal checking */ |
}; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_inlines.h |
---|
0,0 → 1,256 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_STATE_INLINES_H |
#define I915_STATE_INLINES_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_defines.h" |
#include "util/u_debug.h" |
#include "i915_reg.h" |
static INLINE unsigned |
i915_translate_compare_func(unsigned func) |
{ |
switch (func) { |
case PIPE_FUNC_NEVER: |
return COMPAREFUNC_NEVER; |
case PIPE_FUNC_LESS: |
return COMPAREFUNC_LESS; |
case PIPE_FUNC_LEQUAL: |
return COMPAREFUNC_LEQUAL; |
case PIPE_FUNC_GREATER: |
return COMPAREFUNC_GREATER; |
case PIPE_FUNC_GEQUAL: |
return COMPAREFUNC_GEQUAL; |
case PIPE_FUNC_NOTEQUAL: |
return COMPAREFUNC_NOTEQUAL; |
case PIPE_FUNC_EQUAL: |
return COMPAREFUNC_EQUAL; |
case PIPE_FUNC_ALWAYS: |
return COMPAREFUNC_ALWAYS; |
default: |
return COMPAREFUNC_ALWAYS; |
} |
} |
static INLINE unsigned |
i915_translate_shadow_compare_func(unsigned func) |
{ |
switch (func) { |
case PIPE_FUNC_NEVER: |
return COMPAREFUNC_ALWAYS; |
case PIPE_FUNC_LESS: |
return COMPAREFUNC_LEQUAL; |
case PIPE_FUNC_LEQUAL: |
return COMPAREFUNC_LESS; |
case PIPE_FUNC_GREATER: |
return COMPAREFUNC_GEQUAL; |
case PIPE_FUNC_GEQUAL: |
return COMPAREFUNC_GREATER; |
case PIPE_FUNC_NOTEQUAL: |
return COMPAREFUNC_EQUAL; |
case PIPE_FUNC_EQUAL: |
return COMPAREFUNC_NOTEQUAL; |
case PIPE_FUNC_ALWAYS: |
return COMPAREFUNC_NEVER; |
default: |
return COMPAREFUNC_NEVER; |
} |
} |
static INLINE unsigned |
i915_translate_stencil_op(unsigned op) |
{ |
switch (op) { |
case PIPE_STENCIL_OP_KEEP: |
return STENCILOP_KEEP; |
case PIPE_STENCIL_OP_ZERO: |
return STENCILOP_ZERO; |
case PIPE_STENCIL_OP_REPLACE: |
return STENCILOP_REPLACE; |
case PIPE_STENCIL_OP_INCR: |
return STENCILOP_INCRSAT; |
case PIPE_STENCIL_OP_DECR: |
return STENCILOP_DECRSAT; |
case PIPE_STENCIL_OP_INCR_WRAP: |
return STENCILOP_INCR; |
case PIPE_STENCIL_OP_DECR_WRAP: |
return STENCILOP_DECR; |
case PIPE_STENCIL_OP_INVERT: |
return STENCILOP_INVERT; |
default: |
return STENCILOP_ZERO; |
} |
} |
static INLINE unsigned |
i915_translate_blend_factor(unsigned factor) |
{ |
switch (factor) { |
case PIPE_BLENDFACTOR_ZERO: |
return BLENDFACT_ZERO; |
case PIPE_BLENDFACTOR_SRC_ALPHA: |
return BLENDFACT_SRC_ALPHA; |
case PIPE_BLENDFACTOR_ONE: |
return BLENDFACT_ONE; |
case PIPE_BLENDFACTOR_SRC_COLOR: |
return BLENDFACT_SRC_COLR; |
case PIPE_BLENDFACTOR_INV_SRC_COLOR: |
return BLENDFACT_INV_SRC_COLR; |
case PIPE_BLENDFACTOR_DST_COLOR: |
return BLENDFACT_DST_COLR; |
case PIPE_BLENDFACTOR_INV_DST_COLOR: |
return BLENDFACT_INV_DST_COLR; |
case PIPE_BLENDFACTOR_INV_SRC_ALPHA: |
return BLENDFACT_INV_SRC_ALPHA; |
case PIPE_BLENDFACTOR_DST_ALPHA: |
return BLENDFACT_DST_ALPHA; |
case PIPE_BLENDFACTOR_INV_DST_ALPHA: |
return BLENDFACT_INV_DST_ALPHA; |
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: |
return BLENDFACT_SRC_ALPHA_SATURATE; |
case PIPE_BLENDFACTOR_CONST_COLOR: |
return BLENDFACT_CONST_COLOR; |
case PIPE_BLENDFACTOR_INV_CONST_COLOR: |
return BLENDFACT_INV_CONST_COLOR; |
case PIPE_BLENDFACTOR_CONST_ALPHA: |
return BLENDFACT_CONST_ALPHA; |
case PIPE_BLENDFACTOR_INV_CONST_ALPHA: |
return BLENDFACT_INV_CONST_ALPHA; |
default: |
return BLENDFACT_ZERO; |
} |
} |
static INLINE unsigned |
i915_translate_blend_func(unsigned mode) |
{ |
switch (mode) { |
case PIPE_BLEND_ADD: |
return BLENDFUNC_ADD; |
case PIPE_BLEND_MIN: |
return BLENDFUNC_MIN; |
case PIPE_BLEND_MAX: |
return BLENDFUNC_MAX; |
case PIPE_BLEND_SUBTRACT: |
return BLENDFUNC_SUBTRACT; |
case PIPE_BLEND_REVERSE_SUBTRACT: |
return BLENDFUNC_REVERSE_SUBTRACT; |
default: |
return 0; |
} |
} |
static INLINE unsigned |
i915_translate_logic_op(unsigned opcode) |
{ |
switch (opcode) { |
case PIPE_LOGICOP_CLEAR: |
return LOGICOP_CLEAR; |
case PIPE_LOGICOP_AND: |
return LOGICOP_AND; |
case PIPE_LOGICOP_AND_REVERSE: |
return LOGICOP_AND_RVRSE; |
case PIPE_LOGICOP_COPY: |
return LOGICOP_COPY; |
case PIPE_LOGICOP_COPY_INVERTED: |
return LOGICOP_COPY_INV; |
case PIPE_LOGICOP_AND_INVERTED: |
return LOGICOP_AND_INV; |
case PIPE_LOGICOP_NOOP: |
return LOGICOP_NOOP; |
case PIPE_LOGICOP_XOR: |
return LOGICOP_XOR; |
case PIPE_LOGICOP_OR: |
return LOGICOP_OR; |
case PIPE_LOGICOP_OR_INVERTED: |
return LOGICOP_OR_INV; |
case PIPE_LOGICOP_NOR: |
return LOGICOP_NOR; |
case PIPE_LOGICOP_EQUIV: |
return LOGICOP_EQUIV; |
case PIPE_LOGICOP_INVERT: |
return LOGICOP_INV; |
case PIPE_LOGICOP_OR_REVERSE: |
return LOGICOP_OR_RVRSE; |
case PIPE_LOGICOP_NAND: |
return LOGICOP_NAND; |
case PIPE_LOGICOP_SET: |
return LOGICOP_SET; |
default: |
return LOGICOP_SET; |
} |
} |
static INLINE boolean i915_validate_vertices( unsigned hw_prim, unsigned nr ) |
{ |
boolean ok; |
switch (hw_prim) { |
case PRIM3D_POINTLIST: |
ok = (nr >= 1); |
assert(ok); |
break; |
case PRIM3D_LINELIST: |
ok = (nr >= 2) && (nr % 2) == 0; |
assert(ok); |
break; |
case PRIM3D_LINESTRIP: |
ok = (nr >= 2); |
assert(ok); |
break; |
case PRIM3D_TRILIST: |
ok = (nr >= 3) && (nr % 3) == 0; |
assert(ok); |
break; |
case PRIM3D_TRISTRIP: |
ok = (nr >= 3); |
assert(ok); |
break; |
case PRIM3D_TRIFAN: |
ok = (nr >= 3); |
assert(ok); |
break; |
case PRIM3D_POLY: |
ok = (nr >= 3); |
assert(ok); |
break; |
default: |
assert(0); |
ok = 0; |
break; |
} |
return ok; |
} |
#endif |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_sampler.c |
---|
0,0 → 1,390 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "pipe/p_context.h" |
#include "pipe/p_state.h" |
#include "i915_state_inlines.h" |
#include "i915_context.h" |
#include "i915_reg.h" |
#include "i915_state.h" |
#include "i915_resource.h" |
/* |
* A note about min_lod & max_lod. |
* |
* There is a circular dependancy between the sampler state |
* and the map state to be submitted to hw. |
* |
* Two condition must be meet: |
* min_lod =< max_lod == true |
* max_lod =< last_level == true |
* |
* |
* This is all fine and dandy if it were for the fact that max_lod |
* is set on the map state instead of the sampler state. That is |
* the max_lod we submit on map is: |
* max_lod = MIN2(last_level, max_lod); |
* |
* So we need to update the map state when we change samplers and |
* we need to change the sampler state when map state is changed. |
* The first part is done by calling update_texture in update_samplers |
* and the second part is done else where in code tracking the state |
* changes. |
*/ |
static void update_map(struct i915_context *i915, |
uint unit, |
const struct i915_texture *tex, |
const struct i915_sampler_state *sampler, |
const struct pipe_sampler_view* view, |
uint state[3]); |
/*********************************************************************** |
* Samplers |
*/ |
/** |
* Compute i915 texture sampling state. |
* |
* Recalculate all state from scratch. Perhaps not the most |
* efficient, but this has gotten complex enough that we need |
* something which is understandable and reliable. |
* \param state returns the 3 words of compute state |
*/ |
static void update_sampler(struct i915_context *i915, |
uint unit, |
const struct i915_sampler_state *sampler, |
const struct i915_texture *tex, |
unsigned state[3]) |
{ |
const struct pipe_resource *pt = &tex->b.b; |
unsigned minlod, lastlod; |
state[0] = sampler->state[0]; |
state[1] = sampler->state[1]; |
state[2] = sampler->state[2]; |
if (pt->format == PIPE_FORMAT_UYVY || |
pt->format == PIPE_FORMAT_YUYV) |
state[0] |= SS2_COLORSPACE_CONVERSION; |
if (pt->format == PIPE_FORMAT_B8G8R8A8_SRGB || |
pt->format == PIPE_FORMAT_L8_SRGB ) |
state[0] |= SS2_REVERSE_GAMMA_ENABLE; |
/* 3D textures don't seem to respect the border color. |
* Fallback if there's ever a danger that they might refer to |
* it. |
* |
* Effectively this means fallback on 3D clamp or |
* clamp_to_border. |
* |
* XXX: Check if this is true on i945. |
* XXX: Check if this bug got fixed in release silicon. |
*/ |
#if 0 |
{ |
const unsigned ws = sampler->templ->wrap_s; |
const unsigned wt = sampler->templ->wrap_t; |
const unsigned wr = sampler->templ->wrap_r; |
if (pt->target == PIPE_TEXTURE_3D && |
(sampler->templ->min_img_filter != PIPE_TEX_FILTER_NEAREST || |
sampler->templ->mag_img_filter != PIPE_TEX_FILTER_NEAREST) && |
(ws == PIPE_TEX_WRAP_CLAMP || |
wt == PIPE_TEX_WRAP_CLAMP || |
wr == PIPE_TEX_WRAP_CLAMP || |
ws == PIPE_TEX_WRAP_CLAMP_TO_BORDER || |
wt == PIPE_TEX_WRAP_CLAMP_TO_BORDER || |
wr == PIPE_TEX_WRAP_CLAMP_TO_BORDER)) { |
if (i915->conformance_mode > 0) { |
assert(0); |
/* sampler->fallback = true; */ |
/* TODO */ |
} |
} |
} |
#endif |
/* See note at the top of file */ |
minlod = sampler->minlod; |
lastlod = pt->last_level << 4; |
if (lastlod < minlod) { |
minlod = lastlod; |
} |
state[1] |= (sampler->minlod << SS3_MIN_LOD_SHIFT); |
state[1] |= (unit << SS3_TEXTUREMAP_INDEX_SHIFT); |
} |
static void update_samplers(struct i915_context *i915) |
{ |
uint unit; |
i915->current.sampler_enable_nr = 0; |
i915->current.sampler_enable_flags = 0x0; |
for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers; |
unit++) { |
/* determine unit enable/disable by looking for a bound texture */ |
/* could also examine the fragment program? */ |
if (i915->fragment_sampler_views[unit]) { |
struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); |
update_sampler(i915, |
unit, |
i915->fragment_sampler[unit], /* sampler state */ |
texture, /* texture */ |
i915->current.sampler[unit]); /* the result */ |
update_map(i915, |
unit, |
texture, /* texture */ |
i915->fragment_sampler[unit], /* sampler state */ |
i915->fragment_sampler_views[unit], /* sampler view */ |
i915->current.texbuffer[unit]); /* the result */ |
i915->current.sampler_enable_nr++; |
i915->current.sampler_enable_flags |= (1 << unit); |
} |
} |
i915->hardware_dirty |= I915_HW_SAMPLER | I915_HW_MAP; |
} |
struct i915_tracked_state i915_hw_samplers = { |
"samplers", |
update_samplers, |
I915_NEW_SAMPLER | I915_NEW_SAMPLER_VIEW |
}; |
/*********************************************************************** |
* Sampler views |
*/ |
static uint translate_texture_format(enum pipe_format pipeFormat, |
const struct pipe_sampler_view* view) |
{ |
if ( (view->swizzle_r != PIPE_SWIZZLE_RED || |
view->swizzle_g != PIPE_SWIZZLE_GREEN || |
view->swizzle_b != PIPE_SWIZZLE_BLUE || |
view->swizzle_a != PIPE_SWIZZLE_ALPHA ) && |
pipeFormat != PIPE_FORMAT_Z24_UNORM_S8_UINT && |
pipeFormat != PIPE_FORMAT_Z24X8_UNORM ) |
debug_printf("i915: unsupported texture swizzle for format %d\n", pipeFormat); |
switch (pipeFormat) { |
case PIPE_FORMAT_L8_UNORM: |
return MAPSURF_8BIT | MT_8BIT_L8; |
case PIPE_FORMAT_I8_UNORM: |
return MAPSURF_8BIT | MT_8BIT_I8; |
case PIPE_FORMAT_A8_UNORM: |
return MAPSURF_8BIT | MT_8BIT_A8; |
case PIPE_FORMAT_L8A8_UNORM: |
return MAPSURF_16BIT | MT_16BIT_AY88; |
case PIPE_FORMAT_B5G6R5_UNORM: |
return MAPSURF_16BIT | MT_16BIT_RGB565; |
case PIPE_FORMAT_B5G5R5A1_UNORM: |
return MAPSURF_16BIT | MT_16BIT_ARGB1555; |
case PIPE_FORMAT_B4G4R4A4_UNORM: |
return MAPSURF_16BIT | MT_16BIT_ARGB4444; |
case PIPE_FORMAT_B10G10R10A2_UNORM: |
return MAPSURF_32BIT | MT_32BIT_ARGB2101010; |
case PIPE_FORMAT_B8G8R8A8_UNORM: |
case PIPE_FORMAT_B8G8R8A8_SRGB: |
return MAPSURF_32BIT | MT_32BIT_ARGB8888; |
case PIPE_FORMAT_B8G8R8X8_UNORM: |
return MAPSURF_32BIT | MT_32BIT_XRGB8888; |
case PIPE_FORMAT_R8G8B8A8_UNORM: |
return MAPSURF_32BIT | MT_32BIT_ABGR8888; |
case PIPE_FORMAT_R8G8B8X8_UNORM: |
return MAPSURF_32BIT | MT_32BIT_XBGR8888; |
case PIPE_FORMAT_YUYV: |
return (MAPSURF_422 | MT_422_YCRCB_NORMAL); |
case PIPE_FORMAT_UYVY: |
return (MAPSURF_422 | MT_422_YCRCB_SWAPY); |
#if 0 |
case PIPE_FORMAT_RGB_FXT1: |
case PIPE_FORMAT_RGBA_FXT1: |
return (MAPSURF_COMPRESSED | MT_COMPRESS_FXT1); |
#endif |
case PIPE_FORMAT_Z16_UNORM: |
return (MAPSURF_16BIT | MT_16BIT_L16); |
case PIPE_FORMAT_DXT1_RGBA: |
case PIPE_FORMAT_DXT1_RGB: |
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT1); |
case PIPE_FORMAT_DXT3_RGBA: |
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT2_3); |
case PIPE_FORMAT_DXT5_RGBA: |
return (MAPSURF_COMPRESSED | MT_COMPRESS_DXT4_5); |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
case PIPE_FORMAT_Z24X8_UNORM: |
{ |
if ( view->swizzle_r == PIPE_SWIZZLE_RED && |
view->swizzle_g == PIPE_SWIZZLE_RED && |
view->swizzle_b == PIPE_SWIZZLE_RED && |
view->swizzle_a == PIPE_SWIZZLE_ONE) |
return (MAPSURF_32BIT | MT_32BIT_xA824); |
if ( view->swizzle_r == PIPE_SWIZZLE_RED && |
view->swizzle_g == PIPE_SWIZZLE_RED && |
view->swizzle_b == PIPE_SWIZZLE_RED && |
view->swizzle_a == PIPE_SWIZZLE_RED) |
return (MAPSURF_32BIT | MT_32BIT_xI824); |
if ( view->swizzle_r == PIPE_SWIZZLE_ZERO && |
view->swizzle_g == PIPE_SWIZZLE_ZERO && |
view->swizzle_b == PIPE_SWIZZLE_ZERO && |
view->swizzle_a == PIPE_SWIZZLE_RED) |
return (MAPSURF_32BIT | MT_32BIT_xL824); |
debug_printf("i915: unsupported depth swizzle %d %d %d %d\n", |
view->swizzle_r, |
view->swizzle_g, |
view->swizzle_b, |
view->swizzle_a); |
return (MAPSURF_32BIT | MT_32BIT_xL824); |
} |
default: |
debug_printf("i915: translate_texture_format() bad image format %x\n", |
pipeFormat); |
assert(0); |
return 0; |
} |
} |
static inline uint32_t |
ms3_tiling_bits(enum i915_winsys_buffer_tile tiling) |
{ |
uint32_t tiling_bits = 0; |
switch (tiling) { |
case I915_TILE_Y: |
tiling_bits |= MS3_TILE_WALK_Y; |
case I915_TILE_X: |
tiling_bits |= MS3_TILED_SURFACE; |
case I915_TILE_NONE: |
break; |
} |
return tiling_bits; |
} |
static void update_map(struct i915_context *i915, |
uint unit, |
const struct i915_texture *tex, |
const struct i915_sampler_state *sampler, |
const struct pipe_sampler_view* view, |
uint state[3]) |
{ |
const struct pipe_resource *pt = &tex->b.b; |
uint width = pt->width0, height = pt->height0, depth = pt->depth0; |
int first_level = view->u.tex.first_level; |
const uint num_levels = pt->last_level - first_level; |
unsigned max_lod = num_levels * 4; |
bool is_npot = (!util_is_power_of_two(pt->width0) || !util_is_power_of_two(pt->height0)); |
uint format, pitch; |
/* |
* This is a bit messy. i915 doesn't support NPOT with mipmaps, but we can |
* still texture from a single level. This is useful to make u_blitter work. |
*/ |
if (is_npot) { |
width = u_minify(width, first_level); |
height = u_minify(height, first_level); |
max_lod = 1; |
} |
assert(tex); |
assert(width); |
assert(height); |
assert(depth); |
format = translate_texture_format(pt->format, view); |
pitch = tex->stride; |
assert(format); |
assert(pitch); |
/* MS3 state */ |
state[0] = |
(((height - 1) << MS3_HEIGHT_SHIFT) |
| ((width - 1) << MS3_WIDTH_SHIFT) |
| format |
| ms3_tiling_bits(tex->tiling)); |
/* |
* XXX When min_filter != mag_filter and there's just one mipmap level, |
* set max_lod = 1 to make sure i915 chooses between min/mag filtering. |
*/ |
/* See note at the top of file */ |
if (max_lod > (sampler->maxlod >> 2)) |
max_lod = sampler->maxlod >> 2; |
/* MS4 state */ |
state[1] = |
((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
| MS4_CUBE_FACE_ENA_MASK |
| ((max_lod) << MS4_MAX_LOD_SHIFT) |
| ((depth - 1) << MS4_VOLUME_DEPTH_SHIFT)); |
if (is_npot) |
state[2] = i915_texture_offset(tex, first_level, 0); |
else |
state[2] = 0; |
} |
static void update_maps(struct i915_context *i915) |
{ |
uint unit; |
for (unit = 0; unit < i915->num_fragment_sampler_views && unit < i915->num_samplers; |
unit++) { |
/* determine unit enable/disable by looking for a bound texture */ |
/* could also examine the fragment program? */ |
if (i915->fragment_sampler_views[unit]) { |
struct i915_texture *texture = i915_texture(i915->fragment_sampler_views[unit]->texture); |
update_map(i915, |
unit, |
texture, /* texture */ |
i915->fragment_sampler[unit], /* sampler state */ |
i915->fragment_sampler_views[unit], /* sampler view */ |
i915->current.texbuffer[unit]); |
} |
} |
i915->hardware_dirty |= I915_HW_MAP; |
} |
struct i915_tracked_state i915_hw_sampler_views = { |
"sampler_views", |
update_maps, |
I915_NEW_SAMPLER_VIEW |
}; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_state_static.c |
---|
0,0 → 1,255 |
/************************************************************************** |
* |
* Copyright © 2010 Jakob Bornecrantz |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_reg.h" |
#include "i915_context.h" |
#include "i915_state.h" |
#include "i915_resource.h" |
#include "i915_screen.h" |
/*********************************************************************** |
* Update framebuffer state |
*/ |
static unsigned translate_format(enum pipe_format format) |
{ |
switch (format) { |
case PIPE_FORMAT_B8G8R8A8_UNORM: |
case PIPE_FORMAT_B8G8R8A8_SRGB: |
case PIPE_FORMAT_B8G8R8X8_UNORM: |
case PIPE_FORMAT_R8G8B8A8_UNORM: |
case PIPE_FORMAT_R8G8B8X8_UNORM: |
return COLOR_BUF_ARGB8888; |
case PIPE_FORMAT_B5G6R5_UNORM: |
return COLOR_BUF_RGB565; |
case PIPE_FORMAT_B5G5R5A1_UNORM: |
return COLOR_BUF_ARGB1555; |
case PIPE_FORMAT_B4G4R4A4_UNORM: |
return COLOR_BUF_ARGB4444; |
case PIPE_FORMAT_B10G10R10A2_UNORM: |
return COLOR_BUF_ARGB2101010; |
case PIPE_FORMAT_L8_UNORM: |
case PIPE_FORMAT_A8_UNORM: |
case PIPE_FORMAT_I8_UNORM: |
return COLOR_BUF_8BIT; |
default: |
assert(0); |
return 0; |
} |
} |
static unsigned translate_depth_format(enum pipe_format zformat) |
{ |
switch (zformat) { |
case PIPE_FORMAT_Z24X8_UNORM: |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
return DEPTH_FRMT_24_FIXED_8_OTHER; |
case PIPE_FORMAT_Z16_UNORM: |
return DEPTH_FRMT_16_FIXED; |
default: |
assert(0); |
return 0; |
} |
} |
static inline uint32_t |
buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling) |
{ |
uint32_t tiling_bits = 0; |
switch (tiling) { |
case I915_TILE_Y: |
tiling_bits |= BUF_3D_TILE_WALK_Y; |
case I915_TILE_X: |
tiling_bits |= BUF_3D_TILED_SURFACE; |
case I915_TILE_NONE: |
break; |
} |
return tiling_bits; |
} |
static void update_framebuffer(struct i915_context *i915) |
{ |
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; |
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; |
unsigned x, y; |
int layer; |
uint32_t draw_offset, draw_size; |
if (cbuf_surface) { |
struct i915_texture *tex = i915_texture(cbuf_surface->texture); |
assert(tex); |
i915->current.cbuf_bo = tex->buffer; |
i915->current.cbuf_flags = BUF_3D_ID_COLOR_BACK | |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ |
buf_3d_tiling_bits(tex->tiling); |
layer = cbuf_surface->u.tex.first_layer; |
x = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksx; |
y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy; |
} else { |
i915->current.cbuf_bo = NULL; |
x = y = 0; |
} |
i915->static_dirty |= I915_DST_BUF_COLOR; |
/* What happens if no zbuf?? |
*/ |
if (depth_surface) { |
struct i915_texture *tex = i915_texture(depth_surface->texture); |
unsigned offset = i915_texture_offset(tex, depth_surface->u.tex.level, |
depth_surface->u.tex.first_layer); |
assert(tex); |
if (offset != 0) |
debug_printf("Depth offset is %d\n",offset); |
i915->current.depth_bo = tex->buffer; |
i915->current.depth_flags = BUF_3D_ID_DEPTH | |
BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ |
buf_3d_tiling_bits(tex->tiling); |
} else |
i915->current.depth_bo = NULL; |
i915->static_dirty |= I915_DST_BUF_DEPTH; |
/* drawing rect calculations */ |
draw_offset = x | (y << 16); |
draw_size = (i915->framebuffer.width - 1 + x) | |
((i915->framebuffer.height - 1 + y) << 16); |
if (i915->current.draw_offset != draw_offset) { |
i915->current.draw_offset = draw_offset; |
i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); |
i915->static_dirty |= I915_DST_RECT; |
} |
if (i915->current.draw_size != draw_size) { |
i915->current.draw_size = draw_size; |
i915->static_dirty |= I915_DST_RECT; |
} |
i915->hardware_dirty |= I915_HW_STATIC; |
/* flush the cache in case we sample from the old renderbuffers */ |
i915_set_flush_dirty(i915, I915_FLUSH_CACHE); |
} |
struct i915_tracked_state i915_hw_framebuffer = { |
"framebuffer", |
update_framebuffer, |
I915_NEW_FRAMEBUFFER |
}; |
static uint32_t need_target_fixup(struct pipe_surface* p, uint32_t *fixup) |
{ |
const struct |
{ |
enum pipe_format format; |
uint hw_swizzle; |
} fixup_formats[] = { |
{ PIPE_FORMAT_R8G8B8A8_UNORM, 0x21030000 /* BGRA */}, |
{ PIPE_FORMAT_R8G8B8X8_UNORM, 0x21030000 /* BGRX */}, |
{ PIPE_FORMAT_L8_UNORM, 0x00030000 /* RRRA */}, |
{ PIPE_FORMAT_I8_UNORM, 0x00030000 /* RRRA */}, |
{ PIPE_FORMAT_A8_UNORM, 0x33330000 /* AAAA */}, |
{ PIPE_FORMAT_NONE, 0x00000000}, |
}; |
enum pipe_format f; |
/* if we don't have a surface bound yet, we don't need to fixup the shader */ |
if (!p) |
return 0; |
f = p->format; |
for(int i = 0; fixup_formats[i].format != PIPE_FORMAT_NONE; i++) |
if (fixup_formats[i].format == f) { |
*fixup = fixup_formats[i].hw_swizzle; |
return f; |
} |
*fixup = 0; |
return 0; |
} |
static void update_dst_buf_vars(struct i915_context *i915) |
{ |
struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; |
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; |
uint32_t dst_buf_vars, cformat, zformat; |
uint32_t early_z = 0; |
uint32_t fixup = 0; |
int need_fixup; |
if (cbuf_surface) |
cformat = cbuf_surface->format; |
else |
cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */ |
cformat = translate_format(cformat); |
if (depth_surface) { |
struct i915_texture *tex = i915_texture(depth_surface->texture); |
struct i915_screen *is = i915_screen(i915->base.screen); |
zformat = translate_depth_format(depth_surface->format); |
if (is->is_i945 && tex->tiling != I915_TILE_NONE |
&& !i915->fs->info.writes_z) |
early_z = CLASSIC_EARLY_DEPTH; |
} else |
zformat = 0; |
dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ |
DSTORG_VERT_BIAS(0x8) | /* .5 */ |
LOD_PRECLAMP_OGL | |
TEX_DEFAULT_COLOR_OGL | |
cformat | |
zformat | |
early_z; |
if (i915->current.dst_buf_vars != dst_buf_vars) { |
if (early_z != (i915->current.dst_buf_vars & CLASSIC_EARLY_DEPTH)) |
i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); |
i915->current.dst_buf_vars = dst_buf_vars; |
i915->static_dirty |= I915_DST_VARS; |
i915->hardware_dirty |= I915_HW_STATIC; |
} |
need_fixup = need_target_fixup(cbuf_surface, &fixup); |
if (i915->current.target_fixup_format != need_fixup || |
i915->current.fixup_swizzle != fixup) { |
i915->current.target_fixup_format = need_fixup; |
i915->current.fixup_swizzle = fixup; |
/* we also send a new program to make sure the fixup for RGBA surfaces happens */ |
i915->hardware_dirty |= I915_HW_PROGRAM; |
} |
} |
struct i915_tracked_state i915_hw_dst_buf_vars = { |
"dst buf vars", |
update_dst_buf_vars, |
I915_NEW_FRAMEBUFFER | I915_NEW_FS |
}; |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_surface.c |
---|
0,0 → 1,412 |
/************************************************************************** |
* |
* Copyright 2003 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#include "i915_surface.h" |
#include "i915_resource.h" |
#include "i915_state.h" |
#include "i915_blit.h" |
#include "i915_reg.h" |
#include "i915_screen.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_math.h" |
#include "util/u_format.h" |
#include "util/u_memory.h" |
#include "util/u_pack_color.h" |
#include "util/u_surface.h" |
static struct pipe_surface * |
i915_create_surface_custom(struct pipe_context *ctx, |
struct pipe_resource *pt, |
const struct pipe_surface *surf_tmpl, |
unsigned width0, |
unsigned height0); |
/* |
* surface functions using the render engine |
*/ |
static void |
i915_util_blitter_save_states(struct i915_context *i915) |
{ |
util_blitter_save_blend(i915->blitter, (void *)i915->blend); |
util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil); |
util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref); |
util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer); |
util_blitter_save_fragment_shader(i915->blitter, i915->fs); |
util_blitter_save_vertex_shader(i915->blitter, i915->vs); |
util_blitter_save_viewport(i915->blitter, &i915->viewport); |
util_blitter_save_scissor(i915->blitter, &i915->scissor); |
util_blitter_save_vertex_elements(i915->blitter, i915->velems); |
util_blitter_save_vertex_buffer_slot(i915->blitter, |
i915->vertex_buffers); |
util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); |
util_blitter_save_fragment_sampler_states(i915->blitter, |
i915->num_samplers, |
(void**)i915->fragment_sampler); |
util_blitter_save_fragment_sampler_views(i915->blitter, |
i915->num_fragment_sampler_views, |
i915->fragment_sampler_views); |
} |
static void |
i915_surface_copy_render(struct pipe_context *pipe, |
struct pipe_resource *dst, unsigned dst_level, |
unsigned dstx, unsigned dsty, unsigned dstz, |
struct pipe_resource *src, unsigned src_level, |
const struct pipe_box *src_box) |
{ |
struct i915_context *i915 = i915_context(pipe); |
unsigned src_width0 = src->width0; |
unsigned src_height0 = src->height0; |
unsigned dst_width0 = dst->width0; |
unsigned dst_height0 = dst->height0; |
struct pipe_box dstbox; |
struct pipe_sampler_view src_templ, *src_view; |
struct pipe_surface dst_templ, *dst_view; |
const struct util_format_description *desc; |
/* Fallback for buffers. */ |
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) |
goto fallback; |
/* Fallback for depth&stencil. XXX: see if we can use a proxy format */ |
desc = util_format_description(src->format); |
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) |
goto fallback; |
desc = util_format_description(dst->format); |
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) |
goto fallback; |
util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); |
util_blitter_default_src_texture(&src_templ, src, src_level); |
if (!util_blitter_is_copy_supported(i915->blitter, dst, src)) |
goto fallback; |
i915_util_blitter_save_states(i915); |
dst_view = i915_create_surface_custom(pipe, dst, &dst_templ, dst_width0, dst_height0); |
src_view = i915_create_sampler_view_custom(pipe, src, &src_templ, src_width0, src_height0); |
u_box_3d(dstx, dsty, dstz, abs(src_box->width), abs(src_box->height), |
abs(src_box->depth), &dstbox); |
util_blitter_blit_generic(i915->blitter, dst_view, &dstbox, |
src_view, src_box, src_width0, src_height0, |
PIPE_MASK_RGBAZS, PIPE_TEX_FILTER_NEAREST, NULL); |
return; |
fallback: |
util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, |
src, src_level, src_box); |
} |
static void |
i915_clear_render_target_render(struct pipe_context *pipe, |
struct pipe_surface *dst, |
const union pipe_color_union *color, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct pipe_framebuffer_state fb_state; |
util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); |
fb_state.width = dst->width; |
fb_state.height = dst->height; |
fb_state.nr_cbufs = 1; |
fb_state.cbufs[0] = dst; |
fb_state.zsbuf = NULL; |
pipe->set_framebuffer_state(pipe, &fb_state); |
if (i915->dirty) |
i915_update_derived(i915); |
i915_clear_emit(pipe, PIPE_CLEAR_COLOR, color, 0.0, 0x0, |
dstx, dsty, width, height); |
pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); |
util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); |
i915->blitter->saved_fb_state.nr_cbufs = ~0; |
} |
static void |
i915_clear_depth_stencil_render(struct pipe_context *pipe, |
struct pipe_surface *dst, |
unsigned clear_flags, |
double depth, |
unsigned stencil, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct pipe_framebuffer_state fb_state; |
util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); |
fb_state.width = dst->width; |
fb_state.height = dst->height; |
fb_state.nr_cbufs = 0; |
fb_state.zsbuf = dst; |
pipe->set_framebuffer_state(pipe, &fb_state); |
if (i915->dirty) |
i915_update_derived(i915); |
i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL, |
NULL, depth, stencil, |
dstx, dsty, width, height); |
pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); |
util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); |
i915->blitter->saved_fb_state.nr_cbufs = ~0; |
} |
/* |
* surface functions using the blitter |
*/ |
/* Assumes all values are within bounds -- no checking at this level - |
* do it higher up if required. |
*/ |
static void |
i915_surface_copy_blitter(struct pipe_context *pipe, |
struct pipe_resource *dst, unsigned dst_level, |
unsigned dstx, unsigned dsty, unsigned dstz, |
struct pipe_resource *src, unsigned src_level, |
const struct pipe_box *src_box) |
{ |
struct i915_texture *dst_tex = i915_texture(dst); |
struct i915_texture *src_tex = i915_texture(src); |
struct pipe_resource *dpt = &dst_tex->b.b; |
struct pipe_resource *spt = &src_tex->b.b; |
unsigned dst_offset, src_offset; /* in bytes */ |
/* Fallback for buffers. */ |
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { |
util_resource_copy_region(pipe, dst, dst_level, dstx, dsty, dstz, |
src, src_level, src_box); |
return; |
} |
/* XXX cannot copy 3d regions at this time */ |
assert(src_box->depth == 1); |
if (dst->target != PIPE_TEXTURE_CUBE && |
dst->target != PIPE_TEXTURE_3D) |
assert(dstz == 0); |
dst_offset = i915_texture_offset(dst_tex, dst_level, dstz); |
if (src->target != PIPE_TEXTURE_CUBE && |
src->target != PIPE_TEXTURE_3D) |
assert(src_box->z == 0); |
src_offset = i915_texture_offset(src_tex, src_level, src_box->z); |
assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) ); |
assert( util_format_get_blockwidth(dpt->format) == util_format_get_blockwidth(spt->format) ); |
assert( util_format_get_blockheight(dpt->format) == util_format_get_blockheight(spt->format) ); |
assert( util_format_get_blockwidth(dpt->format) == 1 ); |
assert( util_format_get_blockheight(dpt->format) == 1 ); |
i915_copy_blit( i915_context(pipe), |
util_format_get_blocksize(dpt->format), |
(unsigned short) src_tex->stride, src_tex->buffer, src_offset, |
(unsigned short) dst_tex->stride, dst_tex->buffer, dst_offset, |
(short) src_box->x, (short) src_box->y, (short) dstx, (short) dsty, |
(short) src_box->width, (short) src_box->height ); |
} |
static void |
i915_blit(struct pipe_context *pipe, const struct pipe_blit_info *blit_info) |
{ |
struct i915_context *i915 = i915_context(pipe); |
struct pipe_blit_info info = *blit_info; |
if (util_try_blit_via_copy_region(pipe, &info)) { |
return; /* done */ |
} |
if (info.mask & PIPE_MASK_S) { |
debug_printf("i915: cannot blit stencil, skipping\n"); |
info.mask &= ~PIPE_MASK_S; |
} |
if (!util_blitter_is_blit_supported(i915->blitter, &info)) { |
debug_printf("i915: blit unsupported %s -> %s\n", |
util_format_short_name(info.src.resource->format), |
util_format_short_name(info.dst.resource->format)); |
return; |
} |
i915_util_blitter_save_states(i915); |
util_blitter_blit(i915->blitter, &info); |
} |
static void |
i915_flush_resource(struct pipe_context *ctx, struct pipe_resource *resource) |
{ |
} |
static void |
i915_clear_render_target_blitter(struct pipe_context *pipe, |
struct pipe_surface *dst, |
const union pipe_color_union *color, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct i915_texture *tex = i915_texture(dst->texture); |
struct pipe_resource *pt = &tex->b.b; |
union util_color uc; |
unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); |
assert(util_format_get_blockwidth(pt->format) == 1); |
assert(util_format_get_blockheight(pt->format) == 1); |
util_pack_color(color->f, dst->format, &uc); |
i915_fill_blit( i915_context(pipe), |
util_format_get_blocksize(pt->format), |
XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB, |
(unsigned short) tex->stride, |
tex->buffer, offset, |
(short) dstx, (short) dsty, |
(short) width, (short) height, |
uc.ui[0] ); |
} |
static void |
i915_clear_depth_stencil_blitter(struct pipe_context *pipe, |
struct pipe_surface *dst, |
unsigned clear_flags, |
double depth, |
unsigned stencil, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct i915_texture *tex = i915_texture(dst->texture); |
struct pipe_resource *pt = &tex->b.b; |
unsigned packedds; |
unsigned mask = 0; |
unsigned offset = i915_texture_offset(tex, dst->u.tex.level, dst->u.tex.first_layer); |
assert(util_format_get_blockwidth(pt->format) == 1); |
assert(util_format_get_blockheight(pt->format) == 1); |
packedds = util_pack_z_stencil(dst->format, depth, stencil); |
if (clear_flags & PIPE_CLEAR_DEPTH) |
mask |= XY_COLOR_BLT_WRITE_RGB; |
/* XXX presumably this does read-modify-write |
(otherwise this won't work anyway). Hence will only want to |
do it if really have stencil and it isn't cleared */ |
if ((clear_flags & PIPE_CLEAR_STENCIL) || |
(dst->format != PIPE_FORMAT_Z24_UNORM_S8_UINT)) |
mask |= XY_COLOR_BLT_WRITE_ALPHA; |
i915_fill_blit( i915_context(pipe), |
util_format_get_blocksize(pt->format), |
mask, |
(unsigned short) tex->stride, |
tex->buffer, offset, |
(short) dstx, (short) dsty, |
(short) width, (short) height, |
packedds ); |
} |
/* |
* Screen surface functions |
*/ |
static struct pipe_surface * |
i915_create_surface_custom(struct pipe_context *ctx, |
struct pipe_resource *pt, |
const struct pipe_surface *surf_tmpl, |
unsigned width0, |
unsigned height0) |
{ |
struct pipe_surface *ps; |
assert(surf_tmpl->u.tex.first_layer == surf_tmpl->u.tex.last_layer); |
if (pt->target != PIPE_TEXTURE_CUBE && |
pt->target != PIPE_TEXTURE_3D) |
assert(surf_tmpl->u.tex.first_layer == 0); |
ps = CALLOC_STRUCT(pipe_surface); |
if (ps) { |
/* could subclass pipe_surface and store offset as it used to do */ |
pipe_reference_init(&ps->reference, 1); |
pipe_resource_reference(&ps->texture, pt); |
ps->format = surf_tmpl->format; |
ps->width = u_minify(width0, surf_tmpl->u.tex.level); |
ps->height = u_minify(height0, surf_tmpl->u.tex.level); |
ps->u.tex.level = surf_tmpl->u.tex.level; |
ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; |
ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; |
ps->context = ctx; |
} |
return ps; |
} |
static struct pipe_surface * |
i915_create_surface(struct pipe_context *ctx, |
struct pipe_resource *pt, |
const struct pipe_surface *surf_tmpl) |
{ |
return i915_create_surface_custom(ctx, pt, surf_tmpl, |
pt->width0, pt->height0); |
} |
static void |
i915_surface_destroy(struct pipe_context *ctx, |
struct pipe_surface *surf) |
{ |
pipe_resource_reference(&surf->texture, NULL); |
FREE(surf); |
} |
void |
i915_init_surface_functions(struct i915_context *i915) |
{ |
if (i915_screen(i915->base.screen)->debug.use_blitter) { |
i915->base.resource_copy_region = i915_surface_copy_blitter; |
i915->base.clear_render_target = i915_clear_render_target_blitter; |
i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter; |
} else { |
i915->base.resource_copy_region = i915_surface_copy_render; |
i915->base.clear_render_target = i915_clear_render_target_render; |
i915->base.clear_depth_stencil = i915_clear_depth_stencil_render; |
} |
i915->base.blit = i915_blit; |
i915->base.flush_resource = i915_flush_resource; |
i915->base.create_surface = i915_create_surface; |
i915->base.surface_destroy = i915_surface_destroy; |
} |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_surface.h |
---|
0,0 → 1,37 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* All Rights Reserved. |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the |
* "Software"), to deal in the Software without restriction, including |
* without limitation the rights to use, copy, modify, merge, publish, |
* distribute, sub license, and/or sell copies of the Software, and to |
* permit persons to whom the Software is furnished to do so, subject to |
* the following conditions: |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. |
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR |
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_SURFACE_H |
#define I915_SURFACE_H |
struct i915_context; |
struct i915_screen; |
void i915_init_surface_functions( struct i915_context *i915 ); |
#endif /* I915_SCREEN_H */ |
/contrib/sdk/sources/Mesa/mesa-10.6.0/src/gallium/drivers/i915/i915_winsys.h |
---|
0,0 → 1,263 |
/************************************************************************** |
* |
* Copyright © 2009 Jakob Bornecrantz |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* to deal in the Software without restriction, including without limitation |
* the rights to use, copy, modify, merge, publish, distribute, sublicense, |
* and/or sell copies of the Software, and to permit persons to whom the |
* Software is furnished to do so, subject to the following conditions: |
* |
* The above copyright notice and this permission notice (including the next |
* paragraph) shall be included in all copies or substantial portions of the |
* Software. |
* |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
* DEALINGS IN THE SOFTWARE. |
* |
**************************************************************************/ |
#ifndef I915_WINSYS_H |
#define I915_WINSYS_H |
#include "pipe/p_compiler.h" |
struct i915_winsys; |
struct i915_winsys_buffer; |
struct i915_winsys_batchbuffer; |
struct pipe_resource; |
struct pipe_fence_handle; |
struct winsys_handle; |
enum i915_winsys_buffer_usage |
{ |
/* use on textures */ |
I915_USAGE_RENDER = 0x01, |
I915_USAGE_SAMPLER = 0x02, |
I915_USAGE_2D_TARGET = 0x04, |
I915_USAGE_2D_SOURCE = 0x08, |
/* use on vertex */ |
I915_USAGE_VERTEX = 0x10 |
}; |
enum i915_winsys_buffer_type |
{ |
I915_NEW_TEXTURE, |
I915_NEW_SCANOUT, /**< a texture used for scanning out from */ |
I915_NEW_VERTEX |
}; |
/* These need to be in sync with the definitions of libdrm-intel! */ |
enum i915_winsys_buffer_tile |
{ |
I915_TILE_NONE, |
I915_TILE_X, |
I915_TILE_Y |
}; |
enum i915_winsys_flush_flags |
{ |
I915_FLUSH_ASYNC = 0, |
I915_FLUSH_END_OF_FRAME = 1 |
}; |
struct i915_winsys_batchbuffer { |
struct i915_winsys *iws; |
/** |
* Values exported to speed up the writing the batchbuffer, |
* instead of having to go trough a accesor function for |
* each dword written. |
*/ |
/*{@*/ |
uint8_t *map; |
uint8_t *ptr; |
size_t size; |
size_t relocs; |
/*@}*/ |
}; |
struct i915_winsys { |
unsigned pci_id; /**< PCI ID for the device */ |
/** |
* Batchbuffer functions. |
*/ |
/*@{*/ |
/** |
* Create a new batchbuffer. |
*/ |
struct i915_winsys_batchbuffer * |
(*batchbuffer_create)(struct i915_winsys *iws); |
/** |
* Validate buffers for usage in this batchbuffer. |
* Does space-checking and asorted other book-keeping. |
* |
* @batch |
* @buffers array to buffers to validate |
* @num_of_buffers size of the passed array |
*/ |
boolean (*validate_buffers)(struct i915_winsys_batchbuffer *batch, |
struct i915_winsys_buffer **buffers, |
int num_of_buffers); |
/** |
* Emit a relocation to a buffer. |
* Target position in batchbuffer is the same as ptr. |
* |
* @batch |
* @reloc buffer address to be inserted into target. |
* @usage how is the hardware going to use the buffer. |
* @offset add this to the reloc buffers address |
* @target buffer where to write the address, null for batchbuffer. |
* @fenced relocation needs a fence. |
*/ |
int (*batchbuffer_reloc)(struct i915_winsys_batchbuffer *batch, |
struct i915_winsys_buffer *reloc, |
enum i915_winsys_buffer_usage usage, |
unsigned offset, boolean fenced); |
/** |
* Flush a bufferbatch. |
*/ |
void (*batchbuffer_flush)(struct i915_winsys_batchbuffer *batch, |
struct pipe_fence_handle **fence, |
enum i915_winsys_flush_flags flags); |
/** |
* Destroy a batchbuffer. |
*/ |
void (*batchbuffer_destroy)(struct i915_winsys_batchbuffer *batch); |
/*@}*/ |
/** |
* Buffer functions. |
*/ |
/*@{*/ |
/** |
* Create a buffer. |
*/ |
struct i915_winsys_buffer * |
(*buffer_create)(struct i915_winsys *iws, |
unsigned size, |
enum i915_winsys_buffer_type type); |
/** |
* Create a tiled buffer. |
* |
* *stride, height are in bytes. The winsys tries to allocate the buffer with |
* the tiling mode provide in *tiling. If tiling is no possible, *tiling will |
* be set to I915_TILE_NONE. The calculated stride (incorporateing hw/kernel |
* requirements) is always returned in *stride. |
*/ |
struct i915_winsys_buffer * |
(*buffer_create_tiled)(struct i915_winsys *iws, |
unsigned *stride, unsigned height, |
enum i915_winsys_buffer_tile *tiling, |
enum i915_winsys_buffer_type type); |
/** |
* Creates a buffer from a handle. |
* Used to implement pipe_screen::resource_from_handle. |
* Also provides the stride information needed for the |
* texture via the stride argument. |
*/ |
struct i915_winsys_buffer * |
(*buffer_from_handle)(struct i915_winsys *iws, |
struct winsys_handle *whandle, |
unsigned height, |
enum i915_winsys_buffer_tile *tiling, |
unsigned *stride); |
/** |
* Used to implement pipe_screen::resource_get_handle. |
* The winsys might need the stride information. |
*/ |
boolean (*buffer_get_handle)(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer, |
struct winsys_handle *whandle, |
unsigned stride); |
/** |
* Map a buffer. |
*/ |
void *(*buffer_map)(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer, |
boolean write); |
/** |
* Unmap a buffer. |
*/ |
void (*buffer_unmap)(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer); |
/** |
* Write to a buffer. |
* |
* Arguments follows pipe_buffer_write. |
*/ |
int (*buffer_write)(struct i915_winsys *iws, |
struct i915_winsys_buffer *dst, |
size_t offset, |
size_t size, |
const void *data); |
void (*buffer_destroy)(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer); |
/** |
* Check if a buffer is busy. |
*/ |
boolean (*buffer_is_busy)(struct i915_winsys *iws, |
struct i915_winsys_buffer *buffer); |
/*@}*/ |
/** |
* Fence functions. |
*/ |
/*@{*/ |
/** |
* Reference fence and set ptr to fence. |
*/ |
void (*fence_reference)(struct i915_winsys *iws, |
struct pipe_fence_handle **ptr, |
struct pipe_fence_handle *fence); |
/** |
* Check if a fence has finished. |
*/ |
int (*fence_signalled)(struct i915_winsys *iws, |
struct pipe_fence_handle *fence); |
/** |
* Wait on a fence to finish. |
*/ |
int (*fence_finish)(struct i915_winsys *iws, |
struct pipe_fence_handle *fence); |
/*@}*/ |
/** |
* Retrieve the aperture size (in MiB) of the device. |
*/ |
int (*aperture_size)(struct i915_winsys *iws); |
/** |
* Destroy the winsys. |
*/ |
void (*destroy)(struct i915_winsys *iws); |
}; |
#endif |