diff options
author | Brian Paul <[email protected]> | 2010-01-22 15:36:28 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2010-01-22 15:36:38 -0700 |
commit | 8d1a01d37039a76ecbb8fdb4c10ff8d11aa02dfb (patch) | |
tree | fcac644b35a093ecbfb1142ee17b3f84456fd5f3 /src | |
parent | efde2df114c2c15212198cb196b50cd29bd75f70 (diff) |
mesa: use new fetch_vector1ui() function for 'unpack' GPU instructions
The UP2H, UP2US, UP4B and UP4UB instructions interpret the float
registers as integers. With gcc -O3 some bits were getting mixed up
somewhere. This is part of the fix for the piglit fp-unpack-01 test
failure (bug 25973).
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/shader/prog_execute.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 1ef801a17dd..fb29768935f 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -341,6 +341,28 @@ fetch_vector1(const struct prog_src_register *source, } +static GLuint +fetch_vector1ui(const struct prog_src_register *source, + const struct gl_program_machine *machine) +{ + const GLuint *src = (GLuint *) get_src_register_pointer(source, machine); + GLuint result; + + ASSERT(src); + + result = src[GET_SWZ(source->Swizzle, 0)]; + + if (source->Abs) { + result = FABSF(result); + } + if (source->Negate) { + result = -result; + } + + return result; +} + + /** * Fetch texel from texture. Use partial derivatives when possible. */ @@ -1633,12 +1655,11 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_UP2H: /* unpack two 16-bit floats */ { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; GLhalfNV hx, hy; - fetch_vector1(&inst->SrcReg[0], machine, a); - hx = rawBits[0] & 0xffff; - hy = rawBits[0] >> 16; + hx = raw & 0xffff; + hy = raw >> 16; result[0] = result[2] = _mesa_half_to_float(hx); result[1] = result[3] = _mesa_half_to_float(hy); store_vector4(inst, machine, result); @@ -1646,12 +1667,11 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_UP2US: /* unpack two GLushorts */ { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; GLushort usx, usy; - fetch_vector1(&inst->SrcReg[0], machine, a); - usx = rawBits[0] & 0xffff; - usy = rawBits[0] >> 16; + usx = raw & 0xffff; + usy = raw >> 16; result[0] = result[2] = usx * (1.0f / 65535.0f); result[1] = result[3] = usy * (1.0f / 65535.0f); store_vector4(inst, machine, result); @@ -1659,25 +1679,23 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_UP4B: /* unpack four GLbytes */ { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1(&inst->SrcReg[0], machine, a); - result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; - result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; - result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; - result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; + result[0] = (((raw >> 0) & 0xff) - 128) / 127.0F; + result[1] = (((raw >> 8) & 0xff) - 128) / 127.0F; + result[2] = (((raw >> 16) & 0xff) - 128) / 127.0F; + result[3] = (((raw >> 24) & 0xff) - 128) / 127.0F; store_vector4(inst, machine, result); } break; case OPCODE_UP4UB: /* unpack four GLubytes */ { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1(&inst->SrcReg[0], machine, a); - result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; - result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; - result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; - result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; + const GLuint raw = fetch_vector1ui(&inst->SrcReg[0], machine); + GLfloat result[4]; + result[0] = ((raw >> 0) & 0xff) / 255.0F; + result[1] = ((raw >> 8) & 0xff) / 255.0F; + result[2] = ((raw >> 16) & 0xff) / 255.0F; + result[3] = ((raw >> 24) & 0xff) / 255.0F; store_vector4(inst, machine, result); } break; |