diff options
Diffstat (limited to 'src/gallium')
60 files changed, 1613 insertions, 794 deletions
diff --git a/src/gallium/SConscript b/src/gallium/SConscript index 0efab834f66..2265f1de46c 100644 --- a/src/gallium/SConscript +++ b/src/gallium/SConscript @@ -55,6 +55,7 @@ SConscript('winsys/sw/null/SConscript') SConscript('state_trackers/python/SConscript') if env['platform'] != 'embedded': SConscript('state_trackers/vega/SConscript') + SConscript('state_trackers/egl/SConscript') if env['x11']: SConscript('state_trackers/glx/xlib/SConscript') @@ -66,10 +67,7 @@ if env['platform'] != 'embedded': SConscript('state_trackers/xorg/SConscript') if env['platform'] == 'windows': - SConscript([ - 'state_trackers/egl/SConscript', - 'state_trackers/wgl/SConscript', - ]) + SConscript('state_trackers/wgl/SConscript') # # Winsys @@ -85,6 +83,11 @@ SConscript([ 'targets/graw-null/SConscript', ]) +if env['platform'] != 'embedded': + SConscript([ + 'targets/egl-static/SConscript' + ]) + if env['x11']: SConscript([ 'targets/graw-xlib/SConscript', @@ -95,7 +98,6 @@ if env['platform'] == 'windows': SConscript([ 'targets/graw-gdi/SConscript', 'targets/libgl-gdi/SConscript', - #'egl-gdi/SConscript', ]) if env['dri']: diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c index 943ec44bcde..0c51aa85b37 100644 --- a/src/gallium/auxiliary/draw/draw_llvm.c +++ b/src/gallium/auxiliary/draw/draw_llvm.c @@ -229,6 +229,8 @@ create_jit_vertex_buffer_type(struct gallivm_state *gallivm) LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, stride, target, vb_type, 0); + LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, max_index, + target, vb_type, 1); LP_CHECK_MEMBER_OFFSET(struct pipe_vertex_buffer, buffer_offset, target, vb_type, 2); @@ -437,6 +439,7 @@ generate_vs(struct draw_llvm *llvm, LLVMBuilderRef builder, LLVMValueRef (*outputs)[NUM_CHANNELS], const LLVMValueRef (*inputs)[NUM_CHANNELS], + LLVMValueRef system_values_array, LLVMValueRef context_ptr, struct lp_build_sampler_soa *draw_sampler) { @@ -468,6 +471,7 @@ generate_vs(struct draw_llvm *llvm, vs_type, NULL /*struct lp_build_mask_context *mask*/, consts_ptr, + system_values_array, NULL /*pos*/, inputs, outputs, @@ -1118,7 +1122,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) LLVMValueRef start, end, count, stride, step, io_itr; LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef instance_id; + LLVMValueRef system_values_array; struct draw_context *draw = llvm->draw; + const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; @@ -1179,6 +1185,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) lp_build_context_init(&bld, llvm->gallivm, lp_type_int(32)); + system_values_array = lp_build_system_values_array(gallivm, vs_info, + instance_id, NULL); + end = lp_build_add(&bld, start, count); step = lp_build_const_int32(gallivm, max_vertices); @@ -1233,6 +1242,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) builder, outputs, ptr_aos, + system_values_array, context_ptr, sampler); @@ -1263,8 +1273,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant) /* store clipmask in vertex header and positions in data */ convert_to_aos(gallivm, io, outputs, clipmask, - draw->vs.vertex_shader->info.num_outputs, - max_vertices); + vs_info->num_outputs, max_vertices); } lp_build_loop_end_cond(&lp_loop, end, step, LLVMIntUGE); @@ -1315,7 +1324,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian LLVMValueRef fetch_elts, fetch_count, stride, step, io_itr; LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr; LLVMValueRef instance_id; + LLVMValueRef system_values_array; struct draw_context *draw = llvm->draw; + const struct tgsi_shader_info *vs_info = &draw->vs.vertex_shader->info; unsigned i, j; struct lp_build_context bld; struct lp_build_loop_state lp_loop; @@ -1376,6 +1387,10 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian lp_build_context_init(&bld, gallivm, lp_type_int(32)); + system_values_array = lp_build_system_values_array(gallivm, vs_info, + instance_id, NULL); + + step = lp_build_const_int32(gallivm, max_vertices); /* code generated texture sampling */ @@ -1438,6 +1453,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian builder, outputs, ptr_aos, + system_values_array, context_ptr, sampler); @@ -1471,8 +1487,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian * and transformed positions in data */ convert_to_aos(gallivm, io, outputs, clipmask, - draw->vs.vertex_shader->info.num_outputs, - max_vertices); + vs_info->num_outputs, max_vertices); } lp_build_loop_end_cond(&lp_loop, fetch_count, step, LLVMIntUGE); diff --git a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h index 3f66f962e11..75dba8c39a5 100644 --- a/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h +++ b/src/gallium/auxiliary/draw/draw_pt_vsplit_tmp.h @@ -258,9 +258,10 @@ vsplit_segment_fan_linear(struct vsplit_frontend *vsplit, unsigned flags, boolean use_spoken = ((flags & DRAW_SPLIT_BEFORE) != 0); unsigned nr = 0, i; - assert(icount + !!use_spoken <= vsplit->segment_size); + assert(icount <= vsplit->segment_size); if (use_spoken) { + /* replace istart by i0 */ vsplit->fetch_elts[nr++] = i0; for (i = 1 ; i < icount; i++) vsplit->fetch_elts[nr++] = istart + i; diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c index 667eb507855..c41d7c42a01 100644 --- a/src/gallium/auxiliary/draw/draw_vs_exec.c +++ b/src/gallium/auxiliary/draw/draw_vs_exec.c @@ -99,6 +99,12 @@ vs_exec_run_linear( struct draw_vertex_shader *shader, tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, const_size); + if (shader->info.uses_instanceid) { + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INSTANCEID]; + assert(i < Elements(machine->SystemValue)); + machine->SystemValue[i][0] = shader->draw->instance_id; + } + for (i = 0; i < count; i += MAX_TGSI_VERTICES) { unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i); diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c index dee7c0da9b6..d55b9b08070 100644 --- a/src/gallium/auxiliary/draw/draw_vs_sse.c +++ b/src/gallium/auxiliary/draw/draw_vs_sse.c @@ -71,6 +71,12 @@ vs_sse_prepare( struct draw_vertex_shader *base, struct tgsi_exec_machine *machine = shader->machine; machine->Samplers = draw->vs.samplers; + + if (base->info.uses_instanceid) { + unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INSTANCEID]; + assert(i < Elements(machine->SystemValue)); + machine->SystemValue[i][0] = base->draw->instance_id; + } } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h index 40186befb9f..9713d100484 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi.h @@ -180,6 +180,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[4], LLVMValueRef (*outputs)[4], @@ -199,4 +200,11 @@ lp_build_tgsi_aos(struct gallivm_state *gallivm, const struct tgsi_shader_info *info); +LLVMValueRef +lp_build_system_values_array(struct gallivm_state *gallivm, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing); + + #endif /* LP_BLD_TGSI_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c index 1b5a8a5903b..d1585c8e2b7 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c @@ -157,6 +157,8 @@ struct lp_build_tgsi_soa_context */ LLVMValueRef inputs_array; + LLVMValueRef system_values_array; + const struct tgsi_shader_info *info; /** bitmask indicating which register files are accessed indirectly */ unsigned indirect_files; @@ -759,6 +761,23 @@ emit_fetch( } break; + case TGSI_FILE_SYSTEM_VALUE: + assert(!reg->Register.Indirect); + { + LLVMValueRef index; /* index into the system value array */ + LLVMValueRef scalar, scalar_ptr; + + index = lp_build_const_int32(gallivm, + reg->Register.Index * 4 + swizzle); + + scalar_ptr = LLVMBuildGEP(builder, bld->system_values_array, + &index, 1, ""); + scalar = LLVMBuildLoad(builder, scalar_ptr, ""); + + res = lp_build_broadcast_scalar(&bld->base, scalar); + } + break; + default: assert(0 && "invalid src register in emit_fetch()"); return bld->base.undef; @@ -2322,6 +2341,7 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, struct lp_type type, struct lp_build_mask_context *mask, LLVMValueRef consts_ptr, + LLVMValueRef system_values_array, const LLVMValueRef *pos, const LLVMValueRef (*inputs)[NUM_CHANNELS], LLVMValueRef (*outputs)[NUM_CHANNELS], @@ -2411,6 +2431,8 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, } } + bld.system_values_array = system_values_array; + tgsi_parse_init( &parse, tokens ); while( !tgsi_parse_end_of_tokens( &parse ) ) { @@ -2512,3 +2534,54 @@ lp_build_tgsi_soa(struct gallivm_state *gallivm, FREE( bld.instructions ); } + +/** + * Build up the system values array out of individual values such as + * the instance ID, front-face, primitive ID, etc. The shader info is + * used to determine which system values are needed and where to put + * them in the system values array. + * + * XXX only instance ID is implemented at this time. + * + * The system values register file is similar to the constants buffer. + * Example declaration: + * DCL SV[0], INSTANCEID + * Example instruction: + * MOVE foo, SV[0].xxxx; + * + * \return LLVM float array (interpreted as float [][4]) + */ +LLVMValueRef +lp_build_system_values_array(struct gallivm_state *gallivm, + const struct tgsi_shader_info *info, + LLVMValueRef instance_id, + LLVMValueRef facing) +{ + LLVMValueRef size = lp_build_const_int32(gallivm, 4 * info->num_system_values); + LLVMTypeRef float_t = LLVMFloatTypeInContext(gallivm->context); + LLVMValueRef array = lp_build_array_alloca(gallivm, float_t, + size, "sysvals_array"); + unsigned i; + + for (i = 0; i < info->num_system_values; i++) { + LLVMValueRef index = lp_build_const_int32(gallivm, i * 4); + LLVMValueRef ptr, value; + + switch (info->system_value_semantic_name[i]) { + case TGSI_SEMANTIC_INSTANCEID: + /* convert instance ID from int to float */ + value = LLVMBuildSIToFP(gallivm->builder, instance_id, float_t, + "sysval_instanceid"); + break; + case TGSI_SEMANTIC_FACE: + /* fall-through */ + default: + assert(0 && "unexpected semantic in build_system_values_array()"); + } + + ptr = LLVMBuildGEP(gallivm->builder, array, &index, 1, ""); + LLVMBuildStore(gallivm->builder, value, ptr); + } + + return array; +} diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c index 7892a67f04c..35b27423513 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.c +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c @@ -1038,7 +1038,6 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, break; case TGSI_FILE_INPUT: - case TGSI_FILE_SYSTEM_VALUE: for (i = 0; i < QUAD_SIZE; i++) { /* if (TGSI_PROCESSOR_GEOMETRY == mach->Processor) { @@ -1053,6 +1052,15 @@ fetch_src_file_channel(const struct tgsi_exec_machine *mach, } break; + case TGSI_FILE_SYSTEM_VALUE: + /* XXX no swizzling at this point. Will be needed if we put + * gl_FragCoord, for example, in a sys value register. + */ + for (i = 0; i < QUAD_SIZE; i++) { + chan->f[i] = mach->SystemValue[index->i[i]][0]; + } + break; + case TGSI_FILE_TEMPORARY: for (i = 0; i < QUAD_SIZE; i++) { assert(index->i[i] < TGSI_EXEC_NUM_TEMPS); @@ -1907,8 +1915,7 @@ exec_declaration(struct tgsi_exec_machine *mach, const struct tgsi_full_declaration *decl) { if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) { - if (decl->Declaration.File == TGSI_FILE_INPUT || - decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) { + if (decl->Declaration.File == TGSI_FILE_INPUT) { uint first, last, mask; first = decl->Range.First; @@ -1921,6 +1928,7 @@ exec_declaration(struct tgsi_exec_machine *mach, * ureg code to emit the right UsageMask value (WRITEMASK_X). * Then, we could remove the tgsi_exec_machine::Face field. */ + /* XXX make FACE a system value */ if (decl->Semantic.Name == TGSI_SEMANTIC_FACE) { uint i; @@ -1962,8 +1970,13 @@ exec_declaration(struct tgsi_exec_machine *mach, } } } + + if (decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) { + mach->SysSemanticToIndex[decl->Declaration.Semantic] = decl->Range.First; + } } + typedef void (* micro_op)(union tgsi_exec_channel *dst); static void diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h index b5ebbfbfaab..6c204c73714 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_exec.h +++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h @@ -31,6 +31,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_state.h" +#include "pipe/p_shader_tokens.h" #if defined __cplusplus extern "C" { @@ -181,6 +182,8 @@ struct tgsi_sampler /* The maximum total number of vertices */ #define TGSI_MAX_TOTAL_VERTICES (TGSI_MAX_PRIM_VERTICES * TGSI_MAX_PRIMITIVES * PIPE_MAX_ATTRIBS) +#define TGSI_MAX_MISC_INPUTS 8 + /** function call/activation record */ struct tgsi_call_record { @@ -228,6 +231,10 @@ struct tgsi_exec_machine struct tgsi_exec_vector Inputs[TGSI_MAX_PRIM_VERTICES * PIPE_MAX_ATTRIBS]; struct tgsi_exec_vector Outputs[TGSI_MAX_TOTAL_VERTICES]; + /* System values */ + unsigned SysSemanticToIndex[TGSI_SEMANTIC_COUNT]; + float SystemValue[TGSI_MAX_MISC_INPUTS][4]; + struct tgsi_exec_vector *Addrs; struct tgsi_exec_vector *Predicates; diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c index 3521847b619..537a0f6c5e4 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c +++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c @@ -294,7 +294,6 @@ emit_fetch(struct gen_context *gen, case TGSI_SWIZZLE_W: switch (reg->Register.File) { case TGSI_FILE_INPUT: - case TGSI_FILE_SYSTEM_VALUE: { int offset = (reg->Register.Index * 4 + swizzle) * 16; int offset_reg = emit_li_offset(gen, offset); @@ -302,6 +301,9 @@ emit_fetch(struct gen_context *gen, ppc_lvx(gen->f, dst_vec, gen->inputs_reg, offset_reg); } break; + case TGSI_FILE_SYSTEM_VALUE: + assert(!"unhandled system value in tgsi_ppc.c"); + break; case TGSI_FILE_TEMPORARY: if (is_ppc_vec_temporary(reg)) { /* use PPC vec register */ diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index 6585da3e838..83c6ac75e54 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -143,7 +143,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->file_count[file]++; info->file_max[file] = MAX2(info->file_max[file], (int)reg); - if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) { + if (file == TGSI_FILE_INPUT) { info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate; @@ -151,6 +151,23 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->input_cylindrical_wrap[reg] = (ubyte)fulldecl->Declaration.CylindricalWrap; info->num_inputs++; } + else if (file == TGSI_FILE_SYSTEM_VALUE) { + unsigned index = fulldecl->Range.First; + unsigned semName = fulldecl->Semantic.Name; + + info->system_value_semantic_name[index] = semName; + info->num_system_values = MAX2(info->num_system_values, + index + 1); + + /* + info->system_value_semantic_name[info->num_system_values++] = + fulldecl->Semantic.Name; + */ + + if (fulldecl->Semantic.Name == TGSI_SEMANTIC_INSTANCEID) { + info->uses_instanceid = TRUE; + } + } else if (file == TGSI_FILE_OUTPUT) { info->output_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name; info->output_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index; diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h index 104097fbc03..53ab3d509dd 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.h +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h @@ -51,6 +51,9 @@ struct tgsi_shader_info ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */ ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS]; + ubyte num_system_values; + ubyte system_value_semantic_name[PIPE_MAX_SHADER_INPUTS]; + uint file_mask[TGSI_FILE_COUNT]; /**< bitmask of declared registers */ uint file_count[TGSI_FILE_COUNT]; /**< number of declared registers */ int file_max[TGSI_FILE_COUNT]; /**< highest index of declared registers */ @@ -64,6 +67,7 @@ struct tgsi_shader_info boolean writes_stencil; /**< does fragment shader write stencil value? */ boolean writes_edgeflag; /**< vertex shader outputs edgeflag */ boolean uses_kill; /**< KIL or KILP instruction used? */ + boolean uses_instanceid; /** * Bitmask indicating which register files are accessed with diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 086d983a73a..3f2cda860e0 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -163,6 +163,14 @@ get_immediate_base( void ) reg_DX ); } +static struct x86_reg +get_system_value_base( void ) +{ + return x86_make_disp( + get_machine_base(), + Offset(struct tgsi_exec_machine, SystemValue) ); +} + /** * Data access helpers. @@ -229,6 +237,16 @@ get_temp( } static struct x86_reg +get_system_value( + unsigned vec, + unsigned chan ) +{ + return x86_make_disp( + get_system_value_base(), /* base */ + (vec * 4 + chan) * 4 ); /* byte offset from base */ +} + +static struct x86_reg get_coef( unsigned vec, unsigned chan, @@ -423,6 +441,30 @@ emit_tempf( } /** + * Copy a system value to xmm register + * \param xmm the destination xmm register + * \param vec the source system value register + * \param chan src channel to fetch (X, Y, Z or W) + */ +static void +emit_system_value( + struct x86_function *func, + unsigned xmm, + unsigned vec, + unsigned chan ) +{ + sse_movss( + func, + make_xmm( xmm ), + get_system_value( vec, chan ) ); + sse_shufps( + func, + make_xmm( xmm ), + make_xmm( xmm ), + SHUF( 0, 0, 0, 0 ) ); +} + +/** * Load an xmm register with an input attrib coefficient (a0, dadx or dady) * \param xmm the destination xmm register * \param vec the src input/attribute coefficient index @@ -1281,8 +1323,15 @@ emit_fetch( swizzle ); break; - case TGSI_FILE_INPUT: case TGSI_FILE_SYSTEM_VALUE: + emit_system_value( + func, + xmm, + reg->Register.Index, + swizzle ); + break; + + case TGSI_FILE_INPUT: emit_inputf( func, xmm, @@ -2636,8 +2685,7 @@ emit_declaration( struct x86_function *func, struct tgsi_full_declaration *decl ) { - if( decl->Declaration.File == TGSI_FILE_INPUT || - decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) { + if( decl->Declaration.File == TGSI_FILE_INPUT ) { unsigned first, last, mask; unsigned i, j; diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 2ad2f95b13e..f4ad545bee7 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -47,6 +47,7 @@ void _debug_vprintf(const char *format, va_list ap) { +#if defined(PIPE_OS_WINDOWS) || defined(PIPE_OS_EMBEDDED) /* We buffer until we find a newline. */ static char buf[4096] = {'\0'}; size_t len = strlen(buf); @@ -55,6 +56,10 @@ void _debug_vprintf(const char *format, va_list ap) os_log_message(buf); buf[0] = '\0'; } +#else + /* Just print as-is to stderr */ + vfprintf(stderr, format, ap); +#endif } diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst index 09edbaa673d..ab90097add6 100644 --- a/src/gallium/docs/source/screen.rst +++ b/src/gallium/docs/source/screen.rst @@ -36,6 +36,7 @@ The integer capabilities: bound. * ``OCCLUSION_QUERY``: Whether occlusion queries are available. * ``TIMER_QUERY``: Whether timer queries are available. +* ``INSTANCED_DRAWING``: indicates support for instanced drawing. * ``TEXTURE_SHADOW_MAP``: indicates whether the fragment shader hardware can do the depth texture / Z comparison operation in TEX instructions for shadow testing. diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 9459a3cd113..b6919a5c6d3 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -164,6 +164,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 1; case PIPE_CAP_DEPTH_CLAMP: return 0; + case PIPE_CAP_INSTANCED_DRAWING: + return 1; default: return 0; } diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index ae207617cc1..1b9119eda00 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -334,7 +334,8 @@ generate_fs(struct gallivm_state *gallivm, /* Build the actual shader */ lp_build_tgsi_soa(gallivm, tokens, type, &mask, - consts_ptr, interp->pos, interp->inputs, + consts_ptr, NULL, /* sys values array */ + interp->pos, interp->inputs, outputs, sampler, &shader->info.base); /* Alpha test */ diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c index 8c9efc2f536..3680f4622da 100644 --- a/src/gallium/drivers/noop/noop_pipe.c +++ b/src/gallium/drivers/noop/noop_pipe.c @@ -124,7 +124,7 @@ static struct pipe_resource *noop_resource_from_handle(struct pipe_screen *scree struct noop_pipe_screen *noop_screen = (struct noop_pipe_screen*)screen; struct pipe_screen *oscreen = noop_screen->oscreen; struct pipe_resource *result; - struct noop_resource *noop_resource; + struct pipe_resource *noop_resource; result = oscreen->resource_from_handle(oscreen, templ, handle); noop_resource = noop_resource_create(screen, result); diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 702e58b2e3c..31302949d5e 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -8,7 +8,7 @@ http://0x04.net/cgit/index.cgi/rules-ng-ng git clone git://0x04.net/rules-ng-ng The rules-ng-ng source files this header was generated from are: -- nvc0_3d.xml ( 30401 bytes, from 2011-01-08 18:09:11) +- nvc0_3d.xml ( 30827 bytes, from 2011-01-13 18:23:07) - copyright.xml ( 6452 bytes, from 2010-11-25 23:28:20) - nv_defs.xml ( 4437 bytes, from 2010-07-06 07:43:58) - nv_3ddefs.xml ( 16394 bytes, from 2010-12-17 15:10:40) @@ -449,6 +449,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_LINKED_TSC 0x00001234 +#define NVC0_3D_DRAW_TFB_BYTES 0x0000123c + #define NVC0_3D_FP_RESULT_COUNT 0x00001298 #define NVC0_3D_DEPTH_TEST_ENABLE 0x000012cc @@ -511,6 +513,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_ALPHA_TEST_FUNC_GEQUAL 0x00000206 #define NVC0_3D_ALPHA_TEST_FUNC_ALWAYS 0x00000207 +#define NVC0_3D_DRAW_TFB_STRIDE 0x00001318 +#define NVC0_3D_DRAW_TFB_STRIDE__MIN 0x00000001 +#define NVC0_3D_DRAW_TFB_STRIDE__MAX 0x00000fff + #define NVC0_3D_BLEND_COLOR(i0) (0x0000131c + 0x4*(i0)) #define NVC0_3D_BLEND_COLOR__ESIZE 0x00000004 #define NVC0_3D_BLEND_COLOR__LEN 0x00000004 @@ -603,6 +609,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_STENCIL_FRONT_FUNC_MASK 0x0000139c +#define NVC0_3D_DRAW_TFB_BASE 0x000013a4 + #define NVC0_3D_FRAG_COLOR_CLAMP_EN 0x000013a8 #define NVC0_3D_FRAG_COLOR_CLAMP_EN_0 0x00000001 #define NVC0_3D_FRAG_COLOR_CLAMP_EN_1 0x00000010 @@ -613,7 +621,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_FRAG_COLOR_CLAMP_EN_6 0x01000000 #define NVC0_3D_FRAG_COLOR_CLAMP_EN_7 0x10000000 -#define NVC0_3D_Y_ORIGIN_BOTTOM 0x000013ac +#define NVC0_3D_SCREEN_Y_CONTROL 0x000013ac +#define NVC0_3D_SCREEN_Y_CONTROL_Y_NEGATE 0x00000001 +#define NVC0_3D_SCREEN_Y_CONTROL_TRIANGLE_RAST_FLIP 0x00000010 #define NVC0_3D_LINE_WIDTH 0x000013b0 @@ -621,7 +631,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_GP_VERTEX_OUTPUT_COUNT__MIN 0x00000001 #define NVC0_3D_GP_VERTEX_OUTPUT_COUNT__MAX 0x00000400 -#define NVC0_3D_FENCE_UNK 0x0000142c +#define NVC0_3D_VERTEX_ARRAY_FLUSH 0x0000142c #define NVC0_3D_VB_ELEMENT_BASE 0x00001434 @@ -668,7 +678,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_COUNTER_RESET_UNK1E 0x0000001e #define NVC0_3D_COUNTER_RESET_GENERATED_PRIMITIVES 0x0000001f -#define NVC0_3D_MULTISAMPLE_ZETA_ENABLE 0x00001534 +#define NVC0_3D_MULTISAMPLE_ENABLE 0x00001534 #define NVC0_3D_ZETA_ENABLE 0x00001538 @@ -747,7 +757,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_STENCIL_BACK_FUNC_FUNC_GEQUAL 0x00000206 #define NVC0_3D_STENCIL_BACK_FUNC_FUNC_ALWAYS 0x00000207 -#define NVC0_3D_MULTISAMPLE_COLOR_ENABLE 0x000015b4 +#define NVC0_3D_CSAA_ENABLE 0x000015b4 #define NVC0_3D_FRAMEBUFFER_SRGB 0x000015b8 @@ -849,6 +859,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_POINT_SMOOTH_ENABLE 0x00001658 +#define NVC0_3D_POINT_RASTER_RULES 0x0000165c +#define NVC0_3D_POINT_RASTER_RULES_OGL 0x00000000 +#define NVC0_3D_POINT_RASTER_RULES_D3D 0x00000001 + #define NVC0_3D_POINT_SPRITE_CTRL 0x00001660 #define NVC0_3D_TEX_MISC 0x00001664 @@ -1028,6 +1042,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VERTEX_ARRAY_FETCH_STRIDE__SHIFT 0 #define NVC0_3D_VERTEX_ARRAY_FETCH_ENABLE 0x00001000 +#define NVC0_3D_VERTEX_ARRAY_START_HIGH(i0) (0x00001c04 + 0x10*(i0)) +#define NVC0_3D_VERTEX_ARRAY_START_HIGH__ESIZE 0x00000010 +#define NVC0_3D_VERTEX_ARRAY_START_HIGH__LEN 0x00000020 + +#define NVC0_3D_VERTEX_ARRAY_START_LOW(i0) (0x00001c08 + 0x10*(i0)) +#define NVC0_3D_VERTEX_ARRAY_START_LOW__ESIZE 0x00000010 +#define NVC0_3D_VERTEX_ARRAY_START_LOW__LEN 0x00000020 + #define NVC0_3D_VERTEX_ARRAY_DIVISOR(i0) (0x00001c0c + 0x10*(i0)) #define NVC0_3D_VERTEX_ARRAY_DIVISOR__ESIZE 0x00000010 #define NVC0_3D_VERTEX_ARRAY_DIVISOR__LEN 0x00000020 @@ -1058,6 +1080,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_IBLEND_FUNC_DST_ALPHA(i0) (0x00001e18 + 0x20*(i0)) +#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH(i0) (0x00001f00 + 0x8*(i0)) +#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH__ESIZE 0x00000008 +#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH__LEN 0x00000020 + +#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW(i0) (0x00001f04 + 0x8*(i0)) +#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW__ESIZE 0x00000008 +#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW__LEN 0x00000020 + #define NVC0_3D_SP(i0) (0x00002000 + 0x40*(i0)) #define NVC0_3D_SP__ESIZE 0x00000040 #define NVC0_3D_SP__LEN 0x00000006 @@ -1132,14 +1162,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_VERTEX_ARRAY_SELECT 0x00003820 -#define NVC0_3D_VERTEX_ARRAY_LIMIT_HIGH 0x00003824 - -#define NVC0_3D_VERTEX_ARRAY_LIMIT_LOW 0x00003828 - -#define NVC0_3D_VERTEX_ARRAY_START_HIGH 0x0000382c - -#define NVC0_3D_VERTEX_ARRAY_START_LOW 0x00003830 - #define NVC0_3D_BLEND_ENABLES 0x00003858 #define NVC0_3D_POLYGON_MODE_FRONT 0x00003868 diff --git a/src/gallium/drivers/nvc0/nvc0_buffer.c b/src/gallium/drivers/nvc0/nvc0_buffer.c index f5ac6557fe9..ea3e642a448 100644 --- a/src/gallium/drivers/nvc0/nvc0_buffer.c +++ b/src/gallium/drivers/nvc0/nvc0_buffer.c @@ -59,6 +59,18 @@ release_allocation(struct nvc0_mm_allocation **mm, struct nvc0_fence *fence) (*mm) = NULL; } +static INLINE boolean +nvc0_buffer_reallocate(struct nvc0_screen *screen, struct nvc0_resource *buf, + unsigned domain) +{ + nouveau_bo_ref(NULL, &buf->bo); + + if (buf->mm) + release_allocation(&buf->mm, buf->fence); + + return nvc0_buffer_allocate(screen, buf, domain); +} + static void nvc0_buffer_destroy(struct pipe_screen *pscreen, struct pipe_resource *presource) @@ -116,6 +128,12 @@ nvc0_buffer_upload(struct nvc0_context *nvc0, struct nvc0_resource *buf, struct nouveau_bo *bounce = NULL; uint32_t offset; + if (size <= 192) { + nvc0_m2mf_push_linear(nvc0, buf->bo, buf->domain, buf->offset + start, + size, buf->data + start); + return TRUE; + } + mm = nvc0_mm_allocate(nvc0->screen->mm_GART, size, &bounce, &offset); if (!bounce) return FALSE; @@ -366,8 +384,9 @@ nvc0_user_buffer_create(struct pipe_screen *pscreen, return &buffer->base; } +/* Like download, but for GART buffers. Merge ? */ static INLINE boolean -nvc0_buffer_fetch_data(struct nvc0_resource *buf, +nvc0_buffer_data_fetch(struct nvc0_resource *buf, struct nouveau_bo *bo, unsigned offset, unsigned size) { if (!buf->data) { @@ -413,7 +432,7 @@ nvc0_buffer_migrate(struct nvc0_context *nvc0, if (new_domain == NOUVEAU_BO_VRAM) { /* keep a system memory copy of our data in case we hit a fallback */ - if (!nvc0_buffer_fetch_data(buf, buf->bo, buf->offset, size)) + if (!nvc0_buffer_data_fetch(buf, buf->bo, buf->offset, size)) return FALSE; debug_printf("migrating %u KiB to VRAM\n", size / 1024); } @@ -444,19 +463,22 @@ nvc0_buffer_migrate(struct nvc0_context *nvc0, } /* Migrate data from glVertexAttribPointer(non-VBO) user buffers to GART. - * MUST NOT FLUSH THE PUSH BUFFER, we could be in the middle of a method. + * We'd like to only allocate @size bytes here, but then we'd have to rebase + * the vertex indices ... */ boolean -nvc0_migrate_vertices(struct nvc0_resource *buf, unsigned base, unsigned size) +nvc0_user_buffer_upload(struct nvc0_resource *buf, unsigned base, unsigned size) { struct nvc0_screen *screen = nvc0_screen(buf->base.screen); int ret; - assert(buf->data && !buf->domain); + assert(buf->status & NVC0_BUFFER_STATUS_USER_MEMORY); - if (!nvc0_buffer_allocate(screen, buf, NOUVEAU_BO_GART)) + buf->base.width0 = base + size; + if (!nvc0_buffer_reallocate(screen, buf, NOUVEAU_BO_GART)) return FALSE; - ret = nouveau_bo_map_range(buf->bo, base + buf->offset, size, + + ret = nouveau_bo_map_range(buf->bo, buf->offset + base, size, NOUVEAU_BO_WR | NOUVEAU_BO_NOSYNC); if (ret) return FALSE; diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 0f340beb35a..eeb5beff7a7 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -100,7 +100,8 @@ struct nvc0_context { struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned num_vtxbufs; struct pipe_index_buffer idxbuf; - uint32_t vbo_fifo; + uint32_t vbo_fifo; /* bitmask of vertex elements to be pushed to FIFO */ + uint32_t vbo_user; /* bitmask of vertex buffers pointing to user memory */ unsigned vbo_min_index; /* from pipe_draw_info, for vertex upload */ unsigned vbo_max_index; diff --git a/src/gallium/drivers/nvc0/nvc0_pc.c b/src/gallium/drivers/nvc0/nvc0_pc.c index 72483f120ed..304a1919768 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc.c +++ b/src/gallium/drivers/nvc0/nvc0_pc.c @@ -515,6 +515,13 @@ nvc0_insn_insert_after(struct nv_instruction *at, struct nv_instruction *ni) } void +nvc0_insn_insert_before(struct nv_instruction *at, struct nv_instruction *ni) +{ + nvc0_insn_insert_after(at, ni); + nvc0_insns_permute(at, ni); +} + +void nvc0_insn_delete(struct nv_instruction *nvi) { struct nv_basic_block *b = nvi->bb; diff --git a/src/gallium/drivers/nvc0/nvc0_pc.h b/src/gallium/drivers/nvc0/nvc0_pc.h index 74867f02e72..969cc68c596 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc.h +++ b/src/gallium/drivers/nvc0/nvc0_pc.h @@ -473,6 +473,7 @@ struct nv_pc { }; void nvc0_insn_append(struct nv_basic_block *, struct nv_instruction *); +void nvc0_insn_insert_before(struct nv_instruction *, struct nv_instruction *); void nvc0_insn_insert_after(struct nv_instruction *, struct nv_instruction *); static INLINE struct nv_instruction * diff --git a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c index e4449c285b5..acc72bff14c 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c +++ b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c @@ -249,6 +249,13 @@ check_swap_src_0_1(struct nv_instruction *nvi) nvi->src[0] = src1; nvi->src[1] = src0; } + } else + if (is_immd32_load(src0->value->insn)) { + if (!is_cspace_load(src1->value->insn) && + !is_immd32_load(src1->value->insn)) { + nvi->src[0] = src1; + nvi->src[1] = src0; + } } if (nvi->src[0] != src0 && nvi->opcode == NV_OP_SET) @@ -1101,6 +1108,40 @@ nv_pass_cse(struct nv_pass *ctx, struct nv_basic_block *b) return 0; } +/* Make sure all sources of an NV_OP_BIND are distinct, they need to occupy + * neighbouring registers. CSE might have messed this up. + */ +static int +nv_pass_fix_bind(struct nv_pass *ctx, struct nv_basic_block *b) +{ + struct nv_value *val; + struct nv_instruction *bnd, *nvi, *next; + int s, t; + + for (bnd = b->entry; bnd; bnd = next) { + next = bnd->next; + if (bnd->opcode != NV_OP_BIND) + continue; + for (s = 0; s < 4 && bnd->src[s]; ++s) { + val = bnd->src[s]->value; + for (t = s + 1; t < 4 && bnd->src[t]; ++t) { + if (bnd->src[t]->value != val) + continue; + nvi = nv_alloc_instruction(ctx->pc, NV_OP_MOV); + nvi->def[0] = new_value_like(ctx->pc, val); + nvi->def[0]->insn = nvi; + nv_reference(ctx->pc, nvi, 0, val); + nvc0_insn_insert_before(bnd, nvi); + + nv_reference(ctx->pc, bnd, t, nvi->def[0]); + } + } + } + DESCEND_ARBITRARY(t, nv_pass_fix_bind); + + return 0; +} + static int nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root) { @@ -1177,6 +1218,9 @@ nv_pc_pass0(struct nv_pc *pc, struct nv_basic_block *root) if (ret) return ret; + pc->pass_seq++; + ret = nv_pass_fix_bind(&pass, root); + return ret; } diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index 3e7fc4d350e..57a0874e679 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -598,6 +598,13 @@ nvc0_prog_scan(struct nvc0_translation_info *ti) case PIPE_SHADER_FRAGMENT: ti->input_file = NV_FILE_MEM_V; ti->output_file = NV_FILE_GPR; + + if (ti->scan.writes_z) + prog->flags[0] = 0x11; /* ? */ + else + if (!ti->global_stores) + prog->fp.early_z = 1; + ret = nvc0_fp_gen_header(prog, ti); break; default: diff --git a/src/gallium/drivers/nvc0/nvc0_program.h b/src/gallium/drivers/nvc0/nvc0_program.h index 1271303144e..2e84caecc9e 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.h +++ b/src/gallium/drivers/nvc0/nvc0_program.h @@ -23,12 +23,15 @@ struct nvc0_program { uint32_t hdr[20]; - uint32_t flags[2]; /* FP_ZORDER */ + uint32_t flags[2]; struct { uint8_t edgeflag; uint8_t num_ucps; } vp; + struct { + uint8_t early_z; + } fp; void *relocs; unsigned num_relocs; @@ -66,6 +69,7 @@ struct nvc0_translation_info { boolean indirect_inputs; boolean indirect_outputs; boolean require_stores; + boolean global_stores; uint32_t *immd32; ubyte *immd32_ty; unsigned immd32_nr; diff --git a/src/gallium/drivers/nvc0/nvc0_resource.h b/src/gallium/drivers/nvc0/nvc0_resource.h index d33e2f0ed0a..17e79642a6d 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.h +++ b/src/gallium/drivers/nvc0/nvc0_resource.h @@ -18,6 +18,12 @@ struct nvc0_context; #define NVC0_BUFFER_SCORE_MAX 25000 #define NVC0_BUFFER_SCORE_VRAM_THRESHOLD 20000 +/* DIRTY: buffer was (or will be after the next flush) written to by GPU and + * resource->data has not been updated to reflect modified VRAM contents + * + * USER_MEMORY: resource->data is a pointer to client memory and may change + * between GL calls + */ #define NVC0_BUFFER_STATUS_DIRTY (1 << 0) #define NVC0_BUFFER_STATUS_USER_MEMORY (1 << 7) @@ -84,7 +90,8 @@ nvc0_resource_map_offset(struct nvc0_context *nvc0, (res->status & NVC0_BUFFER_STATUS_DIRTY)) nvc0_buffer_download(nvc0, res, 0, res->base.width0); - if (res->domain != NOUVEAU_BO_GART) + if ((res->domain != NOUVEAU_BO_GART) || + (res->status & NVC0_BUFFER_STATUS_USER_MEMORY)) return res->data + offset; if (res->mm) @@ -189,6 +196,6 @@ void nvc0_miptree_surface_del(struct pipe_context *, struct pipe_surface *); boolean -nvc0_migrate_vertices(struct nvc0_resource *buf, unsigned base, unsigned size); +nvc0_user_buffer_upload(struct nvc0_resource *, unsigned base, unsigned size); #endif diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index c191790ab14..54eec660b2a 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -289,11 +289,11 @@ nvc0_magic_3d_init(struct nouveau_channel *chan) OUT_RING (chan, (2 << 16) | 2); BEGIN_RING(chan, RING_3D_(0x0de8), 1); OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D_(0x165c), 1); - OUT_RING (chan, 0); +#if 0 /* software method */ BEGIN_RING(chan, RING_3D_(0x1528), 1); /* MP poke */ OUT_RING (chan, 0); +#endif BEGIN_RING(chan, RING_3D_(0x12ac), 1); OUT_RING (chan, 0); @@ -323,8 +323,10 @@ nvc0_magic_3d_init(struct nouveau_channel *chan) OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D_(0x0300), 1); OUT_RING (chan, 3); +#if 0 /* software method */ BEGIN_RING(chan, RING_3D_(0x1280), 1); /* PGRAPH poke */ OUT_RING (chan, 0); +#endif BEGIN_RING(chan, RING_3D_(0x02d0), 1); OUT_RING (chan, 0x1f40); BEGIN_RING(chan, RING_3D_(0x00fdc), 1); @@ -441,9 +443,9 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(RT_CONTROL), 1); OUT_RING (chan, 1); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_ZETA_ENABLE), 1); + BEGIN_RING(chan, RING_3D(CSAA_ENABLE), 1); OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(MULTISAMPLE_COLOR_ENABLE), 1); + BEGIN_RING(chan, RING_3D(MULTISAMPLE_ENABLE), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(MULTISAMPLE_MODE), 1); OUT_RING (chan, NVC0_3D_MULTISAMPLE_MODE_1X); @@ -503,8 +505,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) goto fail; BEGIN_RING(chan, RING_3D_(0x17bc), 3); - OUT_RELOCh(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); - OUT_RELOCl(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RDWR); + OUT_RELOCh(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, screen->mp_stack_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); OUT_RING (chan, 1); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc); @@ -521,7 +523,7 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RELOCl(chan, screen->txc, 65536, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); OUT_RING (chan, NVC0_TSC_MAX_ENTRIES - 1); - BEGIN_RING(chan, RING_3D(Y_ORIGIN_BOTTOM), 1); + BEGIN_RING(chan, RING_3D(SCREEN_Y_CONTROL), 1); OUT_RING (chan, 0); BEGIN_RING(chan, RING_3D(WINDOW_OFFSET_X), 2); OUT_RING (chan, 0); @@ -587,6 +589,8 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1); OUT_RING (chan, 0); + BEGIN_RING(chan, RING_3D(POINT_RASTER_RULES), 1); + OUT_RING (chan, NVC0_3D_POINT_RASTER_RULES_OGL); BEGIN_RING(chan, RING_3D(FRAG_COLOR_CLAMP_EN), 1); OUT_RING (chan, 0x11111111); diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index a6595c56106..981b5488d08 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -100,7 +100,7 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0) return; BEGIN_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), 1); - OUT_RING (chan, 0); + OUT_RING (chan, fp->fp.early_z); BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2); OUT_RING (chan, 0x51); OUT_RING (chan, fp->code_base); diff --git a/src/gallium/drivers/nvc0/nvc0_state.c b/src/gallium/drivers/nvc0/nvc0_state.c index 5a9b1c28509..c08f3693f5e 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -207,6 +207,7 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe, SB_DATA (so, fui(cso->point_size)); } SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); + SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); SB_BEGIN_3D(so, POLYGON_MODE_FRONT, 1); SB_DATA (so, nvgl_polygon_mode(cso->fill_front)); diff --git a/src/gallium/drivers/nvc0/nvc0_stateobj.h b/src/gallium/drivers/nvc0/nvc0_stateobj.h index e7cd94800de..ee788c5bb9c 100644 --- a/src/gallium/drivers/nvc0/nvc0_stateobj.h +++ b/src/gallium/drivers/nvc0/nvc0_stateobj.h @@ -48,7 +48,7 @@ nvc0_tic_entry(struct pipe_sampler_view *view) struct nvc0_rasterizer_stateobj { struct pipe_rasterizer_state pipe; int size; - uint32_t state[43]; + uint32_t state[36]; }; struct nvc0_zsa_stateobj { diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index fd7a7942cb8..a14e9557382 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -141,52 +141,107 @@ nvc0_emit_vtxattr(struct nvc0_context *nvc0, struct pipe_vertex_buffer *vb, OUT_RINGf(chan, v[i]); } -void -nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) +static void +nvc0_prevalidate_vbufs(struct nvc0_context *nvc0) { - struct nouveau_channel *chan = nvc0->screen->base.channel; - struct nvc0_vertex_stateobj *vertex = nvc0->vertex; struct pipe_vertex_buffer *vb; - struct nvc0_vertex_element *ve; - unsigned i; - boolean push = FALSE; + struct nvc0_resource *buf; + int i; + uint32_t base, size; - nvc0->vbo_fifo = 0; + nvc0->vbo_fifo = nvc0->vbo_user = 0; for (i = 0; i < nvc0->num_vtxbufs; ++i) { vb = &nvc0->vtxbuf[i]; + if (!vb->stride) + continue; + buf = nvc0_resource(vb->buffer); if (!nvc0_resource_mapped_by_gpu(vb->buffer)) { - if (vb->stride == 0) + if (nvc0->vbo_push_hint) { + nvc0->vbo_fifo = ~0; continue; - push = nvc0->vbo_push_hint; - if (!push) { - unsigned base, size; - base = vb->buffer_offset + nvc0->vbo_min_index * vb->stride; - size = (nvc0->vbo_max_index - nvc0->vbo_min_index + 1) * vb->stride; - nvc0_migrate_vertices(nvc0_resource(vb->buffer), base, size); + } else { + if (buf->status & NVC0_BUFFER_STATUS_USER_MEMORY) { + nvc0->vbo_user |= 1 << i; + assert(vb->stride > vb->buffer_offset); + size = vb->stride * (nvc0->vbo_max_index - + nvc0->vbo_min_index + 1); + base = vb->stride * nvc0->vbo_min_index; + nvc0_user_buffer_upload(buf, base, size); + } else { + nvc0_buffer_migrate(nvc0, buf, NOUVEAU_BO_GART); + } nvc0->vbo_dirty = TRUE; - } else - continue; + } } - nvc0_buffer_adjust_score(nvc0, nvc0_resource(vb->buffer), 1); + nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, buf, NOUVEAU_BO_RD); + nvc0_buffer_adjust_score(nvc0, buf, 1); + } +} - nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_VERTEX, - nvc0_resource(vb->buffer), NOUVEAU_BO_RD); +static void +nvc0_update_user_vbufs(struct nvc0_context *nvc0) +{ + struct nouveau_channel *chan = nvc0->screen->base.channel; + const uint32_t vertex_count = nvc0->vbo_max_index - nvc0->vbo_min_index + 1; + uint32_t base, offset, size; + int i; + uint32_t written = 0; + + for (i = 0; i < nvc0->vertex->num_elements; ++i) { + struct pipe_vertex_element *ve = &nvc0->vertex->element[i].pipe; + const int b = ve->vertex_buffer_index; + struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[b]; + struct nvc0_resource *buf = nvc0_resource(vb->buffer); + + if (!(nvc0->vbo_user & (1 << b))) + continue; + + if (!vb->stride) { + nvc0_emit_vtxattr(nvc0, vb, ve, i); + continue; + } + size = vb->stride * vertex_count; + base = vb->stride * nvc0->vbo_min_index; + + if (!(written & (1 << b))) { + written |= 1 << b; + nvc0_user_buffer_upload(buf, base, size); + } + offset = vb->buffer_offset + ve->src_offset; + + BEGIN_RING_1I(chan, RING_3D(VERTEX_ARRAY_SELECT), 5); + OUT_RING (chan, i); + OUT_RESRCh(chan, buf, size - 1, NOUVEAU_BO_RD); + OUT_RESRCl(chan, buf, size - 1, NOUVEAU_BO_RD); + OUT_RESRCh(chan, buf, offset, NOUVEAU_BO_RD); + OUT_RESRCl(chan, buf, offset, NOUVEAU_BO_RD); } + nvc0->vbo_dirty = TRUE; +} + +void +nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) +{ + struct nouveau_channel *chan = nvc0->screen->base.channel; + struct nvc0_vertex_stateobj *vertex = nvc0->vertex; + struct pipe_vertex_buffer *vb; + struct nvc0_vertex_element *ve; + unsigned i; + + nvc0_prevalidate_vbufs(nvc0); BEGIN_RING(chan, RING_3D(VERTEX_ATTRIB_FORMAT(0)), vertex->num_elements); for (i = 0; i < vertex->num_elements; ++i) { ve = &vertex->element[i]; vb = &nvc0->vtxbuf[ve->pipe.vertex_buffer_index]; - if (push) - nvc0->vbo_fifo |= 1 << i; - - if (likely(vb->stride) || push) { + if (likely(vb->stride) || nvc0->vbo_fifo) { OUT_RING(chan, ve->state); } else { OUT_RING(chan, ve->state | NVC0_3D_VERTEX_ATTRIB_FORMAT_CONST); + nvc0->vbo_fifo &= ~(1 << i); } } @@ -210,8 +265,8 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) res = nvc0_resource(vb->buffer); - if (push || unlikely(vb->stride == 0)) { - if (!push) + if (nvc0->vbo_fifo || unlikely(vb->stride == 0)) { + if (!nvc0->vbo_fifo) nvc0_emit_vtxattr(nvc0, vb, &ve->pipe, i); BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FETCH(i)), 1); OUT_RING (chan, 0); @@ -540,6 +595,9 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nvc0->vbo_min_index = info->min_index; nvc0->vbo_max_index = info->max_index; + if (nvc0->vbo_user && !(nvc0->dirty & (NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS))) + nvc0_update_user_vbufs(nvc0); + nvc0_state_validate(nvc0); if (nvc0->state.instance_base != info->start_instance) { @@ -554,7 +612,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } if (nvc0->vbo_dirty) { - BEGIN_RING(chan, RING_3D_(0x142c), 1); + BEGIN_RING(chan, RING_3D(VERTEX_ARRAY_FLUSH), 1); OUT_RING (chan, 0); nvc0->vbo_dirty = FALSE; } diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c index 1881e633d54..4f86e3b4c38 100644 --- a/src/gallium/drivers/r600/eg_asm.c +++ b/src/gallium/drivers/r600/eg_asm.c @@ -36,6 +36,8 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) switch (cf->inst) { case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3): + case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3): + case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3): case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3): assert(!end_of_program); bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) | diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h index ecea1db4f15..5a39d7cdeec 100644 --- a/src/gallium/drivers/r600/eg_state_inlines.h +++ b/src/gallium/drivers/r600/eg_state_inlines.h @@ -506,139 +506,4 @@ static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format) return r600_translate_colorformat(format) != ~0; } -static INLINE uint32_t r600_translate_vertex_data_type(enum pipe_format format) -{ - uint32_t result = 0; - const struct util_format_description *desc; - unsigned i; - - desc = util_format_description(format); - if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - goto out_unknown; - } - - /* Find the first non-VOID channel. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - break; - } - } - - switch (desc->channel[i].type) { - /* Half-floats, floats, doubles */ - case UTIL_FORMAT_TYPE_FLOAT: - switch (desc->channel[i].size) { - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16_FLOAT; - break; - case 2: - result = FMT_16_16_FLOAT; - break; - case 3: - result = FMT_16_16_16_FLOAT; - break; - case 4: - result = FMT_16_16_16_16_FLOAT; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32_FLOAT; - break; - case 2: - result = FMT_32_32_FLOAT; - break; - case 3: - result = FMT_32_32_32_FLOAT; - break; - case 4: - result = FMT_32_32_32_32_FLOAT; - break; - } - break; - default: - goto out_unknown; - } - break; - /* Unsigned ints */ - case UTIL_FORMAT_TYPE_UNSIGNED: - /* Signed ints */ - case UTIL_FORMAT_TYPE_SIGNED: - switch (desc->channel[i].size) { - case 8: - switch (desc->nr_channels) { - case 1: - result = FMT_8; - break; - case 2: - result = FMT_8_8; - break; - case 3: -// result = V_038008_FMT_8_8_8; /* fails piglit draw-vertices test */ -// break; - case 4: - result = FMT_8_8_8_8; - break; - } - break; - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16; - break; - case 2: - result = FMT_16_16; - break; - case 3: -// result = V_038008_FMT_16_16_16; /* fails piglit draw-vertices test */ -// break; - case 4: - result = FMT_16_16_16_16; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32; - break; - case 2: - result = FMT_32_32; - break; - case 3: - result = FMT_32_32_32; - break; - case 4: - result = FMT_32_32_32_32; - break; - } - break; - default: - goto out_unknown; - } - break; - default: - goto out_unknown; - } - - result = S_030008_DATA_FORMAT(result); - - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - result |= S_030008_FORMAT_COMP_ALL(1); - } - if (desc->channel[i].normalized) { - result |= S_030008_NUM_FORMAT_ALL(0); - } else { - result |= S_030008_NUM_FORMAT_ALL(2); - } - return result; -out_unknown: - R600_ERR("unsupported vertex format %s\n", util_format_name(format)); - return ~0; -} - #endif diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 94eef77945b..306ca03234f 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -409,7 +409,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]); r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4, word4 | S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_NORM) | - S_030010_SRF_MODE_ALL(V_030010_SFR_MODE_NO_ZERO) | + S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_NO_ZERO) | S_030010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5, S_030014_LAST_LEVEL(state->u.tex.last_level) | diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h index e67254b2560..e09e02ca000 100644 --- a/src/gallium/drivers/r600/evergreend.h +++ b/src/gallium/drivers/r600/evergreend.h @@ -988,8 +988,8 @@ #define S_030010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) #define G_030010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) #define C_030010_SRF_MODE_ALL 0xFFFFFBFF -#define V_030010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 -#define V_030010_SFR_MODE_NO_ZERO 0x00000001 +#define V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_030010_SRF_MODE_NO_ZERO 0x00000001 #define S_030010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) #define G_030010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) #define C_030010_FORCE_DEGAMMA 0xFFFFF7FF diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 31f386964a1..61de24b31ae 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -38,52 +38,109 @@ #define PREV_ALU(alu) LIST_ENTRY(struct r600_bc_alu, alu->list.prev, list) #define NEXT_ALU(alu) LIST_ENTRY(struct r600_bc_alu, alu->list.next, list) -static inline unsigned int r600_bc_get_num_operands(struct r600_bc_alu *alu) +static inline unsigned int r600_bc_get_num_operands(struct r600_bc *bc, struct r600_bc_alu *alu) { if(alu->is_op3) return 3; - switch (alu->inst) { - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP: - return 0; - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: - return 2; - - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: - case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: - return 1; - default: R600_ERR( - "Need instruction operand number for 0x%x.\n", alu->inst); - }; + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + switch (alu->inst) { + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP: + return 0; + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: + return 2; + + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: + case V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: + return 1; + default: R600_ERR( + "Need instruction operand number for 0x%x.\n", alu->inst); + } + break; + case CHIPREV_EVERGREEN: + switch (alu->inst) { + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP: + return 0; + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MIN: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETNE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SETGE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_XY: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_ZW: + return 2; + + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FRACT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLOOR: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_TRUNC: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN: + case EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS: + return 1; + default: R600_ERR( + "Need instruction operand number for 0x%x.\n", alu->inst); + } + break; + } return 3; } @@ -241,125 +298,226 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output) } /* alu predicate instructions */ -static int is_alu_pred_inst(struct r600_bc_alu *alu) -{ - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT); +static int is_alu_pred_inst(struct r600_bc *bc, struct r600_bc_alu *alu) +{ + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_INV || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_POP || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_CLR || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SET_RESTORE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETNE_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLT_PUSH_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETLE_PUSH_INT); + } } /* alu kill instructions */ -static int is_alu_kill_inst(struct r600_bc_alu *alu) +static int is_alu_kill_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT); + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT); + } } /* alu instructions that can ony exits once per group */ -static int is_alu_once_inst(struct r600_bc_alu *alu) +static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return is_alu_kill_inst(alu) || - is_alu_pred_inst(alu); + return is_alu_kill_inst(bc, alu) || + is_alu_pred_inst(bc, alu); } -static int is_alu_reduction_inst(struct r600_bc_alu *alu) +static int is_alu_reduction_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4); + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4); + } } -static int is_alu_mova_inst(struct r600_bc_alu *alu) +static int is_alu_mova_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !alu->is_op3 && ( - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT); + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + return !alu->is_op3 && ( + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_FLOOR || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT); + case CHIPREV_EVERGREEN: + default: + return !alu->is_op3 && ( + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT); + } } /* alu instructions that can only execute on the vector unit */ -static int is_alu_vec_unit_inst(struct r600_bc_alu *alu) +static int is_alu_vec_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return is_alu_reduction_inst(alu) || - is_alu_mova_inst(alu); + return is_alu_reduction_inst(bc, alu) || + is_alu_mova_inst(bc, alu); } /* alu instructions that can only execute on the trans unit */ -static int is_alu_trans_unit_inst(struct r600_bc_alu *alu) -{ - if(!alu->is_op3) - return alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN || - alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE; - else - return alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT || - alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 || - alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 || - alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4; +static int is_alu_trans_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) +{ + switch (bc->chiprev) { + case CHIPREV_R600: + case CHIPREV_R700: + if (!alu->is_op3) + return alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN || + alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE; + else + return alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT || + alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_D2 || + alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M2 || + alu->inst == V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT_M4; + case CHIPREV_EVERGREEN: + default: + if (!alu->is_op3) + return alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ASHR_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHR_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULHI_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MULLO_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_INT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_UINT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_COS || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_EXP_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_CLAMPED || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LOG_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_CLAMPED || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_FF || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_FF || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SIN || + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_IEEE; + else + return alu->inst == EG_V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MUL_LIT; + } } /* alu instructions that can execute on any unit */ -static int is_alu_any_unit_inst(struct r600_bc_alu *alu) +static int is_alu_any_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) { - return !is_alu_vec_unit_inst(alu) && - !is_alu_trans_unit_inst(alu); + return !is_alu_vec_unit_inst(bc, alu) && + !is_alu_trans_unit_inst(bc, alu); } -static int assign_alu_units(struct r600_bc_alu *alu_first, struct r600_bc_alu *assignment[5]) +static int assign_alu_units(struct r600_bc *bc, struct r600_bc_alu *alu_first, + struct r600_bc_alu *assignment[5]) { struct r600_bc_alu *alu; unsigned i, chan, trans; @@ -367,11 +525,11 @@ static int assign_alu_units(struct r600_bc_alu *alu_first, struct r600_bc_alu *a for (i = 0; i < 5; i++) assignment[i] = NULL; - for (alu = alu_first; alu; alu = NEXT_ALU(alu)) { + for (alu = alu_first; alu; alu = LIST_ENTRY(struct r600_bc_alu, alu->list.next, list)) { chan = alu->dst.chan; - if (is_alu_trans_unit_inst(alu)) + if (is_alu_trans_unit_inst(bc, alu)) trans = 1; - else if (is_alu_vec_unit_inst(alu)) + else if (is_alu_vec_unit_inst(bc, alu)) trans = 0; else if (assignment[chan]) trans = 1; // assume ALU_INST_PREFER_VECTOR @@ -471,34 +629,29 @@ static int is_gpr(unsigned sel) return (sel >= 0 && sel <= 127); } -static int is_cfile(unsigned sel) -{ - return (sel > 255 && sel < 512); -} - /* CB constants start at 512, and get translated to a kcache index when ALU * clauses are constructed. Note that we handle kcache constants the same way * as (the now gone) cfile constants, is that really required? */ -static int is_cb_const(int sel) +static int is_cfile(unsigned sel) { - if (sel > 511 && sel < 4607) - return 1; - return 0; + return (sel > 255 && sel < 512) || + (sel > 511 && sel < 4607) || // Kcache before translate + (sel > 127 && sel < 192); // Kcache after translate } static int is_const(int sel) { return is_cfile(sel) || - is_cb_const(sel) || (sel >= V_SQ_ALU_SRC_0 && sel <= V_SQ_ALU_SRC_LITERAL); } -static int check_vector(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, int bank_swizzle) +static int check_vector(struct r600_bc *bc, struct r600_bc_alu *alu, + struct alu_bank_swizzle *bs, int bank_swizzle) { int r, src, num_src, sel, elem, cycle; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; src++) { sel = alu->src[src].sel; elem = alu->src[src].chan; @@ -523,11 +676,12 @@ static int check_vector(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, in return 0; } -static int check_scalar(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, int bank_swizzle) +static int check_scalar(struct r600_bc *bc, struct r600_bc_alu *alu, + struct alu_bank_swizzle *bs, int bank_swizzle) { int r, src, num_src, const_count, sel, elem, cycle; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (const_count = 0, src = 0; src < num_src; ++src) { sel = alu->src[src].sel; elem = alu->src[src].chan; @@ -564,7 +718,8 @@ static int check_scalar(struct r600_bc_alu *alu, struct alu_bank_swizzle *bs, in return 0; } -static int check_and_set_bank_swizzle(struct r600_bc_alu *slots[5]) +static int check_and_set_bank_swizzle(struct r600_bc *bc, + struct r600_bc_alu *slots[5]) { struct alu_bank_swizzle bs; int bank_swizzle[5]; @@ -588,13 +743,13 @@ static int check_and_set_bank_swizzle(struct r600_bc_alu *slots[5]) init_bank_swizzle(&bs); for (i = 0; i < 4; i++) { if (slots[i]) { - r = check_vector(slots[i], &bs, bank_swizzle[i]); + r = check_vector(bc, slots[i], &bs, bank_swizzle[i]); if (r) break; } } if (!r && slots[4]) { - r = check_scalar(slots[4], &bs, bank_swizzle[4]); + r = check_scalar(bc, slots[4], &bs, bank_swizzle[4]); } if (!r) { for (i = 0; i < 5; i++) { @@ -617,20 +772,21 @@ static int check_and_set_bank_swizzle(struct r600_bc_alu *slots[5]) return -1; } -static int replace_gpr_with_pv_ps(struct r600_bc_alu *slots[5], struct r600_bc_alu *alu_prev) +static int replace_gpr_with_pv_ps(struct r600_bc *bc, + struct r600_bc_alu *slots[5], struct r600_bc_alu *alu_prev) { struct r600_bc_alu *prev[5]; int gpr[5], chan[5]; int i, j, r, src, num_src; - r = assign_alu_units(alu_prev, prev); + r = assign_alu_units(bc, alu_prev, prev); if (r) return r; for (i = 0; i < 5; ++i) { if(prev[i] && prev[i]->dst.write && !prev[i]->dst.rel) { gpr[i] = prev[i]->dst.sel; - if (is_alu_reduction_inst(prev[i])) + if (is_alu_reduction_inst(bc, prev[i])) chan[i] = 0; else chan[i] = prev[i]->dst.chan; @@ -643,7 +799,7 @@ static int replace_gpr_with_pv_ps(struct r600_bc_alu *slots[5], struct r600_bc_a if(!alu) continue; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { if (!is_gpr(alu->src[src].sel) || alu->src[src].rel) continue; @@ -702,9 +858,10 @@ void r600_bc_special_constants(u32 value, unsigned *sel, unsigned *neg) } /* compute how many literal are needed */ -static int r600_bc_alu_nliterals(struct r600_bc_alu *alu, uint32_t literal[4], unsigned *nliteral) +static int r600_bc_alu_nliterals(struct r600_bc *bc, struct r600_bc_alu *alu, + uint32_t literal[4], unsigned *nliteral) { - unsigned num_src = r600_bc_get_num_operands(alu); + unsigned num_src = r600_bc_get_num_operands(bc, alu); unsigned i, j; for (i = 0; i < num_src; ++i) { @@ -727,9 +884,11 @@ static int r600_bc_alu_nliterals(struct r600_bc_alu *alu, uint32_t literal[4], u return 0; } -static void r600_bc_alu_adjust_literals(struct r600_bc_alu *alu, uint32_t literal[4], unsigned nliteral) +static void r600_bc_alu_adjust_literals(struct r600_bc *bc, + struct r600_bc_alu *alu, + uint32_t literal[4], unsigned nliteral) { - unsigned num_src = r600_bc_get_num_operands(alu); + unsigned num_src = r600_bc_get_num_operands(bc, alu); unsigned i, j; for (i = 0; i < num_src; ++i) { @@ -745,40 +904,47 @@ static void r600_bc_alu_adjust_literals(struct r600_bc_alu *alu, uint32_t litera } } -static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], struct r600_bc_alu *alu_prev) +static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], + struct r600_bc_alu *alu_prev) { struct r600_bc_alu *prev[5]; struct r600_bc_alu *result[5] = { NULL }; - uint32_t literal[4]; - unsigned nliteral = 0; + uint32_t literal[4], prev_literal[4]; + unsigned nliteral = 0, prev_nliteral = 0; int i, j, r, src, num_src; int num_once_inst = 0; - r = assign_alu_units(alu_prev, prev); + r = assign_alu_units(bc, alu_prev, prev); if (r) return r; for (i = 0; i < 5; ++i) { + struct r600_bc_alu *alu; + /* check number of literals */ - if (prev[i] && r600_bc_alu_nliterals(prev[i], literal, &nliteral)) - return 0; - if (slots[i] && r600_bc_alu_nliterals(slots[i], literal, &nliteral)) + if (prev[i]) { + if (r600_bc_alu_nliterals(bc, prev[i], literal, &nliteral)) + return 0; + if (r600_bc_alu_nliterals(bc, prev[i], prev_literal, &prev_nliteral)) + return 0; + } + if (slots[i] && r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral)) return 0; // let's check used slots if (prev[i] && !slots[i]) { result[i] = prev[i]; - num_once_inst += is_alu_once_inst(prev[i]); + num_once_inst += is_alu_once_inst(bc, prev[i]); continue; } else if (prev[i] && slots[i]) { if (result[4] == NULL && prev[4] == NULL && slots[4] == NULL) { // trans unit is still free try to use it - if (is_alu_any_unit_inst(slots[i])) { + if (is_alu_any_unit_inst(bc, slots[i])) { result[i] = prev[i]; result[4] = slots[i]; - } else if (is_alu_any_unit_inst(prev[i])) { + } else if (is_alu_any_unit_inst(bc, prev[i])) { result[i] = slots[i]; result[4] = prev[i]; } else @@ -791,10 +957,10 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], s result[i] = slots[i]; // let's check source gprs - struct r600_bc_alu *alu = slots[i]; - num_once_inst += is_alu_once_inst(alu); + alu = slots[i]; + num_once_inst += is_alu_once_inst(bc, alu); - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { // constants doesn't matter if (!is_gpr(alu->src[src].sel)) @@ -818,12 +984,15 @@ static int merge_inst_groups(struct r600_bc *bc, struct r600_bc_alu *slots[5], s return 0; /* check if the result can still be swizzlet */ - r = check_and_set_bank_swizzle(result); + r = check_and_set_bank_swizzle(bc, result); if (r) return 0; /* looks like everything worked out right, apply the changes */ + /* undo adding previus literals */ + bc->cf_last->ndw -= align(prev_nliteral, 2); + /* sort instructions */ for (i = 0; i < 5; ++i) { slots[i] = result[i]; @@ -1009,11 +1178,6 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int if (!bc->cf_last->curr_bs_head) { bc->cf_last->curr_bs_head = nalu; } - /* at most 128 slots, one add alu can add 5 slots + 4 constants(2 slots) - * worst case */ - if (nalu->last && (bc->cf_last->ndw >> 1) >= 120) { - bc->force_add_cf = 1; - } /* replace special constants */ for (i = 0; i < 3; i++) { if (nalu->src[i].sel == V_SQ_ALU_SRC_LITERAL) @@ -1036,8 +1200,10 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int /* process cur ALU instructions for bank swizzle */ if (nalu->last) { + uint32_t literal[4]; + unsigned nliteral; struct r600_bc_alu *slots[5]; - r = assign_alu_units(bc->cf_last->curr_bs_head, slots); + r = assign_alu_units(bc, bc->cf_last->curr_bs_head, slots); if (r) return r; @@ -1048,15 +1214,30 @@ int r600_bc_add_alu_type(struct r600_bc *bc, const struct r600_bc_alu *alu, int } if (bc->cf_last->prev_bs_head) { - r = replace_gpr_with_pv_ps(slots, bc->cf_last->prev_bs_head); + r = replace_gpr_with_pv_ps(bc, slots, bc->cf_last->prev_bs_head); if (r) return r; } - r = check_and_set_bank_swizzle(slots); + r = check_and_set_bank_swizzle(bc, slots); if (r) return r; + for (i = 0, nliteral = 0; i < 5; i++) { + if (slots[i]) { + r = r600_bc_alu_nliterals(bc, slots[i], literal, &nliteral); + if (r) + return r; + } + } + bc->cf_last->ndw += align(nliteral, 2); + + /* at most 128 slots, one add alu can add 5 slots + 4 constants(2 slots) + * worst case */ + if ((bc->cf_last->ndw >> 1) >= 120) { + bc->force_add_cf = 1; + } + bc->cf_last->prev2_bs_head = bc->cf_last->prev_bs_head; bc->cf_last->prev_bs_head = bc->cf_last->curr_bs_head; bc->cf_last->curr_bs_head = NULL; @@ -1129,6 +1310,12 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex) } bc->cf_last->inst = V_SQ_CF_WORD1_SQ_CF_INST_TEX; } + if (ntex->src_gpr >= bc->ngpr) { + bc->ngpr = ntex->src_gpr + 1; + } + if (ntex->dst_gpr >= bc->ngpr) { + bc->ngpr = ntex->dst_gpr + 1; + } LIST_ADDTAIL(&ntex->list, &bc->cf_last->tex); /* each texture fetch use 4 dwords */ bc->cf_last->ndw += 4; @@ -1457,11 +1644,12 @@ static void notice_gpr_rel_write(struct gpr_usage usage[128], int32_t id, unsign notice_gpr_write(&usage[i], id, chan, 1, -1); } -static void notice_alu_src_gprs(struct r600_bc_alu *alu, struct gpr_usage usage[128], int32_t id) +static void notice_alu_src_gprs(struct r600_bc *bc, struct r600_bc_alu *alu, + struct gpr_usage usage[128], int32_t id) { unsigned src, num_src; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { // constants doesn't matter if (!is_gpr(alu->src[src].sel)) @@ -1716,14 +1904,14 @@ static void find_export_replacement(struct gpr_usage usage[128], find_src_range(&usage[next->output.gpr], next_id)->replacement = range->replacement + 1; } -static void replace_alu_gprs(struct r600_bc_alu *alu, struct gpr_usage usage[128], +static void replace_alu_gprs(struct r600_bc *bc, struct r600_bc_alu *alu, struct gpr_usage usage[128], int32_t id, int32_t last_barrier, unsigned *barrier) { struct gpr_usage *cur_usage; struct gpr_usage_range *range; unsigned src, num_src; - num_src = r600_bc_get_num_operands(alu); + num_src = r600_bc_get_num_operands(bc, alu); for (src = 0; src < num_src; ++src) { // constants doesn't matter if (!is_gpr(alu->src[src].sel)) @@ -1851,7 +2039,7 @@ static void replace_export_gprs(struct r600_bc_cf *cf, struct gpr_usage usage[12 cf->output.gpr = range->replacement; } -static void optimize_alu_inst(struct r600_bc_cf *cf, struct r600_bc_alu *alu) +static void optimize_alu_inst(struct r600_bc *bc, struct r600_bc_cf *cf, struct r600_bc_alu *alu) { struct r600_bc_alu *alu_next; unsigned chan; @@ -1877,9 +2065,9 @@ static void optimize_alu_inst(struct r600_bc_cf *cf, struct r600_bc_alu *alu) for (alu_next = alu; !alu_next->last; alu_next = NEXT_ALU(alu_next)); if (alu_next->list.next != &cf->alu) { - chan = is_alu_reduction_inst(alu) ? 0 : alu->dst.chan; + chan = is_alu_reduction_inst(bc, alu) ? 0 : alu->dst.chan; for (alu_next = NEXT_ALU(alu_next); alu_next; alu_next = NEXT_ALU(alu_next)) { - num_src = r600_bc_get_num_operands(alu_next); + num_src = r600_bc_get_num_operands(bc, alu_next); for (src = 0; src < num_src; ++src) { if (alu_next->src[src].sel == V_SQ_ALU_SRC_PV && alu_next->src[src].chan == chan) @@ -1963,13 +2151,13 @@ static void r600_bc_optimize(struct r600_bc *bc) LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { if (!first) first = alu; - notice_alu_src_gprs(alu, usage, id); + notice_alu_src_gprs(bc, alu, usage, id); if (alu->last) { notice_alu_dst_gprs(first, usage, id, predicate || stack > 0); first = NULL; ++id; } - if (is_alu_pred_inst(alu)) + if (is_alu_pred_inst(bc, alu)) predicate++; } if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3) @@ -2058,15 +2246,15 @@ static void r600_bc_optimize(struct r600_bc *bc) first = NULL; cf->barrier = 0; LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) { - replace_alu_gprs(alu, usage, id, barrier[stack], &cf->barrier); + replace_alu_gprs(bc, alu, usage, id, barrier[stack], &cf->barrier); if (alu->last) ++id; - if (is_alu_pred_inst(alu)) + if (is_alu_pred_inst(bc, alu)) predicate++; if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3) - optimize_alu_inst(cf, alu); + optimize_alu_inst(bc, cf, alu); } if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3) stack += predicate; @@ -2159,16 +2347,6 @@ int r600_bc_build(struct r600_bc *bc) LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { switch (get_cf_class(cf)) { case CF_CLASS_ALU: - nliteral = 0; - LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r = r600_bc_alu_nliterals(alu, literal, &nliteral); - if (r) - return r; - if (alu->last) { - cf->ndw += align(nliteral, 2); - nliteral = 0; - } - } break; case CF_CLASS_TEXTURE: case CF_CLASS_VERTEX: @@ -2214,11 +2392,12 @@ int r600_bc_build(struct r600_bc *bc) switch (get_cf_class(cf)) { case CF_CLASS_ALU: nliteral = 0; + memset(literal, 0, sizeof(literal)); LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r = r600_bc_alu_nliterals(alu, literal, &nliteral); + r = r600_bc_alu_nliterals(bc, alu, literal, &nliteral); if (r) return r; - r600_bc_alu_adjust_literals(alu, literal, nliteral); + r600_bc_alu_adjust_literals(bc, alu, literal, nliteral); switch(bc->chiprev) { case CHIPREV_R600: r = r600_bc_alu_build(bc, alu, addr); @@ -2239,6 +2418,7 @@ int r600_bc_build(struct r600_bc *bc) bc->bytecode[addr++] = literal[i]; } nliteral = 0; + memset(literal, 0, sizeof(literal)); } } break; @@ -2307,10 +2487,10 @@ void r600_bc_clear(struct r600_bc *bc) void r600_bc_dump(struct r600_bc *bc) { - struct r600_bc_cf *cf; - struct r600_bc_alu *alu; - struct r600_bc_vtx *vtx; - struct r600_bc_tex *tex; + struct r600_bc_cf *cf = NULL; + struct r600_bc_alu *alu = NULL; + struct r600_bc_vtx *vtx = NULL; + struct r600_bc_tex *tex = NULL; unsigned i, id; uint32_t literal[4]; @@ -2329,7 +2509,7 @@ void r600_bc_dump(struct r600_bc *bc) chip = '6'; break; } - fprintf(stderr, "bytecode %d dw -- %d gprs -----------------------\n", bc->ndw, bc->ngpr); + fprintf(stderr, "bytecode %d dw -- %d gprs ---------------------\n", bc->ndw, bc->ngpr); fprintf(stderr, " %c\n", chip); LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) { @@ -2393,7 +2573,7 @@ void r600_bc_dump(struct r600_bc *bc) id = cf->addr; nliteral = 0; LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) { - r600_bc_alu_nliterals(alu, literal, &nliteral); + r600_bc_alu_nliterals(bc, alu, literal, &nliteral); fprintf(stderr, "%04d %08X ", id, bc->bytecode[id]); fprintf(stderr, "SRC0(SEL:%d ", alu->src[0].sel); @@ -2431,7 +2611,7 @@ void r600_bc_dump(struct r600_bc *bc) if (alu->last) { for (i = 0; i < nliteral; i++, id++) { float *f = (float*)(bc->bytecode + id); - fprintf(stderr, "%04d %08X %f\n", id, bc->bytecode[id], *f); + fprintf(stderr, "%04d %08X\t%f\n", id, bc->bytecode[id], *f); } id += nliteral & 1; nliteral = 0; diff --git a/src/gallium/drivers/r600/r600_opcodes.h b/src/gallium/drivers/r600/r600_opcodes.h index 2ee0c83e5d3..a85d0bbf1e1 100644 --- a/src/gallium/drivers/r600/r600_opcodes.h +++ b/src/gallium/drivers/r600/r600_opcodes.h @@ -330,10 +330,14 @@ #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_CLAMPED_64 0x00000098 #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_SQRT_64 0x00000099 /* TODO Fill in more ALU */ +#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_INT_TO_FLT 0x0000009B +#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_UINT_TO_FLT 0x0000009C +/* TODO Fill in more ALU */ #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR 0x000000B1 #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4 0x000000BE #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4_IEEE 0x000000BF #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE 0x000000C0 +#define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MAX4 0x000000C1 #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOVA_INT 0x000000CC #define EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INTERP_XY 0x000000D6 diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 95367d7c536..106852c1082 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -228,12 +228,20 @@ int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader) int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_shader *shader, u32 **literals); int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *shader, const struct tgsi_token *tokens) { + static int dump_shaders = -1; struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; u32 *literals; int r; -//fprintf(stderr, "--------------------------------------------------------------\n"); -//tgsi_dump(tokens, 0); + /* Would like some magic "get_bool_option_once" routine. + */ + if (dump_shaders == -1) + dump_shaders = debug_get_bool_option("R600_DUMP_SHADERS", FALSE); + + if (dump_shaders) { + fprintf(stderr, "--------------------------------------------------------------\n"); + tgsi_dump(tokens, 0); + } shader->shader.family = r600_get_family(rctx->radeon); r = r600_shader_from_tgsi(tokens, &shader->shader, &literals); if (r) { @@ -246,8 +254,10 @@ int r600_pipe_shader_create(struct pipe_context *ctx, struct r600_pipe_shader *s R600_ERR("building bytecode failed !\n"); return r; } -//r600_bc_dump(&shader->shader.bc); -//fprintf(stderr, "______________________________________________________________\n"); + if (dump_shaders) { + r600_bc_dump(&shader->shader.bc); + fprintf(stderr, "______________________________________________________________\n"); + } return r600_pipe_shader(ctx, shader); } @@ -974,7 +984,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, alu.src[1].chan = 0; alu.src[1].value = (uint32_t *)&half_inv_pi; alu.src[2].sel = V_SQ_ALU_SRC_0_5; - alu.src[2].chan = 1; + alu.src[2].chan = 0; alu.last = 1; r = r600_bc_add_alu(ctx->bc, &alu); if (r) @@ -1008,7 +1018,7 @@ static int tgsi_setup_trig(struct r600_shader_ctx *ctx, alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; alu.src[1].chan = 0; alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; - alu.src[2].chan = 1; + alu.src[2].chan = 0; if (ctx->bc->chiprev == CHIPREV_R600) { alu.src[1].value = (uint32_t *)&double_pi; @@ -1772,6 +1782,7 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) alu.src[2].sel = V_SQ_ALU_SRC_LITERAL; alu.src[2].chan = 0; + alu.src[2].value = (u32*)&one_point_five; alu.dst.sel = ctx->temp_reg; alu.dst.chan = 0; diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 9572ff9a1a2..de2668cee16 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -678,7 +678,7 @@ static struct pipe_sampler_view *r600_create_sampler_view(struct pipe_context *c (tmp->offset[1] + r600_bo_offset(bo[1])) >> 8, 0xFFFFFFFF, bo[1]); r600_pipe_state_add_reg(rstate, R_038010_RESOURCE0_WORD4, word4 | S_038010_NUM_FORMAT_ALL(V_038010_SQ_NUM_FORMAT_NORM) | - S_038010_SRF_MODE_ALL(V_038010_SFR_MODE_NO_ZERO) | + S_038010_SRF_MODE_ALL(V_038010_SRF_MODE_NO_ZERO) | S_038010_REQUEST_SIZE(1) | S_038010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_038014_RESOURCE0_WORD5, diff --git a/src/gallium/drivers/r600/r600_state_inlines.h b/src/gallium/drivers/r600/r600_state_inlines.h index 39ca0a74f3f..a0ec493fc85 100644 --- a/src/gallium/drivers/r600/r600_state_inlines.h +++ b/src/gallium/drivers/r600/r600_state_inlines.h @@ -502,139 +502,4 @@ static INLINE boolean r600_is_vertex_format_supported(enum pipe_format format) return r600_translate_colorformat(format) != ~0; } -static INLINE uint32_t r600_translate_vertex_data_type(enum pipe_format format) -{ - uint32_t result = 0; - const struct util_format_description *desc; - unsigned i; - - desc = util_format_description(format); - if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { - goto out_unknown; - } - - /* Find the first non-VOID channel. */ - for (i = 0; i < 4; i++) { - if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) { - break; - } - } - - switch (desc->channel[i].type) { - /* Half-floats, floats, doubles */ - case UTIL_FORMAT_TYPE_FLOAT: - switch (desc->channel[i].size) { - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16_FLOAT; - break; - case 2: - result = FMT_16_16_FLOAT; - break; - case 3: - result = FMT_16_16_16_FLOAT; - break; - case 4: - result = FMT_16_16_16_16_FLOAT; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32_FLOAT; - break; - case 2: - result = FMT_32_32_FLOAT; - break; - case 3: - result = FMT_32_32_32_FLOAT; - break; - case 4: - result = FMT_32_32_32_32_FLOAT; - break; - } - break; - default: - goto out_unknown; - } - break; - /* Unsigned ints */ - case UTIL_FORMAT_TYPE_UNSIGNED: - /* Signed ints */ - case UTIL_FORMAT_TYPE_SIGNED: - switch (desc->channel[i].size) { - case 8: - switch (desc->nr_channels) { - case 1: - result = FMT_8; - break; - case 2: - result = FMT_8_8; - break; - case 3: - // result = FMT_8_8_8; /* fails piglit draw-vertices test */ - // break; - case 4: - result = FMT_8_8_8_8; - break; - } - break; - case 16: - switch (desc->nr_channels) { - case 1: - result = FMT_16; - break; - case 2: - result = FMT_16_16; - break; - case 3: - // result = FMT_16_16_16; /* fails piglit draw-vertices test */ - // break; - case 4: - result = FMT_16_16_16_16; - break; - } - break; - case 32: - switch (desc->nr_channels) { - case 1: - result = FMT_32; - break; - case 2: - result = FMT_32_32; - break; - case 3: - result = FMT_32_32_32; - break; - case 4: - result = FMT_32_32_32_32; - break; - } - break; - default: - goto out_unknown; - } - break; - default: - goto out_unknown; - } - - result = S_038008_DATA_FORMAT(result); - - if (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED) { - result |= S_038008_FORMAT_COMP_ALL(1); - } - if (desc->channel[i].normalized) { - result |= S_038008_NUM_FORMAT_ALL(0); - } else { - result |= S_038008_NUM_FORMAT_ALL(2); - } - return result; -out_unknown: - R600_ERR("unsupported vertex format %s\n", util_format_name(format)); - return ~0; -} - #endif diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h index ae19bfb8285..8c391936db0 100644 --- a/src/gallium/drivers/r600/r600d.h +++ b/src/gallium/drivers/r600/r600d.h @@ -960,8 +960,8 @@ #define S_038010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) #define G_038010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) #define C_038010_SRF_MODE_ALL 0xFFFFFBFF -#define V_038010_SFR_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 -#define V_038010_SFR_MODE_NO_ZERO 0x00000001 +#define V_038010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 +#define V_038010_SRF_MODE_NO_ZERO 0x00000001 #define S_038010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) #define G_038010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) #define C_038010_FORCE_DEGAMMA 0xFFFFF7FF diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index cd3b6240fe9..c433405cb66 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -124,6 +124,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param) return 0; case PIPE_CAP_SHADER_STENCIL_EXPORT: return 1; + case PIPE_CAP_INSTANCED_DRAWING: + return 1; default: return 0; } diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index f60b131f941..a7f8503251b 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -462,6 +462,7 @@ enum pipe_cap { PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER, PIPE_CAP_DEPTH_CLAMP, PIPE_CAP_SHADER_STENCIL_EXPORT, + PIPE_CAP_INSTANCED_DRAWING, }; /* Shader caps not specific to any single stage */ diff --git a/src/gallium/state_trackers/egl/SConscript b/src/gallium/state_trackers/egl/SConscript index 50c76819954..9ade76ecbb2 100644 --- a/src/gallium/state_trackers/egl/SConscript +++ b/src/gallium/state_trackers/egl/SConscript @@ -10,11 +10,8 @@ env.Append(CPPPATH = [ '#/src/gallium/winsys/sw', '.', ]) -env.Append(CPPDEFINES = [ - 'HAVE_GDI_BACKEND', -]) -common_sources = [ +sources = [ 'common/egl_g3d.c', 'common/egl_g3d_api.c', 'common/egl_g3d_image.c', @@ -23,12 +20,31 @@ common_sources = [ 'common/native_helper.c', ] -gdi_sources = common_sources + [ - 'gdi/native_gdi.c', -] +if env['platform'] == 'windows': + env.Append(CPPDEFINES = ['HAVE_GDI_BACKEND']) + sources.append('gdi/native_gdi.c') +else: + if env['x11']: + env.Append(CPPDEFINES = ['HAVE_X11_BACKEND']) + env.Prepend(CPPPATH = [ + '#/src/glx', + '#/src/mapi', + ]) + sources.append([ + 'x11/native_x11.c', + 'x11/native_dri2.c', + 'x11/native_ximage.c', + 'x11/x11_screen.c', + 'x11/glxinit.c']) + if env['dri']: + env.Append(CPPDEFINES = ['GLX_DIRECT_RENDERING']) + sources.append(['#/src/glx/dri2.c']) + if env['drm']: + env.Append(CPPDEFINES = ['HAVE_DRM_BACKEND']) + sources.append(['drm/native_drm.c', 'drm/modeset.c']) -st_egl_gdi = env.ConvenienceLibrary( - target = 'st_egl_gdi', - source = gdi_sources, +st_egl = env.ConvenienceLibrary( + target = 'st_egl', + source = sources, ) -Export('st_egl_gdi') +Export('st_egl') diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index f2b137a674a..9024f945b8c 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -38,6 +38,46 @@ #include "egl_g3d_loader.h" #include "native.h" +static void +egl_g3d_invalid_surface(struct native_display *ndpy, + struct native_surface *nsurf, + unsigned int seq_num) +{ + /* XXX not thread safe? */ + struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); + struct egl_g3d_context *gctx; + + /* + * Some functions such as egl_g3d_copy_buffers create a temporary native + * surface. There is no gsurf associated with it. + */ + gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL; + if (gctx) + gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi); +} + +static struct pipe_screen * +egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + return gdpy->loader->create_drm_screen(name, fd); +} + +static struct pipe_screen * +egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) +{ + _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + return gdpy->loader->create_sw_screen(ws); +} + +static struct native_event_handler egl_g3d_native_event_handler = { + egl_g3d_invalid_surface, + egl_g3d_new_drm_screen, + egl_g3d_new_sw_screen +}; + /** * Get the native platform. */ @@ -79,7 +119,9 @@ egl_g3d_get_platform(_EGLDriver *drv, _EGLPlatformType plat) break; } - if (!nplat) + if (nplat) + nplat->set_event_handler(&egl_g3d_native_event_handler); + else _eglLog(_EGL_WARNING, "unsupported platform %s", plat_name); gdrv->platforms[plat] = nplat; @@ -280,7 +322,7 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy, ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT; valid = init_config_attributes(&gconf->base, - nconf, dpy->ClientAPIsMask, depth_stencil_format, + nconf, dpy->ClientAPIs, depth_stencil_format, preserve_buffer, max_swap_interval); if (!valid) { _eglLog(_EGL_DEBUG, "skip invalid config 0x%x", nconf->native_visual_id); @@ -384,46 +426,6 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) } static void -egl_g3d_invalid_surface(struct native_display *ndpy, - struct native_surface *nsurf, - unsigned int seq_num) -{ - /* XXX not thread safe? */ - struct egl_g3d_surface *gsurf = egl_g3d_surface(nsurf->user_data); - struct egl_g3d_context *gctx; - - /* - * Some functions such as egl_g3d_copy_buffers create a temporary native - * surface. There is no gsurf associated with it. - */ - gctx = (gsurf) ? egl_g3d_context(gsurf->base.CurrentContext) : NULL; - if (gctx) - gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi); -} - -static struct pipe_screen * -egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd) -{ - _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - return gdpy->loader->create_drm_screen(name, fd); -} - -static struct pipe_screen * -egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws) -{ - _EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data; - struct egl_g3d_display *gdpy = egl_g3d_display(dpy); - return gdpy->loader->create_sw_screen(ws); -} - -static struct native_event_handler egl_g3d_native_event_handler = { - egl_g3d_invalid_surface, - egl_g3d_new_drm_screen, - egl_g3d_new_sw_screen -}; - -static void egl_g3d_free_config(void *conf) { struct egl_g3d_config *gconf = egl_g3d_config((_EGLConfig *) conf); @@ -474,8 +476,7 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) } static EGLBoolean -egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, - EGLint *major, EGLint *minor) +egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy) { struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); struct egl_g3d_display *gdpy; @@ -485,6 +486,9 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, if (!nplat) return EGL_FALSE; + if (dpy->Options.TestOnly) + return EGL_TRUE; + gdpy = CALLOC_STRUCT(egl_g3d_display); if (!gdpy) { _eglError(EGL_BAD_ALLOC, "eglInitialize"); @@ -495,20 +499,20 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, _eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay); gdpy->native = nplat->create_display(dpy->PlatformDisplay, - &egl_g3d_native_event_handler, (void *) dpy); + dpy->Options.UseFallback, (void *) dpy); if (!gdpy->native) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)"); goto fail; } if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_DEFAULT_MASK) - dpy->ClientAPIsMask |= EGL_OPENGL_BIT; + dpy->ClientAPIs |= EGL_OPENGL_BIT; if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES1_MASK) - dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT; + dpy->ClientAPIs |= EGL_OPENGL_ES_BIT; if (gdpy->loader->profile_masks[ST_API_OPENGL] & ST_PROFILE_OPENGL_ES2_MASK) - dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT; + dpy->ClientAPIs |= EGL_OPENGL_ES2_BIT; if (gdpy->loader->profile_masks[ST_API_OPENVG] & ST_PROFILE_DEFAULT_MASK) - dpy->ClientAPIsMask |= EGL_OPENVG_BIT; + dpy->ClientAPIs |= EGL_OPENVG_BIT; gdpy->smapi = egl_g3d_create_st_manager(dpy); if (!gdpy->smapi) { @@ -547,8 +551,8 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, goto fail; } - *major = 1; - *minor = 4; + dpy->VersionMajor = 1; + dpy->VersionMinor = 4; return EGL_TRUE; @@ -573,12 +577,6 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) stapi->get_proc_address(stapi, procname) : NULL); } -static EGLint -egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy) -{ - return (egl_g3d_get_platform(drv, dpy->Platform)) ? 90 : 0; -} - _EGLDriver * egl_g3d_create_driver(const struct egl_g3d_loader *loader) { @@ -595,8 +593,6 @@ egl_g3d_create_driver(const struct egl_g3d_loader *loader) gdrv->base.API.Terminate = egl_g3d_terminate; gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address; - gdrv->base.Probe = egl_g3d_probe; - /* to be filled by the caller */ gdrv->base.Name = NULL; gdrv->base.Unload = NULL; diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index 654f445fca6..6461b5edbdf 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -226,8 +226,9 @@ native_attachment_mask_test(uint mask, enum native_attachment att) struct native_platform { const char *name; + void (*set_event_handler)(struct native_event_handler *handler); struct native_display *(*create_display)(void *dpy, - struct native_event_handler *handler, + boolean use_sw, void *user_data); }; diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index 2441b43fd8e..14c134ea1ad 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -237,9 +237,16 @@ drm_create_display(int fd, struct native_event_handler *event_handler, return &drmdpy->base; } +static struct native_event_handler *drm_event_handler; + +static void +native_set_event_handler(struct native_event_handler *event_handler) +{ + drm_event_handler = event_handler; +} + static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler, - void *user_data) +native_create_display(void *dpy, boolean use_sw, void *user_data) { int fd; @@ -252,11 +259,12 @@ native_create_display(void *dpy, struct native_event_handler *event_handler, if (fd < 0) return NULL; - return drm_create_display(fd, event_handler, user_data); + return drm_create_display(fd, drm_event_handler, user_data); } static const struct native_platform drm_platform = { "DRM", /* name */ + native_set_event_handler, native_create_display }; diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c index 1b5ea8bf9d5..a1e91ba701c 100644 --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c @@ -459,9 +459,16 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler, return &fbdpy->base; } +static struct native_event_handler *fbdev_event_handler; + +static void +native_set_event_handler(struct native_event_handler *event_handler) +{ + fbdev_event_handler = event_handler; +} + static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler, - void *user_data) +native_create_display(void *dpy, boolean use_sw, void *user_data) { struct native_display *ndpy; int fd; @@ -476,7 +483,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler, if (fd < 0) return NULL; - ndpy = fbdev_display_create(fd, event_handler, user_data); + ndpy = fbdev_display_create(fd, fbdev_event_handler, user_data); if (!ndpy) close(fd); @@ -485,6 +492,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler, static const struct native_platform fbdev_platform = { "FBDEV", /* name */ + native_set_event_handler, native_create_display }; diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c index 2d0450604c6..3cc4aefa937 100644 --- a/src/gallium/state_trackers/egl/gdi/native_gdi.c +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c @@ -406,15 +406,23 @@ gdi_create_display(HDC hDC, struct native_event_handler *event_handler, return &gdpy->base; } +static struct native_event_handler *gdi_event_handler; + +static void +native_set_event_handler(struct native_event_handler *event_handler) +{ + gdi_event_handler = event_handler; +} + static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler, - void *user_data) +native_create_display(void *dpy, boolean use_sw, void *user_data) { - return gdi_create_display((HDC) dpy, event_handler, user_data); + return gdi_create_display((HDC) dpy, gdi_event_handler, user_data); } static const struct native_platform gdi_platform = { "GDI", /* name */ + native_set_event_handler, native_create_display }; diff --git a/src/gallium/state_trackers/egl/x11/native_x11.c b/src/gallium/state_trackers/egl/x11/native_x11.c index 37c8b01541f..a0bcad4c734 100644 --- a/src/gallium/state_trackers/egl/x11/native_x11.c +++ b/src/gallium/state_trackers/egl/x11/native_x11.c @@ -30,25 +30,30 @@ #include "native_x11.h" +static struct native_event_handler *x11_event_handler; + +static void +native_set_event_handler(struct native_event_handler *event_handler) +{ + x11_event_handler = event_handler; +} + static struct native_display * -native_create_display(void *dpy, struct native_event_handler *event_handler, - void *user_data) +native_create_display(void *dpy, boolean use_sw, void *user_data) { struct native_display *ndpy = NULL; boolean force_sw; force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE); - if (!force_sw) { - ndpy = x11_create_dri2_display((Display *) dpy, - event_handler, user_data); - } - - if (!ndpy) { - EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING; - _eglLog(level, "use software fallback"); + if (force_sw || use_sw) { + _eglLog(_EGL_INFO, "use software fallback"); ndpy = x11_create_ximage_display((Display *) dpy, - event_handler, user_data); + x11_event_handler, user_data); + } + else { + ndpy = x11_create_dri2_display((Display *) dpy, + x11_event_handler, user_data); } return ndpy; @@ -56,6 +61,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler, static const struct native_platform x11_platform = { "X11", /* name */ + native_set_event_handler, native_create_display }; diff --git a/src/gallium/targets/egl-gdi/SConscript b/src/gallium/targets/egl-gdi/SConscript deleted file mode 100644 index d52eeb70fd5..00000000000 --- a/src/gallium/targets/egl-gdi/SConscript +++ /dev/null @@ -1,55 +0,0 @@ -####################################################################### -# SConscript for egl-gdi target - -Import('*') - -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-static/SConscript b/src/gallium/targets/egl-static/SConscript new file mode 100644 index 00000000000..381ef4e862d --- /dev/null +++ b/src/gallium/targets/egl-static/SConscript @@ -0,0 +1,127 @@ +####################################################################### +# SConscript for egl-static target + +Import('*') + +env = env.Clone() + +env.Append(CPPPATH = [ + '#/include', + '#/src/egl/main', + '#/src/gallium/auxiliary', + '#/src/gallium/drivers', + '#/src/gallium/include', + '#/src/gallium/winsys', + '#/src/gallium/state_trackers/egl', + '#/src/gallium/state_trackers/vega', + '#/src/mesa', +]) + +env.Append(CPPDEFINES = [ + 'GALLIUM_SOFTPIPE', + 'GALLIUM_RBUG', + 'GALLIUM_TRACE', + 'GALLIUM_GALAHAD', + '_EGL_MAIN=_eglBuiltInDriverGALLIUM', +]) + +env.Prepend(LIBS = [ + softpipe, + rbug, + trace, + galahad, + gallium, + egl, + st_egl, +]) + +if env['llvm']: + env.Append(CPPDEFINES = ['GALLIUM_LLVMPIPE']) + env.Prepend(LIBS = [llvmpipe]) + +sources = [ + 'egl.c', + 'egl_pipe.c', + 'egl_st.c', +] + +if env['platform'] == 'windows': + sources.append('#src/egl/main/egl.def') + + env.Append(LIBS = [ + 'gdi32', + 'user32', + 'kernel32', + 'ws2_32', + ]) + + env.Prepend(LIBS = [ + ws_gdi, + ]) +else: + # OpenGL + env.Append(CPPDEFINES = ['FEATURE_GL=1']) + env.Prepend(LIBS = ['GL', 'talloc', glsl, mesa]) + +# OpenVG +if True: + env.Append(CPPDEFINES = ['FEATURE_VG=1']) + env.Prepend(LIBPATH = [openvg.dir]) + # manually add LIBPREFIX on windows + openvg_name = 'OpenVG' if env['platform'] != 'windows' else 'libOpenVG' + env.Prepend(LIBS = [openvg_name, st_vega]) + +if env['x11']: + env.Prepend(LIBS = [ + ws_xlib, + env['X11_LIBS'], + ]) + +if env['dri']: + env.ParseConfig('pkg-config --cflags --libs xfixes') + +# pipe drivers +if env['drm']: + env.ParseConfig('pkg-config --cflags --libs libdrm') + + if env['drm_intel']: + env.ParseConfig('pkg-config --cflags --libs libdrm_intel') + env.Append(CPPDEFINES = ['_EGL_PIPE_I915', '_EGL_PIPE_I965']) + env.Prepend(LIBS = [ + i915drm, + i915, + i965drm, + i965, + ws_wrapper, + ]) + + if env['drm_radeon']: + env.ParseConfig('pkg-config --cflags --libs libdrm_radeon') + env.Append(CPPDEFINES = ['_EGL_PIPE_R300', '_EGL_PIPE_R600']) + env.Prepend(LIBS = [ + radeonwinsys, + r300, + r600winsys, + r600, + ]) + + env.Append(CPPDEFINES = ['_EGL_PIPE_VMWGFX']) + env.Prepend(LIBS = [ + svgadrm, + svga, + ]) + +# libEGL.dll +env['LIBPREFIX'] = 'lib' +env['SHLIBPREFIX'] = 'lib' + +egl_gallium = env.SharedLibrary( + target ='EGL', + source = sources, +) + +env.Depends(egl_gallium, [openvg]) + +egl_gallium = env.InstallSharedLibrary(egl_gallium, version=(1, 4, 0)) + +env.Alias('egl-gallium', egl_gallium) diff --git a/src/gallium/targets/egl-gdi/egl-static.c b/src/gallium/targets/egl-static/egl.c index da6e5ce3396..e617ff50208 100644 --- a/src/gallium/targets/egl-gdi/egl-static.c +++ b/src/gallium/targets/egl-static/egl.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 7.9 + * Version: 7.10 * - * Copyright (C) 2010 LunarG Inc. + * Copyright (C) 2010-2011 LunarG Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -27,41 +27,29 @@ */ #include "common/egl_g3d_loader.h" -#include "state_tracker/st_gl_api.h" -#include "vg_api.h" -#include "target-helpers/inline_sw_helper.h" -#include "target-helpers/inline_debug_helper.h" #include "egldriver.h" -static struct st_api *stapis[ST_API_COUNT]; +#include "egl_pipe.h" +#include "egl_st.h" + +static struct egl_g3d_loader egl_g3d_loader; + +static struct st_module { + boolean initialized; + struct st_api *stapi; +} st_modules[ST_API_COUNT]; static struct st_api * get_st_api(enum st_api_type api) { - struct st_api *stapi; + struct st_module *stmod = &st_modules[api]; - stapi = stapis[api]; - if (stapi) - return stapi; - - switch (api) { -#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 - case ST_API_OPENGL: - stapi = st_gl_api_create(); - break; -#endif -#if FEATURE_VG - case ST_API_OPENVG: - stapi = (struct st_api *) vg_api_get(); - break; -#endif - default: - break; + if (!stmod->initialized) { + stmod->stapi = egl_st_create_api(api); + stmod->initialized = TRUE; } - stapis[api] = stapi; - - return stapi; + return stmod->stapi; } static struct st_api * @@ -73,71 +61,69 @@ guess_gl_api(enum st_profile_type profile) static struct pipe_screen * create_drm_screen(const char *name, int fd) { - return NULL; + return egl_pipe_create_drm_screen(name, fd); } static struct pipe_screen * create_sw_screen(struct sw_winsys *ws) { - struct pipe_screen *screen; - - screen = sw_screen_create(ws); - if (screen) - screen = debug_screen_wrap(screen); - - return screen; + return egl_pipe_create_swrast_screen(ws); } -static void -init_loader(struct egl_g3d_loader *loader) +static const struct egl_g3d_loader * +loader_init(void) { -#if FEATURE_GL - loader->profile_masks[ST_API_OPENGL] |= ST_PROFILE_DEFAULT_MASK; -#endif -#if FEATURE_ES1 - loader->profile_masks[ST_API_OPENGL] |= ST_PROFILE_OPENGL_ES1_MASK; -#endif -#if FEATURE_ES2 - loader->profile_masks[ST_API_OPENGL] |= ST_PROFILE_OPENGL_ES2_MASK; -#endif -#if FEATURE_VG - loader->profile_masks[ST_API_OPENVG] |= ST_PROFILE_DEFAULT_MASK; -#endif - - loader->get_st_api = get_st_api; - loader->guess_gl_api = guess_gl_api; - loader->create_drm_screen = create_drm_screen; - loader->create_sw_screen = create_sw_screen; + int i; + + for (i = 0; i < ST_API_COUNT; i++) + egl_g3d_loader.profile_masks[i] = egl_st_get_profile_mask(i); + + egl_g3d_loader.get_st_api = get_st_api; + egl_g3d_loader.guess_gl_api = guess_gl_api; + egl_g3d_loader.create_drm_screen = create_drm_screen; + egl_g3d_loader.create_sw_screen = create_sw_screen; + + return &egl_g3d_loader; } static void -egl_g3d_unload(_EGLDriver *drv) +loader_fini(void) { int i; - egl_g3d_destroy_driver(drv); - for (i = 0; i < ST_API_COUNT; i++) { - if (stapis[i]) { - stapis[i]->destroy(stapis[i]); - stapis[i] = NULL; + struct st_module *stmod = &st_modules[i]; + + if (stmod->stapi) { + stmod->stapi->destroy(stmod->stapi); + stmod->stapi = NULL; } + stmod->initialized = FALSE; } } -static struct egl_g3d_loader loader; +static void +egl_g3d_unload(_EGLDriver *drv) +{ + egl_g3d_destroy_driver(drv); + loader_fini(); +} _EGLDriver * -_eglMain(const char *args) +_EGL_MAIN(const char *args) { + const struct egl_g3d_loader *loader; _EGLDriver *drv; - init_loader(&loader); - drv = egl_g3d_create_driver(&loader); - if (drv) { - drv->Name = "Gallium"; - drv->Unload = egl_g3d_unload; + loader = loader_init(); + drv = egl_g3d_create_driver(loader); + if (!drv) { + loader_fini(); + return NULL; } + drv->Name = "Gallium"; + drv->Unload = egl_g3d_unload; + return drv; } diff --git a/src/gallium/targets/egl-static/egl_pipe.c b/src/gallium/targets/egl-static/egl_pipe.c new file mode 100644 index 00000000000..a33d419e0aa --- /dev/null +++ b/src/gallium/targets/egl-static/egl_pipe.c @@ -0,0 +1,215 @@ +/* + * Mesa 3-D graphics library + * Version: 7.10 + * + * Copyright (C) 2011 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]> + */ +#include "target-helpers/inline_debug_helper.h" +#include "target-helpers/inline_sw_helper.h" +#include "egl_pipe.h" + +/* for i915 */ +#include "i915/drm/i915_drm_public.h" +#include "i915/i915_public.h" +/* for i965 */ +#include "target-helpers/inline_wrapper_sw_helper.h" +#include "i965/drm/i965_drm_public.h" +#include "i965/brw_public.h" +/* for nouveau */ +#include "nouveau/drm/nouveau_drm_public.h" +/* for r300 */ +#include "radeon/drm/radeon_drm_public.h" +#include "r300/r300_public.h" +/* for r600 */ +#include "r600/drm/r600_drm_public.h" +#include "r600/r600_public.h" +/* for vmwgfx */ +#include "svga/drm/svga_drm_public.h" +#include "svga/svga_public.h" + +static struct pipe_screen * +pipe_i915_create_screen(int fd) +{ +#if _EGL_PIPE_I915 + struct i915_winsys *iws; + struct pipe_screen *screen; + + iws = i915_drm_winsys_create(fd); + if (!iws) + return NULL; + + screen = i915_screen_create(iws); + if (!screen) + return NULL; + + screen = debug_screen_wrap(screen); + + return screen; +#else + return NULL; +#endif +} + +static struct pipe_screen * +pipe_i965_create_screen(int fd) +{ +#if _EGL_PIPE_I965 + struct brw_winsys_screen *bws; + struct pipe_screen *screen; + + bws = i965_drm_winsys_screen_create(fd); + if (!bws) + return NULL; + + screen = brw_screen_create(bws); + if (!screen) + return NULL; + + screen = sw_screen_wrap(screen); + + screen = debug_screen_wrap(screen); + + return screen; +#else + return NULL; +#endif +} + +static struct pipe_screen * +pipe_nouveau_create_screen(int fd) +{ +#if _EGL_PIPE_NOUVEAU + struct pipe_screen *screen; + + screen = nouveau_drm_screen_create(fd); + if (!screen) + return NULL; + + screen = debug_screen_wrap(screen); + + return screen; +#else + return NULL; +#endif +} + +static struct pipe_screen * +pipe_r300_create_screen(int fd) +{ +#if _EGL_PIPE_R300 + struct r300_winsys_screen *sws; + struct pipe_screen *screen; + + sws = r300_drm_winsys_screen_create(fd); + if (!sws) + return NULL; + + screen = r300_screen_create(sws); + if (!screen) + return NULL; + + screen = debug_screen_wrap(screen); + + return screen; +#else + return NULL; +#endif +} + +static struct pipe_screen * +pipe_r600_create_screen(int fd) +{ +#if _EGL_PIPE_R600 + struct radeon *rw; + struct pipe_screen *screen; + + rw = r600_drm_winsys_create(fd); + if (!rw) + return NULL; + + screen = r600_screen_create(rw); + if (!screen) + return NULL; + + screen = debug_screen_wrap(screen); + + return screen; +#else + return NULL; +#endif +} + +static struct pipe_screen * +pipe_vmwgfx_create_screen(int fd) +{ +#if _EGL_PIPE_VMWGFX + struct svga_winsys_screen *sws; + struct pipe_screen *screen; + + sws = svga_drm_winsys_screen_create(fd); + if (!sws) + return NULL; + + screen = svga_screen_create(sws); + if (!screen) + return NULL; + + screen = debug_screen_wrap(screen); + + return screen; +#else + return NULL; +#endif +} + +struct pipe_screen * +egl_pipe_create_drm_screen(const char *name, int fd) +{ + if (strcmp(name, "i915") == 0) + return pipe_i915_create_screen(fd); + else if (strcmp(name, "i965") == 0) + return pipe_i965_create_screen(fd); + else if (strcmp(name, "nouveau") == 0) + return pipe_nouveau_create_screen(fd); + else if (strcmp(name, "r300") == 0) + return pipe_r300_create_screen(fd); + else if (strcmp(name, "r600") == 0) + return pipe_r600_create_screen(fd); + else if (strcmp(name, "vmwgfx") == 0) + return pipe_vmwgfx_create_screen(fd); + else + return NULL; +} + +struct pipe_screen * +egl_pipe_create_swrast_screen(struct sw_winsys *ws) +{ + struct pipe_screen *screen; + + screen = sw_screen_create(ws); + if (screen) + screen = debug_screen_wrap(screen); + + return screen; +} diff --git a/src/gallium/targets/egl-static/egl_pipe.h b/src/gallium/targets/egl-static/egl_pipe.h new file mode 100644 index 00000000000..569b2d067c4 --- /dev/null +++ b/src/gallium/targets/egl-static/egl_pipe.h @@ -0,0 +1,40 @@ +/* + * Mesa 3-D graphics library + * Version: 7.10 + * + * Copyright (C) 2011 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 _EGL_PIPE_H_ +#define _EGL_PIPE_H_ + +struct pipe_screen; +struct sw_winsys; + +struct pipe_screen * +egl_pipe_create_drm_screen(const char *name, int fd); + +struct pipe_screen * +egl_pipe_create_swrast_screen(struct sw_winsys *ws); + +#endif /* _EGL_PIPE_H_ */ diff --git a/src/gallium/targets/egl-static/egl_st.c b/src/gallium/targets/egl-static/egl_st.c new file mode 100644 index 00000000000..3db52621def --- /dev/null +++ b/src/gallium/targets/egl-static/egl_st.c @@ -0,0 +1,105 @@ +/* + * Mesa 3-D graphics library + * Version: 7.10 + * + * Copyright (C) 2011 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]> + */ +#include "util/u_debug.h" +#include "state_tracker/st_api.h" +#include "egl_st.h" + +/* for st/mesa */ +#include "state_tracker/st_gl_api.h" +/* for st/vega */ +#include "vg_api.h" + +static struct st_api * +st_GL_create_api(void) +{ +#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2 + return st_gl_api_create(); +#else + return NULL; +#endif +} + +static struct st_api * +st_OpenVG_create_api(void) +{ +#if FEATURE_VG + return (struct st_api *) vg_api_get(); +#else + return NULL; +#endif +} + +struct st_api * +egl_st_create_api(enum st_api_type api) +{ + struct st_api *stapi; + + switch (api) { + case ST_API_OPENGL: + stapi = st_GL_create_api(); + break; + case ST_API_OPENVG: + stapi = st_OpenVG_create_api(); + break; + default: + assert(!"Unknown API Type\n"); + stapi = NULL; + break; + } + + return stapi; +} + +uint +egl_st_get_profile_mask(enum st_api_type api) +{ + uint mask = 0x0; + + switch (api) { + case ST_API_OPENGL: +#if FEATURE_GL + mask |= ST_PROFILE_DEFAULT_MASK; +#endif +#if FEATURE_ES1 + mask |= ST_PROFILE_OPENGL_ES1_MASK; +#endif +#if FEATURE_ES2 + mask |= ST_PROFILE_OPENGL_ES2_MASK; +#endif + break; + case ST_API_OPENVG: +#if FEATURE_VG + mask |= ST_PROFILE_DEFAULT_MASK; +#endif + break; + default: + break; + } + + return mask; +} diff --git a/src/gallium/targets/egl-static/egl_st.h b/src/gallium/targets/egl-static/egl_st.h new file mode 100644 index 00000000000..ba82faf0b0e --- /dev/null +++ b/src/gallium/targets/egl-static/egl_st.h @@ -0,0 +1,40 @@ +/* + * Mesa 3-D graphics library + * Version: 7.10 + * + * Copyright (C) 2011 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 _EGL_ST_H_ +#define _EGL_ST_H_ + +#include "pipe/p_compiler.h" +#include "state_tracker/st_api.h" + +struct st_api * +egl_st_create_api(enum st_api_type api); + +uint +egl_st_get_profile_mask(enum st_api_type api); + +#endif /* _EGL_ST_H_ */ diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index 3e36000a30e..017c1952141 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -74,7 +74,8 @@ i965_CPPFLAGS := i965_SYS := -ldrm_intel i965_LIBS := \ $(TOP)/src/gallium/winsys/i965/drm/libi965drm.a \ - $(TOP)/src/gallium/drivers/i965/libi965.a + $(TOP)/src/gallium/drivers/i965/libi965.a \ + $(TOP)/src/gallium/winsys/sw/wrapper/libwsw.a # nouveau pipe driver nouveau_CPPFLAGS := diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index ee262c3ea52..69b0a1dcd72 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -41,8 +41,6 @@ #define RADEON_INFO_TILING_CONFIG 0x6 #endif -static struct radeon *radeon_new(int fd, unsigned device); - enum radeon_family r600_get_family(struct radeon *r600) { return r600->family; |