Compare commits
197 Commits
mesa-10.2.
...
mesa_7_7_1
Author | SHA1 | Date | |
---|---|---|---|
|
0c88e34049 | ||
|
663642b435 | ||
|
535742d75f | ||
|
8fe3b3f66a | ||
|
4cf14fa80b | ||
|
6ec259eb17 | ||
|
ca1c8a183d | ||
|
3f3b1094bf | ||
|
e33121b2d8 | ||
|
415d0326bb | ||
|
7e24ce2d9b | ||
|
2ae754b7b9 | ||
|
501156b36b | ||
|
4ff3244457 | ||
|
3889556d70 | ||
|
6412046f65 | ||
|
6e96cea6e2 | ||
|
3a3ef3d6c9 | ||
|
98aed6dc69 | ||
|
d3a607f889 | ||
|
00e41e007e | ||
|
6624845a5d | ||
|
c9c54180e4 | ||
|
93e77b0028 | ||
|
0c9e8e6c6e | ||
|
c50477c255 | ||
|
3bf13656d3 | ||
|
fa4083d38b | ||
|
d311ded31d | ||
|
34f0207161 | ||
|
8d3f629a13 | ||
|
b98ef495d4 | ||
|
21c91b410a | ||
|
a8f3b3f88a | ||
|
e8a8c5e339 | ||
|
7941d31ee6 | ||
|
842351dd76 | ||
|
d74929702f | ||
|
1e431f0454 | ||
|
4cc8d1d79f | ||
|
3d2bc6848a | ||
|
d5327538e7 | ||
|
86ac140937 | ||
|
b584e780ab | ||
|
981e8a2087 | ||
|
72d380b363 | ||
|
cf8af9bcf1 | ||
|
7123f3d77a | ||
|
2edb1b9534 | ||
|
69334d6784 | ||
|
61482ddc1c | ||
|
b0e84e22d5 | ||
|
c0e8d443fe | ||
|
b95d4cd680 | ||
|
293f4d51b4 | ||
|
f0e99179bc | ||
|
69a94e1452 | ||
|
bc7e12e5e3 | ||
|
7accf8ced6 | ||
|
52d83efdbc | ||
|
1702db3a35 | ||
|
fa6eee135e | ||
|
b5fa760972 | ||
|
69cf45cdae | ||
|
f5ffbe0bc3 | ||
|
46d8ca023d | ||
|
9bef69782d | ||
|
b0e5dcb859 | ||
|
bcd561c667 | ||
|
c98eced9ae | ||
|
13cbb5fff6 | ||
|
dd8d78c908 | ||
|
9d17ad2891 | ||
|
d437d905e6 | ||
|
551c96979e | ||
|
c1a4f249f1 | ||
|
18ff85e91d | ||
|
12617c7e30 | ||
|
5dbf44953c | ||
|
a51d638ff3 | ||
|
770945cff4 | ||
|
eaa4066bfc | ||
|
46cf606cd3 | ||
|
a69a7b9688 | ||
|
eb7590a0d9 | ||
|
86870a691c | ||
|
7c34c237a2 | ||
|
13cd4298fb | ||
|
3b724f91c5 | ||
|
2077f375c7 | ||
|
055265b0a3 | ||
|
3094adb3ca | ||
|
7c7247ddbf | ||
|
af2023e31c | ||
|
2eedbc94c2 | ||
|
672f6bb545 | ||
|
ab6bcef99a | ||
|
c5a4cfb03f | ||
|
df944efdbf | ||
|
1ff9cd5079 | ||
|
4a2b54cbdb | ||
|
6bd6a15ab3 | ||
|
c1a5c9bb4c | ||
|
b3c7dc6ff2 | ||
|
a1025ec041 | ||
|
3a4068474c | ||
|
1ae976be4a | ||
|
b685927156 | ||
|
df0c8d029d | ||
|
3477dc4c48 | ||
|
0426bccadd | ||
|
841333cd21 | ||
|
e541dceb67 | ||
|
fea7a70a1a | ||
|
426f607aaa | ||
|
408f32dc16 | ||
|
94028edfc5 | ||
|
7fec5f88a5 | ||
|
67007670bb | ||
|
e8865f199d | ||
|
2d3262d47d | ||
|
3470d821ba | ||
|
0371956d66 | ||
|
45c4addea7 | ||
|
1eba0eb37d | ||
|
d87fb5e003 | ||
|
4be7922a8e | ||
|
a1cac0732b | ||
|
fb32e0fcc5 | ||
|
9564a6fa13 | ||
|
0b9990b2fd | ||
|
8ce99c85e7 | ||
|
a2c402ba53 | ||
|
1ceb906c12 | ||
|
fb1fe8e76f | ||
|
f8b05566aa | ||
|
a6148b8eba | ||
|
64be837b0b | ||
|
e070c1d183 | ||
|
e6ee4b49c4 | ||
|
e65029e9b3 | ||
|
3ca6cb3440 | ||
|
34b36277b7 | ||
|
c8ea0212fe | ||
|
7d6cbcdd9a | ||
|
9d9c1f17dc | ||
|
f1afb352da | ||
|
e4c3abbf55 | ||
|
141b5775c0 | ||
|
c0d5f1d3ad | ||
|
70947e531e | ||
|
7b92cb45b2 | ||
|
43e4b58422 | ||
|
e0d01c9d7f | ||
|
b90b3667a1 | ||
|
0123a2d042 | ||
|
51a2cc5499 | ||
|
f5145a6ec3 | ||
|
ddedfe12d4 | ||
|
cb5447f79c | ||
|
9fd3c74724 | ||
|
4d1234e222 | ||
|
3cba779e16 | ||
|
23eda89ec8 | ||
|
6e68898b05 | ||
|
1befcd5a2a | ||
|
12ba355978 | ||
|
a0907a645f | ||
|
1acf7a09e7 | ||
|
14dc02a1b2 | ||
|
88cf87bd56 | ||
|
31b3420688 | ||
|
4e95983fa8 | ||
|
4e506eac8f | ||
|
46167149ce | ||
|
96ec4eb755 | ||
|
e20547042c | ||
|
0451d0fd01 | ||
|
aa8b23e077 | ||
|
4eb48a3af7 | ||
|
8db8adfd01 | ||
|
8e240d7e0e | ||
|
40298bf272 | ||
|
a0518e66b2 | ||
|
82c76cd16f | ||
|
50e890bc51 | ||
|
bba9557019 | ||
|
2041d3e4b7 | ||
|
77b7b3a1ab | ||
|
0dab80fbfb | ||
|
e3257912e0 | ||
|
15fe491822 | ||
|
ac597f5acc | ||
|
5cb255f0d7 | ||
|
2f28ca0a27 | ||
|
0580e488da | ||
|
5435f790fd |
2
Makefile
2
Makefile
@@ -182,7 +182,7 @@ ultrix-gcc:
|
||||
|
||||
# Rules for making release tarballs
|
||||
|
||||
VERSION=7.7.1-devel
|
||||
VERSION=7.7.1
|
||||
DIRECTORY = Mesa-$(VERSION)
|
||||
LIB_NAME = MesaLib-$(VERSION)
|
||||
DEMO_NAME = MesaDemos-$(VERSION)
|
||||
|
@@ -920,6 +920,11 @@ case $ARCH in
|
||||
|
||||
# make lib
|
||||
${LINK} ${OPTS} ${LDFLAGS} -o ${CYGNAME}-${MAJOR}.dll ${OBJECTS} ${DEPS}
|
||||
# make build fail if link failed
|
||||
es=$?
|
||||
if [ "$es" -ne "0" ]; then
|
||||
exit $es
|
||||
fi
|
||||
# make usual symlinks
|
||||
ln -s ${LIBNAME}-${MAJOR}.dll.a ${LIBNAME}.dll.a
|
||||
# finish up
|
||||
|
19
configure.ac
19
configure.ac
@@ -20,6 +20,8 @@ AC_CANONICAL_HOST
|
||||
dnl Versions for external dependencies
|
||||
LIBDRM_REQUIRED=2.4.15
|
||||
LIBDRM_RADEON_REQUIRED=2.4.17
|
||||
LIBDRM_XORG_REQUIRED=2.4.17
|
||||
LIBKMS_XORG_REQUIRED=1.0.0
|
||||
DRI2PROTO_REQUIRED=1.99.3
|
||||
|
||||
dnl Check for progs
|
||||
@@ -91,6 +93,9 @@ linux*|*-gnu*|gnu*)
|
||||
solaris*)
|
||||
DEFINES="$DEFINES -DPTHREADS -DSVR4"
|
||||
;;
|
||||
cygwin*)
|
||||
DEFINES="$DEFINES -DPTHREADS"
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Add flags for gcc and g++
|
||||
@@ -1149,7 +1154,7 @@ yes)
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
|
||||
fi
|
||||
# Have only tested st/xorg on 1.6.0 servers
|
||||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0],
|
||||
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0 libdrm >= $LIBDRM_XORG_REQUIRED libkms >= $LIBKMS_XORG_REQUIRED],
|
||||
HAVE_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
|
||||
HAVE_XORG="no")
|
||||
;;
|
||||
@@ -1166,15 +1171,21 @@ yes)
|
||||
AC_MSG_ERROR([cannot build egl state tracker without EGL library])
|
||||
fi
|
||||
if test "$tracker" = xorg; then
|
||||
PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
|
||||
HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
|
||||
HAVE_XEXTPROTO_71="no")
|
||||
PKG_CHECK_MODULES([LIBDRM_XORG], [libdrm >= $LIBDRM_XORG_REQUIRED])
|
||||
PKG_CHECK_MODULES([LIBKMS_XORG], [libkms >= $LIBKMS_XORG_REQUIRED])
|
||||
HAVE_XORG="yes"
|
||||
fi
|
||||
done
|
||||
GALLIUM_STATE_TRACKERS_DIRS="$state_trackers"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "x$HAVE_XORG" = xyes; then
|
||||
PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
|
||||
HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71",
|
||||
HAVE_XEXTPROTO_71="no")
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([xorg-driver-dir],
|
||||
[AS_HELP_STRING([--with-xorg-driver-dir=DIR],
|
||||
[Default xorg driver directory[[default=${libdir}/xorg/modules/drivers]]])],
|
||||
|
@@ -10,6 +10,15 @@
|
||||
|
||||
<H1>News</H1>
|
||||
|
||||
|
||||
<h2>March 26, 2010</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.7.1.html">Mesa 7.7.1</a> is released. This is a bug-fix
|
||||
release fixing issues found in the 7.7 release.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h2>December 21, 2009</h2>
|
||||
<p>
|
||||
<a href="relnotes-7.6.1.html">Mesa 7.6.1</a> is released. This is a bug-fix
|
||||
|
@@ -26,7 +26,7 @@ more information about the API functions.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are several examples of OSMesa in the <code>progs/osdemo/</code>
|
||||
There are several examples of OSMesa in the <code>progs/osdemos/</code>
|
||||
directory.
|
||||
</p>
|
||||
|
||||
|
@@ -8,7 +8,7 @@
|
||||
|
||||
<body bgcolor="#eeeeee">
|
||||
|
||||
<H1>Mesa 7.7.1 Release Notes / date tbd</H1>
|
||||
<H1>Mesa 7.7.1 Release Notes / March 28, 2010</H1>
|
||||
|
||||
<p>
|
||||
Mesa 7.7.1 is a bug-fix release.
|
||||
@@ -26,16 +26,18 @@ for DRI hardware acceleration.
|
||||
|
||||
<h2>MD5 checksums</h2>
|
||||
<pre>
|
||||
tbd
|
||||
3ab0638cfa7ce8157337a229cf0db2c4 MesaLib-7.7.1.tar.gz
|
||||
46664d99e03f1e3ac078a7fea02af115 MesaLib-7.7.1.tar.bz2
|
||||
4e73ba8abb59aff79485eb95d7cefff7 MesaLib-7.7.1.zip
|
||||
bf1b108983995f7a712cf3343df1c918 MesaDemos-7.7.1.tar.gz
|
||||
aeb39645d80d656e0adebaa09e5bcd03 MesaDemos-7.7.1.tar.bz2
|
||||
01c49b7454fd292244eaf8bdc6ed8cf0 MesaDemos-7.7.1.zip
|
||||
37ec6386693dcb6dc770d1efd63a7a93 MesaGLUT-7.7.1.tar.gz
|
||||
1e16c85282f843791a21f7bc7b6a1ca8 MesaGLUT-7.7.1.tar.bz2
|
||||
d352c9e36a8e4d1059f4abc017b131e0 MesaGLUT-7.7.1.zip
|
||||
</pre>
|
||||
|
||||
|
||||
<h2>New features</h2>
|
||||
<ul>
|
||||
<li>tbd
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Bug fixes</h2>
|
||||
<ul>
|
||||
<li>Assorted fixes to VMware SVGA gallium driver.
|
||||
@@ -43,6 +45,14 @@ tbd
|
||||
<li>Allocate constants more tightly in GL_ARB_vertex/fragment parser.
|
||||
<li>Fixed mipmap generation bug caused by invalid viewport state.
|
||||
<li>Gallium SSE codegen for XPD didn't always work.
|
||||
<li>Fixed Windows build.
|
||||
<li>Fixed broken glMultiDrawElements().
|
||||
<li>Silence bogus GL errors generated in glxinfo.
|
||||
<li>Fixed several render to texture bugs.
|
||||
<li>Assorted bug fixes in Mesa/Gallium state tracker including
|
||||
glCopy/DrawPixels() to FBOs.
|
||||
<li>Assorted fixes to Gallium drivers.
|
||||
<li>Fixed broken glPush/PopClientAttrib() for vertex arrays in GLX code.
|
||||
</ul>
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<HTML>
|
||||
|
||||
<TITLE>Cocd Repository</TITLE>
|
||||
<TITLE>Code Repository</TITLE>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="mesa.css"></head>
|
||||
|
||||
|
@@ -171,7 +171,7 @@ print_program_limits(GLenum target)
|
||||
GLenum token;
|
||||
const char *name;
|
||||
};
|
||||
static const struct token_name limits[] = {
|
||||
static const struct token_name common_limits[] = {
|
||||
{ GL_MAX_PROGRAM_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" },
|
||||
{ GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" },
|
||||
{ GL_MAX_PROGRAM_TEMPORARIES_ARB, "GL_MAX_PROGRAM_TEMPORARIES_ARB" },
|
||||
@@ -184,6 +184,9 @@ print_program_limits(GLenum target)
|
||||
{ GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" },
|
||||
{ GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" },
|
||||
{ GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" },
|
||||
{ (GLenum) 0, NULL }
|
||||
};
|
||||
static const struct token_name fragment_limits[] = {
|
||||
{ GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" },
|
||||
{ GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" },
|
||||
{ GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" },
|
||||
@@ -192,8 +195,10 @@ print_program_limits(GLenum target)
|
||||
{ GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" },
|
||||
{ (GLenum) 0, NULL }
|
||||
};
|
||||
|
||||
PFNGLGETPROGRAMIVARBPROC GetProgramivARB_func = (PFNGLGETPROGRAMIVARBPROC)
|
||||
glXGetProcAddressARB((GLubyte *) "glGetProgramivARB");
|
||||
|
||||
GLint max[1];
|
||||
int i;
|
||||
|
||||
@@ -207,10 +212,18 @@ print_program_limits(GLenum target)
|
||||
return; /* something's wrong */
|
||||
}
|
||||
|
||||
for (i = 0; limits[i].token; i++) {
|
||||
GetProgramivARB_func(target, limits[i].token, max);
|
||||
for (i = 0; common_limits[i].token; i++) {
|
||||
GetProgramivARB_func(target, common_limits[i].token, max);
|
||||
if (glGetError() == GL_NO_ERROR) {
|
||||
printf(" %s = %d\n", limits[i].name, max[0]);
|
||||
printf(" %s = %d\n", common_limits[i].name, max[0]);
|
||||
}
|
||||
}
|
||||
if (target == GL_FRAGMENT_PROGRAM_ARB) {
|
||||
for (i = 0; fragment_limits[i].token; i++) {
|
||||
GetProgramivARB_func(target, fragment_limits[i].token, max);
|
||||
if (glGetError() == GL_NO_ERROR) {
|
||||
printf(" %s = %d\n", fragment_limits[i].name, max[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* GL_ARB_vertex_program / GL_ARB_fragment_program */
|
||||
|
@@ -53,6 +53,7 @@ prefixes = SCons.Util.Split("""
|
||||
i486-mingw32msvc-
|
||||
i586-mingw32msvc-
|
||||
i686-mingw32msvc-
|
||||
i686-pc-mingw32-
|
||||
""")
|
||||
|
||||
def find(env):
|
||||
|
@@ -235,7 +235,9 @@ def generate(env):
|
||||
# different scons versions building the same source file
|
||||
env['build'] = build_dir
|
||||
env.SConsignFile(os.path.join(build_dir, '.sconsign'))
|
||||
env.CacheDir('build/cache')
|
||||
if 'SCONS_CACHE_DIR' in os.environ:
|
||||
print 'scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],)
|
||||
env.CacheDir(os.environ['SCONS_CACHE_DIR'])
|
||||
|
||||
# Parallel build
|
||||
if env.GetOption('num_jobs') <= 1:
|
||||
@@ -255,8 +257,9 @@ def generate(env):
|
||||
'_WINDOWS',
|
||||
#'_UNICODE',
|
||||
#'UNICODE',
|
||||
('_WIN32_WINNT', '0x0501'), # minimum required OS version
|
||||
('WINVER', '0x0501'),
|
||||
# http://msdn.microsoft.com/en-us/library/aa383745.aspx
|
||||
('_WIN32_WINNT', '0x0601'),
|
||||
('WINVER', '0x0601'),
|
||||
# http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx,
|
||||
'WIN32_LEAN_AND_MEAN',
|
||||
]
|
||||
|
@@ -347,7 +347,8 @@ vcache_check_run( struct draw_pt_front_end *frontend,
|
||||
draw_count);
|
||||
|
||||
if (max_index == 0xffffffff ||
|
||||
fetch_count > draw_count) {
|
||||
fetch_count > draw_count ||
|
||||
max_index != (max_index & ~DRAW_PIPE_FLAG_MASK)) {
|
||||
if (0) debug_printf("fail\n");
|
||||
goto fail;
|
||||
}
|
||||
|
@@ -179,7 +179,9 @@ pb_debug_buffer_check(struct pb_debug_buffer *buf)
|
||||
{
|
||||
uint8_t *map;
|
||||
|
||||
map = pb_map(buf->buffer, PIPE_BUFFER_USAGE_CPU_READ);
|
||||
map = pb_map(buf->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ |
|
||||
PIPE_BUFFER_USAGE_UNSYNCHRONIZED);
|
||||
assert(map);
|
||||
if(map) {
|
||||
boolean underflow, overflow;
|
||||
|
@@ -133,8 +133,7 @@ static const union tgsi_exec_channel ZeroVec =
|
||||
{ { 0.0, 0.0, 0.0, 0.0 } };
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
static INLINE void
|
||||
check_inf_or_nan(const union tgsi_exec_channel *chan)
|
||||
{
|
||||
assert(!util_is_inf_or_nan(chan->f[0]));
|
||||
@@ -142,7 +141,6 @@ check_inf_or_nan(const union tgsi_exec_channel *chan)
|
||||
assert(!util_is_inf_or_nan(chan->f[2]));
|
||||
assert(!util_is_inf_or_nan(chan->f[3]));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -338,7 +336,9 @@ tgsi_exec_machine_bind_shader(
|
||||
/* XXX we only handle SOA dependencies properly for MOV/SWZ
|
||||
* at this time!
|
||||
*/
|
||||
if (opcode != TGSI_OPCODE_MOV) {
|
||||
if (opcode != TGSI_OPCODE_MOV &&
|
||||
opcode != TGSI_OPCODE_MUL &&
|
||||
opcode != TGSI_OPCODE_CMP) {
|
||||
debug_printf("Warning: SOA dependency in instruction"
|
||||
" is not handled:\n");
|
||||
tgsi_dump_instruction(&parse.FullToken.FullInstruction,
|
||||
@@ -1424,9 +1424,9 @@ store_dest(
|
||||
int offset = 0; /* indirection offset */
|
||||
int index;
|
||||
|
||||
#ifdef DEBUG
|
||||
check_inf_or_nan(chan);
|
||||
#endif
|
||||
if (0) {
|
||||
check_inf_or_nan(chan);
|
||||
}
|
||||
|
||||
/* There is an extra source register that indirectly subscripts
|
||||
* a register file. The direct index now becomes an offset
|
||||
@@ -1854,7 +1854,8 @@ exec_instruction(
|
||||
int *pc )
|
||||
{
|
||||
uint chan_index;
|
||||
union tgsi_exec_channel r[10];
|
||||
union tgsi_exec_channel r[3 * NUM_CHANNELS];
|
||||
union tgsi_exec_channel d[8];
|
||||
|
||||
(*pc)++;
|
||||
|
||||
@@ -1981,14 +1982,27 @@ exec_instruction(
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_MUL:
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
|
||||
{
|
||||
FETCH(&r[0], 0, chan_index);
|
||||
FETCH(&r[1], 1, chan_index);
|
||||
if (inst->Flags & SOA_DEPENDENCY_FLAG) {
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
|
||||
{
|
||||
FETCH(&r[chan_index], 0, chan_index);
|
||||
FETCH(&r[chan_index + NUM_CHANNELS], 1, chan_index);
|
||||
}
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
|
||||
{
|
||||
micro_mul( &r[chan_index], &r[chan_index], &r[chan_index + NUM_CHANNELS] );
|
||||
STORE(&r[chan_index], 0, chan_index);
|
||||
}
|
||||
} else {
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index )
|
||||
{
|
||||
FETCH(&r[0], 0, chan_index);
|
||||
FETCH(&r[1], 1, chan_index);
|
||||
|
||||
micro_mul( &r[0], &r[0], &r[1] );
|
||||
micro_mul( &r[0], &r[0], &r[1] );
|
||||
|
||||
STORE(&r[0], 0, chan_index);
|
||||
STORE(&r[0], 0, chan_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2255,11 +2269,7 @@ exec_instruction(
|
||||
FETCH(&r[4], 1, CHAN_Y);
|
||||
|
||||
micro_mul( &r[5], &r[3], &r[4] );
|
||||
micro_sub( &r[2], &r[2], &r[5] );
|
||||
|
||||
if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) {
|
||||
STORE( &r[2], 0, CHAN_X );
|
||||
}
|
||||
micro_sub(&d[CHAN_X], &r[2], &r[5]);
|
||||
|
||||
FETCH(&r[2], 1, CHAN_X);
|
||||
|
||||
@@ -2268,26 +2278,27 @@ exec_instruction(
|
||||
FETCH(&r[5], 0, CHAN_X);
|
||||
|
||||
micro_mul( &r[1], &r[1], &r[5] );
|
||||
micro_sub( &r[3], &r[3], &r[1] );
|
||||
|
||||
if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) {
|
||||
STORE( &r[3], 0, CHAN_Y );
|
||||
}
|
||||
micro_sub(&d[CHAN_Y], &r[3], &r[1]);
|
||||
|
||||
micro_mul( &r[5], &r[5], &r[4] );
|
||||
micro_mul( &r[0], &r[0], &r[2] );
|
||||
micro_sub( &r[5], &r[5], &r[0] );
|
||||
micro_sub(&d[CHAN_Z], &r[5], &r[0]);
|
||||
|
||||
if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) {
|
||||
STORE( &r[5], 0, CHAN_Z );
|
||||
if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) {
|
||||
STORE(&d[CHAN_X], 0, CHAN_X);
|
||||
}
|
||||
if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) {
|
||||
STORE(&d[CHAN_Y], 0, CHAN_Y);
|
||||
}
|
||||
if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) {
|
||||
STORE(&d[CHAN_Z], 0, CHAN_Z);
|
||||
}
|
||||
|
||||
if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) {
|
||||
STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W );
|
||||
}
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_ABS:
|
||||
case TGSI_OPCODE_ABS:
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
FETCH(&r[0], 0, chan_index);
|
||||
|
||||
@@ -2667,14 +2678,28 @@ exec_instruction(
|
||||
break;
|
||||
|
||||
case TGSI_OPCODE_CMP:
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
FETCH(&r[0], 0, chan_index);
|
||||
FETCH(&r[1], 1, chan_index);
|
||||
FETCH(&r[2], 2, chan_index);
|
||||
if (inst->Flags & SOA_DEPENDENCY_FLAG) {
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
FETCH(&r[chan_index], 0, chan_index);
|
||||
FETCH(&r[chan_index + NUM_CHANNELS], 1, chan_index);
|
||||
FETCH(&r[chan_index + 2 * NUM_CHANNELS], 2, chan_index);
|
||||
}
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
micro_lt( &r[chan_index], &r[chan_index],
|
||||
&mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[chan_index + NUM_CHANNELS],
|
||||
&r[chan_index + 2*NUM_CHANNELS] );
|
||||
STORE(&r[chan_index], 0, chan_index);
|
||||
}
|
||||
} else {
|
||||
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
|
||||
FETCH(&r[0], 0, chan_index);
|
||||
FETCH(&r[1], 1, chan_index);
|
||||
FETCH(&r[2], 2, chan_index);
|
||||
|
||||
micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
|
||||
micro_lt( &r[0], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[1], &r[2] );
|
||||
|
||||
STORE(&r[0], 0, chan_index);
|
||||
STORE(&r[0], 0, chan_index);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@@ -216,6 +216,9 @@ iter_instruction(
|
||||
inst->FullDstRegisters[i].DstRegister.Index,
|
||||
"destination",
|
||||
FALSE );
|
||||
if (!inst->FullDstRegisters[i].DstRegister.WriteMask) {
|
||||
report_error(ctx, "Destination register has empty writemask");
|
||||
}
|
||||
}
|
||||
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
|
||||
check_register_usage(
|
||||
|
@@ -644,6 +644,57 @@ void debug_dump_image(const char *prefix,
|
||||
}
|
||||
|
||||
EngUnmapFile(iFile);
|
||||
#elif defined(PIPE_OS_UNIX)
|
||||
/* write a ppm file */
|
||||
char filename[256];
|
||||
FILE *f;
|
||||
|
||||
util_snprintf(filename, sizeof(filename), "%s.ppm", prefix);
|
||||
|
||||
f = fopen(filename, "w");
|
||||
if (f) {
|
||||
int i, x, y;
|
||||
int r, g, b;
|
||||
const uint8_t *ptr = (uint8_t *) data;
|
||||
|
||||
/* XXX this is a hack */
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
r = 2;
|
||||
g = 1;
|
||||
b = 0;
|
||||
break;
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
b = 0;
|
||||
g = 1;
|
||||
r = 2;
|
||||
break;
|
||||
default:
|
||||
r = 0;
|
||||
g = 1;
|
||||
b = 2;
|
||||
}
|
||||
|
||||
fprintf(f, "P6\n");
|
||||
fprintf(f, "# ppm-file created by osdemo.c\n");
|
||||
fprintf(f, "%i %i\n", width, height);
|
||||
fprintf(f, "255\n");
|
||||
fclose(f);
|
||||
|
||||
f = fopen(filename, "ab"); /* reopen in binary append mode */
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
i = y * stride + x * cpp;
|
||||
fputc(ptr[i + r], f); /* write red */
|
||||
fputc(ptr[i + g], f); /* write green */
|
||||
fputc(ptr[i + b], f); /* write blue */
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Can't open %s for writing\n", filename);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -628,7 +628,8 @@ lp_build_abs(struct lp_build_context *bld,
|
||||
if(type.floating) {
|
||||
/* Mask out the sign bit */
|
||||
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
|
||||
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long)1 << type.width) - 1);
|
||||
unsigned long absMask = ~(1 << (type.width - 1));
|
||||
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
|
||||
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
|
||||
a = LLVMBuildAnd(bld->builder, a, mask, "");
|
||||
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
|
||||
@@ -1082,7 +1083,7 @@ lp_build_log(struct lp_build_context *bld,
|
||||
LLVMValueRef x)
|
||||
{
|
||||
/* log(2) */
|
||||
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
|
||||
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
|
||||
|
||||
return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
|
||||
}
|
||||
@@ -1094,7 +1095,7 @@ lp_build_log(struct lp_build_context *bld,
|
||||
|
||||
/**
|
||||
* Generate polynomial.
|
||||
* Ex: x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
|
||||
* Ex: coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
|
||||
*/
|
||||
static LLVMValueRef
|
||||
lp_build_polynomial(struct lp_build_context *bld,
|
||||
@@ -1284,13 +1285,13 @@ lp_build_log2_approx(struct lp_build_context *bld,
|
||||
/* mant = (float) mantissa(x) */
|
||||
mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
|
||||
mant = LLVMBuildOr(bld->builder, mant, one, "");
|
||||
mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
|
||||
mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
|
||||
|
||||
logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
|
||||
Elements(lp_build_log2_polynomial));
|
||||
|
||||
/* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
|
||||
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
|
||||
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
|
||||
|
||||
res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
|
||||
}
|
||||
|
@@ -766,7 +766,7 @@ emit_instruction(
|
||||
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
|
||||
src0 = emit_fetch( bld, inst, 0, chan_index );
|
||||
tmp0 = lp_build_floor(&bld->base, src0);
|
||||
tmp0 = lp_build_sub(&bld->base, tmp0, src0);
|
||||
tmp0 = lp_build_sub(&bld->base, src0, tmp0);
|
||||
dst0[chan_index] = tmp0;
|
||||
}
|
||||
break;
|
||||
|
71
src/gallium/drivers/llvmpipe/lp_debug.h
Normal file
71
src/gallium/drivers/llvmpipe/lp_debug.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* 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 TUNGSTEN GRAPHICS 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 LP_DEBUG_H
|
||||
#define LP_DEBUG_H
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "util/u_debug.h"
|
||||
|
||||
extern void
|
||||
st_print_current(void);
|
||||
|
||||
|
||||
#define DEBUG_PIPE 0x1
|
||||
#define DEBUG_TGSI 0x2
|
||||
#define DEBUG_TEX 0x4
|
||||
#define DEBUG_ASM 0x8
|
||||
#define DEBUG_SETUP 0x10
|
||||
#define DEBUG_RAST 0x20
|
||||
#define DEBUG_QUERY 0x40
|
||||
#define DEBUG_SCREEN 0x80
|
||||
#define DEBUG_JIT 0x100
|
||||
|
||||
#ifdef DEBUG
|
||||
extern int LP_DEBUG;
|
||||
#else
|
||||
#define LP_DEBUG 0
|
||||
#endif
|
||||
|
||||
void st_debug_init( void );
|
||||
|
||||
static INLINE void
|
||||
LP_DBG( unsigned flag, const char *fmt, ... )
|
||||
{
|
||||
if (LP_DEBUG & flag)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start( args, fmt );
|
||||
debug_vprintf( fmt, args );
|
||||
va_end( args );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* LP_DEBUG_H */
|
@@ -101,7 +101,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
|
||||
draw_arrays(draw, mode, start, count);
|
||||
|
||||
/*
|
||||
* unmap vertex/index buffers - will cause draw module to flush
|
||||
* unmap vertex/index buffers
|
||||
*/
|
||||
for (i = 0; i < lp->num_vertex_buffers; i++) {
|
||||
draw_set_mapped_vertex_buffer(draw, i, NULL);
|
||||
@@ -110,6 +110,12 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
|
||||
draw_set_mapped_element_buffer(draw, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Flush only when a user vertex/index buffer is present
|
||||
* (or even better, modify draw module to do this
|
||||
* internally when this condition is seen?)
|
||||
*/
|
||||
draw_flush(draw);
|
||||
|
||||
/* Note: leave drawing surfaces mapped */
|
||||
|
||||
|
@@ -166,7 +166,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen)
|
||||
if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) {
|
||||
_debug_printf("%s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
abort();
|
||||
assert(0);
|
||||
}
|
||||
|
||||
screen->target = LLVMGetExecutionEngineTargetData(screen->engine);
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_format.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_screen.h"
|
||||
|
||||
@@ -35,6 +36,24 @@
|
||||
#include "lp_winsys.h"
|
||||
#include "lp_jit.h"
|
||||
#include "lp_screen.h"
|
||||
#include "lp_debug.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
int LP_DEBUG = 0;
|
||||
|
||||
static const struct debug_named_value lp_debug_flags[] = {
|
||||
{ "pipe", DEBUG_PIPE },
|
||||
{ "tgsi", DEBUG_TGSI },
|
||||
{ "tex", DEBUG_TEX },
|
||||
{ "asm", DEBUG_ASM },
|
||||
{ "setup", DEBUG_SETUP },
|
||||
{ "rast", DEBUG_RAST },
|
||||
{ "query", DEBUG_QUERY },
|
||||
{ "screen", DEBUG_SCREEN },
|
||||
{ "jit", DEBUG_JIT },
|
||||
{NULL, 0}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static const char *
|
||||
@@ -131,17 +150,17 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
|
||||
{
|
||||
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
|
||||
struct llvmpipe_winsys *winsys = screen->winsys;
|
||||
const struct util_format_description *format_desc;
|
||||
|
||||
format_desc = util_format_description(format);
|
||||
if(!format_desc)
|
||||
return FALSE;
|
||||
|
||||
assert(target == PIPE_TEXTURE_1D ||
|
||||
target == PIPE_TEXTURE_2D ||
|
||||
target == PIPE_TEXTURE_3D ||
|
||||
target == PIPE_TEXTURE_CUBE);
|
||||
|
||||
if(format == PIPE_FORMAT_Z16_UNORM)
|
||||
return FALSE;
|
||||
if(format == PIPE_FORMAT_S8_UNORM)
|
||||
return FALSE;
|
||||
|
||||
switch(format) {
|
||||
case PIPE_FORMAT_DXT1_RGB:
|
||||
case PIPE_FORMAT_DXT1_RGBA:
|
||||
@@ -152,8 +171,51 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen,
|
||||
break;
|
||||
}
|
||||
|
||||
if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
|
||||
return winsys->is_displaytarget_format_supported(winsys, format);
|
||||
if(tex_usage & PIPE_TEXTURE_USAGE_RENDER_TARGET) {
|
||||
if(format_desc->block.width != 1 ||
|
||||
format_desc->block.height != 1)
|
||||
return FALSE;
|
||||
|
||||
if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
|
||||
format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
|
||||
format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
|
||||
return FALSE;
|
||||
|
||||
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
|
||||
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET) {
|
||||
if(!winsys->is_displaytarget_format_supported(winsys, format))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
|
||||
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: Temporary restriction. See lp_state_fs.c. */
|
||||
if(format_desc->block.bits != 32)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: Temporary restrictions. See lp_bld_sample_soa.c */
|
||||
if(tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) {
|
||||
if(format_desc->block.width != 1 ||
|
||||
format_desc->block.height != 1)
|
||||
return FALSE;
|
||||
|
||||
if(format_desc->layout != UTIL_FORMAT_LAYOUT_SCALAR &&
|
||||
format_desc->layout != UTIL_FORMAT_LAYOUT_ARITH &&
|
||||
format_desc->layout != UTIL_FORMAT_LAYOUT_ARRAY)
|
||||
return FALSE;
|
||||
|
||||
if(format_desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB &&
|
||||
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_SRGB &&
|
||||
format_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -213,6 +275,10 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
|
||||
{
|
||||
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
|
||||
|
||||
#ifdef DEBUG
|
||||
LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
|
||||
#endif
|
||||
|
||||
if (!screen)
|
||||
return NULL;
|
||||
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_debug_dump.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "lp_screen.h"
|
||||
#include "lp_context.h"
|
||||
#include "lp_state.h"
|
||||
@@ -51,6 +52,11 @@ void llvmpipe_bind_blend_state( struct pipe_context *pipe,
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
if (llvmpipe->blend == blend)
|
||||
return;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
llvmpipe->blend = blend;
|
||||
|
||||
llvmpipe->dirty |= LP_NEW_BLEND;
|
||||
@@ -69,6 +75,11 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
unsigned i, j;
|
||||
|
||||
if(memcmp(&llvmpipe->blend_color, blend_color, sizeof *blend_color) == 0)
|
||||
return;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
|
||||
|
||||
if(!llvmpipe->jit_context.blend_color)
|
||||
@@ -99,7 +110,12 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
|
||||
if (llvmpipe->depth_stencil == depth_stencil)
|
||||
return;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
llvmpipe->depth_stencil = depth_stencil;
|
||||
|
||||
if(llvmpipe->depth_stencil)
|
||||
llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;
|
||||
|
@@ -85,6 +85,7 @@
|
||||
#include "lp_buffer.h"
|
||||
#include "lp_state.h"
|
||||
#include "lp_tex_sample.h"
|
||||
#include "lp_debug.h"
|
||||
|
||||
|
||||
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
|
||||
@@ -146,6 +147,20 @@ generate_depth(LLVMBuilderRef builder,
|
||||
format_desc = util_format_description(key->zsbuf_format);
|
||||
assert(format_desc);
|
||||
|
||||
/*
|
||||
* Depths are expected to be between 0 and 1, even if they are stored in
|
||||
* floats. Setting these bits here will ensure that the lp_build_conv() call
|
||||
* below won't try to unnecessarily clamp the incoming values.
|
||||
*/
|
||||
if(src_type.floating) {
|
||||
src_type.sign = FALSE;
|
||||
src_type.norm = TRUE;
|
||||
}
|
||||
else {
|
||||
assert(!src_type.sign);
|
||||
assert(src_type.norm);
|
||||
}
|
||||
|
||||
/* Pick the depth type. */
|
||||
dst_type = lp_depth_type(format_desc, src_type.width*src_type.length);
|
||||
|
||||
@@ -153,14 +168,11 @@ generate_depth(LLVMBuilderRef builder,
|
||||
assert(dst_type.width == src_type.width);
|
||||
assert(dst_type.length == src_type.length);
|
||||
|
||||
#if 1
|
||||
src = lp_build_clamped_float_to_unsigned_norm(builder,
|
||||
src_type,
|
||||
dst_type.width,
|
||||
src);
|
||||
#else
|
||||
lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
|
||||
#endif
|
||||
|
||||
dst_ptr = LLVMBuildBitCast(builder,
|
||||
dst_ptr,
|
||||
LLVMPointerType(lp_build_vec_type(dst_type), 0), "");
|
||||
|
||||
lp_build_depth_test(builder,
|
||||
&key->depth,
|
||||
@@ -395,59 +407,58 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
unsigned i;
|
||||
unsigned chan;
|
||||
|
||||
#ifdef DEBUG
|
||||
tgsi_dump(shader->base.tokens, 0);
|
||||
if(key->depth.enabled) {
|
||||
debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
|
||||
debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
|
||||
debug_printf("depth.writemask = %u\n", key->depth.writemask);
|
||||
}
|
||||
if(key->alpha.enabled) {
|
||||
debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
|
||||
debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
|
||||
}
|
||||
if(key->blend.logicop_enable) {
|
||||
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
|
||||
}
|
||||
else if(key->blend.blend_enable) {
|
||||
debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
|
||||
debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
|
||||
debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
|
||||
debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
|
||||
debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
|
||||
debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
|
||||
}
|
||||
debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
|
||||
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
|
||||
if(key->sampler[i].format) {
|
||||
debug_printf("sampler[%u] = \n", i);
|
||||
debug_printf(" .format = %s\n",
|
||||
pf_name(key->sampler[i].format));
|
||||
debug_printf(" .target = %s\n",
|
||||
debug_dump_tex_target(key->sampler[i].target, TRUE));
|
||||
debug_printf(" .pot = %u %u %u\n",
|
||||
key->sampler[i].pot_width,
|
||||
key->sampler[i].pot_height,
|
||||
key->sampler[i].pot_depth);
|
||||
debug_printf(" .wrap = %s %s %s\n",
|
||||
debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
|
||||
debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
|
||||
debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
|
||||
debug_printf(" .min_img_filter = %s\n",
|
||||
debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
|
||||
debug_printf(" .min_mip_filter = %s\n",
|
||||
debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
|
||||
debug_printf(" .mag_img_filter = %s\n",
|
||||
debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
|
||||
if(key->sampler[i].compare_mode)
|
||||
debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
|
||||
debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
|
||||
debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
|
||||
if (LP_DEBUG & DEBUG_JIT) {
|
||||
tgsi_dump(shader->base.tokens, 0);
|
||||
if(key->depth.enabled) {
|
||||
debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
|
||||
debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
|
||||
debug_printf("depth.writemask = %u\n", key->depth.writemask);
|
||||
}
|
||||
if(key->alpha.enabled) {
|
||||
debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
|
||||
debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
|
||||
}
|
||||
if(key->blend.logicop_enable) {
|
||||
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
|
||||
}
|
||||
else if(key->blend.blend_enable) {
|
||||
debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
|
||||
debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
|
||||
debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
|
||||
debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
|
||||
debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
|
||||
debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
|
||||
}
|
||||
debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
|
||||
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
|
||||
if(key->sampler[i].format) {
|
||||
debug_printf("sampler[%u] = \n", i);
|
||||
debug_printf(" .format = %s\n",
|
||||
pf_name(key->sampler[i].format));
|
||||
debug_printf(" .target = %s\n",
|
||||
debug_dump_tex_target(key->sampler[i].target, TRUE));
|
||||
debug_printf(" .pot = %u %u %u\n",
|
||||
key->sampler[i].pot_width,
|
||||
key->sampler[i].pot_height,
|
||||
key->sampler[i].pot_depth);
|
||||
debug_printf(" .wrap = %s %s %s\n",
|
||||
debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
|
||||
debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
|
||||
debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
|
||||
debug_printf(" .min_img_filter = %s\n",
|
||||
debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
|
||||
debug_printf(" .min_mip_filter = %s\n",
|
||||
debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
|
||||
debug_printf(" .mag_img_filter = %s\n",
|
||||
debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
|
||||
if(key->sampler[i].compare_mode)
|
||||
debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
|
||||
debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
|
||||
debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
|
||||
if(!variant)
|
||||
return NULL;
|
||||
@@ -586,8 +597,8 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
}
|
||||
|
||||
lp_build_conv_mask(builder, fs_type, blend_type,
|
||||
fs_mask, num_fs,
|
||||
&blend_mask, 1);
|
||||
fs_mask, num_fs,
|
||||
&blend_mask, 1);
|
||||
|
||||
/*
|
||||
* Blending.
|
||||
@@ -609,23 +620,24 @@ generate_fragment(struct llvmpipe_context *lp,
|
||||
* Translate the LLVM IR into machine code.
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) {
|
||||
LLVMDumpValue(variant->function);
|
||||
abort();
|
||||
assert(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
LLVMRunFunctionPassManager(screen->pass, variant->function);
|
||||
|
||||
#ifdef DEBUG
|
||||
LLVMDumpValue(variant->function);
|
||||
debug_printf("\n");
|
||||
#endif
|
||||
if (LP_DEBUG & DEBUG_JIT) {
|
||||
LLVMDumpValue(variant->function);
|
||||
debug_printf("\n");
|
||||
}
|
||||
|
||||
variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
|
||||
|
||||
#ifdef DEBUG
|
||||
lp_disassemble(variant->jit_function);
|
||||
#endif
|
||||
if (LP_DEBUG & DEBUG_ASM)
|
||||
lp_disassemble(variant->jit_function);
|
||||
|
||||
variant->next = shader->variants;
|
||||
shader->variants = variant;
|
||||
@@ -659,7 +671,12 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
llvmpipe->fs = (struct lp_fragment_shader *) fs;
|
||||
if (llvmpipe->fs == fs)
|
||||
return;
|
||||
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
llvmpipe->fs = fs;
|
||||
|
||||
llvmpipe->dirty |= LP_NEW_FS;
|
||||
}
|
||||
@@ -710,8 +727,7 @@ llvmpipe_set_constant_buffer(struct pipe_context *pipe,
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index == 0);
|
||||
|
||||
if(shader == PIPE_SHADER_VERTEX)
|
||||
draw_flush(llvmpipe->draw);
|
||||
draw_flush(llvmpipe->draw);
|
||||
|
||||
/* note: reference counting */
|
||||
pipe_buffer_reference(&llvmpipe->constants[shader].buffer, buffer);
|
||||
|
@@ -41,14 +41,17 @@ llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
|
||||
}
|
||||
|
||||
void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
|
||||
void *setup)
|
||||
void *rasterizer)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
|
||||
/* pass-through to draw module */
|
||||
draw_set_rasterizer_state(llvmpipe->draw, setup);
|
||||
if (llvmpipe->rasterizer == rasterizer)
|
||||
return;
|
||||
|
||||
llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
|
||||
/* pass-through to draw module */
|
||||
draw_set_rasterizer_state(llvmpipe->draw, rasterizer);
|
||||
|
||||
llvmpipe->rasterizer = rasterizer;
|
||||
|
||||
llvmpipe->dirty |= LP_NEW_RASTERIZER;
|
||||
}
|
||||
|
@@ -48,6 +48,8 @@ llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
|
||||
struct llvmpipe_context *lp = llvmpipe_context(pipe);
|
||||
uint i;
|
||||
|
||||
draw_flush(lp->draw);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
/* check if changing cbuf */
|
||||
if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) {
|
||||
|
@@ -70,14 +70,18 @@ fail:
|
||||
|
||||
|
||||
void
|
||||
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
|
||||
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
|
||||
{
|
||||
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
|
||||
const struct lp_vertex_shader *vs = (const struct lp_vertex_shader *)_vs;
|
||||
|
||||
llvmpipe->vs = (const struct lp_vertex_shader *)vs;
|
||||
if (llvmpipe->vs == vs)
|
||||
return;
|
||||
|
||||
draw_bind_vertex_shader(llvmpipe->draw,
|
||||
(llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
|
||||
draw_bind_vertex_shader(llvmpipe->draw,
|
||||
vs ? vs->draw_data : NULL);
|
||||
|
||||
llvmpipe->vs = vs;
|
||||
|
||||
llvmpipe->dirty |= LP_NEW_VS;
|
||||
}
|
||||
@@ -92,5 +96,6 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
|
||||
(struct lp_vertex_shader *)vs;
|
||||
|
||||
draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
|
||||
FREE( (void *)state->shader.tokens );
|
||||
FREE( state );
|
||||
}
|
||||
|
@@ -714,9 +714,14 @@ depth_test_quads_fallback(struct quad_stage *qs,
|
||||
qs->next->run(qs->next, quads, nr);
|
||||
}
|
||||
|
||||
/* XXX: this function assumes setup function actually emits linear
|
||||
* spans of quads. It seems a lot more natural to do (early)
|
||||
* depth-testing on spans rather than quads.
|
||||
|
||||
/**
|
||||
* Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LESS and
|
||||
* Z buffer writes enabled.
|
||||
*
|
||||
* NOTE: there's no guarantee that the quads are sequentially side by
|
||||
* side. The fragment shader may have culled some quads, etc. Sliver
|
||||
* triangles may generate non-sequential quads.
|
||||
*/
|
||||
static void
|
||||
depth_interp_z16_less_write(struct quad_stage *qs,
|
||||
@@ -733,25 +738,33 @@ depth_interp_z16_less_write(struct quad_stage *qs,
|
||||
const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
|
||||
struct softpipe_cached_tile *tile;
|
||||
ushort (*depth16)[TILE_SIZE];
|
||||
ushort idepth[4], depth_step;
|
||||
ushort init_idepth[4], idepth[4], depth_step;
|
||||
const float scale = 65535.0;
|
||||
|
||||
idepth[0] = (ushort)((z0) * scale);
|
||||
idepth[1] = (ushort)((z0 + dzdx) * scale);
|
||||
idepth[2] = (ushort)((z0 + dzdy) * scale);
|
||||
idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
|
||||
/* compute scaled depth of the four pixels in first quad */
|
||||
init_idepth[0] = (ushort)((z0) * scale);
|
||||
init_idepth[1] = (ushort)((z0 + dzdx) * scale);
|
||||
init_idepth[2] = (ushort)((z0 + dzdy) * scale);
|
||||
init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
|
||||
|
||||
depth_step = (ushort)(dzdx * 2 * scale);
|
||||
depth_step = (ushort)(dzdx * scale);
|
||||
|
||||
tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
|
||||
|
||||
depth16 = (ushort (*)[TILE_SIZE])
|
||||
&tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
unsigned outmask = quads[i]->inout.mask;
|
||||
const unsigned outmask = quads[i]->inout.mask;
|
||||
const int dx = quads[i]->input.x0 - ix;
|
||||
unsigned mask = 0;
|
||||
|
||||
|
||||
/* compute depth for this quad */
|
||||
idepth[0] = init_idepth[0] + dx * depth_step;
|
||||
idepth[1] = init_idepth[1] + dx * depth_step;
|
||||
idepth[2] = init_idepth[2] + dx * depth_step;
|
||||
idepth[3] = init_idepth[3] + dx * depth_step;
|
||||
|
||||
depth16 = (ushort (*)[TILE_SIZE])
|
||||
&tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
|
||||
|
||||
if ((outmask & 1) && idepth[0] < depth16[0][0]) {
|
||||
depth16[0][0] = idepth[0];
|
||||
mask |= (1 << 0);
|
||||
@@ -772,13 +785,6 @@ depth_interp_z16_less_write(struct quad_stage *qs,
|
||||
mask |= (1 << 3);
|
||||
}
|
||||
|
||||
idepth[0] += depth_step;
|
||||
idepth[1] += depth_step;
|
||||
idepth[2] += depth_step;
|
||||
idepth[3] += depth_step;
|
||||
|
||||
depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
|
||||
|
||||
quads[i]->inout.mask = mask;
|
||||
if (quads[i]->inout.mask)
|
||||
quads[pass++] = quads[i];
|
||||
@@ -790,6 +796,14 @@ depth_interp_z16_less_write(struct quad_stage *qs,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special-case Z testing for 16-bit Zbuffer, PIPE_FUNC_LEQUAL and
|
||||
* Z buffer writes enabled.
|
||||
*
|
||||
* NOTE: there's no guarantee that the quads are sequentially side by
|
||||
* side. The fragment shader may have culled some quads, etc. Sliver
|
||||
* triangles may generate non-sequential quads.
|
||||
*/
|
||||
static void
|
||||
depth_interp_z16_lequal_write(struct quad_stage *qs,
|
||||
struct quad_header *quads[],
|
||||
@@ -805,25 +819,33 @@ depth_interp_z16_lequal_write(struct quad_stage *qs,
|
||||
const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
|
||||
struct softpipe_cached_tile *tile;
|
||||
ushort (*depth16)[TILE_SIZE];
|
||||
ushort idepth[4], depth_step;
|
||||
ushort init_idepth[4], idepth[4], depth_step;
|
||||
const float scale = 65535.0;
|
||||
|
||||
idepth[0] = (ushort)((z0) * scale);
|
||||
idepth[1] = (ushort)((z0 + dzdx) * scale);
|
||||
idepth[2] = (ushort)((z0 + dzdy) * scale);
|
||||
idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
|
||||
/* compute scaled depth of the four pixels in first quad */
|
||||
init_idepth[0] = (ushort)((z0) * scale);
|
||||
init_idepth[1] = (ushort)((z0 + dzdx) * scale);
|
||||
init_idepth[2] = (ushort)((z0 + dzdy) * scale);
|
||||
init_idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
|
||||
|
||||
depth_step = (ushort)(dzdx * 2 * scale);
|
||||
depth_step = (ushort)(dzdx * scale);
|
||||
|
||||
tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
|
||||
|
||||
depth16 = (ushort (*)[TILE_SIZE])
|
||||
&tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
unsigned outmask = quads[i]->inout.mask;
|
||||
const unsigned outmask = quads[i]->inout.mask;
|
||||
const int dx = quads[i]->input.x0 - ix;
|
||||
unsigned mask = 0;
|
||||
|
||||
/* compute depth for this quad */
|
||||
idepth[0] = init_idepth[0] + dx * depth_step;
|
||||
idepth[1] = init_idepth[1] + dx * depth_step;
|
||||
idepth[2] = init_idepth[2] + dx * depth_step;
|
||||
idepth[3] = init_idepth[3] + dx * depth_step;
|
||||
|
||||
depth16 = (ushort (*)[TILE_SIZE])
|
||||
&tile->data.depth16[iy % TILE_SIZE][(ix + dx)% TILE_SIZE];
|
||||
|
||||
if ((outmask & 1) && idepth[0] <= depth16[0][0]) {
|
||||
depth16[0][0] = idepth[0];
|
||||
mask |= (1 << 0);
|
||||
@@ -844,11 +866,6 @@ depth_interp_z16_lequal_write(struct quad_stage *qs,
|
||||
mask |= (1 << 3);
|
||||
}
|
||||
|
||||
idepth[0] += depth_step;
|
||||
idepth[1] += depth_step;
|
||||
idepth[2] += depth_step;
|
||||
idepth[3] += depth_step;
|
||||
|
||||
depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
|
||||
|
||||
quads[i]->inout.mask = mask;
|
||||
|
@@ -805,7 +805,6 @@ line_persp_coeff(const struct setup_context *setup,
|
||||
struct tgsi_interp_coef *coef,
|
||||
uint vertSlot, uint i)
|
||||
{
|
||||
/* XXX double-check/verify this arithmetic */
|
||||
const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3];
|
||||
const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3];
|
||||
const float da = a1 - a0;
|
||||
@@ -813,7 +812,7 @@ line_persp_coeff(const struct setup_context *setup,
|
||||
const float dady = da * setup->emaj.dy * setup->oneoverarea;
|
||||
coef->dadx[i] = dadx;
|
||||
coef->dady[i] = dady;
|
||||
coef->a0[i] = (setup->vmin[vertSlot][i] -
|
||||
coef->a0[i] = (a0 -
|
||||
(dadx * (setup->vmin[0][0] - setup->pixel_offset) +
|
||||
dady * (setup->vmin[0][1] - setup->pixel_offset)));
|
||||
}
|
||||
|
@@ -29,6 +29,7 @@
|
||||
*/
|
||||
|
||||
#include "util/u_memory.h"
|
||||
#include "draw/draw_context.h"
|
||||
#include "sp_context.h"
|
||||
#include "sp_state.h"
|
||||
|
||||
@@ -45,6 +46,8 @@ void softpipe_bind_blend_state( struct pipe_context *pipe,
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
softpipe->blend = (struct pipe_blend_state *)blend;
|
||||
|
||||
softpipe->dirty |= SP_NEW_BLEND;
|
||||
@@ -62,6 +65,8 @@ void softpipe_set_blend_color( struct pipe_context *pipe,
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
softpipe->blend_color = *blend_color;
|
||||
|
||||
softpipe->dirty |= SP_NEW_BLEND;
|
||||
|
@@ -69,7 +69,14 @@ softpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
softpipe->fs = (struct sp_fragment_shader *) fs;
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
if (softpipe->fs == fs)
|
||||
return;
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
softpipe->fs = fs;
|
||||
|
||||
softpipe->dirty |= SP_NEW_FS;
|
||||
}
|
||||
@@ -159,6 +166,8 @@ softpipe_set_constant_buffer(struct pipe_context *pipe,
|
||||
assert(shader < PIPE_SHADER_TYPES);
|
||||
assert(index == 0);
|
||||
|
||||
draw_flush(softpipe->draw);
|
||||
|
||||
/* note: reference counting */
|
||||
pipe_buffer_reference(&softpipe->constants[shader].buffer,
|
||||
buf ? buf->buffer : NULL);
|
||||
|
@@ -41,14 +41,17 @@ softpipe_create_rasterizer_state(struct pipe_context *pipe,
|
||||
}
|
||||
|
||||
void softpipe_bind_rasterizer_state(struct pipe_context *pipe,
|
||||
void *setup)
|
||||
void *rasterizer)
|
||||
{
|
||||
struct softpipe_context *softpipe = softpipe_context(pipe);
|
||||
|
||||
/* pass-through to draw module */
|
||||
draw_set_rasterizer_state(softpipe->draw, setup);
|
||||
if (softpipe->rasterizer == rasterizer)
|
||||
return;
|
||||
|
||||
softpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
|
||||
/* pass-through to draw module */
|
||||
draw_set_rasterizer_state(softpipe->draw, rasterizer);
|
||||
|
||||
softpipe->rasterizer = rasterizer;
|
||||
|
||||
softpipe->dirty |= SP_NEW_RASTERIZER;
|
||||
}
|
||||
|
@@ -48,6 +48,8 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
|
||||
struct softpipe_context *sp = softpipe_context(pipe);
|
||||
uint i;
|
||||
|
||||
draw_flush(sp->draw);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
/* check if changing cbuf */
|
||||
if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
|
||||
|
@@ -1306,6 +1306,11 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute nearest mipmap level from texcoords.
|
||||
* Then sample the texture level for four elements of a quad.
|
||||
* \param c0 the LOD bias factors, or absolute LODs (depending on control)
|
||||
*/
|
||||
static void
|
||||
mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
|
||||
const float s[QUAD_SIZE],
|
||||
@@ -1500,8 +1505,8 @@ sample_compare(struct tgsi_sampler *tgsi_sampler,
|
||||
|
||||
|
||||
/**
|
||||
* Compute which cube face is referenced by each texcoord and put that
|
||||
* info into the sampler faces[] array. Then sample the cube faces
|
||||
* Use 3D texcoords to choose a cube face, then sample the 2D cube faces.
|
||||
* Put face info into the sampler faces[] array.
|
||||
*/
|
||||
static void
|
||||
sample_cube(struct tgsi_sampler *tgsi_sampler,
|
||||
@@ -1514,11 +1519,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
|
||||
struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
|
||||
unsigned j;
|
||||
float ssss[4], tttt[4];
|
||||
unsigned face;
|
||||
|
||||
/*
|
||||
major axis
|
||||
direction target sc tc ma
|
||||
---------- ------------------------------- --- --- ---
|
||||
direction target sc tc ma
|
||||
---------- ------------------------------- --- --- ---
|
||||
+rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
|
||||
-rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
|
||||
+ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
|
||||
@@ -1526,56 +1532,93 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
|
||||
+rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
|
||||
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
|
||||
*/
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
float rx = s[j];
|
||||
float ry = t[j];
|
||||
float rz = p[j];
|
||||
|
||||
/* First choose the cube face.
|
||||
* Use the same cube face for all four pixels in the quad.
|
||||
*
|
||||
* This isn't ideal, but if we want to use a different cube face
|
||||
* per pixel in the quad, we'd have to also compute the per-face
|
||||
* LOD here too. That's because the four post-face-selection
|
||||
* texcoords are no longer related to each other (they're
|
||||
* per-face!) so we can't use subtraction to compute the partial
|
||||
* deriviates to compute the LOD. Doing so (near cube edges
|
||||
* anyway) gives us pretty much random values.
|
||||
*/
|
||||
{
|
||||
/* use the average of the four pixel's texcoords to choose the face */
|
||||
const float rx = 0.25 * (s[0] + s[1] + s[2] + s[3]);
|
||||
const float ry = 0.25 * (t[0] + t[1] + t[2] + t[3]);
|
||||
const float rz = 0.25 * (p[0] + p[1] + p[2] + p[3]);
|
||||
const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
|
||||
unsigned face;
|
||||
float sc, tc, ma;
|
||||
|
||||
if (arx >= ary && arx >= arz) {
|
||||
if (rx >= 0.0F) {
|
||||
face = PIPE_TEX_FACE_POS_X;
|
||||
sc = -rz;
|
||||
tc = -ry;
|
||||
ma = arx;
|
||||
}
|
||||
else {
|
||||
face = PIPE_TEX_FACE_NEG_X;
|
||||
sc = rz;
|
||||
tc = -ry;
|
||||
ma = arx;
|
||||
}
|
||||
}
|
||||
else if (ary >= arx && ary >= arz) {
|
||||
if (ry >= 0.0F) {
|
||||
face = PIPE_TEX_FACE_POS_Y;
|
||||
sc = rx;
|
||||
tc = rz;
|
||||
ma = ary;
|
||||
}
|
||||
else {
|
||||
face = PIPE_TEX_FACE_NEG_Y;
|
||||
sc = rx;
|
||||
tc = -rz;
|
||||
ma = ary;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (rz > 0.0F) {
|
||||
face = PIPE_TEX_FACE_POS_Z;
|
||||
sc = rx;
|
||||
tc = -ry;
|
||||
ma = arz;
|
||||
}
|
||||
else {
|
||||
face = PIPE_TEX_FACE_NEG_Z;
|
||||
sc = -rx;
|
||||
tc = -ry;
|
||||
ma = arz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now compute the 2D _face_ texture coords from the
|
||||
* 3D _cube_ texture coords.
|
||||
*/
|
||||
for (j = 0; j < QUAD_SIZE; j++) {
|
||||
const float rx = s[j], ry = t[j], rz = p[j];
|
||||
const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
|
||||
float sc, tc, ma;
|
||||
|
||||
switch (face) {
|
||||
case PIPE_TEX_FACE_POS_X:
|
||||
sc = -rz;
|
||||
tc = -ry;
|
||||
ma = arx;
|
||||
break;
|
||||
case PIPE_TEX_FACE_NEG_X:
|
||||
sc = rz;
|
||||
tc = -ry;
|
||||
ma = arx;
|
||||
break;
|
||||
case PIPE_TEX_FACE_POS_Y:
|
||||
sc = rx;
|
||||
tc = rz;
|
||||
ma = ary;
|
||||
break;
|
||||
case PIPE_TEX_FACE_NEG_Y:
|
||||
sc = rx;
|
||||
tc = -rz;
|
||||
ma = ary;
|
||||
break;
|
||||
case PIPE_TEX_FACE_POS_Z:
|
||||
sc = rx;
|
||||
tc = -ry;
|
||||
ma = arz;
|
||||
break;
|
||||
case PIPE_TEX_FACE_NEG_Z:
|
||||
sc = -rx;
|
||||
tc = -ry;
|
||||
ma = arz;
|
||||
break;
|
||||
default:
|
||||
assert(0 && "bad cube face");
|
||||
}
|
||||
|
||||
{
|
||||
const float ima = 1.0 / ma;
|
||||
|
@@ -297,13 +297,14 @@ sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
|
||||
x, y, TILE_SIZE, TILE_SIZE,
|
||||
tc->tile.data.color32, 0/*STRIDE*/);
|
||||
|
||||
/* do this? */
|
||||
clear_clear_flag(tc->clear_flags, addr);
|
||||
|
||||
numCleared++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reset all clear flags to zero */
|
||||
memset(tc->clear_flags, 0, sizeof(tc->clear_flags));
|
||||
|
||||
#if 0
|
||||
debug_printf("num cleared: %u\n", numCleared);
|
||||
#endif
|
||||
|
@@ -478,7 +478,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_surface *host,
|
||||
SVGA3dTransferType transfer, // IN
|
||||
uint32 size, // IN
|
||||
uint32 offset, // IN
|
||||
uint32 guest_offset, // IN
|
||||
uint32 host_offset, // IN
|
||||
SVGA3dSurfaceDMAFlags flags) // IN
|
||||
{
|
||||
SVGA3dCmdSurfaceDMA *cmd;
|
||||
@@ -517,19 +518,19 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
|
||||
cmd->transfer = transfer;
|
||||
|
||||
box = (SVGA3dCopyBox *)&cmd[1];
|
||||
box->x = offset;
|
||||
box->x = host_offset;
|
||||
box->y = 0;
|
||||
box->z = 0;
|
||||
box->w = size;
|
||||
box->h = 1;
|
||||
box->d = 1;
|
||||
box->srcx = offset;
|
||||
box->srcx = guest_offset;
|
||||
box->srcy = 0;
|
||||
box->srcz = 0;
|
||||
|
||||
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + sizeof *box);
|
||||
pSuffix->suffixSize = sizeof *pSuffix;
|
||||
pSuffix->maximumOffset = offset + size;
|
||||
pSuffix->maximumOffset = guest_offset + size;
|
||||
pSuffix->flags = flags;
|
||||
|
||||
swc->commit(swc);
|
||||
|
@@ -111,7 +111,8 @@ SVGA3D_BufferDMA(struct svga_winsys_context *swc,
|
||||
struct svga_winsys_surface *host,
|
||||
SVGA3dTransferType transfer,
|
||||
uint32 size,
|
||||
uint32 offset,
|
||||
uint32 guest_offset,
|
||||
uint32 host_offset,
|
||||
SVGA3dSurfaceDMAFlags flags);
|
||||
|
||||
/*
|
||||
|
@@ -215,7 +215,6 @@ struct pipe_context *svga_context_create( struct pipe_screen *screen )
|
||||
svga->state.hw_draw.num_views = 0;
|
||||
|
||||
svga->dirty = ~0;
|
||||
svga->state.white_fs_id = SVGA3D_INVALID_ID;
|
||||
|
||||
LIST_INITHEAD(&svga->dirty_buffers);
|
||||
|
||||
@@ -285,3 +284,8 @@ void svga_hwtnl_flush_retry( struct svga_context *svga )
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
struct svga_winsys_context *
|
||||
svga_winsys_context( struct pipe_context *pipe )
|
||||
{
|
||||
return svga_context( pipe )->swc;
|
||||
}
|
||||
|
@@ -139,6 +139,7 @@ struct svga_rasterizer_state {
|
||||
unsigned multisampleantialias:1;
|
||||
unsigned antialiasedlineenable:1;
|
||||
unsigned lastpixel:1;
|
||||
unsigned pointspriteenable:1;
|
||||
|
||||
unsigned linepattern;
|
||||
|
||||
@@ -329,10 +330,6 @@ struct svga_context
|
||||
|
||||
unsigned texture_timestamp;
|
||||
|
||||
/* Internally generated shaders:
|
||||
*/
|
||||
unsigned white_fs_id;
|
||||
|
||||
/*
|
||||
*/
|
||||
struct svga_sw_state sw;
|
||||
|
@@ -253,7 +253,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
|
||||
assert(index_bias >= 0);
|
||||
assert(min_index <= max_index);
|
||||
assert(offset + index_bias*stride < size);
|
||||
assert(offset + (index_bias + min_index)*stride < size);
|
||||
if (min_index != ~0) {
|
||||
assert(offset + (index_bias + min_index) * stride < size);
|
||||
}
|
||||
|
||||
switch (hwtnl->cmd.vdecl[i].identity.type) {
|
||||
case SVGA3D_DECLTYPE_FLOAT1:
|
||||
@@ -314,7 +316,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl,
|
||||
}
|
||||
|
||||
assert(!stride || width <= stride);
|
||||
assert(offset + (index_bias + max_index)*stride + width <= size);
|
||||
if (max_index != ~0) {
|
||||
assert(offset + (index_bias + max_index) * stride + width <= size);
|
||||
}
|
||||
}
|
||||
|
||||
assert(range->indexWidth == range->indexArray.stride);
|
||||
|
@@ -92,6 +92,7 @@ svga_create_blend_state(struct pipe_context *pipe,
|
||||
if (templ->logicop_enable) {
|
||||
switch (templ->logicop_func) {
|
||||
case PIPE_LOGICOP_XOR:
|
||||
case PIPE_LOGICOP_INVERT:
|
||||
blend->need_white_fragments = TRUE;
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_ONE;
|
||||
@@ -125,12 +126,6 @@ svga_create_blend_state(struct pipe_context *pipe,
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ONE;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_MAXIMUM;
|
||||
break;
|
||||
case PIPE_LOGICOP_INVERT:
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
blend->rt[i].srcblend = SVGA3D_BLENDOP_INVSRCCOLOR;
|
||||
blend->rt[i].dstblend = SVGA3D_BLENDOP_ZERO;
|
||||
blend->rt[i].blendeq = SVGA3D_BLENDEQ_ADD;
|
||||
break;
|
||||
case PIPE_LOGICOP_AND:
|
||||
/* Approximate with minimum - works for the 0 & anything case: */
|
||||
blend->rt[i].blend_enable = TRUE;
|
||||
@@ -228,7 +223,7 @@ static void svga_set_blend_color( struct pipe_context *pipe,
|
||||
|
||||
svga->curr.blend_color = *blend_color;
|
||||
|
||||
svga->dirty |= SVGA_NEW_BLEND;
|
||||
svga->dirty |= SVGA_NEW_BLEND_COLOR;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -218,9 +218,6 @@ svga_draw_range_elements( struct pipe_context *pipe,
|
||||
if (SVGA_DEBUG & DEBUG_FLUSH) {
|
||||
static unsigned id;
|
||||
debug_printf("%s %d\n", __FUNCTION__, id++);
|
||||
if (id > 1300)
|
||||
util_time_sleep( 2000 );
|
||||
|
||||
svga_hwtnl_flush_retry( svga );
|
||||
svga_context_flush(svga, NULL);
|
||||
}
|
||||
|
@@ -70,7 +70,6 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
|
||||
/* light_twoside - XXX: need fragment shader varient */
|
||||
/* poly_smooth - XXX: no fallback available */
|
||||
/* poly_stipple_enable - draw module */
|
||||
/* point_sprite - ? */
|
||||
/* point_size_per_vertex - ? */
|
||||
/* sprite_coord_mode - ??? */
|
||||
/* bypass_vs_viewport_and_clip - handled by viewport setup */
|
||||
@@ -86,6 +85,7 @@ svga_create_rasterizer_state(struct pipe_context *pipe,
|
||||
rast->multisampleantialias = templ->multisample;
|
||||
rast->antialiasedlineenable = templ->line_smooth;
|
||||
rast->lastpixel = templ->line_last_pixel;
|
||||
rast->pointspriteenable = templ->point_sprite;
|
||||
rast->pointsize = templ->point_size;
|
||||
rast->pointsize_min = templ->point_size_min;
|
||||
rast->pointsize_max = templ->point_size_max;
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include "pipe/p_defines.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_pack_color.h"
|
||||
#include "tgsi/tgsi_parse.h"
|
||||
|
||||
#include "svga_context.h"
|
||||
@@ -112,14 +111,12 @@ svga_create_sampler_state(struct pipe_context *pipe,
|
||||
cso->compare_func = sampler->compare_func;
|
||||
|
||||
{
|
||||
ubyte r = float_to_ubyte(sampler->border_color[0]);
|
||||
ubyte g = float_to_ubyte(sampler->border_color[1]);
|
||||
ubyte b = float_to_ubyte(sampler->border_color[2]);
|
||||
ubyte a = float_to_ubyte(sampler->border_color[3]);
|
||||
uint32 r = float_to_ubyte(sampler->border_color[0]);
|
||||
uint32 g = float_to_ubyte(sampler->border_color[1]);
|
||||
uint32 b = float_to_ubyte(sampler->border_color[2]);
|
||||
uint32 a = float_to_ubyte(sampler->border_color[3]);
|
||||
|
||||
util_pack_color_ub( r, g, b, a,
|
||||
PIPE_FORMAT_B8G8R8A8_UNORM,
|
||||
&cso->bordercolor );
|
||||
cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
/* No SVGA3D support for:
|
||||
|
@@ -50,7 +50,7 @@ static void svga_set_vertex_buffers(struct pipe_context *pipe,
|
||||
/* Adjust refcounts */
|
||||
for (i = 0; i < count; i++) {
|
||||
pipe_buffer_reference(&svga->curr.vb[i].buffer, buffers[i].buffer);
|
||||
if (svga_buffer(buffers[i].buffer)->user)
|
||||
if (svga_buffer_is_user_buffer(buffers[i].buffer))
|
||||
any_user_buffer = TRUE;
|
||||
}
|
||||
|
||||
|
@@ -104,7 +104,9 @@ svga_get_paramf(struct pipe_screen *screen, int param)
|
||||
return 80.0;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
|
||||
return 4.0;
|
||||
if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result))
|
||||
return 4.0;
|
||||
return result.u;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
|
||||
return 16.0;
|
||||
@@ -131,12 +133,33 @@ svga_get_paramf(struct pipe_screen *screen, int param)
|
||||
return 1;
|
||||
case PIPE_CAP_TEXTURE_SHADOW_MAP:
|
||||
return 1;
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
|
||||
return SVGA_MAX_TEXTURE_LEVELS;
|
||||
{
|
||||
unsigned levels = SVGA_MAX_TEXTURE_LEVELS;
|
||||
if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result))
|
||||
levels = MIN2(util_logbase2(result.u) + 1, levels);
|
||||
else
|
||||
levels = 12 /* 2048x2048 */;
|
||||
if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result))
|
||||
levels = MIN2(util_logbase2(result.u) + 1, levels);
|
||||
else
|
||||
levels = 12 /* 2048x2048 */;
|
||||
return levels;
|
||||
}
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
|
||||
return 8; /* max 128x128x128 */
|
||||
if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result))
|
||||
return 8; /* max 128x128x128 */
|
||||
return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS);
|
||||
|
||||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
|
||||
return SVGA_MAX_TEXTURE_LEVELS;
|
||||
/*
|
||||
* No mechanism to query the host, and at least limited to 2048x2048 on
|
||||
* certain hardware.
|
||||
*/
|
||||
return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS),
|
||||
12.0 /* 2048x2048 */);
|
||||
|
||||
case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */
|
||||
return 1;
|
||||
|
@@ -83,7 +83,7 @@ svga_buffer_create_host_surface(struct svga_screen *ss,
|
||||
* as svga_screen_surface_create might have passed a recycled host
|
||||
* buffer.
|
||||
*/
|
||||
sbuf->hw.flags.discard = TRUE;
|
||||
sbuf->dma.flags.discard = TRUE;
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, " --> got sid %p sz %d (buffer)\n", sbuf->handle, sbuf->base.size);
|
||||
}
|
||||
@@ -109,10 +109,10 @@ svga_buffer_destroy_hw_storage(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
|
||||
assert(!sbuf->map.count);
|
||||
assert(sbuf->hw.buf);
|
||||
if(sbuf->hw.buf) {
|
||||
sws->buffer_destroy(sws, sbuf->hw.buf);
|
||||
sbuf->hw.buf = NULL;
|
||||
assert(sbuf->hwbuf);
|
||||
if(sbuf->hwbuf) {
|
||||
sws->buffer_destroy(sws, sbuf->hwbuf);
|
||||
sbuf->hwbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,16 +151,18 @@ static INLINE enum pipe_error
|
||||
svga_buffer_create_hw_storage(struct svga_screen *ss,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
if(!sbuf->hw.buf) {
|
||||
assert(!sbuf->user);
|
||||
|
||||
if(!sbuf->hwbuf) {
|
||||
unsigned alignment = sbuf->base.alignment;
|
||||
unsigned usage = 0;
|
||||
unsigned size = sbuf->base.size;
|
||||
|
||||
sbuf->hw.buf = svga_winsys_buffer_create(ss, alignment, usage, size);
|
||||
if(!sbuf->hw.buf)
|
||||
sbuf->hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
|
||||
if(!sbuf->hwbuf)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
assert(!sbuf->needs_flush);
|
||||
assert(!sbuf->dma.pending);
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
@@ -175,12 +177,11 @@ svga_buffer_upload_command(struct svga_context *svga,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
struct svga_winsys_context *swc = svga->swc;
|
||||
struct svga_winsys_buffer *guest = sbuf->hw.buf;
|
||||
struct svga_winsys_buffer *guest = sbuf->hwbuf;
|
||||
struct svga_winsys_surface *host = sbuf->handle;
|
||||
SVGA3dTransferType transfer = SVGA3D_WRITE_HOST_VRAM;
|
||||
SVGA3dSurfaceDMAFlags flags = sbuf->hw.flags;
|
||||
SVGA3dCmdSurfaceDMA *cmd;
|
||||
uint32 numBoxes = sbuf->hw.num_ranges;
|
||||
uint32 numBoxes = sbuf->map.num_ranges;
|
||||
SVGA3dCopyBox *boxes;
|
||||
SVGA3dCmdSurfaceDMASuffix *pSuffix;
|
||||
unsigned region_flags;
|
||||
@@ -218,8 +219,8 @@ svga_buffer_upload_command(struct svga_context *svga,
|
||||
|
||||
cmd->transfer = transfer;
|
||||
|
||||
sbuf->hw.boxes = (SVGA3dCopyBox *)&cmd[1];
|
||||
sbuf->hw.svga = svga;
|
||||
sbuf->dma.boxes = (SVGA3dCopyBox *)&cmd[1];
|
||||
sbuf->dma.svga = svga;
|
||||
|
||||
/* Increment reference count */
|
||||
dummy = NULL;
|
||||
@@ -228,9 +229,11 @@ svga_buffer_upload_command(struct svga_context *svga,
|
||||
pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + numBoxes * sizeof *boxes);
|
||||
pSuffix->suffixSize = sizeof *pSuffix;
|
||||
pSuffix->maximumOffset = sbuf->base.size;
|
||||
pSuffix->flags = flags;
|
||||
pSuffix->flags = sbuf->dma.flags;
|
||||
|
||||
swc->commit(swc);
|
||||
SVGA_FIFOCommitAll(swc);
|
||||
|
||||
sbuf->dma.flags.discard = FALSE;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
@@ -248,10 +251,10 @@ svga_buffer_upload_flush(struct svga_context *svga,
|
||||
unsigned i;
|
||||
|
||||
assert(sbuf->handle);
|
||||
assert(sbuf->hw.buf);
|
||||
assert(sbuf->hw.num_ranges);
|
||||
assert(sbuf->hw.svga == svga);
|
||||
assert(sbuf->hw.boxes);
|
||||
assert(sbuf->hwbuf);
|
||||
assert(sbuf->map.num_ranges);
|
||||
assert(sbuf->dma.svga == svga);
|
||||
assert(sbuf->dma.boxes);
|
||||
|
||||
/*
|
||||
* Patch the DMA command with the final copy box.
|
||||
@@ -259,36 +262,33 @@ svga_buffer_upload_flush(struct svga_context *svga,
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
|
||||
|
||||
boxes = sbuf->hw.boxes;
|
||||
for(i = 0; i < sbuf->hw.num_ranges; ++i) {
|
||||
boxes = sbuf->dma.boxes;
|
||||
for(i = 0; i < sbuf->map.num_ranges; ++i) {
|
||||
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
|
||||
sbuf->hw.ranges[i].start, sbuf->hw.ranges[i].end);
|
||||
sbuf->map.ranges[i].start, sbuf->map.ranges[i].end);
|
||||
|
||||
boxes[i].x = sbuf->hw.ranges[i].start;
|
||||
boxes[i].x = sbuf->map.ranges[i].start;
|
||||
boxes[i].y = 0;
|
||||
boxes[i].z = 0;
|
||||
boxes[i].w = sbuf->hw.ranges[i].end - sbuf->hw.ranges[i].start;
|
||||
boxes[i].w = sbuf->map.ranges[i].end - sbuf->map.ranges[i].start;
|
||||
boxes[i].h = 1;
|
||||
boxes[i].d = 1;
|
||||
boxes[i].srcx = sbuf->hw.ranges[i].start;
|
||||
boxes[i].srcx = sbuf->map.ranges[i].start;
|
||||
boxes[i].srcy = 0;
|
||||
boxes[i].srcz = 0;
|
||||
}
|
||||
|
||||
sbuf->hw.num_ranges = 0;
|
||||
memset(&sbuf->hw.flags, 0, sizeof sbuf->hw.flags);
|
||||
sbuf->map.num_ranges = 0;
|
||||
|
||||
assert(sbuf->head.prev && sbuf->head.next);
|
||||
LIST_DEL(&sbuf->head);
|
||||
#ifdef DEBUG
|
||||
sbuf->head.next = sbuf->head.prev = NULL;
|
||||
#endif
|
||||
sbuf->needs_flush = FALSE;
|
||||
sbuf->dma.pending = FALSE;
|
||||
|
||||
sbuf->hw.svga = NULL;
|
||||
sbuf->hw.boxes = NULL;
|
||||
|
||||
sbuf->host_written = TRUE;
|
||||
sbuf->dma.svga = NULL;
|
||||
sbuf->dma.boxes = NULL;
|
||||
|
||||
/* Decrement reference count */
|
||||
pipe_buffer_reference((struct pipe_buffer **)&sbuf, NULL);
|
||||
@@ -296,7 +296,7 @@ svga_buffer_upload_flush(struct svga_context *svga,
|
||||
|
||||
|
||||
/**
|
||||
* Queue a DMA upload of a range of this buffer to the host.
|
||||
* Note a dirty range.
|
||||
*
|
||||
* This function only notes the range down. It doesn't actually emit a DMA
|
||||
* upload command. That only happens when a context tries to refer to this
|
||||
@@ -305,15 +305,24 @@ svga_buffer_upload_flush(struct svga_context *svga,
|
||||
* We try to lump as many contiguous DMA transfers together as possible.
|
||||
*/
|
||||
static void
|
||||
svga_buffer_upload_queue(struct svga_buffer *sbuf,
|
||||
unsigned start,
|
||||
unsigned end)
|
||||
svga_buffer_add_range(struct svga_buffer *sbuf,
|
||||
unsigned start,
|
||||
unsigned end)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned nearest_range;
|
||||
unsigned nearest_dist;
|
||||
|
||||
assert(sbuf->hw.buf);
|
||||
assert(end > start);
|
||||
|
||||
if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) {
|
||||
nearest_range = sbuf->map.num_ranges;
|
||||
nearest_dist = ~0;
|
||||
} else {
|
||||
nearest_range = SVGA_BUFFER_MAX_RANGES - 1;
|
||||
nearest_dist = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to grow one of the ranges.
|
||||
*
|
||||
@@ -324,12 +333,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf,
|
||||
* buffer should be flushed.
|
||||
*/
|
||||
|
||||
for(i = 0; i < sbuf->hw.num_ranges; ++i) {
|
||||
if(start <= sbuf->hw.ranges[i].end && sbuf->hw.ranges[i].start <= end) {
|
||||
sbuf->hw.ranges[i].start = MIN2(sbuf->hw.ranges[i].start, start);
|
||||
sbuf->hw.ranges[i].end = MAX2(sbuf->hw.ranges[i].end, end);
|
||||
for(i = 0; i < sbuf->map.num_ranges; ++i) {
|
||||
int left_dist;
|
||||
int right_dist;
|
||||
int dist;
|
||||
|
||||
left_dist = start - sbuf->map.ranges[i].end;
|
||||
right_dist = sbuf->map.ranges[i].start - end;
|
||||
dist = MAX2(left_dist, right_dist);
|
||||
|
||||
if (dist <= 0) {
|
||||
/*
|
||||
* Ranges are contiguous or overlapping -- extend this one and return.
|
||||
*/
|
||||
|
||||
sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start);
|
||||
sbuf->map.ranges[i].end = MAX2(sbuf->map.ranges[i].end, end);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Discontiguous ranges -- keep track of the nearest range.
|
||||
*/
|
||||
|
||||
if (dist < nearest_dist) {
|
||||
nearest_range = i;
|
||||
nearest_dist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -337,20 +368,34 @@ svga_buffer_upload_queue(struct svga_buffer *sbuf,
|
||||
* pending DMA upload and start clean.
|
||||
*/
|
||||
|
||||
if(sbuf->needs_flush)
|
||||
svga_buffer_upload_flush(sbuf->hw.svga, sbuf);
|
||||
if(sbuf->dma.pending)
|
||||
svga_buffer_upload_flush(sbuf->dma.svga, sbuf);
|
||||
|
||||
assert(!sbuf->needs_flush);
|
||||
assert(!sbuf->hw.svga);
|
||||
assert(!sbuf->hw.boxes);
|
||||
assert(!sbuf->dma.pending);
|
||||
assert(!sbuf->dma.svga);
|
||||
assert(!sbuf->dma.boxes);
|
||||
|
||||
/*
|
||||
* Add a new range.
|
||||
*/
|
||||
if (sbuf->map.num_ranges < SVGA_BUFFER_MAX_RANGES) {
|
||||
/*
|
||||
* Add a new range.
|
||||
*/
|
||||
|
||||
sbuf->hw.ranges[sbuf->hw.num_ranges].start = start;
|
||||
sbuf->hw.ranges[sbuf->hw.num_ranges].end = end;
|
||||
++sbuf->hw.num_ranges;
|
||||
sbuf->map.ranges[sbuf->map.num_ranges].start = start;
|
||||
sbuf->map.ranges[sbuf->map.num_ranges].end = end;
|
||||
++sbuf->map.num_ranges;
|
||||
} else {
|
||||
/*
|
||||
* Everything else failed, so just extend the nearest range.
|
||||
*
|
||||
* It is OK to do this because we always keep a local copy of the
|
||||
* host buffer data, for SW TNL, and the host never modifies the buffer.
|
||||
*/
|
||||
|
||||
assert(nearest_range < SVGA_BUFFER_MAX_RANGES);
|
||||
assert(nearest_range < sbuf->map.num_ranges);
|
||||
sbuf->map.ranges[nearest_range].start = MIN2(sbuf->map.ranges[nearest_range].start, start);
|
||||
sbuf->map.ranges[nearest_range].end = MAX2(sbuf->map.ranges[nearest_range].end, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -365,55 +410,30 @@ svga_buffer_map_range( struct pipe_screen *screen,
|
||||
struct svga_buffer *sbuf = svga_buffer( buf );
|
||||
void *map;
|
||||
|
||||
if(sbuf->swbuf) {
|
||||
if (!sbuf->swbuf && !sbuf->hwbuf) {
|
||||
if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) {
|
||||
/*
|
||||
* We can't create a hardware buffer big enough, so create a malloc
|
||||
* buffer instead.
|
||||
*/
|
||||
|
||||
debug_printf("%s: failed to allocate %u KB of DMA, splitting DMA transfers\n",
|
||||
__FUNCTION__,
|
||||
(sbuf->base.size + 1023)/1024);
|
||||
|
||||
sbuf->swbuf = align_malloc(sbuf->base.size, sbuf->base.alignment);
|
||||
}
|
||||
}
|
||||
|
||||
if (sbuf->swbuf) {
|
||||
/* User/malloc buffer */
|
||||
map = sbuf->swbuf;
|
||||
}
|
||||
else if (sbuf->hwbuf) {
|
||||
map = sws->buffer_map(sws, sbuf->hwbuf, usage);
|
||||
}
|
||||
else {
|
||||
if(!sbuf->hw.buf) {
|
||||
if(svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK)
|
||||
return NULL;
|
||||
|
||||
/* Populate the hardware storage if the host surface pre-existed */
|
||||
if(sbuf->host_written) {
|
||||
SVGA3dSurfaceDMAFlags flags;
|
||||
enum pipe_error ret;
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
|
||||
assert(sbuf->handle);
|
||||
|
||||
SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "dma from sid %p (buffer), bytes %u - %u\n",
|
||||
sbuf->handle, 0, sbuf->base.size);
|
||||
|
||||
memset(&flags, 0, sizeof flags);
|
||||
|
||||
ret = SVGA3D_BufferDMA(ss->swc,
|
||||
sbuf->hw.buf,
|
||||
sbuf->handle,
|
||||
SVGA3D_READ_HOST_VRAM,
|
||||
sbuf->base.size,
|
||||
0,
|
||||
flags);
|
||||
if(ret != PIPE_OK) {
|
||||
ss->swc->flush(ss->swc, NULL);
|
||||
|
||||
ret = SVGA3D_BufferDMA(ss->swc,
|
||||
sbuf->hw.buf,
|
||||
sbuf->handle,
|
||||
SVGA3D_READ_HOST_VRAM,
|
||||
sbuf->base.size,
|
||||
0,
|
||||
flags);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
ss->swc->flush(ss->swc, &fence);
|
||||
sws->fence_finish(sws, fence, 0);
|
||||
sws->fence_reference(sws, &fence, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
map = sws->buffer_map(sws, sbuf->hw.buf, usage);
|
||||
map = NULL;
|
||||
}
|
||||
|
||||
if(map) {
|
||||
@@ -446,8 +466,7 @@ svga_buffer_flush_mapped_range( struct pipe_screen *screen,
|
||||
assert(sbuf->map.writing);
|
||||
if(sbuf->map.writing) {
|
||||
assert(sbuf->map.flush_explicit);
|
||||
if(sbuf->hw.buf)
|
||||
svga_buffer_upload_queue(sbuf, offset, offset + length);
|
||||
svga_buffer_add_range(sbuf, offset, offset + length);
|
||||
}
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
}
|
||||
@@ -466,16 +485,15 @@ svga_buffer_unmap( struct pipe_screen *screen,
|
||||
if(sbuf->map.count)
|
||||
--sbuf->map.count;
|
||||
|
||||
if(sbuf->hw.buf)
|
||||
sws->buffer_unmap(sws, sbuf->hw.buf);
|
||||
if(sbuf->hwbuf)
|
||||
sws->buffer_unmap(sws, sbuf->hwbuf);
|
||||
|
||||
if(sbuf->map.writing) {
|
||||
if(!sbuf->map.flush_explicit) {
|
||||
/* No mapped range was flushed -- flush the whole buffer */
|
||||
SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n");
|
||||
|
||||
if(sbuf->hw.buf)
|
||||
svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
|
||||
svga_buffer_add_range(sbuf, 0, sbuf->base.size);
|
||||
}
|
||||
|
||||
sbuf->map.writing = FALSE;
|
||||
@@ -493,12 +511,15 @@ svga_buffer_destroy( struct pipe_buffer *buf )
|
||||
|
||||
assert(!p_atomic_read(&buf->reference.count));
|
||||
|
||||
assert(!sbuf->needs_flush);
|
||||
assert(!sbuf->dma.pending);
|
||||
|
||||
if(sbuf->handle)
|
||||
svga_buffer_destroy_host_surface(ss, sbuf);
|
||||
|
||||
if(sbuf->hw.buf)
|
||||
if(sbuf->uploaded.buffer)
|
||||
pipe_buffer_reference(&sbuf->uploaded.buffer, NULL);
|
||||
|
||||
if(sbuf->hwbuf)
|
||||
svga_buffer_destroy_hw_storage(ss, sbuf);
|
||||
|
||||
if(sbuf->swbuf && !sbuf->user)
|
||||
@@ -595,13 +616,14 @@ svga_screen_init_buffer_functions(struct pipe_screen *screen)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the contents of the user buffer / malloc buffer to a hardware buffer.
|
||||
/**
|
||||
* Copy the contents of the malloc buffer to a hardware buffer.
|
||||
*/
|
||||
static INLINE enum pipe_error
|
||||
svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
{
|
||||
if(!sbuf->hw.buf) {
|
||||
assert(!sbuf->user);
|
||||
if(!sbuf->hwbuf) {
|
||||
enum pipe_error ret;
|
||||
void *map;
|
||||
|
||||
@@ -610,20 +632,20 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
return PIPE_ERROR;
|
||||
|
||||
ret = svga_buffer_create_hw_storage(ss, sbuf);
|
||||
assert(ret == PIPE_OK);
|
||||
if(ret != PIPE_OK)
|
||||
return ret;
|
||||
|
||||
pipe_mutex_lock(ss->swc_mutex);
|
||||
map = ss->sws->buffer_map(ss->sws, sbuf->hw.buf, PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
map = ss->sws->buffer_map(ss->sws, sbuf->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
assert(map);
|
||||
if(!map) {
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
svga_buffer_destroy_hw_storage(ss, sbuf);
|
||||
return PIPE_ERROR;
|
||||
}
|
||||
|
||||
memcpy(map, sbuf->swbuf, sbuf->base.size);
|
||||
ss->sws->buffer_unmap(ss->sws, sbuf->hw.buf);
|
||||
ss->sws->buffer_unmap(ss->sws, sbuf->hwbuf);
|
||||
|
||||
/* This user/malloc buffer is now indistinguishable from a gpu buffer */
|
||||
assert(!sbuf->map.count);
|
||||
@@ -635,10 +657,89 @@ svga_buffer_update_hw(struct svga_screen *ss, struct svga_buffer *sbuf)
|
||||
sbuf->swbuf = NULL;
|
||||
}
|
||||
|
||||
svga_buffer_upload_queue(sbuf, 0, sbuf->base.size);
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
}
|
||||
|
||||
pipe_mutex_unlock(ss->swc_mutex);
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Upload the buffer to the host in a piecewise fashion.
|
||||
*
|
||||
* Used when the buffer is too big to fit in the GMR aperture.
|
||||
*/
|
||||
static INLINE enum pipe_error
|
||||
svga_buffer_upload_piecewise(struct svga_screen *ss,
|
||||
struct svga_context *svga,
|
||||
struct svga_buffer *sbuf)
|
||||
{
|
||||
struct svga_winsys_screen *sws = ss->sws;
|
||||
const unsigned alignment = sizeof(void *);
|
||||
const unsigned usage = 0;
|
||||
unsigned i;
|
||||
|
||||
assert(sbuf->map.num_ranges);
|
||||
assert(!sbuf->dma.pending);
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, "dma to sid %p\n", sbuf->handle);
|
||||
|
||||
for (i = 0; i < sbuf->map.num_ranges; ++i) {
|
||||
struct svga_buffer_range *range = &sbuf->map.ranges[i];
|
||||
unsigned offset = range->start;
|
||||
unsigned size = range->end - range->start;
|
||||
|
||||
while (offset < range->end) {
|
||||
struct svga_winsys_buffer *hwbuf;
|
||||
uint8_t *map;
|
||||
enum pipe_error ret;
|
||||
|
||||
if (offset + size > range->end)
|
||||
size = range->end - offset;
|
||||
|
||||
hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
|
||||
while (!hwbuf) {
|
||||
size /= 2;
|
||||
if (!size)
|
||||
return PIPE_ERROR_OUT_OF_MEMORY;
|
||||
hwbuf = svga_winsys_buffer_create(ss, alignment, usage, size);
|
||||
}
|
||||
|
||||
SVGA_DBG(DEBUG_DMA, " bytes %u - %u\n",
|
||||
offset, offset + size);
|
||||
|
||||
map = sws->buffer_map(sws, hwbuf,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE |
|
||||
PIPE_BUFFER_USAGE_DISCARD);
|
||||
assert(map);
|
||||
if (map) {
|
||||
memcpy(map, sbuf->swbuf, size);
|
||||
sws->buffer_unmap(sws, hwbuf);
|
||||
}
|
||||
|
||||
ret = SVGA3D_BufferDMA(svga->swc,
|
||||
hwbuf, sbuf->handle,
|
||||
SVGA3D_WRITE_HOST_VRAM,
|
||||
size, 0, offset, sbuf->dma.flags);
|
||||
if(ret != PIPE_OK) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = SVGA3D_BufferDMA(svga->swc,
|
||||
hwbuf, sbuf->handle,
|
||||
SVGA3D_WRITE_HOST_VRAM,
|
||||
size, 0, offset, sbuf->dma.flags);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
|
||||
sbuf->dma.flags.discard = FALSE;
|
||||
|
||||
sws->buffer_destroy(sws, hwbuf);
|
||||
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
sbuf->map.num_ranges = 0;
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
@@ -658,34 +759,74 @@ svga_buffer_handle(struct svga_context *svga,
|
||||
sbuf = svga_buffer(buf);
|
||||
|
||||
assert(!sbuf->map.count);
|
||||
assert(!sbuf->user);
|
||||
|
||||
if(!sbuf->handle) {
|
||||
ret = svga_buffer_create_host_surface(ss, sbuf);
|
||||
if(ret != PIPE_OK)
|
||||
return NULL;
|
||||
|
||||
ret = svga_buffer_update_hw(ss, sbuf);
|
||||
if(ret != PIPE_OK)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!sbuf->needs_flush && sbuf->hw.num_ranges) {
|
||||
/* Queue the buffer for flushing */
|
||||
ret = svga_buffer_upload_command(svga, sbuf);
|
||||
if(ret != PIPE_OK)
|
||||
/* XXX: Should probably have a richer return value */
|
||||
return NULL;
|
||||
assert(sbuf->handle);
|
||||
|
||||
assert(sbuf->hw.svga == svga);
|
||||
if (sbuf->map.num_ranges) {
|
||||
if (!sbuf->dma.pending) {
|
||||
/*
|
||||
* No pending DMA upload yet, so insert a DMA upload command now.
|
||||
*/
|
||||
|
||||
sbuf->needs_flush = TRUE;
|
||||
assert(!sbuf->head.prev && !sbuf->head.next);
|
||||
LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
|
||||
/*
|
||||
* Migrate the data from swbuf -> hwbuf if necessary.
|
||||
*/
|
||||
ret = svga_buffer_update_hw(ss, sbuf);
|
||||
if (ret == PIPE_OK) {
|
||||
/*
|
||||
* Queue a dma command.
|
||||
*/
|
||||
|
||||
ret = svga_buffer_upload_command(svga, sbuf);
|
||||
if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
|
||||
svga_context_flush(svga, NULL);
|
||||
ret = svga_buffer_upload_command(svga, sbuf);
|
||||
assert(ret == PIPE_OK);
|
||||
}
|
||||
if (ret == PIPE_OK) {
|
||||
sbuf->dma.pending = TRUE;
|
||||
assert(!sbuf->head.prev && !sbuf->head.next);
|
||||
LIST_ADDTAIL(&sbuf->head, &svga->dirty_buffers);
|
||||
}
|
||||
}
|
||||
else if (ret == PIPE_ERROR_OUT_OF_MEMORY) {
|
||||
/*
|
||||
* The buffer is too big to fit in the GMR aperture, so break it in
|
||||
* smaller pieces.
|
||||
*/
|
||||
ret = svga_buffer_upload_piecewise(ss, svga, sbuf);
|
||||
}
|
||||
|
||||
if (ret != PIPE_OK) {
|
||||
/*
|
||||
* Something unexpected happened above. There is very little that
|
||||
* we can do other than proceeding while ignoring the dirty ranges.
|
||||
*/
|
||||
assert(0);
|
||||
sbuf->map.num_ranges = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* There a pending dma already. Make sure it is from this context.
|
||||
*/
|
||||
assert(sbuf->dma.svga == svga);
|
||||
}
|
||||
}
|
||||
|
||||
assert(!sbuf->map.num_ranges || sbuf->dma.pending);
|
||||
|
||||
return sbuf->handle;
|
||||
}
|
||||
|
||||
|
||||
struct pipe_buffer *
|
||||
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
|
||||
enum SVGA3dSurfaceFormat format,
|
||||
@@ -738,7 +879,7 @@ svga_context_flush_buffers(struct svga_context *svga)
|
||||
sbuf = LIST_ENTRY(struct svga_buffer, curr, head);
|
||||
|
||||
assert(p_atomic_read(&sbuf->base.reference.count) != 0);
|
||||
assert(sbuf->needs_flush);
|
||||
assert(sbuf->dma.pending);
|
||||
|
||||
svga_buffer_upload_flush(svga, sbuf);
|
||||
|
||||
|
@@ -56,35 +56,6 @@ struct svga_buffer_range
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Describe a
|
||||
*
|
||||
* This holds the information to emit a SVGA3dCmdSurfaceDMA.
|
||||
*/
|
||||
struct svga_buffer_upload
|
||||
{
|
||||
/**
|
||||
* Guest memory region.
|
||||
*/
|
||||
struct svga_winsys_buffer *buf;
|
||||
|
||||
struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
|
||||
unsigned num_ranges;
|
||||
|
||||
SVGA3dSurfaceDMAFlags flags;
|
||||
|
||||
/**
|
||||
* Pointer to the DMA copy box *inside* the command buffer.
|
||||
*/
|
||||
SVGA3dCopyBox *boxes;
|
||||
|
||||
/**
|
||||
* Context that has the pending DMA to this buffer.
|
||||
*/
|
||||
struct svga_context *svga;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* SVGA pipe buffer.
|
||||
*/
|
||||
@@ -110,14 +81,6 @@ struct svga_buffer
|
||||
*/
|
||||
boolean user;
|
||||
|
||||
/**
|
||||
* DMA'ble memory.
|
||||
*
|
||||
* A piece of GMR memory. It is created when mapping the buffer, and will be
|
||||
* used to upload/download vertex data from the host.
|
||||
*/
|
||||
struct svga_buffer_upload hw;
|
||||
|
||||
/**
|
||||
* Creation key for the host surface handle.
|
||||
*
|
||||
@@ -134,19 +97,94 @@ struct svga_buffer
|
||||
* trying to bind
|
||||
*/
|
||||
struct svga_winsys_surface *handle;
|
||||
|
||||
/**
|
||||
* Whether the host has been ever written.
|
||||
*/
|
||||
boolean host_written;
|
||||
|
||||
/**
|
||||
* Information about ongoing and past map operations.
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* Number of concurrent mappings.
|
||||
*
|
||||
* XXX: It is impossible to guarantee concurrent maps work in all
|
||||
* circumstances -- pipe_buffers really need transfer objects too.
|
||||
*/
|
||||
unsigned count;
|
||||
|
||||
/**
|
||||
* Whether this buffer is currently mapped for writing.
|
||||
*/
|
||||
boolean writing;
|
||||
|
||||
/**
|
||||
* Whether the application will tell us explicity which ranges it touched
|
||||
* or not.
|
||||
*/
|
||||
boolean flush_explicit;
|
||||
|
||||
/**
|
||||
* Dirty ranges.
|
||||
*
|
||||
* Ranges that were touched by the application and need to be uploaded to
|
||||
* the host.
|
||||
*
|
||||
* This information will be copied into dma.boxes, when emiting the
|
||||
* SVGA3dCmdSurfaceDMA command.
|
||||
*/
|
||||
struct svga_buffer_range ranges[SVGA_BUFFER_MAX_RANGES];
|
||||
unsigned num_ranges;
|
||||
} map;
|
||||
|
||||
boolean needs_flush;
|
||||
|
||||
/**
|
||||
* Information about uploaded version of user buffers.
|
||||
*/
|
||||
struct {
|
||||
struct pipe_buffer *buffer;
|
||||
|
||||
/**
|
||||
* We combine multiple user buffers into the same hardware buffer. This
|
||||
* is the relative offset within that buffer.
|
||||
*/
|
||||
unsigned offset;
|
||||
} uploaded;
|
||||
|
||||
/**
|
||||
* DMA'ble memory.
|
||||
*
|
||||
* A piece of GMR memory, with the same size of the buffer. It is created
|
||||
* when mapping the buffer, and will be used to upload vertex data to the
|
||||
* host.
|
||||
*/
|
||||
struct svga_winsys_buffer *hwbuf;
|
||||
|
||||
/**
|
||||
* Information about pending DMA uploads.
|
||||
*
|
||||
*/
|
||||
struct {
|
||||
/**
|
||||
* Whether this buffer has an unfinished DMA upload command.
|
||||
*
|
||||
* If not set then the rest of the information is null.
|
||||
*/
|
||||
boolean pending;
|
||||
|
||||
SVGA3dSurfaceDMAFlags flags;
|
||||
|
||||
/**
|
||||
* Pointer to the DMA copy box *inside* the command buffer.
|
||||
*/
|
||||
SVGA3dCopyBox *boxes;
|
||||
|
||||
/**
|
||||
* Context that has the pending DMA to this buffer.
|
||||
*/
|
||||
struct svga_context *svga;
|
||||
} dma;
|
||||
|
||||
/**
|
||||
* Linked list head, used to gather all buffers with pending dma uploads on
|
||||
* a context. It is only valid if the dma.pending is set above.
|
||||
*/
|
||||
struct list_head head;
|
||||
};
|
||||
|
||||
@@ -176,6 +214,16 @@ svga_buffer_is_user_buffer( struct pipe_buffer *buffer )
|
||||
void
|
||||
svga_screen_init_buffer_functions(struct pipe_screen *screen);
|
||||
|
||||
|
||||
/**
|
||||
* Get the host surface handle for this buffer.
|
||||
*
|
||||
* This will ensure the host surface is updated, issuing DMAs as needed.
|
||||
*
|
||||
* NOTE: This may insert new commands in the context, so it *must* be called
|
||||
* before reserving command buffer space. And, in order to insert commands
|
||||
* it may need to call svga_context_flush().
|
||||
*/
|
||||
struct svga_winsys_surface *
|
||||
svga_buffer_handle(struct svga_context *svga,
|
||||
struct pipe_buffer *buf);
|
||||
|
@@ -203,7 +203,7 @@ svga_transfer_dma(struct svga_transfer *st,
|
||||
if(transfer == SVGA3D_READ_HOST_VRAM) {
|
||||
svga_screen_flush(screen, &fence);
|
||||
sws->fence_finish(sws, fence, 0);
|
||||
//sws->fence_reference(sws, &fence, NULL);
|
||||
sws->fence_reference(sws, &fence, NULL);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -232,7 +232,7 @@ svga_transfer_dma(struct svga_transfer *st,
|
||||
if(y) {
|
||||
svga_screen_flush(screen, &fence);
|
||||
sws->fence_finish(sws, fence, 0);
|
||||
//sws->fence_reference(sws, &fence, NULL);
|
||||
sws->fence_reference(sws, &fence, NULL);
|
||||
}
|
||||
|
||||
hw = sws->buffer_map(sws, st->hwbuf, PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
|
@@ -38,7 +38,7 @@ struct svga_winsys_surface;
|
||||
enum SVGA3dSurfaceFormat;
|
||||
|
||||
|
||||
#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */
|
||||
#define SVGA_MAX_TEXTURE_LEVELS 16
|
||||
|
||||
|
||||
/**
|
||||
|
@@ -103,70 +103,6 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The blend workaround for simulating logicop xor behaviour requires
|
||||
* that the incoming fragment color be white. This change achieves
|
||||
* that by hooking up a hard-wired fragment shader that just emits
|
||||
* color 1,1,1,1
|
||||
*
|
||||
* This is a slightly incomplete solution as it assumes that the
|
||||
* actual bound shader has no other effects beyond generating a
|
||||
* fragment color. In particular shaders containing TEXKIL and/or
|
||||
* depth-write will not have the correct behaviour, nor will those
|
||||
* expecting to use alphatest.
|
||||
*
|
||||
* These are avoidable issues, but they are not much worse than the
|
||||
* unavoidable ones associated with this technique, so it's not clear
|
||||
* how much effort should be expended trying to resolve them - the
|
||||
* ultimate result will still not be correct in most cases.
|
||||
*
|
||||
* Shader below was generated with:
|
||||
* SVGA_DEBUG=tgsi ./mesa/progs/fp/fp-tri white.txt
|
||||
*/
|
||||
static int emit_white_fs( struct svga_context *svga )
|
||||
{
|
||||
int ret = PIPE_ERROR;
|
||||
|
||||
/* ps_3_0
|
||||
* def c0, 1.000000, 0.000000, 0.000000, 1.000000
|
||||
* mov oC0, c0.x
|
||||
* end
|
||||
*/
|
||||
static const unsigned white_tokens[] = {
|
||||
0xffff0300,
|
||||
0x05000051,
|
||||
0xa00f0000,
|
||||
0x3f800000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x3f800000,
|
||||
0x02000001,
|
||||
0x800f0800,
|
||||
0xa0000000,
|
||||
0x0000ffff,
|
||||
};
|
||||
|
||||
assert(SVGA3D_INVALID_ID == UTIL_BITMASK_INVALID_INDEX);
|
||||
svga->state.white_fs_id = util_bitmask_add(svga->fs_bm);
|
||||
if(svga->state.white_fs_id == SVGA3D_INVALID_ID)
|
||||
goto no_fs_id;
|
||||
|
||||
ret = SVGA3D_DefineShader(svga->swc,
|
||||
svga->state.white_fs_id,
|
||||
SVGA3D_SHADERTYPE_PS,
|
||||
white_tokens,
|
||||
sizeof(white_tokens));
|
||||
if (ret)
|
||||
goto no_definition;
|
||||
|
||||
return 0;
|
||||
|
||||
no_definition:
|
||||
util_bitmask_clear(svga->fs_bm, svga->state.white_fs_id);
|
||||
svga->state.white_fs_id = SVGA3D_INVALID_ID;
|
||||
no_fs_id:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* SVGA_NEW_TEXTURE_BINDING
|
||||
* SVGA_NEW_RAST
|
||||
@@ -194,6 +130,23 @@ static int make_fs_key( const struct svga_context *svga,
|
||||
PIPE_WINDING_CW);
|
||||
}
|
||||
|
||||
/* The blend workaround for simulating logicop xor behaviour
|
||||
* requires that the incoming fragment color be white. This change
|
||||
* achieves that by creating a varient of the current fragment
|
||||
* shader that overrides all output colors with 1,1,1,1
|
||||
*
|
||||
* This will work for most shaders, including those containing
|
||||
* TEXKIL and/or depth-write. However, it will break on the
|
||||
* combination of xor-logicop plus alphatest.
|
||||
*
|
||||
* Ultimately, we could implement alphatest in the shader using
|
||||
* texkil prior to overriding the outgoing fragment color.
|
||||
*
|
||||
* SVGA_NEW_BLEND
|
||||
*/
|
||||
if (svga->curr.blend->need_white_fragments) {
|
||||
key->white_fragments = 1;
|
||||
}
|
||||
|
||||
/* XXX: want to limit this to the textures that the shader actually
|
||||
* refers to.
|
||||
@@ -233,40 +186,29 @@ static int emit_hw_fs( struct svga_context *svga,
|
||||
unsigned id = SVGA3D_INVALID_ID;
|
||||
int ret = 0;
|
||||
|
||||
/* SVGA_NEW_BLEND
|
||||
*/
|
||||
if (svga->curr.blend->need_white_fragments) {
|
||||
if (svga->state.white_fs_id == SVGA3D_INVALID_ID) {
|
||||
ret = emit_white_fs( svga );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
id = svga->state.white_fs_id;
|
||||
}
|
||||
else {
|
||||
struct svga_fragment_shader *fs = svga->curr.fs;
|
||||
struct svga_fs_compile_key key;
|
||||
struct svga_fragment_shader *fs = svga->curr.fs;
|
||||
struct svga_fs_compile_key key;
|
||||
|
||||
/* SVGA_NEW_TEXTURE_BINDING
|
||||
* SVGA_NEW_RAST
|
||||
* SVGA_NEW_NEED_SWTNL
|
||||
* SVGA_NEW_SAMPLER
|
||||
*/
|
||||
ret = make_fs_key( svga, &key );
|
||||
/* SVGA_NEW_BLEND
|
||||
* SVGA_NEW_TEXTURE_BINDING
|
||||
* SVGA_NEW_RAST
|
||||
* SVGA_NEW_NEED_SWTNL
|
||||
* SVGA_NEW_SAMPLER
|
||||
*/
|
||||
ret = make_fs_key( svga, &key );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
result = search_fs_key( fs, &key );
|
||||
if (!result) {
|
||||
ret = compile_fs( svga, fs, &key, &result );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
result = search_fs_key( fs, &key );
|
||||
if (!result) {
|
||||
ret = compile_fs( svga, fs, &key, &result );
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert (result);
|
||||
id = result->id;
|
||||
}
|
||||
|
||||
assert (result);
|
||||
id = result->id;
|
||||
|
||||
assert(id != SVGA3D_INVALID_ID);
|
||||
|
||||
if (result != svga->state.hw_draw.fs) {
|
||||
|
@@ -101,6 +101,19 @@ static int emit_rss( struct svga_context *svga,
|
||||
}
|
||||
|
||||
|
||||
if (dirty & SVGA_NEW_BLEND_COLOR) {
|
||||
uint32 color;
|
||||
uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]);
|
||||
uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]);
|
||||
uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]);
|
||||
uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]);
|
||||
|
||||
color = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
|
||||
EMIT_RS( svga, color, BLENDCOLOR, fail );
|
||||
}
|
||||
|
||||
|
||||
if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) {
|
||||
const struct svga_depth_stencil_state *curr = svga->curr.depth;
|
||||
const struct svga_rasterizer_state *rast = svga->curr.rast;
|
||||
@@ -179,18 +192,28 @@ static int emit_rss( struct svga_context *svga,
|
||||
}
|
||||
|
||||
|
||||
if (dirty & SVGA_NEW_RAST)
|
||||
if (dirty & (SVGA_NEW_RAST | SVGA_NEW_NEED_PIPELINE))
|
||||
{
|
||||
const struct svga_rasterizer_state *curr = svga->curr.rast;
|
||||
unsigned cullmode = curr->cullmode;
|
||||
|
||||
/* Shademode: still need to rearrange index list to move
|
||||
* flat-shading PV first vertex.
|
||||
*/
|
||||
EMIT_RS( svga, curr->shademode, SHADEMODE, fail );
|
||||
EMIT_RS( svga, curr->cullmode, CULLMODE, fail );
|
||||
|
||||
/* Don't do culling while the software pipeline is active. It
|
||||
* does it for us, and additionally introduces potentially
|
||||
* back-facing triangles.
|
||||
*/
|
||||
if (svga->state.sw.need_pipeline)
|
||||
cullmode = SVGA3D_FACE_NONE;
|
||||
|
||||
EMIT_RS( svga, cullmode, CULLMODE, fail );
|
||||
EMIT_RS( svga, curr->scissortestenable, SCISSORTESTENABLE, fail );
|
||||
EMIT_RS( svga, curr->multisampleantialias, MULTISAMPLEANTIALIAS, fail );
|
||||
EMIT_RS( svga, curr->lastpixel, LASTPIXEL, fail );
|
||||
EMIT_RS( svga, curr->pointspriteenable, POINTSPRITEENABLE, fail );
|
||||
EMIT_RS( svga, curr->linepattern, LINEPATTERN, fail );
|
||||
EMIT_RS_FLOAT( svga, curr->pointsize, POINTSIZE, fail );
|
||||
EMIT_RS_FLOAT( svga, curr->pointsize_min, POINTSIZEMIN, fail );
|
||||
@@ -230,13 +253,10 @@ static int emit_rss( struct svga_context *svga,
|
||||
memcpy( rs,
|
||||
queue.rs,
|
||||
queue.rs_count * sizeof queue.rs[0]);
|
||||
|
||||
|
||||
SVGA_FIFOCommitAll( svga->swc );
|
||||
}
|
||||
|
||||
/* Also blend color:
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@@ -256,6 +276,7 @@ struct svga_tracked_state svga_hw_rss =
|
||||
"hw rss state",
|
||||
|
||||
(SVGA_NEW_BLEND |
|
||||
SVGA_NEW_BLEND_COLOR |
|
||||
SVGA_NEW_DEPTH_STENCIL |
|
||||
SVGA_NEW_RAST |
|
||||
SVGA_NEW_FRAME_BUFFER |
|
||||
|
@@ -54,33 +54,30 @@ upload_user_buffers( struct svga_context *svga )
|
||||
{
|
||||
if (svga_buffer_is_user_buffer(svga->curr.vb[i].buffer))
|
||||
{
|
||||
struct pipe_buffer *upload_buffer = NULL;
|
||||
unsigned offset = /*svga->curr.vb[i].buffer_offset*/ 0;
|
||||
unsigned size = svga->curr.vb[i].buffer->size /*- offset*/;
|
||||
unsigned upload_offset;
|
||||
struct svga_buffer *buffer = svga_buffer(svga->curr.vb[i].buffer);
|
||||
|
||||
ret = u_upload_buffer( svga->upload_vb,
|
||||
offset,
|
||||
size,
|
||||
svga->curr.vb[i].buffer,
|
||||
&upload_offset,
|
||||
&upload_buffer );
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!buffer->uploaded.buffer) {
|
||||
ret = u_upload_buffer( svga->upload_vb,
|
||||
0,
|
||||
buffer->base.size,
|
||||
&buffer->base,
|
||||
&buffer->uploaded.offset,
|
||||
&buffer->uploaded.buffer );
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (0)
|
||||
debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
|
||||
__FUNCTION__,
|
||||
i,
|
||||
svga->curr.vb[i].buffer,
|
||||
upload_buffer, upload_offset, size);
|
||||
if (0)
|
||||
debug_printf("%s: %d: orig buf %p upl buf %p ofs %d sz %d\n",
|
||||
__FUNCTION__,
|
||||
i,
|
||||
buffer,
|
||||
buffer->uploaded.buffer,
|
||||
buffer->uploaded.offset,
|
||||
buffer->base.size);
|
||||
}
|
||||
|
||||
/* Make sure we release the old buffer and end up with the
|
||||
* correct refcount on the uploaded buffer.
|
||||
*/
|
||||
pipe_buffer_reference( &svga->curr.vb[i].buffer, NULL );
|
||||
svga->curr.vb[i].buffer = upload_buffer;
|
||||
svga->curr.vb[i].buffer_offset = upload_offset;
|
||||
pipe_buffer_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer );
|
||||
svga->curr.vb[i].buffer_offset = buffer->uploaded.offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -49,6 +49,7 @@ struct svga_fs_compile_key
|
||||
{
|
||||
boolean light_twoside:1;
|
||||
boolean front_cw:1;
|
||||
boolean white_fragments:1;
|
||||
ubyte num_textures;
|
||||
ubyte num_unnormalized_coords;
|
||||
struct {
|
||||
|
@@ -194,8 +194,19 @@ static boolean ps30_output( struct svga_shader_emitter *emit,
|
||||
|
||||
switch (semantic.SemanticName) {
|
||||
case TGSI_SEMANTIC_COLOR:
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
|
||||
semantic.SemanticIndex );
|
||||
if (emit->unit == PIPE_SHADER_FRAGMENT &&
|
||||
emit->key.fkey.white_fragments) {
|
||||
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
emit->nr_hw_temp++ );
|
||||
emit->temp_col[idx] = emit->output_map[idx];
|
||||
emit->true_col[idx] = dst_register( SVGA3DREG_COLOROUT,
|
||||
semantic.SemanticIndex );
|
||||
}
|
||||
else {
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_COLOROUT,
|
||||
semantic.SemanticIndex );
|
||||
}
|
||||
break;
|
||||
case TGSI_SEMANTIC_POSITION:
|
||||
emit->output_map[idx] = dst_register( SVGA3DREG_TEMP,
|
||||
|
@@ -79,6 +79,8 @@ struct svga_shader_emitter
|
||||
|
||||
int ps30_input_count;
|
||||
|
||||
int dynamic_branching_level;
|
||||
|
||||
boolean in_main_func;
|
||||
|
||||
boolean created_zero_immediate;
|
||||
@@ -136,6 +138,7 @@ static INLINE boolean emit_dst( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderDestToken dest )
|
||||
{
|
||||
assert(dest.reserved0);
|
||||
assert(dest.mask);
|
||||
return svga_shader_emit_dword( emit, dest.value );
|
||||
}
|
||||
|
||||
@@ -199,6 +202,23 @@ static INLINE boolean emit_op3( struct svga_shader_emitter *emit,
|
||||
}
|
||||
|
||||
|
||||
static INLINE boolean emit_op4( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderInstToken inst,
|
||||
SVGA3dShaderDestToken dest,
|
||||
struct src_register src0,
|
||||
struct src_register src1,
|
||||
struct src_register src2,
|
||||
struct src_register src3)
|
||||
{
|
||||
return (emit_instruction( emit, inst ) &&
|
||||
emit_dst( emit, dest ) &&
|
||||
emit_src( emit, src0 ) &&
|
||||
emit_src( emit, src1 ) &&
|
||||
emit_src( emit, src2 ) &&
|
||||
emit_src( emit, src3 ));
|
||||
}
|
||||
|
||||
|
||||
#define TRANSLATE_SWIZZLE(x,y,z,w) ((x) | ((y) << 2) | ((z) << 4) | ((w) << 6))
|
||||
#define SWIZZLE_XYZW \
|
||||
TRANSLATE_SWIZZLE(TGSI_SWIZZLE_X,TGSI_SWIZZLE_Y,TGSI_SWIZZLE_Z,TGSI_SWIZZLE_W)
|
||||
@@ -248,6 +268,7 @@ static INLINE SVGA3dShaderDestToken
|
||||
writemask( SVGA3dShaderDestToken dest,
|
||||
unsigned mask )
|
||||
{
|
||||
assert(dest.mask & mask);
|
||||
dest.mask &= mask;
|
||||
return dest;
|
||||
}
|
||||
|
@@ -46,8 +46,6 @@ translate_opcode(
|
||||
case TGSI_OPCODE_ABS: return SVGA3DOP_ABS;
|
||||
case TGSI_OPCODE_ADD: return SVGA3DOP_ADD;
|
||||
case TGSI_OPCODE_BREAKC: return SVGA3DOP_BREAKC;
|
||||
case TGSI_OPCODE_DDX: return SVGA3DOP_DSX;
|
||||
case TGSI_OPCODE_DDY: return SVGA3DOP_DSY;
|
||||
case TGSI_OPCODE_DP2A: return SVGA3DOP_DP2ADD;
|
||||
case TGSI_OPCODE_DP3: return SVGA3DOP_DP3;
|
||||
case TGSI_OPCODE_DP4: return SVGA3DOP_DP4;
|
||||
@@ -114,6 +112,7 @@ translate_dst_register( struct svga_shader_emitter *emit,
|
||||
}
|
||||
|
||||
dest.mask = reg->DstRegister.WriteMask;
|
||||
assert(dest.mask);
|
||||
|
||||
if (insn->Instruction.Saturate)
|
||||
dest.dstMod = SVGA3DDSTMOD_SATURATE;
|
||||
@@ -415,6 +414,88 @@ static boolean submit_op3( struct svga_shader_emitter *emit,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* SVGA shaders may not refer to >1 constant register in a single
|
||||
* instruction. This function checks for that usage and inserts a
|
||||
* move to temporary if detected.
|
||||
*/
|
||||
static boolean submit_op4( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderInstToken inst,
|
||||
SVGA3dShaderDestToken dest,
|
||||
struct src_register src0,
|
||||
struct src_register src1,
|
||||
struct src_register src2,
|
||||
struct src_register src3)
|
||||
{
|
||||
SVGA3dShaderDestToken temp0;
|
||||
SVGA3dShaderDestToken temp3;
|
||||
boolean need_temp0 = FALSE;
|
||||
boolean need_temp3 = FALSE;
|
||||
SVGA3dShaderRegType type0, type1, type2, type3;
|
||||
|
||||
temp0.value = 0;
|
||||
temp3.value = 0;
|
||||
type0 = SVGA3dShaderGetRegType( src0.base.value );
|
||||
type1 = SVGA3dShaderGetRegType( src1.base.value );
|
||||
type2 = SVGA3dShaderGetRegType( src2.base.value );
|
||||
type3 = SVGA3dShaderGetRegType( src2.base.value );
|
||||
|
||||
/* Make life a little easier - this is only used by the TXD
|
||||
* instruction which is guaranteed not to have a constant/input reg
|
||||
* in one slot at least:
|
||||
*/
|
||||
assert(type1 == SVGA3DREG_SAMPLER);
|
||||
|
||||
if (type0 == SVGA3DREG_CONST &&
|
||||
((type3 == SVGA3DREG_CONST && src0.base.num != src3.base.num) ||
|
||||
(type2 == SVGA3DREG_CONST && src0.base.num != src2.base.num)))
|
||||
need_temp0 = TRUE;
|
||||
|
||||
if (type3 == SVGA3DREG_CONST &&
|
||||
(type2 == SVGA3DREG_CONST && src3.base.num != src2.base.num))
|
||||
need_temp3 = TRUE;
|
||||
|
||||
if (type0 == SVGA3DREG_INPUT &&
|
||||
((type3 == SVGA3DREG_INPUT && src0.base.num != src3.base.num) ||
|
||||
(type2 == SVGA3DREG_INPUT && src0.base.num != src2.base.num)))
|
||||
need_temp0 = TRUE;
|
||||
|
||||
if (type3 == SVGA3DREG_INPUT &&
|
||||
(type2 == SVGA3DREG_INPUT && src3.base.num != src2.base.num))
|
||||
need_temp3 = TRUE;
|
||||
|
||||
if (need_temp0)
|
||||
{
|
||||
temp0 = get_temp( emit );
|
||||
|
||||
if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp0, src0 ))
|
||||
return FALSE;
|
||||
|
||||
src0 = src( temp0 );
|
||||
}
|
||||
|
||||
if (need_temp3)
|
||||
{
|
||||
temp3 = get_temp( emit );
|
||||
|
||||
if (!emit_op1( emit, inst_token( SVGA3DOP_MOV ), temp3, src3 ))
|
||||
return FALSE;
|
||||
|
||||
src3 = src( temp3 );
|
||||
}
|
||||
|
||||
if (!emit_op4( emit, inst, dest, src0, src1, src2, src3 ))
|
||||
return FALSE;
|
||||
|
||||
if (need_temp3)
|
||||
release_temp( emit, temp3 );
|
||||
if (need_temp0)
|
||||
release_temp( emit, temp0 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static boolean emit_def_const( struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderConstType type,
|
||||
unsigned idx,
|
||||
@@ -660,6 +741,8 @@ static boolean emit_if(struct svga_shader_emitter *emit,
|
||||
if_token.control = SVGA3DOPCOMPC_NE;
|
||||
zero = scalar(zero, TGSI_SWIZZLE_X);
|
||||
|
||||
emit->dynamic_branching_level++;
|
||||
|
||||
return (emit_instruction( emit, if_token ) &&
|
||||
emit_src( emit, src ) &&
|
||||
emit_src( emit, zero ) );
|
||||
@@ -668,6 +751,8 @@ static boolean emit_if(struct svga_shader_emitter *emit,
|
||||
static boolean emit_endif(struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_instruction *insn)
|
||||
{
|
||||
emit->dynamic_branching_level--;
|
||||
|
||||
return (emit_instruction( emit,
|
||||
inst_token( SVGA3DOP_ENDIF )));
|
||||
}
|
||||
@@ -1011,10 +1096,10 @@ static boolean emit_kilp(struct svga_shader_emitter *emit,
|
||||
{
|
||||
SVGA3dShaderInstToken inst;
|
||||
SVGA3dShaderDestToken temp;
|
||||
struct src_register one = get_zero_immediate( emit );
|
||||
struct src_register one = scalar( get_zero_immediate( emit ),
|
||||
TGSI_SWIZZLE_W );
|
||||
|
||||
inst = inst_token( SVGA3DOP_TEXKILL );
|
||||
one = scalar( one, TGSI_SWIZZLE_W );
|
||||
|
||||
/* texkill doesn't allow negation on the operand so lets move
|
||||
* negation of {1} to a temp register */
|
||||
@@ -1169,41 +1254,79 @@ static boolean emit_tex2(struct svga_shader_emitter *emit,
|
||||
SVGA3dShaderDestToken dst )
|
||||
{
|
||||
SVGA3dShaderInstToken inst;
|
||||
struct src_register src0;
|
||||
struct src_register src1;
|
||||
|
||||
struct src_register texcoord;
|
||||
struct src_register sampler;
|
||||
SVGA3dShaderDestToken tmp;
|
||||
|
||||
inst.value = 0;
|
||||
inst.op = SVGA3DOP_TEX;
|
||||
|
||||
switch (insn->Instruction.Opcode) {
|
||||
case TGSI_OPCODE_TEX:
|
||||
inst.op = SVGA3DOP_TEX;
|
||||
break;
|
||||
case TGSI_OPCODE_TXP:
|
||||
inst.op = SVGA3DOP_TEX;
|
||||
inst.control = SVGA3DOPCONT_PROJECT;
|
||||
break;
|
||||
case TGSI_OPCODE_TXB:
|
||||
inst.op = SVGA3DOP_TEX;
|
||||
inst.control = SVGA3DOPCONT_BIAS;
|
||||
break;
|
||||
case TGSI_OPCODE_TXL:
|
||||
inst.op = SVGA3DOP_TEXLDL;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
|
||||
src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
|
||||
texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] );
|
||||
sampler = translate_src_register( emit, &insn->FullSrcRegisters[1] );
|
||||
|
||||
if (emit->key.fkey.tex[src1.base.num].unnormalized) {
|
||||
struct src_register wh = get_tex_dimensions( emit, src1.base.num );
|
||||
SVGA3dShaderDestToken tmp = get_temp( emit );
|
||||
if (emit->key.fkey.tex[sampler.base.num].unnormalized ||
|
||||
emit->dynamic_branching_level > 0)
|
||||
tmp = get_temp( emit );
|
||||
|
||||
/* Can't do mipmapping inside dynamic branch constructs. Force LOD
|
||||
* zero in that case.
|
||||
*/
|
||||
if (emit->dynamic_branching_level > 0 &&
|
||||
inst.op == SVGA3DOP_TEX &&
|
||||
SVGA3dShaderGetRegType(texcoord.base.value) == SVGA3DREG_TEMP) {
|
||||
struct src_register zero = get_zero_immediate( emit );
|
||||
|
||||
/* MOV tmp, texcoord */
|
||||
if (!submit_op1( emit,
|
||||
inst_token( SVGA3DOP_MOV ),
|
||||
tmp,
|
||||
texcoord ))
|
||||
return FALSE;
|
||||
|
||||
/* MOV tmp.w, zero */
|
||||
if (!submit_op1( emit,
|
||||
inst_token( SVGA3DOP_MOV ),
|
||||
writemask( tmp, TGSI_WRITEMASK_W ),
|
||||
scalar( zero, TGSI_SWIZZLE_X )))
|
||||
return FALSE;
|
||||
|
||||
texcoord = src( tmp );
|
||||
inst.op = SVGA3DOP_TEXLDL;
|
||||
}
|
||||
|
||||
/* Explicit normalization of texcoords:
|
||||
*/
|
||||
if (emit->key.fkey.tex[sampler.base.num].unnormalized) {
|
||||
struct src_register wh = get_tex_dimensions( emit, sampler.base.num );
|
||||
|
||||
/* MUL tmp, SRC0, WH */
|
||||
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
|
||||
tmp, src0, wh ))
|
||||
tmp, texcoord, wh ))
|
||||
return FALSE;
|
||||
src0 = src( tmp );
|
||||
|
||||
texcoord = src( tmp );
|
||||
}
|
||||
|
||||
return submit_op2( emit, inst, dst, src0, src1 );
|
||||
return submit_op2( emit, inst, dst, texcoord, sampler );
|
||||
}
|
||||
|
||||
|
||||
@@ -1211,31 +1334,33 @@ static boolean emit_tex2(struct svga_shader_emitter *emit,
|
||||
|
||||
/* Translate texture instructions to SVGA3D representation.
|
||||
*/
|
||||
static boolean emit_tex3(struct svga_shader_emitter *emit,
|
||||
static boolean emit_tex4(struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_instruction *insn,
|
||||
SVGA3dShaderDestToken dst )
|
||||
{
|
||||
SVGA3dShaderInstToken inst;
|
||||
struct src_register src0;
|
||||
struct src_register src1;
|
||||
struct src_register src2;
|
||||
struct src_register texcoord;
|
||||
struct src_register ddx;
|
||||
struct src_register ddy;
|
||||
struct src_register sampler;
|
||||
|
||||
texcoord = translate_src_register( emit, &insn->FullSrcRegisters[0] );
|
||||
ddx = translate_src_register( emit, &insn->FullSrcRegisters[1] );
|
||||
ddy = translate_src_register( emit, &insn->FullSrcRegisters[2] );
|
||||
sampler = translate_src_register( emit, &insn->FullSrcRegisters[3] );
|
||||
|
||||
inst.value = 0;
|
||||
|
||||
switch (insn->Instruction.Opcode) {
|
||||
case TGSI_OPCODE_TXD:
|
||||
inst.op = SVGA3DOP_TEXLDD;
|
||||
break;
|
||||
case TGSI_OPCODE_TXL:
|
||||
inst.op = SVGA3DOP_TEXLDL;
|
||||
inst.op = SVGA3DOP_TEXLDD; /* 4 args! */
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src0 = translate_src_register( emit, &insn->FullSrcRegisters[0] );
|
||||
src1 = translate_src_register( emit, &insn->FullSrcRegisters[1] );
|
||||
src2 = translate_src_register( emit, &insn->FullSrcRegisters[2] );
|
||||
|
||||
return submit_op3( emit, inst, dst, src0, src1, src2 );
|
||||
return submit_op4( emit, inst, dst, texcoord, sampler, ddx, ddy );
|
||||
}
|
||||
|
||||
|
||||
@@ -1271,12 +1396,12 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
|
||||
case TGSI_OPCODE_TEX:
|
||||
case TGSI_OPCODE_TXB:
|
||||
case TGSI_OPCODE_TXP:
|
||||
case TGSI_OPCODE_TXL:
|
||||
if (!emit_tex2( emit, insn, tex_result ))
|
||||
return FALSE;
|
||||
break;
|
||||
case TGSI_OPCODE_TXL:
|
||||
case TGSI_OPCODE_TXD:
|
||||
if (!emit_tex3( emit, insn, tex_result ))
|
||||
if (!emit_tex4( emit, insn, tex_result ))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
@@ -1285,34 +1410,42 @@ static boolean emit_tex(struct svga_shader_emitter *emit,
|
||||
|
||||
|
||||
if (compare) {
|
||||
SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
|
||||
struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
|
||||
struct src_register one =
|
||||
scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
|
||||
if (dst.mask & TGSI_WRITEMASK_XYZ) {
|
||||
SVGA3dShaderDestToken src0_zdivw = get_temp( emit );
|
||||
struct src_register tex_src_x = scalar(src(tex_result), TGSI_SWIZZLE_Y);
|
||||
|
||||
/* Divide texcoord R by Q */
|
||||
if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
|
||||
src0_zdivw,
|
||||
scalar(src0, TGSI_SWIZZLE_W) ))
|
||||
return FALSE;
|
||||
/* Divide texcoord R by Q */
|
||||
if (!submit_op1( emit, inst_token( SVGA3DOP_RCP ),
|
||||
writemask(src0_zdivw, TGSI_WRITEMASK_X),
|
||||
scalar(src0, TGSI_SWIZZLE_W) ))
|
||||
return FALSE;
|
||||
|
||||
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
|
||||
src0_zdivw,
|
||||
scalar(src0, TGSI_SWIZZLE_Z),
|
||||
src(src0_zdivw) ))
|
||||
return FALSE;
|
||||
if (!submit_op2( emit, inst_token( SVGA3DOP_MUL ),
|
||||
writemask(src0_zdivw, TGSI_WRITEMASK_X),
|
||||
scalar(src0, TGSI_SWIZZLE_Z),
|
||||
scalar(src(src0_zdivw), TGSI_SWIZZLE_X) ))
|
||||
return FALSE;
|
||||
|
||||
if (!emit_select(
|
||||
emit,
|
||||
emit->key.fkey.tex[src1.base.num].compare_func,
|
||||
dst,
|
||||
src(src0_zdivw),
|
||||
tex_src_x))
|
||||
return FALSE;
|
||||
if (!emit_select(
|
||||
emit,
|
||||
emit->key.fkey.tex[src1.base.num].compare_func,
|
||||
writemask( dst, TGSI_WRITEMASK_XYZ ),
|
||||
scalar(src(src0_zdivw), TGSI_SWIZZLE_X),
|
||||
tex_src_x))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return submit_op1( emit, inst_token( SVGA3DOP_MOV ),
|
||||
writemask( dst, TGSI_WRITEMASK_W),
|
||||
one );
|
||||
if (dst.mask & TGSI_WRITEMASK_W) {
|
||||
struct src_register one =
|
||||
scalar( get_zero_immediate( emit ), TGSI_SWIZZLE_W );
|
||||
|
||||
if (!submit_op1( emit, inst_token( SVGA3DOP_MOV ),
|
||||
writemask( dst, TGSI_WRITEMASK_W ),
|
||||
one ))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else if (!emit->use_sm30 && dst.mask != TGSI_WRITEMASK_XYZW)
|
||||
{
|
||||
@@ -1330,6 +1463,8 @@ static boolean emit_bgnloop2( struct svga_shader_emitter *emit,
|
||||
struct src_register loop_reg = src_register( SVGA3DREG_LOOP, 0 );
|
||||
struct src_register const_int = get_loop_const( emit );
|
||||
|
||||
emit->dynamic_branching_level++;
|
||||
|
||||
return (emit_instruction( emit, inst ) &&
|
||||
emit_src( emit, loop_reg ) &&
|
||||
emit_src( emit, const_int ) );
|
||||
@@ -1339,6 +1474,9 @@ static boolean emit_endloop2( struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_instruction *insn )
|
||||
{
|
||||
SVGA3dShaderInstToken inst = inst_token( SVGA3DOP_ENDLOOP );
|
||||
|
||||
emit->dynamic_branching_level--;
|
||||
|
||||
return emit_instruction( emit, inst );
|
||||
}
|
||||
|
||||
@@ -1398,6 +1536,46 @@ static boolean emit_simple_instruction(struct svga_shader_emitter *emit,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static boolean emit_deriv(struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_instruction *insn )
|
||||
{
|
||||
if (emit->dynamic_branching_level > 0 &&
|
||||
insn->FullSrcRegisters[0].SrcRegister.File == TGSI_FILE_TEMPORARY)
|
||||
{
|
||||
struct src_register zero = get_zero_immediate( emit );
|
||||
SVGA3dShaderDestToken dst =
|
||||
translate_dst_register( emit, insn, 0 );
|
||||
|
||||
/* Deriv opcodes not valid inside dynamic branching, workaround
|
||||
* by zeroing out the destination.
|
||||
*/
|
||||
if (!submit_op1(emit,
|
||||
inst_token( SVGA3DOP_MOV ),
|
||||
dst,
|
||||
scalar(zero, TGSI_SWIZZLE_X)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
unsigned opcode;
|
||||
|
||||
switch (insn->Instruction.Opcode) {
|
||||
case TGSI_OPCODE_DDX:
|
||||
opcode = SVGA3DOP_DSX;
|
||||
break;
|
||||
case TGSI_OPCODE_DDY:
|
||||
opcode = SVGA3DOP_DSY;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return emit_simple_instruction( emit, opcode, insn );
|
||||
}
|
||||
}
|
||||
|
||||
static boolean emit_arl(struct svga_shader_emitter *emit,
|
||||
const struct tgsi_full_instruction *insn)
|
||||
{
|
||||
@@ -1655,13 +1833,13 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
|
||||
*/
|
||||
if (dst.mask & TGSI_WRITEMASK_X) {
|
||||
if (!submit_op2( emit, inst_token( SVGA3DOP_ADD ),
|
||||
writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
|
||||
writemask( dst, TGSI_WRITEMASK_X ),
|
||||
src0,
|
||||
scalar( negate( src( fraction ) ), TGSI_SWIZZLE_Y ) ) )
|
||||
return FALSE;
|
||||
|
||||
if (!submit_op1( emit, inst_token( SVGA3DOP_EXP ),
|
||||
writemask( dst, dst.mask & TGSI_WRITEMASK_X ),
|
||||
writemask( dst, TGSI_WRITEMASK_X ),
|
||||
scalar( src( dst ), TGSI_SWIZZLE_X ) ) )
|
||||
return FALSE;
|
||||
|
||||
@@ -1673,7 +1851,7 @@ static boolean emit_exp(struct svga_shader_emitter *emit,
|
||||
*/
|
||||
if (dst.mask & TGSI_WRITEMASK_Z) {
|
||||
if (!submit_op1( emit, inst_token( SVGA3DOP_EXPP ),
|
||||
writemask( dst, dst.mask & TGSI_WRITEMASK_Z ),
|
||||
writemask( dst, TGSI_WRITEMASK_Z ),
|
||||
src0 ) )
|
||||
return FALSE;
|
||||
}
|
||||
@@ -2002,6 +2180,10 @@ static boolean svga_emit_instruction( struct svga_shader_emitter *emit,
|
||||
case TGSI_OPCODE_TXD:
|
||||
return emit_tex( emit, insn );
|
||||
|
||||
case TGSI_OPCODE_DDX:
|
||||
case TGSI_OPCODE_DDY:
|
||||
return emit_deriv( emit, insn );
|
||||
|
||||
case TGSI_OPCODE_BGNSUB:
|
||||
return emit_bgnsub( emit, position, insn );
|
||||
|
||||
@@ -2254,11 +2436,28 @@ static boolean emit_ps_postamble( struct svga_shader_emitter *emit )
|
||||
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
|
||||
if (SVGA3dShaderGetRegType(emit->true_col[i].value) != 0) {
|
||||
|
||||
if (!submit_op1( emit,
|
||||
inst_token(SVGA3DOP_MOV),
|
||||
emit->true_col[i],
|
||||
src(emit->temp_col[i]) ))
|
||||
return FALSE;
|
||||
/* Potentially override output colors with white for XOR
|
||||
* logicop workaround.
|
||||
*/
|
||||
if (emit->unit == PIPE_SHADER_FRAGMENT &&
|
||||
emit->key.fkey.white_fragments) {
|
||||
|
||||
struct src_register one = scalar( get_zero_immediate( emit ),
|
||||
TGSI_SWIZZLE_W );
|
||||
|
||||
if (!submit_op1( emit,
|
||||
inst_token(SVGA3DOP_MOV),
|
||||
emit->true_col[i],
|
||||
one ))
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
if (!submit_op1( emit,
|
||||
inst_token(SVGA3DOP_MOV),
|
||||
emit->true_col[i],
|
||||
src(emit->temp_col[i]) ))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2467,6 +2666,9 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
|
||||
if (emit->key.fkey.light_twoside)
|
||||
return TRUE;
|
||||
|
||||
if (emit->key.fkey.white_fragments)
|
||||
return TRUE;
|
||||
|
||||
if (emit->emit_frontface)
|
||||
return TRUE;
|
||||
|
||||
@@ -2476,6 +2678,10 @@ needs_to_create_zero( struct svga_shader_emitter *emit )
|
||||
}
|
||||
|
||||
if (emit->info.opcode_count[TGSI_OPCODE_IF] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_BGNLOOP] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_BGNFOR] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_DDX] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_DDY] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_SGE] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_SGT] >= 1 ||
|
||||
emit->info.opcode_count[TGSI_OPCODE_SLE] >= 1 ||
|
||||
@@ -2702,6 +2908,8 @@ boolean svga_shader_emit_instructions( struct svga_shader_emitter *emit,
|
||||
goto done;
|
||||
}
|
||||
|
||||
assert(emit->dynamic_branching_level == 0);
|
||||
|
||||
/* Need to terminate the whole shader:
|
||||
*/
|
||||
ret = emit_instruction( emit, inst_token( SVGA3DOP_END ) );
|
||||
|
@@ -281,6 +281,9 @@ svga_screen_create(struct svga_winsys_screen *sws);
|
||||
struct svga_winsys_screen *
|
||||
svga_winsys_screen(struct pipe_screen *screen);
|
||||
|
||||
struct svga_winsys_context *
|
||||
svga_winsys_context(struct pipe_context *context);
|
||||
|
||||
struct pipe_buffer *
|
||||
svga_screen_buffer_wrap_surface(struct pipe_screen *screen,
|
||||
enum SVGA3dSurfaceFormat format,
|
||||
|
@@ -132,14 +132,22 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
|
||||
boolean have_depth = FALSE;
|
||||
int i, count;
|
||||
|
||||
buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
|
||||
&dri_drawable->w,
|
||||
&dri_drawable->h,
|
||||
drawable->attachments,
|
||||
drawable->
|
||||
num_attachments, &count,
|
||||
dri_drawable->
|
||||
loaderPrivate);
|
||||
if ((dri_screen->dri2.loader
|
||||
&& (dri_screen->dri2.loader->base.version > 2)
|
||||
&& (dri_screen->dri2.loader->getBuffersWithFormat != NULL)))
|
||||
buffers = (*dri_screen->dri2.loader->getBuffersWithFormat)
|
||||
(dri_drawable, &dri_drawable->w, &dri_drawable->h,
|
||||
drawable->attachments, drawable->num_attachments,
|
||||
&count, dri_drawable->loaderPrivate);
|
||||
else
|
||||
buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable,
|
||||
&dri_drawable->w,
|
||||
&dri_drawable->h,
|
||||
drawable->attachments,
|
||||
drawable->
|
||||
num_attachments, &count,
|
||||
dri_drawable->
|
||||
loaderPrivate);
|
||||
|
||||
if (buffers == NULL) {
|
||||
return;
|
||||
@@ -346,12 +354,12 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
|
||||
case 24:
|
||||
if (visual->stencilBits == 0) {
|
||||
drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
|
||||
PIPE_FORMAT_X8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24X8_UNORM;
|
||||
PIPE_FORMAT_X8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24X8_UNORM;
|
||||
} else {
|
||||
drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
|
||||
PIPE_FORMAT_S8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24S8_UNORM;
|
||||
PIPE_FORMAT_S8Z24_UNORM:
|
||||
PIPE_FORMAT_Z24S8_UNORM;
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
@@ -375,23 +383,49 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
|
||||
/* setup dri2 buffers information */
|
||||
/* TODO incase of double buffer visual, delay fake creation */
|
||||
i = 0;
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
||||
if (!screen->auto_fake_front)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
|
||||
if (visual->doubleBufferMode)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
||||
if (visual->depthBits && visual->stencilBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
||||
else if (visual->depthBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
|
||||
else if (visual->stencilBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
|
||||
drawable->num_attachments = i;
|
||||
if (sPriv->dri2.loader
|
||||
&& (sPriv->dri2.loader->base.version > 2)
|
||||
&& (sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
||||
drawable->attachments[i++] = visual->rgbBits;
|
||||
if (!screen->auto_fake_front) {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
|
||||
drawable->attachments[i++] = visual->rgbBits;
|
||||
}
|
||||
if (visual->doubleBufferMode) {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
||||
drawable->attachments[i++] = visual->rgbBits;
|
||||
}
|
||||
if (visual->depthBits && visual->stencilBits) {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
||||
drawable->attachments[i++] = visual->depthBits + visual->stencilBits;
|
||||
} else if (visual->depthBits) {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
|
||||
drawable->attachments[i++] = visual->depthBits;
|
||||
} else if (visual->stencilBits) {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
|
||||
drawable->attachments[i++] = visual->stencilBits;
|
||||
}
|
||||
drawable->num_attachments = i / 2;
|
||||
} else {
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
|
||||
if (!screen->auto_fake_front)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
|
||||
if (visual->doubleBufferMode)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
|
||||
if (visual->depthBits && visual->stencilBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
|
||||
else if (visual->depthBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
|
||||
else if (visual->stencilBits)
|
||||
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
|
||||
drawable->num_attachments = i;
|
||||
}
|
||||
|
||||
drawable->desired_fences = 2;
|
||||
|
||||
return GL_TRUE;
|
||||
fail:
|
||||
fail:
|
||||
FREE(drawable);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
@@ -80,6 +80,9 @@ dri_fill_in_modes(struct dri_screen *screen,
|
||||
unsigned pixel_bits)
|
||||
{
|
||||
__DRIconfig **configs = NULL;
|
||||
__DRIconfig **configs_r5g6b5 = NULL;
|
||||
__DRIconfig **configs_a8r8g8b8 = NULL;
|
||||
__DRIconfig **configs_x8r8g8b8 = NULL;
|
||||
unsigned num_modes;
|
||||
uint8_t depth_bits_array[5];
|
||||
uint8_t stencil_bits_array[5];
|
||||
@@ -99,12 +102,6 @@ dri_fill_in_modes(struct dri_screen *screen,
|
||||
stencil_bits_array[0] = 0;
|
||||
depth_buffer_factor = 1;
|
||||
|
||||
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
|
||||
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
|
||||
pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
|
||||
@@ -117,15 +114,30 @@ dri_fill_in_modes(struct dri_screen *screen,
|
||||
pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
|
||||
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
|
||||
pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
|
||||
pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
|
||||
pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
|
||||
|
||||
/* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */
|
||||
if (screen->sPriv->dri2.loader &&
|
||||
(screen->sPriv->dri2.loader->base.version > 2) &&
|
||||
(screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) {
|
||||
pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
|
||||
pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
|
||||
PIPE_TEXTURE_2D,
|
||||
PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
|
||||
} else {
|
||||
pf_z16 = FALSE;
|
||||
pf_z32 = FALSE;
|
||||
}
|
||||
|
||||
if (pf_z16) {
|
||||
depth_bits_array[depth_buffer_factor] = 16;
|
||||
@@ -153,41 +165,43 @@ dri_fill_in_modes(struct dri_screen *screen,
|
||||
num_modes =
|
||||
depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
|
||||
|
||||
if (pixel_bits == 16 && pf_r5g6b5) {
|
||||
configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
|
||||
depth_bits_array, stencil_bits_array,
|
||||
depth_buffer_factor, back_buffer_modes,
|
||||
back_buffer_factor,
|
||||
msaa_samples_array, 1);
|
||||
if (pf_r5g6b5)
|
||||
configs_r5g6b5 = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
|
||||
depth_bits_array, stencil_bits_array,
|
||||
depth_buffer_factor, back_buffer_modes,
|
||||
back_buffer_factor,
|
||||
msaa_samples_array, 1);
|
||||
|
||||
if (pf_a8r8g8b8)
|
||||
configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
depth_bits_array,
|
||||
stencil_bits_array,
|
||||
depth_buffer_factor,
|
||||
back_buffer_modes,
|
||||
back_buffer_factor,
|
||||
msaa_samples_array, 1);
|
||||
|
||||
if (pf_x8r8g8b8)
|
||||
configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
depth_bits_array,
|
||||
stencil_bits_array,
|
||||
depth_buffer_factor,
|
||||
back_buffer_modes,
|
||||
back_buffer_factor,
|
||||
msaa_samples_array, 1);
|
||||
|
||||
if (pixel_bits == 16) {
|
||||
configs = configs_r5g6b5;
|
||||
if (configs_a8r8g8b8)
|
||||
configs = configs ? driConcatConfigs(configs, configs_a8r8g8b8) : configs_a8r8g8b8;
|
||||
if (configs_x8r8g8b8)
|
||||
configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8;
|
||||
} else {
|
||||
__DRIconfig **configs_a8r8g8b8 = NULL;
|
||||
__DRIconfig **configs_x8r8g8b8 = NULL;
|
||||
|
||||
if (pf_a8r8g8b8)
|
||||
configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
depth_bits_array,
|
||||
stencil_bits_array,
|
||||
depth_buffer_factor,
|
||||
back_buffer_modes,
|
||||
back_buffer_factor,
|
||||
msaa_samples_array, 1);
|
||||
if (pf_x8r8g8b8)
|
||||
configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
depth_bits_array,
|
||||
stencil_bits_array,
|
||||
depth_buffer_factor,
|
||||
back_buffer_modes,
|
||||
back_buffer_factor,
|
||||
msaa_samples_array, 1);
|
||||
|
||||
if (configs_a8r8g8b8 && configs_x8r8g8b8)
|
||||
configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8);
|
||||
else if (configs_a8r8g8b8)
|
||||
configs = configs_a8r8g8b8;
|
||||
else if (configs_x8r8g8b8)
|
||||
configs = configs_x8r8g8b8;
|
||||
else
|
||||
configs = NULL;
|
||||
configs = configs_a8r8g8b8;
|
||||
if (configs_x8r8g8b8)
|
||||
configs = configs ? driConcatConfigs(configs, configs_x8r8g8b8) : configs_x8r8g8b8;
|
||||
if (configs_r5g6b5)
|
||||
configs = configs ? driConcatConfigs(configs, configs_r5g6b5) : configs_r5g6b5;
|
||||
}
|
||||
|
||||
if (configs == NULL) {
|
||||
|
@@ -21,6 +21,7 @@ if 'python' in env['statetrackers']:
|
||||
'gdi32',
|
||||
'user32',
|
||||
'kernel32',
|
||||
'ws2_32',
|
||||
])
|
||||
else:
|
||||
env.Append(LIBS = [
|
||||
|
@@ -531,6 +531,8 @@ class Context(Object):
|
||||
gallium.PIPE_FORMAT_R32G32B32_FLOAT: '3f',
|
||||
gallium.PIPE_FORMAT_R32G32B32A32_FLOAT: '4f',
|
||||
gallium.PIPE_FORMAT_B8G8R8A8_UNORM: '4B',
|
||||
gallium.PIPE_FORMAT_R8G8B8A8_UNORM: '4B',
|
||||
gallium.PIPE_FORMAT_R16G16B16_SNORM: '3h',
|
||||
}[velem.src_format]
|
||||
|
||||
data = vbuf.buffer.read()
|
||||
@@ -557,7 +559,7 @@ class Context(Object):
|
||||
|
||||
sys.stdout.write('\t{\n')
|
||||
for i in range(start, start + count):
|
||||
if i >= start + 16:
|
||||
if i >= start + 16 and not self.interpreter.verbosity(3):
|
||||
sys.stdout.write('\t...\n')
|
||||
break
|
||||
offset = i*isize
|
||||
|
@@ -362,7 +362,7 @@ EXPORTS
|
||||
wglShareLists
|
||||
wglSwapBuffers
|
||||
wglSwapLayerBuffers
|
||||
; wglSwapMultipleBuffers
|
||||
wglSwapMultipleBuffers
|
||||
wglUseFontBitmapsA
|
||||
wglUseFontBitmapsW
|
||||
wglUseFontOutlinesA
|
||||
|
@@ -362,7 +362,7 @@ EXPORTS
|
||||
wglShareLists = wglShareLists@8
|
||||
wglSwapBuffers = wglSwapBuffers@4
|
||||
wglSwapLayerBuffers = wglSwapLayerBuffers@8
|
||||
; wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
|
||||
wglSwapMultipleBuffers = wglSwapMultipleBuffers@8
|
||||
wglUseFontBitmapsA = wglUseFontBitmapsA@16
|
||||
wglUseFontBitmapsW = wglUseFontBitmapsW@16
|
||||
wglUseFontOutlinesA = wglUseFontOutlinesA@32
|
||||
|
@@ -80,6 +80,9 @@ DrvCopyContext(
|
||||
struct stw_context *dst;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!stw_dev)
|
||||
return FALSE;
|
||||
|
||||
pipe_mutex_lock( stw_dev->ctx_mutex );
|
||||
|
||||
src = stw_lookup_context_locked( dhrcSource );
|
||||
@@ -107,13 +110,15 @@ DrvShareLists(
|
||||
struct stw_context *ctx2;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (!stw_dev)
|
||||
return FALSE;
|
||||
|
||||
pipe_mutex_lock( stw_dev->ctx_mutex );
|
||||
|
||||
ctx1 = stw_lookup_context_locked( dhglrc1 );
|
||||
ctx2 = stw_lookup_context_locked( dhglrc2 );
|
||||
|
||||
if (ctx1 && ctx2 &&
|
||||
ctx1->iPixelFormat == ctx2->iPixelFormat) {
|
||||
if (ctx1 && ctx2) {
|
||||
ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
|
||||
}
|
||||
|
||||
|
@@ -152,24 +152,27 @@ stw_cleanup_thread(void)
|
||||
void
|
||||
stw_cleanup(void)
|
||||
{
|
||||
unsigned i;
|
||||
DHGLRC dhglrc;
|
||||
|
||||
debug_printf("%s\n", __FUNCTION__);
|
||||
|
||||
if (!stw_dev)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Abort cleanup if there are still active contexts. In some situations
|
||||
* this DLL may be unloaded before the DLL that is using GL contexts is.
|
||||
*/
|
||||
pipe_mutex_lock( stw_dev->ctx_mutex );
|
||||
{
|
||||
/* Ensure all contexts are destroyed */
|
||||
i = handle_table_get_first_handle(stw_dev->ctx_table);
|
||||
while (i) {
|
||||
DrvDeleteContext(i);
|
||||
i = handle_table_get_next_handle(stw_dev->ctx_table, i);
|
||||
}
|
||||
handle_table_destroy(stw_dev->ctx_table);
|
||||
}
|
||||
dhglrc = handle_table_get_first_handle(stw_dev->ctx_table);
|
||||
pipe_mutex_unlock( stw_dev->ctx_mutex );
|
||||
if (dhglrc) {
|
||||
debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__);
|
||||
stw_dev = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
handle_table_destroy(stw_dev->ctx_table);
|
||||
|
||||
stw_framebuffer_cleanup();
|
||||
|
||||
|
@@ -178,7 +178,7 @@ stw_call_window_proc(
|
||||
if(!tls_data)
|
||||
return 0;
|
||||
|
||||
if (nCode < 0)
|
||||
if (nCode < 0 || !stw_dev)
|
||||
return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam);
|
||||
|
||||
if (pParams->message == WM_WINDOWPOSCHANGED) {
|
||||
@@ -333,6 +333,9 @@ stw_framebuffer_cleanup( void )
|
||||
struct stw_framebuffer *fb;
|
||||
struct stw_framebuffer *next;
|
||||
|
||||
if (!stw_dev)
|
||||
return;
|
||||
|
||||
pipe_mutex_lock( stw_dev->fb_mutex );
|
||||
|
||||
fb = stw_dev->fb_head;
|
||||
@@ -388,6 +391,9 @@ stw_framebuffer_from_hdc(
|
||||
{
|
||||
struct stw_framebuffer *fb;
|
||||
|
||||
if (!stw_dev)
|
||||
return NULL;
|
||||
|
||||
pipe_mutex_lock( stw_dev->fb_mutex );
|
||||
fb = stw_framebuffer_from_hdc_locked(hdc);
|
||||
pipe_mutex_unlock( stw_dev->fb_mutex );
|
||||
@@ -422,6 +428,9 @@ DrvSetPixelFormat(
|
||||
uint index;
|
||||
struct stw_framebuffer *fb;
|
||||
|
||||
if (!stw_dev)
|
||||
return FALSE;
|
||||
|
||||
index = (uint) iPixelFormat - 1;
|
||||
count = stw_pixelformat_get_extended_count();
|
||||
if (index >= count)
|
||||
@@ -476,6 +485,9 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_surface *surface;
|
||||
|
||||
if (!stw_dev)
|
||||
return FALSE;
|
||||
|
||||
fb = stw_framebuffer_from_hdc( hdc );
|
||||
if (fb == NULL)
|
||||
return FALSE;
|
||||
@@ -577,6 +589,9 @@ DrvSwapBuffers(
|
||||
struct stw_framebuffer *fb;
|
||||
struct pipe_surface *surface = NULL;
|
||||
|
||||
if (!stw_dev)
|
||||
return FALSE;
|
||||
|
||||
fb = stw_framebuffer_from_hdc( hdc );
|
||||
if (fb == NULL)
|
||||
return FALSE;
|
||||
|
@@ -34,6 +34,8 @@
|
||||
|
||||
#include "glapi/glapi.h"
|
||||
#include "stw_ext_gallium.h"
|
||||
#include "stw_device.h"
|
||||
#include "stw_icd.h"
|
||||
|
||||
struct stw_extension_entry
|
||||
{
|
||||
@@ -73,6 +75,9 @@ DrvGetProcAddress(
|
||||
{
|
||||
const struct stw_extension_entry *entry;
|
||||
|
||||
if (!stw_dev)
|
||||
return NULL;
|
||||
|
||||
if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l')
|
||||
for (entry = stw_extension_entries; entry->name; entry++)
|
||||
if (strcmp( lpszProc, entry->name ) == 0)
|
||||
|
@@ -303,6 +303,9 @@ DrvDescribePixelFormat(
|
||||
|
||||
(void) hdc;
|
||||
|
||||
if (!stw_dev)
|
||||
return 0;
|
||||
|
||||
count = stw_pixelformat_get_extended_count();
|
||||
index = (uint) iPixelFormat - 1;
|
||||
|
||||
|
@@ -97,6 +97,19 @@ wglSwapBuffers(
|
||||
}
|
||||
|
||||
|
||||
WINGDIAPI DWORD WINAPI
|
||||
wglSwapMultipleBuffers(UINT n,
|
||||
CONST WGLSWAP *ps)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
for (i =0; i < n; ++i)
|
||||
wglSwapBuffers(ps->hdc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
WINGDIAPI BOOL APIENTRY
|
||||
wglSwapLayerBuffers(
|
||||
HDC hdc,
|
||||
|
@@ -59,5 +59,21 @@ wglSetPixelFormat(HDC hdc,
|
||||
int iPixelFormat,
|
||||
CONST PIXELFORMATDESCRIPTOR *ppfd);
|
||||
|
||||
#if defined(__MINGW32__) || (WINVER < 0x0500)
|
||||
|
||||
typedef struct _WGLSWAP
|
||||
{
|
||||
HDC hdc;
|
||||
UINT uiFlags;
|
||||
} WGLSWAP;
|
||||
|
||||
#define WGL_SWAPMULTIPLE_MAX 16
|
||||
|
||||
WINGDIAPI DWORD WINAPI
|
||||
wglSwapMultipleBuffers(UINT n,
|
||||
CONST WGLSWAP *ps);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* STW_WGL_H_ */
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include <xf86.h>
|
||||
#include <xf86i2c.h>
|
||||
#include <xf86Crtc.h>
|
||||
#include <cursorstr.h>
|
||||
#include "xorg_tracker.h"
|
||||
#include "xf86Modes.h"
|
||||
|
||||
@@ -146,6 +147,7 @@ crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue,
|
||||
/* XXX: hockup */
|
||||
}
|
||||
|
||||
#if 0 /* Implement and enable to enable rotation and reflection. */
|
||||
static void *
|
||||
crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
|
||||
{
|
||||
@@ -168,6 +170,8 @@ crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
|
||||
/* ScrnInfoPtr pScrn = crtc->scrn; */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Cursor functions
|
||||
*/
|
||||
@@ -243,7 +247,11 @@ crtc_load_cursor_argb_kms(xf86CrtcPtr crtc, CARD32 * image)
|
||||
unsigned attr[8];
|
||||
|
||||
attr[0] = KMS_BO_TYPE;
|
||||
#ifdef KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8
|
||||
attr[1] = KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
|
||||
#else
|
||||
attr[1] = KMS_BO_TYPE_CURSOR;
|
||||
#endif
|
||||
attr[2] = KMS_WIDTH;
|
||||
attr[3] = 64;
|
||||
attr[4] = KMS_HEIGHT;
|
||||
@@ -272,7 +280,21 @@ err_bo_destroy:
|
||||
static void
|
||||
crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||
|
||||
/* Older X servers have cursor reference counting bugs leading to use of
|
||||
* freed memory and consequently random crashes. Should be fixed as of
|
||||
* xserver 1.8, but this workaround shouldn't hurt anyway.
|
||||
*/
|
||||
if (config->cursor)
|
||||
config->cursor->refcnt++;
|
||||
|
||||
if (ms->cursor)
|
||||
FreeCursor(ms->cursor, None);
|
||||
|
||||
ms->cursor = config->cursor;
|
||||
|
||||
if (ms->screen)
|
||||
crtc_load_cursor_argb_ga3d(crtc, image);
|
||||
#ifdef HAVE_LIBKMS
|
||||
@@ -344,9 +366,9 @@ static const xf86CrtcFuncsRec crtc_funcs = {
|
||||
.hide_cursor = crtc_hide_cursor,
|
||||
.load_cursor_argb = crtc_load_cursor_argb,
|
||||
|
||||
.shadow_create = crtc_shadow_create,
|
||||
.shadow_allocate = crtc_shadow_allocate,
|
||||
.shadow_destroy = crtc_shadow_destroy,
|
||||
.shadow_create = NULL,
|
||||
.shadow_allocate = NULL,
|
||||
.shadow_destroy = NULL,
|
||||
|
||||
.gamma_set = crtc_gamma_set,
|
||||
.destroy = crtc_destroy,
|
||||
|
@@ -102,14 +102,26 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form
|
||||
pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
|
||||
else {
|
||||
struct pipe_texture template;
|
||||
unsigned depthBits = (format != 0) ? format : pDraw->depth;
|
||||
memset(&template, 0, sizeof(template));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
if (buffer->attachment == DRI2BufferDepth)
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
|
||||
else
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
|
||||
if (buffer->attachment == DRI2BufferDepth) {
|
||||
switch(depthBits) {
|
||||
case 16:
|
||||
template.format = PIPE_FORMAT_Z16_UNORM;
|
||||
break;
|
||||
case 32:
|
||||
template.format = PIPE_FORMAT_Z32_UNORM;
|
||||
break;
|
||||
default:
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
template.format = ms->ds_depth_bits_last ?
|
||||
PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
|
||||
}
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.width[0] = pDraw->width;
|
||||
template.height[0] = pDraw->height;
|
||||
@@ -283,6 +295,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
|
||||
GCPtr gc;
|
||||
RegionPtr copy_clip;
|
||||
Bool save_accel;
|
||||
CustomizerPtr cust = ms->cust;
|
||||
|
||||
/*
|
||||
* In driCreateBuffers we dewrap windows into the
|
||||
@@ -336,7 +349,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
|
||||
ValidateGC(dst_draw, gc);
|
||||
|
||||
/* If this is a full buffer swap, throttle on the previous one */
|
||||
if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
|
||||
if (ms->swapThrottling &&
|
||||
dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
|
||||
BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
|
||||
|
||||
if (extents->x1 == 0 && extents->y1 == 0 &&
|
||||
@@ -358,6 +372,9 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
|
||||
DamageRegionAppend(src_draw, pRegion);
|
||||
DamageRegionProcessPending(src_draw);
|
||||
|
||||
if (cust && cust->winsys_context_throttle)
|
||||
cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_SWAP);
|
||||
|
||||
(*gc->ops->CopyArea)(src_draw, dst_draw, gc,
|
||||
0, 0, pDraw->width, pDraw->height, 0, 0);
|
||||
ms->exa->accel = save_accel;
|
||||
@@ -365,8 +382,13 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion,
|
||||
FreeScratchGC(gc);
|
||||
|
||||
ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
|
||||
pDestBuffer->attachment == DRI2BufferFrontLeft ?
|
||||
(pDestBuffer->attachment == DRI2BufferFrontLeft
|
||||
&& ms->swapThrottling) ?
|
||||
&dst_priv->fence : NULL);
|
||||
|
||||
if (cust && cust->winsys_context_throttle)
|
||||
cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
|
||||
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@@ -79,12 +79,16 @@ typedef enum
|
||||
OPTION_SW_CURSOR,
|
||||
OPTION_2D_ACCEL,
|
||||
OPTION_DEBUG_FALLBACK,
|
||||
OPTION_THROTTLE_SWAP,
|
||||
OPTION_THROTTLE_DIRTY
|
||||
} drv_option_enums;
|
||||
|
||||
static const OptionInfoRec drv_options[] = {
|
||||
{OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_2D_ACCEL, "2DAccel", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_DEBUG_FALLBACK, "DebugFallback", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_THROTTLE_SWAP, "SwapThrottling", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPTION_THROTTLE_DIRTY, "DirtyThrottling", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{-1, NULL, OPTV_NONE, {0}, FALSE}
|
||||
};
|
||||
|
||||
@@ -155,7 +159,7 @@ drv_get_rec(ScrnInfoPtr pScrn)
|
||||
if (pScrn->driverPrivate)
|
||||
return TRUE;
|
||||
|
||||
pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1);
|
||||
pScrn->driverPrivate = xnfcalloc(1, sizeof(modesettingRec));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -183,31 +187,66 @@ drv_probe_ddc(ScrnInfoPtr pScrn, int index)
|
||||
static Bool
|
||||
drv_crtc_resize(ScrnInfoPtr pScrn, int width, int height)
|
||||
{
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
PixmapPtr rootPixmap;
|
||||
ScreenPtr pScreen = pScrn->pScreen;
|
||||
int old_width, old_height;
|
||||
PixmapPtr rootPixmap;
|
||||
int i;
|
||||
|
||||
if (width == pScrn->virtualX && height == pScrn->virtualY)
|
||||
return TRUE;
|
||||
|
||||
old_width = pScrn->virtualX;
|
||||
old_height = pScrn->virtualY;
|
||||
pScrn->virtualX = width;
|
||||
pScrn->virtualY = height;
|
||||
|
||||
/*
|
||||
* Remove the old framebuffer & texture.
|
||||
*/
|
||||
drmModeRmFB(ms->fd, ms->fb_id);
|
||||
if (!ms->destroy_front_buffer(pScrn))
|
||||
FatalError("failed to destroy front buffer\n");
|
||||
/* ms->create_front_buffer will remove the old front buffer */
|
||||
|
||||
rootPixmap = pScreen->GetScreenPixmap(pScreen);
|
||||
if (!pScreen->ModifyPixmapHeader(rootPixmap, width, height, -1, -1, -1, NULL))
|
||||
return FALSE;
|
||||
goto error_modify;
|
||||
|
||||
pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
|
||||
|
||||
/* now create new frontbuffer */
|
||||
return ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn);
|
||||
if (!ms->create_front_buffer(pScrn) || !ms->bind_front_buffer(pScrn))
|
||||
goto error_create;
|
||||
|
||||
/*
|
||||
* create && bind will turn off all crtc(s) in the kernel so we need to
|
||||
* re-enable all the crtcs again. For real HW we might want to do this
|
||||
* before destroying the old framebuffer.
|
||||
*/
|
||||
for (i = 0; i < xf86_config->num_crtc; i++) {
|
||||
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
||||
|
||||
if (!crtc->enabled)
|
||||
continue;
|
||||
|
||||
crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation, crtc->x, crtc->y);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
* This is the error recovery path.
|
||||
*/
|
||||
error_create:
|
||||
if (!pScreen->ModifyPixmapHeader(rootPixmap, old_width, old_height, -1, -1, -1, NULL))
|
||||
FatalError("failed to resize rootPixmap error path\n");
|
||||
|
||||
pScrn->displayWidth = rootPixmap->devKind / (rootPixmap->drawable.bitsPerPixel / 8);
|
||||
|
||||
error_modify:
|
||||
pScrn->virtualX = old_width;
|
||||
pScrn->virtualY = old_height;
|
||||
|
||||
if (ms->create_front_buffer(pScrn) && ms->bind_front_buffer(pScrn))
|
||||
return FALSE;
|
||||
|
||||
FatalError("failed to setup old framebuffer\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const xf86CrtcConfigFuncsRec crtc_config_funcs = {
|
||||
@@ -333,6 +372,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
|
||||
EntityInfoPtr pEnt;
|
||||
EntPtr msEnt = NULL;
|
||||
int max_width, max_height;
|
||||
CustomizerPtr cust;
|
||||
|
||||
if (pScrn->numEntities != 1)
|
||||
return FALSE;
|
||||
@@ -344,6 +384,9 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
cust = (CustomizerPtr) pScrn->driverPrivate;
|
||||
pScrn->driverPrivate = NULL;
|
||||
|
||||
/* Allocate driverPrivate */
|
||||
if (!drv_get_rec(pScrn))
|
||||
return FALSE;
|
||||
@@ -351,6 +394,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
|
||||
ms = modesettingPTR(pScrn);
|
||||
ms->SaveGeneration = -1;
|
||||
ms->pEnt = pEnt;
|
||||
ms->cust = cust;
|
||||
|
||||
pScrn->displayWidth = 640; /* default it */
|
||||
|
||||
@@ -423,8 +467,8 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
|
||||
xf86CrtcConfigInit(pScrn, &crtc_config_funcs);
|
||||
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
|
||||
max_width = 8192;
|
||||
max_height = 8192;
|
||||
max_width = 2048; /* A very low default */
|
||||
max_height = 2048; /* see screen_init */
|
||||
xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height);
|
||||
|
||||
if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) {
|
||||
@@ -510,23 +554,29 @@ static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
|
||||
if (ms->ctx) {
|
||||
int j;
|
||||
|
||||
ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, &ms->fence[XORG_NR_FENCES-1]);
|
||||
ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE,
|
||||
ms->dirtyThrottling ?
|
||||
&ms->fence[XORG_NR_FENCES-1] :
|
||||
NULL);
|
||||
|
||||
if (ms->fence[0])
|
||||
ms->ctx->screen->fence_finish(ms->ctx->screen, ms->fence[0], 0);
|
||||
if (ms->dirtyThrottling) {
|
||||
if (ms->fence[0])
|
||||
ms->ctx->screen->fence_finish(ms->ctx->screen,
|
||||
ms->fence[0], 0);
|
||||
|
||||
/* The amount of rendering generated by a block handler can be
|
||||
* quite small. Let us get a fair way ahead of hardware before
|
||||
* throttling.
|
||||
*/
|
||||
for (j = 0; j < XORG_NR_FENCES - 1; j++)
|
||||
ms->screen->fence_reference(ms->screen,
|
||||
&ms->fence[j],
|
||||
ms->fence[j+1]);
|
||||
/* The amount of rendering generated by a block handler can be
|
||||
* quite small. Let us get a fair way ahead of hardware before
|
||||
* throttling.
|
||||
*/
|
||||
for (j = 0; j < XORG_NR_FENCES - 1; j++)
|
||||
ms->screen->fence_reference(ms->screen,
|
||||
&ms->fence[j],
|
||||
ms->fence[j+1]);
|
||||
|
||||
ms->screen->fence_reference(ms->screen,
|
||||
&ms->fence[XORG_NR_FENCES-1],
|
||||
NULL);
|
||||
ms->screen->fence_reference(ms->screen,
|
||||
&ms->fence[XORG_NR_FENCES-1],
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -607,7 +657,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
unsigned max_width, max_height;
|
||||
VisualPtr visual;
|
||||
CustomizerPtr cust = ms->cust;
|
||||
MessageType from_st;
|
||||
MessageType from_dt;
|
||||
|
||||
if (!drv_init_drm(pScrn)) {
|
||||
FatalError("Could not init DRM");
|
||||
@@ -624,6 +678,26 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* get max width and height */
|
||||
{
|
||||
drmModeResPtr res;
|
||||
res = drmModeGetResources(ms->fd);
|
||||
max_width = res->max_width;
|
||||
max_height = res->max_height;
|
||||
drmModeFreeResources(res);
|
||||
}
|
||||
|
||||
if (ms->screen) {
|
||||
float maxf;
|
||||
int max;
|
||||
maxf = ms->screen->get_paramf(ms->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
|
||||
max = (1 << (int)(maxf - 1.0f));
|
||||
max_width = max < max_width ? max : max_width;
|
||||
max_height = max < max_height ? max : max_height;
|
||||
}
|
||||
|
||||
xf86CrtcSetSizeRange(pScrn, 1, 1, max_width, max_height);
|
||||
|
||||
pScrn->pScreen = pScreen;
|
||||
|
||||
/* HW dependent - FIXME */
|
||||
@@ -673,7 +747,20 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||||
xf86SetBlackWhitePixels(pScreen);
|
||||
|
||||
ms->accelerate_2d = xf86ReturnOptValBool(ms->Options, OPTION_2D_ACCEL, FALSE);
|
||||
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, TRUE);
|
||||
ms->debug_fallback = xf86ReturnOptValBool(ms->Options, OPTION_DEBUG_FALLBACK, ms->accelerate_2d);
|
||||
|
||||
if (cust && cust->winsys_screen_init)
|
||||
cust->winsys_screen_init(cust, ms->fd);
|
||||
|
||||
ms->swapThrottling = cust ? cust->swap_throttling : TRUE;
|
||||
from_st = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_SWAP,
|
||||
&ms->swapThrottling) ?
|
||||
X_CONFIG : X_DEFAULT;
|
||||
|
||||
ms->dirtyThrottling = cust ? cust->dirty_throttling : TRUE;
|
||||
from_dt = xf86GetOptValBool(ms->Options, OPTION_THROTTLE_DIRTY,
|
||||
&ms->dirtyThrottling) ?
|
||||
X_CONFIG : X_DEFAULT;
|
||||
|
||||
if (ms->screen) {
|
||||
ms->exa = xorg_exa_init(pScrn, ms->accelerate_2d);
|
||||
@@ -684,6 +771,11 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "# Usefull debugging info follows #\n");
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %s backend\n",
|
||||
ms->screen ? "Gallium3D" : "libkms");
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "2D Acceleration is %s\n",
|
||||
ms->screen && ms->accelerate_2d ? "enabled" : "disabled");
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Fallback debugging is %s\n",
|
||||
@@ -694,6 +786,12 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||||
#else
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "3D Acceleration is disabled\n");
|
||||
#endif
|
||||
xf86DrvMsg(pScrn->scrnIndex, from_st, "Swap Throttling is %s.\n",
|
||||
ms->swapThrottling ? "enabled" : "disabled");
|
||||
xf86DrvMsg(pScrn->scrnIndex, from_dt, "Dirty Throttling is %s.\n",
|
||||
ms->dirtyThrottling ? "enabled" : "disabled");
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "##################################\n");
|
||||
|
||||
miInitializeBackingStore(pScreen);
|
||||
xf86SetBackingStore(pScreen);
|
||||
@@ -725,9 +823,6 @@ drv_screen_init(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
||||
if (serverGeneration == 1)
|
||||
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
|
||||
|
||||
if (ms->winsys_screen_init)
|
||||
ms->winsys_screen_init(pScrn);
|
||||
|
||||
return drv_enter_vt(scrnIndex, 1);
|
||||
}
|
||||
|
||||
@@ -759,10 +854,11 @@ drv_leave_vt(int scrnIndex, int flags)
|
||||
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
CustomizerPtr cust = ms->cust;
|
||||
int o;
|
||||
|
||||
if (ms->winsys_leave_vt)
|
||||
ms->winsys_leave_vt(pScrn);
|
||||
if (cust && cust->winsys_leave_vt)
|
||||
cust->winsys_leave_vt(cust);
|
||||
|
||||
for (o = 0; o < config->num_crtc; o++) {
|
||||
xf86CrtcPtr crtc = config->crtc[o];
|
||||
@@ -778,6 +874,7 @@ drv_leave_vt(int scrnIndex, int flags)
|
||||
}
|
||||
|
||||
drmModeRmFB(ms->fd, ms->fb_id);
|
||||
ms->fb_id = -1;
|
||||
|
||||
drv_restore_hw_state(pScrn);
|
||||
|
||||
@@ -796,6 +893,7 @@ drv_enter_vt(int scrnIndex, int flags)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
CustomizerPtr cust = ms->cust;
|
||||
|
||||
if (drmSetMaster(ms->fd)) {
|
||||
if (errno == EINVAL) {
|
||||
@@ -826,8 +924,8 @@ drv_enter_vt(int scrnIndex, int flags)
|
||||
if (!xf86SetDesiredModes(pScrn))
|
||||
return FALSE;
|
||||
|
||||
if (ms->winsys_enter_vt)
|
||||
ms->winsys_enter_vt(pScrn);
|
||||
if (cust && cust->winsys_enter_vt)
|
||||
cust->winsys_enter_vt(cust);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -845,13 +943,19 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
CustomizerPtr cust = ms->cust;
|
||||
|
||||
if (pScrn->vtSema) {
|
||||
drv_leave_vt(scrnIndex, 0);
|
||||
}
|
||||
|
||||
if (ms->winsys_screen_close)
|
||||
ms->winsys_screen_close(pScrn);
|
||||
if (ms->cursor) {
|
||||
FreeCursor(ms->cursor, None);
|
||||
ms->cursor = NULL;
|
||||
}
|
||||
|
||||
if (cust && cust->winsys_screen_close)
|
||||
cust->winsys_screen_close(cust);
|
||||
|
||||
#ifdef DRI2
|
||||
if (ms->screen)
|
||||
@@ -900,6 +1004,15 @@ static Bool
|
||||
drv_destroy_front_buffer_ga3d(ScrnInfoPtr pScrn)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
|
||||
if (!ms->root_texture)
|
||||
return TRUE;
|
||||
|
||||
if (ms->fb_id != -1) {
|
||||
drmModeRmFB(ms->fd, ms->fb_id);
|
||||
ms->fb_id = -1;
|
||||
}
|
||||
|
||||
pipe_texture_reference(&ms->root_texture, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -908,7 +1021,7 @@ static Bool
|
||||
drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
unsigned handle, stride;
|
||||
unsigned handle, stride, fb_id;
|
||||
struct pipe_texture *tex;
|
||||
int ret;
|
||||
|
||||
@@ -933,19 +1046,23 @@ drv_create_front_buffer_ga3d(ScrnInfoPtr pScrn)
|
||||
pScrn->bitsPerPixel,
|
||||
stride,
|
||||
handle,
|
||||
&ms->fb_id);
|
||||
&fb_id);
|
||||
if (ret) {
|
||||
debug_printf("%s: failed to create framebuffer (%i, %s)",
|
||||
debug_printf("%s: failed to create framebuffer (%i, %s)\n",
|
||||
__func__, ret, strerror(-ret));
|
||||
goto err_destroy;
|
||||
}
|
||||
|
||||
if (!drv_destroy_front_buffer_ga3d(pScrn))
|
||||
FatalError("%s: failed to take down old framebuffer\n", __func__);
|
||||
|
||||
pScrn->frameX0 = 0;
|
||||
pScrn->frameY0 = 0;
|
||||
drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
|
||||
|
||||
pipe_texture_reference(&ms->root_texture, tex);
|
||||
pipe_texture_reference(&tex, NULL);
|
||||
ms->fb_id = fb_id;
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -993,6 +1110,11 @@ drv_destroy_front_buffer_kms(ScrnInfoPtr pScrn)
|
||||
if (!ms->root_bo)
|
||||
return TRUE;
|
||||
|
||||
if (ms->fb_id != -1) {
|
||||
drmModeRmFB(ms->fd, ms->fb_id);
|
||||
ms->fb_id = -1;
|
||||
}
|
||||
|
||||
kms_bo_unmap(ms->root_bo);
|
||||
kms_bo_destroy(&ms->root_bo);
|
||||
return TRUE;
|
||||
@@ -1005,10 +1127,15 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
|
||||
unsigned handle, stride;
|
||||
struct kms_bo *bo;
|
||||
unsigned attr[8];
|
||||
unsigned fb_id;
|
||||
int ret;
|
||||
|
||||
attr[0] = KMS_BO_TYPE;
|
||||
#ifdef KMS_BO_TYPE_SCANOUT_X8R8G8B8
|
||||
attr[1] = KMS_BO_TYPE_SCANOUT_X8R8G8B8;
|
||||
#else
|
||||
attr[1] = KMS_BO_TYPE_SCANOUT;
|
||||
#endif
|
||||
attr[2] = KMS_WIDTH;
|
||||
attr[3] = pScrn->virtualX;
|
||||
attr[4] = KMS_HEIGHT;
|
||||
@@ -1031,17 +1158,21 @@ drv_create_front_buffer_kms(ScrnInfoPtr pScrn)
|
||||
pScrn->bitsPerPixel,
|
||||
stride,
|
||||
handle,
|
||||
&ms->fb_id);
|
||||
&fb_id);
|
||||
if (ret) {
|
||||
debug_printf("%s: failed to create framebuffer (%i, %s)",
|
||||
__func__, ret, strerror(-ret));
|
||||
goto err_destroy;
|
||||
}
|
||||
|
||||
if (!drv_destroy_front_buffer_kms(pScrn))
|
||||
FatalError("%s: could not takedown old bo", __func__);
|
||||
|
||||
pScrn->frameX0 = 0;
|
||||
pScrn->frameY0 = 0;
|
||||
drv_adjust_frame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
|
||||
ms->root_bo = bo;
|
||||
ms->fb_id = fb_id;
|
||||
|
||||
return TRUE;
|
||||
|
||||
@@ -1109,4 +1240,14 @@ static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn)
|
||||
{
|
||||
return modesettingPTR(pScrn)->cust;
|
||||
}
|
||||
|
||||
Bool xorg_has_gallium(ScrnInfoPtr pScrn)
|
||||
{
|
||||
return modesettingPTR(pScrn)->screen != NULL;
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=8 sts=4: */
|
||||
|
@@ -1035,6 +1035,7 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
struct exa_context *exa;
|
||||
ExaDriverPtr pExa;
|
||||
CustomizerPtr cust = ms->cust;
|
||||
|
||||
exa = xcalloc(1, sizeof(struct exa_context));
|
||||
if (!exa)
|
||||
@@ -1093,6 +1094,8 @@ xorg_exa_init(ScrnInfoPtr pScrn, Bool accel)
|
||||
exa->pipe = ms->api->create_context(ms->api, exa->scrn);
|
||||
/* Share context with DRI */
|
||||
ms->ctx = exa->pipe;
|
||||
if (cust && cust->winsys_context_throttle)
|
||||
cust->winsys_context_throttle(cust, ms->ctx, THROTTLE_RENDER);
|
||||
|
||||
exa->renderer = renderer_create(exa->pipe);
|
||||
exa->accel = accel;
|
||||
|
@@ -586,7 +586,7 @@ void renderer_copy_pixmap(struct xorg_renderer *r,
|
||||
|
||||
|
||||
void renderer_draw_yuv(struct xorg_renderer *r,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
float src_x, float src_y, float src_w, float src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
struct pipe_texture **textures)
|
||||
{
|
||||
|
@@ -53,7 +53,7 @@ void renderer_set_constants(struct xorg_renderer *r,
|
||||
|
||||
|
||||
void renderer_draw_yuv(struct xorg_renderer *r,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
float src_x, float src_y, float src_w, float src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h,
|
||||
struct pipe_texture **textures);
|
||||
|
||||
|
@@ -65,6 +65,24 @@ typedef struct
|
||||
|
||||
#define XORG_NR_FENCES 3
|
||||
|
||||
enum xorg_throttling_reason {
|
||||
THROTTLE_RENDER,
|
||||
THROTTLE_SWAP
|
||||
};
|
||||
|
||||
typedef struct _CustomizerRec
|
||||
{
|
||||
Bool dirty_throttling;
|
||||
Bool swap_throttling;
|
||||
Bool (*winsys_screen_init)(struct _CustomizerRec *cust, int fd);
|
||||
Bool (*winsys_screen_close)(struct _CustomizerRec *cust);
|
||||
Bool (*winsys_enter_vt)(struct _CustomizerRec *cust);
|
||||
Bool (*winsys_leave_vt)(struct _CustomizerRec *cust);
|
||||
void (*winsys_context_throttle)(struct _CustomizerRec *cust,
|
||||
struct pipe_context *pipe,
|
||||
enum xorg_throttling_reason reason);
|
||||
} CustomizerRec, *CustomizerPtr;
|
||||
|
||||
typedef struct _modesettingRec
|
||||
{
|
||||
/* drm */
|
||||
@@ -80,6 +98,9 @@ typedef struct _modesettingRec
|
||||
|
||||
Bool noAccel;
|
||||
Bool SWCursor;
|
||||
CursorPtr cursor;
|
||||
Bool swapThrottling;
|
||||
Bool dirtyThrottling;
|
||||
CloseScreenProcPtr CloseScreen;
|
||||
|
||||
/* Broken-out options. */
|
||||
@@ -115,12 +136,7 @@ typedef struct _modesettingRec
|
||||
Bool accelerate_2d;
|
||||
Bool debug_fallback;
|
||||
|
||||
/* winsys hocks */
|
||||
Bool (*winsys_screen_init)(ScrnInfoPtr pScr);
|
||||
Bool (*winsys_screen_close)(ScrnInfoPtr pScr);
|
||||
Bool (*winsys_enter_vt)(ScrnInfoPtr pScr);
|
||||
Bool (*winsys_leave_vt)(ScrnInfoPtr pScr);
|
||||
void *winsys_priv;
|
||||
CustomizerPtr cust;
|
||||
|
||||
#ifdef DRM_MODE_FEATURE_DIRTYFB
|
||||
DamagePtr damage;
|
||||
@@ -129,6 +145,9 @@ typedef struct _modesettingRec
|
||||
|
||||
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
|
||||
|
||||
CustomizerPtr xorg_customizer(ScrnInfoPtr pScrn);
|
||||
|
||||
Bool xorg_has_gallium(ScrnInfoPtr pScrn);
|
||||
|
||||
/***********************************************************************
|
||||
* xorg_exa.c
|
||||
|
@@ -384,11 +384,14 @@ setup_fs_video_constants(struct xorg_renderer *r, boolean hdtv)
|
||||
|
||||
static void
|
||||
draw_yuv(struct xorg_xv_port_priv *port,
|
||||
int src_x, int src_y, int src_w, int src_h,
|
||||
float src_x, float src_y, float src_w, float src_h,
|
||||
int dst_x, int dst_y, int dst_w, int dst_h)
|
||||
{
|
||||
struct pipe_texture **textures = port->yuv[port->current_set];
|
||||
|
||||
/*debug_printf(" draw_yuv([%d, %d, %d ,%d], [%d, %d, %d, %d])\n",
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h);*/
|
||||
renderer_draw_yuv(port->r,
|
||||
src_x, src_y, src_w, src_h,
|
||||
dst_x, dst_y, dst_w, dst_h,
|
||||
@@ -490,6 +493,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
|
||||
exaMoveInPixmap(pPixmap);
|
||||
dst = exaGetPixmapDriverPrivate(pPixmap);
|
||||
|
||||
/*debug_printf("display_video([%d, %d, %d, %d], [%d, %d, %d, %d])\n",
|
||||
src_x, src_y, src_w, src_h, dstX, dstY, dst_w, dst_h);*/
|
||||
|
||||
if (dst && !dst->tex) {
|
||||
xorg_exa_set_shared_usage(pPixmap);
|
||||
pScrn->pScreen->ModifyPixmapHeader(pPixmap, 0, 0, 0, 0, 0, NULL);
|
||||
@@ -527,10 +533,10 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
|
||||
int box_y2 = pbox->y2;
|
||||
float diff_x = (float)src_w / (float)dst_w;
|
||||
float diff_y = (float)src_h / (float)dst_h;
|
||||
int offset_x = box_x1 - dstX + pPixmap->screen_x;
|
||||
int offset_y = box_y1 - dstY + pPixmap->screen_y;
|
||||
int offset_w;
|
||||
int offset_h;
|
||||
float offset_x = box_x1 - dstX + pPixmap->screen_x;
|
||||
float offset_y = box_y1 - dstY + pPixmap->screen_y;
|
||||
float offset_w;
|
||||
float offset_h;
|
||||
|
||||
x = box_x1;
|
||||
y = box_y1;
|
||||
@@ -540,8 +546,9 @@ display_video(ScrnInfoPtr pScrn, struct xorg_xv_port_priv *pPriv, int id,
|
||||
offset_w = dst_w - w;
|
||||
offset_h = dst_h - h;
|
||||
|
||||
draw_yuv(pPriv, src_x + offset_x*diff_x, src_y + offset_y*diff_y,
|
||||
src_w - offset_w*diff_x, src_h - offset_h*diff_x,
|
||||
draw_yuv(pPriv,
|
||||
(float) src_x + offset_x*diff_x, (float) src_y + offset_y*diff_y,
|
||||
(float) src_w - offset_w*diff_x, (float) src_h - offset_h*diff_y,
|
||||
x, y, w, h);
|
||||
|
||||
pbox++;
|
||||
|
@@ -103,6 +103,9 @@ struct vmw_svga_winsys_context
|
||||
* referred.
|
||||
*/
|
||||
boolean preemptive_flush;
|
||||
|
||||
boolean throttle_set;
|
||||
uint32_t throttle_us;
|
||||
};
|
||||
|
||||
|
||||
@@ -122,6 +125,7 @@ vmw_swc_flush(struct svga_winsys_context *swc,
|
||||
struct pipe_fence_handle *fence = NULL;
|
||||
unsigned i;
|
||||
enum pipe_error ret;
|
||||
uint32_t throttle_us;
|
||||
|
||||
ret = pb_validate_validate(vswc->validate);
|
||||
assert(ret == PIPE_OK);
|
||||
@@ -140,8 +144,13 @@ vmw_swc_flush(struct svga_winsys_context *swc,
|
||||
*reloc->where = ptr;
|
||||
}
|
||||
|
||||
throttle_us = vswc->throttle_set ?
|
||||
vswc->throttle_us : vswc->vws->default_throttle_us;
|
||||
|
||||
if (vswc->command.used)
|
||||
vmw_ioctl_command(vswc->vws,
|
||||
vswc->base.cid,
|
||||
throttle_us,
|
||||
vswc->command.buffer,
|
||||
vswc->command.used,
|
||||
&vswc->last_fence);
|
||||
@@ -385,3 +394,14 @@ vmw_svga_context_create(struct pipe_screen *screen)
|
||||
{
|
||||
return svga_context_create(screen);
|
||||
}
|
||||
|
||||
void
|
||||
vmw_svga_context_set_throttling(struct pipe_context *pipe,
|
||||
uint32_t throttle_us)
|
||||
{
|
||||
struct svga_winsys_context *swc = svga_winsys_context(pipe);
|
||||
struct vmw_svga_winsys_context *vswc = vmw_svga_winsys_context(swc);
|
||||
|
||||
vswc->throttle_us = throttle_us;
|
||||
vswc->throttle_set = TRUE;
|
||||
}
|
||||
|
@@ -55,5 +55,8 @@ vmw_svga_winsys_context_create(struct svga_winsys_screen *sws);
|
||||
struct pipe_context *
|
||||
vmw_svga_context_create(struct pipe_screen *screen);
|
||||
|
||||
void
|
||||
vmw_svga_context_set_throttling(struct pipe_context *pipe,
|
||||
uint32_t throttle_us);
|
||||
|
||||
#endif /* VMW_CONTEXT_H_ */
|
||||
|
@@ -37,13 +37,16 @@
|
||||
* module.
|
||||
*/
|
||||
struct vmw_winsys_screen *
|
||||
vmw_winsys_create( int fd )
|
||||
vmw_winsys_create( int fd, boolean use_old_scanout_flag )
|
||||
{
|
||||
struct vmw_winsys_screen *vws = CALLOC_STRUCT(vmw_winsys_screen);
|
||||
if (!vws)
|
||||
goto out_no_vws;
|
||||
|
||||
vws->ioctl.drm_fd = fd;
|
||||
vws->use_old_scanout_flag = use_old_scanout_flag;
|
||||
debug_printf("%s: use_old_scanout_flag == %s\n", __FUNCTION__,
|
||||
use_old_scanout_flag ? "true" : "false");
|
||||
|
||||
if (!vmw_ioctl_init(vws))
|
||||
goto out_no_ioctl;
|
||||
@@ -72,3 +75,13 @@ vmw_winsys_destroy(struct vmw_winsys_screen *vws)
|
||||
vmw_ioctl_cleanup(vws);
|
||||
FREE(vws);
|
||||
}
|
||||
|
||||
void
|
||||
vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
|
||||
uint32_t throttle_us)
|
||||
{
|
||||
struct vmw_winsys_screen *vws =
|
||||
vmw_winsys_screen(svga_winsys_screen(screen));
|
||||
|
||||
vws->default_throttle_us = throttle_us;
|
||||
}
|
||||
|
@@ -52,6 +52,9 @@ struct vmw_winsys_screen
|
||||
{
|
||||
struct svga_winsys_screen base;
|
||||
|
||||
boolean use_old_scanout_flag;
|
||||
uint32_t default_throttle_us;
|
||||
|
||||
struct {
|
||||
volatile uint32_t *fifo_map;
|
||||
uint64_t last_fence;
|
||||
@@ -94,9 +97,11 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws,
|
||||
|
||||
void
|
||||
vmw_ioctl_command(struct vmw_winsys_screen *vws,
|
||||
void *commands,
|
||||
uint32_t size,
|
||||
uint32_t *fence);
|
||||
int32_t cid,
|
||||
uint32_t throttle_us,
|
||||
void *commands,
|
||||
uint32_t size,
|
||||
uint32_t *fence);
|
||||
|
||||
struct vmw_region *
|
||||
vmw_ioctl_region_create(struct vmw_winsys_screen *vws, uint32_t size);
|
||||
@@ -131,8 +136,9 @@ boolean vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws);
|
||||
void vmw_ioctl_cleanup(struct vmw_winsys_screen *vws);
|
||||
void vmw_pools_cleanup(struct vmw_winsys_screen *vws);
|
||||
|
||||
struct vmw_winsys_screen *vmw_winsys_create(int fd);
|
||||
struct vmw_winsys_screen *vmw_winsys_create(int fd, boolean use_old_scanout_flag);
|
||||
void vmw_winsys_destroy(struct vmw_winsys_screen *sws);
|
||||
|
||||
void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
|
||||
uint32_t throttle_us);
|
||||
|
||||
#endif /* VMW_SCREEN_H_ */
|
||||
|
@@ -48,8 +48,9 @@ static struct dri1_api_version ddx_required = { 0, 1, 0 };
|
||||
static struct dri1_api_version ddx_compat = { 0, 0, 0 };
|
||||
static struct dri1_api_version dri_required = { 4, 0, 0 };
|
||||
static struct dri1_api_version dri_compat = { 4, 0, 0 };
|
||||
static struct dri1_api_version drm_required = { 0, 1, 0 };
|
||||
static struct dri1_api_version drm_compat = { 0, 0, 0 };
|
||||
static struct dri1_api_version drm_required = { 1, 0, 0 };
|
||||
static struct dri1_api_version drm_compat = { 1, 0, 0 };
|
||||
static struct dri1_api_version drm_scanout = { 0, 9, 0 };
|
||||
|
||||
static boolean
|
||||
vmw_dri1_check_version(const struct dri1_api_version *cur,
|
||||
@@ -84,6 +85,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
|
||||
struct vmw_winsys_screen *vws;
|
||||
struct pipe_screen *screen;
|
||||
struct dri1_create_screen_arg *dri1;
|
||||
boolean use_old_scanout_flag = FALSE;
|
||||
|
||||
if (!arg || arg->mode == DRM_CREATE_NORMAL) {
|
||||
struct dri1_api_version drm_ver;
|
||||
@@ -95,11 +97,16 @@ vmw_drm_create_screen(struct drm_api *drm_api,
|
||||
|
||||
drm_ver.major = ver->version_major;
|
||||
drm_ver.minor = ver->version_minor;
|
||||
drm_ver.patch_level = 0; /* ??? */
|
||||
|
||||
drmFreeVersion(ver);
|
||||
if (!vmw_dri1_check_version(&drm_ver, &drm_required,
|
||||
&drm_compat, "vmwgfx drm driver"))
|
||||
return NULL;
|
||||
|
||||
if (!vmw_dri1_check_version(&drm_ver, &drm_scanout,
|
||||
&drm_compat, "use old scanout field (not a error)"))
|
||||
use_old_scanout_flag = TRUE;
|
||||
}
|
||||
|
||||
if (arg != NULL) {
|
||||
@@ -117,6 +124,9 @@ vmw_drm_create_screen(struct drm_api *drm_api,
|
||||
if (!vmw_dri1_check_version(&dri1->drm_version, &drm_required,
|
||||
&drm_compat, "vmwgfx drm driver"))
|
||||
return NULL;
|
||||
if (!vmw_dri1_check_version(&dri1->drm_version, &drm_scanout,
|
||||
&drm_compat, "use old scanout field (not a error)"))
|
||||
use_old_scanout_flag = TRUE;
|
||||
dri1->api = &dri1_api_hooks;
|
||||
break;
|
||||
default:
|
||||
@@ -124,7 +134,7 @@ vmw_drm_create_screen(struct drm_api *drm_api,
|
||||
}
|
||||
}
|
||||
|
||||
vws = vmw_winsys_create( fd );
|
||||
vws = vmw_winsys_create( fd, use_old_scanout_flag );
|
||||
if (!vws)
|
||||
goto out_no_vws;
|
||||
|
||||
@@ -228,7 +238,7 @@ vmw_dri1_present_locked(struct pipe_context *locked_pipe,
|
||||
cmd.rect.y,
|
||||
cmd.rect.w, cmd.rect.h, cmd.rect.srcx, cmd.rect.srcy);
|
||||
|
||||
vmw_ioctl_command(vws, &cmd, sizeof cmd.header + cmd.header.size,
|
||||
vmw_ioctl_command(vws, -1, 0, &cmd, sizeof cmd.header + cmd.header.size,
|
||||
&fence_seq);
|
||||
visible = TRUE;
|
||||
}
|
||||
|
@@ -57,6 +57,12 @@ struct vmw_region
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
/* XXX: This isn't a real hardware flag, but just a hack for kernel to
|
||||
* know about primary surfaces. In newer versions of the kernel
|
||||
* interface the driver uses a special field.
|
||||
*/
|
||||
#define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9)
|
||||
|
||||
static void
|
||||
vmw_check_last_cmd(struct vmw_winsys_screen *vws)
|
||||
{
|
||||
@@ -169,7 +175,17 @@ vmw_ioctl_surface_create(struct vmw_winsys_screen *vws,
|
||||
vmw_printf("%s flags %d format %d\n", __FUNCTION__, flags, format);
|
||||
|
||||
memset(&s_arg, 0, sizeof(s_arg));
|
||||
req->flags = (uint32_t) flags;
|
||||
if (vws->use_old_scanout_flag &&
|
||||
(flags & SVGA3D_SURFACE_HINT_SCANOUT)) {
|
||||
req->flags = (uint32_t) flags;
|
||||
req->scanout = false;
|
||||
} else if (flags & SVGA3D_SURFACE_HINT_SCANOUT) {
|
||||
req->flags = (uint32_t) (flags & ~SVGA3D_SURFACE_HINT_SCANOUT);
|
||||
req->scanout = true;
|
||||
} else {
|
||||
req->flags = (uint32_t) flags;
|
||||
req->scanout = false;
|
||||
}
|
||||
req->format = (uint32_t) format;
|
||||
req->shareable = 1;
|
||||
|
||||
@@ -225,8 +241,9 @@ vmw_ioctl_surface_destroy(struct vmw_winsys_screen *vws, uint32 sid)
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
|
||||
uint32_t * pfence)
|
||||
vmw_ioctl_command(struct vmw_winsys_screen *vws, int32_t cid,
|
||||
uint32_t throttle_us, void *commands, uint32_t size,
|
||||
uint32_t *pfence)
|
||||
{
|
||||
struct drm_vmw_execbuf_arg arg;
|
||||
struct drm_vmw_fence_rep rep;
|
||||
@@ -259,6 +276,7 @@ vmw_ioctl_command(struct vmw_winsys_screen *vws, void *commands, uint32_t size,
|
||||
arg.fence_rep = (unsigned long)&rep;
|
||||
arg.commands = (unsigned long)commands;
|
||||
arg.command_size = size;
|
||||
arg.throttle_us = throttle_us;
|
||||
|
||||
do {
|
||||
ret = drmCommandWrite(vws->ioctl.drm_fd, DRM_VMW_EXECBUF, &arg, sizeof(arg));
|
||||
|
@@ -68,7 +68,8 @@
|
||||
#define DRM_VMW_PARAM_NUM_FREE_STREAMS 1
|
||||
#define DRM_VMW_PARAM_3D 2
|
||||
#define DRM_VMW_PARAM_FIFO_OFFSET 3
|
||||
|
||||
#define DRM_VMW_PARAM_HW_CAPS 4
|
||||
#define DRM_VMW_PARAM_FIFO_CAPS 5
|
||||
|
||||
/**
|
||||
* struct drm_vmw_getparam_arg
|
||||
@@ -85,49 +86,6 @@ struct drm_vmw_getparam_arg {
|
||||
uint32_t pad64;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_EXTENSION - Query device extensions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* struct drm_vmw_extension_rep
|
||||
*
|
||||
* @exists: The queried extension exists.
|
||||
* @driver_ioctl_offset: Ioctl number of the first ioctl in the extension.
|
||||
* @driver_sarea_offset: Offset to any space in the DRI SAREA
|
||||
* used by the extension.
|
||||
* @major: Major version number of the extension.
|
||||
* @minor: Minor version number of the extension.
|
||||
* @pl: Patch level version number of the extension.
|
||||
*
|
||||
* Output argument to the DRM_VMW_EXTENSION Ioctl.
|
||||
*/
|
||||
|
||||
struct drm_vmw_extension_rep {
|
||||
int32_t exists;
|
||||
uint32_t driver_ioctl_offset;
|
||||
uint32_t driver_sarea_offset;
|
||||
uint32_t major;
|
||||
uint32_t minor;
|
||||
uint32_t pl;
|
||||
uint32_t pad64;
|
||||
};
|
||||
|
||||
/**
|
||||
* union drm_vmw_extension_arg
|
||||
*
|
||||
* @extension - Ascii name of the extension to be queried. //In
|
||||
* @rep - Reply as defined above. //Out
|
||||
*
|
||||
* Argument to the DRM_VMW_EXTENSION Ioctl.
|
||||
*/
|
||||
|
||||
union drm_vmw_extension_arg {
|
||||
char extension[DRM_VMW_EXT_NAME_LEN];
|
||||
struct drm_vmw_extension_rep rep;
|
||||
};
|
||||
|
||||
/*************************************************************************/
|
||||
/**
|
||||
* DRM_VMW_CREATE_CONTEXT - Create a host context.
|
||||
@@ -181,6 +139,8 @@ struct drm_vmw_context_arg {
|
||||
* The size of the array should equal the total number of mipmap levels.
|
||||
* @shareable: Boolean whether other clients (as identified by file descriptors)
|
||||
* may reference this surface.
|
||||
* @scanout: Boolean whether the surface is intended to be used as a
|
||||
* scanout.
|
||||
*
|
||||
* Input data to the DRM_VMW_CREATE_SURFACE Ioctl.
|
||||
* Output data from the DRM_VMW_REF_SURFACE Ioctl.
|
||||
@@ -192,7 +152,7 @@ struct drm_vmw_surface_create_req {
|
||||
uint32_t mip_levels[DRM_VMW_MAX_SURFACE_FACES];
|
||||
uint64_t size_addr;
|
||||
int32_t shareable;
|
||||
uint32_t pad64;
|
||||
int32_t scanout;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -295,17 +255,28 @@ union drm_vmw_surface_reference_arg {
|
||||
*
|
||||
* @commands: User-space address of a command buffer cast to an uint64_t.
|
||||
* @command-size: Size in bytes of the command buffer.
|
||||
* @throttle-us: Sleep until software is less than @throttle_us
|
||||
* microseconds ahead of hardware. The driver may round this value
|
||||
* to the nearest kernel tick.
|
||||
* @fence_rep: User-space address of a struct drm_vmw_fence_rep cast to an
|
||||
* uint64_t.
|
||||
* @version: Allows expanding the execbuf ioctl parameters without breaking
|
||||
* backwards compatibility, since user-space will always tell the kernel
|
||||
* which version it uses.
|
||||
* @flags: Execbuf flags. None currently.
|
||||
*
|
||||
* Argument to the DRM_VMW_EXECBUF Ioctl.
|
||||
*/
|
||||
|
||||
#define DRM_VMW_EXECBUF_VERSION 0
|
||||
|
||||
struct drm_vmw_execbuf_arg {
|
||||
uint64_t commands;
|
||||
uint32_t command_size;
|
||||
uint32_t pad64;
|
||||
uint32_t throttle_us;
|
||||
uint64_t fence_rep;
|
||||
uint32_t version;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -40,8 +40,11 @@
|
||||
|
||||
struct vmw_dma_buffer;
|
||||
|
||||
struct vmw_driver
|
||||
struct vmw_customizer
|
||||
{
|
||||
CustomizerRec base;
|
||||
ScrnInfoPtr pScrn;
|
||||
|
||||
int fd;
|
||||
|
||||
void *cursor_priv;
|
||||
@@ -50,11 +53,10 @@ struct vmw_driver
|
||||
void *video_priv;
|
||||
};
|
||||
|
||||
static INLINE struct vmw_driver *
|
||||
vmw_driver(ScrnInfoPtr pScrn)
|
||||
static INLINE struct vmw_customizer *
|
||||
vmw_customizer(CustomizerPtr cust)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
return ms ? (struct vmw_driver *)ms->winsys_priv : NULL;
|
||||
return cust ? (struct vmw_customizer *) cust : NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,40 +64,40 @@ vmw_driver(ScrnInfoPtr pScrn)
|
||||
* vmw_video.c
|
||||
*/
|
||||
|
||||
Bool vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
|
||||
Bool vmw_video_init(struct vmw_customizer *vmw);
|
||||
|
||||
Bool vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
|
||||
Bool vmw_video_close(struct vmw_customizer *vmw);
|
||||
|
||||
void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
|
||||
void vmw_video_stop_all(struct vmw_customizer *vmw);
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* vmw_ioctl.c
|
||||
*/
|
||||
|
||||
int vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot);
|
||||
int vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot);
|
||||
|
||||
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_driver *vmw,
|
||||
struct vmw_dma_buffer * vmw_ioctl_buffer_create(struct vmw_customizer *vmw,
|
||||
uint32_t size,
|
||||
unsigned *handle);
|
||||
|
||||
void * vmw_ioctl_buffer_map(struct vmw_driver *vmw,
|
||||
void * vmw_ioctl_buffer_map(struct vmw_customizer *vmw,
|
||||
struct vmw_dma_buffer *buf);
|
||||
|
||||
void vmw_ioctl_buffer_unmap(struct vmw_driver *vmw,
|
||||
void vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw,
|
||||
struct vmw_dma_buffer *buf);
|
||||
|
||||
void vmw_ioctl_buffer_destroy(struct vmw_driver *vmw,
|
||||
void vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw,
|
||||
struct vmw_dma_buffer *buf);
|
||||
|
||||
int vmw_ioctl_supports_streams(struct vmw_driver *vmw);
|
||||
int vmw_ioctl_supports_streams(struct vmw_customizer *vmw);
|
||||
|
||||
int vmw_ioctl_num_streams(struct vmw_driver *vmw,
|
||||
int vmw_ioctl_num_streams(struct vmw_customizer *vmw,
|
||||
uint32_t *ntot, uint32_t *nfree);
|
||||
|
||||
int vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id);
|
||||
int vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id);
|
||||
|
||||
int vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out);
|
||||
int vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -57,7 +57,7 @@ struct vmw_dma_buffer
|
||||
};
|
||||
|
||||
static int
|
||||
vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
|
||||
vmw_ioctl_get_param(struct vmw_customizer *vmw, uint32_t param, uint64_t *out)
|
||||
{
|
||||
struct drm_vmw_getparam_arg gp_arg;
|
||||
int ret;
|
||||
@@ -75,7 +75,7 @@ vmw_ioctl_get_param(struct vmw_driver *vmw, uint32_t param, uint64_t *out)
|
||||
}
|
||||
|
||||
int
|
||||
vmw_ioctl_supports_streams(struct vmw_driver *vmw)
|
||||
vmw_ioctl_supports_streams(struct vmw_customizer *vmw)
|
||||
{
|
||||
uint64_t value;
|
||||
int ret;
|
||||
@@ -88,7 +88,7 @@ vmw_ioctl_supports_streams(struct vmw_driver *vmw)
|
||||
}
|
||||
|
||||
int
|
||||
vmw_ioctl_num_streams(struct vmw_driver *vmw,
|
||||
vmw_ioctl_num_streams(struct vmw_customizer *vmw,
|
||||
uint32_t *ntot, uint32_t *nfree)
|
||||
{
|
||||
uint64_t v1, v2;
|
||||
@@ -109,7 +109,7 @@ vmw_ioctl_num_streams(struct vmw_driver *vmw,
|
||||
}
|
||||
|
||||
int
|
||||
vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
|
||||
vmw_ioctl_claim_stream(struct vmw_customizer *vmw, uint32_t *out)
|
||||
{
|
||||
struct drm_vmw_stream_arg s_arg;
|
||||
int ret;
|
||||
@@ -125,7 +125,7 @@ vmw_ioctl_claim_stream(struct vmw_driver *vmw, uint32_t *out)
|
||||
}
|
||||
|
||||
int
|
||||
vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
|
||||
vmw_ioctl_unref_stream(struct vmw_customizer *vmw, uint32_t stream_id)
|
||||
{
|
||||
struct drm_vmw_stream_arg s_arg;
|
||||
int ret;
|
||||
@@ -140,7 +140,7 @@ vmw_ioctl_unref_stream(struct vmw_driver *vmw, uint32_t stream_id)
|
||||
}
|
||||
|
||||
int
|
||||
vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
|
||||
vmw_ioctl_cursor_bypass(struct vmw_customizer *vmw, int xhot, int yhot)
|
||||
{
|
||||
struct drm_vmw_cursor_bypass_arg arg;
|
||||
int ret;
|
||||
@@ -157,7 +157,7 @@ vmw_ioctl_cursor_bypass(struct vmw_driver *vmw, int xhot, int yhot)
|
||||
}
|
||||
|
||||
struct vmw_dma_buffer *
|
||||
vmw_ioctl_buffer_create(struct vmw_driver *vmw, uint32_t size, unsigned *handle)
|
||||
vmw_ioctl_buffer_create(struct vmw_customizer *vmw, uint32_t size, unsigned *handle)
|
||||
{
|
||||
struct vmw_dma_buffer *buf;
|
||||
union drm_vmw_alloc_dmabuf_arg arg;
|
||||
@@ -198,7 +198,7 @@ err:
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
|
||||
vmw_ioctl_buffer_destroy(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
|
||||
{
|
||||
struct drm_vmw_unref_dmabuf_arg arg;
|
||||
|
||||
@@ -215,7 +215,7 @@ vmw_ioctl_buffer_destroy(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
|
||||
}
|
||||
|
||||
void *
|
||||
vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
|
||||
vmw_ioctl_buffer_map(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
|
||||
{
|
||||
void *map;
|
||||
|
||||
@@ -236,7 +236,7 @@ vmw_ioctl_buffer_map(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
|
||||
}
|
||||
|
||||
void
|
||||
vmw_ioctl_buffer_unmap(struct vmw_driver *vmw, struct vmw_dma_buffer *buf)
|
||||
vmw_ioctl_buffer_unmap(struct vmw_customizer *vmw, struct vmw_dma_buffer *buf)
|
||||
{
|
||||
--buf->map_count;
|
||||
}
|
||||
|
@@ -32,16 +32,22 @@
|
||||
|
||||
#include "vmw_hook.h"
|
||||
#include "vmw_driver.h"
|
||||
#include <pipe/p_context.h>
|
||||
|
||||
#include "cursorstr.h"
|
||||
|
||||
void vmw_winsys_screen_set_throttling(struct pipe_screen *screen,
|
||||
uint32_t throttle_us);
|
||||
|
||||
|
||||
/* modified version of crtc functions */
|
||||
xf86CrtcFuncsRec vmw_screen_crtc_funcs;
|
||||
|
||||
static void
|
||||
vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
|
||||
{
|
||||
struct vmw_driver *vmw = modesettingPTR(crtc->scrn)->winsys_priv;
|
||||
struct vmw_customizer *vmw =
|
||||
vmw_customizer(xorg_customizer(crtc->scrn));
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
|
||||
xf86CrtcFuncsPtr funcs = vmw->cursor_priv;
|
||||
CursorPtr c = config->cursor;
|
||||
@@ -53,8 +59,9 @@ vmw_screen_cursor_load_argb(xf86CrtcPtr crtc, CARD32 *image)
|
||||
}
|
||||
|
||||
static void
|
||||
vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
vmw_screen_cursor_init(struct vmw_customizer *vmw)
|
||||
{
|
||||
ScrnInfoPtr pScrn = vmw->pScrn;
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int i;
|
||||
|
||||
@@ -70,9 +77,9 @@ vmw_screen_cursor_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
}
|
||||
|
||||
static void
|
||||
vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
vmw_screen_cursor_close(struct vmw_customizer *vmw)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(vmw->pScrn);
|
||||
int i;
|
||||
|
||||
vmw_ioctl_cursor_bypass(vmw, 0, 0);
|
||||
@@ -81,51 +88,81 @@ vmw_screen_cursor_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
config->crtc[i]->funcs = vmw->cursor_priv;
|
||||
}
|
||||
|
||||
static Bool
|
||||
vmw_screen_init(ScrnInfoPtr pScrn)
|
||||
static void
|
||||
vmw_context_throttle(CustomizerPtr cust,
|
||||
struct pipe_context *pipe,
|
||||
enum xorg_throttling_reason reason)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
struct vmw_driver *vmw;
|
||||
switch (reason) {
|
||||
case THROTTLE_RENDER:
|
||||
vmw_winsys_screen_set_throttling(pipe->screen, 20000);
|
||||
break;
|
||||
default:
|
||||
vmw_winsys_screen_set_throttling(pipe->screen, 0);
|
||||
}
|
||||
}
|
||||
|
||||
vmw = xnfcalloc(sizeof(*vmw), 1);
|
||||
if (!vmw)
|
||||
return FALSE;
|
||||
static void
|
||||
vmw_context_no_throttle(CustomizerPtr cust,
|
||||
struct pipe_context *pipe,
|
||||
enum xorg_throttling_reason reason)
|
||||
{
|
||||
vmw_winsys_screen_set_throttling(pipe->screen, 0);
|
||||
}
|
||||
|
||||
static Bool
|
||||
vmw_screen_init(CustomizerPtr cust, int fd)
|
||||
{
|
||||
struct vmw_customizer *vmw = vmw_customizer(cust);
|
||||
drmVersionPtr ver;
|
||||
|
||||
vmw->fd = fd;
|
||||
ver = drmGetVersion(fd);
|
||||
if (ver == NULL ||
|
||||
(ver->version_major == 1 && ver->version_minor < 1)) {
|
||||
cust->swap_throttling = TRUE;
|
||||
cust->dirty_throttling = TRUE;
|
||||
cust->winsys_context_throttle = vmw_context_no_throttle;
|
||||
} else {
|
||||
cust->swap_throttling = TRUE;
|
||||
cust->dirty_throttling = FALSE;
|
||||
cust->winsys_context_throttle = vmw_context_throttle;
|
||||
debug_printf("%s: Enabling kernel throttling.\n", __func__);
|
||||
}
|
||||
|
||||
if (ver)
|
||||
drmFreeVersion(ver);
|
||||
|
||||
vmw_screen_cursor_init(vmw);
|
||||
|
||||
vmw->fd = ms->fd;
|
||||
ms->winsys_priv = vmw;
|
||||
|
||||
vmw_screen_cursor_init(pScrn, vmw);
|
||||
|
||||
/* if gallium is used then we don't need to do anything more. */
|
||||
if (ms->screen)
|
||||
if (xorg_has_gallium(vmw->pScrn))
|
||||
return TRUE;
|
||||
|
||||
vmw_video_init(pScrn, vmw);
|
||||
vmw_video_init(vmw);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
vmw_screen_close(ScrnInfoPtr pScrn)
|
||||
vmw_screen_close(CustomizerPtr cust)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(pScrn);
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(cust);
|
||||
|
||||
if (!vmw)
|
||||
return TRUE;
|
||||
|
||||
vmw_screen_cursor_close(pScrn, vmw);
|
||||
vmw_screen_cursor_close(vmw);
|
||||
|
||||
vmw_video_close(pScrn, vmw);
|
||||
|
||||
ms->winsys_priv = NULL;
|
||||
xfree(vmw);
|
||||
vmw_video_close(vmw);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
vmw_screen_enter_vt(ScrnInfoPtr pScrn)
|
||||
vmw_screen_enter_vt(CustomizerPtr cust)
|
||||
{
|
||||
debug_printf("%s: enter\n", __func__);
|
||||
|
||||
@@ -133,13 +170,13 @@ vmw_screen_enter_vt(ScrnInfoPtr pScrn)
|
||||
}
|
||||
|
||||
static Bool
|
||||
vmw_screen_leave_vt(ScrnInfoPtr pScrn)
|
||||
vmw_screen_leave_vt(CustomizerPtr cust)
|
||||
{
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(cust);
|
||||
|
||||
debug_printf("%s: enter\n", __func__);
|
||||
|
||||
vmw_video_stop_all(pScrn, vmw);
|
||||
vmw_video_stop_all(vmw);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -153,18 +190,27 @@ static Bool (*vmw_screen_pre_init_saved)(ScrnInfoPtr pScrn, int flags) = NULL;
|
||||
static Bool
|
||||
vmw_screen_pre_init(ScrnInfoPtr pScrn, int flags)
|
||||
{
|
||||
modesettingPtr ms;
|
||||
struct vmw_customizer *vmw;
|
||||
CustomizerPtr cust;
|
||||
|
||||
vmw = xnfcalloc(1, sizeof(*vmw));
|
||||
if (!vmw)
|
||||
return FALSE;
|
||||
|
||||
cust = &vmw->base;
|
||||
|
||||
cust->winsys_screen_init = vmw_screen_init;
|
||||
cust->winsys_screen_close = vmw_screen_close;
|
||||
cust->winsys_enter_vt = vmw_screen_enter_vt;
|
||||
cust->winsys_leave_vt = vmw_screen_leave_vt;
|
||||
vmw->pScrn = pScrn;
|
||||
|
||||
pScrn->driverPrivate = cust;
|
||||
|
||||
pScrn->PreInit = vmw_screen_pre_init_saved;
|
||||
if (!pScrn->PreInit(pScrn, flags))
|
||||
return FALSE;
|
||||
|
||||
ms = modesettingPTR(pScrn);
|
||||
ms->winsys_screen_init = vmw_screen_init;
|
||||
ms->winsys_screen_close = vmw_screen_close;
|
||||
ms->winsys_enter_vt = vmw_screen_enter_vt;
|
||||
ms->winsys_leave_vt = vmw_screen_leave_vt;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -226,7 +226,7 @@ static void vmw_xv_query_best_size(ScrnInfoPtr pScrn, Bool motion,
|
||||
/*
|
||||
* Local functions.
|
||||
*/
|
||||
static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw);
|
||||
static XF86VideoAdaptorPtr vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw);
|
||||
|
||||
static int vmw_video_port_init(ScrnInfoPtr pScrn,
|
||||
struct vmw_video_port *port,
|
||||
@@ -243,9 +243,9 @@ static int vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
|
||||
short height, RegionPtr clipBoxes);
|
||||
static void vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port);
|
||||
|
||||
static int vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
|
||||
static int vmw_video_buffer_alloc(struct vmw_customizer *vmw, int size,
|
||||
struct vmw_video_buffer *out);
|
||||
static int vmw_video_buffer_free(struct vmw_driver *vmw,
|
||||
static int vmw_video_buffer_free(struct vmw_customizer *vmw,
|
||||
struct vmw_video_buffer *out);
|
||||
|
||||
|
||||
@@ -267,8 +267,9 @@ static int vmw_video_buffer_free(struct vmw_driver *vmw,
|
||||
*/
|
||||
|
||||
Bool
|
||||
vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
vmw_video_init(struct vmw_customizer *vmw)
|
||||
{
|
||||
ScrnInfoPtr pScrn = vmw->pScrn;
|
||||
ScreenPtr pScreen = pScrn->pScreen;
|
||||
XF86VideoAdaptorPtr *overlayAdaptors, *newAdaptors = NULL;
|
||||
XF86VideoAdaptorPtr newAdaptor = NULL;
|
||||
@@ -345,8 +346,9 @@ vmw_video_init(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
*/
|
||||
|
||||
Bool
|
||||
vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
vmw_video_close(struct vmw_customizer *vmw)
|
||||
{
|
||||
ScrnInfoPtr pScrn = vmw->pScrn;
|
||||
struct vmw_video_private *video;
|
||||
int i;
|
||||
|
||||
@@ -387,8 +389,9 @@ vmw_video_close(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
void vmw_video_stop_all(struct vmw_customizer *vmw)
|
||||
{
|
||||
ScrnInfoPtr pScrn = vmw->pScrn;
|
||||
struct vmw_video_private *video = vmw->video_priv;
|
||||
int i;
|
||||
|
||||
@@ -421,7 +424,7 @@ void vmw_video_stop_all(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
*/
|
||||
|
||||
static XF86VideoAdaptorPtr
|
||||
vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_driver *vmw)
|
||||
vmw_video_init_adaptor(ScrnInfoPtr pScrn, struct vmw_customizer *vmw)
|
||||
{
|
||||
XF86VideoAdaptorPtr adaptor;
|
||||
struct vmw_video_private *video;
|
||||
@@ -515,7 +518,7 @@ vmw_video_port_init(ScrnInfoPtr pScrn, struct vmw_video_port *port,
|
||||
unsigned char *buf, short width,
|
||||
short height, RegionPtr clipBoxes)
|
||||
{
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
|
||||
unsigned short w, h;
|
||||
int i, ret;
|
||||
|
||||
@@ -583,7 +586,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
|
||||
unsigned char *buf, short width,
|
||||
short height, RegionPtr clipBoxes)
|
||||
{
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
|
||||
struct drm_vmw_control_stream_arg arg;
|
||||
unsigned short w, h;
|
||||
int size;
|
||||
@@ -675,7 +678,7 @@ vmw_video_port_play(ScrnInfoPtr pScrn, struct vmw_video_port *port,
|
||||
static void
|
||||
vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
|
||||
{
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
|
||||
uint32 id, colorKey, flags;
|
||||
Bool isAutoPaintColorkey;
|
||||
int i;
|
||||
@@ -721,7 +724,7 @@ vmw_video_port_cleanup(ScrnInfoPtr pScrn, struct vmw_video_port *port)
|
||||
*/
|
||||
|
||||
static int
|
||||
vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
|
||||
vmw_video_buffer_alloc(struct vmw_customizer *vmw, int size,
|
||||
struct vmw_video_buffer *out)
|
||||
{
|
||||
out->buf = vmw_ioctl_buffer_create(vmw, size, &out->handle);
|
||||
@@ -764,7 +767,7 @@ vmw_video_buffer_alloc(struct vmw_driver *vmw, int size,
|
||||
*/
|
||||
|
||||
static int
|
||||
vmw_video_buffer_free(struct vmw_driver *vmw,
|
||||
vmw_video_buffer_free(struct vmw_customizer *vmw,
|
||||
struct vmw_video_buffer *out)
|
||||
{
|
||||
if (out->size == 0)
|
||||
@@ -814,7 +817,7 @@ vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
|
||||
Bool sync, RegionPtr clipBoxes, pointer data,
|
||||
DrawablePtr dst)
|
||||
{
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
|
||||
struct vmw_video_port *port = data;
|
||||
|
||||
debug_printf("%s: enter (%u, %u) (%ux%u) (%u, %u) (%ux%u) (%ux%u)\n", __func__,
|
||||
@@ -852,7 +855,7 @@ vmw_xv_put_image(ScrnInfoPtr pScrn, short src_x, short src_y,
|
||||
static void
|
||||
vmw_xv_stop_video(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
|
||||
{
|
||||
struct vmw_driver *vmw = vmw_driver(pScrn);
|
||||
struct vmw_customizer *vmw = vmw_customizer(xorg_customizer(pScrn));
|
||||
struct vmw_video_port *port = data;
|
||||
struct drm_vmw_control_stream_arg arg;
|
||||
int ret;
|
||||
|
@@ -33,12 +33,50 @@
|
||||
|
||||
#include "vmw_hook.h"
|
||||
|
||||
|
||||
/*
|
||||
* Defines and modinfo
|
||||
*/
|
||||
|
||||
#define VMWGFX_DRIVER_NAME "vmwgfx"
|
||||
|
||||
#define VMW_STRING_INNER(s) #s
|
||||
#define VMW_STRING(str) VMW_STRING_INNER(str)
|
||||
|
||||
#define VMWGFX_VERSION_MAJOR 11
|
||||
#define VMWGFX_VERSION_MINOR 0
|
||||
#define VMWGFX_VERSION_PATCH 0
|
||||
#define VMWGFX_VERSION_STRING_MAJOR VMW_STRING(VMWGFX_VERSION_MAJOR)
|
||||
#define VMWGFX_VERSION_STRING_MINOR VMW_STRING(VMWGFX_VERSION_MINOR)
|
||||
#define VMWGFX_VERSION_STRING_PATCH VMW_STRING(VMWGFX_VERSION_PATCH)
|
||||
|
||||
#define VMWGFX_DRIVER_VERSION \
|
||||
(VMWGFX_VERSION_MAJOR * 65536 + VMWGFX_VERSION_MINOR * 256 + VMWGFX_VERSION_PATCH)
|
||||
#define VMWGFX_DRIVER_VERSION_STRING \
|
||||
VMWGFX_VERSION_STRING_MAJOR "." VMWGFX_VERSION_STRING_MINOR \
|
||||
"." VMWGFX_VERSION_STRING_PATCH
|
||||
|
||||
/*
|
||||
* Standard four digit version string expected by VMware Tools installer.
|
||||
* As the driver's version is only {major, minor, patchlevel}, simply append an
|
||||
* extra zero for the fourth digit.
|
||||
*/
|
||||
#ifdef __GNUC__
|
||||
_X_EXPORT const char vmwgfx_drv_modinfo[] __attribute__((section(".modinfo"),unused)) =
|
||||
"version=" VMWGFX_DRIVER_VERSION_STRING ".0";
|
||||
#endif
|
||||
|
||||
static void vmw_xorg_identify(int flags);
|
||||
_X_EXPORT Bool vmw_xorg_pci_probe(DriverPtr driver,
|
||||
int entity_num,
|
||||
struct pci_device *device,
|
||||
intptr_t match_data);
|
||||
|
||||
|
||||
/*
|
||||
* Tables
|
||||
*/
|
||||
|
||||
static const struct pci_id_match vmw_xorg_device_match[] = {
|
||||
{0x15ad, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0},
|
||||
@@ -55,12 +93,12 @@ static PciChipsets vmw_xorg_pci_devices[] = {
|
||||
};
|
||||
|
||||
static XF86ModuleVersionInfo vmw_xorg_version = {
|
||||
"vmwgfx",
|
||||
VMWGFX_DRIVER_NAME,
|
||||
MODULEVENDORSTRING,
|
||||
MODINFOSTRING1,
|
||||
MODINFOSTRING2,
|
||||
XORG_VERSION_CURRENT,
|
||||
0, 1, 0, /* major, minor, patch */
|
||||
VMWGFX_VERSION_MAJOR, VMWGFX_VERSION_MINOR, VMWGFX_VERSION_PATCH,
|
||||
ABI_CLASS_VIDEODRV,
|
||||
ABI_VIDEODRV_VERSION,
|
||||
MOD_CLASS_VIDEODRV,
|
||||
@@ -73,7 +111,7 @@ static XF86ModuleVersionInfo vmw_xorg_version = {
|
||||
|
||||
_X_EXPORT DriverRec vmwgfx = {
|
||||
1,
|
||||
"vmwgfx",
|
||||
VMWGFX_DRIVER_NAME,
|
||||
vmw_xorg_identify,
|
||||
NULL,
|
||||
xorg_tracker_available_options,
|
||||
@@ -92,6 +130,7 @@ _X_EXPORT XF86ModuleData vmwgfxModuleData = {
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Xorg driver functions
|
||||
*/
|
||||
|
@@ -267,13 +267,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (!stw_init(&stw_winsys)) {
|
||||
return FALSE;
|
||||
}
|
||||
return stw_init_thread();
|
||||
stw_init(&stw_winsys);
|
||||
stw_init_thread();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
return stw_init_thread();
|
||||
stw_init_thread();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
stw_cleanup_thread();
|
||||
|
@@ -317,13 +317,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
|
||||
{
|
||||
switch (fdwReason) {
|
||||
case DLL_PROCESS_ATTACH:
|
||||
if (!stw_init(&stw_winsys)) {
|
||||
return FALSE;
|
||||
}
|
||||
return stw_init_thread();
|
||||
stw_init(&stw_winsys);
|
||||
stw_init_thread();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_ATTACH:
|
||||
return stw_init_thread();
|
||||
stw_init_thread();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
stw_cleanup_thread();
|
||||
|
@@ -437,8 +437,10 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
|
||||
psc->ext_list_first_time = GL_TRUE;
|
||||
|
||||
if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
|
||||
&driverName, &deviceName))
|
||||
&driverName, &deviceName)) {
|
||||
XFree(psp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
psc->driver = driOpenDriver(driverName);
|
||||
if (psc->driver == NULL) {
|
||||
@@ -467,17 +469,17 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
|
||||
psc->fd = open(deviceName, O_RDWR);
|
||||
if (psc->fd < 0) {
|
||||
ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
|
||||
return NULL;
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
if (drmGetMagic(psc->fd, &magic)) {
|
||||
ErrorMessageF("failed to get magic\n");
|
||||
return NULL;
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
|
||||
ErrorMessageF("failed to authenticate magic %d\n", magic);
|
||||
return NULL;
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
/* If the server does not support the protocol for
|
||||
@@ -491,7 +493,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
|
||||
|
||||
if (psc->__driScreen == NULL) {
|
||||
ErrorMessageF("failed to create dri screen\n");
|
||||
return NULL;
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
driBindExtensions(psc, 1);
|
||||
@@ -521,6 +523,7 @@ dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
|
||||
handle_error:
|
||||
Xfree(driverName);
|
||||
Xfree(deviceName);
|
||||
XFree(psp);
|
||||
|
||||
/* FIXME: clean up here */
|
||||
|
||||
|
@@ -385,7 +385,8 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig,
|
||||
req->glxwindow = (GLXWindow) XAllocID(dpy);
|
||||
req->numAttribs = (CARD32) i;
|
||||
|
||||
memcpy(data, attrib_list, 8 * i);
|
||||
if (attrib_list)
|
||||
memcpy(data, attrib_list, 8 * i);
|
||||
|
||||
UnlockDisplay(dpy);
|
||||
SyncHandle();
|
||||
|
@@ -291,7 +291,8 @@ __glXInitVertexArrayState(__GLXcontext * gc)
|
||||
|
||||
arrays->stack_index = 0;
|
||||
arrays->stack = malloc(sizeof(struct array_stack_state)
|
||||
* arrays->num_arrays);
|
||||
* arrays->num_arrays
|
||||
* __GL_CLIENT_ATTRIB_STACK_DEPTH);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -60,14 +60,6 @@ driNewRenderbuffer(gl_format format, GLvoid *addr,
|
||||
{
|
||||
driRenderbuffer *drb;
|
||||
|
||||
assert(format == GL_RGBA ||
|
||||
format == GL_RGB5 ||
|
||||
format == GL_RGBA8 ||
|
||||
format == GL_DEPTH_COMPONENT16 ||
|
||||
format == GL_DEPTH_COMPONENT24 ||
|
||||
format == GL_DEPTH_COMPONENT32 ||
|
||||
format == GL_STENCIL_INDEX8_EXT);
|
||||
|
||||
assert(cpp > 0);
|
||||
assert(pitch > 0);
|
||||
|
||||
|
@@ -254,7 +254,7 @@ void intel_flush_prim(struct intel_context *intel)
|
||||
BEGIN_BATCH(5, LOOP_CLIPRECTS);
|
||||
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
|
||||
I1_LOAD_S(0) | I1_LOAD_S(1) | 1);
|
||||
assert((offset & !S0_VB_OFFSET_MASK) == 0);
|
||||
assert((offset & ~S0_VB_OFFSET_MASK) == 0);
|
||||
OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0, offset);
|
||||
OUT_BATCH((intel->vertex_size << S1_VERTEX_WIDTH_SHIFT) |
|
||||
(intel->vertex_size << S1_VERTEX_PITCH_SHIFT));
|
||||
@@ -273,7 +273,7 @@ void intel_flush_prim(struct intel_context *intel)
|
||||
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
|
||||
I1_LOAD_S(0) | I1_LOAD_S(2) | 1);
|
||||
/* S0 */
|
||||
assert((offset & !S0_VB_OFFSET_MASK_830) == 0);
|
||||
assert((offset & ~S0_VB_OFFSET_MASK_830) == 0);
|
||||
OUT_RELOC(vb_bo, I915_GEM_DOMAIN_VERTEX, 0,
|
||||
offset | (intel->vertex_size << S0_VB_PITCH_SHIFT_830) |
|
||||
S0_VB_ENABLE_830);
|
||||
|
@@ -770,7 +770,13 @@ get_constant(struct brw_vs_compile *c,
|
||||
if (c->current_const[argIndex].index != src->Index || relAddr) {
|
||||
struct brw_reg addrReg = c->regs[PROGRAM_ADDRESS][0];
|
||||
|
||||
c->current_const[argIndex].index = src->Index;
|
||||
/* If using a non-relative-addressed constant, then keep track of it for
|
||||
* later use without reloading.
|
||||
*/
|
||||
if (relAddr)
|
||||
c->current_const[argIndex].index = -1;
|
||||
else
|
||||
c->current_const[argIndex].index = src->Index;
|
||||
|
||||
#if 0
|
||||
printf(" fetch const[%d] for arg %d into reg %d\n",
|
||||
|
@@ -376,6 +376,7 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
|
||||
GLint cx, cy, cw, ch;
|
||||
drm_clip_rect_t clear;
|
||||
int i;
|
||||
drm_intel_bo *aper_array[2];
|
||||
|
||||
/* Get clear bounds after locking */
|
||||
cx = fb->_Xmin;
|
||||
@@ -526,6 +527,15 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
|
||||
assert(x1 < x2);
|
||||
assert(y1 < y2);
|
||||
|
||||
/* do space check before going any further */
|
||||
aper_array[0] = intel->batch->buf;
|
||||
aper_array[1] = write_buffer;
|
||||
|
||||
if (drm_intel_bufmgr_check_aperture_space(aper_array,
|
||||
ARRAY_SIZE(aper_array)) != 0) {
|
||||
intel_batchbuffer_flush(intel->batch);
|
||||
}
|
||||
|
||||
BEGIN_BATCH(6, REFERENCES_CLIPRECTS);
|
||||
OUT_BATCH(CMD);
|
||||
OUT_BATCH(BR13);
|
||||
|
@@ -172,6 +172,8 @@ do_blit_readpixels(GLcontext * ctx,
|
||||
struct intel_buffer_object *dst = intel_buffer_object(pack->BufferObj);
|
||||
GLuint dst_offset;
|
||||
GLuint rowLength;
|
||||
drm_intel_bo *dst_buffer;
|
||||
drm_clip_rect_t read_bounds, rect, src_rect;
|
||||
|
||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||
_mesa_printf("%s\n", __FUNCTION__);
|
||||
@@ -212,58 +214,47 @@ do_blit_readpixels(GLcontext * ctx,
|
||||
return GL_FALSE;
|
||||
}
|
||||
else {
|
||||
rowLength = -rowLength;
|
||||
if (ctx->ReadBuffer->Name == 0)
|
||||
rowLength = -rowLength;
|
||||
}
|
||||
|
||||
dst_offset = (GLintptr) _mesa_image_address(2, pack, pixels, width, height,
|
||||
format, type, 0, 0, 0);
|
||||
|
||||
GLboolean all = (width * height * src->cpp == dst->Base.Size &&
|
||||
x == 0 && dst_offset == 0);
|
||||
|
||||
/* Although the blits go on the command buffer, need to do this and
|
||||
* fire with lock held to guarentee cliprects are correct.
|
||||
*/
|
||||
intelFlush(&intel->ctx);
|
||||
LOCK_HARDWARE(intel);
|
||||
dst_buffer = intel_bufferobj_buffer(intel, dst,
|
||||
all ? INTEL_WRITE_FULL :
|
||||
INTEL_WRITE_PART);
|
||||
|
||||
if (intel->driReadDrawable->numClipRects) {
|
||||
GLboolean all = (width * height * src->cpp == dst->Base.Size &&
|
||||
x == 0 && dst_offset == 0);
|
||||
src_rect.x1 = x;
|
||||
if (ctx->ReadBuffer->Name == 0)
|
||||
src_rect.y1 = ctx->ReadBuffer->Height - (y + height);
|
||||
else
|
||||
src_rect.y1 = y;
|
||||
src_rect.x2 = src_rect.x1 + width;
|
||||
src_rect.y2 = src_rect.y1 + height;
|
||||
|
||||
dri_bo *dst_buffer = intel_bufferobj_buffer(intel, dst,
|
||||
all ? INTEL_WRITE_FULL :
|
||||
INTEL_WRITE_PART);
|
||||
__DRIdrawablePrivate *dPriv = intel->driReadDrawable;
|
||||
int nbox = dPriv->numClipRects;
|
||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||
drm_clip_rect_t rect;
|
||||
drm_clip_rect_t src_rect;
|
||||
int i;
|
||||
read_bounds.x1 = 0;
|
||||
read_bounds.y1 = 0;
|
||||
read_bounds.x2 = ctx->ReadBuffer->Width;
|
||||
read_bounds.y2 = ctx->ReadBuffer->Height;
|
||||
|
||||
src_rect.x1 = dPriv->x + x;
|
||||
src_rect.y1 = dPriv->y + dPriv->h - (y + height);
|
||||
src_rect.x2 = src_rect.x1 + width;
|
||||
src_rect.y2 = src_rect.y1 + height;
|
||||
if (!intel_intersect_cliprects(&rect, &src_rect, &read_bounds))
|
||||
return GL_TRUE;
|
||||
|
||||
|
||||
|
||||
for (i = 0; i < nbox; i++) {
|
||||
if (!intel_intersect_cliprects(&rect, &src_rect, &box[i]))
|
||||
continue;
|
||||
|
||||
if (!intelEmitCopyBlit(intel,
|
||||
src->cpp,
|
||||
src->pitch, src->buffer, 0, src->tiling,
|
||||
rowLength, dst_buffer, dst_offset, GL_FALSE,
|
||||
rect.x1,
|
||||
rect.y1,
|
||||
rect.x1 - src_rect.x1,
|
||||
rect.y2 - src_rect.y2,
|
||||
rect.x2 - rect.x1, rect.y2 - rect.y1,
|
||||
GL_COPY)) {
|
||||
UNLOCK_HARDWARE(intel);
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
if (!intelEmitCopyBlit(intel,
|
||||
src->cpp,
|
||||
src->pitch, src->buffer, 0, src->tiling,
|
||||
rowLength, dst_buffer, dst_offset, GL_FALSE,
|
||||
rect.x1,
|
||||
rect.y1,
|
||||
rect.x1 - src_rect.x1,
|
||||
rect.y2 - src_rect.y2,
|
||||
rect.x2 - rect.x1, rect.y2 - rect.y1,
|
||||
GL_COPY)) {
|
||||
return GL_FALSE;
|
||||
}
|
||||
UNLOCK_HARDWARE(intel);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user