| Summary: | Missing ArcSine and ArcCosine capability in GLSL | ||
|---|---|---|---|
| Product: | Mesa | Reporter: | James Burns <James.Burns> |
| Component: | Mesa core | Assignee: | mesa-dev |
| Status: | RESOLVED FIXED | QA Contact: | |
| Severity: | critical | ||
| Priority: | high | ||
| Version: | 6.5 | ||
| Hardware: | All | ||
| OS: | Linux (All) | ||
| Whiteboard: | |||
| i915 platform: | i915 features: | ||
|
Description
James Burns
2007-04-27 13:26:09 UTC
Hmmm, I don't think I have time to implement acos/asin() today, but I can at least fix the crash. I'll mark it as a known issue and fix it properly for Mesa 7.0. How's that? I did a bit of research on the net, and I think asin, acos, and atan can be approcimated pretty easilly. This should make the GLSL to GL_ARB_{fragment,vertex}_program conversion pretty simple:
asin(x) = pi/2 - sqrt(1 - x)(a0 + a1*x + a2*x^2 + a3*x^3)
acos(x) = sqrt(1 - x)(a0 + a1*x + a2*x^2 + a3*x^3)
where
a0 = 1.5707288
a1 = -0.2121144
a2 = 0.0742610
a3 = -0.0187293
atan(y, x) = s * ( pi/4 - (pi / 4) * ((x - |y|) / (x + |y|))) for x >= 0
s * (3pi/4 - (pi / 4) * ((x + |y|) / (|y| - x))) for x < 0
where
s = -1 for y < 0
s = 1 otherwise
References:
http://mathforum.org/library/drmath/view/54137.html
http://dspguru.com/comp.dsp/tricks/alg/fxdatan2.htm
http://en.wikipedia.org/wiki/Arcsin#Recommended_method_of_calculation
(In reply to comment #1) > Hmmm, I don't think I have time to implement acos/asin() today, but I can at > least fix the crash. > I'll mark it as a known issue and fix it properly for Mesa 7.0. How's that? > I've fixed this in my own version of Mesa, so I will be fine waiting for Mesa 7.0 on this. I surely would like to see this fixed in the next release. (In reply to comment #2) > I did a bit of research on the net, and I think asin, acos, and atan can be > approcimated pretty easilly. This should make the GLSL to > GL_ARB_{fragment,vertex}_program conversion pretty simple: > > asin(x) = pi/2 - sqrt(1 - x)(a0 + a1*x + a2*x^2 + a3*x^3) > acos(x) = sqrt(1 - x)(a0 + a1*x + a2*x^2 + a3*x^3) > > where > > a0 = 1.5707288 > a1 = -0.2121144 > a2 = 0.0742610 > a3 = -0.0187293 > > atan(y, x) = s * ( pi/4 - (pi / 4) * ((x - |y|) / (x + |y|))) for x >= 0 > s * (3pi/4 - (pi / 4) * ((x + |y|) / (|y| - x))) for x < 0 > > where > s = -1 for y < 0 > s = 1 otherwise > > References: > > http://mathforum.org/library/drmath/view/54137.html > http://dspguru.com/comp.dsp/tricks/alg/fxdatan2.htm > http://en.wikipedia.org/wiki/Arcsin#Recommended_method_of_calculation > In this case, I would defer to whatever the community wants to do here. (Assuming the math here is correct, and I have not checked it.) It would appear that this solution is faster than a typical asin/acos implemented by most compilers. We do similiar sorts of approximations here for our realtime applications, but we often use 6th order expressions. It does seem that this approach is out of sync with the remainder of the MESA GLSL approach, using the _mesa_XXX functions which call the standard C math functions. In the patch I am using here, I stuck with the current approach for the sake of consistency. If I were to follow the pattern of the other trigonometry functions in Mesa's GLSL, I'd add OPCODE_ACOS/ASIN instructions and simply call acos/asin() in the program interpreter. I doubt, however, that any target GPUs will have native ACOS/ASIN instructions so those Mesa instructions would have to be expanded into code to compute an approximation. That'll probably be needed for sin/cos as-is. I believe Ian's code is meant to go into the GLSL acos/asin functions so that it gets compiled into Mesa GPU instructions. I'll give that a try. (In reply to comment #5) > If I were to follow the pattern of the other trigonometry functions in Mesa's > GLSL, I'd add OPCODE_ACOS/ASIN instructions and simply call acos/asin() in the > program interpreter. > > I doubt, however, that any target GPUs will have native ACOS/ASIN instructions > so those Mesa instructions would have to be expanded into code to compute an > approximation. That'll probably be needed for sin/cos as-is. > > I believe Ian's code is meant to go into the GLSL acos/asin functions so that > it gets compiled into Mesa GPU instructions. I'll give that a try. > That's probably a good point. I'm a rare bird living in the land of OSMesa. Ian, is a0 supposed to be PI/2? 1.5707288 is pretty close, but not quite. In any case, I've commited asin() based on your series. acos() and atan() are in terms of acos(). (In reply to comment #7) > Ian, is a0 supposed to be PI/2? 1.5707288 is pretty close, but not quite. > > In any case, I've commited asin() based on your series. acos() and atan() are > in terms of acos(). > Fix checked out ok in my test cases and main application. |
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.