diff options
Diffstat (limited to 'src/gallium')
140 files changed, 3144 insertions, 2454 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 3c171552bed..0efab834f66 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -1,30 +1,135 @@ -import os +Import('env') -Import('*') +# +# Auxiliary modules +# SConscript('auxiliary/SConscript') -for driver in env['drivers']: - SConscript(os.path.join('drivers', driver, 'SConscript')) +# +# Drivers +# + +SConscript([ + 'drivers/failover/SConscript', + 'drivers/galahad/SConscript', + 'drivers/identity/SConscript', + 'drivers/llvmpipe/SConscript', + 'drivers/rbug/SConscript', + 'drivers/softpipe/SConscript', + 'drivers/svga/SConscript', + 'drivers/trace/SConscript', +]) + +if not env['msvc']: + # These drivers do not build on MSVC compilers + SConscript([ + 'drivers/i915/SConscript', + 'drivers/i965/SConscript', + 'drivers/r300/SConscript', + ]) + +if env['drm']: + # These drivers depend on drm headers + if env['drm_radeon']: + SConscript([ + 'drivers/r600/SConscript', + ]) + # XXX: nouveau drivers have a tight dependency on libdrm, so to enable + # we need some version logic before we enable them. Also, ATM there is + # no nouveau target in scons + # if env['drm_nouveau']: + # SConscript([ + # 'drivers/nouveau/SConscript', + # 'drivers/nv50/SConscript', + # 'drivers/nvfx/SConscript', + # ]) + +# +# State trackers +# # Needed by some state trackers SConscript('winsys/sw/null/SConscript') SConscript('state_trackers/python/SConscript') -if platform != 'embedded': - SConscript('state_trackers/glx/xlib/SConscript') - SConscript('state_trackers/dri/SConscript') - SConscript('state_trackers/xorg/SConscript') - SConscript('state_trackers/egl/SConscript') - SConscript('state_trackers/vega/SConscript') +if env['platform'] != 'embedded': + SConscript('state_trackers/vega/SConscript') + + if env['x11']: + SConscript('state_trackers/glx/xlib/SConscript') + + if env['dri']: + SConscript('state_trackers/dri/SConscript') + + if env['dri'] and env['xorg']: + SConscript('state_trackers/xorg/SConscript') + +if env['platform'] == 'windows': + SConscript([ + 'state_trackers/egl/SConscript', + 'state_trackers/wgl/SConscript', + ]) -if platform == 'windows': - SConscript('state_trackers/wgl/SConscript') +# +# Winsys +# SConscript('winsys/SConscript') -SConscript('targets/SConscript') +# +# Targets +# + +SConscript([ + 'targets/graw-null/SConscript', +]) + +if env['x11']: + SConscript([ + 'targets/graw-xlib/SConscript', + 'targets/libgl-xlib/SConscript', + ]) + +if env['platform'] == 'windows': + SConscript([ + 'targets/graw-gdi/SConscript', + 'targets/libgl-gdi/SConscript', + #'egl-gdi/SConscript', + ]) + +if env['dri']: + SConscript([ + 'targets/SConscript.dri', + 'targets/dri-swrast/SConscript', + 'targets/dri-vmwgfx/SConscript', + #'targets/dri-nouveau/SConscript', + ]) + if env['drm_intel']: + SConscript([ + 'targets/dri-i915/SConscript', + 'targets/dri-i965/SConscript', + ]) + if env['drm_radeon']: + SConscript([ + 'targets/dri-r300/SConscript', + 'targets/dri-r600/SConscript', + ]) + +if env['xorg'] and env['drm']: + SConscript([ + #'targets/xorg-i915/SConscript', + #'targets/xorg-i965/SConscript', + #'targets/xorg-nouveau/SConscript', + #'targets/xorg-radeon/SConscript', + 'targets/xorg-vmwgfx/SConscript', + ]) + + +# +# Unit tests & tools +# -if platform != 'embedded': - SConscript('tests/unit/SConscript') - SConscript('tests/graw/SConscript') +if env['platform'] != 'embedded': + SConscript('tests/unit/SConscript') + SConscript('tests/graw/SConscript') diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index f22c8b96123..4b9059d9aa3 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -7,8 +7,6 @@ env.Append(CPPPATH = [ 'util', ]) -env.Tool('udis86') - env.CodeGenerate( target = 'indices/u_indices_gen.c', script = 'indices/u_indices_gen.py', @@ -200,39 +198,42 @@ source = [ ] if env['llvm']: + if env['UDIS86']: + env.Append(CPPDEFINES = [('HAVE_UDIS86', '1')]) + source += [ - 'gallivm/lp_bld_arit.c', - 'gallivm/lp_bld_assert.c', - 'gallivm/lp_bld_bitarit.c', - 'gallivm/lp_bld_const.c', - 'gallivm/lp_bld_conv.c', - 'gallivm/lp_bld_debug.c', - 'gallivm/lp_bld_flow.c', - 'gallivm/lp_bld_format_aos.c', - 'gallivm/lp_bld_format_soa.c', - 'gallivm/lp_bld_format_yuv.c', - 'gallivm/lp_bld_gather.c', - 'gallivm/lp_bld_init.c', - 'gallivm/lp_bld_intr.c', - 'gallivm/lp_bld_logic.c', - 'gallivm/lp_bld_misc.cpp', - 'gallivm/lp_bld_pack.c', - 'gallivm/lp_bld_printf.c', - 'gallivm/lp_bld_quad.c', - 'gallivm/lp_bld_sample.c', - 'gallivm/lp_bld_sample_aos.c', - 'gallivm/lp_bld_sample_soa.c', - 'gallivm/lp_bld_struct.c', - 'gallivm/lp_bld_swizzle.c', - 'gallivm/lp_bld_tgsi_aos.c', - 'gallivm/lp_bld_tgsi_info.c', - 'gallivm/lp_bld_tgsi_soa.c', - 'gallivm/lp_bld_type.c', - 'draw/draw_llvm.c', - 'draw/draw_llvm_sample.c', - 'draw/draw_llvm_translate.c', - 'draw/draw_pt_fetch_shade_pipeline_llvm.c', - 'draw/draw_vs_llvm.c' + 'gallivm/lp_bld_arit.c', + 'gallivm/lp_bld_assert.c', + 'gallivm/lp_bld_bitarit.c', + 'gallivm/lp_bld_const.c', + 'gallivm/lp_bld_conv.c', + 'gallivm/lp_bld_debug.c', + 'gallivm/lp_bld_flow.c', + 'gallivm/lp_bld_format_aos.c', + 'gallivm/lp_bld_format_soa.c', + 'gallivm/lp_bld_format_yuv.c', + 'gallivm/lp_bld_gather.c', + 'gallivm/lp_bld_init.c', + 'gallivm/lp_bld_intr.c', + 'gallivm/lp_bld_logic.c', + 'gallivm/lp_bld_misc.cpp', + 'gallivm/lp_bld_pack.c', + 'gallivm/lp_bld_printf.c', + 'gallivm/lp_bld_quad.c', + 'gallivm/lp_bld_sample.c', + 'gallivm/lp_bld_sample_aos.c', + 'gallivm/lp_bld_sample_soa.c', + 'gallivm/lp_bld_struct.c', + 'gallivm/lp_bld_swizzle.c', + 'gallivm/lp_bld_tgsi_aos.c', + 'gallivm/lp_bld_tgsi_info.c', + 'gallivm/lp_bld_tgsi_soa.c', + 'gallivm/lp_bld_type.c', + 'draw/draw_llvm.c', + 'draw/draw_llvm_sample.c', + 'draw/draw_llvm_translate.c', + 'draw/draw_pt_fetch_shade_pipeline_llvm.c', + 'draw/draw_vs_llvm.c' ] gallium = env.ConvenienceLibrary( @@ -240,4 +241,6 @@ gallium = env.ConvenienceLibrary( source = source, ) +env.Alias('gallium', gallium) + Export('gallium') diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 140e596f994..2b5f01cda74 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -1164,11 +1164,6 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) sampler->destroy(sampler); -#ifdef PIPE_ARCH_X86 - /* Avoid corrupting the FPU stack on 32bit OSes. */ - lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); -#endif - ret = LLVMBuildLoad(builder, ret_ptr,""); LLVMBuildRet(builder, ret); @@ -1378,11 +1373,6 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian sampler->destroy(sampler); -#ifdef PIPE_ARCH_X86 - /* Avoid corrupting the FPU stack on 32bit OSes. */ - lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); -#endif - ret = LLVMBuildLoad(builder, ret_ptr,""); LLVMBuildRet(builder, ret); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c index 5598ca5c489..0b9a6f745fb 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_init.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c @@ -145,13 +145,7 @@ lp_build_init(void) LLVMAddCFGSimplificationPass(lp_build_pass); LLVMAddPromoteMemoryToRegisterPass(lp_build_pass); LLVMAddConstantPropagationPass(lp_build_pass); - if(util_cpu_caps.has_sse4_1) { - /* FIXME: There is a bug in this pass, whereby the combination of fptosi - * and sitofp (necessary for trunc/floor/ceil/round implementation) - * somehow becomes invalid code. - */ - LLVMAddInstructionCombiningPass(lp_build_pass); - } + LLVMAddInstructionCombiningPass(lp_build_pass); LLVMAddGVNPass(lp_build_pass); } else { /* We need at least this pass to prevent the backends to fail in diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 3c318cc8c80..7f0f058c222 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -58,6 +58,7 @@ #include "lp_bld_tgsi.h" #include "lp_bld_limits.h" #include "lp_bld_debug.h" +#include "lp_bld_printf.h" #define FOR_EACH_CHANNEL( CHAN )\ @@ -119,9 +120,12 @@ struct lp_build_tgsi_soa_context { struct lp_build_context base; - /* Builder for integer masks and indices */ + /* Builder for vector integer masks and indices */ struct lp_build_context uint_bld; + /* Builder for scalar elements of shader's data type (float) */ + struct lp_build_context elem_bld; + LLVMValueRef consts_ptr; const LLVMValueRef *pos; const LLVMValueRef (*inputs)[NUM_CHANNELS]; @@ -140,6 +144,18 @@ struct lp_build_tgsi_soa_context */ LLVMValueRef temps_array; + /* We allocate/use this array of output if (1 << TGSI_FILE_OUTPUT) is + * set in the indirect_files field. + * The outputs[] array above is unused then. + */ + LLVMValueRef outputs_array; + + /* We allocate/use this array of inputs if (1 << TGSI_FILE_INPUT) is + * set in the indirect_files field. + * The inputs[] array above is unused then. + */ + LLVMValueRef inputs_array; + const struct tgsi_shader_info *info; /** bitmask indicating which register files are accessed indirectly */ unsigned indirect_files; @@ -435,6 +451,26 @@ get_temp_ptr(struct lp_build_tgsi_soa_context *bld, } } +/** + * Return pointer to a output register channel (src or dest). + * Note that indirect addressing cannot be handled here. + * \param index which output register + * \param chan which channel of the output register. + */ +static LLVMValueRef +get_output_ptr(struct lp_build_tgsi_soa_context *bld, + unsigned index, + unsigned chan) +{ + assert(chan < 4); + if (bld->indirect_files & (1 << TGSI_FILE_OUTPUT)) { + LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan); + return LLVMBuildGEP(bld->base.builder, bld->outputs_array, &lindex, 1, ""); + } + else { + return bld->outputs[index][chan]; + } +} /** * Gather vector. @@ -457,7 +493,7 @@ build_gather(struct lp_build_tgsi_soa_context *bld, LLVMValueRef index = LLVMBuildExtractElement(bld->base.builder, indexes, ii, ""); LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, base_ptr, - &index, 1, ""); + &index, 1, "gather_ptr"); LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, ""); res = LLVMBuildInsertElement(bld->base.builder, res, scalar, ii, ""); @@ -468,8 +504,60 @@ build_gather(struct lp_build_tgsi_soa_context *bld, /** + * Scatter/store vector. + */ +static void +emit_mask_scatter(struct lp_build_tgsi_soa_context *bld, + LLVMValueRef base_ptr, + LLVMValueRef indexes, + LLVMValueRef values, + struct lp_exec_mask *mask, + LLVMValueRef pred) +{ + LLVMBuilderRef builder = bld->base.builder; + unsigned i; + + /* Mix the predicate and execution mask */ + if (mask->has_mask) { + if (pred) { + pred = LLVMBuildAnd(mask->bld->builder, pred, mask->exec_mask, ""); + } + else { + pred = mask->exec_mask; + } + } + + /* + * Loop over elements of index_vec, store scalar value. + */ + for (i = 0; i < bld->base.type.length; i++) { + LLVMValueRef ii = LLVMConstInt(LLVMInt32Type(), i, 0); + LLVMValueRef index = LLVMBuildExtractElement(builder, indexes, ii, ""); + LLVMValueRef scalar_ptr = LLVMBuildGEP(builder, base_ptr, &index, 1, "scatter_ptr"); + LLVMValueRef val = LLVMBuildExtractElement(builder, values, ii, "scatter_val"); + LLVMValueRef scalar_pred = pred ? + LLVMBuildExtractElement(builder, pred, ii, "scatter_pred") : NULL; + + if (0) + lp_build_printf(builder, "scatter %d: val %f at %d %p\n", + ii, val, index, scalar_ptr); + + if (scalar_pred) { + LLVMValueRef real_val, dst_val; + dst_val = LLVMBuildLoad(builder, scalar_ptr, ""); + real_val = lp_build_select(&bld->elem_bld, scalar_pred, val, dst_val); + LLVMBuildStore(builder, real_val, scalar_ptr); + } + else { + LLVMBuildStore(builder, val, scalar_ptr); + } + } +} + + +/** * Read the current value of the ADDR register, convert the floats to - * ints, multiply by four and return the vector of offsets. + * ints, add the base index and return the vector of offsets. * The offsets will be used to index into the constant buffer or * temporary register file. */ @@ -577,7 +665,38 @@ emit_fetch( break; case TGSI_FILE_INPUT: - res = bld->inputs[reg->Register.Index][swizzle]; + if (reg->Register.Indirect) { + LLVMValueRef swizzle_vec = + lp_build_const_int_vec(uint_bld->type, swizzle); + LLVMValueRef length_vec = + lp_build_const_int_vec(uint_bld->type, bld->base.type.length); + LLVMValueRef index_vec; /* index into the const buffer */ + LLVMValueRef inputs_array; + LLVMTypeRef float4_ptr_type; + + /* index_vec = (indirect_index * 4 + swizzle) * length */ + index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); + index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec); + index_vec = lp_build_mul(uint_bld, index_vec, length_vec); + + /* cast inputs_array pointer to float* */ + float4_ptr_type = LLVMPointerType(LLVMFloatType(), 0); + inputs_array = LLVMBuildBitCast(uint_bld->builder, bld->inputs_array, + float4_ptr_type, ""); + + /* Gather values from the temporary register array */ + res = build_gather(bld, inputs_array, index_vec); + } else { + if (bld->indirect_files & (1 << TGSI_FILE_INPUT)) { + LLVMValueRef lindex = lp_build_const_int32(reg->Register.Index * 4 + swizzle); + LLVMValueRef input_ptr = LLVMBuildGEP(bld->base.builder, + bld->inputs_array, &lindex, 1, ""); + res = LLVMBuildLoad(bld->base.builder, input_ptr, ""); + } + else { + res = bld->inputs[reg->Register.Index][swizzle]; + } + } assert(res); break; @@ -748,6 +867,7 @@ emit_store( LLVMValueRef value) { const struct tgsi_full_dst_register *reg = &inst->Dst[index]; + struct lp_build_context *uint_bld = &bld->uint_bld; LLVMValueRef indirect_index = NULL; switch( inst->Instruction.Saturate ) { @@ -779,15 +899,81 @@ emit_store( switch( reg->Register.File ) { case TGSI_FILE_OUTPUT: - lp_exec_mask_store(&bld->exec_mask, pred, value, - bld->outputs[reg->Register.Index][chan_index]); + if (reg->Register.Indirect) { + LLVMBuilderRef builder = bld->base.builder; + LLVMValueRef chan_vec = + lp_build_const_int_vec(uint_bld->type, chan_index); + LLVMValueRef length_vec = + lp_build_const_int_vec(uint_bld->type, bld->base.type.length); + LLVMValueRef index_vec; /* indexes into the temp registers */ + LLVMValueRef outputs_array; + LLVMValueRef pixel_offsets; + LLVMTypeRef float_ptr_type; + int i; + + /* build pixel offset vector: {0, 1, 2, 3, ...} */ + pixel_offsets = uint_bld->undef; + for (i = 0; i < bld->base.type.length; i++) { + LLVMValueRef ii = lp_build_const_int32(i); + pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets, + ii, ii, ""); + } + + /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */ + index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); + index_vec = lp_build_add(uint_bld, index_vec, chan_vec); + index_vec = lp_build_mul(uint_bld, index_vec, length_vec); + index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets); + + float_ptr_type = LLVMPointerType(LLVMFloatType(), 0); + outputs_array = LLVMBuildBitCast(builder, bld->outputs_array, + float_ptr_type, ""); + + /* Scatter store values into temp registers */ + emit_mask_scatter(bld, outputs_array, index_vec, value, + &bld->exec_mask, pred); + } + else { + LLVMValueRef out_ptr = get_output_ptr(bld, reg->Register.Index, + chan_index); + lp_exec_mask_store(&bld->exec_mask, pred, value, out_ptr); + } break; case TGSI_FILE_TEMPORARY: if (reg->Register.Indirect) { - /* XXX not done yet */ - debug_printf("WARNING: LLVM scatter store of temp regs" - " not implemented\n"); + LLVMBuilderRef builder = bld->base.builder; + LLVMValueRef chan_vec = + lp_build_const_int_vec(uint_bld->type, chan_index); + LLVMValueRef length_vec = + lp_build_const_int_vec(uint_bld->type, bld->base.type.length); + LLVMValueRef index_vec; /* indexes into the temp registers */ + LLVMValueRef temps_array; + LLVMValueRef pixel_offsets; + LLVMTypeRef float_ptr_type; + int i; + + /* build pixel offset vector: {0, 1, 2, 3, ...} */ + pixel_offsets = uint_bld->undef; + for (i = 0; i < bld->base.type.length; i++) { + LLVMValueRef ii = lp_build_const_int32(i); + pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets, + ii, ii, ""); + } + + /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */ + index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2); + index_vec = lp_build_add(uint_bld, index_vec, chan_vec); + index_vec = lp_build_mul(uint_bld, index_vec, length_vec); + index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets); + + float_ptr_type = LLVMPointerType(LLVMFloatType(), 0); + temps_array = LLVMBuildBitCast(builder, bld->temps_array, + float_ptr_type, ""); + + /* Scatter store values into temp registers */ + emit_mask_scatter(bld, temps_array, index_vec, value, + &bld->exec_mask, pred); } else { LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index, @@ -1040,15 +1226,60 @@ emit_kilp(struct lp_build_tgsi_soa_context *bld, lp_build_mask_check(bld->mask); } + +/** + * Emit code which will dump the value of all the temporary registers + * to stdout. + */ +static void +emit_dump_temps(struct lp_build_tgsi_soa_context *bld) +{ + LLVMBuilderRef builder = bld->base.builder; + LLVMValueRef temp_ptr; + LLVMValueRef i0 = lp_build_const_int32(0); + LLVMValueRef i1 = lp_build_const_int32(1); + LLVMValueRef i2 = lp_build_const_int32(2); + LLVMValueRef i3 = lp_build_const_int32(3); + int index; + int n = bld->info->file_max[TGSI_FILE_TEMPORARY]; + + for (index = 0; index < n; index++) { + LLVMValueRef idx = lp_build_const_int32(index); + LLVMValueRef v[4][4], res; + int chan; + + lp_build_printf(builder, "TEMP[%d]:\n", idx); + + for (chan = 0; chan < 4; chan++) { + temp_ptr = get_temp_ptr(bld, index, chan); + res = LLVMBuildLoad(bld->base.builder, temp_ptr, ""); + v[chan][0] = LLVMBuildExtractElement(builder, res, i0, ""); + v[chan][1] = LLVMBuildExtractElement(builder, res, i1, ""); + v[chan][2] = LLVMBuildExtractElement(builder, res, i2, ""); + v[chan][3] = LLVMBuildExtractElement(builder, res, i3, ""); + } + + lp_build_printf(builder, " X: %f %f %f %f\n", + v[0][0], v[0][1], v[0][2], v[0][3]); + lp_build_printf(builder, " Y: %f %f %f %f\n", + v[1][0], v[1][1], v[1][2], v[1][3]); + lp_build_printf(builder, " Z: %f %f %f %f\n", + v[2][0], v[2][1], v[2][2], v[2][3]); + lp_build_printf(builder, " W: %f %f %f %f\n", + v[3][0], v[3][1], v[3][2], v[3][3]); + } +} + + + static void emit_declaration( struct lp_build_tgsi_soa_context *bld, const struct tgsi_full_declaration *decl) { LLVMTypeRef vec_type = bld->base.vec_type; - - unsigned first = decl->Range.First; - unsigned last = decl->Range.Last; + const unsigned first = decl->Range.First; + const unsigned last = decl->Range.Last; unsigned idx, i; for (idx = first; idx <= last; ++idx) { @@ -1056,36 +1287,33 @@ emit_declaration( switch (decl->Declaration.File) { case TGSI_FILE_TEMPORARY: assert(idx < LP_MAX_TGSI_TEMPS); - if (bld->indirect_files & (1 << TGSI_FILE_TEMPORARY)) { - LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), - last*4 + 4, 0); - bld->temps_array = lp_build_array_alloca(bld->base.builder, - vec_type, array_size, ""); - } else { + if (!(bld->indirect_files & (1 << TGSI_FILE_TEMPORARY))) { for (i = 0; i < NUM_CHANNELS; i++) bld->temps[idx][i] = lp_build_alloca(bld->base.builder, - vec_type, ""); + vec_type, "temp"); } break; case TGSI_FILE_OUTPUT: - for (i = 0; i < NUM_CHANNELS; i++) - bld->outputs[idx][i] = lp_build_alloca(bld->base.builder, - vec_type, ""); + if (!(bld->indirect_files & (1 << TGSI_FILE_OUTPUT))) { + for (i = 0; i < NUM_CHANNELS; i++) + bld->outputs[idx][i] = lp_build_alloca(bld->base.builder, + vec_type, "output"); + } break; case TGSI_FILE_ADDRESS: assert(idx < LP_MAX_TGSI_ADDRS); for (i = 0; i < NUM_CHANNELS; i++) bld->addr[idx][i] = lp_build_alloca(bld->base.builder, - vec_type, ""); + vec_type, "addr"); break; case TGSI_FILE_PREDICATE: assert(idx < LP_MAX_TGSI_PREDS); for (i = 0; i < NUM_CHANNELS; i++) bld->preds[idx][i] = lp_build_alloca(bld->base.builder, - vec_type, ""); + vec_type, "predicate"); break; default: @@ -1740,6 +1968,10 @@ emit_instruction( break; case TGSI_OPCODE_END: + if (0) { + /* for debugging */ + emit_dump_temps(bld); + } *pc = -1; break; @@ -2082,6 +2314,7 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, memset(&bld, 0, sizeof bld); lp_build_context_init(&bld.base, builder, type); lp_build_context_init(&bld.uint_bld, builder, lp_uint_type(type)); + lp_build_context_init(&bld.elem_bld, builder, lp_elem_type(type)); bld.mask = mask; bld.pos = pos; bld.inputs = inputs; @@ -2100,6 +2333,48 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, lp_exec_mask_init(&bld.exec_mask, &bld.base); + if (bld.indirect_files & (1 << TGSI_FILE_TEMPORARY)) { + LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), + info->file_max[TGSI_FILE_TEMPORARY]*4 + 4, 0); + bld.temps_array = lp_build_array_alloca(bld.base.builder, + bld.base.vec_type, array_size, + "temp_array"); + } + + if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) { + LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), + info->file_max[TGSI_FILE_OUTPUT]*4 + 4, 0); + bld.outputs_array = lp_build_array_alloca(bld.base.builder, + bld.base.vec_type, array_size, + "output_array"); + } + + /* If we have indirect addressing in inputs we need to copy them into + * our alloca array to be able to iterate over them */ + if (bld.indirect_files & (1 << TGSI_FILE_INPUT)) { + unsigned index, chan; + LLVMTypeRef vec_type = bld.base.vec_type; + LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(), + info->file_max[TGSI_FILE_INPUT]*4 + 4, 0); + bld.inputs_array = lp_build_array_alloca(bld.base.builder, + vec_type, array_size, + "input_array"); + + assert(info->num_inputs <= info->file_max[TGSI_FILE_INPUT] + 1); + + for (index = 0; index < info->num_inputs; ++index) { + for (chan = 0; chan < NUM_CHANNELS; ++chan) { + LLVMValueRef lindex = lp_build_const_int32(index * 4 + chan); + LLVMValueRef input_ptr = + LLVMBuildGEP(bld.base.builder, bld.inputs_array, + &lindex, 1, ""); + LLVMValueRef value = bld.inputs[index][chan]; + if (value) + LLVMBuildStore(bld.base.builder, value, input_ptr); + } + } + } + tgsi_parse_init( &parse, tokens ); while( !tgsi_parse_end_of_tokens( &parse ) ) { @@ -2169,6 +2444,18 @@ lp_build_tgsi_soa(LLVMBuilderRef builder, opcode_info->mnemonic); } + /* If we have indirect addressing in outputs we need to copy our alloca array + * to the outputs slots specified by the called */ + if (bld.indirect_files & (1 << TGSI_FILE_OUTPUT)) { + unsigned index, chan; + assert(info->num_outputs <= info->file_max[TGSI_FILE_OUTPUT] + 1); + for (index = 0; index < info->num_outputs; ++index) { + for (chan = 0; chan < NUM_CHANNELS; ++chan) { + bld.outputs[index][chan] = get_output_ptr(&bld, index, chan); + } + } + } + if (0) { LLVMBasicBlockRef block = LLVMGetInsertBlock(builder); LLVMValueRef function = LLVMGetBasicBlockParent(block); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c index 06f1aae6dcc..5205c7ada91 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_type.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c @@ -188,6 +188,22 @@ lp_build_int32_vec4_type(void) /** + * Create element of vector type + */ +struct lp_type +lp_elem_type(struct lp_type type) +{ + struct lp_type res_type; + + assert(type.length > 1); + res_type = type; + res_type.length = 1; + + return res_type; +} + + +/** * Create unsigned integer type variation of given type. */ struct lp_type diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h index fec1d3dfbc6..a135d0df847 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_type.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h @@ -365,6 +365,10 @@ lp_unorm8_vec4_type(void) struct lp_type +lp_elem_type(struct lp_type type); + + +struct lp_type lp_uint_type(struct lp_type type); diff --git a/src/gallium/auxiliary/os/os_stream_stdc.c b/src/gallium/auxiliary/os/os_stream_stdc.c index 37e7d063e2b..afd3ff6dcea 100644 --- a/src/gallium/auxiliary/os/os_stream_stdc.c +++ b/src/gallium/auxiliary/os/os_stream_stdc.c @@ -106,7 +106,7 @@ os_file_stream_create(const char *filename) stream->base.flush = &os_stdc_stream_flush; stream->base.vprintf = &os_stdc_stream_vprintf; - stream->file = fopen(filename, "w"); + stream->file = fopen(filename, "wb"); if(!stream->file) goto no_file; diff --git a/src/gallium/auxiliary/pipebuffer/SConscript b/src/gallium/auxiliary/pipebuffer/SConscript deleted file mode 100644 index a074a554717..00000000000 --- a/src/gallium/auxiliary/pipebuffer/SConscript +++ /dev/null @@ -1,18 +0,0 @@ -Import('*') - -pipebuffer = env.ConvenienceLibrary( - target = 'pipebuffer', - source = [ - 'pb_buffer_fenced.c', - 'pb_buffer_malloc.c', - 'pb_bufmgr_alt.c', - 'pb_bufmgr_cache.c', - 'pb_bufmgr_debug.c', - 'pb_bufmgr_mm.c', - 'pb_bufmgr_ondemand.c', - 'pb_bufmgr_pool.c', - 'pb_bufmgr_slab.c', - 'pb_validate.c', - ]) - -auxiliaries.insert(0, pipebuffer) diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c index 6dbedf15ca8..16a205f2068 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.c +++ b/src/gallium/auxiliary/tgsi/tgsi_build.c @@ -64,25 +64,14 @@ header_bodysize_grow( struct tgsi_header *header ) } struct tgsi_processor -tgsi_default_processor( void ) -{ - struct tgsi_processor processor; - - processor.Processor = TGSI_PROCESSOR_FRAGMENT; - processor.Padding = 0; - - return processor; -} - -struct tgsi_processor tgsi_build_processor( unsigned type, struct tgsi_header *header ) { struct tgsi_processor processor; - processor = tgsi_default_processor(); processor.Processor = type; + processor.Padding = 0; header_headersize_grow( header ); @@ -93,7 +82,19 @@ tgsi_build_processor( * declaration */ -struct tgsi_declaration +static void +declaration_grow( + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + assert( declaration->NrTokens < 0xFF ); + + declaration->NrTokens++; + + header_bodysize_grow( header ); +} + +static struct tgsi_declaration tgsi_default_declaration( void ) { struct tgsi_declaration declaration; @@ -112,7 +113,7 @@ tgsi_default_declaration( void ) return declaration; } -struct tgsi_declaration +static struct tgsi_declaration tgsi_build_declaration( unsigned file, unsigned usage_mask, @@ -144,16 +145,85 @@ tgsi_build_declaration( return declaration; } -static void -declaration_grow( +static struct tgsi_declaration_range +tgsi_default_declaration_range( void ) +{ + struct tgsi_declaration_range dr; + + dr.First = 0; + dr.Last = 0; + + return dr; +} + +static struct tgsi_declaration_range +tgsi_build_declaration_range( + unsigned first, + unsigned last, struct tgsi_declaration *declaration, struct tgsi_header *header ) { - assert( declaration->NrTokens < 0xFF ); + struct tgsi_declaration_range declaration_range; - declaration->NrTokens++; + assert( last >= first ); + assert( last <= 0xFFFF ); - header_bodysize_grow( header ); + declaration_range.First = first; + declaration_range.Last = last; + + declaration_grow( declaration, header ); + + return declaration_range; +} + +static struct tgsi_declaration_dimension +tgsi_build_declaration_dimension(unsigned index_2d, + struct tgsi_declaration *declaration, + struct tgsi_header *header) +{ + struct tgsi_declaration_dimension dd; + + assert(index_2d <= 0xFFFF); + + dd.Index2D = index_2d; + dd.Padding = 0; + + declaration_grow(declaration, header); + + return dd; +} + +static struct tgsi_declaration_semantic +tgsi_default_declaration_semantic( void ) +{ + struct tgsi_declaration_semantic ds; + + ds.Name = TGSI_SEMANTIC_POSITION; + ds.Index = 0; + ds.Padding = 0; + + return ds; +} + +static struct tgsi_declaration_semantic +tgsi_build_declaration_semantic( + unsigned semantic_name, + unsigned semantic_index, + struct tgsi_declaration *declaration, + struct tgsi_header *header ) +{ + struct tgsi_declaration_semantic ds; + + assert( semantic_name <= TGSI_SEMANTIC_COUNT ); + assert( semantic_index <= 0xFFFF ); + + ds.Name = semantic_name; + ds.Index = semantic_index; + ds.Padding = 0; + + declaration_grow( declaration, header ); + + return ds; } struct tgsi_full_declaration @@ -257,104 +327,11 @@ tgsi_build_full_declaration( return size; } -struct tgsi_declaration_range -tgsi_default_declaration_range( void ) -{ - struct tgsi_declaration_range dr; - - dr.First = 0; - dr.Last = 0; - - return dr; -} - -struct tgsi_declaration_range -tgsi_build_declaration_range( - unsigned first, - unsigned last, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_range declaration_range; - - assert( last >= first ); - assert( last <= 0xFFFF ); - - declaration_range = tgsi_default_declaration_range(); - declaration_range.First = first; - declaration_range.Last = last; - - declaration_grow( declaration, header ); - - return declaration_range; -} - -struct tgsi_declaration_dimension -tgsi_default_declaration_dimension(void) -{ - struct tgsi_declaration_dimension dd; - - dd.Index2D = 0; - dd.Padding = 0; - - return dd; -} - -struct tgsi_declaration_dimension -tgsi_build_declaration_dimension(unsigned index_2d, - struct tgsi_declaration *declaration, - struct tgsi_header *header) -{ - struct tgsi_declaration_dimension dd; - - assert(index_2d <= 0xFFFF); - - dd = tgsi_default_declaration_dimension(); - dd.Index2D = index_2d; - - declaration_grow(declaration, header); - - return dd; -} - -struct tgsi_declaration_semantic -tgsi_default_declaration_semantic( void ) -{ - struct tgsi_declaration_semantic ds; - - ds.Name = TGSI_SEMANTIC_POSITION; - ds.Index = 0; - ds.Padding = 0; - - return ds; -} - -struct tgsi_declaration_semantic -tgsi_build_declaration_semantic( - unsigned semantic_name, - unsigned semantic_index, - struct tgsi_declaration *declaration, - struct tgsi_header *header ) -{ - struct tgsi_declaration_semantic ds; - - assert( semantic_name <= TGSI_SEMANTIC_COUNT ); - assert( semantic_index <= 0xFFFF ); - - ds = tgsi_default_declaration_semantic(); - ds.Name = semantic_name; - ds.Index = semantic_index; - - declaration_grow( declaration, header ); - - return ds; -} - /* * immediate */ -struct tgsi_immediate +static struct tgsi_immediate tgsi_default_immediate( void ) { struct tgsi_immediate immediate; @@ -367,7 +344,7 @@ tgsi_default_immediate( void ) return immediate; } -struct tgsi_immediate +static struct tgsi_immediate tgsi_build_immediate( struct tgsi_header *header ) { @@ -406,7 +383,7 @@ immediate_grow( header_bodysize_grow( header ); } -union tgsi_immediate_data +static union tgsi_immediate_data tgsi_build_immediate_float32( float value, struct tgsi_immediate *immediate, @@ -480,7 +457,7 @@ tgsi_default_instruction( void ) return instruction; } -struct tgsi_instruction +static struct tgsi_instruction tgsi_build_instruction(unsigned opcode, unsigned saturate, unsigned predicate, @@ -519,6 +496,266 @@ instruction_grow( header_bodysize_grow( header ); } +struct tgsi_instruction_predicate +tgsi_default_instruction_predicate(void) +{ + struct tgsi_instruction_predicate instruction_predicate; + + instruction_predicate.SwizzleX = TGSI_SWIZZLE_X; + instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y; + instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z; + instruction_predicate.SwizzleW = TGSI_SWIZZLE_W; + instruction_predicate.Negate = 0; + instruction_predicate.Index = 0; + instruction_predicate.Padding = 0; + + return instruction_predicate; +} + +static struct tgsi_instruction_predicate +tgsi_build_instruction_predicate(int index, + unsigned negate, + unsigned swizzleX, + unsigned swizzleY, + unsigned swizzleZ, + unsigned swizzleW, + struct tgsi_instruction *instruction, + struct tgsi_header *header) +{ + struct tgsi_instruction_predicate instruction_predicate; + + instruction_predicate = tgsi_default_instruction_predicate(); + instruction_predicate.SwizzleX = swizzleX; + instruction_predicate.SwizzleY = swizzleY; + instruction_predicate.SwizzleZ = swizzleZ; + instruction_predicate.SwizzleW = swizzleW; + instruction_predicate.Negate = negate; + instruction_predicate.Index = index; + + instruction_grow(instruction, header); + + return instruction_predicate; +} + +static struct tgsi_instruction_label +tgsi_default_instruction_label( void ) +{ + struct tgsi_instruction_label instruction_label; + + instruction_label.Label = 0; + instruction_label.Padding = 0; + + return instruction_label; +} + +static struct tgsi_instruction_label +tgsi_build_instruction_label( + unsigned label, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_label instruction_label; + + instruction_label.Label = label; + instruction_label.Padding = 0; + instruction->Label = 1; + + instruction_grow( instruction, header ); + + return instruction_label; +} + +static struct tgsi_instruction_texture +tgsi_default_instruction_texture( void ) +{ + struct tgsi_instruction_texture instruction_texture; + + instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN; + instruction_texture.Padding = 0; + + return instruction_texture; +} + +static struct tgsi_instruction_texture +tgsi_build_instruction_texture( + unsigned texture, + struct tgsi_token *prev_token, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_instruction_texture instruction_texture; + + instruction_texture.Texture = texture; + instruction_texture.Padding = 0; + instruction->Texture = 1; + + instruction_grow( instruction, header ); + + return instruction_texture; +} + +static struct tgsi_src_register +tgsi_default_src_register( void ) +{ + struct tgsi_src_register src_register; + + src_register.File = TGSI_FILE_NULL; + src_register.SwizzleX = TGSI_SWIZZLE_X; + src_register.SwizzleY = TGSI_SWIZZLE_Y; + src_register.SwizzleZ = TGSI_SWIZZLE_Z; + src_register.SwizzleW = TGSI_SWIZZLE_W; + src_register.Negate = 0; + src_register.Absolute = 0; + src_register.Indirect = 0; + src_register.Dimension = 0; + src_register.Index = 0; + + return src_register; +} + +static struct tgsi_src_register +tgsi_build_src_register( + unsigned file, + unsigned swizzle_x, + unsigned swizzle_y, + unsigned swizzle_z, + unsigned swizzle_w, + unsigned negate, + unsigned absolute, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_src_register src_register; + + assert( file < TGSI_FILE_COUNT ); + assert( swizzle_x <= TGSI_SWIZZLE_W ); + assert( swizzle_y <= TGSI_SWIZZLE_W ); + assert( swizzle_z <= TGSI_SWIZZLE_W ); + assert( swizzle_w <= TGSI_SWIZZLE_W ); + assert( negate <= 1 ); + assert( index >= -0x8000 && index <= 0x7FFF ); + + src_register.File = file; + src_register.SwizzleX = swizzle_x; + src_register.SwizzleY = swizzle_y; + src_register.SwizzleZ = swizzle_z; + src_register.SwizzleW = swizzle_w; + src_register.Negate = negate; + src_register.Absolute = absolute; + src_register.Indirect = indirect; + src_register.Dimension = dimension; + src_register.Index = index; + + instruction_grow( instruction, header ); + + return src_register; +} + +static struct tgsi_dimension +tgsi_default_dimension( void ) +{ + struct tgsi_dimension dimension; + + dimension.Indirect = 0; + dimension.Dimension = 0; + dimension.Padding = 0; + dimension.Index = 0; + + return dimension; +} + +static struct tgsi_full_src_register +tgsi_default_full_src_register( void ) +{ + struct tgsi_full_src_register full_src_register; + + full_src_register.Register = tgsi_default_src_register(); + full_src_register.Indirect = tgsi_default_src_register(); + full_src_register.Dimension = tgsi_default_dimension(); + full_src_register.DimIndirect = tgsi_default_src_register(); + + return full_src_register; +} + +static struct tgsi_dimension +tgsi_build_dimension( + unsigned indirect, + unsigned index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dimension dimension; + + dimension.Indirect = indirect; + dimension.Dimension = 0; + dimension.Padding = 0; + dimension.Index = index; + + instruction_grow( instruction, header ); + + return dimension; +} + +static struct tgsi_dst_register +tgsi_default_dst_register( void ) +{ + struct tgsi_dst_register dst_register; + + dst_register.File = TGSI_FILE_NULL; + dst_register.WriteMask = TGSI_WRITEMASK_XYZW; + dst_register.Indirect = 0; + dst_register.Dimension = 0; + dst_register.Index = 0; + dst_register.Padding = 0; + + return dst_register; +} + +static struct tgsi_dst_register +tgsi_build_dst_register( + unsigned file, + unsigned mask, + unsigned indirect, + unsigned dimension, + int index, + struct tgsi_instruction *instruction, + struct tgsi_header *header ) +{ + struct tgsi_dst_register dst_register; + + assert( file < TGSI_FILE_COUNT ); + assert( mask <= TGSI_WRITEMASK_XYZW ); + assert( index >= -32768 && index <= 32767 ); + + dst_register.File = file; + dst_register.WriteMask = mask; + dst_register.Indirect = indirect; + dst_register.Dimension = dimension; + dst_register.Index = index; + dst_register.Padding = 0; + + instruction_grow( instruction, header ); + + return dst_register; +} + +static struct tgsi_full_dst_register +tgsi_default_full_dst_register( void ) +{ + struct tgsi_full_dst_register full_dst_register; + + full_dst_register.Register = tgsi_default_dst_register(); + full_dst_register.Indirect = tgsi_default_src_register(); + full_dst_register.Dimension = tgsi_default_dimension(); + full_dst_register.DimIndirect = tgsi_default_src_register(); + + return full_dst_register; +} + struct tgsi_full_instruction tgsi_default_full_instruction( void ) { @@ -794,268 +1031,7 @@ tgsi_build_full_instruction( return size; } -struct tgsi_instruction_predicate -tgsi_default_instruction_predicate(void) -{ - struct tgsi_instruction_predicate instruction_predicate; - - instruction_predicate.SwizzleX = TGSI_SWIZZLE_X; - instruction_predicate.SwizzleY = TGSI_SWIZZLE_Y; - instruction_predicate.SwizzleZ = TGSI_SWIZZLE_Z; - instruction_predicate.SwizzleW = TGSI_SWIZZLE_W; - instruction_predicate.Negate = 0; - instruction_predicate.Index = 0; - instruction_predicate.Padding = 0; - - return instruction_predicate; -} - -struct tgsi_instruction_predicate -tgsi_build_instruction_predicate(int index, - unsigned negate, - unsigned swizzleX, - unsigned swizzleY, - unsigned swizzleZ, - unsigned swizzleW, - struct tgsi_instruction *instruction, - struct tgsi_header *header) -{ - struct tgsi_instruction_predicate instruction_predicate; - - instruction_predicate = tgsi_default_instruction_predicate(); - instruction_predicate.SwizzleX = swizzleX; - instruction_predicate.SwizzleY = swizzleY; - instruction_predicate.SwizzleZ = swizzleZ; - instruction_predicate.SwizzleW = swizzleW; - instruction_predicate.Negate = negate; - instruction_predicate.Index = index; - - instruction_grow(instruction, header); - - return instruction_predicate; -} - -struct tgsi_instruction_label -tgsi_default_instruction_label( void ) -{ - struct tgsi_instruction_label instruction_label; - - instruction_label.Label = 0; - instruction_label.Padding = 0; - - return instruction_label; -} - -struct tgsi_instruction_label -tgsi_build_instruction_label( - unsigned label, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_label instruction_label; - - instruction_label = tgsi_default_instruction_label(); - instruction_label.Label = label; - instruction->Label = 1; - - instruction_grow( instruction, header ); - - return instruction_label; -} - -struct tgsi_instruction_texture -tgsi_default_instruction_texture( void ) -{ - struct tgsi_instruction_texture instruction_texture; - - instruction_texture.Texture = TGSI_TEXTURE_UNKNOWN; - instruction_texture.Padding = 0; - - return instruction_texture; -} - -struct tgsi_instruction_texture -tgsi_build_instruction_texture( - unsigned texture, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_instruction_texture instruction_texture; - - instruction_texture = tgsi_default_instruction_texture(); - instruction_texture.Texture = texture; - instruction->Texture = 1; - - instruction_grow( instruction, header ); - - return instruction_texture; -} - -struct tgsi_src_register -tgsi_default_src_register( void ) -{ - struct tgsi_src_register src_register; - - src_register.File = TGSI_FILE_NULL; - src_register.SwizzleX = TGSI_SWIZZLE_X; - src_register.SwizzleY = TGSI_SWIZZLE_Y; - src_register.SwizzleZ = TGSI_SWIZZLE_Z; - src_register.SwizzleW = TGSI_SWIZZLE_W; - src_register.Negate = 0; - src_register.Absolute = 0; - src_register.Indirect = 0; - src_register.Dimension = 0; - src_register.Index = 0; - - return src_register; -} - -struct tgsi_src_register -tgsi_build_src_register( - unsigned file, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - unsigned negate, - unsigned absolute, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_src_register src_register; - - assert( file < TGSI_FILE_COUNT ); - assert( swizzle_x <= TGSI_SWIZZLE_W ); - assert( swizzle_y <= TGSI_SWIZZLE_W ); - assert( swizzle_z <= TGSI_SWIZZLE_W ); - assert( swizzle_w <= TGSI_SWIZZLE_W ); - assert( negate <= 1 ); - assert( index >= -0x8000 && index <= 0x7FFF ); - - src_register = tgsi_default_src_register(); - src_register.File = file; - src_register.SwizzleX = swizzle_x; - src_register.SwizzleY = swizzle_y; - src_register.SwizzleZ = swizzle_z; - src_register.SwizzleW = swizzle_w; - src_register.Negate = negate; - src_register.Absolute = absolute; - src_register.Indirect = indirect; - src_register.Dimension = dimension; - src_register.Index = index; - - instruction_grow( instruction, header ); - - return src_register; -} - -struct tgsi_full_src_register -tgsi_default_full_src_register( void ) -{ - struct tgsi_full_src_register full_src_register; - - full_src_register.Register = tgsi_default_src_register(); - full_src_register.Indirect = tgsi_default_src_register(); - full_src_register.Dimension = tgsi_default_dimension(); - full_src_register.DimIndirect = tgsi_default_src_register(); - - return full_src_register; -} - - -struct tgsi_dimension -tgsi_default_dimension( void ) -{ - struct tgsi_dimension dimension; - - dimension.Indirect = 0; - dimension.Dimension = 0; - dimension.Padding = 0; - dimension.Index = 0; - - return dimension; -} - -struct tgsi_dimension -tgsi_build_dimension( - unsigned indirect, - unsigned index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dimension dimension; - - dimension = tgsi_default_dimension(); - dimension.Indirect = indirect; - dimension.Index = index; - - instruction_grow( instruction, header ); - - return dimension; -} - -struct tgsi_dst_register -tgsi_default_dst_register( void ) -{ - struct tgsi_dst_register dst_register; - - dst_register.File = TGSI_FILE_NULL; - dst_register.WriteMask = TGSI_WRITEMASK_XYZW; - dst_register.Indirect = 0; - dst_register.Dimension = 0; - dst_register.Index = 0; - dst_register.Padding = 0; - - return dst_register; -} - -struct tgsi_dst_register -tgsi_build_dst_register( - unsigned file, - unsigned mask, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ) -{ - struct tgsi_dst_register dst_register; - - assert( file < TGSI_FILE_COUNT ); - assert( mask <= TGSI_WRITEMASK_XYZW ); - assert( index >= -32768 && index <= 32767 ); - - dst_register = tgsi_default_dst_register(); - dst_register.File = file; - dst_register.WriteMask = mask; - dst_register.Index = index; - dst_register.Indirect = indirect; - dst_register.Dimension = dimension; - - instruction_grow( instruction, header ); - - return dst_register; -} - -struct tgsi_full_dst_register -tgsi_default_full_dst_register( void ) -{ - struct tgsi_full_dst_register full_dst_register; - - full_dst_register.Register = tgsi_default_dst_register(); - full_dst_register.Indirect = tgsi_default_src_register(); - full_dst_register.Dimension = tgsi_default_dimension(); - full_dst_register.DimIndirect = tgsi_default_src_register(); - - return full_dst_register; -} - -struct tgsi_property +static struct tgsi_property tgsi_default_property( void ) { struct tgsi_property property; @@ -1068,7 +1044,7 @@ tgsi_default_property( void ) return property; } -struct tgsi_property +static struct tgsi_property tgsi_build_property(unsigned property_name, struct tgsi_header *header) { @@ -1107,7 +1083,7 @@ property_grow( header_bodysize_grow( header ); } -struct tgsi_property_data +static struct tgsi_property_data tgsi_build_property_data( unsigned value, struct tgsi_property *property, diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h index 112107a0881..3f236a9c241 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_build.h +++ b/src/gallium/auxiliary/tgsi/tgsi_build.h @@ -45,9 +45,6 @@ struct tgsi_header tgsi_build_header( void ); struct tgsi_processor -tgsi_default_processor( void ); - -struct tgsi_processor tgsi_build_processor( unsigned processor, struct tgsi_header *header ); @@ -56,21 +53,6 @@ tgsi_build_processor( * declaration */ -struct tgsi_declaration -tgsi_default_declaration( void ); - -struct tgsi_declaration -tgsi_build_declaration( - unsigned file, - unsigned usage_mask, - unsigned interpolate, - unsigned dimension, - unsigned semantic, - unsigned centroid, - unsigned invariant, - unsigned cylindrical_wrap, - struct tgsi_header *header ); - struct tgsi_full_declaration tgsi_default_full_declaration( void ); @@ -81,54 +63,13 @@ tgsi_build_full_declaration( struct tgsi_header *header, unsigned maxsize ); -struct tgsi_declaration_range -tgsi_default_declaration_range( void ); - -struct tgsi_declaration_range -tgsi_build_declaration_range( - unsigned first, - unsigned last, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - -struct tgsi_declaration_dimension -tgsi_default_declaration_dimension(void); - -struct tgsi_declaration_dimension -tgsi_build_declaration_dimension(unsigned index_2d, - struct tgsi_declaration *declaration, - struct tgsi_header *header); - -struct tgsi_declaration_semantic -tgsi_default_declaration_semantic( void ); - -struct tgsi_declaration_semantic -tgsi_build_declaration_semantic( - unsigned semantic_name, - unsigned semantic_index, - struct tgsi_declaration *declaration, - struct tgsi_header *header ); - /* * immediate */ -struct tgsi_immediate -tgsi_default_immediate( void ); - -struct tgsi_immediate -tgsi_build_immediate( - struct tgsi_header *header ); - struct tgsi_full_immediate tgsi_default_full_immediate( void ); -union tgsi_immediate_data -tgsi_build_immediate_float32( - float value, - struct tgsi_immediate *immediate, - struct tgsi_header *header ); - unsigned tgsi_build_full_immediate( const struct tgsi_full_immediate *full_imm, @@ -140,23 +81,9 @@ tgsi_build_full_immediate( * properties */ -struct tgsi_property -tgsi_default_property( void ); - -struct tgsi_property -tgsi_build_property( - unsigned property_name, - struct tgsi_header *header ); - struct tgsi_full_property tgsi_default_full_property( void ); -struct tgsi_property_data -tgsi_build_property_data( - unsigned value, - struct tgsi_property *property, - struct tgsi_header *header ); - unsigned tgsi_build_full_property( const struct tgsi_full_property *full_prop, @@ -171,15 +98,6 @@ tgsi_build_full_property( struct tgsi_instruction tgsi_default_instruction( void ); -struct tgsi_instruction -tgsi_build_instruction( - unsigned opcode, - unsigned saturate, - unsigned predicate, - unsigned num_dst_regs, - unsigned num_src_regs, - struct tgsi_header *header ); - struct tgsi_full_instruction tgsi_default_full_instruction( void ); @@ -193,85 +111,6 @@ tgsi_build_full_instruction( struct tgsi_instruction_predicate tgsi_default_instruction_predicate(void); -struct tgsi_instruction_predicate -tgsi_build_instruction_predicate(int index, - unsigned negate, - unsigned swizzleX, - unsigned swizzleY, - unsigned swizzleZ, - unsigned swizzleW, - struct tgsi_instruction *instruction, - struct tgsi_header *header); - -struct tgsi_instruction_label -tgsi_default_instruction_label( void ); - -struct tgsi_instruction_label -tgsi_build_instruction_label( - unsigned label, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_instruction_texture -tgsi_default_instruction_texture( void ); - -struct tgsi_instruction_texture -tgsi_build_instruction_texture( - unsigned texture, - struct tgsi_token *prev_token, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_src_register -tgsi_default_src_register( void ); - -struct tgsi_src_register -tgsi_build_src_register( - unsigned file, - unsigned swizzle_x, - unsigned swizzle_y, - unsigned swizzle_z, - unsigned swizzle_w, - unsigned negate, - unsigned absolute, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_full_src_register -tgsi_default_full_src_register( void ); - - -struct tgsi_dimension -tgsi_default_dimension( void ); - -struct tgsi_dimension -tgsi_build_dimension( - unsigned indirect, - unsigned index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_dst_register -tgsi_default_dst_register( void ); - -struct tgsi_dst_register -tgsi_build_dst_register( - unsigned file, - unsigned mask, - unsigned indirect, - unsigned dimension, - int index, - struct tgsi_instruction *instruction, - struct tgsi_header *header ); - -struct tgsi_full_dst_register -tgsi_default_full_dst_register( void ); - - #if defined __cplusplus } #endif diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 3a71540506d..7892a67f04c 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -429,6 +429,24 @@ micro_sne(union tgsi_exec_channel *dst, } static void +micro_sfl(union tgsi_exec_channel *dst) +{ + dst->f[0] = 0.0f; + dst->f[1] = 0.0f; + dst->f[2] = 0.0f; + dst->f[3] = 0.0f; +} + +static void +micro_str(union tgsi_exec_channel *dst) +{ + dst->f[0] = 1.0f; + dst->f[1] = 1.0f; + dst->f[2] = 1.0f; + dst->f[3] = 1.0f; +} + +static void micro_trunc(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src) { @@ -453,50 +471,12 @@ enum tgsi_exec_datatype { /* * Shorthand locations of various utility registers (_I = Index, _C = Channel) */ -#define TEMP_0_I TGSI_EXEC_TEMP_00000000_I -#define TEMP_0_C TGSI_EXEC_TEMP_00000000_C -#define TEMP_7F_I TGSI_EXEC_TEMP_7FFFFFFF_I -#define TEMP_7F_C TGSI_EXEC_TEMP_7FFFFFFF_C -#define TEMP_80_I TGSI_EXEC_TEMP_80000000_I -#define TEMP_80_C TGSI_EXEC_TEMP_80000000_C -#define TEMP_FF_I TGSI_EXEC_TEMP_FFFFFFFF_I -#define TEMP_FF_C TGSI_EXEC_TEMP_FFFFFFFF_C -#define TEMP_1_I TGSI_EXEC_TEMP_ONE_I -#define TEMP_1_C TGSI_EXEC_TEMP_ONE_C -#define TEMP_2_I TGSI_EXEC_TEMP_TWO_I -#define TEMP_2_C TGSI_EXEC_TEMP_TWO_C -#define TEMP_128_I TGSI_EXEC_TEMP_128_I -#define TEMP_128_C TGSI_EXEC_TEMP_128_C -#define TEMP_M128_I TGSI_EXEC_TEMP_MINUS_128_I -#define TEMP_M128_C TGSI_EXEC_TEMP_MINUS_128_C #define TEMP_KILMASK_I TGSI_EXEC_TEMP_KILMASK_I #define TEMP_KILMASK_C TGSI_EXEC_TEMP_KILMASK_C #define TEMP_OUTPUT_I TGSI_EXEC_TEMP_OUTPUT_I #define TEMP_OUTPUT_C TGSI_EXEC_TEMP_OUTPUT_C #define TEMP_PRIMITIVE_I TGSI_EXEC_TEMP_PRIMITIVE_I #define TEMP_PRIMITIVE_C TGSI_EXEC_TEMP_PRIMITIVE_C -#define TEMP_CC_I TGSI_EXEC_TEMP_CC_I -#define TEMP_CC_C TGSI_EXEC_TEMP_CC_C -#define TEMP_3_I TGSI_EXEC_TEMP_THREE_I -#define TEMP_3_C TGSI_EXEC_TEMP_THREE_C -#define TEMP_HALF_I TGSI_EXEC_TEMP_HALF_I -#define TEMP_HALF_C TGSI_EXEC_TEMP_HALF_C -#define TEMP_R0 TGSI_EXEC_TEMP_R0 -#define TEMP_P0 TGSI_EXEC_TEMP_P0 - -#define IS_CHANNEL_ENABLED(INST, CHAN)\ - ((INST).Dst[0].Register.WriteMask & (1 << (CHAN))) - -#define IS_CHANNEL_ENABLED2(INST, CHAN)\ - ((INST).Dst[1].Register.WriteMask & (1 << (CHAN))) - -#define FOR_EACH_ENABLED_CHANNEL(INST, CHAN)\ - for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)\ - if (IS_CHANNEL_ENABLED( INST, CHAN )) - -#define FOR_EACH_ENABLED_CHANNEL2(INST, CHAN)\ - for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)\ - if (IS_CHANNEL_ENABLED2( INST, CHAN )) /** The execution mask depends on the conditional mask and the loop mask */ @@ -511,6 +491,14 @@ static const union tgsi_exec_channel OneVec = { {1.0f, 1.0f, 1.0f, 1.0f} }; +static const union tgsi_exec_channel P128Vec = { + {128.0f, 128.0f, 128.0f, 128.0f} +}; + +static const union tgsi_exec_channel M128Vec = { + {-128.0f, -128.0f, -128.0f, -128.0f} +}; + /** * Assert that none of the float values in 'chan' are infinite or NaN. @@ -572,8 +560,6 @@ tgsi_exec_set_constant_buffers(struct tgsi_exec_machine *mach, } - - /** * Check if there's a potential src/dst register data dependency when * using SOA execution. @@ -607,18 +593,20 @@ tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst) inst->Dst[0].Register.File) && ((inst->Src[i].Register.Index == inst->Dst[0].Register.Index) || - inst->Src[i].Register.Indirect || - inst->Dst[0].Register.Indirect)) { + inst->Src[i].Register.Indirect || + inst->Dst[0].Register.Indirect)) { /* loop over dest channels */ uint channelsWritten = 0x0; - FOR_EACH_ENABLED_CHANNEL(*inst, chan) { - /* check if we're reading a channel that's been written */ - uint swizzle = tgsi_util_get_full_src_register_swizzle(&inst->Src[i], chan); - if (channelsWritten & (1 << swizzle)) { - return TRUE; - } + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + /* check if we're reading a channel that's been written */ + uint swizzle = tgsi_util_get_full_src_register_swizzle(&inst->Src[i], chan); + if (channelsWritten & (1 << swizzle)) { + return TRUE; + } - channelsWritten |= (1 << chan); + channelsWritten |= (1 << chan); + } } } } @@ -813,18 +801,18 @@ tgsi_exec_machine_create( void ) mach->MaxGeometryShaderOutputs = TGSI_MAX_TOTAL_VERTICES; mach->Predicates = &mach->Temps[TGSI_EXEC_TEMP_P0]; - /* Setup constants. */ + /* Setup constants needed by the SSE2 executor. */ for( i = 0; i < 4; i++ ) { - mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000; - mach->Temps[TEMP_7F_I].xyzw[TEMP_7F_C].u[i] = 0x7FFFFFFF; - mach->Temps[TEMP_80_I].xyzw[TEMP_80_C].u[i] = 0x80000000; - mach->Temps[TEMP_FF_I].xyzw[TEMP_FF_C].u[i] = 0xFFFFFFFF; - mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].f[i] = 1.0f; - mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].f[i] = 2.0f; - mach->Temps[TEMP_128_I].xyzw[TEMP_128_C].f[i] = 128.0f; - mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C].f[i] = -128.0f; - mach->Temps[TEMP_3_I].xyzw[TEMP_3_C].f[i] = 3.0f; - mach->Temps[TEMP_HALF_I].xyzw[TEMP_HALF_C].f[i] = 0.5f; + mach->Temps[TGSI_EXEC_TEMP_00000000_I].xyzw[TGSI_EXEC_TEMP_00000000_C].u[i] = 0x00000000; + mach->Temps[TGSI_EXEC_TEMP_7FFFFFFF_I].xyzw[TGSI_EXEC_TEMP_7FFFFFFF_C].u[i] = 0x7FFFFFFF; + mach->Temps[TGSI_EXEC_TEMP_80000000_I].xyzw[TGSI_EXEC_TEMP_80000000_C].u[i] = 0x80000000; + mach->Temps[TGSI_EXEC_TEMP_FFFFFFFF_I].xyzw[TGSI_EXEC_TEMP_FFFFFFFF_C].u[i] = 0xFFFFFFFF; /* not used */ + mach->Temps[TGSI_EXEC_TEMP_ONE_I].xyzw[TGSI_EXEC_TEMP_ONE_C].f[i] = 1.0f; + mach->Temps[TGSI_EXEC_TEMP_TWO_I].xyzw[TGSI_EXEC_TEMP_TWO_C].f[i] = 2.0f; /* not used */ + mach->Temps[TGSI_EXEC_TEMP_128_I].xyzw[TGSI_EXEC_TEMP_128_C].f[i] = 128.0f; + mach->Temps[TGSI_EXEC_TEMP_MINUS_128_I].xyzw[TGSI_EXEC_TEMP_MINUS_128_C].f[i] = -128.0f; + mach->Temps[TGSI_EXEC_TEMP_THREE_I].xyzw[TGSI_EXEC_TEMP_THREE_C].f[i] = 3.0f; + mach->Temps[TGSI_EXEC_TEMP_HALF_I].xyzw[TGSI_EXEC_TEMP_HALF_C].f[i] = 0.5f; } #ifdef DEBUG @@ -886,27 +874,35 @@ micro_div( } static void -micro_float_clamp(union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src) +micro_rcc(union tgsi_exec_channel *dst, + const union tgsi_exec_channel *src) { uint i; for (i = 0; i < 4; i++) { - if (src->f[i] > 0.0f) { - if (src->f[i] > 1.884467e+019f) + float recip = 1.0f / src->f[i]; + + if (recip > 0.0f) { + if (recip > 1.884467e+019f) { dst->f[i] = 1.884467e+019f; - else if (src->f[i] < 5.42101e-020f) + } + else if (recip < 5.42101e-020f) { dst->f[i] = 5.42101e-020f; - else - dst->f[i] = src->f[i]; + } + else { + dst->f[i] = recip; + } } else { - if (src->f[i] < -1.884467e+019f) + if (recip < -1.884467e+019f) { dst->f[i] = -1.884467e+019f; - else if (src->f[i] > -5.42101e-020f) + } + else if (recip > -5.42101e-020f) { dst->f[i] = -5.42101e-020f; - else - dst->f[i] = src->f[i]; + } + else { + dst->f[i] = recip; + } } } } @@ -958,60 +954,6 @@ micro_mul(union tgsi_exec_channel *dst, dst->f[3] = src0->f[3] * src1->f[3]; } -#if 0 -static void -micro_imul64( - union tgsi_exec_channel *dst0, - union tgsi_exec_channel *dst1, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst1->i[0] = src0->i[0] * src1->i[0]; - dst1->i[1] = src0->i[1] * src1->i[1]; - dst1->i[2] = src0->i[2] * src1->i[2]; - dst1->i[3] = src0->i[3] * src1->i[3]; - dst0->i[0] = 0; - dst0->i[1] = 0; - dst0->i[2] = 0; - dst0->i[3] = 0; -} -#endif - -#if 0 -static void -micro_umul64( - union tgsi_exec_channel *dst0, - union tgsi_exec_channel *dst1, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1 ) -{ - dst1->u[0] = src0->u[0] * src1->u[0]; - dst1->u[1] = src0->u[1] * src1->u[1]; - dst1->u[2] = src0->u[2] * src1->u[2]; - dst1->u[3] = src0->u[3] * src1->u[3]; - dst0->u[0] = 0; - dst0->u[1] = 0; - dst0->u[2] = 0; - dst0->u[3] = 0; -} -#endif - - -#if 0 -static void -micro_movc( - union tgsi_exec_channel *dst, - const union tgsi_exec_channel *src0, - const union tgsi_exec_channel *src1, - const union tgsi_exec_channel *src2 ) -{ - dst->u[0] = src0->u[0] ? src1->u[0] : src2->u[0]; - dst->u[1] = src0->u[1] ? src1->u[1] : src2->u[1]; - dst->u[2] = src0->u[2] ? src1->u[2] : src2->u[2]; - dst->u[3] = src0->u[3] ? src1->u[3] : src2->u[3]; -} -#endif - static void micro_neg( union tgsi_exec_channel *dst, @@ -1607,9 +1549,6 @@ store_dest(struct tgsi_exec_machine *mach, #define FETCH(VAL,INDEX,CHAN)\ fetch_source(mach, VAL, &inst->Src[INDEX], CHAN, TGSI_EXEC_DATA_FLOAT) -#define STORE(VAL,INDEX,CHAN)\ - store_dest(mach, VAL, &inst->Dst[INDEX], inst, CHAN, TGSI_EXEC_DATA_FLOAT) - /** * Execute ARB-style KIL which is predicated by a src register. @@ -1753,7 +1692,7 @@ exec_tex(struct tgsi_exec_machine *mach, union tgsi_exec_channel r[4]; const union tgsi_exec_channel *lod = &ZeroVec; enum tgsi_sampler_control control; - uint chan_index; + uint chan; if (modifier != TEX_MODIFIER_NONE) { FETCH(&r[3], 0, CHAN_W); @@ -1825,8 +1764,10 @@ exec_tex(struct tgsi_exec_machine *mach, assert(0); } - FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) { - STORE(&r[chan_index], 0, chan_index); + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } } } @@ -1836,7 +1777,7 @@ exec_txd(struct tgsi_exec_machine *mach, { const uint unit = inst->Src[3].Register.Index; union tgsi_exec_channel r[4]; - uint chan_index; + uint chan; /* * XXX: This is fake TXD -- the derivatives are not taken into account, yet. @@ -1886,8 +1827,10 @@ exec_txd(struct tgsi_exec_machine *mach, assert(0); } - FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) { - STORE(&r[chan_index], 0, chan_index); + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &r[chan], &inst->Dst[0], inst, chan, TGSI_EXEC_DATA_FLOAT); + } } } @@ -2021,6 +1964,26 @@ exec_declaration(struct tgsi_exec_machine *mach, } } +typedef void (* micro_op)(union tgsi_exec_channel *dst); + +static void +exec_vector(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + micro_op op, + enum tgsi_exec_datatype dst_datatype) +{ + unsigned int chan; + + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + union tgsi_exec_channel dst; + + op(&dst); + store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype); + } + } +} + typedef void (* micro_unary_op)(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src); @@ -2074,6 +2037,27 @@ typedef void (* micro_binary_op)(union tgsi_exec_channel *dst, const union tgsi_exec_channel *src1); static void +exec_scalar_binary(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst, + micro_binary_op op, + enum tgsi_exec_datatype dst_datatype, + enum tgsi_exec_datatype src_datatype) +{ + unsigned int chan; + union tgsi_exec_channel src[2]; + union tgsi_exec_channel dst; + + fetch_source(mach, &src[0], &inst->Src[0], CHAN_X, src_datatype); + fetch_source(mach, &src[1], &inst->Src[1], CHAN_Y, src_datatype); + op(&dst, &src[0], &src[1]); + for (chan = 0; chan < NUM_CHANNELS; chan++) { + if (inst->Dst[0].Register.WriteMask & (1 << chan)) { + store_dest(mach, &dst, &inst->Dst[0], inst, chan, dst_datatype); + } + } +} + +static void exec_vector_binary(struct tgsi_exec_machine *mach, const struct tgsi_full_instruction *inst, micro_binary_op op, @@ -2320,6 +2304,289 @@ exec_nrm3(struct tgsi_exec_machine *mach, } static void +exec_scs(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XY) { + union tgsi_exec_channel arg; + union tgsi_exec_channel result; + + fetch_source(mach, &arg, &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + micro_cos(&result, &arg); + store_dest(mach, &result, &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + micro_sin(&result, &arg); + store_dest(mach, &result, &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + store_dest(mach, &ZeroVec, &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_x2d(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[4]; + union tgsi_exec_channel d[2]; + + fetch_source(mach, &r[0], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT); + fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XZ) { + fetch_source(mach, &r[2], &inst->Src[2], CHAN_X, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[2], &r[2], &r[0]); + fetch_source(mach, &r[3], &inst->Src[2], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[3], &r[3], &r[1]); + micro_add(&r[2], &r[2], &r[3]); + fetch_source(mach, &r[3], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + micro_add(&d[0], &r[2], &r[3]); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_YW) { + fetch_source(mach, &r[2], &inst->Src[2], CHAN_Z, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[2], &r[2], &r[0]); + fetch_source(mach, &r[3], &inst->Src[2], CHAN_W, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[3], &r[3], &r[1]); + micro_add(&r[2], &r[2], &r[3]); + fetch_source(mach, &r[3], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + micro_add(&d[1], &r[2], &r[3]); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + store_dest(mach, &d[0], &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + store_dest(mach, &d[1], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + store_dest(mach, &d[0], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &d[1], &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_rfl(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[9]; + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_XYZ) { + /* r0 = dp3(src0, src0) */ + fetch_source(mach, &r[2], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[0], &r[2], &r[2]); + fetch_source(mach, &r[4], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[8], &r[4], &r[4]); + micro_add(&r[0], &r[0], &r[8]); + fetch_source(mach, &r[6], &inst->Src[0], CHAN_Z, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[8], &r[6], &r[6]); + micro_add(&r[0], &r[0], &r[8]); + + /* r1 = dp3(src0, src1) */ + fetch_source(mach, &r[3], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[1], &r[2], &r[3]); + fetch_source(mach, &r[5], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[8], &r[4], &r[5]); + micro_add(&r[1], &r[1], &r[8]); + fetch_source(mach, &r[7], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT); + micro_mul(&r[8], &r[6], &r[7]); + micro_add(&r[1], &r[1], &r[8]); + + /* r1 = 2 * r1 / r0 */ + micro_add(&r[1], &r[1], &r[1]); + micro_div(&r[1], &r[1], &r[0]); + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + micro_mul(&r[2], &r[2], &r[1]); + micro_sub(&r[2], &r[2], &r[3]); + store_dest(mach, &r[2], &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + micro_mul(&r[4], &r[4], &r[1]); + micro_sub(&r[4], &r[4], &r[5]); + store_dest(mach, &r[4], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + micro_mul(&r[6], &r[6], &r[1]); + micro_sub(&r[6], &r[6], &r[7]); + store_dest(mach, &r[6], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_xpd(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[6]; + union tgsi_exec_channel d[3]; + + fetch_source(mach, &r[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + fetch_source(mach, &r[1], &inst->Src[1], CHAN_Z, TGSI_EXEC_DATA_FLOAT); + + micro_mul(&r[2], &r[0], &r[1]); + + fetch_source(mach, &r[3], &inst->Src[0], CHAN_Z, TGSI_EXEC_DATA_FLOAT); + fetch_source(mach, &r[4], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + + micro_mul(&r[5], &r[3], &r[4] ); + micro_sub(&d[CHAN_X], &r[2], &r[5]); + + fetch_source(mach, &r[2], &inst->Src[1], CHAN_X, TGSI_EXEC_DATA_FLOAT); + + micro_mul(&r[3], &r[3], &r[2]); + + fetch_source(mach, &r[5], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + + micro_mul(&r[1], &r[1], &r[5]); + micro_sub(&d[CHAN_Y], &r[3], &r[1]); + + micro_mul(&r[5], &r[5], &r[4]); + micro_mul(&r[0], &r[0], &r[2]); + micro_sub(&d[CHAN_Z], &r[5], &r[0]); + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + store_dest(mach, &d[CHAN_X], &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + store_dest(mach, &d[CHAN_Y], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + store_dest(mach, &d[CHAN_Z], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_dst(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[2]; + union tgsi_exec_channel d[4]; + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + fetch_source(mach, &r[0], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + fetch_source(mach, &r[1], &inst->Src[1], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + micro_mul(&d[CHAN_Y], &r[0], &r[1]); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + fetch_source(mach, &d[CHAN_Z], &inst->Src[0], CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + fetch_source(mach, &d[CHAN_W], &inst->Src[1], CHAN_W, TGSI_EXEC_DATA_FLOAT); + } + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + store_dest(mach, &d[CHAN_Y], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + store_dest(mach, &d[CHAN_Z], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &d[CHAN_W], &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_log(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[3]; + + fetch_source(mach, &r[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + micro_abs(&r[2], &r[0]); /* r2 = abs(r0) */ + micro_lg2(&r[1], &r[2]); /* r1 = lg2(r2) */ + micro_flr(&r[0], &r[1]); /* r0 = floor(r1) */ + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + store_dest(mach, &r[0], &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + micro_exp2(&r[0], &r[0]); /* r0 = 2 ^ r0 */ + micro_div(&r[0], &r[2], &r[0]); /* r0 = r2 / r0 */ + store_dest(mach, &r[0], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + store_dest(mach, &r[1], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_exp(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[3]; + + fetch_source(mach, &r[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + micro_flr(&r[1], &r[0]); /* r1 = floor(r0) */ + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + micro_exp2(&r[2], &r[1]); /* r2 = 2 ^ r1 */ + store_dest(mach, &r[2], &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + micro_sub(&r[2], &r[0], &r[1]); /* r2 = r0 - r1 */ + store_dest(mach, &r[2], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + micro_exp2(&r[2], &r[0]); /* r2 = 2 ^ r0 */ + store_dest(mach, &r[2], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void +exec_lit(struct tgsi_exec_machine *mach, + const struct tgsi_full_instruction *inst) +{ + union tgsi_exec_channel r[3]; + union tgsi_exec_channel d[3]; + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_X) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_X, TGSI_EXEC_DATA_FLOAT); + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_YZ) { + fetch_source(mach, &r[0], &inst->Src[0], CHAN_X, TGSI_EXEC_DATA_FLOAT); + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Y) { + micro_max(&d[CHAN_Y], &r[0], &ZeroVec); + store_dest(mach, &d[CHAN_Y], &inst->Dst[0], inst, CHAN_Y, TGSI_EXEC_DATA_FLOAT); + } + + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_Z) { + fetch_source(mach, &r[1], &inst->Src[0], CHAN_Y, TGSI_EXEC_DATA_FLOAT); + micro_max(&r[1], &r[1], &ZeroVec); + + fetch_source(mach, &r[2], &inst->Src[0], CHAN_W, TGSI_EXEC_DATA_FLOAT); + micro_min(&r[2], &r[2], &P128Vec); + micro_max(&r[2], &r[2], &M128Vec); + micro_pow(&r[1], &r[1], &r[2]); + micro_lt(&d[CHAN_Z], &ZeroVec, &r[0], &r[1], &ZeroVec); + store_dest(mach, &d[CHAN_Z], &inst->Dst[0], inst, CHAN_Z, TGSI_EXEC_DATA_FLOAT); + } + } + if (inst->Dst[0].Register.WriteMask & TGSI_WRITEMASK_W) { + store_dest(mach, &OneVec, &inst->Dst[0], inst, CHAN_W, TGSI_EXEC_DATA_FLOAT); + } +} + +static void exec_break(struct tgsi_exec_machine *mach) { if (mach->BreakType == TGSI_EXEC_BREAK_INSIDE_LOOP) { @@ -2702,9 +2969,7 @@ exec_instruction( const struct tgsi_full_instruction *inst, int *pc ) { - uint chan_index; union tgsi_exec_channel r[10]; - union tgsi_exec_channel d[8]; (*pc)++; @@ -2718,36 +2983,7 @@ exec_instruction( break; case TGSI_OPCODE_LIT: - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y ) || IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[0], 0, CHAN_X ); - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_max(&d[CHAN_Y], &r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); - } - - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH( &r[1], 0, CHAN_Y ); - micro_max( &r[1], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C] ); - - FETCH( &r[2], 0, CHAN_W ); - micro_min( &r[2], &r[2], &mach->Temps[TEMP_128_I].xyzw[TEMP_128_C] ); - micro_max( &r[2], &r[2], &mach->Temps[TEMP_M128_I].xyzw[TEMP_M128_C] ); - micro_pow( &r[1], &r[1], &r[2] ); - micro_lt(&d[CHAN_Z], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[0], &r[1], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C]); - } - - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) { - STORE(&d[CHAN_Y], 0, CHAN_Y); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - STORE(&d[CHAN_Z], 0, CHAN_Z); - } - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } + exec_lit(mach, inst); break; case TGSI_OPCODE_RCP: @@ -2759,44 +2995,11 @@ exec_instruction( break; case TGSI_OPCODE_EXP: - FETCH( &r[0], 0, CHAN_X ); - micro_flr( &r[1], &r[0] ); /* r1 = floor(r0) */ - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - micro_exp2( &r[2], &r[1] ); /* r2 = 2 ^ r1 */ - STORE( &r[2], 0, CHAN_X ); /* store r2 */ - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_sub( &r[2], &r[0], &r[1] ); /* r2 = r0 - r1 */ - STORE( &r[2], 0, CHAN_Y ); /* store r2 */ - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - micro_exp2( &r[2], &r[0] ); /* r2 = 2 ^ r0 */ - STORE( &r[2], 0, CHAN_Z ); /* store r2 */ - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } + exec_exp(mach, inst); break; case TGSI_OPCODE_LOG: - FETCH( &r[0], 0, CHAN_X ); - micro_abs( &r[2], &r[0] ); /* r2 = abs(r0) */ - micro_lg2( &r[1], &r[2] ); /* r1 = lg2(r2) */ - micro_flr( &r[0], &r[1] ); /* r0 = floor(r1) */ - if (IS_CHANNEL_ENABLED( *inst, CHAN_X )) { - STORE( &r[0], 0, CHAN_X ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - micro_exp2( &r[0], &r[0] ); /* r0 = 2 ^ r0 */ - micro_div( &r[0], &r[2], &r[0] ); /* r0 = r2 / r0 */ - STORE( &r[0], 0, CHAN_Y ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - STORE( &r[1], 0, CHAN_Z ); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } + exec_log(mach, inst); break; case TGSI_OPCODE_MUL: @@ -2816,30 +3019,7 @@ exec_instruction( break; case TGSI_OPCODE_DST: - if (IS_CHANNEL_ENABLED( *inst, CHAN_Y )) { - FETCH( &r[0], 0, CHAN_Y ); - FETCH( &r[1], 1, CHAN_Y); - micro_mul(&d[CHAN_Y], &r[0], &r[1]); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_Z )) { - FETCH(&d[CHAN_Z], 0, CHAN_Z); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - FETCH(&d[CHAN_W], 1, CHAN_W); - } - - if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) { - STORE(&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_X); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) { - STORE(&d[CHAN_Y], 0, CHAN_Y); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - STORE(&d[CHAN_Z], 0, CHAN_Z); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_W)) { - STORE(&d[CHAN_W], 0, CHAN_W); - } + exec_dst(mach, inst); break; case TGSI_OPCODE_MIN: @@ -2903,53 +3083,11 @@ exec_instruction( break; case TGSI_OPCODE_POW: - FETCH(&r[0], 0, CHAN_X); - FETCH(&r[1], 1, CHAN_X); - - micro_pow( &r[0], &r[0], &r[1] ); - - FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) { - STORE( &r[0], 0, chan_index ); - } + exec_scalar_binary(mach, inst, micro_pow, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT); break; case TGSI_OPCODE_XPD: - FETCH(&r[0], 0, CHAN_Y); - FETCH(&r[1], 1, CHAN_Z); - - micro_mul( &r[2], &r[0], &r[1] ); - - FETCH(&r[3], 0, CHAN_Z); - FETCH(&r[4], 1, CHAN_Y); - - micro_mul( &r[5], &r[3], &r[4] ); - micro_sub(&d[CHAN_X], &r[2], &r[5]); - - FETCH(&r[2], 1, CHAN_X); - - micro_mul( &r[3], &r[3], &r[2] ); - - FETCH(&r[5], 0, CHAN_X); - - micro_mul( &r[1], &r[1], &r[5] ); - micro_sub(&d[CHAN_Y], &r[3], &r[1]); - - micro_mul( &r[5], &r[5], &r[4] ); - micro_mul( &r[0], &r[0], &r[2] ); - micro_sub(&d[CHAN_Z], &r[5], &r[0]); - - if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) { - STORE(&d[CHAN_X], 0, CHAN_X); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) { - STORE(&d[CHAN_Y], 0, CHAN_Y); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - STORE(&d[CHAN_Z], 0, CHAN_Z); - } - if (IS_CHANNEL_ENABLED( *inst, CHAN_W )) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } + exec_xpd(mach, inst); break; case TGSI_OPCODE_ABS: @@ -2957,12 +3095,7 @@ exec_instruction( break; case TGSI_OPCODE_RCC: - FETCH(&r[0], 0, CHAN_X); - micro_div(&r[0], &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], &r[0]); - micro_float_clamp(&r[0], &r[0]); - FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) { - STORE(&r[0], 0, chan_index); - } + exec_scalar_unary(mach, inst, micro_rcc, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT); break; case TGSI_OPCODE_DPH: @@ -3006,52 +3139,7 @@ exec_instruction( break; case TGSI_OPCODE_RFL: - if (IS_CHANNEL_ENABLED(*inst, CHAN_X) || - IS_CHANNEL_ENABLED(*inst, CHAN_Y) || - IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - /* r0 = dp3(src0, src0) */ - FETCH(&r[2], 0, CHAN_X); - micro_mul(&r[0], &r[2], &r[2]); - FETCH(&r[4], 0, CHAN_Y); - micro_mul(&r[8], &r[4], &r[4]); - micro_add(&r[0], &r[0], &r[8]); - FETCH(&r[6], 0, CHAN_Z); - micro_mul(&r[8], &r[6], &r[6]); - micro_add(&r[0], &r[0], &r[8]); - - /* r1 = dp3(src0, src1) */ - FETCH(&r[3], 1, CHAN_X); - micro_mul(&r[1], &r[2], &r[3]); - FETCH(&r[5], 1, CHAN_Y); - micro_mul(&r[8], &r[4], &r[5]); - micro_add(&r[1], &r[1], &r[8]); - FETCH(&r[7], 1, CHAN_Z); - micro_mul(&r[8], &r[6], &r[7]); - micro_add(&r[1], &r[1], &r[8]); - - /* r1 = 2 * r1 / r0 */ - micro_add(&r[1], &r[1], &r[1]); - micro_div(&r[1], &r[1], &r[0]); - - if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) { - micro_mul(&r[2], &r[2], &r[1]); - micro_sub(&r[2], &r[2], &r[3]); - STORE(&r[2], 0, CHAN_X); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) { - micro_mul(&r[4], &r[4], &r[1]); - micro_sub(&r[4], &r[4], &r[5]); - STORE(&r[4], 0, CHAN_Y); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - micro_mul(&r[6], &r[6], &r[1]); - micro_sub(&r[6], &r[6], &r[7]); - STORE(&r[6], 0, CHAN_Z); - } - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_W)) { - STORE(&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W); - } + exec_rfl(mach, inst); break; case TGSI_OPCODE_SEQ: @@ -3059,9 +3147,7 @@ exec_instruction( break; case TGSI_OPCODE_SFL: - FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) { - STORE(&mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, chan_index); - } + exec_vector(mach, inst, micro_sfl, TGSI_EXEC_DATA_FLOAT); break; case TGSI_OPCODE_SGT: @@ -3081,9 +3167,7 @@ exec_instruction( break; case TGSI_OPCODE_STR: - FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) { - STORE(&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, chan_index); - } + exec_vector(mach, inst, micro_str, TGSI_EXEC_DATA_FLOAT); break; case TGSI_OPCODE_TEX: @@ -3140,42 +3224,7 @@ exec_instruction( break; case TGSI_OPCODE_X2D: - FETCH(&r[0], 1, CHAN_X); - FETCH(&r[1], 1, CHAN_Y); - if (IS_CHANNEL_ENABLED(*inst, CHAN_X) || - IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - FETCH(&r[2], 2, CHAN_X); - micro_mul(&r[2], &r[2], &r[0]); - FETCH(&r[3], 2, CHAN_Y); - micro_mul(&r[3], &r[3], &r[1]); - micro_add(&r[2], &r[2], &r[3]); - FETCH(&r[3], 0, CHAN_X); - micro_add(&d[CHAN_X], &r[2], &r[3]); - - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y) || - IS_CHANNEL_ENABLED(*inst, CHAN_W)) { - FETCH(&r[2], 2, CHAN_Z); - micro_mul(&r[2], &r[2], &r[0]); - FETCH(&r[3], 2, CHAN_W); - micro_mul(&r[3], &r[3], &r[1]); - micro_add(&r[2], &r[2], &r[3]); - FETCH(&r[3], 0, CHAN_Y); - micro_add(&d[CHAN_Y], &r[2], &r[3]); - - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) { - STORE(&d[CHAN_X], 0, CHAN_X); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) { - STORE(&d[CHAN_Y], 0, CHAN_Y); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Z)) { - STORE(&d[CHAN_X], 0, CHAN_Z); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_W)) { - STORE(&d[CHAN_Y], 0, CHAN_W); - } + exec_x2d(mach, inst); break; case TGSI_OPCODE_ARA: @@ -3283,23 +3332,7 @@ exec_instruction( break; case TGSI_OPCODE_SCS: - if( IS_CHANNEL_ENABLED( *inst, CHAN_X ) || IS_CHANNEL_ENABLED( *inst, CHAN_Y ) ) { - FETCH( &r[0], 0, CHAN_X ); - if (IS_CHANNEL_ENABLED(*inst, CHAN_X)) { - micro_cos(&r[1], &r[0]); - STORE(&r[1], 0, CHAN_X); - } - if (IS_CHANNEL_ENABLED(*inst, CHAN_Y)) { - micro_sin(&r[1], &r[0]); - STORE(&r[1], 0, CHAN_Y); - } - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_Z ) ) { - STORE( &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], 0, CHAN_Z ); - } - if( IS_CHANNEL_ENABLED( *inst, CHAN_W ) ) { - STORE( &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C], 0, CHAN_W ); - } + exec_scs(mach, inst); break; case TGSI_OPCODE_NRM: @@ -3684,14 +3717,6 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach ) mach->Primitives[0] = 0; } - for (i = 0; i < QUAD_SIZE; i++) { - mach->Temps[TEMP_CC_I].xyzw[TEMP_CC_C].u[i] = - (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_X_SHIFT) | - (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_Y_SHIFT) | - (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_Z_SHIFT) | - (TGSI_EXEC_CC_EQ << TGSI_EXEC_CC_W_SHIFT); - } - /* execute declarations (interpolants) */ for (i = 0; i < mach->NumDeclarations; i++) { exec_declaration( mach, mach->Declarations+i ); diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index 9d62c1d7e7e..bd5492e9497 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -131,34 +131,15 @@ struct tgsi_sampler #define TGSI_EXEC_TEMP_PRIMITIVE_I (TGSI_EXEC_NUM_TEMPS + 2) #define TGSI_EXEC_TEMP_PRIMITIVE_C 2 -/* NVIDIA condition code (CC) vector - */ -#define TGSI_EXEC_CC_GT 0x01 -#define TGSI_EXEC_CC_EQ 0x02 -#define TGSI_EXEC_CC_LT 0x04 -#define TGSI_EXEC_CC_UN 0x08 - -#define TGSI_EXEC_CC_X_MASK 0x000000ff -#define TGSI_EXEC_CC_X_SHIFT 0 -#define TGSI_EXEC_CC_Y_MASK 0x0000ff00 -#define TGSI_EXEC_CC_Y_SHIFT 8 -#define TGSI_EXEC_CC_Z_MASK 0x00ff0000 -#define TGSI_EXEC_CC_Z_SHIFT 16 -#define TGSI_EXEC_CC_W_MASK 0xff000000 -#define TGSI_EXEC_CC_W_SHIFT 24 - -#define TGSI_EXEC_TEMP_CC_I (TGSI_EXEC_NUM_TEMPS + 2) -#define TGSI_EXEC_TEMP_CC_C 3 - -#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 3) -#define TGSI_EXEC_TEMP_THREE_C 0 +#define TGSI_EXEC_TEMP_THREE_I (TGSI_EXEC_NUM_TEMPS + 2) +#define TGSI_EXEC_TEMP_THREE_C 3 #define TGSI_EXEC_TEMP_HALF_I (TGSI_EXEC_NUM_TEMPS + 3) -#define TGSI_EXEC_TEMP_HALF_C 1 +#define TGSI_EXEC_TEMP_HALF_C 0 /* execution mask, each value is either 0 or ~0 */ #define TGSI_EXEC_MASK_I (TGSI_EXEC_NUM_TEMPS + 3) -#define TGSI_EXEC_MASK_C 2 +#define TGSI_EXEC_MASK_C 1 /* 4 register buffer for various purposes */ #define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4) diff --git a/src/gallium/drivers/failover/SConscript b/src/gallium/drivers/failover/SConscript index f8e9b1b4911..9347431f4e5 100644 --- a/src/gallium/drivers/failover/SConscript +++ b/src/gallium/drivers/failover/SConscript @@ -10,4 +10,6 @@ failover = env.ConvenienceLibrary( 'fo_context.c', ]) +env.Alias('failover', failover) + Export('failover') diff --git a/src/gallium/drivers/galahad/SConscript b/src/gallium/drivers/galahad/SConscript index b398a3f0615..3f39f99e517 100644 --- a/src/gallium/drivers/galahad/SConscript +++ b/src/gallium/drivers/galahad/SConscript @@ -3,11 +3,13 @@ Import('*') env = env.Clone() galahad = env.ConvenienceLibrary( - target = 'identity', + target = 'galahad', source = [ 'glhd_context.c', 'glhd_objects.c', 'glhd_screen.c', ]) +env.Alias('galahad', galahad) + Export('galahad') diff --git a/src/gallium/drivers/i915/SConscript b/src/gallium/drivers/i915/SConscript index d4bf6fef134..8f5deed64a9 100644 --- a/src/gallium/drivers/i915/SConscript +++ b/src/gallium/drivers/i915/SConscript @@ -2,10 +2,6 @@ Import('*') env = env.Clone() -if msvc: - print 'warning: not building i915g' - Return() - i915 = env.ConvenienceLibrary( target = 'i915', source = [ @@ -34,4 +30,6 @@ i915 = env.ConvenienceLibrary( 'i915_resource_texture.c', ]) +env.Alias('i915', i915) + Export('i915') diff --git a/src/gallium/drivers/i965/SConscript b/src/gallium/drivers/i965/SConscript index 119f914a16d..019af682f68 100644 --- a/src/gallium/drivers/i965/SConscript +++ b/src/gallium/drivers/i965/SConscript @@ -2,10 +2,6 @@ Import('*') env = env.Clone() -if msvc: - print 'warning: not building i965g' - Return(); - i965 = env.ConvenienceLibrary( target = 'i965', source = [ diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index ec30d4d7084..e9374cc6efa 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -1,53 +1,6 @@ LLVMPIPE -- a fork of softpipe that employs LLVM for code generation. -Status -====== - -Done so far is: - - - the whole fragment pipeline is code generated in a single function - - - input interpolation - - - depth testing - - - texture sampling - - 1D/2D/3D/cube maps supported - - all texture wrap modes supported - - all texture filtering modes supported - - perhaps not all texture formats yet supported - - - fragment shader TGSI translation - - same level of support as the TGSI SSE2 exec machine, with the exception - we don't fallback to TGSI interpretation when an unsupported opcode is - found, but just ignore it - - done in SoA layout - - input interpolation also code generated - - - alpha testing - - - blend (including logic ops) - - both in SoA and AoS layouts, but only the former used for now - - - code is generic - - intermediates can be vectors of floats, ubytes, fixed point, etc, and of - any width and length - - not all operations are implemented for these types yet though - -Most mesa/progs/demos/* work. - -To do (probably by this order): - - - code generate stipple and stencil testing - - - translate TGSI control flow instructions, and all other remaining opcodes - - - integrate with the draw module for VS code generation - - - code generate the triangle setup and rasterization - - Requirements ============ @@ -98,7 +51,7 @@ Building To build everything on Linux invoke scons as: - scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=xlib dri=false + scons build=debug libgl-xlib Alternatively, you can build it with GNU make, if you prefer, by invoking it as @@ -108,19 +61,16 @@ but the rest of these instructions assume that scons is used. For windows is everything the except except the winsys: - scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=gdi dri=false + scons build=debug libgl-gdi Using ===== -On Linux, building will create a drop-in alternative for libGL.so. To use it -set the environment variables: - - export LD_LIBRARY_PATH=$PWD/build/linux-x86_64-debug/lib:$LD_LIBRARY_PATH +On Linux, building will create a drop-in alternative for libGL.so into -or + build/foo/gallium/targets/libgl-xlib/libGL.so - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib:$LD_LIBRARY_PATH +To use it set the LD_LIBRARY_PATH environment variable accordingly. For performance evaluation pass debug=no to scons, and use the corresponding lib directory without the "-debug" suffix. @@ -136,7 +86,7 @@ Profiling To profile llvmpipe you should pass the options - scons debug=no profile=yes <same-as-before> + scons build=profile <same-as-before> This will ensure that frame pointers are used both in C and JIT functions, and that no tail call optimizations are done by gcc. @@ -200,5 +150,4 @@ Development Notes interfaces very closely, and appear to be complete enough for code generation. See http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html - for a stand-alone example. - See the llvm-c/Core.h file for reference. + for a stand-alone example. See the llvm-c/Core.h file for reference. diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 49950153a4f..26b258b9569 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -9,8 +9,6 @@ if not env['llvm']: env = env.Clone() -env.Tool('udis86') - env.Append(CPPPATH = ['.']) env.CodeGenerate( @@ -78,6 +76,8 @@ llvmpipe = env.ConvenienceLibrary( lp_tile_soa_os, ]) +env.Alias('llvmpipe', llvmpipe) + if env['platform'] != 'embedded': env = env.Clone() @@ -92,7 +92,7 @@ if env['platform'] != 'embedded': 'sincos', ] - if not msvc: + if not env['msvc']: tests.append('round') for test in tests: diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c b/src/gallium/drivers/llvmpipe/lp_rast.c index d358a983943..decf3bd4499 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast.c +++ b/src/gallium/drivers/llvmpipe/lp_rast.c @@ -485,8 +485,11 @@ static void lp_rast_end_query(struct lp_rasterizer_task *task, const union lp_rast_cmd_arg arg) { - task->query->count[task->thread_index] += task->vis_counter; - task->query = NULL; + assert(task->query); + if (task->query) { + task->query->count[task->thread_index] += task->vis_counter; + task->query = NULL; + } } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_line.c b/src/gallium/drivers/llvmpipe/lp_setup_line.c index 827413bb33e..29c231714e1 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_line.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_line.c @@ -569,7 +569,10 @@ try_setup_line( struct lp_setup_context *setup, return TRUE; } - u_rect_find_intersection(&setup->draw_region, &bbox); + /* Can safely discard negative regions: + */ + bbox.x0 = MAX2(bbox.x0, 0); + bbox.y0 = MAX2(bbox.y0, 0); line = lp_setup_alloc_triangle(scene, key->num_inputs, @@ -680,24 +683,26 @@ try_setup_line( struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 8) { + const struct u_rect *scissor = &setup->scissor; + plane[4].dcdx = -1; plane[4].dcdy = 0; - plane[4].c = 1-bbox.x0; + plane[4].c = 1-scissor->x0; plane[4].eo = 1; plane[5].dcdx = 1; plane[5].dcdy = 0; - plane[5].c = bbox.x1+1; + plane[5].c = scissor->x1+1; plane[5].eo = 0; plane[6].dcdx = 0; plane[6].dcdy = 1; - plane[6].c = 1-bbox.y0; + plane[6].c = 1-scissor->y0; plane[6].eo = 1; plane[7].dcdx = 0; plane[7].dcdy = -1; - plane[7].c = bbox.y1+1; + plane[7].c = scissor->y1+1; plane[7].eo = 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index 4ab0b72a574..bfb6bf277bd 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -295,7 +295,12 @@ do_triangle_ccw(struct lp_setup_context *setup, return TRUE; } - u_rect_find_intersection(&setup->draw_region, &bbox); + /* Can safely discard negative regions, but need to keep hold of + * information about when the triangle extends past screen + * boundaries. See trimmed_box in lp_setup_bin_triangle(). + */ + bbox.x0 = MAX2(bbox.x0, 0); + bbox.y0 = MAX2(bbox.y0, 0); tri = lp_setup_alloc_triangle(scene, key->num_inputs, @@ -501,24 +506,26 @@ do_triangle_ccw(struct lp_setup_context *setup, * these planes elsewhere. */ if (nr_planes == 7) { + const struct u_rect *scissor = &setup->scissor; + plane[3].dcdx = -1; plane[3].dcdy = 0; - plane[3].c = 1-bbox.x0; + plane[3].c = 1-scissor->x0; plane[3].eo = 1; plane[4].dcdx = 1; plane[4].dcdy = 0; - plane[4].c = bbox.x1+1; + plane[4].c = scissor->x1+1; plane[4].eo = 0; plane[5].dcdx = 0; plane[5].dcdy = 1; - plane[5].c = 1-bbox.y0; + plane[5].c = 1-scissor->y0; plane[5].eo = 1; plane[6].dcdx = 0; plane[6].dcdy = -1; - plane[6].c = bbox.y1+1; + plane[6].c = scissor->y1+1; plane[6].eo = 0; } @@ -559,6 +566,7 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int nr_planes ) { struct lp_scene *scene = setup->scene; + struct u_rect trimmed_box = *bbox; int i; /* What is the largest power-of-two boundary this triangle crosses: @@ -572,6 +580,13 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, int sz = floor_pot((bbox->x1 - (bbox->x0 & ~3)) | (bbox->y1 - (bbox->y0 & ~3))); + /* Now apply scissor, etc to the bounding box. Could do this + * earlier, but it confuses the logic for tri-16 and would force + * the rasterizer to also respect scissor, etc, just for the rare + * cases where a small triangle extends beyond the scissor. + */ + u_rect_find_intersection(&setup->draw_region, &trimmed_box); + /* Determine which tile(s) intersect the triangle's bounding box */ if (dx < TILE_SIZE) @@ -626,15 +641,16 @@ lp_setup_bin_triangle( struct lp_setup_context *setup, struct lp_rast_plane *plane = GET_PLANES(tri); int c[MAX_PLANES]; int ei[MAX_PLANES]; + int eo[MAX_PLANES]; int xstep[MAX_PLANES]; int ystep[MAX_PLANES]; int x, y; - int ix0 = bbox->x0 / TILE_SIZE; - int iy0 = bbox->y0 / TILE_SIZE; - int ix1 = bbox->x1 / TILE_SIZE; - int iy1 = bbox->y1 / TILE_SIZE; + int ix0 = trimmed_box.x0 / TILE_SIZE; + int iy0 = trimmed_box.y0 / TILE_SIZE; + int ix1 = trimmed_box.x1 / TILE_SIZE; + int iy1 = trimmed_box.y1 / TILE_SIZE; for (i = 0; i < nr_planes; i++) { c[i] = (plane[i].c + @@ -799,6 +815,16 @@ static void triangle_both( struct lp_setup_context *setup, { float area = calc_area(v0, v1, v2); + if (0) { + assert(!util_is_inf_or_nan(v0[0][0])); + assert(!util_is_inf_or_nan(v0[0][1])); + assert(!util_is_inf_or_nan(v1[0][0])); + assert(!util_is_inf_or_nan(v1[0][1])); + assert(!util_is_inf_or_nan(v2[0][0])); + assert(!util_is_inf_or_nan(v2[0][1])); + assert(!util_is_inf_or_nan(area)); + } + if (area > 0.0f) retry_triangle_ccw( setup, v0, v1, v2, setup->ccw_is_frontface ); else if (area < 0.0f) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 9fbedac165f..48971510f21 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -761,11 +761,6 @@ generate_fragment(struct llvmpipe_screen *screen, } } -#ifdef PIPE_ARCH_X86 - /* Avoid corrupting the FPU stack on 32bit OSes. */ - lp_build_intrinsic(builder, "llvm.x86.mmx.emms", LLVMVoidType(), NULL, 0); -#endif - LLVMBuildRetVoid(builder); LLVMDisposeBuilder(builder); @@ -1067,11 +1062,11 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs) draw_flush(llvmpipe->draw); + llvmpipe->fs = (struct lp_fragment_shader *) fs; + draw_bind_fragment_shader(llvmpipe->draw, (llvmpipe->fs ? llvmpipe->fs->draw_data : NULL)); - llvmpipe->fs = fs; - llvmpipe->dirty |= LP_NEW_FS; } diff --git a/src/gallium/drivers/nv50/nv50_shader_state.c b/src/gallium/drivers/nv50/nv50_shader_state.c index 6c41e8f4561..306aa81d985 100644 --- a/src/gallium/drivers/nv50/nv50_shader_state.c +++ b/src/gallium/drivers/nv50/nv50_shader_state.c @@ -39,6 +39,9 @@ nv50_transfer_constbuf(struct nv50_context *nv50, uint32_t *map; unsigned count, start; + if (buf == NULL) + return; + map = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &transfer); if (!map) return; diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 875b3a96ca6..f3ed4ad5bdd 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -78,6 +78,10 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLAMP: return 0; // TODO: implement depth clamp + case PIPE_CAP_PRIMITIVE_RESTART: + return 0; // TODO: implement primitive restart + case PIPE_CAP_SHADER_STENCIL_EXPORT: + return 0; default: NOUVEAU_ERR("Warning: unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/r300/SConscript b/src/gallium/drivers/r300/SConscript index bf023daaa56..b49db937994 100644 --- a/src/gallium/drivers/r300/SConscript +++ b/src/gallium/drivers/r300/SConscript @@ -39,5 +39,7 @@ r300 = env.ConvenienceLibrary( 'r300_transfer.c', ] + r300compiler) + r300compiler +env.Alias('r300', r300) + Export('r300') diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 91a374a5838..0ac4e4c6f12 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -176,12 +176,12 @@ static void r300_clear(struct pipe_context* pipe, fb->zsbuf ? r300_texture(fb->zsbuf->texture) : NULL; uint32_t width = fb->width; uint32_t height = fb->height; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); uint32_t hyperz_dcv = hyperz->zb_depthclearvalue; /* Enable fast Z clear. * The zbuffer must be in micro-tiled mode, otherwise it locks up. */ - if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && has_hyperz) { + if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) && can_hyperz) { hyperz_dcv = hyperz->zb_depthclearvalue = r300_depth_clear_value(fb->zsbuf->format, depth, stencil); diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 624dadd07d7..fb099e2a7d0 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -184,7 +184,7 @@ static void r300_setup_atoms(struct r300_context* r300) boolean has_tcl = r300->screen->caps.has_tcl; boolean drm_2_3_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_3_0); boolean drm_2_6_0 = r300->rws->get_value(r300->rws, R300_VID_DRM_2_6_0); - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); boolean has_hiz_ram = r300->screen->caps.hiz_ram > 0; /* Create the actual atom list. @@ -240,7 +240,7 @@ static void r300_setup_atoms(struct r300_context* r300) /* TX. */ R300_INIT_ATOM(texture_cache_inval, 2); R300_INIT_ATOM(textures_state, 0); - if (has_hyperz) { + if (can_hyperz) { /* HiZ Clear */ if (has_hiz_ram) R300_INIT_ATOM(hiz_clear, 0); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 3a1085d2dc5..c187f115da4 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -358,7 +358,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; struct r300_surface* surf; unsigned i; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); CS_LOCALS(r300); BEGIN_CS(size); @@ -411,7 +411,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain); - if (has_hyperz) { + if (can_hyperz) { uint32_t surf_pitch; struct r300_texture *tex; int level = surf->base.level; diff --git a/src/gallium/drivers/r300/r300_hyperz.c b/src/gallium/drivers/r300/r300_hyperz.c index eb5b0c36f8f..79f7f8abe9b 100644 --- a/src/gallium/drivers/r300/r300_hyperz.c +++ b/src/gallium/drivers/r300/r300_hyperz.c @@ -44,10 +44,10 @@ static bool r300_get_sc_hz_max(struct r300_context *r300) { struct r300_dsa_state *dsa_state = r300->dsa_state.state; - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; int ret = R300_SC_HYPERZ_MIN; - if (func >= 4 && func <= 7) + if (func >= R300_ZS_GEQUAL && func <= R300_ZS_ALWAYS) ret = R300_SC_HYPERZ_MAX; return ret; } @@ -55,23 +55,26 @@ static bool r300_get_sc_hz_max(struct r300_context *r300) static bool r300_zfunc_same_direction(int func1, int func2) { /* func1 is less/lessthan */ - if (func1 == 1 || func1 == 2) - if (func2 == 3 || func2 == 4 || func2 == 5) + if ((func1 == R300_ZS_LESS || func1 == R300_ZS_LEQUAL) && + (func2 == R300_ZS_EQUAL || func2 == R300_ZS_GEQUAL || + func2 == R300_ZS_GREATER)) return FALSE; - if (func2 == 1 || func2 == 2) - if (func1 == 4 || func1 == 5) + /* func1 is greater/greaterthan */ + if ((func1 == R300_ZS_GEQUAL || func1 == R300_ZS_GREATER) && + (func2 == R300_ZS_LESS || func2 == R300_ZS_LEQUAL)) return FALSE; + return TRUE; } - + static int r300_get_hiz_min(struct r300_context *r300) { struct r300_dsa_state *dsa_state = r300->dsa_state.state; - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; int ret = R300_HIZ_MIN; - if (func == 1 || func == 2) + if (func == R300_ZS_LESS || func == R300_ZS_LEQUAL) ret = R300_HIZ_MAX; return ret; } @@ -112,13 +115,16 @@ static boolean r300_can_hiz(struct r300_context *r300) } /* depth comparison function - if just cleared save and return okay */ if (z->current_func == -1) { - int func = dsa_state->z_stencil_control & 0x7; + int func = dsa_state->z_stencil_control & R300_ZS_MASK; if (func != 0 && func != 7) - z->current_func = dsa_state->z_stencil_control & 0x7; + z->current_func = dsa_state->z_stencil_control & R300_ZS_MASK; } else { /* simple don't change */ - if (!r300_zfunc_same_direction(z->current_func, (dsa_state->z_stencil_control & 0x7))) { - DBG(r300, DBG_HYPERZ, "z func changed direction - disabling hyper-z %d -> %d\n", z->current_func, dsa_state->z_stencil_control); + if (!r300_zfunc_same_direction(z->current_func, + (dsa_state->z_stencil_control & R300_ZS_MASK))) { + DBG(r300, DBG_HYPERZ, + "z func changed direction - disabling hyper-z %d -> %d\n", + z->current_func, dsa_state->z_stencil_control); return FALSE; } } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index d445df408dd..1d59e38aac5 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -44,31 +44,31 @@ static const char* r300_get_vendor(struct pipe_screen* pscreen) } static const char* chip_families[] = { - "R300", - "R350", - "R360", - "RV350", - "RV370", - "RV380", - "R420", - "R423", - "R430", - "R480", - "R481", - "RV410", - "RS400", - "RC410", - "RS480", - "RS482", - "RS600", - "RS690", - "RS740", - "RV515", - "R520", - "RV530", - "R580", - "RV560", - "RV570" + "ATI R300", + "ATI R350", + "ATI R360", + "ATI RV350", + "ATI RV370", + "ATI RV380", + "ATI R420", + "ATI R423", + "ATI R430", + "ATI R480", + "ATI R481", + "ATI RV410", + "ATI RS400", + "ATI RC410", + "ATI RS480", + "ATI RS482", + "ATI RS600", + "ATI RS690", + "ATI RS740", + "ATI RV515", + "ATI R520", + "ATI RV530", + "ATI R580", + "ATI RV560", + "ATI RV570" }; static const char* r300_get_name(struct pipe_screen* pscreen) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f2479a994c8..bd08bf2d3fd 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -684,7 +684,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); /* What is marked as dirty depends on the enum r300_fb_state_change. */ r300->gpu_flush.dirty = TRUE; @@ -703,7 +703,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, r300->fb_state.size += 10; else if (state->zsbuf) { r300->fb_state.size += 10; - if (has_hyperz) + if (can_hyperz) r300->fb_state.size += r300->screen->caps.hiz_ram ? 8 : 4; } @@ -717,7 +717,7 @@ static void struct r300_context* r300 = r300_context(pipe); struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state; struct pipe_framebuffer_state *old_state = r300->fb_state.state; - boolean has_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); + boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; int blocksize; @@ -764,7 +764,7 @@ static void zbuffer_bpp = 24; break; } - if (has_hyperz) { + if (can_hyperz) { struct r300_surface *zs_surf = r300_surface(state->zsbuf); struct r300_texture *tex; int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44; @@ -1789,7 +1789,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, { struct r300_context* r300 = r300_context(pipe); struct r300_constant_buffer *cbuf; - uint32_t *mapped = r300_buffer(buf)->user_buffer; + uint32_t *mapped; switch (shader) { case PIPE_SHADER_VERTEX: diff --git a/src/gallium/drivers/r600/SConscript b/src/gallium/drivers/r600/SConscript index bf0ad8571ba..3fc1fa94c27 100644 --- a/src/gallium/drivers/r600/SConscript +++ b/src/gallium/drivers/r600/SConscript @@ -25,10 +25,14 @@ r600 = env.ConvenienceLibrary( 'r600_resource.c', 'r600_shader.c', 'r600_state.c', + 'r600_state_common.c', 'r600_texture.c', + 'r600_translate.c', 'r700_asm.c', 'evergreen_state.c', 'eg_asm.c', ]) +env.Alias('r600', r600) + Export('r600') diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index be81c28b43f..59641976403 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -473,7 +473,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - R600_ERR("unsupported color format %d\n", format); + //R600_ERR("unsupported color format %d\n", format); return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 72223485067..4725b5e75e2 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -281,14 +281,21 @@ static void *evergreen_create_rs_state(struct pipe_context *ctx, tmp = (unsigned)(state->point_size * 8.0); r600_pipe_state_add_reg(rstate, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A04_PA_SU_POINT_MINMAX, 0x80000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, 0x00000008, 0xFFFFFFFF, NULL); + + tmp = (unsigned)state->line_width * 8; + r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C18_PA_CL_GB_HORZ_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028B7C_PA_SU_POLY_OFFSET_CLAMP, 0x0, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, 0x00000005, 0xFFFFFFFF, NULL); + + r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, + S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_02820C_PA_SC_CLIPRECT_RULE, clip_rule, 0xFFFFFFFF, NULL); return rstate; } @@ -826,6 +833,13 @@ static void evergreen_set_constant_buffer(struct pipe_context *ctx, uint shader, struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer = (struct r600_resource*)buffer; + /* Note that the state tracker can unbind constant buffers by + * passing NULL here. + */ + if (buffer == NULL) { + return; + } + switch (shader) { case PIPE_SHADER_VERTEX: rctx->vs_const_buffer.nregs = 0; diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index 8e96f9355e6..a337916c098 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -1636,6 +1636,9 @@ #define R_028980_ALU_CONST_CACHE_VS_0 0x00028980 #define R_028A04_PA_SU_POINT_MINMAX 0x00028A04 #define R_028A08_PA_SU_LINE_CNTL 0x00028A08 +#define S_028A08_WIDTH(x) (((x) & 0xFFFF) << 0) +#define G_028A08_WIDTH(x) (((x) >> 0) & 0xFFFF) +#define C_028A08_WIDTH 0xFFFF0000 #define R_028A10_VGT_OUTPUT_PATH_CNTL 0x00028A10 #define R_028A14_VGT_HOS_CNTL 0x00028A14 #define R_028A18_VGT_HOS_MAX_TESS_LEVEL 0x00028A18 @@ -1687,6 +1690,9 @@ #define R_028C00_PA_SC_LINE_CNTL 0x00028C00 #define R_028C04_PA_SC_AA_CONFIG 0x00028C04 #define R_028C08_PA_SU_VTX_CNTL 0x00028C08 +#define S_028C08_PIX_CENTER_HALF(x) (((x) & 0x1) << 0) +#define G_028C08_PIX_CENTER_HALF(x) (((x) >> 0) & 0x1) +#define C_028C08_PIX_CENTER_HALF 0xFFFFFFFE #define R_028C0C_PA_CL_GB_VERT_CLIP_ADJ 0x00028C0C #define R_028C10_PA_CL_GB_VERT_DISC_ADJ 0x00028C10 #define R_028C14_PA_CL_GB_HORZ_CLIP_ADJ 0x00028C14 diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index 62d983269f5..17858b2d381 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -43,6 +43,7 @@ typedef uint16_t u16; typedef uint8_t u8; struct radeon; +struct winsys_handle; enum radeon_family { CHIP_UNKNOWN, @@ -112,13 +113,16 @@ struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon); /* r600_bo.c */ struct r600_bo; struct r600_bo *r600_bo(struct radeon *radeon, - unsigned size, unsigned alignment, unsigned usage); + unsigned size, unsigned alignment, + unsigned binding, unsigned usage); struct r600_bo *r600_bo_handle(struct radeon *radeon, unsigned handle, unsigned *array_mode); void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx); void r600_bo_unmap(struct radeon *radeon, struct r600_bo *bo); void r600_bo_reference(struct radeon *radeon, struct r600_bo **dst, struct r600_bo *src); +boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo, + unsigned stride, struct winsys_handle *whandle); static INLINE unsigned r600_bo_offset(struct r600_bo *bo) { return 0; diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 455aa2e81f6..ed97b6e69a3 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -38,32 +38,6 @@ extern struct u_resource_vtbl r600_buffer_vtbl; -u32 r600_domain_from_usage(unsigned usage) -{ - u32 domain = RADEON_GEM_DOMAIN_GTT; - - if (usage & PIPE_BIND_RENDER_TARGET) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_DEPTH_STENCIL) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - if (usage & PIPE_BIND_SAMPLER_VIEW) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - /* also need BIND_BLIT_SOURCE/DESTINATION ? */ - if (usage & PIPE_BIND_VERTEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_INDEX_BUFFER) { - domain |= RADEON_GEM_DOMAIN_GTT; - } - if (usage & PIPE_BIND_CONSTANT_BUFFER) { - domain |= RADEON_GEM_DOMAIN_VRAM; - } - - return domain; -} struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) @@ -85,8 +59,7 @@ struct pipe_resource *r600_buffer_create(struct pipe_screen *screen, rbuffer->r.base.b.screen = screen; rbuffer->r.base.vtbl = &r600_buffer_vtbl; rbuffer->r.size = rbuffer->r.base.b.width0; - rbuffer->r.domain = r600_domain_from_usage(rbuffer->r.base.b.bind); - bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind); + bo = r600_bo((struct radeon*)screen->winsys, rbuffer->r.base.b.width0, alignment, rbuffer->r.base.b.bind, rbuffer->r.base.b.usage); if (bo == NULL) { FREE(rbuffer); return NULL; @@ -156,8 +129,9 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe, r600_bo_reference((struct radeon*)pipe->winsys, &rbuffer->r.bo, NULL); rbuffer->num_ranges = 0; rbuffer->r.bo = r600_bo((struct radeon*)pipe->winsys, - rbuffer->r.base.b.width0, 0, - rbuffer->r.base.b.bind); + rbuffer->r.base.b.width0, 0, + rbuffer->r.base.b.bind, + rbuffer->r.base.b.usage); break; } } diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 87ec8cd2e83..8a62d646d3a 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -78,13 +78,16 @@ static void r600_destroy_context(struct pipe_context *context) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)context; + rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush); + r600_context_fini(&rctx->ctx); + + util_blitter_destroy(rctx->blitter); + for (int i = 0; i < R600_PIPE_NSTATES; i++) { free(rctx->states[i]); } - util_blitter_destroy(rctx->blitter); - u_upload_destroy(rctx->upload_vb); u_upload_destroy(rctx->upload_ib); @@ -219,24 +222,24 @@ static const char* r600_get_vendor(struct pipe_screen* pscreen) static const char *r600_get_family_name(enum radeon_family family) { switch(family) { - case CHIP_R600: return "R600"; - case CHIP_RV610: return "RV610"; - case CHIP_RV630: return "RV630"; - case CHIP_RV670: return "RV670"; - case CHIP_RV620: return "RV620"; - case CHIP_RV635: return "RV635"; - case CHIP_RS780: return "RS780"; - case CHIP_RS880: return "RS880"; - case CHIP_RV770: return "RV770"; - case CHIP_RV730: return "RV730"; - case CHIP_RV710: return "RV710"; - case CHIP_RV740: return "RV740"; - case CHIP_CEDAR: return "CEDAR"; - case CHIP_REDWOOD: return "REDWOOD"; - case CHIP_JUNIPER: return "JUNIPER"; - case CHIP_CYPRESS: return "CYPRESS"; - case CHIP_HEMLOCK: return "HEMLOCK"; - default: return "unknown"; + case CHIP_R600: return "AMD R600"; + case CHIP_RV610: return "AMD RV610"; + case CHIP_RV630: return "AMD RV630"; + case CHIP_RV670: return "AMD RV670"; + case CHIP_RV620: return "AMD RV620"; + case CHIP_RV635: return "AMD RV635"; + case CHIP_RS780: return "AMD RS780"; + case CHIP_RS880: return "AMD RS880"; + case CHIP_RV770: return "AMD RV770"; + case CHIP_RV730: return "AMD RV730"; + case CHIP_RV710: return "AMD RV710"; + case CHIP_RV740: return "AMD RV740"; + case CHIP_CEDAR: return "AMD CEDAR"; + case CHIP_REDWOOD: return "AMD REDWOOD"; + case CHIP_JUNIPER: return "AMD JUNIPER"; + case CHIP_CYPRESS: return "AMD CYPRESS"; + case CHIP_HEMLOCK: return "AMD HEMLOCK"; + default: return "AMD unknown"; } } @@ -274,6 +277,7 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* Unsupported features (boolean caps). */ case PIPE_CAP_TIMER_QUERY: case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ return 0; @@ -429,6 +433,9 @@ static void r600_destroy_screen(struct pipe_screen* pscreen) if (rscreen == NULL) return; + + radeon_decref(rscreen->radeon); + FREE(rscreen); } diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h index d152285815c..7a2d1f44122 100644 --- a/src/gallium/drivers/r600/r600_resource.h +++ b/src/gallium/drivers/r600/r600_resource.h @@ -35,7 +35,7 @@ struct r600_transfer { /* Buffer transfer. */ struct pipe_transfer *buffer_transfer; unsigned offset; - struct pipe_resource *linear_texture; + struct pipe_resource *staging_texture; }; /* This gets further specialized into either buffer or texture @@ -45,8 +45,6 @@ struct r600_transfer { struct r600_resource { struct u_resource base; struct r600_bo *bo; - u32 domain; - u32 flink; u32 size; }; @@ -68,9 +66,6 @@ struct r600_resource_texture { void r600_init_screen_resource_functions(struct pipe_screen *screen); -/* r600_buffer */ -u32 r600_domain_from_usage(unsigned usage); - /* r600_texture */ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ); diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 4106587398b..f6153c0e80f 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -218,7 +218,7 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s /* copy new shader */ if (shader->bo == NULL) { - shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0); + shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0); if (shader->bo == NULL) { return -ENOMEM; } @@ -2663,7 +2663,18 @@ static int tgsi_r600_arl(struct r600_shader_ctx *ctx) int r; memset(&alu, 0, sizeof(struct r600_bc_alu)); - alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR; + switch (inst->Instruction.Opcode) { + case TGSI_OPCODE_ARL: + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR; + break; + case TGSI_OPCODE_ARR: + alu.inst = V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA; + break; + default: + assert(0); + return -1; + } + r = tgsi_src(ctx, &inst->Src[0], &alu.src[0]); if (r) @@ -3070,7 +3081,7 @@ static struct r600_shader_tgsi_instruction r600_shader_tgsi_instruction[] = { {TGSI_OPCODE_UP4UB, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_X2D, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_ARA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, - {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_ARR, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_r600_arl}, {TGSI_OPCODE_BRA, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_CAL, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, {TGSI_OPCODE_RET, 0, V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index b3e0d493217..54cc79b1549 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -469,12 +469,17 @@ static void *r600_create_rs_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028A00_PA_SU_POINT_SIZE, S_028A00_HEIGHT(tmp) | S_028A00_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A04_PA_SU_POINT_MINMAX, 0x80000000, 0xFFFFFFFF, NULL); - tmp = (unsigned)(state->line_width * 8.0); + tmp = (unsigned)state->line_width * 8; r600_pipe_state_add_reg(rstate, R_028A08_PA_SU_LINE_CNTL, S_028A08_WIDTH(tmp), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A0C_PA_SC_LINE_STIPPLE, 0x00000005, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028A48_PA_SC_MPASS_PS_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C00_PA_SC_LINE_CNTL, 0x00000400, 0xFFFFFFFF, NULL); + + r600_pipe_state_add_reg(rstate, R_028C08_PA_SU_VTX_CNTL, + S_028C08_PIX_CENTER_HALF(state->gl_rasterization_rules), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0x3F800000, 0xFFFFFFFF, NULL); @@ -1018,6 +1023,13 @@ static void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_resource *rbuffer = (struct r600_resource*)buffer; + /* Note that the state tracker can unbind constant buffers by + * passing NULL here. + */ + if (buffer == NULL) { + return; + } + switch (shader) { case PIPE_SHADER_VERTEX: rctx->vs_const_buffer.nregs = 0; diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 1c1978f8abb..1be5b156d35 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -472,7 +472,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format) case PIPE_FORMAT_UYVY: case PIPE_FORMAT_YUYV: default: - R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); + //R600_ERR("unsupported color format %d %s\n", format, util_format_name(format)); return ~0; /* Unsupported. */ } } diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 4ebd5b754b3..e719f7fb983 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -31,6 +31,7 @@ #include <util/u_inlines.h> #include <util/u_memory.h> #include "state_tracker/drm_driver.h" +#include "pipebuffer/pb_buffer.h" #include "r600_pipe.h" #include "r600_resource.h" #include "r600_state_inlines.h" @@ -39,8 +40,8 @@ extern struct u_resource_vtbl r600_texture_vtbl; -/* Copy from a tiled texture to a detiled one. */ -static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) +/* Copy from a full GPU texture to a transfer's staging one. */ +static void r600_copy_to_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; @@ -48,15 +49,15 @@ static void r600_copy_from_tiled_texture(struct pipe_context *ctx, struct r600_t subdst.face = 0; subdst.level = 0; - ctx->resource_copy_region(ctx, rtransfer->linear_texture, + ctx->resource_copy_region(ctx, rtransfer->staging_texture, subdst, 0, 0, 0, texture, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, transfer->box.width, transfer->box.height); } -/* Copy from a detiled texture to a tiled one. */ -static void r600_copy_into_tiled_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) +/* Copy from a transfer's staging texture to a full GPU one. */ +static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600_transfer *rtransfer) { struct pipe_transfer *transfer = (struct pipe_transfer*)rtransfer; struct pipe_resource *texture = transfer->resource; @@ -66,7 +67,7 @@ static void r600_copy_into_tiled_texture(struct pipe_context *ctx, struct r600_t subsrc.level = 0; ctx->resource_copy_region(ctx, texture, transfer->sr, transfer->box.x, transfer->box.y, transfer->box.z, - rtransfer->linear_texture, subsrc, + rtransfer->staging_texture, subsrc, 0, 0, 0, transfer->box.width, transfer->box.height); @@ -168,6 +169,10 @@ static unsigned r600_texture_get_stride(struct pipe_screen *screen, stride = util_format_get_stride(ptex->format, width); if (chipc == EVERGREEN) stride = align(stride, 512); + + if (ptex->bind & PIPE_BIND_RENDER_TARGET) + stride = align(stride, 512); + return stride; } @@ -283,7 +288,6 @@ r600_texture_create_object(struct pipe_screen *screen, pipe_reference_init(&resource->base.b.reference, 1); resource->base.b.screen = screen; resource->bo = bo; - resource->domain = r600_domain_from_usage(resource->base.b.bind); rtex->pitch_override = pitch_in_bytes_override; if (array_mode) @@ -293,7 +297,7 @@ r600_texture_create_object(struct pipe_screen *screen, resource->size = rtex->size; if (!resource->bo) { - resource->bo = r600_bo(radeon, rtex->size, 4096, 0); + resource->bo = r600_bo(radeon, rtex->size, 4096, base->bind, base->usage); if (!resource->bo) { FREE(rtex); return NULL; @@ -306,8 +310,14 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, const struct pipe_resource *templ) { unsigned array_mode = 0; + static int force_tiling = -1; - if (debug_get_bool_option("R600_FORCE_TILING", FALSE)) { + /* Would like some magic "get_bool_option_once" routine. + */ + if (force_tiling == -1) + force_tiling = debug_get_bool_option("R600_FORCE_TILING", FALSE); + + if (force_tiling) { if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) && !(templ->bind & PIPE_BIND_SCANOUT)) { array_mode = V_038000_ARRAY_2D_TILED_THIN1; @@ -335,6 +345,18 @@ static void r600_texture_destroy(struct pipe_screen *screen, FREE(rtex); } +static boolean r600_texture_get_handle(struct pipe_screen* screen, + struct pipe_resource *ptex, + struct winsys_handle *whandle) +{ + struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex; + struct r600_resource *resource = &rtex->resource; + struct radeon *radeon = (struct radeon *)screen->winsys; + + return r600_bo_get_winsys_handle(radeon, resource->bo, + rtex->pitch_in_bytes[0], whandle); +} + static struct pipe_surface *r600_get_tex_surface(struct pipe_screen *screen, struct pipe_resource *texture, unsigned face, unsigned level, @@ -434,10 +456,59 @@ int r600_texture_depth_flush(struct pipe_context *ctx, } out: + /* XXX: only do this if the depth texture has actually changed: + */ r600_blit_uncompress_depth_ptr(ctx, rtex); return 0; } +/* Needs adjustment for pixelformat: + */ +static INLINE unsigned u_box_volume( const struct pipe_box *box ) +{ + return box->width * box->depth * box->height; +}; + + +/* Figure out whether u_blitter will fallback to a transfer operation. + * If so, don't use a staging resource. + */ +static boolean permit_hardware_blit(struct pipe_screen *screen, + struct pipe_resource *res) +{ + unsigned bind; + + if (util_format_is_depth_or_stencil(res->format)) + bind = PIPE_BIND_DEPTH_STENCIL; + else + bind = PIPE_BIND_RENDER_TARGET; + + /* See r600_resource_copy_region: there is something wrong + * with depth resource copies at the moment so avoid them for + * now. + */ + if (util_format_get_component_bits(res->format, + UTIL_FORMAT_COLORSPACE_ZS, + 0) != 0) + return FALSE; + + if (!screen->is_format_supported(screen, + res->format, + res->target, + res->nr_samples, + bind, 0)) + return FALSE; + + if (!screen->is_format_supported(screen, + res->format, + res->target, + res->nr_samples, + PIPE_BIND_SAMPLER_VIEW, 0)) + return FALSE; + + return TRUE; +} + struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource *texture, struct pipe_subresource sr, @@ -448,6 +519,36 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, struct pipe_resource resource; struct r600_transfer *trans; int r; + boolean use_staging_texture = FALSE; + + /* We cannot map a tiled texture directly because the data is + * in a different order, therefore we do detiling using a blit. + * + * Also, use a temporary in GTT memory for read transfers, as + * the CPU is much happier reading out of cached system memory + * than uncached VRAM. + */ + if (rtex->tiled) + use_staging_texture = TRUE; + + if ((usage & PIPE_TRANSFER_READ) && + u_box_volume(box) > 1024) + use_staging_texture = TRUE; + + /* XXX: Use a staging texture for uploads if the underlying BO + * is busy. No interface for checking that currently? so do + * it eagerly whenever the transfer doesn't require a readback + * and might block. + */ + if ((usage & PIPE_TRANSFER_WRITE) && + !(usage & (PIPE_TRANSFER_READ | + PIPE_TRANSFER_DONTBLOCK | + PIPE_TRANSFER_UNSYNCHRONIZED))) + use_staging_texture = TRUE; + + if (!permit_hardware_blit(ctx->screen, texture) || + (texture->flags & R600_RESOURCE_FLAG_TRANSFER)) + use_staging_texture = FALSE; trans = CALLOC_STRUCT(r600_transfer); if (trans == NULL) @@ -457,6 +558,10 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, trans->transfer.usage = usage; trans->transfer.box = *box; if (rtex->depth) { + /* XXX: only readback the rectangle which is being mapped? + */ + /* XXX: when discard is true, no need to read back from depth texture + */ r = r600_texture_depth_flush(ctx, texture); if (r < 0) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); @@ -464,7 +569,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, FREE(trans); return NULL; } - } else if (rtex->tiled) { + } else if (use_staging_texture) { resource.target = PIPE_TEXTURE_2D; resource.format = texture->format; resource.width0 = box->width; @@ -472,7 +577,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.depth0 = 1; resource.last_level = 0; resource.nr_samples = 0; - resource.usage = PIPE_USAGE_DYNAMIC; + resource.usage = PIPE_USAGE_STAGING; resource.bind = 0; resource.flags = R600_RESOURCE_FLAG_TRANSFER; /* For texture reading, the temporary (detiled) texture is used as @@ -486,8 +591,8 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, resource.bind |= PIPE_BIND_SAMPLER_VIEW; } /* Create the temporary texture. */ - trans->linear_texture = ctx->screen->resource_create(ctx->screen, &resource); - if (trans->linear_texture == NULL) { + trans->staging_texture = ctx->screen->resource_create(ctx->screen, &resource); + if (trans->staging_texture == NULL) { R600_ERR("failed to create temporary texture to hold untiled copy\n"); pipe_resource_reference(&trans->transfer.resource, NULL); FREE(trans); @@ -495,11 +600,9 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, } trans->transfer.stride = - ((struct r600_resource_texture *)trans->linear_texture)->pitch_in_bytes[0]; + ((struct r600_resource_texture *)trans->staging_texture)->pitch_in_bytes[0]; if (usage & PIPE_TRANSFER_READ) { - /* We cannot map a tiled texture directly because the data is - * in a different order, therefore we do detiling using a blit. */ - r600_copy_from_tiled_texture(ctx, trans); + r600_copy_to_staging_texture(ctx, trans); /* Always referenced in the blit. */ ctx->flush(ctx, 0, NULL); } @@ -516,11 +619,11 @@ void r600_texture_transfer_destroy(struct pipe_context *ctx, struct r600_transfer *rtransfer = (struct r600_transfer*)transfer; struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; - if (rtransfer->linear_texture) { + if (rtransfer->staging_texture) { if (transfer->usage & PIPE_TRANSFER_WRITE) { - r600_copy_into_tiled_texture(ctx, rtransfer); + r600_copy_from_staging_texture(ctx, rtransfer); } - pipe_resource_reference(&rtransfer->linear_texture, NULL); + pipe_resource_reference(&rtransfer->staging_texture, NULL); } if (rtex->flushed_depth_texture) { pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL); @@ -537,10 +640,11 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, enum pipe_format format = transfer->resource->format; struct radeon *radeon = (struct radeon *)ctx->screen->winsys; unsigned offset = 0; + unsigned usage = 0; char *map; - if (rtransfer->linear_texture) { - bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; + if (rtransfer->staging_texture) { + bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; @@ -553,7 +657,30 @@ void* r600_texture_transfer_map(struct pipe_context *ctx, transfer->box.y / util_format_get_blockheight(format) * transfer->stride + transfer->box.x / util_format_get_blockwidth(format) * util_format_get_blocksize(format); } - map = r600_bo_map(radeon, bo, 0, ctx); + + if (transfer->usage & PIPE_TRANSFER_WRITE) { + usage |= PB_USAGE_CPU_WRITE; + + if (transfer->usage & PIPE_TRANSFER_DISCARD) { + } + + if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) { + } + } + + if (transfer->usage & PIPE_TRANSFER_READ) { + usage |= PB_USAGE_CPU_READ; + } + + if (transfer->usage & PIPE_TRANSFER_DONTBLOCK) { + usage |= PB_USAGE_DONTBLOCK; + } + + if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) { + usage |= PB_USAGE_UNSYNCHRONIZED; + } + + map = r600_bo_map(radeon, bo, usage, ctx); if (!map) { return NULL; } @@ -568,8 +695,8 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct radeon *radeon = (struct radeon *)ctx->screen->winsys; struct r600_bo *bo; - if (rtransfer->linear_texture) { - bo = ((struct r600_resource *)rtransfer->linear_texture)->bo; + if (rtransfer->staging_texture) { + bo = ((struct r600_resource *)rtransfer->staging_texture)->bo; } else { struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource; @@ -584,7 +711,7 @@ void r600_texture_transfer_unmap(struct pipe_context *ctx, struct u_resource_vtbl r600_texture_vtbl = { - u_default_resource_get_handle, /* get_handle */ + r600_texture_get_handle, /* get_handle */ r600_texture_destroy, /* resource_destroy */ r600_texture_is_referenced, /* is_resource_referenced */ r600_texture_get_transfer, /* get_transfer */ @@ -689,7 +816,7 @@ uint32_t r600_translate_texformat(enum pipe_format format, result = FMT_24_8; goto out_word4; case PIPE_FORMAT_S8_USCALED: - result = V_0280A0_COLOR_8; + result = FMT_8; word4 |= S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_INT); goto out_word4; default: @@ -718,7 +845,29 @@ uint32_t r600_translate_texformat(enum pipe_format format, /* S3TC formats. TODO */ if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { - goto out_unknown; + static int r600_enable_s3tc = -1; + + if (r600_enable_s3tc == -1) + r600_enable_s3tc = + debug_get_bool_option("R600_ENABLE_S3TC", FALSE); + + if (!r600_enable_s3tc) + goto out_unknown; + + switch (format) { + case PIPE_FORMAT_DXT1_RGB: + case PIPE_FORMAT_DXT1_RGBA: + result = FMT_BC1; + goto out_word4; + case PIPE_FORMAT_DXT3_RGBA: + result = FMT_BC2; + goto out_word4; + case PIPE_FORMAT_DXT5_RGBA: + result = FMT_BC3; + goto out_word4; + default: + goto out_unknown; + } } diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index a3cb5b86004..ae19bfb8285 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -2100,6 +2100,10 @@ #define G_028C00_LAST_PIXEL(x) (((x) >> 10) & 0x1) #define C_028C00_LAST_PIXEL 0xFFFFFBFF #define R_028C04_PA_SC_AA_CONFIG 0x028C04 +#define R_028C08_PA_SU_VTX_CNTL 0x028C08 +#define S_028C08_PIX_CENTER_HALF(x) (((x) & 0x1) << 0) +#define G_028C08_PIX_CENTER_HALF(x) (((x) >> 0) & 0x1) +#define C_028C08_PIX_CENTER_HALF 0xFFFFFFFE #define R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX 0x028C1C #define R_028C48_PA_SC_AA_MASK 0x028C48 #define R_028810_PA_CL_CLIP_CNTL 0x028810 diff --git a/src/gallium/drivers/rbug/README b/src/gallium/drivers/rbug/README index b6d3a5cf351..9d7bd4e7695 100644 --- a/src/gallium/drivers/rbug/README +++ b/src/gallium/drivers/rbug/README @@ -7,24 +7,10 @@ This directory contains a Gallium3D remote debugger pipe driver. It provides remote debugging functionality. -= Build Instructions = - -To build, invoke scons on the top dir as - - scons dri=no statetrackers=mesa winsys=xlib - - = Usage = -To use do - - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib - -ensure the right libGL.so is being picked by doing - - ldd progs/trivial/tri +Do - export XMESA_TRACE=y GALLIUM_RBUG=true progs/trivial/tri which should open gallium remote debugging session. While the program is running diff --git a/src/gallium/drivers/rbug/SConscript b/src/gallium/drivers/rbug/SConscript index 3da6ac104a4..169c2718dc3 100644 --- a/src/gallium/drivers/rbug/SConscript +++ b/src/gallium/drivers/rbug/SConscript @@ -11,4 +11,6 @@ rbug = env.ConvenienceLibrary( 'rbug_screen.c', ]) +env.Alias('rbug', rbug) + Export('rbug') diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript index dea7f885e0d..9b2abdfd7f1 100644 --- a/src/gallium/drivers/softpipe/SConscript +++ b/src/gallium/drivers/softpipe/SConscript @@ -38,4 +38,6 @@ softpipe = env.ConvenienceLibrary( 'sp_video_context.c', ]) +env.Alias('softpipe', softpipe) + Export('softpipe') diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index c8f5f89568a..89b2a91fc1f 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -860,6 +860,7 @@ choose_depth_test(struct quad_stage *qs, /* look for special cases */ if (!alpha && !depth && + !occlusion && !stencil) { qs->run = depth_noop; } diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index edc2a6dacf2..5e13d632387 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -65,7 +65,12 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return PIPE_MAX_SAMPLERS; case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: +#ifdef HAVE_LLVM + /* Softpipe doesn't yet know how to tell draw/llvm about textures */ + return 0; +#else return PIPE_MAX_VERTEX_SAMPLERS; +#endif case PIPE_CAP_MAX_COMBINED_SAMPLERS: return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: diff --git a/src/gallium/drivers/sw/SConscript b/src/gallium/drivers/sw/SConscript index e9ebf751ddd..40d01db2f6d 100644 --- a/src/gallium/drivers/sw/SConscript +++ b/src/gallium/drivers/sw/SConscript @@ -20,7 +20,6 @@ if True: if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') env.Prepend(LIBS = [llvmpipe]) extra.append(llvmpipe) diff --git a/src/gallium/drivers/trace/README b/src/gallium/drivers/trace/README index cdcd8d2b4be..c210cba032a 100644 --- a/src/gallium/drivers/trace/README +++ b/src/gallium/drivers/trace/README @@ -7,23 +7,8 @@ This directory contains a Gallium3D trace debugger pipe driver. It can traces all incoming calls. -= Build Instructions = - -To build, invoke scons on the top dir as - - scons dri=no statetrackers=mesa winsys=xlib - - = Usage = -To use do - - export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib - -ensure the right libGL.so is being picked by doing - - ldd progs/trivial/tri - == Tracing == For tracing then do @@ -40,6 +25,7 @@ For remote debugging see: src/gallium/drivers/rbug/README + = Integrating = You can integrate the trace pipe driver either inside the state tracker or the @@ -60,5 +46,5 @@ are automatically wrapped by trace_screen. -- -Jose Fonseca <[email protected]> +Jose Fonseca <[email protected]> Jakob Bornecrantz <[email protected]> diff --git a/src/gallium/drivers/trace/SConscript b/src/gallium/drivers/trace/SConscript index 06b0c4863a4..1384fe33d72 100644 --- a/src/gallium/drivers/trace/SConscript +++ b/src/gallium/drivers/trace/SConscript @@ -12,4 +12,6 @@ trace = env.ConvenienceLibrary( 'tr_texture.c', ]) +env.Alias('trace', trace) + Export('trace') diff --git a/src/gallium/include/state_tracker/graw.h b/src/gallium/include/state_tracker/graw.h index 6a99b234aa5..217fa31ba19 100644 --- a/src/gallium/include/state_tracker/graw.h +++ b/src/gallium/include/state_tracker/graw.h @@ -44,8 +44,9 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" -struct pipe_screen; struct pipe_context; +struct pipe_screen; +struct pipe_surface; /* Returns a handle to be used with flush_frontbuffer()/present(). * @@ -71,4 +72,25 @@ PUBLIC void *graw_parse_vertex_shader( struct pipe_context *pipe, PUBLIC void *graw_parse_fragment_shader( struct pipe_context *pipe, const char *text ); +/* Parse a single command-line option, if any. Options include: + * + * -o <filename> + * + * If an option has been successfully parsed, argi is updated + * to point just after the option and return TRUE. + */ +PUBLIC boolean graw_parse_args(int *argi, int argc, char *argv[]); + +/* Saves surface contents to a file. + * + * If filename is NULL, the filename provided with the `-o' option + * is used. If the option has not been specified, the surface + * will not be saved. + * + * Returns TRUE if the surface has been saved. + */ +PUBLIC boolean graw_save_surface_to_file(struct pipe_context *pipe, + struct pipe_surface *surface, + const char *filename); + #endif diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp index e1c34611d14..c246fc5ef76 100644 --- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp +++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp @@ -1101,6 +1101,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX struct pipe_resource* dst; struct pipe_resource* src; struct pipe_surface* dst_surface; + enum native_attachment att; void* present_cookie; hr = parent->backend->BeginPresent(desc.OutputWindow, &present_cookie, &cur_window, &rect, &rgndata, &preserve_aspect_ratio); @@ -1221,16 +1222,9 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0); - if(db) - { - if(!surface->swap_buffers(surface)) - return DXGI_ERROR_DEVICE_REMOVED; - } - else - { - if(!surface->flush_frontbuffer(surface)) - return DXGI_ERROR_DEVICE_REMOVED; - } + att = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT; + if(!surface->present(surface, att, FALSE, 0)) + return DXGI_ERROR_DEVICE_REMOVED; end_present: parent->backend->EndPresent(desc.OutputWindow, present_cookie); diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript index aba60fb8c5b..7702d8e6323 100644 --- a/src/gallium/state_trackers/dri/SConscript +++ b/src/gallium/state_trackers/dri/SConscript @@ -1,6 +1,6 @@ Import('*') SConscript([ - 'sw/SConscript', - 'drm/SConscript', + 'sw/SConscript', + 'drm/SConscript', ]) diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c index 770b37037f5..3d5d24e692c 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.c +++ b/src/gallium/state_trackers/dri/common/dri_context.c @@ -178,7 +178,8 @@ dri_make_current(__DRIcontext * cPriv, read->texture_stamp = driReadPriv->lastStamp - 1; } - ctx->stapi->make_current(ctx->stapi, ctx->st, &draw->base, &read->base); + ctx->stapi->make_current(ctx->stapi, ctx->st, + (draw) ? &draw->base : NULL, (read) ? &read->base : NULL); return GL_TRUE; } diff --git a/src/gallium/state_trackers/dri/common/dri_drawable.h b/src/gallium/state_trackers/dri/common/dri_drawable.h index 837d3983748..2ff6b713293 100644 --- a/src/gallium/state_trackers/dri/common/dri_drawable.h +++ b/src/gallium/state_trackers/dri/common/dri_drawable.h @@ -70,7 +70,8 @@ struct dri_drawable static INLINE struct dri_drawable * dri_drawable(__DRIdrawable * driDrawPriv) { - return (struct dri_drawable *)driDrawPriv->driverPrivate; + return (struct dri_drawable *) (driDrawPriv) + ? driDrawPriv->driverPrivate : NULL; } /*********************************************************************** diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 252ad1768d8..1302e9bc013 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -231,6 +231,9 @@ dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, { memset(stvis, 0, sizeof(*stvis)); + if (!mode) + return; + stvis->samples = mode->samples; stvis->render_buffer = ST_ATTACHMENT_INVALID; diff --git a/src/gallium/state_trackers/dri/drm/SConscript b/src/gallium/state_trackers/dri/drm/SConscript index 2a0af65f9bd..b188f76f910 100644 --- a/src/gallium/state_trackers/dri/drm/SConscript +++ b/src/gallium/state_trackers/dri/drm/SConscript @@ -3,25 +3,26 @@ Import('*') -if env['dri']: +env = env.Clone() - env = env.Clone() +env.ParseConfig('pkg-config --cflags --libs libdrm') - env.ParseConfig('pkg-config --cflags --libs libdrm') +env.Append(CPPPATH = [ + '#/src/mapi', + '#/src/mesa', + '#/src/gallium/state_trackers/dri/common', + '#/src/mesa/drivers/dri/common', +]) - env.Append(CPPPATH = [ - '#/src/mapi', - '#/src/mesa', - '#/src/gallium/state_trackers/dri/common', - '#/src/mesa/drivers/dri/common', - ]) +sources = [ + 'dri_context.c', + 'dri_drawable.c', + 'dri_screen.c', + 'dri2.c', +] - st_dri = env.ConvenienceLibrary( - target = 'st_dri', - source = [ 'dri_context.c', - 'dri_drawable.c', - 'dri_screen.c', - 'dri2.c', - ] - ) - Export('st_dri') +st_dri = env.ConvenienceLibrary( + target = 'st_dri', + source = sources, +) +Export('st_dri') diff --git a/src/gallium/state_trackers/dri/sw/SConscript b/src/gallium/state_trackers/dri/sw/SConscript index d2eb66668e0..d0c3efc6faa 100644 --- a/src/gallium/state_trackers/dri/sw/SConscript +++ b/src/gallium/state_trackers/dri/sw/SConscript @@ -3,25 +3,26 @@ Import('*') -if env['dri']: +env = env.Clone() - env = env.Clone() +env.Append(CPPPATH = [ + '#/src/mapi', + '#/src/mesa', + '#/src/gallium/state_trackers/dri/common', + '#/src/mesa/drivers/dri/common', +]) - env.Append(CPPPATH = [ - '#/src/mapi', - '#/src/mesa', - '#/src/gallium/state_trackers/dri/common', - '#/src/mesa/drivers/dri/common', - ]) +env.Append(CPPDEFINES = [('__NOT_HAVE_DRM_H', '1')]) - env.Append(CPPDEFINES = [('__NOT_HAVE_DRM_H', '1')]) +sources = [ + 'dri_context.c', + 'dri_drawable.c', + 'dri_screen.c', + 'drisw.c', +] - st_drisw = env.ConvenienceLibrary( - target = 'st_drisw', - source = [ 'dri_context.c', - 'dri_drawable.c', - 'dri_screen.c', - 'drisw.c', - ] - ) - Export('st_drisw') +st_drisw = env.ConvenienceLibrary( + target = 'st_drisw', + source = sources, +) +Export('st_drisw') diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 8dbfc5b8e56..8cfcef968ed 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -17,7 +17,7 @@ x11_INCLUDES = \ -I$(TOP)/src/mapi \ -I$(TOP)/src/mesa \ $(X11_CFLAGS) \ - $(shell pkg-config --cflags-only-I libdrm) + $(shell pkg-config --cflags-only-I libdrm dri2proto) x11_SOURCES = $(wildcard x11/*.c) \ $(TOP)/src/glx/dri2.c diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript index efcce25e317..50c76819954 100644 --- a/src/gallium/state_trackers/egl/SConscript +++ b/src/gallium/state_trackers/egl/SConscript @@ -3,34 +3,32 @@ Import('*') -if 'egl' in env['statetrackers']: +env = env.Clone() - env = env.Clone() +env.Append(CPPPATH = [ + '#/src/egl/main', + '#/src/gallium/winsys/sw', + '.', +]) +env.Append(CPPDEFINES = [ + 'HAVE_GDI_BACKEND', +]) - env.Append(CPPPATH = [ - '#/src/egl/main', - '#/src/gallium/winsys/sw', - '.', - ]) - env.Append(CPPDEFINES = [ - 'HAVE_GDI_BACKEND', - ]) +common_sources = [ + 'common/egl_g3d.c', + 'common/egl_g3d_api.c', + 'common/egl_g3d_image.c', + 'common/egl_g3d_st.c', + 'common/egl_g3d_sync.c', + 'common/native_helper.c', +] - common_sources = [ - 'common/egl_g3d.c', - 'common/egl_g3d_api.c', - 'common/egl_g3d_image.c', - 'common/egl_g3d_st.c', - 'common/egl_g3d_sync.c', - 'common/native_helper.c', - ] +gdi_sources = common_sources + [ + 'gdi/native_gdi.c', +] - gdi_sources = common_sources + [ - 'gdi/native_gdi.c', - ] - - st_egl_gdi = env.ConvenienceLibrary( - target = 'st_egl_gdi', - source = gdi_sources, - ) - Export('st_egl_gdi') +st_egl_gdi = env.ConvenienceLibrary( + target = 'st_egl_gdi', + source = gdi_sources, +) +Export('st_egl_gdi') diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 30ddcd5bc14..a3750ac56fb 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -156,7 +156,8 @@ egl_g3d_add_screens(_EGLDriver *drv, _EGLDisplay *dpy) */ static EGLBoolean init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, - EGLint api_mask, enum pipe_format depth_stencil_format) + EGLint api_mask, enum pipe_format depth_stencil_format, + EGLBoolean preserve_buffer, EGLint max_swap_interval) { uint rgba[4], depth_stencil[2], buffer_size; EGLint surface_type; @@ -238,6 +239,11 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, conf->TransparentBlueValue = nconf->transparent_rgb_values[2]; } + conf->MinSwapInterval = 0; + conf->MaxSwapInterval = max_swap_interval; + if (preserve_buffer) + conf->SurfaceType |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + return _eglValidateConfig(conf, EGL_FALSE); } @@ -247,7 +253,8 @@ init_config_attributes(_EGLConfig *conf, const struct native_config *nconf, static EGLBoolean egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const struct native_config *nconf, - enum pipe_format depth_stencil_format) + enum pipe_format depth_stencil_format, + int preserve_buffer, int max_swap_interval) { struct egl_g3d_config *gconf = egl_g3d_config(conf); EGLint buffer_mask, api_mask; @@ -288,7 +295,8 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, } valid = init_config_attributes(&gconf->base, - nconf, api_mask, depth_stencil_format); + nconf, api_mask, depth_stencil_format, + preserve_buffer, max_swap_interval); if (!valid) { _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id); return EGL_FALSE; @@ -349,6 +357,7 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) const struct native_config **native_configs; enum pipe_format depth_stencil_formats[8]; int num_formats, num_configs, i, j; + int preserve_buffer, max_swap_interval; native_configs = gdpy->native->get_configs(gdpy->native, &num_configs); if (!num_configs) { @@ -357,6 +366,11 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) return id; } + preserve_buffer = + gdpy->native->get_param(gdpy->native, NATIVE_PARAM_PRESERVE_BUFFER); + max_swap_interval = + gdpy->native->get_param(gdpy->native, NATIVE_PARAM_MAX_SWAP_INTERVAL); + num_formats = egl_g3d_fill_depth_stencil_formats(dpy, depth_stencil_formats); @@ -368,7 +382,8 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) if (gconf) { _eglInitConfig(&gconf->base, dpy, id); if (!egl_g3d_init_config(drv, dpy, &gconf->base, - native_configs[i], depth_stencil_formats[j])) { + native_configs[i], depth_stencil_formats[j], + preserve_buffer, max_swap_interval)) { FREE(gconf); break; } @@ -538,7 +553,8 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, if (dpy->Platform == _EGL_PLATFORM_DRM) { dpy->Extensions.MESA_drm_display = EGL_TRUE; - dpy->Extensions.MESA_drm_image = EGL_TRUE; + if (gdpy->native->buffer) + dpy->Extensions.MESA_drm_image = EGL_TRUE; } if (egl_g3d_add_configs(drv, dpy, 1) == 1) { diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index c10245bb067..fd7dc8f8149 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -97,6 +97,70 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx, return stapi; } +static int +egl_g3d_compare_config(const _EGLConfig *conf1, const _EGLConfig *conf2, + void *priv_data) +{ + const _EGLConfig *criteria = (const _EGLConfig *) priv_data; + + /* EGL_NATIVE_VISUAL_TYPE ignored? */ + return _eglCompareConfigs(conf1, conf2, criteria, EGL_TRUE); +} + +static EGLBoolean +egl_g3d_match_config(const _EGLConfig *conf, const _EGLConfig *criteria) +{ + if (!_eglMatchConfig(conf, criteria)) + return EGL_FALSE; + + if (criteria->MatchNativePixmap != EGL_NONE && + criteria->MatchNativePixmap != EGL_DONT_CARE) { + struct egl_g3d_display *gdpy = egl_g3d_display(conf->Display); + struct egl_g3d_config *gconf = egl_g3d_config(conf); + EGLNativePixmapType pix = + (EGLNativePixmapType) criteria->MatchNativePixmap; + + if (!gdpy->native->is_pixmap_supported(gdpy->native, pix, gconf->native)) + return EGL_FALSE; + } + + return EGL_TRUE; +} + +static EGLBoolean +egl_g3d_choose_config(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attribs, + EGLConfig *configs, EGLint size, EGLint *num_configs) +{ + _EGLConfig **tmp_configs, criteria; + EGLint tmp_size, i; + + if (!num_configs) + return _eglError(EGL_BAD_PARAMETER, "eglChooseConfigs"); + + if (!_eglParseConfigAttribList(&criteria, dpy, attribs)) + return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig"); + + tmp_configs = (_EGLConfig **) _eglFilterArray(dpy->Configs, &tmp_size, + (_EGLArrayForEach) egl_g3d_match_config, (void *) &criteria); + if (!tmp_configs) + return _eglError(EGL_BAD_ALLOC, "eglChooseConfig(out of memory)"); + + /* perform sorting of configs */ + if (tmp_configs && tmp_size) { + _eglSortConfigs((const _EGLConfig **) tmp_configs, tmp_size, + egl_g3d_compare_config, (void *) &criteria); + size = MIN2(tmp_size, size); + for (i = 0; i < size; i++) + configs[i] = _eglGetConfigHandle(tmp_configs[i]); + } + + free(tmp_configs); + + *num_configs = size; + + return EGL_TRUE; +} + static _EGLContext * egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share, const EGLint *attribs) @@ -539,7 +603,10 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); } - return gsurf->native->swap_buffers(gsurf->native); + return gsurf->native->present(gsurf->native, + NATIVE_ATTACHMENT_BACK_LEFT, + gsurf->base.SwapBehavior == EGL_BUFFER_PRESERVED, + gsurf->base.SwapInterval); } /** @@ -607,8 +674,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, if (psrc) { gdpy->pipe->resource_copy_region(gdpy->pipe, ptex, subdst, 0, 0, 0, gsurf->render_texture, subsrc, 0, 0, 0, ptex->width0, ptex->height0); - - nsurf->flush_frontbuffer(nsurf); + nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); } pipe_resource_reference(&ptex, NULL); @@ -838,6 +904,8 @@ egl_g3d_init_driver_api(_EGLDriver *drv) { _eglInitDriverFallbacks(drv); + drv->API.ChooseConfig = egl_g3d_choose_config; + drv->API.CreateContext = egl_g3d_create_context; drv->API.DestroyContext = egl_g3d_destroy_context; drv->API.CreateWindowSurface = egl_g3d_create_window_surface; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c index be9c88e5e47..6a1f8cc697b 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c @@ -38,7 +38,7 @@ #include "egl_g3d_api.h" #include "egl_g3d_image.h" -/* move this to native display? */ +/* for struct winsys_handle */ #include "state_tracker/drm_driver.h" /** @@ -137,13 +137,11 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, _EGLImage *img, const EGLint *attribs) { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - struct pipe_screen *screen = gdpy->native->screen; struct pipe_resource templ; struct winsys_handle wsh; _EGLImageAttribs attrs; EGLint format; - /* winsys_handle is in theory platform-specific */ if (dpy->Platform != _EGL_PLATFORM_DRM) return NULL; @@ -178,9 +176,10 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, memset(&wsh, 0, sizeof(wsh)); wsh.handle = (unsigned) name; - wsh.stride = attrs.DRMBufferStrideMESA; + wsh.stride = + attrs.DRMBufferStrideMESA * util_format_get_blocksize(templ.format); - return screen->resource_from_handle(screen, &templ, &wsh); + return gdpy->native->buffer->import_buffer(gdpy->native, &templ, &wsh); } #endif /* EGL_MESA_drm_image */ @@ -302,10 +301,8 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, { struct egl_g3d_display *gdpy = egl_g3d_display(dpy); struct egl_g3d_image *gimg = egl_g3d_image(img); - struct pipe_screen *screen = gdpy->native->screen; struct winsys_handle wsh; - /* winsys_handle is in theory platform-specific */ if (dpy->Platform != _EGL_PLATFORM_DRM) return EGL_FALSE; @@ -313,9 +310,9 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, if (name) { memset(&handle, 0, sizeof(handle)); wsh.type = DRM_API_HANDLE_TYPE_SHARED; - if (!screen->resource_get_handle(screen, gimg->texture, &wsh)) { + if (!gdpy->native->buffer->export_buffer(gdpy->native, + gimg->texture, &wsh)) return EGL_FALSE; - } *name = wsh.handle; } @@ -324,7 +321,8 @@ egl_g3d_export_drm_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img, if (handle || stride) { memset(&wsh, 0, sizeof(wsh)); wsh.type = DRM_API_HANDLE_TYPE_KMS; - if (!screen->resource_get_handle(screen, gimg->texture, &wsh)) + if (!gdpy->native->buffer->export_buffer(gdpy->native, + gimg->texture, &wsh)) return EGL_FALSE; if (handle) diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_st.c b/src/gallium/state_trackers/egl/common/egl_g3d_st.c index 0affe632cfe..25e2999590c 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_st.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_st.c @@ -192,7 +192,8 @@ egl_g3d_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); - return gsurf->native->flush_frontbuffer(gsurf->native); + return gsurf->native->present(gsurf->native, + NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); } static boolean diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index 3c3f57e2670..3886ca20562 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -34,6 +34,11 @@ #include "pipe/p_state.h" #include "state_tracker/sw_winsys.h" +#ifdef __cplusplus +extern "C" { +#endif + +#include "native_buffer.h" #include "native_modeset.h" /** @@ -54,7 +59,17 @@ enum native_param_type { * Return TRUE if window/pixmap surfaces use the buffers of the native * types. */ - NATIVE_PARAM_USE_NATIVE_BUFFER + NATIVE_PARAM_USE_NATIVE_BUFFER, + + /** + * Return TRUE if native_surface::present can preserve the buffer. + */ + NATIVE_PARAM_PRESERVE_BUFFER, + + /** + * Return the maximum supported swap interval. + */ + NATIVE_PARAM_MAX_SWAP_INTERVAL }; struct native_surface { @@ -66,17 +81,12 @@ struct native_surface { void (*destroy)(struct native_surface *nsurf); /** - * Swap the front and back buffers so that the back buffer is visible. It - * is no-op if the surface is single-buffered. The contents of the back - * buffer after swapping may or may not be preserved. - */ - boolean (*swap_buffers)(struct native_surface *nsurf); - - /** - * Make the front buffer visible. In some native displays, changes to the - * front buffer might not be visible immediately and require manual flush. + * Present the given buffer to the native engine. */ - boolean (*flush_frontbuffer)(struct native_surface *nsurf); + boolean (*present)(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval); /** * Validate the buffers of the surface. textures, if not NULL, points to an @@ -181,6 +191,7 @@ struct native_display { EGLNativePixmapType pix, const struct native_config *nconf); + const struct native_display_buffer *buffer; const struct native_display_modeset *modeset; }; @@ -232,4 +243,8 @@ native_get_drm_platform(void); const struct native_platform * native_get_fbdev_platform(void); +#ifdef __cplusplus +} +#endif + #endif /* _NATIVE_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native_buffer.h b/src/gallium/state_trackers/egl/common/native_buffer.h new file mode 100644 index 00000000000..5c29ab97411 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_buffer.h @@ -0,0 +1,59 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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: + * Chia-I Wu <[email protected]> + */ + +#ifndef _NATIVE_BUFFER_H_ +#define _NATIVE_BUFFER_H_ + +#include "pipe/p_compiler.h" + +struct native_display; +struct pipe_resource; + +/** + * Buffer interface of the native display. It allows native buffers to be + * imported and exported. + * + * Just like a native window or a native pixmap, a native buffer is another + * native type. Its definition depends on the native display. + * + * For DRM platform, the type of a native buffer is struct winsys_handle. + */ +struct native_display_buffer { + struct pipe_resource *(*import_buffer)(struct native_display *ndpy, + const struct pipe_resource *templ, + void *buf); + + /** + * The resource must be creatred with PIPE_BIND_SHARED. + */ + boolean (*export_buffer)(struct native_display *ndpy, + struct pipe_resource *res, + void *buf); +}; + +#endif /* _NATIVE_BUFFER_H_ */ diff --git a/src/gallium/state_trackers/egl/drm/modeset.c b/src/gallium/state_trackers/egl/drm/modeset.c index 5ed22f7b9d4..0cc06caa2a1 100644 --- a/src/gallium/state_trackers/egl/drm/modeset.c +++ b/src/gallium/state_trackers/egl/drm/modeset.c @@ -167,6 +167,32 @@ drm_surface_swap_buffers(struct native_surface *nsurf) return TRUE; } +static boolean +drm_surface_present(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval) +{ + boolean ret; + + if (preserve || swap_interval) + return FALSE; + + switch (natt) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + ret = drm_surface_flush_frontbuffer(nsurf); + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + ret = drm_surface_swap_buffers(nsurf); + break; + default: + ret = FALSE; + break; + } + + return ret; +} + static void drm_surface_wait(struct native_surface *nsurf) { @@ -225,8 +251,7 @@ drm_display_create_surface(struct native_display *ndpy, resource_surface_set_size(drmsurf->rsurf, drmsurf->width, drmsurf->height); drmsurf->base.destroy = drm_surface_destroy; - drmsurf->base.swap_buffers = drm_surface_swap_buffers; - drmsurf->base.flush_frontbuffer = drm_surface_flush_frontbuffer; + drmsurf->base.present = drm_surface_present; drmsurf->base.validate = drm_surface_validate; drmsurf->base.wait = drm_surface_wait; diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index f6dc5584370..3759c2a26dd 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -103,6 +103,9 @@ drm_display_get_param(struct native_display *ndpy, int val; switch (param) { + case NATIVE_PARAM_USE_NATIVE_BUFFER: + case NATIVE_PARAM_PRESERVE_BUFFER: + case NATIVE_PARAM_MAX_SWAP_INTERVAL: default: val = 0; break; @@ -182,6 +185,29 @@ drm_display_init_screen(struct native_display *ndpy) return TRUE; } +static struct pipe_resource * +drm_display_import_buffer(struct native_display *ndpy, + const struct pipe_resource *templ, + void *buf) +{ + return ndpy->screen->resource_from_handle(ndpy->screen, + templ, (struct winsys_handle *) buf); +} + +static boolean +drm_display_export_buffer(struct native_display *ndpy, + struct pipe_resource *res, + void *buf) +{ + return ndpy->screen->resource_get_handle(ndpy->screen, + res, (struct winsys_handle *) buf); +} + +static struct native_display_buffer drm_display_buffer = { + drm_display_import_buffer, + drm_display_export_buffer +}; + static struct native_display * drm_create_display(int fd, struct native_event_handler *event_handler, void *user_data) @@ -205,6 +231,7 @@ drm_create_display(int fd, struct native_event_handler *event_handler, drmdpy->base.get_param = drm_display_get_param; drmdpy->base.get_configs = drm_display_get_configs; + drmdpy->base.buffer = &drm_display_buffer; drm_display_init_modeset(&drmdpy->base); return &drmdpy->base; diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c index e459402076d..1b5ea8bf9d5 100644 --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c @@ -137,6 +137,32 @@ fbdev_surface_swap_buffers(struct native_surface *nsurf) return ret; } +static boolean +fbdev_surface_present(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval) +{ + boolean ret; + + if (preserve || swap_interval) + return FALSE; + + switch (natt) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + ret = fbdev_surface_flush_frontbuffer(nsurf); + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + ret = fbdev_surface_swap_buffers(nsurf); + break; + default: + ret = FALSE; + break; + } + + return ret; +} + static void fbdev_surface_wait(struct native_surface *nsurf) { @@ -181,8 +207,7 @@ fbdev_display_create_scanout_surface(struct native_display *ndpy, resource_surface_set_size(fbsurf->rsurf, fbsurf->width, fbsurf->height); fbsurf->base.destroy = fbdev_surface_destroy; - fbsurf->base.swap_buffers = fbdev_surface_swap_buffers; - fbsurf->base.flush_frontbuffer = fbdev_surface_flush_frontbuffer; + fbsurf->base.present = fbdev_surface_present; fbsurf->base.validate = fbdev_surface_validate; fbsurf->base.wait = fbdev_surface_wait; @@ -279,6 +304,9 @@ fbdev_display_get_param(struct native_display *ndpy, int val; switch (param) { + case NATIVE_PARAM_USE_NATIVE_BUFFER: + case NATIVE_PARAM_PRESERVE_BUFFER: + case NATIVE_PARAM_MAX_SWAP_INTERVAL: default: val = 0; break; diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c index 91701e5b7df..d259e6edc89 100644 --- a/src/gallium/state_trackers/egl/gdi/native_gdi.c +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c @@ -160,6 +160,32 @@ gdi_surface_swap_buffers(struct native_surface *nsurf) } static boolean +gdi_surface_present(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval) +{ + boolean ret; + + if (preserve || swap_interval) + return FALSE; + + switch (natt) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + ret = gdi_surface_flush_frontbuffer(nsurf); + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + ret = gdi_surface_swap_buffers(nsurf); + break; + default: + ret = FALSE; + break; + } + + return ret; +} + +static boolean gdi_surface_validate(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_resource **textures, int *width, int *height) @@ -231,8 +257,7 @@ gdi_display_create_window_surface(struct native_display *ndpy, gdi_surface_update_geometry(&gsurf->base); gsurf->base.destroy = gdi_surface_destroy; - gsurf->base.swap_buffers = gdi_surface_swap_buffers; - gsurf->base.flush_frontbuffer = gdi_surface_flush_frontbuffer; + gsurf->base.present = gdi_surface_present; gsurf->base.validate = gdi_surface_validate; gsurf->base.wait = gdi_surface_wait; @@ -321,6 +346,8 @@ gdi_display_get_param(struct native_display *ndpy, /* private buffers are allocated */ val = FALSE; break; + case NATIVE_PARAM_PRESERVE_BUFFER: + case NATIVE_PARAM_MAX_SWAP_INTERVAL: default: val = 0; break; diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index 1169e273c34..331a7de432a 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -338,6 +338,32 @@ dri2_surface_swap_buffers(struct native_surface *nsurf) } static boolean +dri2_surface_present(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval) +{ + boolean ret; + + if (swap_interval) + return FALSE; + + switch (natt) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + ret = dri2_surface_flush_frontbuffer(nsurf); + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + ret = dri2_surface_swap_buffers(nsurf); + break; + default: + ret = FALSE; + break; + } + + return ret; +} + +static boolean dri2_surface_validate(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_resource **textures, int *width, int *height) @@ -430,8 +456,7 @@ dri2_display_create_surface(struct native_display *ndpy, dri2surf->color_format = dri2conf->base.color_format; dri2surf->base.destroy = dri2_surface_destroy; - dri2surf->base.swap_buffers = dri2_surface_swap_buffers; - dri2surf->base.flush_frontbuffer = dri2_surface_flush_frontbuffer; + dri2surf->base.present = dri2_surface_present; dri2surf->base.validate = dri2_surface_validate; dri2surf->base.wait = dri2_surface_wait; @@ -630,9 +655,14 @@ dri2_display_get_param(struct native_display *ndpy, switch (param) { case NATIVE_PARAM_USE_NATIVE_BUFFER: - /* DRI2GetBuffers use the native buffers */ + /* DRI2GetBuffers uses the native buffers */ + val = TRUE; + break; + case NATIVE_PARAM_PRESERVE_BUFFER: + /* DRI2CopyRegion is used */ val = TRUE; break; + case NATIVE_PARAM_MAX_SWAP_INTERVAL: default: val = 0; break; diff --git a/src/gallium/state_trackers/egl/x11/native_x11.h b/src/gallium/state_trackers/egl/x11/native_x11.h index 0b47837e1b5..8945117276e 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.h +++ b/src/gallium/state_trackers/egl/x11/native_x11.h @@ -27,6 +27,7 @@ #define _NATIVE_X11_H_ #include "common/native.h" +#include <X11/Xlib.h> struct native_display * x11_create_ximage_display(Display *dpy, diff --git a/src/gallium/state_trackers/egl/x11/native_ximage.c b/src/gallium/state_trackers/egl/x11/native_ximage.c index 4b32f6e36e0..84811fb6e14 100644 --- a/src/gallium/state_trackers/egl/x11/native_ximage.c +++ b/src/gallium/state_trackers/egl/x11/native_ximage.c @@ -175,6 +175,32 @@ ximage_surface_swap_buffers(struct native_surface *nsurf) } static boolean +ximage_surface_present(struct native_surface *nsurf, + enum native_attachment natt, + boolean preserve, + uint swap_interval) +{ + boolean ret; + + if (preserve || swap_interval) + return FALSE; + + switch (natt) { + case NATIVE_ATTACHMENT_FRONT_LEFT: + ret = ximage_surface_flush_frontbuffer(nsurf); + break; + case NATIVE_ATTACHMENT_BACK_LEFT: + ret = ximage_surface_swap_buffers(nsurf); + break; + default: + ret = FALSE; + break; + } + + return ret; +} + +static boolean ximage_surface_validate(struct native_surface *nsurf, uint attachment_mask, unsigned int *seq_num, struct pipe_resource **textures, int *width, int *height) @@ -257,8 +283,7 @@ ximage_display_create_surface(struct native_display *ndpy, xsurf->xdraw.drawable = xsurf->drawable; xsurf->base.destroy = ximage_surface_destroy; - xsurf->base.swap_buffers = ximage_surface_swap_buffers; - xsurf->base.flush_frontbuffer = ximage_surface_flush_frontbuffer; + xsurf->base.present = ximage_surface_present; xsurf->base.validate = ximage_surface_validate; xsurf->base.wait = ximage_surface_wait; @@ -416,6 +441,8 @@ ximage_display_get_param(struct native_display *ndpy, /* private buffers are allocated */ val = FALSE; break; + case NATIVE_PARAM_PRESERVE_BUFFER: + case NATIVE_PARAM_MAX_SWAP_INTERVAL: default: val = 0; break; diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript index 9df351a2769..9e7ebf3fc91 100644 --- a/src/gallium/state_trackers/glx/xlib/SConscript +++ b/src/gallium/state_trackers/glx/xlib/SConscript @@ -3,25 +3,24 @@ Import('*') -if env['platform'] == 'linux' \ - and 'mesa' in env['statetrackers']: +env = env.Clone() - env = env.Clone() +env.Append(CPPPATH = [ + '#/src/mapi', + '#/src/mesa', + '#/src/mesa/main', +]) - env.Append(CPPPATH = [ - '#/src/mapi', - '#/src/mesa', - '#/src/mesa/main', - ]) +sources = [ + 'glx_api.c', + 'glx_getproc.c', + 'glx_usefont.c', + 'xm_api.c', + 'xm_st.c', +] - st_xlib = env.ConvenienceLibrary( - target = 'st_xlib', - source = [ - 'glx_api.c', - 'glx_getproc.c', - 'glx_usefont.c', - 'xm_api.c', - 'xm_st.c', - ] - ) - Export('st_xlib') +st_xlib = env.ConvenienceLibrary( + target = 'st_xlib', + source = sources, +) +Export('st_xlib') diff --git a/src/gallium/state_trackers/python/SConscript b/src/gallium/state_trackers/python/SConscript index aadeaa0a359..b8371865a61 100644 --- a/src/gallium/state_trackers/python/SConscript +++ b/src/gallium/state_trackers/python/SConscript @@ -3,57 +3,64 @@ import os.path Import('*') -if 'python' in env['statetrackers']: - - env = env.Clone() - - env.Tool('python') - - env.Tool('swig') - env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) - env.Append(SWIGFLAGS = ['-python', '-keyword']) - - env.Append(CPPPATH = '.') - - if env['platform'] == 'windows': - env.Append(LIBS = [ - 'opengl32', - 'gdi32', - 'user32', - 'kernel32', - 'ws2_32', - ]) - else: - env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY']) - env.Append(LIBS = [ - 'GL', - 'X11', - ]) - - sources = [ - 'gallium.i', - 'st_device.c', - 'st_sample.c', - 'st_hardpipe_winsys.c', - 'st_softpipe_winsys.c', - ] - - env.Prepend(LIBS = [ - ws_null, - trace, - gallium, +if env['toolchain'] == 'crossmingw': + # Cross-compilation not supported + Return() + +if not env.Detect(['swig']): + Return() + +env = env.Clone() + +env.Tool('python') + +env.Tool('swig') +env.Append(SWIGPATH = ['#src/gallium/include', '#src/gallium/include/pipe']) +env.Append(SWIGFLAGS = ['-python', '-keyword']) + +env.Append(CPPPATH = '.') + +if env['platform'] == 'windows': + env.Append(LIBS = [ + 'opengl32', + 'gdi32', + 'user32', + 'kernel32', + 'ws2_32', + ]) +else: + env.Append(CPPDEFINES = ['GCC_HASCLASSVISIBILITY']) + env.Append(LIBS = [ + 'GL', + 'X11', ]) - if env['llvm']: - env.Append(CPPDEFINES = ['HAVE_LLVMPIPE']) - env.Prepend(LIBS = [llvmpipe]) - if True: - env.Append(CPPDEFINES = ['HAVE_SOFTPIPE']) - env.Prepend(LIBS = [softpipe]) +sources = [ + 'gallium.i', + 'st_device.c', + 'st_sample.c', + 'st_hardpipe_winsys.c', + 'st_softpipe_winsys.c', +] + +env.Prepend(LIBS = [ + ws_null, + trace, + gallium, +]) + +if env['llvm']: + env.Append(CPPDEFINES = ['HAVE_LLVMPIPE']) + env.Prepend(LIBS = [llvmpipe]) +if True: + env.Append(CPPDEFINES = ['HAVE_SOFTPIPE']) + env.Prepend(LIBS = [softpipe]) + +env['no_import_lib'] = 1 - env['no_import_lib'] = 1 +pyst = env.SharedLibrary( + target = '_gallium', + source = sources, +) - env.SharedLibrary( - target = '_gallium', - source = sources, - ) +env.Alias('python', pyst) diff --git a/src/gallium/state_trackers/vega/SConscript b/src/gallium/state_trackers/vega/SConscript index 548053eb646..a25b8474e4d 100644 --- a/src/gallium/state_trackers/vega/SConscript +++ b/src/gallium/state_trackers/vega/SConscript @@ -3,49 +3,48 @@ Import('*') -if 'egl' in env['statetrackers']: +env = env.Clone() - env = env.Clone() +env.Append(CPPPATH = [ + '#/src/mapi', +]) - env.Append(CPPPATH = [ - '#/src/mapi', - ]) +vega_sources = [ + 'api.c', + 'api_context.c', + 'api_filters.c', + 'api_images.c', + 'api_masks.c', + 'api_misc.c', + 'api_paint.c', + 'api_params.c', + 'api_path.c', + 'api_text.c', + 'api_transform.c', + 'vgu.c', + 'vg_context.c', + 'vg_manager.c', + 'vg_state.c', + 'vg_translate.c', + 'polygon.c', + 'bezier.c', + 'path.c', + 'paint.c', + 'arc.c', + 'image.c', + 'renderer.c', + 'stroker.c', + 'mask.c', + 'shader.c', + 'shaders_cache.c', +] - vega_sources = [ - 'api.c', - 'api_context.c', - 'api_filters.c', - 'api_images.c', - 'api_masks.c', - 'api_misc.c', - 'api_paint.c', - 'api_params.c', - 'api_path.c', - 'api_text.c', - 'api_transform.c', - 'vgu.c', - 'vg_context.c', - 'vg_manager.c', - 'vg_state.c', - 'vg_translate.c', - 'polygon.c', - 'bezier.c', - 'path.c', - 'paint.c', - 'arc.c', - 'image.c', - 'renderer.c', - 'stroker.c', - 'mask.c', - 'shader.c', - 'shaders_cache.c', - ] +# vgapi_header must be generated first +env.Depends(vega_sources, vgapi_header) - # vgapi_header must be generated first - env.Depends(vega_sources, vgapi_header) +st_vega = env.ConvenienceLibrary( + target = 'st_vega', + source = vega_sources, +) - st_vega = env.ConvenienceLibrary( - target = 'st_vega', - source = vega_sources, - ) - Export('st_vega') +Export('st_vega') diff --git a/src/gallium/state_trackers/vega/api_filters.c b/src/gallium/state_trackers/vega/api_filters.c index 8ace9853368..4bd5d7e4bc2 100644 --- a/src/gallium/state_trackers/vega/api_filters.c +++ b/src/gallium/state_trackers/vega/api_filters.c @@ -37,10 +37,8 @@ #include "pipe/p_state.h" #include "util/u_inlines.h" #include "pipe/p_screen.h" -#include "pipe/p_shader_tokens.h" #include "util/u_format.h" -#include "util/u_memory.h" #include "util/u_sampler.h" #include "util/u_string.h" diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c index c36b3d2f3c8..7054d9bb7ed 100644 --- a/src/gallium/state_trackers/vega/api_images.c +++ b/src/gallium/state_trackers/vega/api_images.c @@ -36,9 +36,7 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "util/u_inlines.h" -#include "util/u_blit.h" #include "util/u_tile.h" -#include "util/u_memory.h" static INLINE VGboolean supported_image_format(VGImageFormat format) { diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c index 94c1ff5375f..189390ec2d3 100644 --- a/src/gallium/state_trackers/vega/api_masks.c +++ b/src/gallium/state_trackers/vega/api_masks.c @@ -27,7 +27,6 @@ #include "VG/openvg.h" #include "mask.h" -#include "renderer.h" #include "api.h" #include "vg_context.h" @@ -36,7 +35,6 @@ #include "util/u_pack_color.h" #include "util/u_draw_quad.h" -#include "util/u_memory.h" #define DISABLE_1_1_MASKING 1 diff --git a/src/gallium/state_trackers/vega/api_paint.c b/src/gallium/state_trackers/vega/api_paint.c index d88341b04ff..1411806455c 100644 --- a/src/gallium/state_trackers/vega/api_paint.c +++ b/src/gallium/state_trackers/vega/api_paint.c @@ -28,7 +28,6 @@ #include "vg_context.h" #include "paint.h" -#include "image.h" #include "api.h" VGPaint vegaCreatePaint(void) diff --git a/src/gallium/state_trackers/vega/api_path.c b/src/gallium/state_trackers/vega/api_path.c index 6c9a2e8d658..f76adddb584 100644 --- a/src/gallium/state_trackers/vega/api_path.c +++ b/src/gallium/state_trackers/vega/api_path.c @@ -28,13 +28,9 @@ #include "vg_context.h" #include "path.h" -#include "polygon.h" -#include "paint.h" #include "api.h" #include "pipe/p_context.h" -#include "util/u_inlines.h" -#include "util/u_draw_quad.h" VGPath vegaCreatePath(VGint pathFormat, VGPathDatatype datatype, diff --git a/src/gallium/state_trackers/vega/api_text.c b/src/gallium/state_trackers/vega/api_text.c index b35f3be90ab..2a62da0a1de 100644 --- a/src/gallium/state_trackers/vega/api_text.c +++ b/src/gallium/state_trackers/vega/api_text.c @@ -27,7 +27,6 @@ #include "VG/openvg.h" #include "vg_context.h" -#include "api.h" #include "util/u_memory.h" diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c index c12dc71b860..28bbe420a21 100644 --- a/src/gallium/state_trackers/vega/image.c +++ b/src/gallium/state_trackers/vega/image.c @@ -32,13 +32,11 @@ #include "renderer.h" #include "util_array.h" #include "api_consts.h" -#include "shaders_cache.h" #include "shader.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "util/u_inlines.h" -#include "util/u_blit.h" #include "util/u_format.h" #include "util/u_tile.h" #include "util/u_memory.h" diff --git a/src/gallium/state_trackers/vega/paint.c b/src/gallium/state_trackers/vega/paint.c index 2c0eb6b23d2..c0c8cddabe9 100644 --- a/src/gallium/state_trackers/vega/paint.c +++ b/src/gallium/state_trackers/vega/paint.c @@ -26,7 +26,6 @@ #include "paint.h" -#include "shaders_cache.h" #include "matrix.h" #include "image.h" #include "st_inlines.h" @@ -34,7 +33,6 @@ #include "pipe/p_compiler.h" #include "util/u_inlines.h" -#include "util/u_format.h" #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_sampler.h" diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index bc94170eb96..ca8831064c9 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -29,7 +29,6 @@ #include "matrix.h" /*for floatsEqual*/ #include "vg_context.h" #include "vg_state.h" -#include "paint.h" #include "renderer.h" #include "util_array.h" #include "VG/openvg.h" diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 8c023044c45..c6f5f7a05b8 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -35,12 +35,9 @@ #include "pipe/p_shader_tokens.h" #include "util/u_draw_quad.h" -#include "util/u_format.h" #include "util/u_simple_shaders.h" #include "util/u_memory.h" -#include "util/u_rect.h" #include "util/u_sampler.h" -#include "util/u_surface.h" #include "cso_cache/cso_context.h" diff --git a/src/gallium/state_trackers/vega/shaders_cache.c b/src/gallium/state_trackers/vega/shaders_cache.c index 53e6bfcf16b..e002a7ed428 100644 --- a/src/gallium/state_trackers/vega/shaders_cache.c +++ b/src/gallium/state_trackers/vega/shaders_cache.c @@ -30,8 +30,6 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" -#include "util/u_inlines.h" -#include "pipe/p_screen.h" #include "pipe/p_shader_tokens.h" #include "tgsi/tgsi_build.h" diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index 5cb25906027..b1f98fa477d 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -37,7 +37,6 @@ #include "pipe/p_context.h" #include "util/u_inlines.h" -#include "pipe/p_shader_tokens.h" #include "cso_cache/cso_context.h" diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript index 0f580b859c6..ec55f042f90 100644 --- a/src/gallium/state_trackers/wgl/SConscript +++ b/src/gallium/state_trackers/wgl/SConscript @@ -2,41 +2,38 @@ import os Import('*') -if env['platform'] in ['windows']: - - env = env.Clone() - - env.Append(CPPPATH = [ - '#src/mapi', - '#src/mesa', - '.', - ]) - - env.AppendUnique(CPPDEFINES = [ - '_GDI32_', # prevent wgl* being declared __declspec(dllimport) - 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers - 'WIN32_THREADS', # use Win32 thread API - 'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx - ]) - - sources = [ - 'stw_context.c', - 'stw_device.c', - 'stw_ext_extensionsstring.c', - 'stw_ext_gallium.c', - 'stw_ext_pixelformat.c', - 'stw_ext_swapinterval.c', - 'stw_framebuffer.c', - 'stw_getprocaddress.c', - 'stw_pixelformat.c', - 'stw_st.c', - 'stw_tls.c', - 'stw_wgl.c', - ] +env = env.Clone() - wgl = env.ConvenienceLibrary( - target ='wgl', - source = sources, - ) - - Export('wgl') +env.Append(CPPPATH = [ + '#src/mapi', + '#src/mesa', + '.', +]) + +env.AppendUnique(CPPDEFINES = [ + '_GDI32_', # prevent wgl* being declared __declspec(dllimport) + 'BUILD_GL32', # declare gl* as __declspec(dllexport) in Mesa headers + 'WIN32_THREADS', # use Win32 thread API + 'WIN32_LEAN_AND_MEAN', # http://msdn2.microsoft.com/en-us/library/6dwk3a1z.aspx +]) + +sources = [ + 'stw_context.c', + 'stw_device.c', + 'stw_ext_extensionsstring.c', + 'stw_ext_gallium.c', + 'stw_ext_pixelformat.c', + 'stw_ext_swapinterval.c', + 'stw_framebuffer.c', + 'stw_getprocaddress.c', + 'stw_pixelformat.c', + 'stw_st.c', + 'stw_tls.c', + 'stw_wgl.c', +] + +wgl = env.ConvenienceLibrary( + target ='wgl', + source = sources, +) +Export('wgl') diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript index 0b598dab6e3..19315694b7c 100644 --- a/src/gallium/state_trackers/xorg/SConscript +++ b/src/gallium/state_trackers/xorg/SConscript @@ -3,34 +3,38 @@ Import('*') -if 'xorg' in env['statetrackers']: +env = env.Clone() - env = env.Clone() +env.Append(CPPPATH = [ + '#/src/mesa', +]) - env.Append(CPPPATH = [ - '#/src/mesa', - ]) +env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') - env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') +if env['kms']: + env.Append(CPPDEFINES = ['HAVE_LIBKMS']) - conf = env.Configure() +conf = env.Configure() - if conf.CheckHeader('X11/extensions/dpmsconst.h'): - env.Append(CPPDEFINES = [('HAVE_XEXTPROTO_71', '1')]) +if conf.CheckHeader('X11/extensions/dpmsconst.h'): + env.Append(CPPDEFINES = [('HAVE_XEXTPROTO_71', '1')]) - conf.Finish() +conf.Finish() - st_xorg = env.ConvenienceLibrary( - target = 'st_xorg', - source = [ 'xorg_composite.c', - 'xorg_crtc.c', - 'xorg_dri2.c', - 'xorg_driver.c', - 'xorg_exa.c', - 'xorg_exa_tgsi.c', - 'xorg_output.c', - 'xorg_renderer.c', - 'xorg_xv.c', - ] - ) - Export('st_xorg') +sources = [ + 'xorg_composite.c', + 'xorg_crtc.c', + 'xorg_dri2.c', + 'xorg_driver.c', + 'xorg_exa.c', + 'xorg_exa_tgsi.c', + 'xorg_output.c', + 'xorg_renderer.c', + 'xorg_xv.c', +] + +st_xorg = env.ConvenienceLibrary( + target = 'st_xorg', + source = sources, +) +Export('st_xorg') diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 1ec772df172..1ee79ae177e 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -447,7 +447,7 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags) if (!drv_init_resource_management(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Could not init " - "Gallium3D or libKMS."); + "Gallium3D or libKMS.\n"); return FALSE; } diff --git a/src/gallium/targets/Makefile.dri b/src/gallium/targets/Makefile.dri index 59961e982aa..3fb4cc6b861 100644 --- a/src/gallium/targets/Makefile.dri +++ b/src/gallium/targets/Makefile.dri @@ -80,7 +80,7 @@ $(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) Makefile \ $(OBJECTS) $(PIPE_DRIVERS) \ -Wl,--start-group $(MESA_MODULES) -Wl,--end-group \ $(DRI_LIB_DEPS) $(DRIVER_EXTRAS) - $(CXX) $(CFLAGS) -o [email protected] $(TOP)/src/mesa/drivers/dri/common/dri_test.o [email protected] $(DRI_LIB_DEPS); + $(CXX) $(CFLAGS) -o [email protected] $(TOP)/src/mesa/drivers/dri/common/dri_test.o [email protected] $(DRI_LIB_DEPS) $(LDFLAGS); @rm -f [email protected] mv -f [email protected] $@ diff --git a/src/gallium/targets/Makefile.xorg b/src/gallium/targets/Makefile.xorg index 87eedd7136c..47040bb14c8 100644 --- a/src/gallium/targets/Makefile.xorg +++ b/src/gallium/targets/Makefile.xorg @@ -42,7 +42,7 @@ endif default: depend $(TOP)/$(LIB_DIR)/gallium $(LIBNAME) $(LIBNAME_STAGING) $(LIBNAME): $(OBJECTS) Makefile ../Makefile.xorg $(LIBS) $(DRIVER_PIPES) - $(MKLIB) -linker $(CC) -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS) + $(MKLIB) -linker '$(CC)' -noprefix -o $@ $(LDFLAGS) $(OBJECTS) $(DRIVER_PIPES) $(GALLIUM_AUXILIARIES) $(DRIVER_LINKS) depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS) $(GENERATED_SOURCES) rm -f depend diff --git a/src/gallium/targets/SConscript b/src/gallium/targets/SConscript deleted file mode 100644 index e447d093610..00000000000 --- a/src/gallium/targets/SConscript +++ /dev/null @@ -1,41 +0,0 @@ -import os -Import('*') - -# Compatibility with old build scripts: -# -if 'mesa' in env['statetrackers']: - if 'xlib' in env['winsys'] and 'libgl-xlib' not in env['targets']: - env['targets'].append('libgl-xlib') - if 'gdi' in env['winsys'] and 'libgl-gdi' not in env['targets']: - env['targets'].append('libgl-gdi') - -if not 'graw-xlib' in env['targets'] and not 'graw-null' in env['targets'] and not env['msvc']: - # XXX: disable until MSVC can link correctly - SConscript('graw-null/SConscript') - - -if env['dri']: - SConscript([ - 'SConscript.dri' - ]) - -if 'xorg' in env['statetrackers']: - if 'vmware' in env['winsys']: - SConscript([ - 'xorg-vmwgfx/SConscript', - ]) - -if 'egl' in env['statetrackers']: - SConscript([ - 'egl-gdi/SConscript', - ]) - -# Ideally all non-target directories would produce convenience -# libraries, and the actual shared libraries and other installables -# would be finally assembled in the targets subtree: -# -for target in env['targets']: - SConscript(os.path.join(target, 'SConscript')) - - - diff --git a/src/gallium/targets/SConscript.dri b/src/gallium/targets/SConscript.dri index bc8d179e3d9..bc3671a256b 100644 --- a/src/gallium/targets/SConscript.dri +++ b/src/gallium/targets/SConscript.dri @@ -3,68 +3,71 @@ Import('*') +if not env['dri']: + Return() + drienv = env.Clone() drienv.Replace(CPPPATH = [ - '#src/mesa/drivers/dri/common', - '#include', - '#include/GL/internal', - '#src/mapi', - '#src/gallium/include', - '#src/gallium/auxiliary', - '#src/gallium/drivers', - '#src/gallium/winsys', - '#src/mesa', - '#src/mesa/main', - '#src/mesa/glapi', - '#src/mesa/math', - '#src/mesa/transform', - '#src/mesa/shader', - '#src/mesa/swrast', - '#src/mesa/swrast_setup', - '#src/egl/main', - '#src/egl/drivers/dri', + '#src/mesa/drivers/dri/common', + '#include', + '#include/GL/internal', + '#src/mapi', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/gallium/winsys', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', ]) drienv.ParseConfig('pkg-config --cflags --libs libdrm') dri_common_utils = drienv.SharedObject( - target = 'utils.o', - source = '#src/mesa/drivers/dri/common/utils.c' + target = 'utils.o', + source = '#src/mesa/drivers/dri/common/utils.c' ) dri_common_xmlconfig = drienv.SharedObject( - target = 'xmlconfig.o', - source = '#src/mesa/drivers/dri/common/xmlconfig.c' + target = 'xmlconfig.o', + source = '#src/mesa/drivers/dri/common/xmlconfig.c' ) dri_common_vblank = drienv.SharedObject( - target = 'vblank.o', - source = '#src/mesa/drivers/dri/common/vblank.c' + target = 'vblank.o', + source = '#src/mesa/drivers/dri/common/vblank.c' ) dri_common_dri_util = drienv.SharedObject( - target = 'dri_util.o', - source = '#src/mesa/drivers/dri/common/dri_util.c' + target = 'dri_util.o', + source = '#src/mesa/drivers/dri/common/dri_util.c' ) dri_common_drisw_util = drienv.SharedObject( - target = 'drisw_util.o', - source = '#src/mesa/drivers/dri/common/drisw_util.c' + target = 'drisw_util.o', + source = '#src/mesa/drivers/dri/common/drisw_util.c' ) COMMON_DRI_SW_OBJECTS = [ - dri_common_utils, - dri_common_xmlconfig, - dri_common_drisw_util, + dri_common_utils, + dri_common_xmlconfig, + dri_common_drisw_util, ] COMMON_DRI_DRM_OBJECTS = [ - dri_common_utils, - dri_common_xmlconfig, - dri_common_vblank, - dri_common_dri_util, + dri_common_utils, + dri_common_xmlconfig, + dri_common_vblank, + dri_common_dri_util, ] drienv.AppendUnique(LIBS = [ @@ -73,36 +76,7 @@ drienv.AppendUnique(LIBS = [ ]) Export([ - 'drienv', - 'COMMON_DRI_SW_OBJECTS', - 'COMMON_DRI_DRM_OBJECTS', -]) - -SConscript([ - 'dri-swrast/SConscript', + 'drienv', + 'COMMON_DRI_SW_OBJECTS', + 'COMMON_DRI_DRM_OBJECTS', ]) - -if 'vmware' in env['winsys']: - SConscript([ - 'dri-vmwgfx/SConscript', - ]) - -if 'i915' in env['winsys']: - SConscript([ - 'dri-i915/SConscript', - ]) - -if 'i965' in env['winsys']: - SConscript([ - 'dri-i965/SConscript', - ]) - -if 'radeon' in env['winsys']: - SConscript([ - 'dri-radeong/SConscript', - ]) - -if 'r600' in env['winsys']: - SConscript([ - 'dri-r600/SConscript', - ]) diff --git a/src/gallium/targets/dri-i915/SConscript b/src/gallium/targets/dri-i915/SConscript index 172f92d6b82..ab60013830e 100644 --- a/src/gallium/targets/dri-i915/SConscript +++ b/src/gallium/targets/dri-i915/SConscript @@ -1,9 +1,5 @@ Import('*') -if not 'i915' in env['drivers']: - print 'warning: i915 pipe driver not built skipping i915_dri.so' - Return() - env = drienv.Clone() env.ParseConfig('pkg-config --cflags --libs libdrm_intel') @@ -24,8 +20,10 @@ env.Prepend(LIBS = [ COMMON_DRI_DRM_OBJECTS ]) -env.LoadableModule( +module = env.LoadableModule( target = 'i915_dri.so', source = 'target.c', SHLIBPREFIX = '', ) + +env.Alias('dri-i915', module)
\ No newline at end of file diff --git a/src/gallium/targets/dri-i965/SConscript b/src/gallium/targets/dri-i965/SConscript index 684e3488f71..669f70d6b8d 100644 --- a/src/gallium/targets/dri-i965/SConscript +++ b/src/gallium/targets/dri-i965/SConscript @@ -1,9 +1,5 @@ Import('*') -if not 'i965' in env['drivers']: - print 'warning: i965 pipe driver not built skipping i965_dri.so' - Return() - env = drienv.Clone() env.ParseConfig('pkg-config --cflags --libs libdrm_intel') @@ -27,8 +23,10 @@ env.Prepend(LIBS = [ COMMON_DRI_DRM_OBJECTS ]) -env.LoadableModule( +module = env.LoadableModule( target = 'i965_dri.so', source = 'target.c', SHLIBPREFIX = '', ) + +env.Alias('dri-i965', module)
\ No newline at end of file diff --git a/src/gallium/targets/dri-r300/SConscript b/src/gallium/targets/dri-r300/SConscript index 33a458f2e68..005b4bbf7f1 100644 --- a/src/gallium/targets/dri-r300/SConscript +++ b/src/gallium/targets/dri-r300/SConscript @@ -1,9 +1,5 @@ Import('*') -if not 'r300' in env['drivers']: - print 'warning: r300 pipe driver not built skipping r300_dri.so' - Return() - env = drienv.Clone() env.ParseConfig('pkg-config --cflags --libs libdrm_radeon') @@ -23,8 +19,10 @@ env.Prepend(LIBS = [ COMMON_DRI_DRM_OBJECTS ]) -env.SharedLibrary( +module = env.SharedLibrary( target ='r300_dri.so', source = 'target.c', SHLIBPREFIX = '', ) + +env.Alias('dri-r300', module)
\ No newline at end of file diff --git a/src/gallium/targets/dri-r600/SConscript b/src/gallium/targets/dri-r600/SConscript index 64d6d2a7f6f..aa771db2d1a 100644 --- a/src/gallium/targets/dri-r600/SConscript +++ b/src/gallium/targets/dri-r600/SConscript @@ -1,9 +1,5 @@ Import('*') -if not 'r600' in env['drivers']: - print 'warning: r600 pipe driver not built skipping r600_dri.so' - Return() - env = drienv.Clone() env.ParseConfig('pkg-config --cflags --libs libdrm_radeon') @@ -22,8 +18,10 @@ env.Prepend(LIBS = [ COMMON_DRI_DRM_OBJECTS ]) -env.SharedLibrary( +module = env.SharedLibrary( target ='r600_dri.so', source = 'target.c', SHLIBPREFIX = '', ) + +env.Alias('dri-r600', module) diff --git a/src/gallium/targets/dri-swrast/SConscript b/src/gallium/targets/dri-swrast/SConscript index d8143471194..b67483800e4 100644 --- a/src/gallium/targets/dri-swrast/SConscript +++ b/src/gallium/targets/dri-swrast/SConscript @@ -27,15 +27,16 @@ if True: if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') env.Prepend(LIBS = [llvmpipe]) swrastg_sources = [ 'swrast_drm_api.c' ] -env.LoadableModule( +module = env.LoadableModule( target ='swrastg_dri.so', source = swrastg_sources, SHLIBPREFIX = '', ) + +env.Alias('dri-swrast', module) diff --git a/src/gallium/targets/dri-vmwgfx/Makefile b/src/gallium/targets/dri-vmwgfx/Makefile index 97c703b3739..38f78932e13 100644 --- a/src/gallium/targets/dri-vmwgfx/Makefile +++ b/src/gallium/targets/dri-vmwgfx/Makefile @@ -12,6 +12,7 @@ PIPE_DRIVERS = \ C_SOURCES = \ target.c \ + vmw_powf.c \ $(COMMON_GALLIUM_SOURCES) DRIVER_DEFINES = \ diff --git a/src/gallium/targets/dri-vmwgfx/SConscript b/src/gallium/targets/dri-vmwgfx/SConscript index 7afabc7429f..7888e4f2c8b 100644 --- a/src/gallium/targets/dri-vmwgfx/SConscript +++ b/src/gallium/targets/dri-vmwgfx/SConscript @@ -1,9 +1,5 @@ Import('*') -if not 'svga' in env['drivers']: - print 'warning: svga pipe driver not built skipping vmwgfx_dri.so' - Return() - env = drienv.Clone() env.Append(CPPDEFINES = ['GALLIUM_RBUG', 'GALLIUM_TRACE']) @@ -20,8 +16,10 @@ env.Prepend(LIBS = [ COMMON_DRI_DRM_OBJECTS ]) -env.LoadableModule( +module = env.LoadableModule( target = 'vmwgfx_dri.so', source = 'target.c', SHLIBPREFIX = '', ) + +env.Alias('dri-vmwgfx', module)
\ No newline at end of file diff --git a/src/gallium/targets/dri-vmwgfx/vmw_powf.c b/src/gallium/targets/dri-vmwgfx/vmw_powf.c new file mode 100644 index 00000000000..ca5e39b389a --- /dev/null +++ b/src/gallium/targets/dri-vmwgfx/vmw_powf.c @@ -0,0 +1,17 @@ +/** + * Powf may leave an unresolved symbol pointing to a libstdc++.so powf. + * However, not all libstdc++.so include this function, so optionally + * replace the powf function with calls to expf and logf. + */ + +#ifdef VMW_RESOLVE_POWF + +extern float expf(float x); +extern float logf(float x); +extern float powf(float x, float y); + +float powf(float x, float y) { + return expf(logf(x)*y); +} + +#endif diff --git a/src/gallium/targets/egl-gdi/SConscript b/src/gallium/targets/egl-gdi/SConscript index 8f8b28ef67b..d52eeb70fd5 100644 --- a/src/gallium/targets/egl-gdi/SConscript +++ b/src/gallium/targets/egl-gdi/SConscript @@ -3,45 +3,53 @@ Import('*') -if env['platform'] == 'windows': - - env = env.Clone() - - env.Append(CPPPATH = [ - '#/src/gallium/state_trackers/egl', - '#/src/gallium/state_trackers/vega', - '#/src/egl/main', - '#/src/mesa', - ]) - - env.Append(CPPDEFINES = [ - 'FEATURE_VG=1', - 'GALLIUM_SOFTPIPE', - 'GALLIUM_RBUG', - 'GALLIUM_TRACE', - ]) - - env.Append(LIBS = [ - 'gdi32', - 'user32', - 'kernel32', - 'ws2_32', - ]) - - env['no_import_lib'] = 1 - - drivers = [softpipe] - if env['llvm']: - env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - drivers += [llvmpipe] - drivers += [identity, trace, rbug] - - apis = [vgapi, st_vega] - - egl_gallium = env.SharedLibrary( - target ='egl_gallium', - source = 'egl-static.c', - LIBS = st_egl_gdi + ws_gdi + drivers + apis + gallium + egl + env['LIBS'], - ) - - env.InstallSharedLibrary(egl_gallium) +env = env.Clone() + +env.Append(CPPPATH = [ + '#/src/gallium/state_trackers/egl', + '#/src/gallium/state_trackers/vega', + '#/src/egl/main', + '#/src/mesa', +]) + +env.Append(CPPDEFINES = [ + 'FEATURE_VG=1', + 'GALLIUM_SOFTPIPE', + 'GALLIUM_RBUG', + 'GALLIUM_TRACE', +]) + +env.Append(LIBS = [ + 'gdi32', + 'user32', + 'kernel32', + 'ws2_32', +]) + +env.Prepend(LIBS = [ + st_egl_gdi, + ws_gdi, + identity, + trace, + rbug, + softpipe, + vgapi, + st_vega, + gallium, + egl, +]) + +if env['llvm']: + env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') + env.Prepend(LIBS = [llvmpipe]) + +egl_gallium = env.SharedLibrary( + target ='egl_gallium', + source = 'egl-static.c', +) + +env['no_import_lib'] = 1 + +egl_gdi = env.InstallSharedLibrary(egl_gallium) + +env.Alias('egl-gdi', egl_gdi) diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index 57979c4e9d4..63e9352144e 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -54,9 +54,8 @@ egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a endif # EGL_RENDERABLE_TYPE is a compile time attribute -egl_CPPFLAGS += $(API_DEFINES) ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),) -egl_CPPFLAGS += -DFEATURE_GL=1 +egl_CPPFLAGS += $(API_DEFINES) endif ifneq ($(filter $(GLESv1_CM_LIB), $(EGL_CLIENT_APIS)),) egl_CPPFLAGS += -DFEATURE_ES1=1 diff --git a/src/gallium/targets/graw-gdi/SConscript b/src/gallium/targets/graw-gdi/SConscript new file mode 100644 index 00000000000..8ee8915acec --- /dev/null +++ b/src/gallium/targets/graw-gdi/SConscript @@ -0,0 +1,41 @@ +####################################################################### +# SConscript for graw-gdi + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#src/gallium/winsys/sw', +]) + +env.Prepend(LIBS = [ + gallium, + 'gdi32', + identity, + rbug, + trace, + 'user32', + 'ws2_32', +]) + +sources = [ + 'graw_gdi.c', + graw_util, +] + +env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') +env.Prepend(LIBS = [softpipe]) + +graw = env.SharedLibrary( + target = 'graw', + source = sources, + LIBS = ws_gdi + env['LIBS'], +) + +if env['platform'] == 'windows': + graw = env.FindIxes(graw, 'LIBPREFIX', 'LIBSUFFIX') +else: + graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX') + +env.Alias('graw-gdi', graw) diff --git a/src/gallium/targets/graw-gdi/graw_gdi.c b/src/gallium/targets/graw-gdi/graw_gdi.c new file mode 100644 index 00000000000..bd6242b0779 --- /dev/null +++ b/src/gallium/targets/graw-gdi/graw_gdi.c @@ -0,0 +1,157 @@ +/************************************************************************** + * + * Copyright 2010 VMware, Inc. + * 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 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 + * THE COPYRIGHT HOLDERS, AUTHORS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * + **************************************************************************/ + +#include "gdi/gdi_sw_winsys.h" +#include "pipe/p_screen.h" +#include "state_tracker/graw.h" +#include "target-helpers/wrap_screen.h" +#include "target-helpers/inline_sw_helper.h" +#include <windows.h> + + +static LRESULT CALLBACK +window_proc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) { + case WM_DESTROY: + PostQuitMessage(0); + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + + return 0; +} + +static struct { + void (* draw)(void); +} graw; + +struct pipe_screen * +graw_create_window_and_screen(int x, + int y, + unsigned width, + unsigned height, + enum pipe_format format, + void **handle) +{ + struct sw_winsys *winsys = NULL; + struct pipe_screen *screen = NULL; + WNDCLASSEX wc = {sizeof(wc)}; + UINT style = WS_VISIBLE | WS_TILEDWINDOW; + RECT rect; + HWND hWnd = NULL; + HDC hDC = NULL; + + if (format != PIPE_FORMAT_R8G8B8A8_UNORM) + goto fail; + + winsys = gdi_create_sw_winsys(); + if (winsys == NULL) + goto fail; + + screen = sw_screen_create(winsys); + if (screen == NULL) + goto fail; + + wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = window_proc; + wc.lpszClassName = "graw-gdi"; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + RegisterClassEx(&wc); + + SetRect(&rect, 0, 0, width, height); + AdjustWindowRectEx(&rect, style, FALSE, 0); + + hWnd = CreateWindowEx(0, + wc.lpszClassName, + wc.lpszClassName, + style, + x, + y, + rect.right - rect.left, + rect.bottom - rect.top, + NULL, + NULL, + wc.hInstance, + 0); + if (hWnd == NULL) + goto fail; + + hDC = GetDC(hWnd); + if (hDC == NULL) + goto fail; + + *handle = (void *)hDC; + + return gallium_wrap_screen(screen); + +fail: + if (hWnd) + DestroyWindow(hWnd); + + if (screen) + screen->destroy(screen); + + return NULL; +} + +void +graw_set_display_func(void (* draw)(void)) +{ + graw.draw = draw; +} + +void +graw_main_loop(void) +{ + for (;;) { + MSG msg; + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + if (msg.message == WM_QUIT) { + return; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + + if (graw.draw) { + graw.draw(); + } + + Sleep(0); + } +} diff --git a/src/gallium/targets/graw-null/SConscript b/src/gallium/targets/graw-null/SConscript index 3416989d8eb..ebac1728f04 100644 --- a/src/gallium/targets/graw-null/SConscript +++ b/src/gallium/targets/graw-null/SConscript @@ -5,54 +5,28 @@ Import('*') env = env.Clone() -env.Prepend(LIBS = [ - ws_null, - trace, - rbug, - identity, -# gallium, -]) - -env.Append(CPPPATH = [ - '#src/gallium/drivers', -]) +graw_util = env.SharedObject( + source = ['graw_util.c'], +) -if env['platform'] == 'windows': - # For trace - env.Append(LIBS = [ - 'ws2_32', - ]) +env = env.Clone() sources = [ 'graw_null.c', - '../graw-xlib/graw_util.c', + graw_util, ] -if True: - env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') - env.Prepend(LIBS = [softpipe]) - -if env['llvm']: - env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') - env.Prepend(LIBS = [llvmpipe]) - -# Need this for trace, identity drivers referenced by -# gallium_wrap_screen(). -# env.Prepend(LIBS = [gallium]) # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions graw = env.SharedLibrary( - target ='graw', + target = 'graw', source = sources, ) -env.InstallSharedLibrary(graw, version=(1, 0)) - if env['platform'] == 'windows': graw = env.FindIxes(graw, 'LIBPREFIX', 'LIBSUFFIX') else: graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX') -Export('graw') +Export('graw_util', 'graw') diff --git a/src/gallium/targets/graw-null/graw_null.c b/src/gallium/targets/graw-null/graw_null.c index 5939a5acd3c..f1fe3872c94 100644 --- a/src/gallium/targets/graw-null/graw_null.c +++ b/src/gallium/targets/graw-null/graw_null.c @@ -1,31 +1,5 @@ -#include "pipe/p_compiler.h" -#include "util/u_debug.h" -#include "util/u_memory.h" -#include "target-helpers/wrap_screen.h" -#include "sw/null/null_sw_winsys.h" -#include "os/os_time.h" #include "state_tracker/graw.h" -#ifdef GALLIUM_SOFTPIPE -#include "softpipe/sp_public.h" -#endif - -#ifdef GALLIUM_LLVMPIPE -#include "llvmpipe/lp_public.h" -#endif - -/* Haven't figured out a decent way to build the helper code yet - - * #include it here temporarily. - */ -#include "sw/sw_public.h" -#include "sw/sw.c" - -#include <stdio.h> - - -static struct { - void (*draw)(void); -} graw; @@ -37,45 +11,7 @@ graw_create_window_and_screen( int x, enum pipe_format format, void **handle) { - const char *default_driver; - const char *driver; - struct pipe_screen *screen = NULL; - struct sw_winsys *winsys = NULL; - static int dummy; - - - /* Create the underlying winsys, which performs presents to Xlib - * drawables: - */ - winsys = null_sw_create(); - if (winsys == NULL) - return NULL; - -#if defined(GALLIUM_LLVMPIPE) - default_driver = "llvmpipe"; -#elif defined(GALLIUM_SOFTPIPE) - default_driver = "softpipe"; -#else - default_driver = ""; -#endif - - driver = debug_get_option("GALLIUM_DRIVER", default_driver); - -#if defined(GALLIUM_LLVMPIPE) - if (screen == NULL && strcmp(driver, "llvmpipe") == 0) - screen = llvmpipe_create_screen( winsys ); -#endif - -#if defined(GALLIUM_SOFTPIPE) - if (screen == NULL) - screen = softpipe_create_screen( winsys ); -#endif - - *handle = &dummy; - - /* Inject any wrapping layers we want to here: - */ - return gallium_wrap_screen( screen ); + return NULL; } @@ -83,13 +19,10 @@ graw_create_window_and_screen( int x, void graw_set_display_func( void (*draw)( void ) ) { - graw.draw = draw; } void graw_main_loop( void ) { - graw.draw(); - os_time_sleep(100000); } diff --git a/src/gallium/targets/graw-null/graw_util.c b/src/gallium/targets/graw-null/graw_util.c new file mode 100644 index 00000000000..e5cf526d33a --- /dev/null +++ b/src/gallium/targets/graw-null/graw_util.c @@ -0,0 +1,92 @@ + +#include "pipe/p_compiler.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "tgsi/tgsi_text.h" +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "state_tracker/graw.h" + + +/* Helper functions. These are the same for all graw implementations. + */ +PUBLIC void * +graw_parse_geometry_shader(struct pipe_context *pipe, + const char *text) +{ + struct tgsi_token tokens[1024]; + struct pipe_shader_state state; + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) + return NULL; + + state.tokens = tokens; + return pipe->create_gs_state(pipe, &state); +} + +PUBLIC void * +graw_parse_vertex_shader(struct pipe_context *pipe, + const char *text) +{ + struct tgsi_token tokens[1024]; + struct pipe_shader_state state; + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) + return NULL; + + state.tokens = tokens; + return pipe->create_vs_state(pipe, &state); +} + +PUBLIC void * +graw_parse_fragment_shader(struct pipe_context *pipe, + const char *text) +{ + struct tgsi_token tokens[1024]; + struct pipe_shader_state state; + + if (!tgsi_text_translate(text, tokens, Elements(tokens))) + return NULL; + + state.tokens = tokens; + return pipe->create_fs_state(pipe, &state); +} + +static char out_filename[256] = ""; + +PUBLIC boolean +graw_parse_args(int *argi, + int argc, + char *argv[]) +{ + if (strcmp(argv[*argi], "-o") == 0) { + if (*argi + 1 >= argc) { + return FALSE; + } + + strncpy(out_filename, argv[*argi + 1], sizeof(out_filename) - 1); + out_filename[sizeof(out_filename) - 1] = '\0'; + *argi += 2; + return TRUE; + } + + return FALSE; +} + +PUBLIC boolean +graw_save_surface_to_file(struct pipe_context *pipe, + struct pipe_surface *surface, + const char *filename) +{ + if (!filename || !*filename) { + filename = out_filename; + if (!filename || !*filename) { + return FALSE; + } + } + + /* XXX: Make that working in release builds. + */ + debug_dump_surface_bmp(pipe, filename, surface); + return TRUE; +} diff --git a/src/gallium/targets/graw-xlib/SConscript b/src/gallium/targets/graw-xlib/SConscript index 21fce948f43..e50eb8a03d7 100644 --- a/src/gallium/targets/graw-xlib/SConscript +++ b/src/gallium/targets/graw-xlib/SConscript @@ -3,56 +3,41 @@ Import('*') -if env['platform'] != 'linux': - Return() - env = env.Clone() -env.Tool('x11') - env.Prepend(LIBS = [ ws_xlib, trace, rbug, identity, -# gallium, + gallium, ]) +env.Prepend(LIBS = env['X11_LIBS']) + env.Append(CPPPATH = [ '#src/gallium/drivers', '#src/gallium/include/state_tracker', ]) - sources = [ 'graw_xlib.c', - 'graw_util.c', + graw_util ] -env.Tool('x11') - if True: env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') env.Prepend(LIBS = [softpipe]) if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') env.Prepend(LIBS = [llvmpipe]) -# Need this for trace, identity drivers referenced by -# gallium_wrap_screen(). -# -env.Prepend(LIBS = [gallium]) - -# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions graw = env.SharedLibrary( target ='graw', source = sources, ) -env.InstallSharedLibrary(graw, version=(1, 0)) - -graw = env.FindIxes(graw, 'SHLIBPREFIX', 'SHLIBSUFFIX') +graw = env.InstallSharedLibrary(graw, version=(1, 0)) -Export('graw') +env.Alias('graw-xlib', graw) diff --git a/src/gallium/targets/graw-xlib/graw_util.c b/src/gallium/targets/graw-xlib/graw_util.c deleted file mode 100644 index fc7c9ae6f92..00000000000 --- a/src/gallium/targets/graw-xlib/graw_util.c +++ /dev/null @@ -1,50 +0,0 @@ - -#include "pipe/p_compiler.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "tgsi/tgsi_text.h" -#include "util/u_memory.h" -#include "state_tracker/graw.h" - - -/* Helper functions. These are the same for all graw implementations. - */ -void *graw_parse_geometry_shader(struct pipe_context *pipe, - const char *text) -{ - struct tgsi_token tokens[1024]; - struct pipe_shader_state state; - - if (!tgsi_text_translate(text, tokens, Elements(tokens))) - return NULL; - - state.tokens = tokens; - return pipe->create_gs_state(pipe, &state); -} - -void *graw_parse_vertex_shader(struct pipe_context *pipe, - const char *text) -{ - struct tgsi_token tokens[1024]; - struct pipe_shader_state state; - - if (!tgsi_text_translate(text, tokens, Elements(tokens))) - return NULL; - - state.tokens = tokens; - return pipe->create_vs_state(pipe, &state); -} - -void *graw_parse_fragment_shader(struct pipe_context *pipe, - const char *text) -{ - struct tgsi_token tokens[1024]; - struct pipe_shader_state state; - - if (!tgsi_text_translate(text, tokens, Elements(tokens))) - return NULL; - - state.tokens = tokens; - return pipe->create_fs_state(pipe, &state); -} - diff --git a/src/gallium/targets/graw-xlib/graw_xlib.c b/src/gallium/targets/graw-xlib/graw_xlib.c index 8b64a0b819c..8658e19e3a3 100644 --- a/src/gallium/targets/graw-xlib/graw_xlib.c +++ b/src/gallium/targets/graw-xlib/graw_xlib.c @@ -4,22 +4,8 @@ #include "util/u_debug.h" #include "util/u_memory.h" #include "target-helpers/wrap_screen.h" +#include "target-helpers/inline_sw_helper.h" #include "state_tracker/xlib_sw_winsys.h" - -#ifdef GALLIUM_SOFTPIPE -#include "softpipe/sp_public.h" -#endif - -#ifdef GALLIUM_LLVMPIPE -#include "llvmpipe/lp_public.h" -#endif - -/* Haven't figured out a decent way to build the helper code yet - - * #include it here temporarily. - */ -#include "sw/sw_public.h" -#include "sw/sw.c" - #include "state_tracker/graw.h" #include <X11/Xlib.h> @@ -36,8 +22,6 @@ static struct { static struct pipe_screen * graw_create_screen( void ) { - const char *default_driver; - const char *driver; struct pipe_screen *screen = NULL; struct sw_winsys *winsys = NULL; @@ -48,25 +32,7 @@ graw_create_screen( void ) if (winsys == NULL) return NULL; -#if defined(GALLIUM_LLVMPIPE) - default_driver = "llvmpipe"; -#elif defined(GALLIUM_SOFTPIPE) - default_driver = "softpipe"; -#else - default_driver = ""; -#endif - - driver = debug_get_option("GALLIUM_DRIVER", default_driver); - -#if defined(GALLIUM_LLVMPIPE) - if (screen == NULL && strcmp(driver, "llvmpipe") == 0) - screen = llvmpipe_create_screen( winsys ); -#endif - -#if defined(GALLIUM_SOFTPIPE) - if (screen == NULL) - screen = softpipe_create_screen( winsys ); -#endif + screen = sw_screen_create( winsys ); /* Inject any wrapping layers we want to here: */ @@ -74,9 +40,6 @@ graw_create_screen( void ) } - - - struct pipe_screen * graw_create_window_and_screen( int x, int y, diff --git a/src/gallium/targets/libgl-gdi/SConscript b/src/gallium/targets/libgl-gdi/SConscript index 12fe403f62f..339238756ab 100644 --- a/src/gallium/targets/libgl-gdi/SConscript +++ b/src/gallium/targets/libgl-gdi/SConscript @@ -3,45 +3,46 @@ Import('*') -if env['platform'] == 'windows': - - env = env.Clone() - - env.Append(CPPPATH = [ - '#src/gallium/state_trackers/wgl', - '#src/gallium/winsys/sw', - ]) - - env.Append(LIBS = [ - 'gdi32', - 'user32', - 'kernel32', - 'ws2_32', - talloc, - ]) - - sources = [] - drivers = [] - - if True: - sources = ['gdi_softpipe_winsys.c'] - drivers = [softpipe] - - if env['llvm']: - sources = ['gdi_llvmpipe_winsys.c'] - drivers = [llvmpipe] - - if env['gcc']: - sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def'] - else: - sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] - - drivers += [trace, rbug] - - env['no_import_lib'] = 1 - - env.SharedLibrary( - target ='opengl32', - source = sources, - LIBS = wgl + ws_gdi + glapi + mesa + drivers + gallium + glsl + env['LIBS'], - ) +env = env.Clone() + +env.Append(CPPPATH = [ + '#src/gallium/state_trackers/wgl', + '#src/gallium/winsys/sw', +]) + +env.Append(LIBS = [ + 'gdi32', + 'user32', + 'kernel32', + 'ws2_32', + talloc, +]) + +sources = [] +drivers = [] + +if True: + sources = ['gdi_softpipe_winsys.c'] + drivers = [softpipe] + +if env['llvm']: + sources = ['gdi_llvmpipe_winsys.c'] + drivers = [llvmpipe] + +if env['gcc']: + sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def'] +else: + sources += ['#src/gallium/state_trackers/wgl/opengl32.def'] + +drivers += [trace, rbug] + +env['no_import_lib'] = 1 + +opengl32 = env.SharedLibrary( + target ='opengl32', + source = sources, + LIBS = wgl + ws_gdi + glapi + mesa + drivers + gallium + glsl + env['LIBS'], +) + +env.Alias('opengl32', opengl32) +env.Alias('libgl-gdi', opengl32) diff --git a/src/gallium/targets/libgl-xlib/SConscript b/src/gallium/targets/libgl-xlib/SConscript index 27b562e1d5d..582760eac93 100644 --- a/src/gallium/targets/libgl-xlib/SConscript +++ b/src/gallium/targets/libgl-xlib/SConscript @@ -3,17 +3,6 @@ Import('*') -if env['platform'] != 'linux': - Return() - -if 'mesa' not in env['statetrackers']: - print 'warning: Mesa state tracker disabled: skipping build of xlib libGL.so' - Return() - -if env['dri']: - print 'warning: DRI enabled: skipping build of xlib libGL.so' - Return() - env = env.Clone() env.Append(CPPPATH = [ @@ -25,6 +14,8 @@ env.Append(CPPPATH = [ env.Append(CPPDEFINES = ['USE_XSHM']) +env.Prepend(LIBS = env['X11_LIBS']) + env.Prepend(LIBS = [ st_xlib, ws_xlib, @@ -42,8 +33,6 @@ sources = [ 'xlib.c', ] -env.Tool('x11') - if True: env.Append(CPPDEFINES = 'GALLIUM_SOFTPIPE') env.Prepend(LIBS = [softpipe]) @@ -54,10 +43,10 @@ if True: if env['llvm']: env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE') - env.Tool('udis86') env.Prepend(LIBS = [llvmpipe]) -if 'cell' in env['drivers']: +if False: + # TODO: Detect Cell SDK env.Append(CPPDEFINES = 'GALLIUM_CELL') env.Prepend(LIBS = [cell]) @@ -67,6 +56,8 @@ libgl = env.SharedLibrary( source = sources, ) -if not env['dri']: - # Only install this libGL.so if DRI not enabled - env.InstallSharedLibrary(libgl, version=(1, 5)) +if True: + # XXX: Only install this libGL.so if DRI not enabled + libgl = env.InstallSharedLibrary(libgl, version=(1, 5)) + +env.Alias('libgl-xlib', libgl) diff --git a/src/gallium/targets/libgl-xlib/xlib.c b/src/gallium/targets/libgl-xlib/xlib.c index 2f8cd2d404a..b0d1e529104 100644 --- a/src/gallium/targets/libgl-xlib/xlib.c +++ b/src/gallium/targets/libgl-xlib/xlib.c @@ -33,92 +33,17 @@ #include "pipe/p_compiler.h" #include "util/u_debug.h" #include "target-helpers/wrap_screen.h" +#include "target-helpers/inline_sw_helper.h" #include "state_tracker/xlib_sw_winsys.h" #include "xm_public.h" #include "state_tracker/st_api.h" #include "state_tracker/st_gl_api.h" -/* Helper function to choose and instantiate one of the software rasterizers: - * cell, llvmpipe, softpipe. - * - * This function could be shared, but currently causes headaches for - * the build systems, particularly scons if we try. Long term, want - * to avoid having global #defines for things like GALLIUM_LLVMPIPE, - * GALLIUM_CELL, etc. Scons already eliminates those #defines, so - * things that are painful for it now are likely to be painful for - * other build systems in the future. - * - * Copies (full or partial): - * targets/libgl-xlib - * targets/graw-xlib - * targets/dri-swrast - * winsys/sw/drm - * drivers/sw - * - */ - -#ifdef GALLIUM_SOFTPIPE -#include "softpipe/sp_public.h" -#endif - -#ifdef GALLIUM_LLVMPIPE -#include "llvmpipe/lp_public.h" -#endif - -#ifdef GALLIUM_CELL -#include "cell/ppu/cell_public.h" -#endif - -#ifdef GALLIUM_GALAHAD -#include "galahad/glhd_public.h" -#endif - -static struct pipe_screen * -swrast_create_screen(struct sw_winsys *winsys) -{ - const char *default_driver; - const char *driver; - struct pipe_screen *screen = NULL; - -#if defined(GALLIUM_CELL) - default_driver = "cell"; -#elif defined(GALLIUM_LLVMPIPE) - default_driver = "llvmpipe"; -#elif defined(GALLIUM_SOFTPIPE) - default_driver = "softpipe"; -#else - default_driver = ""; -#endif - - driver = debug_get_option("GALLIUM_DRIVER", default_driver); - -#if defined(GALLIUM_CELL) - if (screen == NULL && strcmp(driver, "cell") == 0) - screen = cell_create_screen( winsys ); -#endif - -#if defined(GALLIUM_LLVMPIPE) - if (screen == NULL && strcmp(driver, "llvmpipe") == 0) - screen = llvmpipe_create_screen( winsys ); -#endif - -#if defined(GALLIUM_SOFTPIPE) - if (screen == NULL) - screen = softpipe_create_screen( winsys ); -#endif - #if defined(GALLIUM_GALAHAD) - if (screen) { - struct pipe_screen *galahad_screen = galahad_screen_create(screen); - if (galahad_screen) - screen = galahad_screen; - } +#include "galahad/glhd_public.h" #endif - return screen; -} - /* Helper function to build a subset of a driver stack consisting of * one of the software rasterizers (cell, llvmpipe, softpipe) and the * xlib winsys. @@ -138,10 +63,19 @@ swrast_xlib_create_screen( Display *display ) /* Create a software rasterizer on top of that winsys: */ - screen = swrast_create_screen( winsys ); + screen = sw_screen_create( winsys ); if (screen == NULL) goto fail; + /* XXX will fix soon */ +#if defined(GALLIUM_GALAHAD) + if (screen) { + struct pipe_screen *galahad_screen = galahad_screen_create( screen ); + if (galahad_screen) + screen = galahad_screen; + } +#endif + /* Inject any wrapping layers we want to here: */ return gallium_wrap_screen( screen ); @@ -195,7 +129,6 @@ extern void (*linker_foo(const unsigned char *procName))() #include "GL/gl.h" #include "glapi/glapi.h" #include "glapi/glapitable.h" -#include "glapi/glapidispatch.h" #if defined(USE_MGL_NAMESPACE) #define NAME(func) mgl##func @@ -204,10 +137,10 @@ extern void (*linker_foo(const unsigned char *procName))() #endif #define DISPATCH(FUNC, ARGS, MESSAGE) \ - CALL_ ## FUNC(GET_DISPATCH(), ARGS); + GET_DISPATCH()->FUNC ARGS #define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ - return CALL_ ## FUNC(GET_DISPATCH(), ARGS); + return GET_DISPATCH()->FUNC ARGS /* skip normal ones */ #define _GLAPI_SKIP_NORMAL_ENTRY_POINTS diff --git a/src/gallium/targets/xorg-vmwgfx/SConscript b/src/gallium/targets/xorg-vmwgfx/SConscript index 43b2c74f9ce..099d49cf1b7 100644 --- a/src/gallium/targets/xorg-vmwgfx/SConscript +++ b/src/gallium/targets/xorg-vmwgfx/SConscript @@ -2,62 +2,62 @@ import os.path Import('*') -if not 'svga' in env['drivers']: - print 'warning: svga pipe driver not built skipping vmwgfx_drv.so' - Return() - -if env['platform'] == 'linux': - - env = env.Clone() - - env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') - - env.Prepend(CPPPATH = [ - '#/include', - '#/src/gallium', - '#/src/mesa', - '#/src/gallium/drivers/svga', - '#/src/gallium/drivers/svga/include', - ]) - - env.Append(CPPDEFINES = [ - ]) - - if env['gcc']: - env.Append(CPPDEFINES = [ - 'HAVE_STDINT_H', - 'HAVE_SYS_TYPES_H', - ]) - - env.Append(CFLAGS = [ - '-std=gnu99', - '-D_FILE_OFFSET_BITS=64', - ]) - - env.Prepend(LIBPATH = [ - ]) - - env.Prepend(LIBS = [ - trace, - rbug, - st_xorg, - svgadrm, - svga, - gallium, - ]) - - sources = [ - 'vmw_ioctl.c', - 'vmw_ctrl.c', - 'vmw_screen.c', - 'vmw_video.c', - 'vmw_xorg.c', - ] - - # TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions - env.LoadableModule( - target ='vmwgfx_drv.so', - source = sources, - LIBS = env['LIBS'], - SHLIBPREFIX = '', - ) +env = env.Clone() + +env.ParseConfig('pkg-config --cflags --libs libdrm xorg-server') + +if env['kms']: + env.ParseConfig('pkg-config --cflags --libs libkms') + +env.Prepend(CPPPATH = [ + '#/include', + '#/src/gallium', + '#/src/mesa', + '#/src/gallium/drivers/svga', + '#/src/gallium/drivers/svga/include', +]) + +env.Append(CPPDEFINES = [ +]) + +if env['gcc']: + env.Append(CPPDEFINES = [ + 'HAVE_STDINT_H', + 'HAVE_SYS_TYPES_H', + ]) + +env.Append(CFLAGS = [ + '-std=gnu99', + '-D_FILE_OFFSET_BITS=64', +]) + +env.Prepend(LIBPATH = [ +]) + +env.Prepend(LIBS = [ + trace, + rbug, + st_xorg, + svgadrm, + svga, + gallium, +]) + +sources = [ + 'vmw_ioctl.c', + 'vmw_ctrl.c', + 'vmw_screen.c', + 'vmw_target.c', + 'vmw_video.c', + 'vmw_xorg.c', +] + +# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions +module = env.LoadableModule( + target ='vmwgfx_drv.so', + source = sources, + LIBS = env['LIBS'], + SHLIBPREFIX = '', +) + +env.Alias('xorg-vmwgfx', module) diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript index ffde61965b4..3341b884985 100644 --- a/src/gallium/tests/graw/SConscript +++ b/src/gallium/tests/graw/SConscript @@ -1,20 +1,17 @@ Import('*') -try: - graw -except NameError: - print 'warning: graw library not avaiable: skipping build of graw test' - Return() - env = env.Clone() +env.Prepend(LIBS = [gallium]) + env.Prepend(LIBPATH = [graw.dir]) -env.Prepend(LIBS = ['graw'] + gallium) +env.Prepend(LIBS = ['graw']) + -if platform in ('freebsd8', 'sunos5'): +if env['platform'] in ('freebsd8', 'sunos5'): env.Append(LIBS = ['m']) -if platform == 'freebsd8': +if env['platform'] == 'freebsd8': env.Append(LIBS = ['pthread']) progs = [ @@ -29,9 +26,10 @@ progs = [ 'tri-gs', ] -for prog in progs: - env.Program( - target = prog, - source = prog + '.c', +for name in progs: + program = env.Program( + target = name, + source = name + '.c', ) - + #env.Depends(program, graw) + env.Alias('graw-progs', program) diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c index ce52a93aa1b..ee4581ef1ed 100644 --- a/src/gallium/tests/graw/clear.c +++ b/src/gallium/tests/graw/clear.c @@ -8,8 +8,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ - enum pipe_format formats[] = { PIPE_FORMAT_R8G8B8A8_UNORM, PIPE_FORMAT_B8G8R8A8_UNORM, @@ -31,17 +29,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -103,10 +91,21 @@ static void init( void ) ctx->set_framebuffer_state(ctx, &fb); } +static void args(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } + exit(1); + } +} int main( int argc, char *argv[] ) { + args(argc, argv); init(); graw_set_display_func( draw ); diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index 53fbb744d86..19af83fda88 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -10,7 +10,6 @@ #include "pipe/p_defines.h" #include <stdio.h> /* for fread(), etc */ -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" @@ -279,17 +278,7 @@ static void draw( void ) util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -526,16 +515,21 @@ static void args(int argc, char *argv[]) { int i; - for (i = 1; i < argc; i++) { + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } if (strcmp(argv[i], "-fps") == 0) { show_fps = 1; + i++; } else if (i == argc - 1) { - filename = argv[i]; + filename = argv[i]; + i++; } else { - usage(argv[0]); - exit(1); + usage(argv[0]); + exit(1); } } diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c index 62714900bd9..ef29f134980 100644 --- a/src/gallium/tests/graw/gs-test.c +++ b/src/gallium/tests/graw/gs-test.c @@ -10,7 +10,6 @@ #include "pipe/p_defines.h" #include <stdio.h> /* for fread(), etc */ -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" @@ -343,17 +342,7 @@ static void draw( void ) ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -591,19 +580,25 @@ static void args(int argc, char *argv[]) { int i; - for (i = 1; i < argc; i++) { + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } if (strcmp(argv[i], "-fps") == 0) { show_fps = 1; + i++; } else if (strcmp(argv[i], "-strip") == 0) { draw_strip = 1; + i++; } else if (i == argc - 1) { - filename = argv[i]; + filename = argv[i]; + i++; } else { - usage(argv[0]); - exit(1); + usage(argv[0]); + exit(1); } } diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c index c50ef12ab5a..35eade939e6 100644 --- a/src/gallium/tests/graw/quad-tex.c +++ b/src/gallium/tests/graw/quad-tex.c @@ -9,7 +9,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" @@ -150,17 +149,7 @@ static void draw( void ) util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -392,9 +381,21 @@ static void init( void ) set_fragment_shader(); } +static void args(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } + exit(1); + } +} int main( int argc, char *argv[] ) { + args(argc, argv); init(); graw_set_display_func( draw ); diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c index ec30871e82c..0a6c362d172 100644 --- a/src/gallium/tests/graw/shader-leak.c +++ b/src/gallium/tests/graw/shader-leak.c @@ -9,7 +9,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index 152ae408eb0..731c4e10cfd 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -8,7 +8,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index 8859f745fdb..76443811629 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -11,7 +11,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" @@ -215,17 +214,7 @@ static void draw( void ) ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -322,9 +311,18 @@ static void init( void ) static void options(int argc, char *argv[]) { int i; - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "-e") == 0) + + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } + if (strcmp(argv[i], "-e") == 0) { draw_elements = 1; + i++; + } + else { + i++; + } } if (draw_elements) printf("Using pipe_context::draw_elements_instanced()\n"); diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c index f7e39588a4d..025a1470dc9 100644 --- a/src/gallium/tests/graw/tri.c +++ b/src/gallium/tests/graw/tri.c @@ -10,7 +10,6 @@ #include "pipe/p_state.h" #include "pipe/p_defines.h" -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" @@ -143,17 +142,7 @@ static void draw( void ) util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -252,9 +241,21 @@ static void init( void ) set_fragment_shader(); } +static void args(int argc, char *argv[]) +{ + int i; + + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } + exit(1); + } +} int main( int argc, char *argv[] ) { + args(argc, argv); init(); graw_set_display_func( draw ); diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index e1cd814bf72..440c40bdcda 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -11,7 +11,6 @@ #include <stdio.h> /* for fread(), etc */ -#include "util/u_debug.h" /* debug_dump_surface_bmp() */ #include "util/u_inlines.h" #include "util/u_memory.h" /* Offset() */ #include "util/u_draw_quad.h" @@ -230,17 +229,7 @@ static void draw( void ) util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); -#if 0 - /* At the moment, libgraw leaks out/makes available some of the - * symbols from gallium/auxiliary, including these debug helpers. - * Will eventually want to bless some of these paths, and lock the - * others down so they aren't accessible from test programs. - * - * This currently just happens to work on debug builds - a release - * build will probably fail to link here: - */ - debug_dump_surface_bmp(ctx, "result.bmp", surf); -#endif + graw_save_surface_to_file(ctx, surf, NULL); screen->flush_frontbuffer(screen, surf, window); } @@ -478,16 +467,21 @@ static void args(int argc, char *argv[]) { int i; - for (i = 1; i < argc; i++) { + for (i = 1; i < argc;) { + if (graw_parse_args(&i, argc, argv)) { + continue; + } if (strcmp(argv[i], "-fps") == 0) { show_fps = 1; + i++; } else if (i == argc - 1) { - filename = argv[i]; + filename = argv[i]; + i++; } else { - usage(argv[0]); - exit(1); + usage(argv[0]); + exit(1); } } diff --git a/src/gallium/tests/unit/SConscript b/src/gallium/tests/unit/SConscript index 359759e22b2..655e8a9b41c 100644 --- a/src/gallium/tests/unit/SConscript +++ b/src/gallium/tests/unit/SConscript @@ -4,10 +4,10 @@ env = env.Clone() env.Prepend(LIBS = [gallium]) -if platform in ('freebsd8', 'sunos5'): +if env['platform'] in ('freebsd8', 'sunos5'): env.Append(LIBS = ['m']) -if platform == 'freebsd8': +if env['platform'] == 'freebsd8': env.Append(LIBS = ['pthread']) progs = [ diff --git a/src/gallium/winsys/SConscript b/src/gallium/winsys/SConscript index 65b12287df7..d74f8a2e989 100644 --- a/src/gallium/winsys/SConscript +++ b/src/gallium/winsys/SConscript @@ -2,45 +2,38 @@ Import('*') SConscript([ - 'sw/wrapper/SConscript', + 'sw/wrapper/SConscript', ]) -if 'xlib' in env['winsys']: - SConscript([ - 'sw/xlib/SConscript', - ]) +SConscript([ + 'sw/xlib/SConscript', +]) -if 'gdi' in env['winsys']: - SConscript([ - 'sw/gdi/SConscript', - ]) +SConscript([ + 'sw/gdi/SConscript', +]) if env['dri']: - SConscript([ - 'sw/dri/SConscript', - ]) - - if 'vmware' in env['winsys']: - SConscript([ - 'svga/drm/SConscript', - ]) - - if 'i915' in env['winsys']: - SConscript([ - 'i915/drm/SConscript', - ]) - - if 'i965' in env['winsys']: - SConscript([ - 'i965/drm/SConscript', - ]) - - if 'radeon' in env['winsys']: - SConscript([ - 'radeon/drm/SConscript', - ]) - - if 'r600' in env['winsys']: - SConscript([ - 'r600/drm/SConscript', - ]) + SConscript([ + 'sw/dri/SConscript', + ]) + + SConscript([ + 'svga/drm/SConscript', + ]) + + SConscript([ + 'i915/drm/SConscript', + ]) + + SConscript([ + 'i965/drm/SConscript', + ]) + + SConscript([ + 'radeon/drm/SConscript', + ]) + + SConscript([ + 'r600/drm/SConscript', + ]) diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index 7d54ff18fc2..251f009a6b0 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -26,26 +26,41 @@ #include <pipe/p_compiler.h> #include <pipe/p_screen.h> #include <pipebuffer/pb_bufmgr.h> -#include "radeon_drm.h" +#include "state_tracker/drm_driver.h" #include "r600_priv.h" #include "r600d.h" +#include "drm.h" +#include "radeon_drm.h" struct r600_bo *r600_bo(struct radeon *radeon, - unsigned size, unsigned alignment, unsigned usage) + unsigned size, unsigned alignment, + unsigned binding, unsigned usage) { struct r600_bo *ws_bo = calloc(1, sizeof(struct r600_bo)); struct pb_desc desc; struct pb_manager *man; desc.alignment = alignment; - desc.usage = usage; + desc.usage = (PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_READ_WRITE); ws_bo->size = size; - if (usage & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) + if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) man = radeon->cman; else man = radeon->kman; + /* Staging resources particpate in transfers and blits only + * and are used for uploads and downloads from regular + * resources. We generate them internally for some transfers. + */ + if (usage == PIPE_USAGE_STAGING) + ws_bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT; + else + ws_bo->domains = (RADEON_GEM_DOMAIN_CPU | + RADEON_GEM_DOMAIN_GTT | + RADEON_GEM_DOMAIN_VRAM); + + ws_bo->pb = man->create_buffer(man, size, &desc); if (ws_bo->pb == NULL) { free(ws_bo); @@ -69,6 +84,10 @@ struct r600_bo *r600_bo_handle(struct radeon *radeon, } bo = radeon_bo_pb_get_bo(ws_bo->pb); ws_bo->size = bo->size; + ws_bo->domains = (RADEON_GEM_DOMAIN_CPU | + RADEON_GEM_DOMAIN_GTT | + RADEON_GEM_DOMAIN_VRAM); + pipe_reference_init(&ws_bo->reference, 1); radeon_bo_get_tiling_flags(radeon, bo, &ws_bo->tiling_flags, @@ -136,3 +155,28 @@ unsigned r600_bo_get_size(struct r600_bo *pb_bo) return bo->size; } + +boolean r600_bo_get_winsys_handle(struct radeon *radeon, struct r600_bo *pb_bo, + unsigned stride, struct winsys_handle *whandle) +{ + struct radeon_bo *bo; + + bo = radeon_bo_pb_get_bo(pb_bo->pb); + if (!bo) + return FALSE; + + whandle->stride = stride; + switch(whandle->type) { + case DRM_API_HANDLE_TYPE_KMS: + whandle->handle = r600_bo_get_handle(pb_bo); + break; + case DRM_API_HANDLE_TYPE_SHARED: + if (radeon_bo_get_name(radeon, bo, &whandle->handle)) + return FALSE; + break; + default: + return FALSE; + } + + return TRUE; +} diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 2521ff96473..37e5baf8de8 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -44,7 +44,7 @@ int r600_context_init_fence(struct r600_context *ctx) { ctx->fence = 1; - ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0); + ctx->fence_bo = r600_bo(ctx->radeon, 4096, 0, 0, 0); if (ctx->fence_bo == NULL) { return -ENOMEM; } @@ -384,6 +384,7 @@ static const struct r600_reg r600_context_reg_list[] = { {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028A0C_PA_SC_LINE_STIPPLE, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028A48_PA_SC_MPASS_PS_CNTL, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C00_PA_SC_LINE_CNTL, 0, 0, 0}, + {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C08_PA_SU_VTX_CNTL, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C0C_PA_CL_GB_VERT_CLIP_ADJ, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C10_PA_CL_GB_VERT_DISC_ADJ, 0, 0, 0}, {PKT3_SET_CONTEXT_REG, R600_CONTEXT_REG_OFFSET, R_028C14_PA_CL_GB_HORZ_CLIP_ADJ, 0, 0, 0}, @@ -611,7 +612,9 @@ void r600_context_fini(struct r600_context *ctx) } free(ctx->range[i].blocks); } + free(ctx->blocks); free(ctx->reloc); + free(ctx->bo); free(ctx->pm4); if (ctx->fence_bo) { r600_bo_reference(ctx->radeon, &ctx->fence_bo, NULL); @@ -785,8 +788,8 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 *pm4, struct r600_bo *r bo->reloc = &ctx->reloc[ctx->creloc]; bo->reloc_id = ctx->creloc * sizeof(struct r600_reloc) / 4; ctx->reloc[ctx->creloc].handle = bo->handle; - ctx->reloc[ctx->creloc].read_domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; - ctx->reloc[ctx->creloc].write_domain = RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM; + ctx->reloc[ctx->creloc].read_domain = rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM); + ctx->reloc[ctx->creloc].write_domain = rbo->domains & (RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM); ctx->reloc[ctx->creloc].flags = 0; radeon_bo_reference(ctx->radeon, &ctx->bo[ctx->creloc], bo); ctx->creloc++; @@ -1106,6 +1109,8 @@ void r600_context_flush(struct r600_context *ctx) chunk_array[1] = (uint64_t)(uintptr_t)&chunks[1]; r = drmCommandWriteRead(ctx->radeon->fd, DRM_RADEON_CS, &drmib, sizeof(struct drm_radeon_cs)); +#else + *ctx->cfence = ctx->fence; #endif r600_context_update_fenced_list(ctx); @@ -1304,7 +1309,12 @@ struct r600_query *r600_context_query_create(struct r600_context *ctx, unsigned query->type = query_type; query->buffer_size = 4096; - query->buffer = r600_bo(ctx->radeon, query->buffer_size, 1, 0); + /* As of GL4, query buffers are normally read by the CPU after + * being written by the gpu, hence staging is probably a good + * usage pattern. + */ + query->buffer = r600_bo(ctx->radeon, query->buffer_size, 1, 0, + PIPE_USAGE_STAGING); if (!query->buffer) { free(query); return NULL; diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index b5bd7bd92c1..9fd77b71c77 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -62,7 +62,7 @@ struct radeon_bo { unsigned handle; unsigned size; unsigned alignment; - unsigned map_count; + int map_count; void *data; struct list_head fencedlist; unsigned fence; @@ -79,6 +79,7 @@ struct r600_bo { unsigned size; unsigned tiling_flags; unsigned kernel_pitch; + unsigned domains; }; @@ -90,7 +91,7 @@ struct radeon *radeon_decref(struct radeon *radeon); /* radeon_bo.c */ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, - unsigned size, unsigned alignment, void *ptr); + unsigned size, unsigned alignment); void radeon_bo_reference(struct radeon *radeon, struct radeon_bo **dst, struct radeon_bo *src); int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo); @@ -101,6 +102,9 @@ int radeon_bo_get_tiling_flags(struct radeon *radeon, struct radeon_bo *bo, uint32_t *tiling_flags, uint32_t *pitch); +int radeon_bo_get_name(struct radeon *radeon, + struct radeon_bo *bo, + uint32_t *name); /* radeon_bo_pb.c */ struct radeon_bo *radeon_bo_pb_get_bo(struct pb_buffer *_buf); diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h index d91f7737af3..5ca7456e906 100644 --- a/src/gallium/winsys/r600/drm/r600d.h +++ b/src/gallium/winsys/r600/drm/r600d.h @@ -795,6 +795,7 @@ #define R_028A48_PA_SC_MPASS_PS_CNTL 0x028A48 #define R_028C00_PA_SC_LINE_CNTL 0x028C00 #define R_028C04_PA_SC_AA_CONFIG 0x028C04 +#define R_028C08_PA_SU_VTX_CNTL 0x028C08 #define R_028C1C_PA_SC_AA_SAMPLE_LOCS_MCTX 0x028C1C #define R_028C48_PA_SC_AA_MASK 0x028C48 #define R_028810_PA_CL_CLIP_CNTL 0x028810 diff --git a/src/gallium/winsys/r600/drm/radeon_bo.c b/src/gallium/winsys/r600/drm/radeon_bo.c index 2d08686fc43..557cfb95970 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo.c +++ b/src/gallium/winsys/r600/drm/radeon_bo.c @@ -69,7 +69,7 @@ static void radeon_bo_fixed_unmap(struct radeon *radeon, struct radeon_bo *bo) } struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, - unsigned size, unsigned alignment, void *ptr) + unsigned size, unsigned alignment) { struct radeon_bo *bo; int r; @@ -121,9 +121,6 @@ struct radeon_bo *radeon_bo(struct radeon *radeon, unsigned handle, radeon_bo_reference(radeon, &bo, NULL); return bo; } - if (ptr) { - memcpy(bo->data, ptr, size); - } return bo; } @@ -156,14 +153,15 @@ int radeon_bo_wait(struct radeon *radeon, struct radeon_bo *bo) struct drm_radeon_gem_wait_idle args; int ret; - if (!bo->fence && !bo->shared) - return 0; - - if (bo->fence <= *bo->ctx->cfence) { - LIST_DELINIT(&bo->fencedlist); - bo->fence = 0; - return 0; - } + if (!bo->shared) { + if (!bo->fence) + return 0; + if (bo->fence <= *bo->ctx->cfence) { + LIST_DELINIT(&bo->fencedlist); + bo->fence = 0; + return 0; + } + } /* Zero out args to make valgrind happy */ memset(&args, 0, sizeof(args)); @@ -219,3 +217,19 @@ int radeon_bo_get_tiling_flags(struct radeon *radeon, *pitch = args.pitch; return ret; } + +int radeon_bo_get_name(struct radeon *radeon, + struct radeon_bo *bo, + uint32_t *name) +{ + struct drm_gem_flink flink; + int ret; + + flink.handle = bo->handle; + ret = drmIoctl(radeon->fd, DRM_IOCTL_GEM_FLINK, &flink); + if (ret) + return ret; + + *name = flink.name; + return ret; +} diff --git a/src/gallium/winsys/r600/drm/radeon_bo_pb.c b/src/gallium/winsys/r600/drm/radeon_bo_pb.c index a3452027f27..312552f0758 100644 --- a/src/gallium/winsys/r600/drm/radeon_bo_pb.c +++ b/src/gallium/winsys/r600/drm/radeon_bo_pb.c @@ -63,11 +63,13 @@ static void radeon_bo_pb_destroy(struct pb_buffer *_buf) { struct radeon_bo_pb *buf = radeon_bo_pb(_buf); - LIST_DEL(&buf->maplist); - - if (buf->bo->data != NULL) { + /* If this buffer is on the list of buffers to unmap, + * do the unmapping now. + */ + if (!LIST_IS_EMPTY(&buf->maplist)) radeon_bo_unmap(buf->mgr->radeon, buf->bo); - } + + LIST_DEL(&buf->maplist); radeon_bo_reference(buf->mgr->radeon, &buf->bo, NULL); FREE(buf); } @@ -80,7 +82,7 @@ radeon_bo_pb_map_internal(struct pb_buffer *_buf, struct pipe_context *pctx = ctx; if (flags & PB_USAGE_UNSYNCHRONIZED) { - if (!buf->bo->data && radeon_bo_map(buf->mgr->radeon, buf->bo)) { + if (radeon_bo_map(buf->mgr->radeon, buf->bo)) { return NULL; } LIST_DELINIT(&buf->maplist); @@ -106,18 +108,12 @@ radeon_bo_pb_map_internal(struct pb_buffer *_buf, goto out; } - if (buf->bo->data != NULL) { - if (radeon_bo_wait(buf->mgr->radeon, buf->bo)) { - return NULL; - } - } else { - if (radeon_bo_map(buf->mgr->radeon, buf->bo)) { - return NULL; - } - if (radeon_bo_wait(buf->mgr->radeon, buf->bo)) { - radeon_bo_unmap(buf->mgr->radeon, buf->bo); - return NULL; - } + if (radeon_bo_map(buf->mgr->radeon, buf->bo)) { + return NULL; + } + if (radeon_bo_wait(buf->mgr->radeon, buf->bo)) { + radeon_bo_unmap(buf->mgr->radeon, buf->bo); + return NULL; } out: LIST_DELINIT(&buf->maplist); @@ -172,7 +168,7 @@ radeon_bo_pb_create_buffer_from_handle(struct pb_manager *_mgr, struct radeon_bo_pb *bo; struct radeon_bo *hw_bo; - hw_bo = radeon_bo(radeon, handle, 0, 0, NULL); + hw_bo = radeon_bo(radeon, handle, 0, 0); if (hw_bo == NULL) return NULL; @@ -217,8 +213,7 @@ radeon_bo_pb_create_buffer(struct pb_manager *_mgr, LIST_INITHEAD(&bo->maplist); - bo->bo = radeon_bo(radeon, 0, size, - desc->alignment, NULL); + bo->bo = radeon_bo(radeon, 0, size, desc->alignment); if (bo->bo == NULL) goto error2; return &bo->b; diff --git a/src/gallium/winsys/svga/drm/SConscript b/src/gallium/winsys/svga/drm/SConscript index 3ad4c725727..b049ea60aa8 100644 --- a/src/gallium/winsys/svga/drm/SConscript +++ b/src/gallium/winsys/svga/drm/SConscript @@ -5,37 +5,37 @@ env = env.Clone() env.ParseConfig('pkg-config --cflags libdrm') if env['gcc']: - env.Append(CCFLAGS = ['-fvisibility=hidden']) - env.Append(CPPDEFINES = [ - 'HAVE_STDINT_H', - 'HAVE_SYS_TYPES_H', - '-D_FILE_OFFSET_BITS=64', - ]) - + env.Append(CCFLAGS = ['-fvisibility=hidden']) + env.Append(CPPDEFINES = [ + 'HAVE_STDINT_H', + 'HAVE_SYS_TYPES_H', + '-D_FILE_OFFSET_BITS=64', + ]) + env.Prepend(CPPPATH = [ - 'include', - '#/src/gallium/drivers/svga', - '#/src/gallium/drivers/svga/include', + 'include', + '#/src/gallium/drivers/svga', + '#/src/gallium/drivers/svga/include', ]) env.Append(CPPDEFINES = [ ]) sources = [ - 'vmw_buffer.c', - 'vmw_context.c', - 'vmw_fence.c', - 'vmw_screen.c', - 'vmw_screen_dri.c', - 'vmw_screen_ioctl.c', - 'vmw_screen_pools.c', - 'vmw_screen_svga.c', - 'vmw_surface.c', + 'vmw_buffer.c', + 'vmw_context.c', + 'vmw_fence.c', + 'vmw_screen.c', + 'vmw_screen_dri.c', + 'vmw_screen_ioctl.c', + 'vmw_screen_pools.c', + 'vmw_screen_svga.c', + 'vmw_surface.c', ] svgadrm = env.ConvenienceLibrary( - target = 'svgadrm', - source = sources, + target = 'svgadrm', + source = sources, ) Export('svgadrm') diff --git a/src/gallium/winsys/sw/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript index 2af6153b4c7..df01a9ec2bf 100644 --- a/src/gallium/winsys/sw/xlib/SConscript +++ b/src/gallium/winsys/sw/xlib/SConscript @@ -4,7 +4,7 @@ Import('*') -if env['platform'] == 'linux': +if env['platform'] in ('cygwin', 'linux'): env = env.Clone() |