Summary: | [softpipe] glxgears floating point exception | ||
---|---|---|---|
Product: | Mesa | Reporter: | Vinson Lee <vlee> |
Component: | Mesa core | Assignee: | mesa-dev |
Status: | RESOLVED FIXED | QA Contact: | |
Severity: | critical | ||
Priority: | medium | CC: | jfonseca, jsg, sroland, zackr |
Version: | git | Keywords: | regression |
Hardware: | x86-64 (AMD64) | ||
OS: | Linux (All) | ||
Whiteboard: | |||
i915 platform: | i915 features: |
Description
Vinson Lee
2013-07-10 23:58:36 UTC
I can't reproduce this here for some reason. That said I think we should probably manipulate mxcsr a bit more, in particular we should explicitly disable all exceptions (they are disabled by default but app may enable them), since a shader can legitimately generate such an exception regardless of denorms, and certainly getting that exception reported is NOT the right answer. (The other question is why there's an exception there in the first place for simple glxgears shader. IIRC there were some problems with viewport being all zero for the first draw call because some resize was missing or something like that for some of the demos a while ago but I would expect that to produce zeros not denorms.) Indeed http://software.intel.com/en-us/articles/x87-and-sse-floating-point-assists-in-ia-32-flush-to-zero-ftz-and-denormals-are-zero-daz suggests to mask certain exceptions together with the FTZ/DAZ bits: // UNDERFLOWS set_mxcsr_on(FTZ_BIT); set_mxcsr_off(UNDERFLOW_EXCEPTION_MASK); make_denormal(); clear_flags(); // DENORMALS set_mxcsr_off(DAZ_BIT); set_mxcsr_on(DENORMAL_EXCEPTION_MASK); make_denormal(); clear_flags(); So we should probably do the same. (In reply to comment #2) > Indeed > http://software.intel.com/en-us/articles/x87-and-sse-floating-point-assists- > in-ia-32-flush-to-zero-ftz-and-denormals-are-zero-daz > > suggests to mask certain exceptions together with the FTZ/DAZ bits: > So we should probably do the same. Yes but I think we really should mask ALL exceptions regardless of denorms. A shader might easily do things causing exceptions (divide by zero or whatnot) and there's certainly no signaled exceptions in 3d graphics. I think we've just not seen issues because they are masked by default and no app unmasked them. Might be worth adding a piglit test for that. commit 63386b2f66a6d450889cd5368bc599beb7f1efbf also regresses ~4000 piglit tests on softpipe. Vinson, since I can't reproduce this here could you do a "info registers mxcsr"? I'm curious what the exception mask actually is. Also, what are the src0->f[0] and src1->f[0] values? Program received signal SIGFPE, Arithmetic exception. 0x00007ffff4d4b21f in micro_mul (dst=0x7fffffffd270, src0=0x7fffffffd250, src1=0x7fffffffd260) at tgsi/tgsi_exec.c:983 983 dst->f[0] = src0->f[0] * src1->f[0]; (gdb) info registers mxcsr mxcsr 0x8060 [ PE DAZ FZ ] (gdb) print src0 $1 = (const union tgsi_exec_channel *) 0x7fffffffd250 (gdb) print src1 $2 = (const union tgsi_exec_channel *) 0x7fffffffd260 (gdb) print src0->f $3 = {3.6500001, 4.33659029, 4.29644442, 3.54915023} (gdb) print src1->f $4 = {4.33012676, 4.33012676, 4.33012676, 4.33012676} (gdb) print dst $5 = (union tgsi_exec_channel *) 0x7fffffffd270 (gdb) print dst->f $6 = {1.08687624e-38, 2.80259693e-45, 9.03817331e-39, 0} (In reply to comment #6) > (gdb) info registers mxcsr > mxcsr 0x8060 [ PE DAZ FZ ] Hmm that is just crazy, somehow all exceptions got unmasked and we get a precision exception (which is really useless as you get that with just about any floating point instruction). Doesn't make sense to me since the code does: unsigned fpstate = util_fpstate_get(); util_fpstate_set_denorms_to_zero(fpstate); which should preserve all already masked exceptions, as the latter simply adds some bits. Maybe somehow the compiler reorders things or something like that, though I'm pretty sure it shouldn't, or need to add some more keywords like volatile or whatnot, but I don't see anything obvious. Vinson, this looks like a compiler issue to me, what compiler are you using? I suspect something funky might be going on when setting/getting mxcsr value. A disassembly of draw_vbo() where these are set might help (there should be some stmxcsr, doing some ors with the return value followed by a ldmxcsr with that value). Another solution would be to just set the exception mask bits regardless what the value before was. Something like this: diff --git a/src/gallium/auxiliary/util/u_math.c b/src/gallium/auxiliary/util/u_math.c index f3fe392..8c394d9 100644 --- a/src/gallium/auxiliary/util/u_math.c +++ b/src/gallium/auxiliary/util/u_math.c @@ -110,7 +110,7 @@ util_fpstate_set_denorms_to_zero(unsigned current_mxcsr) #if defined(PIPE_ARCH_SSE) if (util_cpu_caps.has_sse) { /* Enable flush to zero mode */ - current_mxcsr |= _MM_FLUSH_ZERO_MASK; + current_mxcsr |= _MM_FLUSH_ZERO_MASK | _MM_MASK_MASK; if (util_cpu_caps.has_sse3) { /* Enable denormals are zero mode */ current_mxcsr |= _MM_DENORMALS_ZERO_MASK; In fact could potentially skip getting the previously set values entirely and just set them to whatever we want (and setting back to some sane values at the end, as it seems all ABIs require the same bits set. But I'm not 100% certain the same bits are really right in all environments, so setting them back to what they were before might be safer (as long as it works...). I can reproduce this bug with gcc 4.4.7 on CentOS 6, gcc 4.6.3 on Ubuntu 12.04, gcc 4.7.3 on Ubuntu 13.04, and gcc 4.8.1 on Ubuntu 13.10. Fixed by 1e003b44e83dde3912ec48eb3df0e25802b5101e. *** Bug 67587 has been marked as a duplicate of this bug. *** |
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.