diff options
Diffstat (limited to 'src/gallium/auxiliary')
50 files changed, 1605 insertions, 376 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 896c058fde9..a70ae7384fb 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -18,6 +18,14 @@ endif include ../Makefile.template +default install clean: %: subdirs-% + +subdirs-%: + @for dir in $(SUBDIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) $*) || exit 1; \ + fi \ + done indices/u_indices_gen.c: indices/u_indices_gen.py $(PYTHON2) $< > $@ diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources index 44cf2d326de..277428b38be 100644 --- a/src/gallium/auxiliary/Makefile.sources +++ b/src/gallium/auxiliary/Makefile.sources @@ -1,3 +1,5 @@ +SUBDIRS := pipe-loader + C_SOURCES := \ cso_cache/cso_cache.c \ cso_cache/cso_context.c \ diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c index ea0a4fb3f25..d6b981195b2 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c @@ -237,12 +237,13 @@ aa_transform_inst(struct tgsi_transform_context *ctx, decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; /* XXX this could be linear... */ - decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.Declaration.Interpolate = 1; decl.Declaration.Semantic = 1; decl.Semantic.Name = TGSI_SEMANTIC_GENERIC; decl.Semantic.Index = aactx->maxGeneric + 1; decl.Range.First = decl.Range.Last = aactx->maxInput + 1; + decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; ctx->emit_declaration(ctx, &decl); /* declare new sampler */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c index a900dd3ab54..ec703d0b394 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c +++ b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c @@ -201,12 +201,13 @@ aa_transform_inst(struct tgsi_transform_context *ctx, decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; /* XXX this could be linear... */ - decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; + decl.Declaration.Interpolate = 1; decl.Declaration.Semantic = 1; decl.Semantic.Name = TGSI_SEMANTIC_GENERIC; decl.Semantic.Index = aactx->maxGeneric + 1; decl.Range.First = decl.Range.Last = texInput; + decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE; ctx->emit_declaration(ctx, &decl); /* declare new temp regs */ diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index cfb6ef4453a..842f6eeba22 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -234,12 +234,13 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, /* declare new position input reg */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ + decl.Declaration.Interpolate = 1; decl.Declaration.Semantic = 1; decl.Semantic.Name = TGSI_SEMANTIC_POSITION; decl.Semantic.Index = 0; decl.Range.First = decl.Range.Last = wincoordInput; + decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */ ctx->emit_declaration(ctx, &decl); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_arit.c b/src/gallium/auxiliary/gallivm/lp_bld_arit.c index 4ba4aa54596..3a74790e89f 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_arit.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_arit.c @@ -926,7 +926,7 @@ lp_build_sgn(struct lp_build_context *bld, } else { - LLVMValueRef minus_one = lp_build_const_vec(bld->gallivm, type, -1.0); + LLVMValueRef minus_one = lp_build_const_int_vec(bld->gallivm, type, -1.0); cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero); res = lp_build_select(bld, cond, bld->one, minus_one); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_assert.c b/src/gallium/auxiliary/gallivm/lp_bld_assert.c index 9de5e8e7b51..37c142bd2ae 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_assert.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_assert.c @@ -29,6 +29,7 @@ #include "util/u_memory.h" #include "lp_bld_assert.h" #include "lp_bld_init.h" +#include "lp_bld_const.h" #include "lp_bld_printf.h" @@ -55,48 +56,37 @@ lp_assert(int condition, const char *msg) * \param condition should be an 'i1' or 'i32' value * \param msg a string to print if the assertion fails. */ -LLVMValueRef +void lp_build_assert(struct gallivm_state *gallivm, LLVMValueRef condition, const char *msg) { LLVMBuilderRef builder = gallivm->builder; LLVMContextRef context = gallivm->context; - LLVMModuleRef module = gallivm->module; LLVMTypeRef arg_types[2]; - LLVMValueRef msg_string, assert_func, params[2], r; + LLVMTypeRef ret_type; + LLVMValueRef function; + LLVMValueRef args[2]; + LLVMValueRef msg_string; - msg_string = lp_build_const_string_variable(module, context, - msg, strlen(msg) + 1); + msg_string = lp_build_const_string(gallivm, msg); + ret_type = LLVMVoidTypeInContext(context); arg_types[0] = LLVMInt32TypeInContext(context); arg_types[1] = LLVMPointerType(LLVMInt8TypeInContext(context), 0); - /* lookup the lp_assert function */ - assert_func = LLVMGetNamedFunction(module, "lp_assert"); - - /* Create the assertion function if not found */ - if (!assert_func) { - LLVMTypeRef func_type = - LLVMFunctionType(LLVMVoidTypeInContext(context), arg_types, 2, 0); - - assert_func = LLVMAddFunction(module, "lp_assert", func_type); - LLVMSetFunctionCallConv(assert_func, LLVMCCallConv); - LLVMSetLinkage(assert_func, LLVMExternalLinkage); - LLVMAddGlobalMapping(gallivm->engine, assert_func, - func_to_pointer((func_pointer)lp_assert)); - } - assert(assert_func); + function = lp_build_const_func_pointer(gallivm, + func_to_pointer((func_pointer)lp_assert), + ret_type, arg_types, Elements(arg_types), + "assert"); /* build function call param list */ - params[0] = LLVMBuildZExt(builder, condition, arg_types[0], ""); - params[1] = LLVMBuildBitCast(builder, msg_string, arg_types[1], ""); + args[0] = LLVMBuildZExt(builder, condition, arg_types[0], ""); + args[1] = msg_string; /* check arg types */ - assert(LLVMTypeOf(params[0]) == arg_types[0]); - assert(LLVMTypeOf(params[1]) == arg_types[1]); - - r = LLVMBuildCall(builder, assert_func, params, 2, ""); + assert(LLVMTypeOf(args[0]) == arg_types[0]); + assert(LLVMTypeOf(args[1]) == arg_types[1]); - return r; + LLVMBuildCall(builder, function, args, Elements(args), ""); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_assert.h b/src/gallium/auxiliary/gallivm/lp_bld_assert.h index 1d2baab30a2..e377b59bbed 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_assert.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_assert.h @@ -33,7 +33,7 @@ #include "lp_bld_init.h" -LLVMValueRef +void lp_build_assert(struct gallivm_state *gallivm, LLVMValueRef condition, const char *msg); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.c b/src/gallium/auxiliary/gallivm/lp_bld_const.c index 6d8b7c26fc8..f0611b158d9 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_const.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.c @@ -409,3 +409,69 @@ lp_build_const_mask_aos(struct gallivm_state *gallivm, return LLVMConstVector(masks, type.length); } + + +/** + * Performs lp_build_const_mask_aos, but first swizzles the mask + */ +LLVMValueRef +lp_build_const_mask_aos_swizzled(struct gallivm_state *gallivm, + struct lp_type type, + unsigned mask, + const unsigned char *swizzle) +{ + mask = + ((mask & (1 << swizzle[0])) >> swizzle[0]) + | (((mask & (1 << swizzle[1])) >> swizzle[1]) << 1) + | (((mask & (1 << swizzle[2])) >> swizzle[2]) << 2) + | (((mask & (1 << swizzle[3])) >> swizzle[3]) << 3); + + return lp_build_const_mask_aos(gallivm, type, mask); +} + + +/** + * Build a zero-terminated constant string. + */ +LLVMValueRef +lp_build_const_string(struct gallivm_state *gallivm, + const char *str) +{ + unsigned len = strlen(str) + 1; + LLVMTypeRef i8 = LLVMInt8TypeInContext(gallivm->context); + LLVMValueRef string = LLVMAddGlobal(gallivm->module, LLVMArrayType(i8, len), ""); + LLVMSetGlobalConstant(string, TRUE); + LLVMSetLinkage(string, LLVMInternalLinkage); + LLVMSetInitializer(string, LLVMConstStringInContext(gallivm->context, str, len, TRUE)); + string = LLVMConstBitCast(string, LLVMPointerType(i8, 0)); + return string; +} + + +/** + * Build a callable function pointer. + * + * We this casts instead of LLVMAddGlobalMapping() + * to work around a bug in LLVM 2.6, and for efficiency/simplicity. + */ +LLVMValueRef +lp_build_const_func_pointer(struct gallivm_state *gallivm, + const void *ptr, + LLVMTypeRef ret_type, + LLVMTypeRef *arg_types, + unsigned num_args, + const char *name) +{ + LLVMTypeRef function_type; + LLVMValueRef function; + + function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0); + + function = lp_build_const_int_pointer(gallivm, ptr); + + function = LLVMBuildBitCast(gallivm->builder, function, + LLVMPointerType(function_type, 0), + name); + + return function; +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_const.h b/src/gallium/auxiliary/gallivm/lp_bld_const.h index 69718eb4b3d..2205616274f 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_const.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_const.h @@ -111,6 +111,13 @@ lp_build_const_mask_aos(struct gallivm_state *gallivm, unsigned mask); +LLVMValueRef +lp_build_const_mask_aos_swizzled(struct gallivm_state *gallivm, + struct lp_type type, + unsigned mask, + const unsigned char *swizzle); + + static INLINE LLVMValueRef lp_build_const_int32(struct gallivm_state *gallivm, int i) { @@ -142,5 +149,18 @@ lp_build_const_int_pointer(struct gallivm_state *gallivm, const void *ptr) } +LLVMValueRef +lp_build_const_string(struct gallivm_state *gallivm, + const char *str); + + +LLVMValueRef +lp_build_const_func_pointer(struct gallivm_state *gallivm, + const void *ptr, + LLVMTypeRef ret_type, + LLVMTypeRef *arg_types, + unsigned num_args, + const char *name); + #endif /* !LP_BLD_CONST_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c index a9c9c7af10c..d2b3713ed2d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c @@ -265,6 +265,73 @@ lp_build_loop_end(struct lp_build_loop_state *state, lp_build_loop_end_cond(state, end, step, LLVMIntNE); } +/** + * Creates a c-style for loop, + * contrasts lp_build_loop as this checks condition on entry + * e.g. for(i = start; i cmp_op end; i += step) + * \param state the for loop state, initialized here + * \param gallivm the gallivm state + * \param start starting value of iterator + * \param cmp_op comparison operator used for comparing current value with end value + * \param end value used to compare against iterator + * \param step value added to iterator at end of each loop + */ +void +lp_build_for_loop_begin(struct lp_build_for_loop_state *state, + struct gallivm_state *gallivm, + LLVMValueRef start, + LLVMIntPredicate cmp_op, + LLVMValueRef end, + LLVMValueRef step) +{ + LLVMBuilderRef builder = gallivm->builder; + + assert(LLVMTypeOf(start) == LLVMTypeOf(end)); + assert(LLVMTypeOf(start) == LLVMTypeOf(step)); + + state->begin = lp_build_insert_new_block(gallivm, "loop_begin"); + state->step = step; + state->counter_var = lp_build_alloca(gallivm, LLVMTypeOf(start), "loop_counter"); + state->gallivm = gallivm; + state->cond = cmp_op; + state->end = end; + + LLVMBuildStore(builder, start, state->counter_var); + LLVMBuildBr(builder, state->begin); + + LLVMPositionBuilderAtEnd(builder, state->begin); + state->counter = LLVMBuildLoad(builder, state->counter_var, ""); + + state->body = lp_build_insert_new_block(gallivm, "loop_body"); + LLVMPositionBuilderAtEnd(builder, state->body); +} + +/** + * End the for loop. + */ +void +lp_build_for_loop_end(struct lp_build_for_loop_state *state) +{ + LLVMValueRef next, cond; + LLVMBuilderRef builder = state->gallivm->builder; + + next = LLVMBuildAdd(builder, state->counter, state->step, ""); + LLVMBuildStore(builder, next, state->counter_var); + LLVMBuildBr(builder, state->begin); + + state->exit = lp_build_insert_new_block(state->gallivm, "loop_exit"); + + /* + * We build the comparison for the begin block here, + * if we build it earlier the output llvm ir is not human readable + * as the code produced is not in the standard begin -> body -> end order. + */ + LLVMPositionBuilderAtEnd(builder, state->begin); + cond = LLVMBuildICmp(builder, state->cond, state->counter, state->end, ""); + LLVMBuildCondBr(builder, cond, state->body, state->exit); + + LLVMPositionBuilderAtEnd(builder, state->exit); +} /* diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.h b/src/gallium/auxiliary/gallivm/lp_bld_flow.h index 3cd5a9f42a5..0da849bfe0c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_flow.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.h @@ -131,6 +131,33 @@ lp_build_loop_end_cond(struct lp_build_loop_state *state, LLVMIntPredicate cond); +/** + * Implementation of simple C-style for loops + */ +struct lp_build_for_loop_state +{ + LLVMBasicBlockRef begin; + LLVMBasicBlockRef body; + LLVMBasicBlockRef exit; + LLVMValueRef counter_var; + LLVMValueRef counter; + LLVMValueRef step; + LLVMIntPredicate cond; + LLVMValueRef end; + struct gallivm_state *gallivm; +}; + +void +lp_build_for_loop_begin(struct lp_build_for_loop_state *state, + struct gallivm_state *gallivm, + LLVMValueRef start, + LLVMIntPredicate llvm_cond, + LLVMValueRef end, + LLVMValueRef step); + +void +lp_build_for_loop_end(struct lp_build_for_loop_state *state); + /** * if/else/endif. diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c index 82ab19eda14..e4b8da6bcfd 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_aos.c @@ -643,28 +643,18 @@ lp_build_fetch_rgba_aos(struct gallivm_state *gallivm, */ LLVMTypeRef ret_type; LLVMTypeRef arg_types[4]; - LLVMTypeRef function_type; ret_type = LLVMVoidTypeInContext(gallivm->context); arg_types[0] = pf32t; arg_types[1] = pi8t; arg_types[2] = i32t; arg_types[3] = i32t; - function_type = LLVMFunctionType(ret_type, arg_types, - Elements(arg_types), 0); - /* Note: we're using this casting here instead of LLVMAddGlobalMapping() - * to work around a bug in LLVM 2.6, and for efficiency/simplicity. - */ - - /* make const pointer for the C fetch_rgba_float function */ - function = lp_build_const_int_pointer(gallivm, - func_to_pointer((func_pointer) format_desc->fetch_rgba_float)); - - /* cast the callee pointer to the function's type */ - function = LLVMBuildBitCast(builder, function, - LLVMPointerType(function_type, 0), - "cast callee"); + function = lp_build_const_func_pointer(gallivm, + func_to_pointer((func_pointer) format_desc->fetch_rgba_float), + ret_type, + arg_types, Elements(arg_types), + format_desc->short_name); } tmp_ptr = lp_build_alloca(gallivm, f32x4t, ""); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.h b/src/gallium/auxiliary/gallivm/lp_bld_init.h index f68bf75a851..5fc0f996c64 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.h @@ -81,5 +81,12 @@ extern LLVMValueRef lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal, const char *Name); +void +lp_set_load_alignment(LLVMValueRef Inst, + unsigned Align); + +void +lp_set_store_alignment(LLVMValueRef Inst, + unsigned Align); #endif /* !LP_BLD_INIT_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 68f8808f3ef..6c4586c4212 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -165,3 +165,18 @@ lp_build_load_volatile(LLVMBuilderRef B, LLVMValueRef PointerVal, return llvm::wrap(llvm::unwrap(B)->CreateLoad(llvm::unwrap(PointerVal), true, Name)); } +extern "C" +void +lp_set_load_alignment(LLVMValueRef Inst, + unsigned Align) +{ + llvm::unwrap<llvm::LoadInst>(Inst)->setAlignment(Align); +} + +extern "C" +void +lp_set_store_alignment(LLVMValueRef Inst, + unsigned Align) +{ + llvm::unwrap<llvm::StoreInst>(Inst)->setAlignment(Align); +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.c b/src/gallium/auxiliary/gallivm/lp_bld_printf.c index 56ff4269588..5e359ceaa20 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_printf.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.c @@ -66,19 +66,6 @@ lp_get_printf_arg_count(const char *fmt) return count; } -LLVMValueRef -lp_build_const_string_variable(LLVMModuleRef module, - LLVMContextRef context, - const char *str, int len) -{ - LLVMValueRef string = LLVMAddGlobal(module, LLVMArrayType(LLVMInt8TypeInContext(context), len + 1), ""); - LLVMSetGlobalConstant(string, TRUE); - LLVMSetLinkage(string, LLVMInternalLinkage); - LLVMSetInitializer(string, LLVMConstStringInContext(context, str, len + 1, TRUE)); - return string; -} - - /** * lp_build_printf. * @@ -94,24 +81,22 @@ lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...) int argcount = lp_get_printf_arg_count(fmt); LLVMBuilderRef builder = gallivm->builder; LLVMContextRef context = gallivm->context; - LLVMModuleRef module = gallivm->module; LLVMValueRef params[50]; - LLVMValueRef fmtarg = lp_build_const_string_variable(module, context, - fmt, strlen(fmt) + 1); - LLVMValueRef int0 = lp_build_const_int32(gallivm, 0); - LLVMValueRef index[2]; - LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf"); + LLVMValueRef fmtarg = lp_build_const_string(gallivm, fmt); + LLVMTypeRef printf_type; + LLVMValueRef func_printf; assert(Elements(params) >= argcount + 1); - index[0] = index[1] = int0; + printf_type = LLVMFunctionType(LLVMIntTypeInContext(context, 32), NULL, 0, 1); - if (!func_printf) { - LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntTypeInContext(context, 32), NULL, 0, 1); - func_printf = LLVMAddFunction(module, "printf", printf_type); - } + func_printf = lp_build_const_int_pointer(gallivm, func_to_pointer((func_pointer)debug_printf)); + + func_printf = LLVMBuildBitCast(gallivm->builder, func_printf, + LLVMPointerType(printf_type, 0), + "debug_printf"); - params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, ""); + params[0] = fmtarg; va_start(arglist, fmt); for (i = 1; i <= argcount; i++) { @@ -170,3 +155,30 @@ lp_build_print_ivec4(struct gallivm_state *gallivm, util_snprintf(format, sizeof(format), "%s %%i %%i %%i %%i\n", msg); return lp_build_printf(gallivm, format, x, y, z, w); } + + +/** + * Print a uint8[16] vector. + */ +LLVMValueRef +lp_build_print_uvec16(struct gallivm_state *gallivm, + const char *msg, LLVMValueRef vec) +{ + LLVMBuilderRef builder = gallivm->builder; + char format[1000]; + LLVMValueRef args[16]; + int i; + + for (i = 0; i < 16; ++i) { + args[i] = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, i), ""); + } + + util_snprintf(format, sizeof(format), "%s %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u\n", msg); + + return lp_build_printf( + gallivm, format, + args[ 0], args[ 1], args[ 2], args[ 3], + args[ 4], args[ 5], args[ 6], args[ 7], + args[ 8], args[ 9], args[10], args[11], + args[12], args[13], args[14], args[15]); +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.h b/src/gallium/auxiliary/gallivm/lp_bld_printf.h index 79db74d8886..7a2b26d41f4 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_printf.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.h @@ -34,12 +34,9 @@ #include "lp_bld_init.h" -LLVMValueRef lp_build_const_string_variable(LLVMModuleRef module, - LLVMContextRef context, - const char *str, int len); - -LLVMValueRef lp_build_printf(struct gallivm_state *gallivm, - const char *fmt, ...); +LLVMValueRef +lp_build_printf(struct gallivm_state *gallivm, + const char *fmt, ...); LLVMValueRef lp_build_print_vec4(struct gallivm_state *gallivm, @@ -49,5 +46,9 @@ LLVMValueRef lp_build_print_ivec4(struct gallivm_state *gallivm, const char *msg, LLVMValueRef vec); +LLVMValueRef +lp_build_print_uvec16(struct gallivm_state *gallivm, + const char *msg, LLVMValueRef vec); + #endif diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample.c b/src/gallium/auxiliary/gallivm/lp_bld_sample.c index 07f4f3bf6b8..c6d4f1bcc28 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample.c @@ -349,7 +349,7 @@ lp_build_brilinear_lod(struct lp_build_context *bld, * Combined log2 and brilinear lod computation. * * It's in all identical to calling lp_build_fast_log2() and - * lp_build_brilinear_lod() above, but by combining we can compute the interger + * lp_build_brilinear_lod() above, but by combining we can compute the integer * and fractional part independently. */ static void diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.c b/src/gallium/auxiliary/gallivm/lp_bld_struct.c index 0dc2f24d10a..cc248d15e97 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_struct.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.c @@ -146,6 +146,25 @@ lp_build_pointer_get(LLVMBuilderRef builder, } +LLVMValueRef +lp_build_pointer_get_unaligned(LLVMBuilderRef builder, + LLVMValueRef ptr, + LLVMValueRef index, + unsigned alignment) +{ + LLVMValueRef element_ptr; + LLVMValueRef res; + assert(LLVMGetTypeKind(LLVMTypeOf(ptr)) == LLVMPointerTypeKind); + element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); + res = LLVMBuildLoad(builder, element_ptr, ""); + lp_set_load_alignment(res, alignment); +#ifdef DEBUG + lp_build_name(res, "%s[%s]", LLVMGetValueName(ptr), LLVMGetValueName(index)); +#endif + return res; +} + + void lp_build_pointer_set(LLVMBuilderRef builder, LLVMValueRef ptr, @@ -156,3 +175,18 @@ lp_build_pointer_set(LLVMBuilderRef builder, element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); LLVMBuildStore(builder, value, element_ptr); } + + +void +lp_build_pointer_set_unaligned(LLVMBuilderRef builder, + LLVMValueRef ptr, + LLVMValueRef index, + LLVMValueRef value, + unsigned alignment) +{ + LLVMValueRef element_ptr; + LLVMValueRef instr; + element_ptr = LLVMBuildGEP(builder, ptr, &index, 1, ""); + instr = LLVMBuildStore(builder, value, element_ptr); + lp_set_store_alignment(instr, alignment); +} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_struct.h b/src/gallium/auxiliary/gallivm/lp_bld_struct.h index 11605c685f0..6b7b4f2a6bf 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_struct.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_struct.h @@ -105,6 +105,18 @@ lp_build_pointer_get(LLVMBuilderRef builder, LLVMValueRef index); /** + * Get the value of an array element, with explicit alignment. + * + * If the element size is different from the alignment this will + * cause llvm to emit an unaligned load + */ +LLVMValueRef +lp_build_pointer_get_unaligned(LLVMBuilderRef builder, + LLVMValueRef ptr, + LLVMValueRef index, + unsigned alignment); + +/** * Set the value of an array element. */ void @@ -113,4 +125,17 @@ lp_build_pointer_set(LLVMBuilderRef builder, LLVMValueRef index, LLVMValueRef value); +/** + * Set the value of an array element, with explicit alignment. + * + * If the element size is different from the alignment this will + * cause llvm to emit an unaligned store + */ +void +lp_build_pointer_set_unaligned(LLVMBuilderRef builder, + LLVMValueRef ptr, + LLVMValueRef index, + LLVMValueRef value, + unsigned alignment); + #endif /* !LP_BLD_STRUCT_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c index 45bbf81eb29..680c85f843c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.c @@ -215,8 +215,6 @@ lp_build_tgsi_inst_llvm( case TGSI_OPCODE_PUSHA: case TGSI_OPCODE_POPA: case TGSI_OPCODE_SAD: - case TGSI_OPCODE_TXF: - case TGSI_OPCODE_TXQ: /* deprecated? */ assert(0); return FALSE; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 888221d4d64..773c679a4d8 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -122,6 +122,11 @@ struct lp_tgsi_info unsigned indirect_textures:1; /* + * Whether any immediate values are outside the range of 0 and 1 + */ + unsigned unclamped_immediates:1; + + /* * Texture opcode description. Aimed at detecting and described direct * texture opcodes. */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c index 7f011563264..d278444ce90 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c @@ -1007,6 +1007,17 @@ i2f_emit_cpu( emit_data->args[0]); } +/* TGSI_OPCODE_IABS (CPU Only) */ +static void +iabs_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_abs(&bld_base->int_bld, + emit_data->args[0]); +} + /* TGSI_OPCODE_IDIV (CPU Only) */ static void idiv_emit_cpu( @@ -1101,6 +1112,18 @@ islt_emit_cpu( iset_emit_cpu(action, bld_base, emit_data, PIPE_FUNC_LESS); } + +/* TGSI_OPCODE_ISSG (CPU Only) */ +static void +issg_emit_cpu( + const struct lp_build_tgsi_action * action, + struct lp_build_tgsi_context * bld_base, + struct lp_build_emit_data * emit_data) +{ + emit_data->output[emit_data->chan] = lp_build_sgn(&bld_base->int_bld, + emit_data->args[0]); +} + /* TGSI_OPCODE_LG2 (CPU Only) */ static void lg2_emit_cpu( @@ -1541,6 +1564,7 @@ lp_set_default_actions_cpu( bld_base->op_actions[TGSI_OPCODE_FLR].emit = flr_emit_cpu; bld_base->op_actions[TGSI_OPCODE_I2F].emit = i2f_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_IABS].emit = iabs_emit_cpu; bld_base->op_actions[TGSI_OPCODE_IDIV].emit = idiv_emit_cpu; bld_base->op_actions[TGSI_OPCODE_INEG].emit = ineg_emit_cpu; bld_base->op_actions[TGSI_OPCODE_IMAX].emit = imax_emit_cpu; @@ -1548,6 +1572,7 @@ lp_set_default_actions_cpu( bld_base->op_actions[TGSI_OPCODE_ISGE].emit = isge_emit_cpu; bld_base->op_actions[TGSI_OPCODE_ISHR].emit = ishr_emit_cpu; bld_base->op_actions[TGSI_OPCODE_ISLT].emit = islt_emit_cpu; + bld_base->op_actions[TGSI_OPCODE_ISSG].emit = issg_emit_cpu; bld_base->op_actions[TGSI_OPCODE_LG2].emit = lg2_emit_cpu; bld_base->op_actions[TGSI_OPCODE_LOG].emit = log_emit_cpu; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c index 80c148124ee..24bc13a9be8 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_aos.c @@ -325,8 +325,10 @@ lp_emit_store_aos( if (reg->Register.WriteMask != TGSI_WRITEMASK_XYZW) { LLVMValueRef writemask; - writemask = lp_build_const_mask_aos(bld->bld_base.base.gallivm, bld->bld_base.base.type, - reg->Register.WriteMask); + writemask = lp_build_const_mask_aos_swizzled(bld->bld_base.base.gallivm, + bld->bld_base.base.type, + reg->Register.WriteMask, + bld->swizzles); if (mask) { mask = LLVMBuildAnd(builder, mask, writemask, ""); @@ -1089,6 +1091,7 @@ lp_build_tgsi_aos(struct gallivm_state *gallivm, debug_printf("2222222222222222222222222222 \n"); } tgsi_parse_free(&parse); + FREE(bld.bld_base.instructions); if (0) { LLVMModuleRef module = LLVMGetGlobalParent( diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c index 3373ed4426d..ab393ed942a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_info.c @@ -442,8 +442,12 @@ lp_build_tgsi_info(const struct tgsi_token *tokens, assert(size <= 4); if (ctx.num_imms < Elements(ctx.imm)) { for (chan = 0; chan < size; ++chan) { - ctx.imm[ctx.num_imms][chan] = - parse.FullToken.FullImmediate.u[chan].Float; + float value = parse.FullToken.FullImmediate.u[chan].Float; + ctx.imm[ctx.num_imms][chan] = value; + + if (value < 0.0f || value > 1.0f) { + info->unclamped_immediates = TRUE; + } } ++ctx.num_imms; } diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index 3e1c273027b..3773be945dd 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -44,6 +44,7 @@ #include <pthread.h> /* POSIX threads headers */ #include <stdio.h> /* for perror() */ +#include <signal.h> /* pipe_thread diff --git a/src/gallium/auxiliary/pipe-loader/Makefile.am b/src/gallium/auxiliary/pipe-loader/Makefile.am new file mode 100644 index 00000000000..c63dce3fe4a --- /dev/null +++ b/src/gallium/auxiliary/pipe-loader/Makefile.am @@ -0,0 +1,38 @@ +AUTOMAKE_OPTIONS = subdir-objects + +AM_CPPFLAGS = $(DEFINES) \ + $(GALLIUM_PIPE_LOADER_DEFINES) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + -I$(top_srcdir)/src/gallium/winsys + +AM_CFLAGS = $(PIC_FLAGS) + +noinst_LTLIBRARIES = + +if HAVE_LOADER_GALLIUM +noinst_LTLIBRARIES += libpipe_loader.la + +libpipe_loader_la_SOURCES = \ + pipe_loader.h \ + pipe_loader_priv.h \ + pipe_loader.c \ + pipe_loader_sw.c + +if HAVE_DRM_LOADER_GALLIUM +libpipe_loader_la_SOURCES += pipe_loader_drm.c +AM_CFLAGS += $(LIBDRM_CFLAGS) +endif + +# Provide compatibility with scripts for the old Mesa build system for +# a while by putting a link to the library in the current directory. +all-local: libpipe_loader.la + ln -f .libs/libpipe_loader.a . + +clean-local: + rm -f libpipe_loader.a +endif + +# FIXME: Remove when the rest of Gallium is converted to automake. +default: all diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader.c b/src/gallium/auxiliary/pipe-loader/pipe_loader.c new file mode 100644 index 00000000000..6a10ac3998d --- /dev/null +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader.c @@ -0,0 +1,102 @@ +/************************************************************************** + * + * Copyright 2012 Francisco Jerez + * 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. + * + **************************************************************************/ + +#include "pipe_loader_priv.h" + +#include "util/u_inlines.h" +#include "util/u_memory.h" +#include "util/u_string.h" +#include "util/u_dl.h" + +#define MODULE_PREFIX "pipe_" + +static int (*backends[])(struct pipe_loader_device **, int) = { +#ifdef HAVE_PIPE_LOADER_DRM + &pipe_loader_drm_probe, +#endif + &pipe_loader_sw_probe +}; + +int +pipe_loader_probe(struct pipe_loader_device **devs, int ndev) +{ + int i, n = 0; + + for (i = 0; i < Elements(backends); i++) + n += backends[i](&devs[n], MAX2(0, ndev - n)); + + return n; +} + +void +pipe_loader_release(struct pipe_loader_device **devs, int ndev) +{ + int i; + + for (i = 0; i < ndev; i++) + devs[i]->ops->release(&devs[i]); +} + +struct pipe_screen * +pipe_loader_create_screen(struct pipe_loader_device *dev, + const char *library_paths) +{ + return dev->ops->create_screen(dev, library_paths); +} + +struct util_dl_library * +pipe_loader_find_module(struct pipe_loader_device *dev, + const char *library_paths) +{ + struct util_dl_library *lib; + const char *next; + char path[PATH_MAX]; + int len, ret; + + for (next = library_paths; *next; library_paths = next + 1) { + next = util_strchrnul(library_paths, ':'); + len = next - library_paths; + + if (len) + ret = util_snprintf(path, sizeof(path), "%.*s/%s%s%s", + len, library_paths, + MODULE_PREFIX, dev->driver_name, UTIL_DL_EXT); + else + ret = util_snprintf(path, sizeof(path), "%s%s%s", + MODULE_PREFIX, dev->driver_name, UTIL_DL_EXT); + + if (ret > 0 && ret < sizeof(path)) { + lib = util_dl_open(path); + if (lib) { + debug_printf("loaded %s\n", path); + return lib; + } + } + } + + return NULL; +} diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader.h b/src/gallium/auxiliary/pipe-loader/pipe_loader.h new file mode 100644 index 00000000000..e41969458dd --- /dev/null +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader.h @@ -0,0 +1,144 @@ +/************************************************************************** + * + * Copyright 2012 Francisco Jerez + * 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. + * + **************************************************************************/ + +/** + * \file Library that provides device enumeration and creation of + * winsys/pipe_screen instances. + */ + +#ifndef PIPE_LOADER_H +#define PIPE_LOADER_H + +#include "pipe/p_compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct pipe_screen; + +enum pipe_loader_device_type { + PIPE_LOADER_DEVICE_SOFTWARE, + PIPE_LOADER_DEVICE_PCI, + NUM_PIPE_LOADER_DEVICE_TYPES +}; + +/** + * A device known to the pipe loader. + */ +struct pipe_loader_device { + enum pipe_loader_device_type type; + + union { + struct { + int vendor_id; + int chip_id; + } pci; + }; /**< Discriminated by \a type */ + + const char *driver_name; + const struct pipe_loader_ops *ops; +}; + +/** + * Get a list of known devices. + * + * \param devs Array that will be filled with pointers to the devices + * available in the system. + * \param ndev Maximum number of devices to return. + * \return Number of devices available in the system. + */ +int +pipe_loader_probe(struct pipe_loader_device **devs, int ndev); + +/** + * Create a pipe_screen for the specified device. + * + * \param dev Device the screen will be created for. + * \param library_paths Colon-separated list of filesystem paths that + * will be used to look for the pipe driver + * module that handles this device. + */ +struct pipe_screen * +pipe_loader_create_screen(struct pipe_loader_device *dev, + const char *library_paths); + +/** + * Release resources allocated for a list of devices. + * + * Should be called when the specified devices are no longer in use to + * release any resources allocated by pipe_loader_probe. + * + * \param devs Devices to release. + * \param ndev Number of devices to release. + */ +void +pipe_loader_release(struct pipe_loader_device **devs, int ndev); + +#ifdef HAVE_PIPE_LOADER_SW + +/** + * Get a list of known software devices. + * + * This function is platform-specific. + * + * \sa pipe_loader_probe + */ +int +pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev); + +#endif + +#ifdef HAVE_PIPE_LOADER_DRM + +/** + * Get a list of known DRM devices. + * + * This function is platform-specific. + * + * \sa pipe_loader_probe + */ +int +pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev); + +/** + * Initialize a DRM device in an already opened fd. + * + * This function is platform-specific. + * + * \sa pipe_loader_probe + */ +boolean +pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PIPE_LOADER_H */ diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c new file mode 100644 index 00000000000..7a7e9942f3b --- /dev/null +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_drm.c @@ -0,0 +1,218 @@ +/************************************************************************** + * + * Copyright 2011 Intel Corporation + * Copyright 2012 Francisco Jerez + * 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. + * + * Authors: + * Kristian Høgsberg <[email protected]> + * Benjamin Franzke <[email protected]> + * + **************************************************************************/ + +#include <fcntl.h> +#include <stdio.h> +#include <libudev.h> +#include <xf86drm.h> + +#include "state_tracker/drm_driver.h" +#include "pipe_loader_priv.h" + +#include "util/u_memory.h" +#include "util/u_dl.h" +#include "util/u_debug.h" + +#define DRIVER_MAP_GALLIUM_ONLY +#include "pci_ids/pci_id_driver_map.h" + +struct pipe_loader_drm_device { + struct pipe_loader_device base; + struct util_dl_library *lib; + int fd; +}; + +#define pipe_loader_drm_device(dev) ((struct pipe_loader_drm_device *)dev) + +static boolean +find_drm_pci_id(struct pipe_loader_drm_device *ddev) +{ + struct udev *udev = NULL; + struct udev_device *parent, *device = NULL; + struct stat stat; + const char *pci_id; + + if (fstat(ddev->fd, &stat) < 0) + goto fail; + + udev = udev_new(); + if (!udev) + goto fail; + + device = udev_device_new_from_devnum(udev, 'c', stat.st_rdev); + if (!device) + goto fail; + + parent = udev_device_get_parent(device); + if (!parent) + goto fail; + + pci_id = udev_device_get_property_value(parent, "PCI_ID"); + if (!pci_id || + sscanf(pci_id, "%x:%x", &ddev->base.pci.vendor_id, + &ddev->base.pci.chip_id) != 2) + goto fail; + + return TRUE; + + fail: + if (device) + udev_device_unref(device); + if (udev) + udev_unref(udev); + + debug_printf("pci id for fd %d not found\n", ddev->fd); + return FALSE; +} + +static boolean +find_drm_driver_name(struct pipe_loader_drm_device *ddev) +{ + struct pipe_loader_device *dev = &ddev->base; + int i, j; + + for (i = 0; driver_map[i].driver; i++) { + if (dev->pci.vendor_id != driver_map[i].vendor_id) + continue; + + if (driver_map[i].num_chips_ids == -1) { + dev->driver_name = driver_map[i].driver; + goto found; + } + + for (j = 0; j < driver_map[i].num_chips_ids; j++) { + if (dev->pci.chip_id == driver_map[i].chip_ids[j]) { + dev->driver_name = driver_map[i].driver; + goto found; + } + } + } + + return FALSE; + + found: + debug_printf("driver for %04x:%04x: %s\n", dev->pci.vendor_id, + dev->pci.chip_id, dev->driver_name); + return TRUE; +} + +static struct pipe_loader_ops pipe_loader_drm_ops; + +boolean +pipe_loader_drm_probe_fd(struct pipe_loader_device **dev, int fd) +{ + struct pipe_loader_drm_device *ddev = CALLOC_STRUCT(pipe_loader_drm_device); + + ddev->base.type = PIPE_LOADER_DEVICE_PCI; + ddev->base.ops = &pipe_loader_drm_ops; + ddev->fd = fd; + + if (!find_drm_pci_id(ddev)) + goto fail; + + if (!find_drm_driver_name(ddev)) + goto fail; + + *dev = &ddev->base; + return TRUE; + + fail: + FREE(ddev); + return FALSE; +} + +static int +open_drm_minor(int minor) +{ + char path[PATH_MAX]; + snprintf(path, sizeof(path), DRM_DEV_NAME, DRM_DIR_NAME, minor); + return open(path, O_RDWR, 0); +} + +int +pipe_loader_drm_probe(struct pipe_loader_device **devs, int ndev) +{ + int i, j, fd; + + for (i = 0, j = 0; i < DRM_MAX_MINOR; i++) { + fd = open_drm_minor(i); + if (fd < 0) + continue; + + if (j >= ndev || !pipe_loader_drm_probe_fd(&devs[j], fd)) + close(fd); + + j++; + } + + return j; +} + +static void +pipe_loader_drm_release(struct pipe_loader_device **dev) +{ + struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(*dev); + + if (ddev->lib) + util_dl_close(ddev->lib); + + close(ddev->fd); + FREE(ddev); + *dev = NULL; +} + +static struct pipe_screen * +pipe_loader_drm_create_screen(struct pipe_loader_device *dev, + const char *library_paths) +{ + struct pipe_loader_drm_device *ddev = pipe_loader_drm_device(dev); + const struct drm_driver_descriptor *dd; + + if (!ddev->lib) + ddev->lib = pipe_loader_find_module(dev, library_paths); + if (!ddev->lib) + return NULL; + + dd = (const struct drm_driver_descriptor *) + util_dl_get_proc_address(ddev->lib, "driver_descriptor"); + + /* sanity check on the name */ + if (!dd || strcmp(dd->name, ddev->base.driver_name) != 0) + return NULL; + + return dd->create_screen(ddev->fd); +} + +static struct pipe_loader_ops pipe_loader_drm_ops = { + .create_screen = pipe_loader_drm_create_screen, + .release = pipe_loader_drm_release +}; diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_priv.h b/src/gallium/auxiliary/pipe-loader/pipe_loader_priv.h new file mode 100644 index 00000000000..0be833a0f3f --- /dev/null +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_priv.h @@ -0,0 +1,47 @@ +/************************************************************************** + * + * Copyright 2012 Francisco Jerez + * 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 PIPE_LOADER_PRIV_H +#define PIPE_LOADER_PRIV_H + +#include "pipe_loader.h" + +struct pipe_loader_ops { + struct pipe_screen *(*create_screen)(struct pipe_loader_device *dev, + const char *library_paths); + + void (*release)(struct pipe_loader_device **dev); +}; + +/** + * Open the pipe driver module that handles a specified device. + */ +struct util_dl_library * +pipe_loader_find_module(struct pipe_loader_device *dev, + const char *library_paths); + +#endif /* PIPE_LOADER_PRIV_H */ diff --git a/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c b/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c new file mode 100644 index 00000000000..c2b78c636a7 --- /dev/null +++ b/src/gallium/auxiliary/pipe-loader/pipe_loader_sw.c @@ -0,0 +1,107 @@ +/************************************************************************** + * + * Copyright 2012 Francisco Jerez + * 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. + * + **************************************************************************/ + +#include "pipe_loader_priv.h" + +#include "util/u_memory.h" +#include "util/u_dl.h" +#include "sw/null/null_sw_winsys.h" +#include "target-helpers/inline_sw_helper.h" +#include "state_tracker/xlib_sw_winsys.h" + +struct pipe_loader_sw_device { + struct pipe_loader_device base; + struct util_dl_library *lib; + struct sw_winsys *ws; +}; + +#define pipe_loader_sw_device(dev) ((struct pipe_loader_sw_device *)dev) + +static struct pipe_loader_ops pipe_loader_sw_ops; + +static struct sw_winsys *(*backends[])() = { +#ifdef HAVE_WINSYS_XLIB + x11_sw_create, +#endif + null_sw_create +}; + +int +pipe_loader_sw_probe(struct pipe_loader_device **devs, int ndev) +{ + int i; + + for (i = 0; i < Elements(backends); i++) { + if (i < ndev) { + struct pipe_loader_sw_device *sdev = CALLOC_STRUCT(pipe_loader_sw_device); + + sdev->base.type = PIPE_LOADER_DEVICE_SOFTWARE; + sdev->base.driver_name = "swrast"; + sdev->base.ops = &pipe_loader_sw_ops; + sdev->ws = backends[i](); + devs[i] = &sdev->base; + } + } + + return i; +} + +static void +pipe_loader_sw_release(struct pipe_loader_device **dev) +{ + struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(*dev); + + if (sdev->lib) + util_dl_close(sdev->lib); + + FREE(sdev); + *dev = NULL; +} + +static struct pipe_screen * +pipe_loader_sw_create_screen(struct pipe_loader_device *dev, + const char *library_paths) +{ + struct pipe_loader_sw_device *sdev = pipe_loader_sw_device(dev); + struct pipe_screen *(*init)(struct sw_winsys *); + + if (!sdev->lib) + sdev->lib = pipe_loader_find_module(dev, library_paths); + if (!sdev->lib) + return NULL; + + init = (void *)util_dl_get_proc_address(sdev->lib, "swrast_create_screen"); + if (!init) + return NULL; + + return init(sdev->ws); +} + +static struct pipe_loader_ops pipe_loader_sw_ops = { + .create_screen = pipe_loader_sw_create_screen, + .release = pipe_loader_sw_release +}; diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 6ec2b0d8f21..1c24b9bdbed 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -104,12 +104,11 @@ tgsi_default_declaration( void ) declaration.NrTokens = 1; declaration.File = TGSI_FILE_NULL; declaration.UsageMask = TGSI_WRITEMASK_XYZW; - declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT; + declaration.Interpolate = 0; declaration.Dimension = 0; declaration.Semantic = 0; - declaration.Centroid = 0; declaration.Invariant = 0; - declaration.CylindricalWrap = 0; + declaration.Local = 0; return declaration; } @@ -121,9 +120,8 @@ tgsi_build_declaration( unsigned interpolate, unsigned dimension, unsigned semantic, - unsigned centroid, unsigned invariant, - unsigned cylindrical_wrap, + unsigned local, struct tgsi_header *header ) { struct tgsi_declaration declaration; @@ -137,9 +135,8 @@ tgsi_build_declaration( declaration.Interpolate = interpolate; declaration.Dimension = dimension; declaration.Semantic = semantic; - declaration.Centroid = centroid; declaration.Invariant = invariant; - declaration.CylindricalWrap = cylindrical_wrap; + declaration.Local = local; header_bodysize_grow( header ); @@ -194,6 +191,36 @@ tgsi_build_declaration_dimension(unsigned index_2d, return dd; } +static struct tgsi_declaration_interp +tgsi_default_declaration_interp( void ) +{ + struct tgsi_declaration_interp di; + + di.Interpolate = TGSI_INTERPOLATE_CONSTANT; + di.Centroid = 0; + di.CylindricalWrap = 0; + + return di; +} + +static struct tgsi_declaration_interp +tgsi_build_declaration_interp(unsigned interpolate, + unsigned centroid, + unsigned cylindrical_wrap, + struct tgsi_declaration *declaration, + struct tgsi_header *header) +{ + struct tgsi_declaration_interp di; + + di.Interpolate = interpolate; + di.Centroid = centroid; + di.CylindricalWrap = cylindrical_wrap; + + declaration_grow(declaration, header); + + return di; +} + static struct tgsi_declaration_semantic tgsi_default_declaration_semantic( void ) { @@ -227,42 +254,72 @@ tgsi_build_declaration_semantic( return ds; } - static struct tgsi_declaration_resource tgsi_default_declaration_resource(void) { - struct tgsi_declaration_resource declaration_resource; + struct tgsi_declaration_resource dr; - declaration_resource.Resource = TGSI_TEXTURE_UNKNOWN; - declaration_resource.ReturnTypeX = PIPE_TYPE_UNORM; - declaration_resource.ReturnTypeY = PIPE_TYPE_UNORM; - declaration_resource.ReturnTypeZ = PIPE_TYPE_UNORM; - declaration_resource.ReturnTypeW = PIPE_TYPE_UNORM; + dr.Resource = TGSI_TEXTURE_BUFFER; + dr.Raw = 0; + dr.Writable = 0; - return declaration_resource; + return dr; } static struct tgsi_declaration_resource tgsi_build_declaration_resource(unsigned texture, - unsigned return_type_x, - unsigned return_type_y, - unsigned return_type_z, - unsigned return_type_w, + unsigned raw, + unsigned writable, struct tgsi_declaration *declaration, struct tgsi_header *header) { - struct tgsi_declaration_resource declaration_resource; + struct tgsi_declaration_resource dr; + + dr = tgsi_default_declaration_resource(); + dr.Resource = texture; + dr.Raw = raw; + dr.Writable = writable; + + declaration_grow(declaration, header); + + return dr; +} + +static struct tgsi_declaration_sampler_view +tgsi_default_declaration_sampler_view(void) +{ + struct tgsi_declaration_sampler_view dsv; - declaration_resource = tgsi_default_declaration_resource(); - declaration_resource.Resource = texture; - declaration_resource.ReturnTypeX = return_type_x; - declaration_resource.ReturnTypeY = return_type_y; - declaration_resource.ReturnTypeZ = return_type_z; - declaration_resource.ReturnTypeW = return_type_w; + dsv.Resource = TGSI_TEXTURE_BUFFER; + dsv.ReturnTypeX = PIPE_TYPE_UNORM; + dsv.ReturnTypeY = PIPE_TYPE_UNORM; + dsv.ReturnTypeZ = PIPE_TYPE_UNORM; + dsv.ReturnTypeW = PIPE_TYPE_UNORM; + + return dsv; +} + +static struct tgsi_declaration_sampler_view +tgsi_build_declaration_sampler_view(unsigned texture, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w, + struct tgsi_declaration *declaration, + struct tgsi_header *header) +{ + struct tgsi_declaration_sampler_view dsv; + + dsv = tgsi_default_declaration_sampler_view(); + dsv.Resource = texture; + dsv.ReturnTypeX = return_type_x; + dsv.ReturnTypeY = return_type_y; + dsv.ReturnTypeZ = return_type_z; + dsv.ReturnTypeW = return_type_w; declaration_grow(declaration, header); - return declaration_resource; + return dsv; } @@ -274,8 +331,10 @@ tgsi_default_full_declaration( void ) full_declaration.Declaration = tgsi_default_declaration(); full_declaration.Range = tgsi_default_declaration_range(); full_declaration.Semantic = tgsi_default_declaration_semantic(); + full_declaration.Interp = tgsi_default_declaration_interp(); full_declaration.ImmediateData.u = NULL; full_declaration.Resource = tgsi_default_declaration_resource(); + full_declaration.SamplerView = tgsi_default_declaration_sampler_view(); return full_declaration; } @@ -302,9 +361,8 @@ tgsi_build_full_declaration( full_decl->Declaration.Interpolate, full_decl->Declaration.Dimension, full_decl->Declaration.Semantic, - full_decl->Declaration.Centroid, full_decl->Declaration.Invariant, - full_decl->Declaration.CylindricalWrap, + full_decl->Declaration.Local, header ); if (maxsize <= size) @@ -332,6 +390,22 @@ tgsi_build_full_declaration( header); } + if (full_decl->Declaration.Interpolate) { + struct tgsi_declaration_interp *di; + + if (maxsize <= size) { + return 0; + } + di = (struct tgsi_declaration_interp *)&tokens[size]; + size++; + + *di = tgsi_build_declaration_interp(full_decl->Interp.Interpolate, + full_decl->Interp.Centroid, + full_decl->Interp.CylindricalWrap, + declaration, + header); + } + if( full_decl->Declaration.Semantic ) { struct tgsi_declaration_semantic *ds; @@ -375,14 +449,31 @@ tgsi_build_full_declaration( size++; *dr = tgsi_build_declaration_resource(full_decl->Resource.Resource, - full_decl->Resource.ReturnTypeX, - full_decl->Resource.ReturnTypeY, - full_decl->Resource.ReturnTypeZ, - full_decl->Resource.ReturnTypeW, + full_decl->Resource.Raw, + full_decl->Resource.Writable, declaration, header); } + if (full_decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { + struct tgsi_declaration_sampler_view *dsv; + + if (maxsize <= size) { + return 0; + } + dsv = (struct tgsi_declaration_sampler_view *)&tokens[size]; + size++; + + *dsv = tgsi_build_declaration_sampler_view( + full_decl->SamplerView.Resource, + full_decl->SamplerView.ReturnTypeX, + full_decl->SamplerView.ReturnTypeY, + full_decl->SamplerView.ReturnTypeZ, + full_decl->SamplerView.ReturnTypeW, + declaration, + header); + } + return size; } @@ -405,11 +496,13 @@ tgsi_default_immediate( void ) static struct tgsi_immediate tgsi_build_immediate( - struct tgsi_header *header ) + struct tgsi_header *header, + unsigned type ) { struct tgsi_immediate immediate; immediate = tgsi_default_immediate(); + immediate.DataType = type; header_bodysize_grow( header ); @@ -442,21 +535,6 @@ immediate_grow( header_bodysize_grow( header ); } -static union tgsi_immediate_data -tgsi_build_immediate_float32( - float value, - struct tgsi_immediate *immediate, - struct tgsi_header *header ) -{ - union tgsi_immediate_data immediate_data; - - immediate_data.Float = value; - - immediate_grow( immediate, header ); - - return immediate_data; -} - unsigned tgsi_build_full_immediate( const struct tgsi_full_immediate *full_imm, @@ -472,7 +550,7 @@ tgsi_build_full_immediate( immediate = (struct tgsi_immediate *) &tokens[size]; size++; - *immediate = tgsi_build_immediate( header ); + *immediate = tgsi_build_immediate( header, full_imm->Immediate.DataType ); assert( full_imm->Immediate.NrTokens <= 4 + 1 ); @@ -481,13 +559,12 @@ tgsi_build_full_immediate( if( maxsize <= size ) return 0; + data = (union tgsi_immediate_data *) &tokens[size]; - size++; + *data = full_imm->u[i]; - *data = tgsi_build_immediate_float32( - full_imm->u[i].Float, - immediate, - header ); + immediate_grow( immediate, header ); + size++; } return size; diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c index 635212b7e86..383c54590af 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_dump.c +++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c @@ -271,6 +271,9 @@ iter_declaration( ctx, decl->Declaration.UsageMask ); + if (decl->Declaration.Local) + TXT( ", LOCAL" ); + if (decl->Declaration.Semantic) { TXT( ", " ); ENM( decl->Semantic.Name, tgsi_semantic_names ); @@ -285,53 +288,64 @@ iter_declaration( if (decl->Declaration.File == TGSI_FILE_RESOURCE) { TXT(", "); ENM(decl->Resource.Resource, tgsi_texture_names); + if (decl->Resource.Writable) + TXT(", WR"); + if (decl->Resource.Raw) + TXT(", RAW"); + } + + if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { TXT(", "); - if ((decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeY) && - (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeZ) && - (decl->Resource.ReturnTypeX == decl->Resource.ReturnTypeW)) { - ENM(decl->Resource.ReturnTypeX, tgsi_type_names); + ENM(decl->SamplerView.Resource, tgsi_texture_names); + TXT(", "); + if ((decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeY) && + (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeZ) && + (decl->SamplerView.ReturnTypeX == decl->SamplerView.ReturnTypeW)) { + ENM(decl->SamplerView.ReturnTypeX, tgsi_type_names); } else { - ENM(decl->Resource.ReturnTypeX, tgsi_type_names); + ENM(decl->SamplerView.ReturnTypeX, tgsi_type_names); TXT(", "); - ENM(decl->Resource.ReturnTypeY, tgsi_type_names); + ENM(decl->SamplerView.ReturnTypeY, tgsi_type_names); TXT(", "); - ENM(decl->Resource.ReturnTypeZ, tgsi_type_names); + ENM(decl->SamplerView.ReturnTypeZ, tgsi_type_names); TXT(", "); - ENM(decl->Resource.ReturnTypeW, tgsi_type_names); + ENM(decl->SamplerView.ReturnTypeW, tgsi_type_names); } - } - if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT && - decl->Declaration.File == TGSI_FILE_INPUT) - { - TXT( ", " ); - ENM( decl->Declaration.Interpolate, tgsi_interpolate_names ); - } + if (decl->Declaration.Interpolate) { + if (iter->processor.Processor == TGSI_PROCESSOR_FRAGMENT && + decl->Declaration.File == TGSI_FILE_INPUT) + { + TXT( ", " ); + ENM( decl->Interp.Interpolate, tgsi_interpolate_names ); + } + + if (decl->Interp.Centroid) { + TXT( ", CENTROID" ); + } - if (decl->Declaration.Centroid) { - TXT( ", CENTROID" ); + if (decl->Interp.CylindricalWrap) { + TXT(", CYLWRAP_"); + if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_X) { + CHR('X'); + } + if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Y) { + CHR('Y'); + } + if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Z) { + CHR('Z'); + } + if (decl->Interp.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_W) { + CHR('W'); + } + } } if (decl->Declaration.Invariant) { TXT( ", INVARIANT" ); } - if (decl->Declaration.CylindricalWrap) { - TXT(", CYLWRAP_"); - if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_X) { - CHR('X'); - } - if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Y) { - CHR('Y'); - } - if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_Z) { - CHR('Z'); - } - if (decl->Declaration.CylindricalWrap & TGSI_CYLINDRICAL_WRAP_W) { - CHR('W'); - } - } if (decl->Declaration.File == TGSI_FILE_IMMEDIATE_ARRAY) { unsigned i; diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index c4ad34b1e61..5e23f5da65b 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -2121,7 +2121,7 @@ exec_sample(struct tgsi_exec_machine *mach, control = tgsi_sampler_lod_bias; } - switch (mach->Resources[resource_unit].Resource) { + switch (mach->SamplerViews[resource_unit].Resource) { case TGSI_TEXTURE_1D: case TGSI_TEXTURE_SHADOW1D: FETCH(&r[0], 0, TGSI_CHAN_X); @@ -2215,7 +2215,7 @@ exec_sample_d(struct tgsi_exec_machine *mach, * XXX: This is fake SAMPLE_D -- the derivatives are not taken into account, yet. */ - switch (mach->Resources[resource_unit].Resource) { + switch (mach->SamplerViews[resource_unit].Resource) { case TGSI_TEXTURE_1D: case TGSI_TEXTURE_SHADOW1D: @@ -2338,8 +2338,8 @@ static void exec_declaration(struct tgsi_exec_machine *mach, const struct tgsi_full_declaration *decl) { - if (decl->Declaration.File == TGSI_FILE_RESOURCE) { - mach->Resources[decl->Range.First] = decl->Resource; + if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { + mach->SamplerViews[decl->Range.First] = decl->SamplerView; return; } @@ -2371,7 +2371,7 @@ exec_declaration(struct tgsi_exec_machine *mach, eval_coef_func eval; uint i, j; - switch (decl->Declaration.Interpolate) { + switch (decl->Interp.Interpolate) { case TGSI_INTERPOLATE_CONSTANT: eval = eval_constant_coef; break; @@ -4154,11 +4154,11 @@ exec_instruction( exec_endswitch(mach); break; - case TGSI_OPCODE_LOAD: + case TGSI_OPCODE_SAMPLE_I: assert(0); break; - case TGSI_OPCODE_LOAD_MS: + case TGSI_OPCODE_SAMPLE_I_MS: assert(0); break; @@ -4190,7 +4190,7 @@ exec_instruction( assert(0); break; - case TGSI_OPCODE_RESINFO: + case TGSI_OPCODE_SVIEWINFO: assert(0); break; diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index d9e93ce138d..0ecb4e952bb 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -331,7 +331,8 @@ struct tgsi_exec_machine struct tgsi_full_declaration *Declarations; uint NumDeclarations; - struct tgsi_declaration_resource Resources[PIPE_MAX_SHADER_RESOURCES]; + struct tgsi_declaration_sampler_view + SamplerViews[PIPE_MAX_SHADER_SAMPLER_VIEWS]; boolean UsedGeometryShader; }; diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c index 81df96b3c7a..8bf9aeb4284 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_info.c +++ b/src/gallium/auxiliary/tgsi/tgsi_info.c @@ -183,22 +183,39 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] = { 0, 0, 0, 0, 0, 0, NONE, "DEFAULT", TGSI_OPCODE_DEFAULT }, { 0, 0, 0, 0, 0, 0, NONE, "ENDSWITCH", TGSI_OPCODE_ENDSWITCH }, - { 1, 2, 0, 0, 0, 0, OTHR, "LOAD", TGSI_OPCODE_LOAD }, - { 1, 2, 0, 0, 0, 0, OTHR, "LOAD_MS", TGSI_OPCODE_LOAD_MS }, { 1, 3, 0, 0, 0, 0, OTHR, "SAMPLE", TGSI_OPCODE_SAMPLE }, + { 1, 2, 0, 0, 0, 0, OTHR, "SAMPLE_I", TGSI_OPCODE_SAMPLE_I }, + { 1, 2, 0, 0, 0, 0, OTHR, "SAMPLE_I_MS", TGSI_OPCODE_SAMPLE_I_MS }, { 1, 4, 0, 0, 0, 0, OTHR, "SAMPLE_B", TGSI_OPCODE_SAMPLE_B }, { 1, 4, 0, 0, 0, 0, OTHR, "SAMPLE_C", TGSI_OPCODE_SAMPLE_C }, { 1, 4, 0, 0, 0, 0, OTHR, "SAMPLE_C_LZ", TGSI_OPCODE_SAMPLE_C_LZ }, { 1, 5, 0, 0, 0, 0, OTHR, "SAMPLE_D", TGSI_OPCODE_SAMPLE_D }, { 1, 3, 0, 0, 0, 0, OTHR, "SAMPLE_L", TGSI_OPCODE_SAMPLE_L }, { 1, 3, 0, 0, 0, 0, OTHR, "GATHER4", TGSI_OPCODE_GATHER4 }, - { 1, 2, 0, 0, 0, 0, OTHR, "RESINFO", TGSI_OPCODE_RESINFO }, + { 1, 2, 0, 0, 0, 0, OTHR, "SVIEWINFO", TGSI_OPCODE_SVIEWINFO }, { 1, 2, 0, 0, 0, 0, OTHR, "SAMPLE_POS", TGSI_OPCODE_SAMPLE_POS }, { 1, 2, 0, 0, 0, 0, OTHR, "SAMPLE_INFO", TGSI_OPCODE_SAMPLE_INFO }, { 1, 1, 0, 0, 0, 0, COMP, "UARL", TGSI_OPCODE_UARL }, { 1, 3, 0, 0, 0, 0, COMP, "UCMP", TGSI_OPCODE_UCMP }, { 1, 1, 0, 0, 0, 0, COMP, "IABS", TGSI_OPCODE_IABS }, { 1, 1, 0, 0, 0, 0, COMP, "ISSG", TGSI_OPCODE_ISSG }, + { 1, 2, 0, 0, 0, 0, OTHR, "LOAD", TGSI_OPCODE_LOAD }, + { 1, 2, 0, 0, 0, 0, OTHR, "STORE", TGSI_OPCODE_STORE }, + { 1, 0, 0, 0, 0, 0, OTHR, "MFENCE", TGSI_OPCODE_MFENCE }, + { 1, 0, 0, 0, 0, 0, OTHR, "LFENCE", TGSI_OPCODE_LFENCE }, + { 1, 0, 0, 0, 0, 0, OTHR, "SFENCE", TGSI_OPCODE_SFENCE }, + { 0, 0, 0, 0, 0, 0, OTHR, "BARRIER", TGSI_OPCODE_BARRIER }, + + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMUADD", TGSI_OPCODE_ATOMUADD }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMXCHG", TGSI_OPCODE_ATOMXCHG }, + { 1, 4, 0, 0, 0, 0, OTHR, "ATOMCAS", TGSI_OPCODE_ATOMCAS }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMAND", TGSI_OPCODE_ATOMAND }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMOR", TGSI_OPCODE_ATOMOR }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMXOR", TGSI_OPCODE_ATOMXOR }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMUMIN", TGSI_OPCODE_ATOMUMIN }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMUMAX", TGSI_OPCODE_ATOMUMAX }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMIMIN", TGSI_OPCODE_ATOMIMIN }, + { 1, 3, 0, 0, 0, 0, OTHR, "ATOMIMAX", TGSI_OPCODE_ATOMIMAX } }; const struct tgsi_opcode_info * diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h index b5d4504425b..96b864f50d0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h +++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h @@ -168,16 +168,16 @@ OP01(CASE) OP00(DEFAULT) OP00(ENDSWITCH) -OP12(LOAD) -OP12(LOAD_MS) OP13(SAMPLE) +OP12(SAMPLE_I) +OP12(SAMPLE_I_MS) OP14(SAMPLE_B) OP14(SAMPLE_C) OP14(SAMPLE_C_LZ) OP15(SAMPLE_D) OP13(SAMPLE_L) OP13(GATHER4) -OP12(RESINFO) +OP12(SVIEWINFO) OP13(SAMPLE_POS) OP12(SAMPLE_INFO) diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c index e1902eb1862..45c5c41ec82 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.c +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c @@ -113,6 +113,10 @@ tgsi_parse_token( next_token(ctx, &decl->Dim); } + if( decl->Declaration.Interpolate ) { + next_token( ctx, &decl->Interp ); + } + if( decl->Declaration.Semantic ) { next_token( ctx, &decl->Semantic ); } @@ -132,6 +136,10 @@ tgsi_parse_token( next_token(ctx, &decl->Resource); } + if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) { + next_token(ctx, &decl->SamplerView); + } + break; } diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h index f7b7e6edc98..3f8bf99e3c1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_parse.h +++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h @@ -67,9 +67,11 @@ struct tgsi_full_declaration struct tgsi_declaration Declaration; struct tgsi_declaration_range Range; struct tgsi_declaration_dimension Dim; + struct tgsi_declaration_interp Interp; struct tgsi_declaration_semantic Semantic; struct tgsi_immediate_array_data ImmediateData; struct tgsi_declaration_resource Resource; + struct tgsi_declaration_sampler_view SamplerView; }; struct tgsi_full_immediate diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index 1e00e2e54ed..ce728ecee06 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -1170,7 +1170,7 @@ emit_declaration( for( i = first; i <= last; i++ ) { for( j = 0; j < NUM_CHANNELS; j++ ) { if( mask & (1 << j) ) { - switch( decl->Declaration.Interpolate ) { + switch( decl->Interp.Interpolate ) { case TGSI_INTERPOLATE_CONSTANT: emit_coef_a0( func, 0, i, j ); emit_inputs( func, 0, i, j ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index e4e9c032e02..df299baa9c1 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -68,7 +68,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens, procType = parse.FullHeader.Processor.Processor; assert(procType == TGSI_PROCESSOR_FRAGMENT || procType == TGSI_PROCESSOR_VERTEX || - procType == TGSI_PROCESSOR_GEOMETRY); + procType == TGSI_PROCESSOR_GEOMETRY || + procType == TGSI_PROCESSOR_COMPUTE); /** @@ -157,9 +158,9 @@ tgsi_scan_shader(const struct tgsi_token *tokens, if (file == TGSI_FILE_INPUT) { info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; - info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate; - info->input_centroid[reg] = (ubyte)fulldecl->Declaration.Centroid; - info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Declaration.CylindricalWrap; + info->input_interpolate[reg] = (ubyte)fulldecl->Interp.Interpolate; + info->input_centroid[reg] = (ubyte)fulldecl->Interp.Centroid; + info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Interp.CylindricalWrap; info->num_inputs++; if (procType == TGSI_PROCESSOR_FRAGMENT && diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.c b/src/gallium/auxiliary/tgsi/tgsi_strings.c index 520452ce1b8..b5fd1fc0a65 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.c +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.c @@ -32,11 +32,12 @@ #include "tgsi_strings.h" -const char *tgsi_processor_type_names[3] = +const char *tgsi_processor_type_names[4] = { "FRAG", "VERT", - "GEOM" + "GEOM", + "COMP" }; const char *tgsi_file_names[TGSI_FILE_COUNT] = @@ -53,7 +54,8 @@ const char *tgsi_file_names[TGSI_FILE_COUNT] = "SV", "IMMX", "TEMPX", - "RES" + "RES", + "SVIEW" }; const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] = @@ -72,12 +74,16 @@ const char *tgsi_semantic_names[TGSI_SEMANTIC_COUNT] = "VERTEXID", "STENCIL", "CLIPDIST", - "CLIPVERTEX" + "CLIPVERTEX", + "GRID_SIZE", + "BLOCK_ID", + "BLOCK_SIZE", + "THREAD_ID" }; const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] = { - "UNKNOWN", + "BUFFER", "1D", "2D", "3D", @@ -90,7 +96,8 @@ const char *tgsi_texture_names[TGSI_TEXTURE_COUNT] = "2DARRAY", "SHADOW1DARRAY", "SHADOW2DARRAY", - "SHADOWCUBE" + "SHADOWCUBE", + "UNKNOWN" }; const char *tgsi_property_names[TGSI_PROPERTY_COUNT] = diff --git a/src/gallium/auxiliary/tgsi/tgsi_strings.h b/src/gallium/auxiliary/tgsi/tgsi_strings.h index 0946a58f135..5c57e229c28 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_strings.h +++ b/src/gallium/auxiliary/tgsi/tgsi_strings.h @@ -38,7 +38,7 @@ extern "C" { #endif -extern const char *tgsi_processor_type_names[3]; +extern const char *tgsi_processor_type_names[4]; extern const char *tgsi_file_names[TGSI_FILE_COUNT]; diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 4b3d22c3072..279a046e202 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -132,6 +132,23 @@ static boolean parse_uint( const char **pcur, uint *val ) return FALSE; } +static boolean parse_int( const char **pcur, int *val ) +{ + const char *cur = *pcur; + int sign = (*cur == '-' ? -1 : 1); + + if (*cur == '+' || *cur == '-') + cur++; + + if (parse_uint(&cur, (uint *)val)) { + *val *= sign; + *pcur = cur; + return TRUE; + } + + return FALSE; +} + static boolean parse_identifier( const char **pcur, char *ret ) { const char *cur = *pcur; @@ -238,6 +255,8 @@ static boolean parse_header( struct translate_ctx *ctx ) processor = TGSI_PROCESSOR_VERTEX; else if (str_match_no_case( &ctx->cur, "GEOM" )) processor = TGSI_PROCESSOR_GEOMETRY; + else if (str_match_no_case( &ctx->cur, "COMP" )) + processor = TGSI_PROCESSOR_COMPUTE; else { report_error( ctx, "Unknown header" ); return FALSE; @@ -447,24 +466,10 @@ parse_register_bracket( eat_opt_white(&ctx->cur); } - if (*ctx->cur == '+' || *ctx->cur == '-') { - boolean negate; - - negate = *ctx->cur == '-'; - ctx->cur++; - eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, &uindex )) { - report_error( ctx, "Expected literal unsigned integer" ); - return FALSE; - } - if (negate) - brackets->index = -(int) uindex; - else - brackets->index = (int) uindex; - } - else { + if (*ctx->cur == '+' || *ctx->cur == '-') + parse_int( &ctx->cur, &brackets->index ); + else brackets->index = 0; - } } else { if (!parse_uint( &ctx->cur, &uindex )) { @@ -819,6 +824,7 @@ parse_instruction( uint saturate = TGSI_SAT_NONE; const struct tgsi_opcode_info *info; struct tgsi_full_instruction inst; + const char *cur; uint advance; inst = tgsi_default_full_instruction(); @@ -864,7 +870,7 @@ parse_instruction( */ eat_opt_white( &ctx->cur ); for (i = 0; i < TGSI_OPCODE_LAST; i++) { - const char *cur = ctx->cur; + cur = ctx->cur; info = tgsi_get_opcode_info( i ); if (match_inst_mnemonic(&cur, info)) { @@ -938,22 +944,20 @@ parse_instruction( } } - if (info->is_branch) { + cur = ctx->cur; + eat_opt_white( &cur ); + if (info->is_branch && *cur == ':') { uint target; - eat_opt_white( &ctx->cur ); - if (*ctx->cur != ':') { - report_error( ctx, "Expected `:'" ); - return FALSE; - } - ctx->cur++; - eat_opt_white( &ctx->cur ); - if (!parse_uint( &ctx->cur, &target )) { + cur++; + eat_opt_white( &cur ); + if (!parse_uint( &cur, &target )) { report_error( ctx, "Expected a label" ); return FALSE; } inst.Instruction.Label = 1; inst.Label.Label = target; + ctx->cur = cur; } advance = tgsi_build_full_instruction( @@ -970,10 +974,11 @@ parse_instruction( /* parses a 4-touple of the form {x, y, z, w} * where x, y, z, w are numbers */ -static boolean parse_immediate_data(struct translate_ctx *ctx, - float *values) +static boolean parse_immediate_data(struct translate_ctx *ctx, unsigned type, + union tgsi_immediate_data *values) { unsigned i; + int ret; eat_opt_white( &ctx->cur ); if (*ctx->cur != '{') { @@ -991,8 +996,21 @@ static boolean parse_immediate_data(struct translate_ctx *ctx, ctx->cur++; eat_opt_white( &ctx->cur ); } - if (!parse_float( &ctx->cur, &values[i] )) { - report_error( ctx, "Expected literal floating point" ); + + switch (type) { + case TGSI_IMM_FLOAT32: + ret = parse_float(&ctx->cur, &values[i].Float); + break; + case TGSI_IMM_UINT32: + ret = parse_uint(&ctx->cur, &values[i].Uint); + break; + case TGSI_IMM_INT32: + ret = parse_int(&ctx->cur, &values[i].Int); + break; + } + + if (!ret) { + report_error( ctx, "Expected immediate constant" ); return FALSE; } } @@ -1013,7 +1031,7 @@ static boolean parse_declaration( struct translate_ctx *ctx ) struct parsed_dcl_bracket brackets[2]; int num_brackets; uint writemask; - const char *cur; + const char *cur, *cur2; uint advance; boolean is_vs_input; boolean is_imm_array; @@ -1066,6 +1084,42 @@ static boolean parse_declaration( struct translate_ctx *ctx ) report_error(ctx, "Expected texture target"); return FALSE; } + + cur2 = cur; + eat_opt_white(&cur2); + while (*cur2 == ',') { + cur2++; + eat_opt_white(&cur2); + if (str_match_no_case(&cur2, "RAW") && + !is_digit_alpha_underscore(cur2)) { + decl.Resource.Raw = 1; + + } else if (str_match_no_case(&cur2, "WR") && + !is_digit_alpha_underscore(cur2)) { + decl.Resource.Writable = 1; + + } else { + break; + } + cur = cur2; + eat_opt_white(&cur2); + } + + ctx->cur = cur; + + } else if (file == TGSI_FILE_SAMPLER_VIEW) { + for (i = 0; i < TGSI_TEXTURE_COUNT; i++) { + if (str_match_no_case(&cur, tgsi_texture_names[i])) { + if (!is_digit_alpha_underscore(cur)) { + decl.SamplerView.Resource = i; + break; + } + } + } + if (i == TGSI_TEXTURE_COUNT) { + report_error(ctx, "Expected texture target"); + return FALSE; + } eat_opt_white( &cur ); if (*cur != ',') { report_error( ctx, "Expected `,'" ); @@ -1079,16 +1133,16 @@ static boolean parse_declaration( struct translate_ctx *ctx ) if (!is_digit_alpha_underscore(cur)) { switch (j) { case 0: - decl.Resource.ReturnTypeX = i; + decl.SamplerView.ReturnTypeX = i; break; case 1: - decl.Resource.ReturnTypeY = i; + decl.SamplerView.ReturnTypeY = i; break; case 2: - decl.Resource.ReturnTypeZ = i; + decl.SamplerView.ReturnTypeZ = i; break; case 3: - decl.Resource.ReturnTypeW = i; + decl.SamplerView.ReturnTypeW = i; break; default: assert(0); @@ -1104,7 +1158,7 @@ static boolean parse_declaration( struct translate_ctx *ctx ) } break; } else { - const char *cur2 = cur; + cur2 = cur; eat_opt_white( &cur2 ); if (*cur2 == ',') { cur2++; @@ -1116,51 +1170,64 @@ static boolean parse_declaration( struct translate_ctx *ctx ) } } if (j < 4) { - decl.Resource.ReturnTypeY = - decl.Resource.ReturnTypeZ = - decl.Resource.ReturnTypeW = - decl.Resource.ReturnTypeX; + decl.SamplerView.ReturnTypeY = + decl.SamplerView.ReturnTypeZ = + decl.SamplerView.ReturnTypeW = + decl.SamplerView.ReturnTypeX; } ctx->cur = cur; } else { - for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { - if (str_match_no_case( &cur, tgsi_semantic_names[i] )) { - const char *cur2 = cur; - uint index; + if (str_match_no_case(&cur, "LOCAL") && + !is_digit_alpha_underscore(cur)) { + decl.Declaration.Local = 1; + ctx->cur = cur; + } - if (is_digit_alpha_underscore( cur )) - continue; - eat_opt_white( &cur2 ); - if (*cur2 == '[') { - cur2++; - eat_opt_white( &cur2 ); - if (!parse_uint( &cur2, &index )) { - report_error( ctx, "Expected literal integer" ); - return FALSE; - } + cur = ctx->cur; + eat_opt_white( &cur ); + if (*cur == ',') { + cur++; + eat_opt_white( &cur ); + + for (i = 0; i < TGSI_SEMANTIC_COUNT; i++) { + if (str_match_no_case( &cur, tgsi_semantic_names[i] )) { + uint index; + + if (is_digit_alpha_underscore( cur )) + continue; + cur2 = cur; eat_opt_white( &cur2 ); - if (*cur2 != ']') { - report_error( ctx, "Expected `]'" ); - return FALSE; - } - cur2++; + if (*cur2 == '[') { + cur2++; + eat_opt_white( &cur2 ); + if (!parse_uint( &cur2, &index )) { + report_error( ctx, "Expected literal integer" ); + return FALSE; + } + eat_opt_white( &cur2 ); + if (*cur2 != ']') { + report_error( ctx, "Expected `]'" ); + return FALSE; + } + cur2++; - decl.Semantic.Index = index; + decl.Semantic.Index = index; - cur = cur2; - } + cur = cur2; + } - decl.Declaration.Semantic = 1; - decl.Semantic.Name = i; + decl.Declaration.Semantic = 1; + decl.Semantic.Name = i; - ctx->cur = cur; - break; + ctx->cur = cur; + break; + } } } } } else if (is_imm_array) { unsigned i; - float *vals_itr; + union tgsi_immediate_data *vals_itr; /* we have our immediate data */ if (*cur != '{') { report_error( ctx, "Immediate array without data" ); @@ -1172,9 +1239,9 @@ static boolean parse_declaration( struct translate_ctx *ctx ) decl.ImmediateData.u = MALLOC(sizeof(union tgsi_immediate_data) * 4 * (decl.Range.Last + 1)); - vals_itr = (float*)decl.ImmediateData.u; + vals_itr = decl.ImmediateData.u; for (i = 0; i <= decl.Range.Last; ++i) { - if (!parse_immediate_data(ctx, vals_itr)) { + if (!parse_immediate_data(ctx, TGSI_IMM_FLOAT32, vals_itr)) { FREE(decl.ImmediateData.u); return FALSE; } @@ -1209,7 +1276,8 @@ static boolean parse_declaration( struct translate_ctx *ctx ) if (str_match_no_case( &cur, tgsi_interpolate_names[i] )) { if (is_digit_alpha_underscore( cur )) continue; - decl.Declaration.Interpolate = i; + decl.Declaration.Interpolate = 1; + decl.Interp.Interpolate = i; ctx->cur = cur; break; @@ -1240,28 +1308,27 @@ static boolean parse_declaration( struct translate_ctx *ctx ) static boolean parse_immediate( struct translate_ctx *ctx ) { struct tgsi_full_immediate imm; - float values[4]; uint advance; + int type; if (!eat_white( &ctx->cur )) { report_error( ctx, "Syntax error" ); return FALSE; } - if (!str_match_no_case( &ctx->cur, "FLT32" ) || - is_digit_alpha_underscore( ctx->cur )) { - report_error( ctx, "Expected `FLT32'" ); + for (type = 0; type < Elements(tgsi_immediate_type_names); ++type) { + if (str_match_no_case(&ctx->cur, tgsi_immediate_type_names[type]) && + !is_digit_alpha_underscore(ctx->cur)) + break; + } + if (type == Elements(tgsi_immediate_type_names)) { + report_error( ctx, "Expected immediate type" ); return FALSE; } - parse_immediate_data(ctx, values); - imm = tgsi_default_full_immediate(); imm.Immediate.NrTokens += 4; - imm.Immediate.DataType = TGSI_IMM_FLOAT32; - imm.u[0].Float = values[0]; - imm.u[1].Float = values[1]; - imm.u[2].Float = values[2]; - imm.u[3].Float = values[3]; + imm.Immediate.DataType = type; + parse_immediate_data(ctx, type, imm.u); advance = tgsi_build_full_immediate( &imm, diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c index 0f9aa3ab43a..e427585db19 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c @@ -36,6 +36,7 @@ #include "util/u_debug.h" #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_bitmask.h" union tgsi_any_token { struct tgsi_header header; @@ -46,8 +47,9 @@ union tgsi_any_token { struct tgsi_declaration decl; struct tgsi_declaration_range decl_range; struct tgsi_declaration_dimension decl_dim; + struct tgsi_declaration_interp decl_interp; struct tgsi_declaration_semantic decl_semantic; - struct tgsi_declaration_resource decl_resource; + struct tgsi_declaration_sampler_view decl_sampler_view; struct tgsi_immediate imm; union tgsi_immediate_data imm_data; struct tgsi_instruction insn; @@ -74,7 +76,6 @@ struct ureg_tokens { #define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS #define UREG_MAX_CONSTANT_RANGE 32 #define UREG_MAX_IMMEDIATE 256 -#define UREG_MAX_TEMP 256 #define UREG_MAX_ADDR 2 #define UREG_MAX_PRED 1 @@ -147,10 +148,11 @@ struct ureg_program unsigned return_type_y; unsigned return_type_z; unsigned return_type_w; - } resource[PIPE_MAX_SHADER_RESOURCES]; - unsigned nr_resources; + } sampler_view[PIPE_MAX_SHADER_SAMPLER_VIEWS]; + unsigned nr_sampler_views; - unsigned temps_active[UREG_MAX_TEMP / 32]; + struct util_bitmask *free_temps; + struct util_bitmask *local_temps; unsigned nr_temps; struct const_decl const_decls; @@ -529,43 +531,48 @@ out: return ureg_src_register(TGSI_FILE_CONSTANT, index); } - -/* Allocate a new temporary. Temporaries greater than UREG_MAX_TEMP - * are legal, but will not be released. - */ -struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) +static struct ureg_dst alloc_temporary( struct ureg_program *ureg, + boolean local ) { unsigned i; - for (i = 0; i < UREG_MAX_TEMP; i += 32) { - int bit = ffs(~ureg->temps_active[i/32]); - if (bit != 0) { - i += bit - 1; - goto out; - } + /* Look for a released temporary. + */ + for (i = util_bitmask_get_first_index(ureg->free_temps); + i != UTIL_BITMASK_INVALID_INDEX; + i = util_bitmask_get_next_index(ureg->free_temps, i + 1)) { + if (util_bitmask_get(ureg->local_temps, i) == local) + break; } - /* No reusable temps, so allocate a new one: + /* Or allocate a new one. */ - i = ureg->nr_temps++; + if (i == UTIL_BITMASK_INVALID_INDEX) + i = ureg->nr_temps++; -out: - if (i < UREG_MAX_TEMP) - ureg->temps_active[i/32] |= 1 << (i % 32); + util_bitmask_clear(ureg->free_temps, i); - if (i >= ureg->nr_temps) - ureg->nr_temps = i + 1; + if (local) + util_bitmask_set(ureg->local_temps, i); return ureg_dst_register( TGSI_FILE_TEMPORARY, i ); } +struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg ) +{ + return alloc_temporary(ureg, FALSE); +} + +struct ureg_dst ureg_DECL_local_temporary( struct ureg_program *ureg ) +{ + return alloc_temporary(ureg, TRUE); +} void ureg_release_temporary( struct ureg_program *ureg, struct ureg_dst tmp ) { if(tmp.File == TGSI_FILE_TEMPORARY) - if (tmp.Index < UREG_MAX_TEMP) - ureg->temps_active[tmp.Index/32] &= ~(1 << (tmp.Index % 32)); + util_bitmask_set(ureg->free_temps, tmp.Index); } @@ -615,34 +622,34 @@ struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg, } /* - * Allocate a new shader resource. + * Allocate a new shader sampler view. */ struct ureg_src -ureg_DECL_resource(struct ureg_program *ureg, - unsigned index, - unsigned target, - unsigned return_type_x, - unsigned return_type_y, - unsigned return_type_z, - unsigned return_type_w) +ureg_DECL_sampler_view(struct ureg_program *ureg, + unsigned index, + unsigned target, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w) { - struct ureg_src reg = ureg_src_register(TGSI_FILE_RESOURCE, index); + struct ureg_src reg = ureg_src_register(TGSI_FILE_SAMPLER_VIEW, index); uint i; - for (i = 0; i < ureg->nr_resources; i++) { - if (ureg->resource[i].index == index) { + for (i = 0; i < ureg->nr_sampler_views; i++) { + if (ureg->sampler_view[i].index == index) { return reg; } } - if (i < PIPE_MAX_SHADER_RESOURCES) { - ureg->resource[i].index = index; - ureg->resource[i].target = target; - ureg->resource[i].return_type_x = return_type_x; - ureg->resource[i].return_type_y = return_type_y; - ureg->resource[i].return_type_z = return_type_z; - ureg->resource[i].return_type_w = return_type_w; - ureg->nr_resources++; + if (i < PIPE_MAX_SHADER_SAMPLER_VIEWS) { + ureg->sampler_view[i].index = index; + ureg->sampler_view[i].target = target; + ureg->sampler_view[i].return_type_x = return_type_x; + ureg->sampler_view[i].return_type_y = return_type_y; + ureg->sampler_view[i].return_type_z = return_type_z; + ureg->sampler_view[i].return_type_w = return_type_w; + ureg->nr_sampler_views++; return reg; } @@ -891,7 +898,7 @@ ureg_emit_dst( struct ureg_program *ureg, assert(dst.File != TGSI_FILE_CONSTANT); assert(dst.File != TGSI_FILE_INPUT); assert(dst.File != TGSI_FILE_SAMPLER); - assert(dst.File != TGSI_FILE_RESOURCE); + assert(dst.File != TGSI_FILE_SAMPLER_VIEW); assert(dst.File != TGSI_FILE_IMMEDIATE); assert(dst.File < TGSI_FILE_COUNT); @@ -1229,28 +1236,50 @@ emit_decl_fs(struct ureg_program *ureg, unsigned cylindrical_wrap, unsigned centroid) { - union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); + union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 4); out[0].value = 0; out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; - out[0].decl.NrTokens = 3; + out[0].decl.NrTokens = 4; out[0].decl.File = file; out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */ - out[0].decl.Interpolate = interpolate; + out[0].decl.Interpolate = 1; out[0].decl.Semantic = 1; - out[0].decl.CylindricalWrap = cylindrical_wrap; - out[0].decl.Centroid = centroid; out[1].value = 0; out[1].decl_range.First = index; out[1].decl_range.Last = index; out[2].value = 0; - out[2].decl_semantic.Name = semantic_name; - out[2].decl_semantic.Index = semantic_index; + out[2].decl_interp.Interpolate = interpolate; + out[2].decl_interp.CylindricalWrap = cylindrical_wrap; + out[2].decl_interp.Centroid = centroid; + + out[3].value = 0; + out[3].decl_semantic.Name = semantic_name; + out[3].decl_semantic.Index = semantic_index; } +static void emit_decl( struct ureg_program *ureg, + unsigned file, + unsigned index, + boolean local ) +{ + union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 ); + + out[0].value = 0; + out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; + out[0].decl.NrTokens = 2; + out[0].decl.File = file; + out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; + out[0].decl.Local = local; + + out[1].value = 0; + out[1].decl_range.First = index; + out[1].decl_range.Last = index; +} + static void emit_decl_range( struct ureg_program *ureg, unsigned file, unsigned first, @@ -1263,7 +1292,6 @@ static void emit_decl_range( struct ureg_program *ureg, out[0].decl.NrTokens = 2; out[0].decl.File = file; out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; - out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT; out[0].decl.Semantic = 0; out[1].value = 0; @@ -1285,7 +1313,6 @@ emit_decl_range2D(struct ureg_program *ureg, out[0].decl.NrTokens = 3; out[0].decl.File = file; out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; - out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT; out[0].decl.Dimension = 1; out[1].value = 0; @@ -1297,33 +1324,32 @@ emit_decl_range2D(struct ureg_program *ureg, } static void -emit_decl_resource(struct ureg_program *ureg, - unsigned index, - unsigned target, - unsigned return_type_x, - unsigned return_type_y, - unsigned return_type_z, - unsigned return_type_w ) +emit_decl_sampler_view(struct ureg_program *ureg, + unsigned index, + unsigned target, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w ) { union tgsi_any_token *out = get_tokens(ureg, DOMAIN_DECL, 3); out[0].value = 0; out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION; out[0].decl.NrTokens = 3; - out[0].decl.File = TGSI_FILE_RESOURCE; + out[0].decl.File = TGSI_FILE_SAMPLER_VIEW; out[0].decl.UsageMask = 0xf; - out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT; out[1].value = 0; out[1].decl_range.First = index; out[1].decl_range.Last = index; out[2].value = 0; - out[2].decl_resource.Resource = target; - out[2].decl_resource.ReturnTypeX = return_type_x; - out[2].decl_resource.ReturnTypeY = return_type_y; - out[2].decl_resource.ReturnTypeZ = return_type_z; - out[2].decl_resource.ReturnTypeW = return_type_w; + out[2].decl_sampler_view.Resource = target; + out[2].decl_sampler_view.ReturnTypeX = return_type_x; + out[2].decl_sampler_view.ReturnTypeY = return_type_y; + out[2].decl_sampler_view.ReturnTypeZ = return_type_z; + out[2].decl_sampler_view.ReturnTypeW = return_type_w; } static void @@ -1473,14 +1499,14 @@ static void emit_decls( struct ureg_program *ureg ) ureg->sampler[i].Index, 1 ); } - for (i = 0; i < ureg->nr_resources; i++) { - emit_decl_resource(ureg, - ureg->resource[i].index, - ureg->resource[i].target, - ureg->resource[i].return_type_x, - ureg->resource[i].return_type_y, - ureg->resource[i].return_type_z, - ureg->resource[i].return_type_w); + for (i = 0; i < ureg->nr_sampler_views; i++) { + emit_decl_sampler_view(ureg, + ureg->sampler_view[i].index, + ureg->sampler_view[i].target, + ureg->sampler_view[i].return_type_x, + ureg->sampler_view[i].return_type_y, + ureg->sampler_view[i].return_type_z, + ureg->sampler_view[i].return_type_w); } if (ureg->const_decls.nr_constant_ranges) { @@ -1508,10 +1534,9 @@ static void emit_decls( struct ureg_program *ureg ) } } - if (ureg->nr_temps) { - emit_decl_range( ureg, - TGSI_FILE_TEMPORARY, - 0, ureg->nr_temps ); + for (i = 0; i < ureg->nr_temps; i++) { + emit_decl( ureg, TGSI_FILE_TEMPORARY, i, + util_bitmask_get(ureg->local_temps, i) ); } if (ureg->nr_addrs) { @@ -1668,7 +1693,21 @@ struct ureg_program *ureg_create( unsigned processor ) ureg->property_gs_input_prim = ~0; ureg->property_gs_output_prim = ~0; ureg->property_gs_max_vertices = ~0; + + ureg->free_temps = util_bitmask_create(); + if (ureg->free_temps == NULL) + goto fail; + + ureg->local_temps = util_bitmask_create(); + if (ureg->local_temps == NULL) + goto fail; + return ureg; + +fail: + FREE(ureg->free_temps); + FREE(ureg); + return NULL; } @@ -1681,6 +1720,9 @@ void ureg_destroy( struct ureg_program *ureg ) ureg->domain[i].tokens != error_tokens) FREE(ureg->domain[i].tokens); } - + + util_bitmask_destroy(ureg->free_temps); + util_bitmask_destroy(ureg->local_temps); + FREE(ureg); } diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h index 07ab8cba0ba..e6131f25aae 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h +++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h @@ -272,6 +272,14 @@ ureg_DECL_constant( struct ureg_program *, struct ureg_dst ureg_DECL_temporary( struct ureg_program * ); +/** + * Emit a temporary with the LOCAL declaration flag set. For use when + * the register value is not required to be preserved across + * subroutine boundaries. + */ +struct ureg_dst +ureg_DECL_local_temporary( struct ureg_program * ); + void ureg_release_temporary( struct ureg_program *ureg, struct ureg_dst tmp ); @@ -292,13 +300,13 @@ ureg_DECL_sampler( struct ureg_program *, unsigned index ); struct ureg_src -ureg_DECL_resource(struct ureg_program *, - unsigned index, - unsigned target, - unsigned return_type_x, - unsigned return_type_y, - unsigned return_type_z, - unsigned return_type_w ); +ureg_DECL_sampler_view(struct ureg_program *, + unsigned index, + unsigned target, + unsigned return_type_x, + unsigned return_type_y, + unsigned return_type_z, + unsigned return_type_w ); static INLINE struct ureg_src diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index bd4e51d279f..1718fb5e240 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -549,6 +549,19 @@ util_format_colormask(const struct util_format_description *desc) } +/** + * Checks if color mask covers every channel for the specified format + * + * @param desc a format description to check colormask with + * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA + */ +static INLINE boolean +util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) +{ + return (~colormask & util_format_colormask(desc)) == 0; +} + + boolean util_format_is_float(enum pipe_format format); diff --git a/src/gallium/auxiliary/util/u_pstipple.c b/src/gallium/auxiliary/util/u_pstipple.c index ac0df8c1a9c..3a91b1da138 100644 --- a/src/gallium/auxiliary/util/u_pstipple.c +++ b/src/gallium/auxiliary/util/u_pstipple.c @@ -298,12 +298,13 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, /* declare new position input reg */ decl = tgsi_default_full_declaration(); decl.Declaration.File = TGSI_FILE_INPUT; - decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.Declaration.Interpolate = 1; decl.Declaration.Semantic = 1; decl.Semantic.Name = TGSI_SEMANTIC_POSITION; decl.Semantic.Index = 0; decl.Range.First = decl.Range.Last = wincoordInput; + decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; ctx->emit_declaration(ctx, &decl); } diff --git a/src/gallium/auxiliary/util/u_string.h b/src/gallium/auxiliary/util/u_string.h index cc7992d7391..ed15981f1a5 100644 --- a/src/gallium/auxiliary/util/u_string.h +++ b/src/gallium/auxiliary/util/u_string.h @@ -48,6 +48,21 @@ extern "C" { #endif +#ifdef _GNU_SOURCE + +#define util_strchrnul strchrnul + +#else + +static INLINE char * +util_strchrnul(const char *s, char c) +{ + for (; *s && *s != c; ++s); + + return (char *)s; +} + +#endif #ifdef WIN32 @@ -72,12 +87,9 @@ util_sprintf(char *str, const char *format, ...) static INLINE char * util_strchr(const char *s, char c) { - while(*s) { - if(*s == c) - return (char *)s; - ++s; - } - return NULL; + char *p = util_strchrnul(s, c); + + return *p ? p : NULL; } static INLINE char* |