diff options
author | Marek Olšák <[email protected]> | 2015-07-24 00:54:08 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2015-07-25 10:38:14 +0200 |
commit | 9deb614cacbeca3e99724f08254ab1789f34b56c (patch) | |
tree | efd7e37eaa497b35fd13f97ee7c77522d022d609 /src/gallium/drivers/radeon | |
parent | e39ece0d7856d0532a0f011cd5cb17bc85ee82e2 (diff) |
radeonsi: fix GLSL textureGrad(samplerCube*) functions
+4 piglits
Reviewed-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/gallium/drivers/radeon')
-rw-r--r-- | src/gallium/drivers/radeon/radeon_llvm.h | 5 | ||||
-rw-r--r-- | src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c | 84 |
2 files changed, 66 insertions, 23 deletions
diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h index ef09ead9774..950a51beff3 100644 --- a/src/gallium/drivers/radeon/radeon_llvm.h +++ b/src/gallium/drivers/radeon/radeon_llvm.h @@ -173,8 +173,9 @@ static inline LLVMValueRef bitcast( void radeon_llvm_emit_prepare_cube_coords(struct lp_build_tgsi_context * bld_base, - struct lp_build_emit_data * emit_data, - LLVMValueRef *coords_arg); + struct lp_build_emit_data * emit_data, + LLVMValueRef *coords_arg, + LLVMValueRef *derivs_arg); void radeon_llvm_context_init(struct radeon_llvm_context * ctx); diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c index 39bbdb67778..2362979cf87 100644 --- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c +++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c @@ -748,32 +748,24 @@ static void kil_emit( } } -void radeon_llvm_emit_prepare_cube_coords( - struct lp_build_tgsi_context * bld_base, - struct lp_build_emit_data * emit_data, - LLVMValueRef *coords_arg) +static void radeon_llvm_cube_to_2d_coords(struct lp_build_tgsi_context *bld_base, + LLVMValueRef *in, LLVMValueRef *out) { - - unsigned target = emit_data->inst->Texture.Texture; - unsigned opcode = emit_data->inst->Instruction.Opcode; struct gallivm_state * gallivm = bld_base->base.gallivm; LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef type = bld_base->base.elem_type; LLVMValueRef coords[4]; LLVMValueRef mad_args[3]; - LLVMValueRef idx; - struct LLVMOpaqueValue *cube_vec; - LLVMValueRef v; + LLVMValueRef v, cube_vec; unsigned i; - cube_vec = lp_build_gather_values(bld_base->base.gallivm, coords_arg, 4); + cube_vec = lp_build_gather_values(bld_base->base.gallivm, in, 4); v = build_intrinsic(builder, "llvm.AMDGPU.cube", LLVMVectorType(type, 4), &cube_vec, 1, LLVMReadNoneAttribute); - for (i = 0; i < 4; ++i) { - idx = lp_build_const_int32(gallivm, i); - coords[i] = LLVMBuildExtractElement(builder, v, idx, ""); - } + for (i = 0; i < 4; ++i) + coords[i] = LLVMBuildExtractElement(builder, v, + lp_build_const_int32(gallivm, i), ""); coords[2] = build_intrinsic(builder, "fabs", type, &coords[2], 1, LLVMReadNoneAttribute); @@ -791,10 +783,60 @@ void radeon_llvm_emit_prepare_cube_coords( mad_args[0], mad_args[1], mad_args[2]); /* apply xyz = yxw swizzle to cooords */ - coords[2] = coords[3]; - coords[3] = coords[1]; - coords[1] = coords[0]; - coords[0] = coords[3]; + out[0] = coords[1]; + out[1] = coords[0]; + out[2] = coords[3]; +} + +void radeon_llvm_emit_prepare_cube_coords( + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data, + LLVMValueRef *coords_arg, + LLVMValueRef *derivs_arg) +{ + + unsigned target = emit_data->inst->Texture.Texture; + unsigned opcode = emit_data->inst->Instruction.Opcode; + struct gallivm_state * gallivm = bld_base->base.gallivm; + LLVMBuilderRef builder = gallivm->builder; + LLVMValueRef coords[4]; + unsigned i; + + radeon_llvm_cube_to_2d_coords(bld_base, coords_arg, coords); + + if (opcode == TGSI_OPCODE_TXD && derivs_arg) { + LLVMValueRef derivs[4]; + int axis; + + /* Convert cube derivatives to 2D derivatives. */ + for (axis = 0; axis < 2; axis++) { + LLVMValueRef shifted_cube_coords[4], shifted_coords[4]; + + /* Shift the cube coordinates by the derivatives to get + * the cube coordinates of the "neighboring pixel". + */ + for (i = 0; i < 3; i++) + shifted_cube_coords[i] = + LLVMBuildFAdd(builder, coords_arg[i], + derivs_arg[axis*3+i], ""); + shifted_cube_coords[3] = LLVMGetUndef(bld_base->base.elem_type); + + /* Project the shifted cube coordinates onto the face. */ + radeon_llvm_cube_to_2d_coords(bld_base, shifted_cube_coords, + shifted_coords); + + /* Subtract both sets of 2D coordinates to get 2D derivatives. + * This won't work if the shifted coordinates ended up + * in a different face. + */ + for (i = 0; i < 2; i++) + derivs[axis * 2 + i] = + LLVMBuildFSub(builder, shifted_coords[i], + coords[i], ""); + } + + memcpy(derivs_arg, derivs, sizeof(derivs)); + } if (target == TGSI_TEXTURE_CUBE_ARRAY || target == TGSI_TEXTURE_SHADOWCUBE_ARRAY) { @@ -864,7 +906,7 @@ static void txp_fetch_args( inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) && inst->Instruction.Opcode != TGSI_OPCODE_TXQ && inst->Instruction.Opcode != TGSI_OPCODE_TXQ_LZ) { - radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords); + radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords, NULL); } emit_data->args[0] = lp_build_gather_values(bld_base->base.gallivm, @@ -909,7 +951,7 @@ static void tex_fetch_args( inst->Texture.Texture == TGSI_TEXTURE_SHADOWCUBE_ARRAY) && inst->Instruction.Opcode != TGSI_OPCODE_TXQ && inst->Instruction.Opcode != TGSI_OPCODE_TXQ_LZ) { - radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords); + radeon_llvm_emit_prepare_cube_coords(bld_base, emit_data, coords, NULL); } emit_data->arg_count = 1; |