diff options
Diffstat (limited to 'src/mesa')
39 files changed, 1237 insertions, 224 deletions
diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c index de4500a39b..738b1ae97f 100644 --- a/src/mesa/drivers/dri/common/xmlconfig.c +++ b/src/mesa/drivers/dri/common/xmlconfig.c @@ -65,7 +65,7 @@ extern char *program_invocation_name, *program_invocation_short_name; #endif #if !defined(GET_PROGRAM_NAME) -# if defined(OpenBSD) || defined(NetBSD) || defined(__UCLIBC__) +# if defined(__OpenBSD__) || defined(NetBSD) || defined(__UCLIBC__) /* This is a hack. It's said to work on OpenBSD, NetBSD and GNU. * Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's * used as a last resort, if there is no documented facility available. */ diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile index c8acd3a333..e432afc3d4 100644 --- a/src/mesa/drivers/dri/r300/compiler/Makefile +++ b/src/mesa/drivers/dri/r300/compiler/Makefile @@ -8,6 +8,7 @@ LIBNAME = r300compiler C_SOURCES = \ radeon_code.c \ radeon_compiler.c \ + radeon_emulate_branches.c \ radeon_program.c \ radeon_program_print.c \ radeon_opcodes.c \ diff --git a/src/mesa/drivers/dri/r300/compiler/memory_pool.h b/src/mesa/drivers/dri/r300/compiler/memory_pool.h index ce23c319ad..42344d0e3b 100644 --- a/src/mesa/drivers/dri/r300/compiler/memory_pool.h +++ b/src/mesa/drivers/dri/r300/compiler/memory_pool.h @@ -46,4 +46,35 @@ void memory_pool_init(struct memory_pool * pool); void memory_pool_destroy(struct memory_pool * pool); void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes); + +/** + * Generic helper for growing an array that has separate size/count + * and reserved counters to accomodate up to num new element. + * + * type * Array; + * unsigned int Size; + * unsigned int Reserved; + * + * memory_pool_array_reserve(pool, type, Array, Size, Reserved, k); + * assert(Size + k < Reserved); + * + * \note Size is not changed by this macro. + * + * \warning Array, Size, Reserved have to be lvalues and may be evaluated + * several times. + */ +#define memory_pool_array_reserve(pool, type, array, size, reserved, num) do { \ + unsigned int _num = (num); \ + if ((size) + _num > (reserved)) { \ + unsigned int newreserve = (reserved) * 2; \ + type * newarray; \ + if (newreserve < _num) \ + newreserve = 4 * _num; /* arbitrary heuristic */ \ + newarray = memory_pool_malloc((pool), newreserve * sizeof(type)); \ + memcpy(newarray, (array), (size) * sizeof(type)); \ + (array) = newarray; \ + (reserved) = newreserve; \ + } \ +} while(0) + #endif /* MEMORY_POOL_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c index 5fe10dbfe8..25bf373b6f 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c @@ -25,6 +25,7 @@ #include <stdio.h> #include "radeon_dataflow.h" +#include "radeon_emulate_branches.h" #include "radeon_program_alu.h" #include "radeon_program_tex.h" #include "r300_fragprog.h" @@ -85,10 +86,27 @@ static void rewrite_depth_out(struct r300_fragment_program_compiler * c) } } +static void debug_program_log(struct r300_fragment_program_compiler* c, const char * where) +{ + if (c->Base.Debug) { + fprintf(stderr, "Fragment Program: %s\n", where); + rc_print_program(&c->Base.Program); + } +} + void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) { rewrite_depth_out(c); + debug_program_log(c, "before compilation"); + + /* XXX Ideally this should be done only for r3xx, but since + * we don't have branching support for r5xx, we use the emulation + * on all chipsets. */ + rc_emulate_branches(&c->Base); + + debug_program_log(c, "after emulate branches"); + if (c->is_r500) { struct radeon_program_transformation transformations[] = { { &r500_transform_IF, 0 }, @@ -98,6 +116,8 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) }; radeonLocalTransform(&c->Base, 4, transformations); + debug_program_log(c, "after native rewrite part 1"); + c->Base.SwizzleCaps = &r500_swizzle_caps; } else { struct radeon_program_transformation transformations[] = { @@ -106,6 +126,8 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) }; radeonLocalTransform(&c->Base, 2, transformations); + debug_program_log(c, "after native rewrite part 1"); + c->Base.SwizzleCaps = &r300_swizzle_caps; } @@ -119,62 +141,41 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c) common_transformations[0].function = &radeonTransformALU; radeonLocalTransform(&c->Base, 1, common_transformations); - if (c->Base.Debug) { - fprintf(stderr, "Fragment Program: After native rewrite:\n"); - rc_print_program(&c->Base.Program); - fflush(stderr); - } + if (c->Base.Error) + return; + + debug_program_log(c, "after native rewrite part 2"); rc_dataflow_deadcode(&c->Base, &dataflow_outputs_mark_use, c); if (c->Base.Error) return; - if (c->Base.Debug) { - fprintf(stderr, "Fragment Program: After deadcode:\n"); - rc_print_program(&c->Base.Program); - fflush(stderr); - } + debug_program_log(c, "after deadcode"); rc_dataflow_swizzles(&c->Base); if (c->Base.Error) return; - if (c->Base.Debug) { - fprintf(stderr, "Compiler: after dataflow passes:\n"); - rc_print_program(&c->Base.Program); - fflush(stderr); - } + debug_program_log(c, "after dataflow passes"); rc_pair_translate(c); if (c->Base.Error) return; - if (c->Base.Debug) { - fprintf(stderr, "Compiler: after pair translate:\n"); - rc_print_program(&c->Base.Program); - fflush(stderr); - } + debug_program_log(c, "after pair translate"); rc_pair_schedule(c); if (c->Base.Error) return; - if (c->Base.Debug) { - fprintf(stderr, "Compiler: after pair scheduling:\n"); - rc_print_program(&c->Base.Program); - fflush(stderr); - } + debug_program_log(c, "after pair scheduling"); rc_pair_regalloc(c, c->max_temp_regs); if (c->Base.Error) return; - if (c->Base.Debug) { - fprintf(stderr, "Compiler: after pair register allocation:\n"); - rc_print_program(&c->Base.Program); - fflush(stderr); - } + debug_program_log(c, "after register allocation"); if (c->is_r500) { r500BuildFragmentProgramHwCode(c); diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c index 1b2cb8dde7..4a0b6c02ef 100644 --- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c +++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c @@ -29,7 +29,7 @@ #include "radeon_dataflow.h" #include "radeon_program_alu.h" #include "radeon_swizzle.h" - +#include "radeon_emulate_branches.h" /* * Take an already-setup and valid source then swizzle it appropriately to @@ -566,6 +566,14 @@ static int swizzle_is_native(rc_opcode opcode, struct rc_src_register reg) return 1; } +static void debug_program_log(struct r300_vertex_program_compiler* c, const char * where) +{ + if (c->Base.Debug) { + fprintf(stderr, "Vertex Program: %s\n", where); + rc_print_program(&c->Base.Program); + } +} + static struct rc_swizzle_caps r300_vertprog_swizzle_caps = { .IsNative = &swizzle_is_native, @@ -579,6 +587,15 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler) addArtificialOutputs(compiler); + debug_program_log(compiler, "before compilation"); + + /* XXX Ideally this should be done only for r3xx, but since + * we don't have branching support for r5xx, we use the emulation + * on all chipsets. */ + rc_emulate_branches(&compiler->Base); + + debug_program_log(compiler, "after emulate branches"); + { struct radeon_program_transformation transformations[] = { { &r300_transform_vertex_alu, 0 }, @@ -586,11 +603,7 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler) radeonLocalTransform(&compiler->Base, 1, transformations); } - if (compiler->Base.Debug) { - fprintf(stderr, "Vertex program after native rewrite:\n"); - rc_print_program(&compiler->Base.Program); - fflush(stderr); - } + debug_program_log(compiler, "after native rewrite"); { /* Note: This pass has to be done seperately from ALU rewrite, @@ -603,29 +616,17 @@ void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler) radeonLocalTransform(&compiler->Base, 1, transformations); } - if (compiler->Base.Debug) { - fprintf(stderr, "Vertex program after source conflict resolve:\n"); - rc_print_program(&compiler->Base.Program); - fflush(stderr); - } + debug_program_log(compiler, "after source conflict resolve"); rc_dataflow_deadcode(&compiler->Base, &dataflow_outputs_mark_used, compiler); - if (compiler->Base.Debug) { - fprintf(stderr, "Vertex program after deadcode:\n"); - rc_print_program(&compiler->Base.Program); - fflush(stderr); - } + debug_program_log(compiler, "after deadcode"); rc_dataflow_swizzles(&compiler->Base); allocate_temporary_registers(compiler); - if (compiler->Base.Debug) { - fprintf(stderr, "Vertex program after dataflow:\n"); - rc_print_program(&compiler->Base.Program); - fflush(stderr); - } + debug_program_log(compiler, "after dataflow"); translate_vertex_program(compiler); diff --git a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c index b6dfe28def..10c5e2349e 100644 --- a/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c +++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c @@ -348,21 +348,6 @@ static int emit_tex(struct r300_fragment_program_compiler *c, struct rc_sub_inst return 1; } -static void grow_branches(struct emit_state * s) -{ - unsigned int newreserved = s->BranchesReserved * 2; - struct branch_info * newbranches; - - if (!newreserved) - newreserved = 4; - - newbranches = memory_pool_malloc(&s->C->Pool, newreserved*sizeof(struct branch_info)); - memcpy(newbranches, s->Branches, s->CurrentBranchDepth*sizeof(struct branch_info)); - - s->Branches = newbranches; - s->BranchesReserved = newreserved; -} - static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst) { if (s->Code->inst_end >= 511) { @@ -380,8 +365,8 @@ static void emit_flowcontrol(struct emit_state * s, struct rc_instruction * inst return; } - if (s->CurrentBranchDepth >= s->BranchesReserved) - grow_branches(s); + memory_pool_array_reserve(&s->C->Pool, struct branch_info, + s->Branches, s->CurrentBranchDepth, s->BranchesReserved, 1); struct branch_info * branch = &s->Branches[s->CurrentBranchDepth++]; branch->If = newip; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c index cce9166e64..16e2f3a218 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c @@ -160,3 +160,92 @@ void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * writes_pair(inst, cb, userdata); } } + + +static void remap_normal_instruction(struct rc_instruction * fullinst, + rc_remap_register_fn cb, void * userdata) +{ + struct rc_sub_instruction * inst = &fullinst->U.I; + const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); + + if (opcode->HasDstReg) { + rc_register_file file = inst->DstReg.File; + unsigned int index = inst->DstReg.Index; + + cb(userdata, fullinst, &file, &index); + + inst->DstReg.File = file; + inst->DstReg.Index = index; + } + + for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { + rc_register_file file = inst->SrcReg[src].File; + unsigned int index = inst->SrcReg[src].Index; + + cb(userdata, fullinst, &file, &index); + + inst->SrcReg[src].File = file; + inst->SrcReg[src].Index = index; + } +} + +static void remap_pair_instruction(struct rc_instruction * fullinst, + rc_remap_register_fn cb, void * userdata) +{ + struct rc_pair_instruction * inst = &fullinst->U.P; + + if (inst->RGB.WriteMask) { + rc_register_file file = RC_FILE_TEMPORARY; + unsigned int index = inst->RGB.DestIndex; + + cb(userdata, fullinst, &file, &index); + + inst->RGB.DestIndex = index; + } + + if (inst->Alpha.WriteMask) { + rc_register_file file = RC_FILE_TEMPORARY; + unsigned int index = inst->Alpha.DestIndex; + + cb(userdata, fullinst, &file, &index); + + inst->Alpha.DestIndex = index; + } + + for(unsigned int src = 0; src < 3; ++src) { + if (inst->RGB.Src[src].Used) { + rc_register_file file = inst->RGB.Src[src].File; + unsigned int index = inst->RGB.Src[src].Index; + + cb(userdata, fullinst, &file, &index); + + inst->RGB.Src[src].File = file; + inst->RGB.Src[src].Index = index; + } + + if (inst->Alpha.Src[src].Used) { + rc_register_file file = inst->Alpha.Src[src].File; + unsigned int index = inst->Alpha.Src[src].Index; + + cb(userdata, fullinst, &file, &index); + + inst->Alpha.Src[src].File = file; + inst->Alpha.Src[src].Index = index; + } + } +} + + +/** + * Remap all register accesses according to the given function. + * That is, call the function \p cb for each referenced register (both read and written) + * and update the given instruction \p inst accordingly + * if it modifies its \ref pfile and \ref pindex contents. + */ +void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata) +{ + if (inst->Type == RC_INSTRUCTION_NORMAL) + remap_normal_instruction(inst, cb, userdata); + else + remap_pair_instruction(inst, cb, userdata); +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h index 5aa4cb64f3..62cda20eea 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h @@ -36,13 +36,17 @@ struct rc_swizzle_caps; /** - * Help analyze the register accesses of instructions. + * Help analyze and modify the register accesses of instructions. */ /*@{*/ typedef void (*rc_read_write_fn)(void * userdata, struct rc_instruction * inst, rc_register_file file, unsigned int index, unsigned int chan); void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata); void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata); + +typedef void (*rc_remap_register_fn)(void * userdata, struct rc_instruction * inst, + rc_register_file * pfile, unsigned int * pindex); +void rc_remap_registers(struct rc_instruction * inst, rc_remap_register_fn cb, void * userdata); /*@}*/ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c index f3734852cc..e3c2c83c0c 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow_deadcode.c @@ -80,19 +80,8 @@ static void or_updatemasks( static void push_branch(struct deadcode_state * s) { - if (s->BranchStackSize >= s->BranchStackReserved) { - unsigned int new_reserve = 2 * s->BranchStackReserved; - struct branchinfo * new_stack; - - if (!new_reserve) - new_reserve = 4; - - new_stack = memory_pool_malloc(&s->C->Pool, new_reserve * sizeof(struct branchinfo)); - memcpy(new_stack, s->BranchStack, s->BranchStackSize * sizeof(struct branchinfo)); - - s->BranchStack = new_stack; - s->BranchStackReserved = new_reserve; - } + memory_pool_array_reserve(&s->C->Pool, struct branchinfo, s->BranchStack, + s->BranchStackSize, s->BranchStackReserved, 1); struct branchinfo * branch = &s->BranchStack[s->BranchStackSize++]; branch->HaveElse = 0; diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c new file mode 100644 index 0000000000..d889612f4f --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c @@ -0,0 +1,331 @@ +/* + * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> + * + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#include "radeon_emulate_branches.h" + +#include <stdio.h> + +#include "radeon_compiler.h" +#include "radeon_dataflow.h" + +#define VERBOSE 0 + +#define DBG(...) do { if (VERBOSE) fprintf(stderr, __VA_ARGS__); } while(0) + + +struct proxy_info { + unsigned int Proxied:1; + unsigned int Index:RC_REGISTER_INDEX_BITS; +}; + +struct register_proxies { + struct proxy_info Temporary[RC_REGISTER_MAX_INDEX]; +}; + +struct branch_info { + struct rc_instruction * If; + struct rc_instruction * Else; +}; + +struct emulate_branch_state { + struct radeon_compiler * C; + + struct branch_info * Branches; + unsigned int BranchCount; + unsigned int BranchReserved; +}; + + +static void handle_if(struct emulate_branch_state * s, struct rc_instruction * inst) +{ + memory_pool_array_reserve(&s->C->Pool, struct branch_info, + s->Branches, s->BranchCount, s->BranchReserved, 1); + + DBG("%s\n", __FUNCTION__); + + struct branch_info * branch = &s->Branches[s->BranchCount++]; + memset(branch, 0, sizeof(struct branch_info)); + branch->If = inst; + + /* Make a safety copy of the decision register, because we will need + * it at ENDIF time and it might be overwritten in both branches. */ + struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, inst->Prev); + inst_mov->U.I.Opcode = RC_OPCODE_MOV; + inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; + inst_mov->U.I.DstReg.Index = rc_find_free_temporary(s->C); + inst_mov->U.I.DstReg.WriteMask = RC_MASK_X; + inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; + + inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; + inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index; + inst->U.I.SrcReg[0].Swizzle = 0; + inst->U.I.SrcReg[0].Abs = 0; + inst->U.I.SrcReg[0].Negate = 0; +} + +static void handle_else(struct emulate_branch_state * s, struct rc_instruction * inst) +{ + if (!s->BranchCount) { + rc_error(s->C, "Encountered ELSE outside of branches"); + return; + } + + DBG("%s\n", __FUNCTION__); + + struct branch_info * branch = &s->Branches[s->BranchCount - 1]; + branch->Else = inst; +} + + +struct state_and_proxies { + struct emulate_branch_state * S; + struct register_proxies * Proxies; +}; + +static struct proxy_info * get_proxy_info(struct state_and_proxies * sap, + rc_register_file file, unsigned int index) +{ + if (file == RC_FILE_TEMPORARY) { + return &sap->Proxies->Temporary[index]; + } else { + return 0; + } +} + +static void scan_write(void * userdata, struct rc_instruction * inst, + rc_register_file file, unsigned int index, unsigned int comp) +{ + struct state_and_proxies * sap = userdata; + struct proxy_info * proxy = get_proxy_info(sap, file, index); + + if (proxy && !proxy->Proxied) { + proxy->Proxied = 1; + proxy->Index = rc_find_free_temporary(sap->S->C); + } +} + +static void remap_proxy_function(void * userdata, struct rc_instruction * inst, + rc_register_file * pfile, unsigned int * pindex) +{ + struct state_and_proxies * sap = userdata; + struct proxy_info * proxy = get_proxy_info(sap, *pfile, *pindex); + + if (proxy && proxy->Proxied) { + *pfile = RC_FILE_TEMPORARY; + *pindex = proxy->Index; + } +} + +/** + * Redirect all writes in the instruction range [begin, end) to proxy + * temporary registers. + */ +static void allocate_and_insert_proxies(struct emulate_branch_state * s, + struct register_proxies * proxies, + struct rc_instruction * begin, + struct rc_instruction * end) +{ + struct state_and_proxies sap; + + sap.S = s; + sap.Proxies = proxies; + + for(struct rc_instruction * inst = begin; inst != end; inst = inst->Next) { + rc_for_all_writes(inst, scan_write, &sap); + rc_remap_registers(inst, remap_proxy_function, &sap); + } + + for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) { + if (proxies->Temporary[index].Proxied) { + struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, begin->Prev); + inst_mov->U.I.Opcode = RC_OPCODE_MOV; + inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; + inst_mov->U.I.DstReg.Index = proxies->Temporary[index].Index; + inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZW; + inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; + inst_mov->U.I.SrcReg[0].Index = index; + } + } +} + + +static void inject_cmp(struct emulate_branch_state * s, + struct rc_instruction * inst_if, + struct rc_instruction * inst_endif, + rc_register_file file, unsigned int index, + struct proxy_info ifproxy, + struct proxy_info elseproxy) +{ + struct rc_instruction * inst_cmp = rc_insert_new_instruction(s->C, inst_endif); + inst_cmp->U.I.Opcode = RC_OPCODE_CMP; + inst_cmp->U.I.DstReg.File = file; + inst_cmp->U.I.DstReg.Index = index; + inst_cmp->U.I.DstReg.WriteMask = RC_MASK_XYZW; + inst_cmp->U.I.SrcReg[0] = inst_if->U.I.SrcReg[0]; + inst_cmp->U.I.SrcReg[0].Abs = 1; + inst_cmp->U.I.SrcReg[0].Negate = RC_MASK_XYZW; + inst_cmp->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; + inst_cmp->U.I.SrcReg[1].Index = ifproxy.Proxied ? ifproxy.Index : index; + inst_cmp->U.I.SrcReg[2].File = RC_FILE_TEMPORARY; + inst_cmp->U.I.SrcReg[2].Index = elseproxy.Proxied ? elseproxy.Index : index; +} + +static void handle_endif(struct emulate_branch_state * s, struct rc_instruction * inst) +{ + if (!s->BranchCount) { + rc_error(s->C, "Encountered ENDIF outside of branches"); + return; + } + + DBG("%s\n", __FUNCTION__); + + struct branch_info * branch = &s->Branches[s->BranchCount - 1]; + struct register_proxies IfProxies; + struct register_proxies ElseProxies; + + memset(&IfProxies, 0, sizeof(IfProxies)); + memset(&ElseProxies, 0, sizeof(ElseProxies)); + + allocate_and_insert_proxies(s, &IfProxies, branch->If->Next, branch->Else ? branch->Else : inst); + + if (branch->Else) + allocate_and_insert_proxies(s, &ElseProxies, branch->Else->Next, inst); + + /* Insert the CMP instructions at the end. */ + for(unsigned int index = 0; index < RC_REGISTER_MAX_INDEX; ++index) { + if (IfProxies.Temporary[index].Proxied || ElseProxies.Temporary[index].Proxied) { + inject_cmp(s, branch->If, inst, RC_FILE_TEMPORARY, index, + IfProxies.Temporary[index], ElseProxies.Temporary[index]); + } + } + + /* Remove all traces of the branch instructions */ + rc_remove_instruction(branch->If); + if (branch->Else) + rc_remove_instruction(branch->Else); + rc_remove_instruction(inst); + + s->BranchCount--; + + if (VERBOSE) { + DBG("Program after ENDIF handling:\n"); + rc_print_program(&s->C->Program); + } +} + + +struct remap_output_data { + unsigned int Output:RC_REGISTER_INDEX_BITS; + unsigned int Temporary:RC_REGISTER_INDEX_BITS; +}; + +static void remap_output_function(void * userdata, struct rc_instruction * inst, + rc_register_file * pfile, unsigned int * pindex) +{ + struct remap_output_data * data = userdata; + + if (*pfile == RC_FILE_OUTPUT && *pindex == data->Output) { + *pfile = RC_FILE_TEMPORARY; + *pindex = data->Temporary; + } +} + + +/** + * Output registers cannot be read from and so cannot be dealt with like + * temporary registers. + * + * We do the simplest thing: If an output registers is written within + * a branch, then *all* writes to this register are proxied to a + * temporary register, and a final MOV is appended to the end of + * the program. + */ +static void fix_output_writes(struct emulate_branch_state * s, struct rc_instruction * inst) +{ + if (!s->BranchCount) + return; + + const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); + + if (!opcode->HasDstReg) + return; + + if (inst->U.I.DstReg.File == RC_FILE_OUTPUT) { + struct remap_output_data remap; + + remap.Output = inst->U.I.DstReg.Index; + remap.Temporary = rc_find_free_temporary(s->C); + + for(struct rc_instruction * inst = s->C->Program.Instructions.Next; + inst != &s->C->Program.Instructions; + inst = inst->Next) { + rc_remap_registers(inst, &remap_output_function, &remap); + } + + struct rc_instruction * inst_mov = rc_insert_new_instruction(s->C, s->C->Program.Instructions.Prev); + inst_mov->U.I.Opcode = RC_OPCODE_MOV; + inst_mov->U.I.DstReg.File = RC_FILE_OUTPUT; + inst_mov->U.I.DstReg.Index = remap.Output; + inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZW; + inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; + inst_mov->U.I.SrcReg[0].Index = remap.Temporary; + } +} + +/** + * Remove branch instructions; instead, execute both branches + * on different register sets and choose between their results + * using CMP instructions in place of the original ENDIF. + */ +void rc_emulate_branches(struct radeon_compiler * c) +{ + struct emulate_branch_state s; + + memset(&s, 0, sizeof(s)); + s.C = c; + + /* Untypical loop because we may remove the current instruction */ + struct rc_instruction * ptr = c->Program.Instructions.Next; + while(ptr != &c->Program.Instructions) { + struct rc_instruction * inst = ptr; + ptr = ptr->Next; + + if (inst->Type == RC_INSTRUCTION_NORMAL) { + switch(inst->U.I.Opcode) { + case RC_OPCODE_IF: + handle_if(&s, inst); + break; + case RC_OPCODE_ELSE: + handle_else(&s, inst); + break; + case RC_OPCODE_ENDIF: + handle_endif(&s, inst); + break; + default: + fix_output_writes(&s, inst); + break; + } + } else { + rc_error(c, "%s: unhandled instruction type\n", __FUNCTION__); + } + } +} diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h new file mode 100644 index 0000000000..e07279f093 --- /dev/null +++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.h @@ -0,0 +1,30 @@ +/* + * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> + * + * 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 + * on the rights to use, copy, modify, merge, publish, distribute, sub + * license, and/or sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +#ifndef RADEON_EMULATE_BRANCHES_H +#define RADEON_EMULATE_BRANCHES_H + +struct radeon_compiler; + +void rc_emulate_branches(struct radeon_compiler * c); + +#endif /* RADEON_EMULATE_BRANCHES_H */ diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c index ffc91241ab..d593b3e81a 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.c @@ -60,6 +60,13 @@ struct rc_opcode_info rc_opcodes[MAX_RC_OPCODE] = { .HasDstReg = 1 }, { + .Opcode = RC_OPCODE_CEIL, + .Name = "CEIL", + .NumSrcRegs = 1, + .HasDstReg = 1, + .IsComponentwise = 1 + }, + { .Opcode = RC_OPCODE_CMP, .Name = "CMP", .NumSrcRegs = 3, diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h index 1c9b34df78..87a2e23084 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h +++ b/src/mesa/drivers/dri/r300/compiler/radeon_opcodes.h @@ -47,6 +47,9 @@ typedef enum { * dst.x = floor(src.x), where dst must be an address register */ RC_OPCODE_ARL, + /** vec4 instruction: dst.c = ceil(src0.c) */ + RC_OPCODE_CEIL, + /** vec4 instruction: dst.c = src0.c < 0.0 ? src1.c : src2.c */ RC_OPCODE_CMP, diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c index b2fe7f76b2..fdfee86701 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c @@ -196,9 +196,10 @@ static void compute_live_intervals(struct regalloc_state * s) } } -static void rewrite_register(struct regalloc_state * s, +static void remap_register(void * data, struct rc_instruction * inst, rc_register_file * file, unsigned int * index) { + struct regalloc_state * s = data; const struct register_info * reg; if (*file == RC_FILE_TEMPORARY) @@ -214,74 +215,6 @@ static void rewrite_register(struct regalloc_state * s, } } -static void rewrite_normal_instruction(struct regalloc_state * s, struct rc_sub_instruction * inst) -{ - const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode); - - if (opcode->HasDstReg) { - rc_register_file file = inst->DstReg.File; - unsigned int index = inst->DstReg.Index; - - rewrite_register(s, &file, &index); - - inst->DstReg.File = file; - inst->DstReg.Index = index; - } - - for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) { - rc_register_file file = inst->SrcReg[src].File; - unsigned int index = inst->SrcReg[src].Index; - - rewrite_register(s, &file, &index); - - inst->SrcReg[src].File = file; - inst->SrcReg[src].Index = index; - } -} - -static void rewrite_pair_instruction(struct regalloc_state * s, struct rc_pair_instruction * inst) -{ - if (inst->RGB.WriteMask) { - rc_register_file file = RC_FILE_TEMPORARY; - unsigned int index = inst->RGB.DestIndex; - - rewrite_register(s, &file, &index); - - inst->RGB.DestIndex = index; - } - - if (inst->Alpha.WriteMask) { - rc_register_file file = RC_FILE_TEMPORARY; - unsigned int index = inst->Alpha.DestIndex; - - rewrite_register(s, &file, &index); - - inst->Alpha.DestIndex = index; - } - - for(unsigned int src = 0; src < 3; ++src) { - if (inst->RGB.Src[src].Used) { - rc_register_file file = inst->RGB.Src[src].File; - unsigned int index = inst->RGB.Src[src].Index; - - rewrite_register(s, &file, &index); - - inst->RGB.Src[src].File = file; - inst->RGB.Src[src].Index = index; - } - - if (inst->Alpha.Src[src].Used) { - rc_register_file file = inst->Alpha.Src[src].File; - unsigned int index = inst->Alpha.Src[src].Index; - - rewrite_register(s, &file, &index); - - inst->Alpha.Src[src].File = file; - inst->Alpha.Src[src].Index = index; - } - } -} - static void do_regalloc(struct regalloc_state * s) { /* Simple and stupid greedy register allocation */ @@ -310,10 +243,7 @@ static void do_regalloc(struct regalloc_state * s) for(struct rc_instruction * inst = s->C->Program.Instructions.Next; inst != &s->C->Program.Instructions; inst = inst->Next) { - if (inst->Type == RC_INSTRUCTION_NORMAL) - rewrite_normal_instruction(s, &inst->U.I); - else - rewrite_pair_instruction(s, &inst->U.P); + rc_remap_registers(inst, &remap_register, s); } } diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c index f5b7d57eab..05b874ba7c 100644 --- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c +++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c @@ -175,6 +175,26 @@ static void transform_ABS(struct radeon_compiler* c, rc_remove_instruction(inst); } +static void transform_CEIL(struct radeon_compiler* c, + struct rc_instruction* inst) +{ + /* Assuming: + * ceil(x) = -floor(-x) + * + * After inlining floor: + * ceil(x) = -(-x-frac(-x)) + * + * After simplification: + * ceil(x) = x+frac(-x) + */ + + int tempreg = rc_find_free_temporary(c); + emit1(c, inst->Prev, RC_OPCODE_FRC, 0, dstreg(RC_FILE_TEMPORARY, tempreg), negate(inst->U.I.SrcReg[0])); + emit2(c, inst->Prev, RC_OPCODE_ADD, inst->U.I.SaturateMode, inst->U.I.DstReg, + inst->U.I.SrcReg[0], srcreg(RC_FILE_TEMPORARY, tempreg)); + rc_remove_instruction(inst); +} + static void transform_DP3(struct radeon_compiler* c, struct rc_instruction* inst) { @@ -458,7 +478,7 @@ static void transform_XPD(struct radeon_compiler* c, * no userData necessary. * * Eliminates the following ALU instructions: - * ABS, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD + * ABS, CEIL, DPH, DST, FLR, LIT, LRP, POW, SEQ, SFL, SGE, SGT, SLE, SLT, SNE, SUB, SWZ, XPD * using: * MOV, ADD, MUL, MAD, FRC, DP3, LG2, EX2, CMP * @@ -474,6 +494,7 @@ int radeonTransformALU( { switch(inst->U.I.Opcode) { case RC_OPCODE_ABS: transform_ABS(c, inst); return 1; + case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1; case RC_OPCODE_DPH: transform_DPH(c, inst); return 1; case RC_OPCODE_DST: transform_DST(c, inst); return 1; case RC_OPCODE_FLR: transform_FLR(c, inst); return 1; @@ -511,37 +532,26 @@ static void transform_r300_vertex_CMP(struct radeon_compiler* c, { /* There is no decent CMP available, so let's rig one up. * CMP is defined as dst = src0 < 0.0 ? src1 : src2 - * The following sequence consumes two temps and three extra slots, + * The following sequence consumes two temps and two extra slots + * (the second temp and the second slot is consumed by transform_LRP), * but should be equivalent: * * SLT tmp0, src0, 0.0 - * SGE tmp1, src0, 0.0 - * MUL tmp0, tmp0, src1 - * MAD dst, src2, tmp1, tmp0 + * LRP dst, tmp0, src1, src2 * - * Yes, I know, I'm a mad scientist. ~ C. */ + * Yes, I know, I'm a mad scientist. ~ C. & M. */ int tempreg0 = rc_find_free_temporary(c); - int tempreg1 = rc_find_free_temporary(c); /* SLT tmp0, src0, 0.0 */ emit2(c, inst->Prev, RC_OPCODE_SLT, 0, dstreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[0], builtin_zero); - /* SGE tmp1, src0, 0.0 */ - emit2(c, inst->Prev, RC_OPCODE_SGE, 0, - dstreg(RC_FILE_TEMPORARY, tempreg1), - inst->U.I.SrcReg[0], builtin_zero); - - /* MUL tmp0, tmp0, src1 */ - emit2(c, inst->Prev, RC_OPCODE_MUL, 0, - dstreg(RC_FILE_TEMPORARY, tempreg0), - srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1]); - - /* MAD dst, src2, tmp1, tmp0 */ - emit3(c, inst->Prev, RC_OPCODE_MAD, inst->U.I.SaturateMode, - inst->U.I.DstReg, - inst->U.I.SrcReg[2], srcreg(RC_FILE_TEMPORARY, tempreg1), srcreg(RC_FILE_TEMPORARY, tempreg0)); + /* LRP dst, tmp0, src1, src2 */ + transform_LRP(c, + emit3(c, inst->Prev, RC_OPCODE_LRP, 0, + inst->U.I.DstReg, + srcreg(RC_FILE_TEMPORARY, tempreg0), inst->U.I.SrcReg[1], inst->U.I.SrcReg[2])); rc_remove_instruction(inst); } @@ -557,6 +567,7 @@ int r300_transform_vertex_alu( { switch(inst->U.I.Opcode) { case RC_OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return 1; + case RC_OPCODE_CEIL: transform_CEIL(c, inst); return 1; case RC_OPCODE_CMP: transform_r300_vertex_CMP(c, inst); return 1; case RC_OPCODE_DP3: transform_DP3(c, inst); return 1; case RC_OPCODE_DPH: transform_DPH(c, inst); return 1; diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h index 98732c810c..b7ee9a134b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_chipset.h +++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h @@ -12,6 +12,7 @@ #define PCI_CHIP_RV380_3150 0x3150 #define PCI_CHIP_RV380_3152 0x3152 #define PCI_CHIP_RV380_3154 0x3154 +#define PCI_CHIP_RV380_3155 0x3155 #define PCI_CHIP_RV380_3E50 0x3E50 #define PCI_CHIP_RV380_3E54 0x3E54 #define PCI_CHIP_RS100_4136 0x4136 diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c index cc951a12cb..c2722a4e19 100644 --- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c +++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c @@ -326,7 +326,7 @@ static int cs_emit(struct radeon_cs_int *cs) (!IS_R600_CLASS(csm->ctx->radeonScreen))) { /* +r6/r7 : No irq for r6/r7 yet. */ drm_radeon_irq_emit_t emit_cmd; emit_cmd.irq_seq = (int*)&csm->pending_age; - r = drmCommandWrite(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd)); + r = drmCommandWriteRead(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd)); if (r) { return r; } diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 7f5fb99fa4..6cd1d87de2 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -526,8 +526,10 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, unsigned mtCount = 0; unsigned maxMtIndex = 0; radeon_mipmap_tree *tmp; + unsigned int level; + int i; - for (unsigned level = firstLevel; level <= lastLevel; ++level) { + for (level = firstLevel; level <= lastLevel; ++level) { radeon_texture_image *img = get_radeon_texture_image(texObj->base.Image[0][level]); unsigned found = 0; // TODO: why this hack?? @@ -537,7 +539,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, if (!img->mt) continue; - for (int i = 0; i < mtCount; ++i) { + for (i = 0; i < mtCount; ++i) { if (mts[i] == img->mt) { found = 1; mtSizes[i] += img->mt->levels[img->mtlevel].size; @@ -558,7 +560,7 @@ static radeon_mipmap_tree * get_biggest_matching_miptree(radeonTexObj *texObj, return NULL; } - for (int i = 1; i < mtCount; ++i) { + for (i = 1; i < mtCount; ++i) { if (mtSizes[i] > mtSizes[maxMtIndex]) { maxMtIndex = i; } diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index 4d7255f47e..fca0f8173b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -516,6 +516,7 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id) case PCI_CHIP_RV380_3150: case PCI_CHIP_RV380_3152: case PCI_CHIP_RV380_3154: + case PCI_CHIP_RV380_3155: case PCI_CHIP_RV380_3E50: case PCI_CHIP_RV380_3E54: screen->chip_family = CHIP_FAMILY_RV380; diff --git a/src/mesa/drivers/dri/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c index 6f07ac275e..c3a53ea5e2 100644 --- a/src/mesa/drivers/dri/savage/savage_xmesa.c +++ b/src/mesa/drivers/dri/savage/savage_xmesa.c @@ -44,6 +44,7 @@ #include "tnl/t_pipeline.h" #include "drivers/common/driverfuncs.h" +#include "drivers/common/meta.h" #include "savagedd.h" #include "savagestate.h" @@ -473,6 +474,8 @@ savageCreateContext( const __GLcontextModes *mesaVis, imesa->CurrentTexObj[0] = 0; imesa->CurrentTexObj[1] = 0; + _mesa_meta_init( ctx ); + /* Initialize the software rasterizer and helper modules. */ _swrast_CreateContext( ctx ); @@ -564,6 +567,8 @@ savageDestroyContext(__DRIcontext *driContextPriv) free(imesa->cmdBuf.base); free(imesa->clientVtxBuf.buf); + _mesa_meta_free( imesa->glCtx ); + _swsetup_DestroyContext(imesa->glCtx ); _tnl_DestroyContext( imesa->glCtx ); _vbo_DestroyContext( imesa->glCtx ); diff --git a/src/mesa/glapi/gen/GL3.xml b/src/mesa/glapi/gen/GL3.xml new file mode 100644 index 0000000000..0d8d935f0a --- /dev/null +++ b/src/mesa/glapi/gen/GL3.xml @@ -0,0 +1,581 @@ +<?xml version="1.0"?> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"> + +<!-- Note: no GLX protocol info yet. --> + + +<OpenGLAPI> + +<category name="3.0"> + + <enum name="COMPARE_REF_TO_TEXTURE" value="0x884E"/> + <enum name="CLIP_DISTANCE0" value="0x3000"/> + <enum name="CLIP_DISTANCE1" value="0x3001"/> + <enum name="CLIP_DISTANCE2" value="0x3002"/> + <enum name="CLIP_DISTANCE3" value="0x3003"/> + <enum name="CLIP_DISTANCE4" value="0x3004"/> + <enum name="CLIP_DISTANCE5" value="0x3005"/> + <enum name="CLIP_DISTANCE6" value="0x3006"/> + <enum name="CLIP_DISTANCE7" value="0x3007"/> + <enum name="MAX_CLIP_DISTANCES" value="0x0D32"/> + <enum name="MAJOR_VERSION" value="0x821B"/> + <enum name="MINOR_VERSION" value="0x821C"/> + <enum name="NUM_EXTENSIONS" value="0x821D"/> + <enum name="CONTEXT_FLAGS" value="0x821E"/> + <enum name="DEPTH_BUFFER" value="0x8223"/> + <enum name="STENCIL_BUFFER" value="0x8224"/> + <enum name="COMPRESSED_RED" value="0x8225"/> + <enum name="COMPRESSED_RG" value="0x8226"/> + <enum name="CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT" value="0x0001"/> + <enum name="RGBA32F" value="0x8814"/> + <enum name="RGB32F" value="0x8815"/> + <enum name="RGBA16F" value="0x881A"/> + <enum name="RGB16F" value="0x881B"/> + <enum name="VERTEX_ATTRIB_ARRAY_INTEGER" value="0x88FD"/> + <enum name="MAX_ARRAY_TEXTURE_LAYERS" value="0x88FF"/> + <enum name="MIN_PROGRAM_TEXEL_OFFSET" value="0x8904"/> + <enum name="MAX_PROGRAM_TEXEL_OFFSET" value="0x8905"/> + <enum name="CLAMP_READ_COLOR" value="0x891C"/> + <enum name="FIXED_ONLY" value="0x891D"/> + <enum name="MAX_VARYING_COMPONENTS" value="0x8B4B"/> + <enum name="TEXTURE_1D_ARRAY" value="0x8C18"/> + <enum name="PROXY_TEXTURE_1D_ARRAY" value="0x8C19"/> + <enum name="TEXTURE_2D_ARRAY" value="0x8C1A"/> + <enum name="PROXY_TEXTURE_2D_ARRAY" value="0x8C1B"/> + <enum name="TEXTURE_BINDING_1D_ARRAY" value="0x8C1C"/> + <enum name="TEXTURE_BINDING_2D_ARRAY" value="0x8C1D"/> + <enum name="R11F_G11F_B10F" value="0x8C3A"/> + <enum name="UNSIGNED_INT_10F_11F_11F_REV" value="0x8C3B"/> + <enum name="RGB9_E5" value="0x8C3D"/> + <enum name="UNSIGNED_INT_5_9_9_9_REV" value="0x8C3E"/> + <enum name="TEXTURE_SHARED_SIZE" value="0x8C3F"/> + <enum name="TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH" value="0x8C76"/> + <enum name="TRANSFORM_FEEDBACK_BUFFER_MODE" value="0x8C7F"/> + <enum name="MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS" value="0x8C80"/> + <enum name="TRANSFORM_FEEDBACK_VARYINGS" value="0x8C83"/> + <enum name="TRANSFORM_FEEDBACK_BUFFER_START" value="0x8C84"/> + <enum name="TRANSFORM_FEEDBACK_BUFFER_SIZE" value="0x8C85"/> + <enum name="PRIMITIVES_GENERATED" value="0x8C87"/> + <enum name="TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN" value="0x8C88"/> + <enum name="RASTERIZER_DISCARD" value="0x8C89"/> + <enum name="MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS" value="0x8C8A"/> + <enum name="MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS" value="0x8C8B"/> + <enum name="INTERLEAVED_ATTRIBS" value="0x8C8C"/> + <enum name="SEPARATE_ATTRIBS" value="0x8C8D"/> + <enum name="TRANSFORM_FEEDBACK_BUFFER" value="0x8C8E"/> + <enum name="TRANSFORM_FEEDBACK_BUFFER_BINDING" value="0x8C8F"/> + <enum name="RGBA32UI" value="0x8D70"/> + <enum name="RGB32UI" value="0x8D71"/> + <enum name="RGBA16UI" value="0x8D76"/> + <enum name="RGB16UI" value="0x8D77"/> + <enum name="RGBA8UI" value="0x8D7C"/> + <enum name="RGB8UI" value="0x8D7D"/> + <enum name="RGBA32I" value="0x8D82"/> + <enum name="RGB32I" value="0x8D83"/> + <enum name="RGBA16I" value="0x8D88"/> + <enum name="RGB16I" value="0x8D89"/> + <enum name="RGBA8I" value="0x8D8E"/> + <enum name="RGB8I" value="0x8D8F"/> + <enum name="RED_INTEGER" value="0x8D94"/> + <enum name="GREEN_INTEGER" value="0x8D95"/> + <enum name="BLUE_INTEGER" value="0x8D96"/> + <enum name="RGB_INTEGER" value="0x8D98"/> + <enum name="RGBA_INTEGER" value="0x8D99"/> + <enum name="BGR_INTEGER" value="0x8D9A"/> + <enum name="BGRA_INTEGER" value="0x8D9B"/> + <enum name="SAMPLER_1D_ARRAY" value="0x8DC0"/> + <enum name="SAMPLER_2D_ARRAY" value="0x8DC1"/> + <enum name="SAMPLER_1D_ARRAY_SHADOW" value="0x8DC3"/> + <enum name="SAMPLER_2D_ARRAY_SHADOW" value="0x8DC4"/> + <enum name="SAMPLER_CUBE_SHADOW" value="0x8DC5"/> + <enum name="UNSIGNED_INT_VEC2" value="0x8DC6"/> + <enum name="UNSIGNED_INT_VEC3" value="0x8DC7"/> + <enum name="UNSIGNED_INT_VEC4" value="0x8DC8"/> + <enum name="INT_SAMPLER_1D" value="0x8DC9"/> + <enum name="INT_SAMPLER_2D" value="0x8DCA"/> + <enum name="INT_SAMPLER_3D" value="0x8DCB"/> + <enum name="INT_SAMPLER_CUBE" value="0x8DCC"/> + <enum name="INT_SAMPLER_1D_ARRAY" value="0x8DCE"/> + <enum name="INT_SAMPLER_2D_ARRAY" value="0x8DCF"/> + <enum name="UNSIGNED_INT_SAMPLER_1D" value="0x8DD1"/> + <enum name="UNSIGNED_INT_SAMPLER_2D" value="0x8DD2"/> + <enum name="UNSIGNED_INT_SAMPLER_3D" value="0x8DD3"/> + <enum name="UNSIGNED_INT_SAMPLER_CUBE" value="0x8DD4"/> + <enum name="UNSIGNED_INT_SAMPLER_1D_ARRAY" value="0x8DD6"/> + <enum name="UNSIGNED_INT_SAMPLER_2D_ARRAY" value="0x8DD7"/> + <enum name="QUERY_WAIT" value="0x8E13"/> + <enum name="QUERY_NO_WAIT" value="0x8E14"/> + <enum name="QUERY_BY_REGION_WAIT" value="0x8E15"/> + <enum name="QUERY_BY_REGION_NO_WAIT" value="0x8E16"/> + <enum name="BUFFER_ACCESS_FLAGS" value="0x911F"/> + <enum name="BUFFER_MAP_LENGTH" value="0x9120"/> + <enum name="BUFFER_MAP_OFFSET" value="0x9121"/> + + <function name="ClearBufferiv" offset="assign"> + <param name="buffer" type="GLenum"/> + <param name="drawbuffer" type="GLint"/> + <param name="value" type="const GLint *"/> + </function> + + <function name="ClearBufferuiv" offset="assign"> + <param name="buffer" type="GLenum"/> + <param name="drawbuffer" type="GLint"/> + <param name="value" type="const GLuint *"/> + </function> + + <function name="ClearBufferfv" offset="assign"> + <param name="buffer" type="GLenum"/> + <param name="drawbuffer" type="GLint"/> + <param name="value" type="const GLfloat *"/> + </function> + + <function name="ClearBufferfi" offset="assign"> + <param name="buffer" type="GLenum"/> + <param name="drawbuffer" type="GLint"/> + <param name="depth" type="const GLfloat"/> + <param name="stencil" type="const GLint"/> + </function> + + <function name="GetStringi" offset="assign"> + <param name="name" type="GLenum"/> + <param name="index" type="GLuint"/> + <return type="const GLubyte *"/> + </function> + + <function name="IsEnabledi" offset="assign"> + <param name="cap" type="GLenum"/> + <param name="index" type="GLuint"/> + <return type="GLboolean"/> + </function> + + <function name="GetFragDataLocation" offset="assign"> + <param name="program" type="GLuint"/> + <param name="name" type="const GLchar *"/> + <return type="GLint"/> + </function> + + <function name="BindFragDataLocation" offset="assign"> + <param name="program" type="GLuint"/> + <param name="color" type="GLuint"/> + <param name="name" type="const GLchar *"/> + </function> + + <function name="ColorMaski" offset="assign"> + <param name="index" type="GLuint"/> + <param name="r" type="GLboolean"/> + <param name="g" type="GLboolean"/> + <param name="b" type="GLboolean"/> + <param name="a" type="GLboolean"/> + </function> + + <function name="GetBooleani_v" offset="assign"> + <param name="cap" type="GLenum"/> + <param name="index" type="GLuint"/> + <param name="value" type="GLboolean *"/> + </function> + + <function name="GetIntegeri_v" offset="assign"> + <param name="cap" type="GLenum"/> + <param name="index" type="GLuint"/> + <param name="value" type="GLint *"/> + </function> + + <function name="Enablei" offset="assign"> + <param name="cap" type="GLenum"/> + <param name="index" type="GLuint"/> + </function> + + <function name="Disablei" offset="assign"> + <param name="cap" type="GLenum"/> + <param name="index" type="GLuint"/> + </function> + + <function name="BeginTransformFeedback" offset="assign"> + <param name="mode" type="GLenum"/> + </function> + + <function name="EndTransformFeedback" offset="assign"> + </function> + + <function name="BindBufferRange" offset="assign"> + <param name="target" type="GLenum"/> + <param name="index" type="GLuint"/> + <param name="buffer" type="GLuint"/> + <param name="offset" type="GLintptr"/> + <param name="size" type="GLsizeiptr"/> + </function> + + <function name="BindBufferBase" offset="assign"> + <param name="target" type="GLenum"/> + <param name="index" type="GLuint"/> + <param name="buffer" type="GLuint"/> + </function> + + <function name="TransformFeedbackVaryings" offset="assign"> + <param name="program" type="GLuint"/> + <param name="count" type="GLsizei"/> + <param name="varyings" type="const GLchar* *"/> + <param name="bufferMode" type="GLenum"/> + </function> + + <function name="GetTransformFeedbackVarying" offset="assign"> + <param name="program" type="GLuint"/> + <param name="index" type="GLuint"/> + <param name="bufSize" type="GLsizei"/> + <param name="length" type="GLsizei *"/> + <param name="size" type="GLsizei *"/> + <param name="type" type="GLenum *"/> + <param name="name" type="GLchar *"/> + </function> + + <function name="ClampColor" offset="assign"> + <param name="target" type="GLenum"/> + <param name="clamp" type="GLenum"/> + </function> + + <function name="BeginConditionalRender" offset="assign"> + <param name="id" type="GLuint"/> + <param name="mode" type="GLenum"/> + </function> + + <function name="EndConditionalRender" offset="assign"> + </function> + + <function name="VertexAttribIPointer" offset="assign"> + <param name="index" type="GLuint"/> + <param name="size" type="GLint"/> + <param name="type" type="GLenum"/> + <param name="stride" type="GLsizei"/> + <param name="pointer" type="const GLvoid *"/> + </function> + + <function name="GetVertexAttribIiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint *"/> + </function> + + <function name="GetVertexAttribIuiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLuint *"/> + </function> + + <function name="VertexAttribI1i" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLint"/> + </function> + + <function name="VertexAttribI2i" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + </function> + + <function name="VertexAttribI3i" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + </function> + + <function name="VertexAttribI4i" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLint"/> + <param name="y" type="GLint"/> + <param name="z" type="GLint"/> + <param name="w" type="GLint"/> + </function> + + <function name="VertexAttribI1ui" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLuint"/> + </function> + + <function name="VertexAttribI2ui" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLuint"/> + <param name="y" type="GLuint"/> + </function> + + <function name="VertexAttribI3ui" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLuint"/> + <param name="y" type="GLuint"/> + <param name="z" type="GLuint"/> + </function> + + <function name="VertexAttribI4ui" offset="assign"> + <param name="index" type="GLuint"/> + <param name="x" type="GLuint"/> + <param name="y" type="GLuint"/> + <param name="z" type="GLuint"/> + <param name="w" type="GLuint"/> + </function> + + <function name="VertexAttribI1iv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLint *"/> + </function> + + <function name="VertexAttribI2iv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLint *"/> + </function> + + <function name="VertexAttribI3iv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLint *"/> + </function> + + <function name="VertexAttribI4iv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLint *"/> + </function> + + <function name="VertexAttribI1uiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLuint *"/> + </function> + + <function name="VertexAttribI2uiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLuint *"/> + </function> + + <function name="VertexAttribI3uiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLuint *"/> + </function> + + <function name="VertexAttribI4uiv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLuint *"/> + </function> + + <function name="VertexAttribI4bv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLbyte *"/> + </function> + + <function name="VertexAttribI4sv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLshort *"/> + </function> + + <function name="VertexAttribI4ubv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLubyte *"/> + </function> + + <function name="VertexAttribI4usv" offset="assign"> + <param name="index" type="GLuint"/> + <param name="v" type="const GLushort *"/> + </function> + + <function name="GetUniformuiv" offset="assign"> + <param name="program" type="GLuint"/> + <param name="location" type="GLint"/> + <param name="params" type="GLuint *"/> + </function> + + <function name="Uniform1ui" offset="assign"> + <param name="locatoin" type="GLint"/> + <param name="x" type="GLuint"/> + </function> + + <function name="Uniform2ui" offset="assign"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint"/> + <param name="y" type="GLuint"/> + </function> + + <function name="Uniform3ui" offset="assign"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint"/> + <param name="y" type="GLuint"/> + <param name="z" type="GLuint"/> + </function> + + <function name="Uniform4ui" offset="assign"> + <param name="location" type="GLint"/> + <param name="x" type="GLuint"/> + <param name="y" type="GLuint"/> + <param name="z" type="GLuint"/> + <param name="w" type="GLuint"/> + </function> + + <function name="Uniform1uiv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint *"/> + </function> + + <function name="Uniform2uiv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint *"/> + </function> + + <function name="Uniform3uiv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint *"/> + </function> + + <function name="Uniform4uiv" offset="assign"> + <param name="location" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="value" type="const GLuint *"/> + </function> + + <function name="TexParameterIiv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="value" type="const GLint *"/> + </function> + + <function name="TexParameterIuiv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="value" type="const GLuint *"/> + </function> + + <function name="GetTexParameterIiv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="value" type="GLint *"/> + </function> + + <function name="GetTexParameterIuiv" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="value" type="GLuint *"/> + </function> + +</category> + + +<category name="3.1"> + + <enum name="SAMPLER_2D_RECT" value="0x8B63"/> + <enum name="SAMPLER_2D_RECT_SHADOW" value="0x8B64"/> + <enum name="SAMPLER_BUFFER" value="0x8DC2"/> + <enum name="INT_SAMPLER_2D_RECT" value="0x8DCD"/> + <enum name="INT_SAMPLER_BUFFER" value="0x8DD0"/> + <enum name="UNSIGNED_INT_SAMPLER_2D_RECT" value="0x8DD5"/> + <enum name="UNSIGNED_INT_SAMPLER_BUFFER" value="0x8DD8"/> + <enum name="TEXTURE_BUFFER" value="0x8C2A"/> + <enum name="MAX_TEXTURE_BUFFER_SIZE" value="0x8C2B"/> + <enum name="TEXTURE_BINDING_BUFFER" value="0x8C2C"/> + <enum name="TEXTURE_BUFFER_DATA_STORE_BINDING" value="0x8C2D"/> + <enum name="TEXTURE_BUFFER_FORMAT" value="0x8C2E"/> + <enum name="TEXTURE_RECTANGLE" value="0x84F5"/> + <enum name="TEXTURE_BINDING_RECTANGLE" value="0x84F6"/> + <enum name="PROXY_TEXTURE_RECTANGLE" value="0x84F7"/> + <enum name="MAX_RECTANGLE_TEXTURE_SIZE" value="0x84F8"/> + <enum name="RED_SNORM" value="0x8F90"/> + <enum name="RG_SNORM" value="0x8F91"/> + <enum name="RGB_SNORM" value="0x8F92"/> + <enum name="RGBA_SNORM" value="0x8F93"/> + <enum name="R8_SNORM" value="0x8F94"/> + <enum name="RG8_SNORM" value="0x8F95"/> + <enum name="RGB8_SNORM" value="0x8F96"/> + <enum name="RGBA8_SNORM" value="0x8F97"/> + <enum name="R16_SNORM" value="0x8F98"/> + <enum name="RG16_SNORM" value="0x8F99"/> + <enum name="RGB16_SNORM" value="0x8F9A"/> + <enum name="RGBA16_SNORM" value="0x8F9B"/> + <enum name="SIGNED_NORMALIZED" value="0x8F9C"/> + <enum name="PRIMITIVE_RESTART" value="0x8F9D"/> + <enum name="PRIMITIVE_RESTART_INDEX" value="0x8F9E"/> + + <function name="DrawArraysInstanced" offset="assign"> + <param name="mode" type="GLenum"/> + <param name="first" type="GLint"/> + <param name="count" type="GLsizei"/> + <param name="primcount" type="GLsizei"/> + </function> + + <function name="DrawElementsInstanced" offset="assign"> + <param name="mode" type="GLenum"/> + <param name="count" type="GLsizei"/> + <param name="type" type="GLenum"/> + <param name="indices" type="const GLvoid *"/> + <param name="primcount" type="GLsizei"/> + </function> + + <function name="TexBuffer" offset="assign"> + <param name="target" type="GLenum"/> + <param name="internalFormat" type="GLenum"/> + <param name="buffer" type="GLuint"/> + </function> + + <function name="glPrimitiveRestartIndex" offset="assign"> + <param name="index" type="GLuint"/> + </function> + +</category> + + +<category name="3.2"> + + <enum name="CONTEXT_CORE_PROFILE_BIT" value="0x00000001"/> + <enum name="CONTEXT_COMPATIBILITY_PROFILE_BIT" value="0x00000002"/> + <enum name="LINES_ADJACENCY" value="0x000A"/> + <enum name="LINE_STRIP_ADJACENCY" value="0x000B"/> + <enum name="TRIANGLES_ADJACENCY" value="0x000C"/> + <enum name="TRIANGLE_STRIP_ADJACENCY" value="0x000D"/> + <enum name="PROGRAM_POINT_SIZE" value="0x8642"/> + <enum name="MAX_GEOMETRY_TEXTURE_IMAGE_UNITS" value="0x8C29"/> + <enum name="FRAMEBUFFER_ATTACHMENT_LAYERED" value="0x8DA7"/> + <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS" value="0x8DA8"/> + <enum name="GEOMETRY_SHADER" value="0x8DD9"/> + <enum name="GEOMETRY_VERTICES_OUT" value="0x8916"/> + <enum name="GEOMETRY_INPUT_TYPE" value="0x8917"/> + <enum name="GEOMETRY_OUTPUT_TYPE" value="0x8918"/> + <enum name="MAX_GEOMETRY_UNIFORM_COMPONENTS" value="0x8DDF"/> + <enum name="MAX_GEOMETRY_OUTPUT_VERTICES" value="0x8DE0"/> + <enum name="MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS" value="0x8DE1"/> + <enum name="MAX_VERTEX_OUTPUT_COMPONENTS" value="0x9122"/> + <enum name="MAX_GEOMETRY_INPUT_COMPONENTS" value="0x9123"/> + <enum name="MAX_GEOMETRY_OUTPUT_COMPONENTS" value="0x9124"/> + <enum name="MAX_FRAGMENT_INPUT_COMPONENTS" value="0x9125"/> + <enum name="CONTEXT_PROFILE_MASK" value="0x9126"/> + + <function name="GetInteger64i_v" offset="assign"> + <param name="cap" type="GLenum"/> + <param name="index" type="GLuint"/> + <param name="data" type="GLint64 *"/> + </function> + + <function name="GetBufferParameteri64v" offset="assign"> + <param name="target" type="GLenum"/> + <param name="pname" type="GLenum"/> + <param name="params" type="GLint64 *"/> + </function> + + <function name="ProgramParameteri" offset="assign"> + <param name="program" type="GLuint"/> + <param name="pname" type="GLenum"/> + <param name="value" type="GLint"/> + </function> + + <function name="FramebufferTexture" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + </function> + + <function name="FramebufferTextureFace" offset="assign"> + <param name="target" type="GLenum"/> + <param name="attachment" type="GLenum"/> + <param name="texture" type="GLuint"/> + <param name="level" type="GLint"/> + <param name="face" type="GLenum"/> + </function> + +</category> + +</OpenGLAPI> diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c index 1ae0853364..b1389b25f2 100644 --- a/src/mesa/main/imports.c +++ b/src/mesa/main/imports.c @@ -564,7 +564,8 @@ _mesa_ffsll(int64_t val) unsigned int _mesa_bitcount(unsigned int n) { -#if defined(__GNUC__) +#if defined(__GNUC__) && \ + ((_GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) return __builtin_popcount(n); #else unsigned int bits; diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index d28f4ad125..1c263aabca 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -404,7 +404,8 @@ _mesa_is_pow_two(int x) static INLINE int32_t _mesa_next_pow_two_32(uint32_t x) { -#ifdef __GNUC__ +#if defined(__GNUC__) && \ + ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) uint32_t y = (x != 1); return (1 + y) << ((__builtin_clz(x - y) ^ 31) ); #else @@ -422,7 +423,8 @@ _mesa_next_pow_two_32(uint32_t x) static INLINE int64_t _mesa_next_pow_two_64(uint64_t x) { -#ifdef __GNUC__ +#if defined(__GNUC__) && \ + ((__GNUC__ == 3 && __GNUC_MINOR__ >= 4) || __GNUC__ >= 4) uint64_t y = (x != 1); if (sizeof(x) == sizeof(long)) return (1 + y) << ((__builtin_clzl(x - y) ^ 63)); diff --git a/src/mesa/state_tracker/st_atom_pixeltransfer.c b/src/mesa/state_tracker/st_atom_pixeltransfer.c index 4aac5bd97f..e8e67f8030 100644 --- a/src/mesa/state_tracker/st_atom_pixeltransfer.c +++ b/src/mesa/state_tracker/st_atom_pixeltransfer.c @@ -256,7 +256,7 @@ get_pixel_transfer_program(GLcontext *ctx, const struct state_key *key) /* create the colormap/texture now if not already done */ if (!st->pixel_xfer.pixelmap_texture) { st->pixel_xfer.pixelmap_texture = create_color_map_texture(ctx); - st->pixel_xfer.pixelmap_sampler_view = st_sampler_view_from_texture(ctx->st->pipe, + st->pixel_xfer.pixelmap_sampler_view = st_create_texture_sampler_view(ctx->st->pipe, st->pixel_xfer.pixelmap_texture); } diff --git a/src/mesa/state_tracker/st_atom_scissor.c b/src/mesa/state_tracker/st_atom_scissor.c index 5e0c51cff0..56b1383ae3 100644 --- a/src/mesa/state_tracker/st_atom_scissor.c +++ b/src/mesa/state_tracker/st_atom_scissor.c @@ -72,12 +72,15 @@ update_scissor( struct st_context *st ) scissor.minx = scissor.miny = scissor.maxx = scissor.maxy = 0; } - /* Now invert Y. Pipe drivers use the convention Y=0=top for surfaces + /* Now invert Y if needed. + * Gallium drivers use the convention Y=0=top for surfaces. */ - miny = fb->Height - scissor.maxy; - maxy = fb->Height - scissor.miny; - scissor.miny = miny; - scissor.maxy = maxy; + if (st_fb_orientation(fb) == Y_0_TOP) { + miny = fb->Height - scissor.maxy; + maxy = fb->Height - scissor.miny; + scissor.miny = miny; + scissor.maxy = maxy; + } if (memcmp(&scissor, &st->state.scissor, sizeof(scissor)) != 0) { /* state has changed */ diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c index 241c001f94..f4294ac1e6 100644 --- a/src/mesa/state_tracker/st_atom_texture.c +++ b/src/mesa/state_tracker/st_atom_texture.c @@ -46,6 +46,7 @@ static void update_textures(struct st_context *st) { + struct pipe_context *pipe = st->pipe; struct gl_vertex_program *vprog = st->ctx->VertexProgram._Current; struct gl_fragment_program *fprog = st->ctx->FragmentProgram._Current; const GLbitfield samplersUsed = (vprog->Base.SamplersUsed | @@ -84,7 +85,7 @@ update_textures(struct st_context *st) st->state.num_textures = su + 1; - sampler_view = st_get_stobj_sampler_view(stObj); + sampler_view = st_get_texture_sampler_view(stObj, pipe); } /* diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c index 074fc27711..12bba050a6 100644 --- a/src/mesa/state_tracker/st_cb_bitmap.c +++ b/src/mesa/state_tracker/st_cb_bitmap.c @@ -622,7 +622,7 @@ st_flush_bitmap_cache(struct st_context *st) cache->trans = NULL; } - sv = st_sampler_view_from_texture(st->pipe, cache->texture); + sv = st_create_texture_sampler_view(st->pipe, cache->texture); if (sv) { draw_bitmap_quad(st->ctx, cache->xpos, @@ -756,7 +756,7 @@ st_Bitmap(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, pt = make_bitmap_texture(ctx, width, height, unpack, bitmap); if (pt) { - struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt); + struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt); assert(pt->target == PIPE_TEXTURE_2D); diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c index 0498080ccf..d6fdfaccd6 100644 --- a/src/mesa/state_tracker/st_cb_blit.c +++ b/src/mesa/state_tracker/st_cb_blit.c @@ -133,7 +133,7 @@ st_BlitFramebuffer(GLcontext *ctx, return; util_blit_pixels(st->blit, - srcSurf, st_get_stobj_sampler_view(srcObj), + srcSurf, st_get_texture_sampler_view(srcObj, pipe), srcX0, srcY0, srcX1, srcY1, dstSurf, dstX0, dstY0, dstX1, dstY1, 0.0, pFilter); @@ -146,7 +146,7 @@ st_BlitFramebuffer(GLcontext *ctx, struct st_renderbuffer *dstRb = st_renderbuffer(drawFB->_ColorDrawBuffers[0]); struct pipe_surface *srcSurf = srcRb->surface; - struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcRb, pipe); + struct pipe_sampler_view *srcView = st_get_renderbuffer_sampler_view(srcRb, pipe); struct pipe_surface *dstSurf = dstRb->surface; util_blit_pixels(st->blit, @@ -182,7 +182,7 @@ st_BlitFramebuffer(GLcontext *ctx, if ((mask & depthStencil) == depthStencil && srcDepthSurf == srcStencilSurf && dstDepthSurf == dstStencilSurf) { - struct pipe_sampler_view *srcView = st_renderbuffer_get_sampler_view(srcDepthRb, pipe); + struct pipe_sampler_view *srcView = st_get_renderbuffer_sampler_view(srcDepthRb, pipe); /* Blitting depth and stencil values between combined * depth/stencil buffers. This is the ideal case for such buffers. diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 955e371398..2c18ded2ab 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -834,7 +834,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, struct pipe_resource *pt = make_texture(st, width, height, format, type, unpack, pixels); if (pt) { - struct pipe_sampler_view *sv = st_sampler_view_from_texture(st->pipe, pt); + struct pipe_sampler_view *sv = st_create_texture_sampler_view(st->pipe, pt); if (sv) { draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2], @@ -1041,7 +1041,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (!pt) return; - sv = st_sampler_view_from_texture(st->pipe, pt); + sv = st_create_texture_sampler_view(st->pipe, pt); if (!sv) { pipe_resource_reference(&pt, NULL); return; diff --git a/src/mesa/state_tracker/st_cb_eglimage.c b/src/mesa/state_tracker/st_cb_eglimage.c index 3c4fe32090..a924f87223 100644 --- a/src/mesa/state_tracker/st_cb_eglimage.c +++ b/src/mesa/state_tracker/st_cb_eglimage.c @@ -126,7 +126,6 @@ st_bind_surface(GLcontext *ctx, GLenum target, texImage->TexFormat = st_pipe_format_to_mesa_format(ps->format); _mesa_set_fetch_functions(texImage, 2); - stObj->pipe = ctx->st->pipe; /* FIXME create a non-default sampler view from the pipe_surface? */ pipe_resource_reference(&stImage->pt, ps->texture); diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c index aec487b001..de1b8e7dc0 100644 --- a/src/mesa/state_tracker/st_cb_fbo.c +++ b/src/mesa/state_tracker/st_cb_fbo.c @@ -310,10 +310,12 @@ st_render_texture(GLcontext *ctx, struct gl_framebuffer *fb, struct gl_renderbuffer_attachment *att) { + struct st_context *st = ctx->st; + struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = ctx->st->pipe->screen; struct st_renderbuffer *strb; struct gl_renderbuffer *rb; - struct pipe_resource *pt = st_get_texobj_texture(att->Texture); + struct pipe_resource *pt = st_get_texobj_resource(att->Texture); struct st_texture_object *stObj; const struct gl_texture_image *texImage; GLint pt_level; @@ -360,7 +362,8 @@ st_render_texture(GLcontext *ctx, pipe_surface_reference(&strb->surface, NULL); - pipe_sampler_view_reference(&strb->sampler_view, st_get_stobj_sampler_view(stObj)); + pipe_sampler_view_reference(&strb->sampler_view, + st_get_texture_sampler_view(stObj, pipe)); assert(strb->rtt_level <= strb->texture->last_level); @@ -542,11 +545,11 @@ void st_init_fbo_functions(struct dd_function_table *functions) } struct pipe_sampler_view * -st_renderbuffer_get_sampler_view(struct st_renderbuffer *rb, +st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb, struct pipe_context *pipe) { if (!rb->sampler_view) { - rb->sampler_view = st_sampler_view_from_texture(pipe, rb->texture); + rb->sampler_view = st_create_texture_sampler_view(pipe, rb->texture); } return rb->sampler_view; diff --git a/src/mesa/state_tracker/st_cb_fbo.h b/src/mesa/state_tracker/st_cb_fbo.h index 5f11a7cd8a..beb26ab4da 100644 --- a/src/mesa/state_tracker/st_cb_fbo.h +++ b/src/mesa/state_tracker/st_cb_fbo.h @@ -74,7 +74,7 @@ extern void st_init_fbo_functions(struct dd_function_table *functions); extern struct pipe_sampler_view * -st_renderbuffer_get_sampler_view(struct st_renderbuffer *rb, +st_get_renderbuffer_sampler_view(struct st_renderbuffer *rb, struct pipe_context *pipe); diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 9479819e83..89f10284ce 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -322,8 +322,6 @@ guess_and_alloc_texture(struct st_context *st, depth, usage); - stObj->pipe = st->pipe; - DBG("%s - success\n", __FUNCTION__); } @@ -838,7 +836,8 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level, struct pipe_screen *screen = pipe->screen; struct st_texture_image *stImage = st_texture_image(texImage); struct st_texture_object *stObj = st_texture_object(texObj); - struct pipe_sampler_view *src_view = st_get_stobj_sampler_view(stObj); + struct pipe_sampler_view *src_view = + st_get_texture_sampler_view(stObj, pipe); const GLuint width = texImage->Width; const GLuint height = texImage->Height; struct pipe_surface *dst_surface; @@ -1624,7 +1623,7 @@ st_copy_texsubimage(GLcontext *ctx, } util_blit_pixels_writemask(ctx->st->blit, strb->surface, - st_renderbuffer_get_sampler_view(strb, pipe), + st_get_renderbuffer_sampler_view(strb, pipe), srcX, srcY0, srcX + width, srcY1, dest_surface, diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index c753fdca34..5fcb6b9dcf 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -129,7 +129,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe ) _vbo_CreateContext(ctx); #if FEATURE_feedback || FEATURE_drawpix - st->draw = draw_create(); /* for selection/feedback */ + st->draw = draw_create(pipe); /* for selection/feedback */ /* Disable draw options that might convert points/lines to tris, etc. * as that would foul-up feedback/selection mode. diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index a28ad8eebb..0889f1a522 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -137,7 +137,7 @@ st_feedback_draw_vbo(GLcontext *ctx, assert(draw); draw_set_viewport_state(draw, &st->state.viewport); draw_set_clip_state(draw, &st->state.clip); - draw_set_rasterizer_state(draw, &st->state.rasterizer); + draw_set_rasterizer_state(draw, &st->state.rasterizer, NULL); draw_bind_vertex_shader(draw, st->vp_varient->draw_shader); set_feedback_vertex_format(ctx); diff --git a/src/mesa/state_tracker/st_gen_mipmap.c b/src/mesa/state_tracker/st_gen_mipmap.c index f0fe31967c..5b7a962037 100644 --- a/src/mesa/state_tracker/st_gen_mipmap.c +++ b/src/mesa/state_tracker/st_gen_mipmap.c @@ -84,7 +84,7 @@ st_render_mipmap(struct st_context *st, { struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; - struct pipe_sampler_view *psv = st_get_stobj_sampler_view(stObj); + struct pipe_sampler_view *psv = st_get_texture_sampler_view(stObj, pipe); const uint face = _mesa_tex_target_to_face(target); assert(target != GL_TEXTURE_3D); /* not done yet */ @@ -107,7 +107,7 @@ fallback_generate_mipmap(GLcontext *ctx, GLenum target, struct gl_texture_object *texObj) { struct pipe_context *pipe = ctx->st->pipe; - struct pipe_resource *pt = st_get_texobj_texture(texObj); + struct pipe_resource *pt = st_get_texobj_resource(texObj); const uint baseLevel = texObj->BaseLevel; const uint lastLevel = pt->last_level; const uint face = _mesa_tex_target_to_face(target), zslice = 0; @@ -213,7 +213,7 @@ st_generate_mipmap(GLcontext *ctx, GLenum target, { struct st_context *st = ctx->st; struct st_texture_object *stObj = st_texture_object(texObj); - struct pipe_resource *pt = st_get_texobj_texture(texObj); + struct pipe_resource *pt = st_get_texobj_resource(texObj); const uint baseLevel = texObj->BaseLevel; uint lastLevel; uint dstLevel; diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c index 26f9554c9e..5cf17fe530 100644 --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -556,7 +556,6 @@ st_context_teximage(struct st_context_iface *stctxi, enum st_texture_type target _mesa_clear_texture_image(ctx, texImage); } - stObj->pipe = st->pipe; pipe_resource_reference(&stImage->pt, tex); _mesa_dirty_texobj(ctx, texObj, GL_TRUE); diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h index 76ea7e6950..416468478b 100644 --- a/src/mesa/state_tracker/st_texture.h +++ b/src/mesa/state_tracker/st_texture.h @@ -34,7 +34,7 @@ #include "main/mtypes.h" -struct pipe_context; + struct pipe_resource; @@ -76,8 +76,6 @@ struct st_texture_object */ struct pipe_sampler_view *sampler_view; - struct pipe_context *pipe; - GLboolean teximage_realloc; /* True if there is/was a surface bound to this texture object. It helps @@ -101,7 +99,7 @@ st_texture_object(struct gl_texture_object *obj) static INLINE struct pipe_resource * -st_get_texobj_texture(struct gl_texture_object *texObj) +st_get_texobj_resource(struct gl_texture_object *texObj) { struct st_texture_object *stObj = st_texture_object(texObj); return stObj ? stObj->pt : NULL; @@ -109,15 +107,15 @@ st_get_texobj_texture(struct gl_texture_object *texObj) static INLINE struct pipe_resource * -st_get_stobj_texture(struct st_texture_object *stObj) +st_get_stobj_resource(struct st_texture_object *stObj) { return stObj ? stObj->pt : NULL; } static INLINE struct pipe_sampler_view * -st_sampler_view_from_texture(struct pipe_context *pipe, - struct pipe_resource *texture) +st_create_texture_sampler_view(struct pipe_context *pipe, + struct pipe_resource *texture) { struct pipe_sampler_view templ; @@ -130,14 +128,16 @@ st_sampler_view_from_texture(struct pipe_context *pipe, static INLINE struct pipe_sampler_view * -st_get_stobj_sampler_view(struct st_texture_object *stObj) +st_get_texture_sampler_view(struct st_texture_object *stObj, + struct pipe_context *pipe) + { if (!stObj || !stObj->pt) { return NULL; } if (!stObj->sampler_view) { - stObj->sampler_view = st_sampler_view_from_texture(stObj->pipe, stObj->pt); + stObj->sampler_view = st_create_texture_sampler_view(pipe, stObj->pt); } return stObj->sampler_view; diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index e83bd9e404..0ccbb42383 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -850,8 +850,11 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ) NULL); } - /* Free the vertex buffer: + /* Free the vertex buffer. Unmap first if needed. */ + if (_mesa_bufferobj_mapped(exec->vtx.bufferobj)) { + ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, exec->vtx.bufferobj); + } _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL); } |