diff options
author | Christian König <[email protected]> | 2011-03-19 01:02:40 +0100 |
---|---|---|
committer | Christian König <[email protected]> | 2011-03-19 01:02:40 +0100 |
commit | 2bf95c519e755146704f4942b1703d47d18bfeaa (patch) | |
tree | 9d29c5d56014377013770615611f903cd5b25292 /src/gallium | |
parent | f36846c77ee196881c0da560229279fc7ed88170 (diff) | |
parent | 8042d751debb7a8375e8bc587189fea9a5a8371d (diff) |
Merge remote branch 'origin/master' into pipe-video
Conflicts:
src/gallium/drivers/r600/r600_asm.c
src/gallium/tests/unit/SConscript
Diffstat (limited to 'src/gallium')
258 files changed, 4223 insertions, 2453 deletions
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index f5fea1f71b8..869b2d486a4 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -110,6 +110,7 @@ C_SOURCES = \ util/u_draw_quad.c \ util/u_format.c \ util/u_format_other.c \ + util/u_format_latc.c \ util/u_format_s3tc.c \ util/u_format_rgtc.c \ util/u_format_srgb.c \ @@ -130,6 +131,7 @@ C_SOURCES = \ util/u_network.c \ util/u_math.c \ util/u_mm.c \ + util/u_pstipple.c \ util/u_rect.c \ util/u_ringbuffer.c \ util/u_sampler.c \ @@ -159,7 +161,6 @@ GALLIVM_SOURCES = \ gallivm/lp_bld_bitarit.c \ gallivm/lp_bld_const.c \ gallivm/lp_bld_conv.c \ - gallivm/lp_bld_debug.c \ gallivm/lp_bld_flow.c \ gallivm/lp_bld_format_aos.c \ gallivm/lp_bld_format_soa.c \ @@ -187,6 +188,7 @@ GALLIVM_SOURCES = \ draw/draw_pt_fetch_shade_pipeline_llvm.c GALLIVM_CPP_SOURCES = \ + gallivm/lp_bld_debug.cpp \ gallivm/lp_bld_misc.cpp GENERATED_SOURCES = \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index f4ab8a50da4..84519cfd048 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -157,6 +157,7 @@ source = [ 'util/u_draw_quad.c', 'util/u_format.c', 'util/u_format_other.c', + 'util/u_format_latc.c', 'util/u_format_s3tc.c', 'util/u_format_rgtc.c', 'util/u_format_srgb.c', @@ -177,6 +178,7 @@ source = [ 'util/u_network.c', 'util/u_math.c', 'util/u_mm.c', + 'util/u_pstipple.c', 'util/u_rect.c', 'util/u_resource.c', 'util/u_ringbuffer.c', @@ -199,16 +201,13 @@ source = [ ] if env['llvm']: - if env['UDIS86']: - env.Append(CPPDEFINES = [('HAVE_UDIS86', '1')]) - source += [ 'gallivm/lp_bld_arit.c', 'gallivm/lp_bld_assert.c', 'gallivm/lp_bld_bitarit.c', 'gallivm/lp_bld_const.c', 'gallivm/lp_bld_conv.c', - 'gallivm/lp_bld_debug.c', + 'gallivm/lp_bld_debug.cpp', 'gallivm/lp_bld_flow.c', 'gallivm/lp_bld_format_aos.c', 'gallivm/lp_bld_format_soa.c', diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c index ea62c9739fd..fe3627be867 100644 --- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c +++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c @@ -388,13 +388,6 @@ pstip_update_texture(struct pstip_stage *pstip) uint i, j; ubyte *data; - /* XXX: want to avoid flushing just because we use stipple: - * - * Flush should no longer be necessary if driver is properly - * interleaving drawing and transfers on a given context: - */ - pipe->flush( pipe, PIPE_FLUSH_TEXTURE_CACHE, NULL ); - transfer = pipe_get_transfer(pipe, pstip->texture, 0, 0, PIPE_TRANSFER_WRITE, 0, 0, 32, 32); data = pipe->transfer_map(pipe, transfer); diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h index bfb72d50efa..e6d187e9774 100644 --- a/src/gallium/auxiliary/draw/draw_vs.h +++ b/src/gallium/auxiliary/draw/draw_vs.h @@ -33,6 +33,7 @@ #include "draw_context.h" #include "draw_private.h" +#include "draw_vertex.h" struct draw_context; @@ -48,7 +49,7 @@ struct draw_variant_input struct draw_variant_output { - enum pipe_format format; /* output format */ + enum attrib_emit format; /* output format */ unsigned vs_output:8; /* which vertex shader output is this? */ unsigned offset:24; /* offset into output vertex */ }; diff --git a/src/gallium/auxiliary/draw/draw_vs_aos_io.c b/src/gallium/auxiliary/draw/draw_vs_aos_io.c index 8f8bbe7cb88..f1dd4487732 100644 --- a/src/gallium/auxiliary/draw/draw_vs_aos_io.c +++ b/src/gallium/auxiliary/draw/draw_vs_aos_io.c @@ -384,7 +384,7 @@ static void emit_store_R8G8B8A8_UNORM( struct aos_compilation *cp, static boolean emit_output( struct aos_compilation *cp, struct x86_reg ptr, struct x86_reg dataXMM, - unsigned format ) + enum attrib_emit format ) { switch (format) { case EMIT_1F: @@ -422,7 +422,7 @@ boolean aos_emit_outputs( struct aos_compilation *cp ) unsigned i; for (i = 0; i < cp->vaos->base.key.nr_outputs; i++) { - unsigned format = cp->vaos->base.key.element[i].out.format; + enum attrib_emit format = cp->vaos->base.key.element[i].out.format; unsigned offset = cp->vaos->base.key.element[i].out.offset; unsigned vs_output = cp->vaos->base.key.element[i].out.vs_output; diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.c b/src/gallium/auxiliary/gallivm/lp_bld_debug.c deleted file mode 100644 index 93e56553d7b..00000000000 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.c +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#ifdef HAVE_UDIS86 -#include <udis86.h> -#endif - -#include "util/u_math.h" -#include "util/u_debug.h" -#include "lp_bld_debug.h" - - -/** - * Check alignment. - * - * It is important that this check is not implemented as a macro or inlined - * function, as the compiler assumptions in respect to alignment of global - * and stack variables would often make the check a no op, defeating the - * whole purpose of the exercise. - */ -boolean -lp_check_alignment(const void *ptr, unsigned alignment) -{ - assert(util_is_power_of_two(alignment)); - return ((uintptr_t)ptr & (alignment - 1)) == 0; -} - - -void -lp_disassemble(const void* func) -{ -#ifdef HAVE_UDIS86 - ud_t ud_obj; - uint64_t max_jmp_pc; - uint inst_no; - boolean emit_addrs = TRUE, emit_line_nos = FALSE; - - ud_init(&ud_obj); - - ud_set_input_buffer(&ud_obj, (void*)func, 0xffff); - - max_jmp_pc = (uint64_t) (uintptr_t) func; - ud_set_pc(&ud_obj, max_jmp_pc); - -#ifdef PIPE_ARCH_X86 - ud_set_mode(&ud_obj, 32); -#endif -#ifdef PIPE_ARCH_X86_64 - ud_set_mode(&ud_obj, 64); -#endif - - ud_set_syntax(&ud_obj, UD_SYN_ATT); - - while (ud_disassemble(&ud_obj)) { - - if (emit_addrs) { -#ifdef PIPE_ARCH_X86 - debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj)); -#endif -#ifdef PIPE_ARCH_X86_64 - debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj)); -#endif - } - else if (emit_line_nos) { - debug_printf("%6d:\t", inst_no); - inst_no++; - } -#if 0 - debug_printf("%-16s ", ud_insn_hex(&ud_obj)); -#endif - - debug_printf("%s\n", ud_insn_asm(&ud_obj)); - - if(ud_obj.mnemonic != UD_Icall) { - unsigned i; - for(i = 0; i < 3; ++i) { - const struct ud_operand *op = &ud_obj.operand[i]; - if (op->type == UD_OP_JIMM){ - uint64_t pc = ud_obj.pc; - - switch (op->size) { - case 8: - pc += op->lval.sbyte; - break; - case 16: - pc += op->lval.sword; - break; - case 32: - pc += op->lval.sdword; - break; - default: - break; - } - if(pc > max_jmp_pc) - max_jmp_pc = pc; - } - } - } - - if (ud_obj.mnemonic == UD_Iinvalid || - (ud_insn_off(&ud_obj) >= max_jmp_pc && - (ud_obj.mnemonic == UD_Iret || - ud_obj.mnemonic == UD_Ijmp))) - break; - } - -#if 0 - /* Print GDB command, useful to verify udis86 output */ - debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc); -#endif - - debug_printf("\n"); -#else - (void)func; -#endif -} diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp new file mode 100644 index 00000000000..bb2c82fe0ed --- /dev/null +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.cpp @@ -0,0 +1,357 @@ +/************************************************************************** + * + * Copyright 2009-2011 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <llvm-c/Core.h> +#include <llvm/Target/TargetMachine.h> +#include <llvm/Target/TargetRegistry.h> +#include <llvm/Target/TargetSelect.h> +#include <llvm/Target/TargetInstrInfo.h> +#include <llvm/Support/raw_ostream.h> +#include <llvm/Support/MemoryObject.h> +#include <llvm/System/Host.h> + +#if HAVE_LLVM >= 0x0207 +#include <llvm/MC/MCDisassembler.h> +#include <llvm/MC/MCAsmInfo.h> +#include <llvm/MC/MCInst.h> +#include <llvm/MC/MCInstPrinter.h> +#endif /* HAVE_LLVM >= 0x0207 */ + +#include "util/u_math.h" +#include "util/u_debug.h" + +#include "lp_bld_debug.h" + + + +/** + * Check alignment. + * + * It is important that this check is not implemented as a macro or inlined + * function, as the compiler assumptions in respect to alignment of global + * and stack variables would often make the check a no op, defeating the + * whole purpose of the exercise. + */ +extern "C" boolean +lp_check_alignment(const void *ptr, unsigned alignment) +{ + assert(util_is_power_of_two(alignment)); + return ((uintptr_t)ptr & (alignment - 1)) == 0; +} + + +class raw_debug_ostream : + public llvm::raw_ostream +{ + uint64_t pos; + + void write_impl(const char *Ptr, size_t Size); + uint64_t current_pos() { return pos; } + uint64_t current_pos() const { return pos; } + +#if HAVE_LLVM >= 0x207 + uint64_t preferred_buffer_size() { return 512; } +#else + size_t preferred_buffer_size() { return 512; } +#endif +}; + + +void +raw_debug_ostream::write_impl(const char *Ptr, size_t Size) +{ + if (Size > 0) { + char *lastPtr = (char *)&Ptr[Size]; + char last = *lastPtr; + *lastPtr = 0; + _debug_printf("%*s", Size, Ptr); + *lastPtr = last; + pos += Size; + } +} + + +/** + * Same as LLVMDumpValue, but through our debugging channels. + */ +extern "C" void +lp_debug_dump_value(LLVMValueRef value) +{ +#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) + raw_debug_ostream os; + llvm::unwrap(value)->print(os); + os.flush(); +#else + LLVMDumpValue(value); +#endif +} + + +#if HAVE_LLVM >= 0x0207 +/* + * MemoryObject wrapper around a buffer of memory, to be used by MC + * disassembler. + */ +class BufferMemoryObject: + public llvm::MemoryObject +{ +private: + const uint8_t *Bytes; + uint64_t Length; +public: + BufferMemoryObject(const uint8_t *bytes, uint64_t length) : + Bytes(bytes), Length(length) + { + } + + uint64_t getBase() const + { + return 0; + } + + uint64_t getExtent() const + { + return Length; + } + + int readByte(uint64_t addr, uint8_t *byte) const + { + if (addr > getExtent()) + return -1; + *byte = Bytes[addr]; + return 0; + } +}; +#endif /* HAVE_LLVM >= 0x0207 */ + + +/* + * Disassemble a function, using the LLVM MC disassembler. + * + * See also: + * - http://blog.llvm.org/2010/01/x86-disassembler.html + * - http://blog.llvm.org/2010/04/intro-to-llvm-mc-project.html + */ +extern "C" void +lp_disassemble(const void* func) +{ +#if HAVE_LLVM >= 0x0207 + using namespace llvm; + + const uint8_t *bytes = (const uint8_t *)func; + + /* + * Limit disassembly to this extent + */ + const uint64_t extent = 0x10000; + + uint64_t max_pc = 0; + + /* + * Initialize all used objects. + */ + + std::string Triple = sys::getHostTriple(); + + std::string Error; + const Target *T = TargetRegistry::lookupTarget(Triple, Error); + +#if HAVE_LLVM >= 0x0208 + InitializeNativeTargetAsmPrinter(); +#else + InitializeAllAsmPrinters(); +#endif + + InitializeAllDisassemblers(); + + OwningPtr<const MCAsmInfo> AsmInfo(T->createAsmInfo(Triple)); + + if (!AsmInfo) { + debug_printf("error: no assembly info for target %s\n", Triple.c_str()); + return; + } + + OwningPtr<const MCDisassembler> DisAsm(T->createMCDisassembler()); + if (!DisAsm) { + debug_printf("error: no disassembler for target %s\n", Triple.c_str()); + return; + } + + raw_debug_ostream Out; + + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); +#if HAVE_LLVM >= 0x0208 + OwningPtr<MCInstPrinter> Printer( + T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo)); +#else + OwningPtr<MCInstPrinter> Printer( + T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo, Out)); +#endif + if (!Printer) { + debug_printf("error: no instruction printer for target %s\n", Triple.c_str()); + return; + } + + TargetMachine *TM = T->createTargetMachine(Triple, ""); + + const TargetInstrInfo *TII = TM->getInstrInfo(); + + /* + * Wrap the data in a MemoryObject + */ + BufferMemoryObject memoryObject((const uint8_t *)bytes, extent); + + uint64_t pc; + pc = 0; + while (true) { + MCInst Inst; + uint64_t Size; + + /* + * Print address. We use addresses relative to the start of the function, + * so that between runs. + */ + + debug_printf("%6lu:\t", (unsigned long)pc); + + if (!DisAsm->getInstruction(Inst, Size, memoryObject, + pc, + nulls())) { + debug_printf("invalid\n"); + pc += 1; + } + + /* + * Output the bytes in hexidecimal format. + */ + + if (0) { + unsigned i; + for (i = 0; i < Size; ++i) { + debug_printf("%02x ", ((const uint8_t*)bytes)[pc + i]); + } + for (; i < 16; ++i) { + debug_printf(" "); + } + } + + /* + * Print the instruction. + */ + +#if HAVE_LLVM >= 0x208 + Printer->printInst(&Inst, Out); +#else + Printer->printInst(&Inst); +#endif + Out.flush(); + + /* + * Advance. + */ + + pc += Size; + + const TargetInstrDesc &TID = TII->get(Inst.getOpcode()); + + /* + * Keep track of forward jumps to a nearby address. + */ + + if (TID.isBranch()) { + for (unsigned i = 0; i < Inst.getNumOperands(); ++i) { + const MCOperand &operand = Inst.getOperand(i); + if (operand.isImm()) { + uint64_t jump; + + /* + * FIXME: Handle both relative and absolute addresses correctly. + * EDInstInfo actually has this info, but operandTypes and + * operandFlags enums are not exposed in the public interface. + */ + + if (1) { + /* + * PC relative addr. + */ + + jump = pc + operand.getImm(); + } else { + /* + * Absolute addr. + */ + + jump = (uint64_t)operand.getImm(); + } + + /* + * Output the address relative to the function start, given + * that MC will print the addresses relative the current pc. + */ + debug_printf("\t\t; %lu", (unsigned long)jump); + + /* + * Ignore far jumps given it could be actually a tail return to + * a random address. + */ + + if (jump > max_pc && + jump < extent) { + max_pc = jump; + } + } + } + } + + debug_printf("\n"); + + /* + * Stop disassembling on return statements, if there is no record of a + * jump to a successive address. + */ + + if (TID.isReturn()) { + if (pc > max_pc) { + break; + } + } + } + + /* + * Print GDB command, useful to verify output. + */ + + if (0) { + debug_printf("disassemble %p %p\n", bytes, bytes + pc); + } + + debug_printf("\n"); +#else /* HAVE_LLVM < 0x0207 */ + (void)func; +#endif /* HAVE_LLVM < 0x0207 */ +} + diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h index 8a58f95b78f..da873f30b2d 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h @@ -45,6 +45,11 @@ #define GALLIVM_DEBUG_GC (1 << 6) +#ifdef __cplusplus +extern "C" { +#endif + + #ifdef DEBUG extern unsigned gallivm_debug; #else @@ -81,4 +86,9 @@ void lp_disassemble(const void* func); +#ifdef __cplusplus +} +#endif + + #endif /* !LP_BLD_DEBUG_H */ diff --git a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp index 46dd00d8224..843a14a500c 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp +++ b/src/gallium/auxiliary/gallivm/lp_bld_misc.cpp @@ -46,66 +46,6 @@ #include "util/u_debug.h" -#if (defined(PIPE_OS_WINDOWS) && !defined(PIPE_CC_MSVC)) || defined(PIPE_OS_EMBDDED) - -#include "llvm/Support/raw_ostream.h" - -class raw_debug_ostream : - public llvm::raw_ostream -{ - uint64_t pos; - - void write_impl(const char *Ptr, size_t Size); - uint64_t current_pos() { return pos; } - uint64_t current_pos() const { return pos; } - -#if HAVE_LLVM >= 0x207 - uint64_t preferred_buffer_size() { return 512; } -#else - size_t preferred_buffer_size() { return 512; } -#endif -}; - - -void -raw_debug_ostream::write_impl(const char *Ptr, size_t Size) -{ - if (Size > 0) { - char *lastPtr = (char *)&Ptr[Size]; - char last = *lastPtr; - *lastPtr = 0; - _debug_printf("%*s", Size, Ptr); - *lastPtr = last; - pos += Size; - } -} - - -/** - * Same as LLVMDumpValue, but through our debugging channels. - */ -extern "C" void -lp_debug_dump_value(LLVMValueRef value) -{ - raw_debug_ostream os; - llvm::unwrap(value)->print(os); - os.flush(); -} - - -#else - - -extern "C" void -lp_debug_dump_value(LLVMValueRef value) -{ - LLVMDumpValue(value); -} - - -#endif - - /** * Register the engine with oprofile. * diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 1fec3adf5b1..9961ba08f3a 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -1108,6 +1108,11 @@ lp_build_sample_compare(struct lp_build_sample_context *bld, coord, tex); } + /* Clamp p coords to [0,1] */ + p = lp_build_clamp(&bld->coord_bld, p, + bld->coord_bld.zero, + bld->coord_bld.one); + /* result = (p FUNC texel) ? 1 : 0 */ res = lp_build_cmp(texel_bld, bld->static_state->compare_func, p, texel[chan]); diff --git a/src/gallium/auxiliary/os/os_thread.h b/src/gallium/auxiliary/os/os_thread.h index a084310d4ff..8173d4cc37f 100644 --- a/src/gallium/auxiliary/os/os_thread.h +++ b/src/gallium/auxiliary/os/os_thread.h @@ -152,8 +152,9 @@ static INLINE int pipe_thread_destroy( pipe_thread thread ) */ typedef CRITICAL_SECTION pipe_mutex; +/* http://locklessinc.com/articles/pthreads_on_windows/ */ #define pipe_static_mutex(mutex) \ - /*static*/ pipe_mutex mutex = {0,0,0,0,0,0} + static pipe_mutex mutex = {(PCRITICAL_SECTION_DEBUG)-1, -1, 0, 0, 0, 0} #define pipe_mutex_init(mutex) \ InitializeCriticalSection(&mutex) diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index c2322eed19b..5754f476188 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -174,11 +174,20 @@ pb_malloc_bufmgr_destroy(struct pb_manager *mgr) } +static boolean +pb_malloc_bufmgr_is_buffer_busy( struct pb_manager *mgr, + struct pb_buffer *buf ) +{ + return FALSE; +} + + static struct pb_manager pb_malloc_bufmgr = { pb_malloc_bufmgr_destroy, pb_malloc_bufmgr_create_buffer, - pb_malloc_bufmgr_flush + pb_malloc_bufmgr_flush, + pb_malloc_bufmgr_is_buffer_busy }; diff --git a/src/gallium/auxiliary/rbug/rbug_context.c b/src/gallium/auxiliary/rbug/rbug_context.c index a3fd7e8430e..36824058c7d 100644 --- a/src/gallium/auxiliary/rbug/rbug_context.c +++ b/src/gallium/auxiliary/rbug/rbug_context.c @@ -288,7 +288,6 @@ int rbug_send_context_draw_rule(struct rbug_connection *__con, int rbug_send_context_flush(struct rbug_connection *__con, rbug_context_t context, - int32_t flags, uint32_t *__serial) { uint32_t __len = 0; @@ -298,7 +297,6 @@ int rbug_send_context_flush(struct rbug_connection *__con, LEN(8); /* header */ LEN(8); /* context */ - LEN(4); /* flags */ /* align */ PAD(__len, 8); @@ -310,7 +308,6 @@ int rbug_send_context_flush(struct rbug_connection *__con, WRITE(4, int32_t, ((int32_t)RBUG_OP_CONTEXT_FLUSH)); WRITE(4, uint32_t, ((uint32_t)(__len / 4))); WRITE(8, rbug_context_t, context); /* context */ - WRITE(4, int32_t, flags); /* flags */ /* final pad */ PAD(__pos, 8); @@ -663,7 +660,6 @@ struct rbug_proto_context_flush * rbug_demarshal_context_flush(struct rbug_proto ret->header.opcode = header->opcode; READ(8, rbug_context_t, context); /* context */ - READ(4, int32_t, flags); /* flags */ return ret; } diff --git a/src/gallium/auxiliary/rbug/rbug_context.h b/src/gallium/auxiliary/rbug/rbug_context.h index 03126d6b123..4a865c25fc5 100644 --- a/src/gallium/auxiliary/rbug/rbug_context.h +++ b/src/gallium/auxiliary/rbug/rbug_context.h @@ -96,7 +96,6 @@ struct rbug_proto_context_flush { struct rbug_header header; rbug_context_t context; - int32_t flags; }; struct rbug_proto_context_list_reply @@ -162,7 +161,6 @@ int rbug_send_context_draw_rule(struct rbug_connection *__con, int rbug_send_context_flush(struct rbug_connection *__con, rbug_context_t context, - int32_t flags, uint32_t *__serial); int rbug_send_context_list_reply(struct rbug_connection *__con, diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c index 1eac762e6e5..57622a0dea6 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_text.c +++ b/src/gallium/auxiliary/tgsi/tgsi_text.c @@ -137,7 +137,7 @@ static boolean parse_identifier( const char **pcur, char *ret ) int i = 0; if (is_alpha_underscore( cur )) { ret[i++] = *cur++; - while (is_alpha_underscore( cur )) + while (is_alpha_underscore( cur ) || is_digit( cur )) ret[i++] = *cur++; ret[i++] = '\0'; *pcur = cur; diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c index 76bd7ace526..421726b40e0 100644 --- a/src/gallium/auxiliary/util/u_blit.c +++ b/src/gallium/auxiliary/util/u_blit.c @@ -128,21 +128,6 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso) ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } - /* vertex shader - still required to provide the linkage between - * fragment shader input semantics and vertex_element/buffers. - */ - { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC }; - const uint semantic_indexes[] = { 0, 0 }; - ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); - } - - /* fragment shader */ - ctx->fs[TGSI_WRITEMASK_XYZW] = - util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); ctx->vbuf = NULL; /* init vertex data that doesn't change */ @@ -170,7 +155,8 @@ util_destroy_blit(struct blit_state *ctx) struct pipe_context *pipe = ctx->pipe; unsigned i; - pipe->delete_vs_state(pipe, ctx->vs); + if (ctx->vs) + pipe->delete_vs_state(pipe, ctx->vs); for (i = 0; i < Elements(ctx->fs); i++) if (ctx->fs[i]) @@ -186,6 +172,59 @@ util_destroy_blit(struct blit_state *ctx) /** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct blit_state *ctx, uint writemask) +{ + if (!ctx->fs[writemask]) + ctx->fs[writemask] = + util_make_fragment_tex_shader_writemask(ctx->pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR, + writemask); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); +} + + +/** + * Helper function to set the depthwrite shader. + */ +static INLINE void +set_depth_fragment_shader(struct blit_state *ctx) +{ + if (!ctx->fs_depth) + ctx->fs_depth = + util_make_fragment_tex_shader_writedepth(ctx->pipe, TGSI_TEXTURE_2D, + TGSI_INTERPOLATE_LINEAR); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct blit_state *ctx) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!ctx->vs) { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); +} + + +/** * Get offset of next free slot in vertex buffer for quad vertices. */ static unsigned @@ -304,8 +343,10 @@ util_blit_pixels_writemask(struct blit_state *ctx, { struct pipe_context *pipe = ctx->pipe; struct pipe_screen *screen = pipe->screen; + enum pipe_format src_format, dst_format; struct pipe_sampler_view *sampler_view = NULL; struct pipe_sampler_view sv_templ; + struct pipe_surface *dst_surface; struct pipe_framebuffer_state fb; const int srcW = abs(srcX1 - srcX0); const int srcH = abs(srcY1 - srcY0); @@ -326,12 +367,15 @@ util_blit_pixels_writemask(struct blit_state *ctx, regions_overlap(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1); + src_format = util_format_linear(src_tex->format); + dst_format = util_format_linear(dst->format); + /* * Check for simple case: no format conversion, no flipping, no stretching, * no overlapping. * Filter mode should not matter since there's no stretching. */ - if (dst->format == src_tex->format && + if (dst_format == src_format && srcX0 < srcX1 && dstX0 < dstX1 && srcY0 < srcY1 && @@ -354,6 +398,14 @@ util_blit_pixels_writemask(struct blit_state *ctx, return; } + if (dst_format == dst->format) { + dst_surface = dst; + } else { + struct pipe_surface templ = *dst; + templ.format = dst_format; + dst_surface = pipe->create_surface(pipe, dst->texture, &templ); + } + /* Create a temporary texture when src and dest alias or when src * is anything other than a 2d texture. * XXX should just use appropriate shader to access 1d / 3d slice / cube face, @@ -361,9 +413,9 @@ util_blit_pixels_writemask(struct blit_state *ctx, * * This can still be improved upon. */ - if ((src_tex == dst->texture && - dst->u.tex.level == src_level && - dst->u.tex.first_layer == srcZ0) || + if ((src_tex == dst_surface->texture && + dst_surface->u.tex.level == src_level && + dst_surface->u.tex.first_layer == srcZ0) || (src_tex->target != PIPE_TEXTURE_2D && src_tex->target != PIPE_TEXTURE_2D && src_tex->target != PIPE_TEXTURE_RECT)) @@ -392,7 +444,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* create temp texture */ memset(&texTemp, 0, sizeof(texTemp)); texTemp.target = ctx->internal_target; - texTemp.format = src_tex->format; + texTemp.format = src_format; texTemp.last_level = 0; texTemp.width0 = srcW; texTemp.height0 = srcH; @@ -439,7 +491,7 @@ util_blit_pixels_writemask(struct blit_state *ctx, pipe_resource_reference(&tex, NULL); } else { - u_sampler_view_default_template(&sv_templ, src_tex, src_tex->format); + u_sampler_view_default_template(&sv_templ, src_tex, src_format); sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); if (!sampler_view) { @@ -460,15 +512,15 @@ util_blit_pixels_writemask(struct blit_state *ctx, } } - dst_is_depth = util_format_is_depth_or_stencil(dst->format); + dst_is_depth = util_format_is_depth_or_stencil(dst_format); assert(screen->is_format_supported(screen, sampler_view->format, ctx->internal_target, sampler_view->texture->nr_samples, - PIPE_BIND_SAMPLER_VIEW, 0)); - assert(screen->is_format_supported(screen, dst->format, ctx->internal_target, - dst->texture->nr_samples, + PIPE_BIND_SAMPLER_VIEW)); + assert(screen->is_format_supported(screen, dst_format, ctx->internal_target, + dst_surface->texture->nr_samples, dst_is_depth ? PIPE_BIND_DEPTH_STENCIL : - PIPE_BIND_RENDER_TARGET, 0)); + PIPE_BIND_RENDER_TARGET)); /* save state (restored below) */ cso_save_blend(ctx->cso); cso_save_depth_stencil_alpha(ctx->cso); @@ -502,12 +554,12 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_single_sampler_done(ctx->cso); /* viewport */ - ctx->viewport.scale[0] = 0.5f * dst->width; - ctx->viewport.scale[1] = 0.5f * dst->height; + ctx->viewport.scale[0] = 0.5f * dst_surface->width; + ctx->viewport.scale[1] = 0.5f * dst_surface->height; ctx->viewport.scale[2] = 0.5f; ctx->viewport.scale[3] = 1.0f; - ctx->viewport.translate[0] = 0.5f * dst->width; - ctx->viewport.translate[1] = 0.5f * dst->height; + ctx->viewport.translate[0] = 0.5f * dst_surface->width; + ctx->viewport.translate[1] = 0.5f * dst_surface->height; ctx->viewport.translate[2] = 0.5f; ctx->viewport.translate[3] = 0.0f; cso_set_viewport(ctx->cso, &ctx->viewport); @@ -517,41 +569,30 @@ util_blit_pixels_writemask(struct blit_state *ctx, /* shaders */ if (dst_is_depth) { - if (ctx->fs_depth == NULL) - ctx->fs_depth = - util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); - - cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth); + set_depth_fragment_shader(ctx); } else { - if (ctx->fs[writemask] == NULL) - ctx->fs[writemask] = - util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR, - writemask); - - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]); + set_fragment_shader(ctx, writemask); } - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + set_vertex_shader(ctx); /* drawing dest */ memset(&fb, 0, sizeof(fb)); - fb.width = dst->width; - fb.height = dst->height; + fb.width = dst_surface->width; + fb.height = dst_surface->height; if (dst_is_depth) { - fb.zsbuf = dst; + fb.zsbuf = dst_surface; } else { fb.nr_cbufs = 1; - fb.cbufs[0] = dst; + fb.cbufs[0] = dst_surface; } cso_set_framebuffer(ctx->cso, &fb); /* draw quad */ offset = setup_vertex_data_tex(ctx, - (float) dstX0 / dst->width * 2.0f - 1.0f, - (float) dstY0 / dst->height * 2.0f - 1.0f, - (float) dstX1 / dst->width * 2.0f - 1.0f, - (float) dstY1 / dst->height * 2.0f - 1.0f, + (float) dstX0 / dst_surface->width * 2.0f - 1.0f, + (float) dstY0 / dst_surface->height * 2.0f - 1.0f, + (float) dstX1 / dst_surface->width * 2.0f - 1.0f, + (float) dstY1 / dst_surface->height * 2.0f - 1.0f, s0, t0, s1, t1, z); @@ -576,6 +617,8 @@ util_blit_pixels_writemask(struct blit_state *ctx, cso_restore_vertex_buffers(ctx->cso); pipe_sampler_view_reference(&sampler_view, NULL); + if (dst_surface != dst) + pipe_surface_reference(&dst_surface, NULL); } @@ -660,8 +703,7 @@ util_blit_pixels_tex(struct blit_state *ctx, assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, PIPE_TEXTURE_2D, dst->texture->nr_samples, - PIPE_BIND_RENDER_TARGET, - 0)); + PIPE_BIND_RENDER_TARGET)); /* save state (restored below) */ cso_save_blend(ctx->cso); @@ -706,8 +748,8 @@ util_blit_pixels_tex(struct blit_state *ctx, cso_set_fragment_sampler_views(ctx->cso, 1, &src_sampler_view); /* shaders */ - cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]); - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW); + set_vertex_shader(ctx); /* drawing dest */ memset(&fb, 0, sizeof(fb)); diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index fd1c2b72d04..a4c399052fd 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -772,9 +772,9 @@ void util_blitter_copy_region(struct blitter_context *blitter, /* (assuming copying a stencil buffer is not possible) */ if ((!ignore_stencil && is_stencil) || !screen->is_format_supported(screen, dst->format, dst->target, - dst->nr_samples, bind, 0) || + dst->nr_samples, bind) || !screen->is_format_supported(screen, src->format, src->target, - src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) { + src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { ctx->base.running = TRUE; util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz, src, srclevel, srcbox); @@ -785,6 +785,7 @@ void util_blitter_copy_region(struct blitter_context *blitter, /* Get surface. */ memset(&surf_templ, 0, sizeof(surf_templ)); u_surface_default_template(&surf_templ, dst, bind); + surf_templ.format = util_format_linear(dst->format); surf_templ.u.tex.level = dstlevel; surf_templ.u.tex.first_layer = dstz; surf_templ.u.tex.last_layer = dstz; @@ -823,7 +824,7 @@ void util_blitter_copy_region(struct blitter_context *blitter, normalized = src->target != PIPE_TEXTURE_RECT; /* Initialize sampler view. */ - u_sampler_view_default_template(&viewTempl, src, src->format); + u_sampler_view_default_template(&viewTempl, src, util_format_linear(src->format)); view = pipe->create_sampler_view(pipe, src, &viewTempl); /* Set rasterizer state, shaders, and textures. */ diff --git a/src/gallium/auxiliary/util/u_cache.c b/src/gallium/auxiliary/util/u_cache.c index 15f4a8831f2..df08ec302a2 100644 --- a/src/gallium/auxiliary/util/u_cache.c +++ b/src/gallium/auxiliary/util/u_cache.c @@ -27,9 +27,10 @@ /** * @file - * Simple cache implementation. + * Improved cache implementation. * - * We simply have fixed size array, and destroy previous values on collision. + * Fixed size array with linear probing on collision and LRU eviction + * on full. * * @author Jose Fonseca <[email protected]> */ @@ -41,10 +42,17 @@ #include "util/u_math.h" #include "util/u_memory.h" #include "util/u_cache.h" +#include "util/u_simple_list.h" struct util_cache_entry { + enum { EMPTY = 0, FILLED, DELETED } state; + uint32_t hash; + + struct util_cache_entry *next; + struct util_cache_entry *prev; + void *key; void *value; @@ -69,11 +77,14 @@ struct util_cache struct util_cache_entry *entries; -#ifdef DEBUG unsigned count; -#endif + struct util_cache_entry lru; }; +static void +ensure_sanity(const struct util_cache *cache); + +#define CACHE_DEFAULT_ALPHA 2 struct util_cache * util_cache_create(uint32_t (*hash)(const void *key), @@ -90,6 +101,10 @@ util_cache_create(uint32_t (*hash)(const void *key), cache->hash = hash; cache->compare = compare; cache->destroy = destroy; + + make_empty_list(&cache->lru); + + size *= CACHE_DEFAULT_ALPHA; cache->size = size; cache->entries = CALLOC(size, sizeof(struct util_cache_entry)); @@ -98,19 +113,46 @@ util_cache_create(uint32_t (*hash)(const void *key), return NULL; } + ensure_sanity(cache); return cache; } -static INLINE struct util_cache_entry * +static struct util_cache_entry * util_cache_entry_get(struct util_cache *cache, + uint32_t hash, const void *key) { - uint32_t hash; - - hash = cache->hash(key); + struct util_cache_entry *first_unfilled = NULL; + uint32_t index = hash % cache->size; + uint32_t probe; + + /* Probe until we find either a matching FILLED entry or an EMPTY + * slot (which has never been occupied). + * + * Deleted or non-matching slots are not indicative of completion + * as a previous linear probe for the same key could have continued + * past this point. + */ + for (probe = 0; probe < cache->size; probe++) { + uint32_t i = (index + probe) % cache->size; + struct util_cache_entry *current = &cache->entries[i]; + + if (current->state == FILLED) { + if (current->hash == hash && + cache->compare(key, current->key) == 0) + return current; + } + else { + if (!first_unfilled) + first_unfilled = current; + + if (current->state == EMPTY) + return first_unfilled; + } + } - return &cache->entries[hash % cache->size]; + return NULL; } static INLINE void @@ -123,9 +165,15 @@ util_cache_entry_destroy(struct util_cache *cache, entry->key = NULL; entry->value = NULL; - if(key || value) + if (entry->state == FILLED) { + remove_from_list(entry); + cache->count--; + if(cache->destroy) cache->destroy(key, value); + + entry->state = DELETED; + } } @@ -135,21 +183,33 @@ util_cache_set(struct util_cache *cache, void *value) { struct util_cache_entry *entry; + uint32_t hash = cache->hash(key); assert(cache); if (!cache) return; - entry = util_cache_entry_get(cache, key); + entry = util_cache_entry_get(cache, hash, key); + if (!entry) + entry = cache->lru.prev; + + if (cache->count >= cache->size / CACHE_DEFAULT_ALPHA) + util_cache_entry_destroy(cache, cache->lru.prev); + util_cache_entry_destroy(cache, entry); #ifdef DEBUG ++entry->count; - ++cache->count; #endif entry->key = key; + entry->hash = hash; entry->value = value; + entry->state = FILLED; + insert_at_head(&cache->lru, entry); + cache->count++; + + ensure_sanity(cache); } @@ -158,17 +218,18 @@ util_cache_get(struct util_cache *cache, const void *key) { struct util_cache_entry *entry; + uint32_t hash = cache->hash(key); assert(cache); if (!cache) return NULL; - entry = util_cache_entry_get(cache, key); - if(!entry->key && !entry->value) - return NULL; - - if(cache->compare(key, entry->key) != 0) + entry = util_cache_entry_get(cache, hash, key); + if (!entry) return NULL; + + if (entry->state == FILLED) + move_to_head(&cache->lru, entry); return entry->value; } @@ -183,8 +244,14 @@ util_cache_clear(struct util_cache *cache) if (!cache) return; - for(i = 0; i < cache->size; ++i) + for(i = 0; i < cache->size; ++i) { util_cache_entry_destroy(cache, &cache->entries[i]); + cache->entries[i].state = EMPTY; + } + + assert(cache->count == 0); + assert(is_empty_list(&cache->lru)); + ensure_sanity(cache); } @@ -215,3 +282,70 @@ util_cache_destroy(struct util_cache *cache) FREE(cache->entries); FREE(cache); } + + +void +util_cache_remove(struct util_cache *cache, + const void *key) +{ + struct util_cache_entry *entry; + uint32_t hash; + + assert(cache); + if (!cache) + return; + + hash = cache->hash(key); + + entry = util_cache_entry_get(cache, hash, key); + if (!entry) + return; + + if (entry->state == FILLED) + util_cache_entry_destroy(cache, entry); + + ensure_sanity(cache); +} + + +static void +ensure_sanity(const struct util_cache *cache) +{ +#ifdef DEBUG + unsigned i, cnt = 0; + + assert(cache); + for (i = 0; i < cache->size; i++) { + struct util_cache_entry *header = &cache->entries[i]; + + assert(header); + assert(header->state == FILLED || + header->state == EMPTY || + header->state == DELETED); + if (header->state == FILLED) { + cnt++; + assert(header->hash == cache->hash(header->key)); + } + } + + assert(cnt == cache->count); + assert(cache->size >= cnt); + + if (cache->count == 0) { + assert (is_empty_list(&cache->lru)); + } + else { + struct util_cache_entry *header = cache->lru.next; + + assert (header); + assert (!is_empty_list(&cache->lru)); + + for (i = 0; i < cache->count; i++) + header = header->next; + + assert(header == &cache->lru); + } +#endif + + (void)cache; +} diff --git a/src/gallium/auxiliary/util/u_cache.h b/src/gallium/auxiliary/util/u_cache.h index 8a612c6585f..be3631b7254 100644 --- a/src/gallium/auxiliary/util/u_cache.h +++ b/src/gallium/auxiliary/util/u_cache.h @@ -79,6 +79,10 @@ util_cache_clear(struct util_cache *cache); void util_cache_destroy(struct util_cache *cache); +void +util_cache_remove(struct util_cache *cache, + const void *key); + #ifdef __cplusplus } diff --git a/src/gallium/auxiliary/util/u_caps.c b/src/gallium/auxiliary/util/u_caps.c index e209a98b706..75677b2b133 100644 --- a/src/gallium/auxiliary/util/u_caps.c +++ b/src/gallium/auxiliary/util/u_caps.c @@ -69,8 +69,7 @@ util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) list[i++], PIPE_TEXTURE_2D, 0, - PIPE_BIND_SAMPLER_VIEW, - 0)) { + PIPE_BIND_SAMPLER_VIEW)) { *out = i - 2; return FALSE; } diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c index 0defd919974..8ed3b3c0959 100644 --- a/src/gallium/auxiliary/util/u_draw_quad.c +++ b/src/gallium/auxiliary/util/u_draw_quad.c @@ -82,7 +82,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso, uint numAttribs = 2, i, j; uint vertexBytes = 4 * (4 * numAttribs * sizeof(float)); struct pipe_resource *vbuf = NULL; - uint *v = NULL; + float *v = NULL; v = MALLOC(vertexBytes); if (v == NULL) @@ -121,7 +121,7 @@ util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso, vbuf = pipe_user_buffer_create(pipe->screen, v, vertexBytes, PIPE_BIND_VERTEX_BUFFER); - if (!vbuf) + if (!vbuf) goto out; util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2); diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv index 0ae15c9cc0a..22c63ae162a 100644 --- a/src/gallium/auxiliary/util/u_format.csv +++ b/src/gallium/auxiliary/util/u_format.csv @@ -141,6 +141,7 @@ PIPE_FORMAT_R8G8Bx_SNORM , other, 1, 1, sn8 , sn8 , , , x # - http://en.wikipedia.org/wiki/S3_Texture_Compression # - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt # - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt +# - http://www.opengl.org/registry/specs/EXT/texture_compression_latc.txt # - http://msdn.microsoft.com/en-us/library/bb694531.aspx PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb @@ -156,6 +157,11 @@ PIPE_FORMAT_RGTC1_SNORM , rgtc, 4, 4, x64, , , , x001, rg PIPE_FORMAT_RGTC2_UNORM , rgtc, 4, 4, x128, , , , xy01, rgb PIPE_FORMAT_RGTC2_SNORM , rgtc, 4, 4, x128, , , , xy01, rgb +PIPE_FORMAT_LATC1_UNORM , rgtc, 4, 4, x64, , , , xxx1, rgb +PIPE_FORMAT_LATC1_SNORM , rgtc, 4, 4, x64, , , , xxx1, rgb +PIPE_FORMAT_LATC2_UNORM , rgtc, 4, 4, x128, , , , xxxy, rgb +PIPE_FORMAT_LATC2_SNORM , rgtc, 4, 4, x128, , , , xxxy, rgb + # Straightforward D3D10-like formats (also used for # vertex buffer element description) # diff --git a/src/gallium/auxiliary/util/u_format_latc.c b/src/gallium/auxiliary/util/u_format_latc.c new file mode 100644 index 00000000000..e84c493bb1e --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_latc.c @@ -0,0 +1,328 @@ +/************************************************************************** + * + * Copyright (C) 2011 Red Hat 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 + * BRIAN PAUL 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 <stdio.h> +#include "u_math.h" +#include "u_format.h" +#include "u_format_rgtc.h" +#include "u_format_latc.h" + +static void u_format_unsigned_encode_rgtc_chan(uint8_t *blkaddr, uint8_t srccolors[4][4], + int numxpixels, int numypixels); + +static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, + unsigned i, unsigned j, uint8_t *value, unsigned comps); + +static void u_format_signed_encode_rgtc_chan(int8_t *blkaddr, int8_t srccolors[4][4], + int numxpixels, int numypixels); + +static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, + unsigned i, unsigned j, int8_t *value, unsigned comps); + +void +util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + /* Fix warnings here: */ + (void) u_format_unsigned_encode_rgtc_chan; + (void) u_format_signed_encode_rgtc_chan; + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); +} + +void +util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, + unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 8; + + for(y = 0; y < height; y += 4) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + uint8_t tmp_r; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + uint8_t tmp_r; + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = 1.0; +} + +void +util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc1_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 8; + + for(y = 0; y < height; y += 4) { + const int8_t *src = (int8_t *)src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + int8_t tmp_r; + u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = 1.0; + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + int8_t tmp_r; + + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = 1.0; +} + + +void +util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + puts(__func__); + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); +} + +void +util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc2_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rgtc2_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); +} + +void +util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); +} + +void +util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 16; + + for(y = 0; y < height; y += 4) { + const uint8_t *src = src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + uint8_t tmp_r, tmp_g; + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = ubyte_to_float(tmp_g); + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + uint8_t tmp_r, tmp_g; + + u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = ubyte_to_float(tmp_r); + dst[3] = ubyte_to_float(tmp_g); +} + + +void +util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + fprintf(stderr,"%s\n", __func__); +} + +void +util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + unsigned x, y, i, j; + int block_size = 16; + + for(y = 0; y < height; y += 4) { + const int8_t *src = (int8_t *)src_row; + for(x = 0; x < width; x += 4) { + for(j = 0; j < 4; ++j) { + for(i = 0; i < 4; ++i) { + float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; + int8_t tmp_r, tmp_g; + u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); + u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = byte_to_float_tex(tmp_g); + } + } + src += block_size; + } + src_row += src_stride; + } +} + +void +util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); +} + +void +util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) +{ + int8_t tmp_r, tmp_g; + + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); + u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); + dst[0] = + dst[1] = + dst[2] = byte_to_float_tex(tmp_r); + dst[3] = byte_to_float_tex(tmp_g); +} + + +#define TAG(x) u_format_unsigned_##x +#define TYPE uint8_t +#define T_MIN 0 +#define T_MAX 255 + +#include "../../../mesa/main/texcompress_rgtc_tmp.h" + +#undef TYPE +#undef TAG +#undef T_MIN +#undef T_MAX + + +#define TAG(x) u_format_signed_##x +#define TYPE int8_t +#define T_MIN (int8_t)-128 +#define T_MAX (int8_t)127 + +#include "../../../mesa/main/texcompress_rgtc_tmp.h" + +#undef TYPE +#undef TAG +#undef T_MIN +#undef T_MAX diff --git a/src/gallium/auxiliary/util/u_format_latc.h b/src/gallium/auxiliary/util/u_format_latc.h new file mode 100644 index 00000000000..1f08887533d --- /dev/null +++ b/src/gallium/auxiliary/util/u_format_latc.h @@ -0,0 +1,108 @@ +/************************************************************************** + * + * Copyright 2011 Red Hat Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + **************************************************************************/ + +#ifndef U_FORMAT_LATC_H_ +#define U_FORMAT_LATC_H_ + +void +util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); + +void +util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); + + + +void +util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); + +void +util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); + + +void +util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); + +void +util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); + + +void +util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); + +void +util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); + +void +util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); + + +#endif diff --git a/src/gallium/auxiliary/util/u_format_rgtc.c b/src/gallium/auxiliary/util/u_format_rgtc.c index 6ffcd7e99ef..c929fd47e99 100644 --- a/src/gallium/auxiliary/util/u_format_rgtc.c +++ b/src/gallium/auxiliary/util/u_format_rgtc.c @@ -281,7 +281,7 @@ util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, } void -util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) { const unsigned bw = 4, bh = 4, bytes_per_block = 16; unsigned x, y, i, j; @@ -294,7 +294,7 @@ util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c for(j = 0; j < bh; ++j) { for(i = 0; i < bw; ++i) { tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); - tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]); + tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); } } u_format_unsigned_encode_rgtc_chan(dst, tmp_r, 4, 4); @@ -306,6 +306,12 @@ util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c } void +util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); +} + +void util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) { unsigned x, y, i, j; @@ -389,7 +395,7 @@ util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, c } void -util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) { const unsigned bw = 4, bh = 4, bytes_per_block = 16; unsigned x, y, i, j; @@ -402,7 +408,7 @@ util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c for(j = 0; j < bh; ++j) { for(i = 0; i < bw; ++i) { tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); - tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + 1]); + tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); } } u_format_signed_encode_rgtc_chan(dst, tmp_r, 4, 4); @@ -414,6 +420,12 @@ util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, c } void +util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) +{ + util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); +} + +void util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) { int8_t tmp_r, tmp_g; diff --git a/src/gallium/auxiliary/util/u_format_rgtc.h b/src/gallium/auxiliary/util/u_format_rgtc.h index 3e8636d110c..67ac4728e56 100644 --- a/src/gallium/auxiliary/util/u_format_rgtc.h +++ b/src/gallium/auxiliary/util/u_format_rgtc.h @@ -77,6 +77,9 @@ void util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); void +util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off); + +void util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); void @@ -99,6 +102,9 @@ void util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); void +util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off); + +void util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); void diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py index 7468bc38b32..55e0f7827ef 100755 --- a/src/gallium/auxiliary/util/u_format_table.py +++ b/src/gallium/auxiliary/util/u_format_table.py @@ -88,6 +88,7 @@ def write_format_table(formats): print '#include "u_format.h"' print '#include "u_format_s3tc.h"' print '#include "u_format_rgtc.h"' + print '#include "u_format_latc.h"' print u_format_pack.generate(formats) diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c index 4f1b0e71934..4a1662462e5 100644 --- a/src/gallium/auxiliary/util/u_gen_mipmap.c +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c @@ -67,7 +67,7 @@ struct gen_mipmap_state struct pipe_vertex_element velem[2]; void *vs; - void *fs1d, *fs2d, *fs3d, *fsCube, *fs1da, *fs2da; + void *fs[TGSI_TEXTURE_COUNT]; /**< Not all are used, but simplifies code */ struct pipe_resource *vbuf; /**< quad vertices */ unsigned vbuf_slot; @@ -1301,34 +1301,6 @@ util_create_gen_mipmap(struct pipe_context *pipe, ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; } - /* vertex shader - still needed to specify mapping from fragment - * shader input semantics to vertex elements - */ - { - const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, - TGSI_SEMANTIC_GENERIC }; - const uint semantic_indexes[] = { 0, 0 }; - ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names, - semantic_indexes); - } - - /* fragment shader */ - ctx->fs1d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D, - TGSI_INTERPOLATE_LINEAR); - ctx->fs2d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D, - TGSI_INTERPOLATE_LINEAR); - ctx->fs3d = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D, - TGSI_INTERPOLATE_LINEAR); - ctx->fsCube = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE, - TGSI_INTERPOLATE_LINEAR); - if (pipe->screen->get_param(pipe->screen, PIPE_CAP_ARRAY_TEXTURES)) { - ctx->fs1da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D_ARRAY, - TGSI_INTERPOLATE_LINEAR); - ctx->fs2da = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D_ARRAY, - TGSI_INTERPOLATE_LINEAR); - } - - /* vertex data that doesn't change */ for (i = 0; i < 4; i++) { ctx->vertices[i][0][2] = 0.0f; /* z */ @@ -1343,6 +1315,44 @@ util_create_gen_mipmap(struct pipe_context *pipe, /** + * Helper function to set the fragment shaders. + */ +static INLINE void +set_fragment_shader(struct gen_mipmap_state *ctx, uint type) +{ + if (!ctx->fs[type]) + ctx->fs[type] = + util_make_fragment_tex_shader(ctx->pipe, type, + TGSI_INTERPOLATE_LINEAR); + + cso_set_fragment_shader_handle(ctx->cso, ctx->fs[type]); +} + + +/** + * Helper function to set the vertex shader. + */ +static INLINE void +set_vertex_shader(struct gen_mipmap_state *ctx) +{ + /* vertex shader - still required to provide the linkage between + * fragment shader input semantics and vertex_element/buffers. + */ + if (!ctx->vs) + { + const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, + TGSI_SEMANTIC_GENERIC }; + const uint semantic_indexes[] = { 0, 0 }; + ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, + semantic_names, + semantic_indexes); + } + + cso_set_vertex_shader_handle(ctx->cso, ctx->vs); +} + + +/** * Get next "slot" of vertex space in the vertex buffer. * We're allocating one large vertex buffer and using it piece by piece. */ @@ -1450,16 +1460,14 @@ void util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) { struct pipe_context *pipe = ctx->pipe; + unsigned i; + + for (i = 0; i < Elements(ctx->fs); i++) + if (ctx->fs[i]) + pipe->delete_fs_state(pipe, ctx->fs[i]); - if (ctx->fs2da) - pipe->delete_fs_state(pipe, ctx->fs2da); - if (ctx->fs1da) - pipe->delete_fs_state(pipe, ctx->fs1da); - pipe->delete_fs_state(pipe, ctx->fsCube); - pipe->delete_fs_state(pipe, ctx->fs3d); - pipe->delete_fs_state(pipe, ctx->fs2d); - pipe->delete_fs_state(pipe, ctx->fs1d); - pipe->delete_vs_state(pipe, ctx->vs); + if (ctx->vs) + pipe->delete_vs_state(pipe, ctx->vs); pipe_resource_reference(&ctx->vbuf, NULL); @@ -1498,9 +1506,9 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, struct pipe_screen *screen = pipe->screen; struct pipe_framebuffer_state fb; struct pipe_resource *pt = psv->texture; - void *fs; uint dstLevel; uint offset; + uint type; /* The texture object should have room for the levels which we're * about to generate. @@ -1515,31 +1523,31 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, switch (pt->target) { case PIPE_TEXTURE_1D: - fs = ctx->fs1d; + type = TGSI_TEXTURE_1D; break; case PIPE_TEXTURE_2D: - fs = ctx->fs2d; + type = TGSI_TEXTURE_2D; break; case PIPE_TEXTURE_3D: - fs = ctx->fs3d; + type = TGSI_TEXTURE_3D; break; case PIPE_TEXTURE_CUBE: - fs = ctx->fsCube; + type = TGSI_TEXTURE_CUBE; break; case PIPE_TEXTURE_1D_ARRAY: - fs = ctx->fs1da; + type = TGSI_TEXTURE_1D_ARRAY; break; case PIPE_TEXTURE_2D_ARRAY: - fs = ctx->fs2da; + type = TGSI_TEXTURE_2D_ARRAY; break; default: assert(0); - fs = ctx->fs2d; + type = TGSI_TEXTURE_2D; } /* check if we can render in the texture's format */ if (!screen->is_format_supported(screen, psv->format, pt->target, - pt->nr_samples, PIPE_BIND_RENDER_TARGET, 0)) { + pt->nr_samples, PIPE_BIND_RENDER_TARGET)) { fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); return; } @@ -1564,8 +1572,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, cso_set_clip(ctx->cso, &ctx->clip); cso_set_vertex_elements(ctx->cso, 2, ctx->velem); - cso_set_fragment_shader_handle(ctx->cso, fs); - cso_set_vertex_shader_handle(ctx->cso, ctx->vs); + set_fragment_shader(ctx, type); + set_vertex_shader(ctx); /* init framebuffer state */ memset(&fb, 0, sizeof(fb)); @@ -1660,8 +1668,6 @@ util_gen_mipmap(struct gen_mipmap_state *ctx, 4, /* verts */ 2); /* attribs/vert */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - /* need to signal that the texture has changed _after_ rendering to it */ pipe_surface_reference( &surf, NULL ); } diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 98889fb70ac..ddb81b5b957 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -299,13 +299,20 @@ pipe_buffer_write(struct pipe_context *pipe, const void *data) { struct pipe_box box; + unsigned usage = PIPE_TRANSFER_WRITE; + + if (offset == 0 && size == buf->width0) { + usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; + } else { + usage |= PIPE_TRANSFER_DISCARD_RANGE; + } u_box_1d(offset, size, &box); pipe->transfer_inline_write( pipe, buf, 0, - PIPE_TRANSFER_WRITE, + usage, &box, data, size, diff --git a/src/gallium/auxiliary/util/u_pstipple.c b/src/gallium/auxiliary/util/u_pstipple.c new file mode 100644 index 00000000000..f79a6938d1d --- /dev/null +++ b/src/gallium/auxiliary/util/u_pstipple.c @@ -0,0 +1,434 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * Polygon stipple helper module. Drivers/GPUs which don't support polygon + * stipple natively can use this module to simulate it. + * + * Basically, modify fragment shader to sample the 32x32 stipple pattern + * texture and do a fragment kill for the 'off' bits. + * + * This was originally a 'draw' module stage, but since we don't need + * vertex window coords or anything, it can be a stand-alone utility module. + * + * Authors: Brian Paul + */ + + +#include "pipe/p_context.h" +#include "pipe/p_defines.h" +#include "pipe/p_shader_tokens.h" +#include "util/u_inlines.h" + +#include "util/u_format.h" +#include "util/u_memory.h" +#include "util/u_pstipple.h" +#include "util/u_sampler.h" + +#include "tgsi/tgsi_transform.h" +#include "tgsi/tgsi_dump.h" + +/** Approx number of new tokens for instructions in pstip_transform_inst() */ +#define NUM_NEW_TOKENS 50 + + +static void +util_pstipple_update_stipple_texture(struct pipe_context *pipe, + struct pipe_resource *tex, + const uint32_t pattern[32]) +{ + static const uint bit31 = 1 << 31; + struct pipe_transfer *transfer; + ubyte *data; + int i, j; + + /* map texture memory */ + transfer = pipe_get_transfer(pipe, tex, 0, 0, + PIPE_TRANSFER_WRITE, 0, 0, 32, 32); + data = pipe->transfer_map(pipe, transfer); + + /* + * Load alpha texture. + * Note: 0 means keep the fragment, 255 means kill it. + * We'll negate the texel value and use KILP which kills if value + * is negative. + */ + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + if (pattern[i] & (bit31 >> j)) { + /* fragment "on" */ + data[i * transfer->stride + j] = 0; + } + else { + /* fragment "off" */ + data[i * transfer->stride + j] = 255; + } + } + } + + /* unmap */ + pipe->transfer_unmap(pipe, transfer); + pipe->transfer_destroy(pipe, transfer); +} + + +/** + * Create a 32x32 alpha8 texture that encodes the given stipple pattern. + */ +struct pipe_resource * +util_pstipple_create_stipple_texture(struct pipe_context *pipe, + const uint32_t pattern[32]) +{ + struct pipe_screen *screen = pipe->screen; + struct pipe_resource templat, *tex; + + memset(&templat, 0, sizeof(templat)); + templat.target = PIPE_TEXTURE_2D; + templat.format = PIPE_FORMAT_A8_UNORM; + templat.last_level = 0; + templat.width0 = 32; + templat.height0 = 32; + templat.depth0 = 1; + templat.array_size = 1; + templat.bind = PIPE_BIND_SAMPLER_VIEW; + + tex = screen->resource_create(screen, &templat); + + if (tex) + util_pstipple_update_stipple_texture(pipe, tex, pattern); + + return tex; +} + + +/** + * Create sampler view to sample the stipple texture. + */ +struct pipe_sampler_view * +util_pstipple_create_sampler_view(struct pipe_context *pipe, + struct pipe_resource *tex) +{ + struct pipe_sampler_view templat, *sv; + + u_sampler_view_default_template(&templat, tex, tex->format); + sv = pipe->create_sampler_view(pipe, tex, &templat); + + return sv; +} + + +/** + * Create the sampler CSO that'll be used for stippling. + */ +void * +util_pstipple_create_sampler(struct pipe_context *pipe) +{ + struct pipe_sampler_state templat; + void *s; + + memset(&templat, 0, sizeof(templat)); + templat.wrap_s = PIPE_TEX_WRAP_REPEAT; + templat.wrap_t = PIPE_TEX_WRAP_REPEAT; + templat.wrap_r = PIPE_TEX_WRAP_REPEAT; + templat.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + templat.min_img_filter = PIPE_TEX_FILTER_NEAREST; + templat.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + templat.normalized_coords = 1; + templat.min_lod = 0.0f; + templat.max_lod = 0.0f; + + s = pipe->create_sampler_state(pipe, &templat); + return s; +} + + + +/** + * Subclass of tgsi_transform_context, used for transforming the + * user's fragment shader to add the extra texture sample and fragment kill + * instructions. + */ +struct pstip_transform_context { + struct tgsi_transform_context base; + uint tempsUsed; /**< bitmask */ + int wincoordInput; + int maxInput; + uint samplersUsed; /**< bitfield of samplers used */ + int freeSampler; /** an available sampler for the pstipple */ + int texTemp; /**< temp registers */ + int numImmed; + boolean firstInstruction; +}; + + +/** + * TGSI declaration transform callback. + * Look for a free sampler, a free input attrib, and two free temp regs. + */ +static void +pstip_transform_decl(struct tgsi_transform_context *ctx, + struct tgsi_full_declaration *decl) +{ + struct pstip_transform_context *pctx = + (struct pstip_transform_context *) ctx; + + if (decl->Declaration.File == TGSI_FILE_SAMPLER) { + uint i; + for (i = decl->Range.First; + i <= decl->Range.Last; i++) { + pctx->samplersUsed |= 1 << i; + } + } + else if (decl->Declaration.File == TGSI_FILE_INPUT) { + pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last); + if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) + pctx->wincoordInput = (int) decl->Range.First; + } + else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { + uint i; + for (i = decl->Range.First; + i <= decl->Range.Last; i++) { + pctx->tempsUsed |= (1 << i); + } + } + + ctx->emit_declaration(ctx, decl); +} + + +static void +pstip_transform_immed(struct tgsi_transform_context *ctx, + struct tgsi_full_immediate *immed) +{ + struct pstip_transform_context *pctx = + (struct pstip_transform_context *) ctx; + pctx->numImmed++; +} + + +/** + * Find the lowest zero bit in the given word, or -1 if bitfield is all ones. + */ +static int +free_bit(uint bitfield) +{ + return ffs(~bitfield) - 1; +} + + +/** + * TGSI instruction transform callback. + * Replace writes to result.color w/ a temp reg. + * Upon END instruction, insert texture sampling code for antialiasing. + */ +static void +pstip_transform_inst(struct tgsi_transform_context *ctx, + struct tgsi_full_instruction *inst) +{ + struct pstip_transform_context *pctx = + (struct pstip_transform_context *) ctx; + + if (pctx->firstInstruction) { + /* emit our new declarations before the first instruction */ + + struct tgsi_full_declaration decl; + struct tgsi_full_instruction newInst; + uint i; + int wincoordInput; + + /* find free sampler */ + pctx->freeSampler = free_bit(pctx->samplersUsed); + if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) + pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; + + if (pctx->wincoordInput < 0) + wincoordInput = pctx->maxInput + 1; + else + wincoordInput = pctx->wincoordInput; + + /* find one free temp reg */ + for (i = 0; i < 32; i++) { + if ((pctx->tempsUsed & (1 << i)) == 0) { + /* found a free temp */ + if (pctx->texTemp < 0) + pctx->texTemp = i; + else + break; + } + } + assert(pctx->texTemp >= 0); + + if (pctx->wincoordInput < 0) { + /* declare new position input reg */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_INPUT; + decl.Declaration.Interpolate = TGSI_INTERPOLATE_LINEAR; + decl.Declaration.Semantic = 1; + decl.Semantic.Name = TGSI_SEMANTIC_POSITION; + decl.Semantic.Index = 0; + decl.Range.First = + decl.Range.Last = wincoordInput; + ctx->emit_declaration(ctx, &decl); + } + + /* declare new sampler */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_SAMPLER; + decl.Range.First = + decl.Range.Last = pctx->freeSampler; + ctx->emit_declaration(ctx, &decl); + + /* declare new temp regs */ + decl = tgsi_default_full_declaration(); + decl.Declaration.File = TGSI_FILE_TEMPORARY; + decl.Range.First = + decl.Range.Last = pctx->texTemp; + ctx->emit_declaration(ctx, &decl); + + /* emit immediate = {1/32, 1/32, 1, 1} + * The index/position of this immediate will be pctx->numImmed + */ + { + static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; + struct tgsi_full_immediate immed; + uint size = 4; + immed = tgsi_default_full_immediate(); + immed.Immediate.NrTokens = 1 + size; /* one for the token itself */ + immed.u[0].Float = value[0]; + immed.u[1].Float = value[1]; + immed.u[2].Float = value[2]; + immed.u[3].Float = value[3]; + ctx->emit_immediate(ctx, &immed); + } + + pctx->firstInstruction = FALSE; + + + /* + * Insert new MUL/TEX/KILP instructions at start of program + * Take gl_FragCoord, divide by 32 (stipple size), sample the + * texture and kill fragment if needed. + * + * We'd like to use non-normalized texcoords to index into a RECT + * texture, but we can only use REPEAT wrap mode with normalized + * texcoords. Darn. + */ + + /* XXX invert wincoord if origin isn't lower-left... */ + + /* MUL texTemp, INPUT[wincoord], 1/32; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_MUL; + newInst.Instruction.NumDstRegs = 1; + newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; + newInst.Dst[0].Register.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.Src[0].Register.File = TGSI_FILE_INPUT; + newInst.Src[0].Register.Index = wincoordInput; + newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE; + newInst.Src[1].Register.Index = pctx->numImmed; + ctx->emit_instruction(ctx, &newInst); + + /* TEX texTemp, texTemp, sampler; */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_TEX; + newInst.Instruction.NumDstRegs = 1; + newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; + newInst.Dst[0].Register.Index = pctx->texTemp; + newInst.Instruction.NumSrcRegs = 2; + newInst.Instruction.Texture = TRUE; + newInst.Texture.Texture = TGSI_TEXTURE_2D; + newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; + newInst.Src[0].Register.Index = pctx->texTemp; + newInst.Src[1].Register.File = TGSI_FILE_SAMPLER; + newInst.Src[1].Register.Index = pctx->freeSampler; + ctx->emit_instruction(ctx, &newInst); + + /* KIL -texTemp; # if -texTemp < 0, KILL fragment */ + newInst = tgsi_default_full_instruction(); + newInst.Instruction.Opcode = TGSI_OPCODE_KIL; + newInst.Instruction.NumDstRegs = 0; + newInst.Instruction.NumSrcRegs = 1; + newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; + newInst.Src[0].Register.Index = pctx->texTemp; + newInst.Src[0].Register.Negate = 1; + ctx->emit_instruction(ctx, &newInst); + } + + /* emit this instruction */ + ctx->emit_instruction(ctx, inst); +} + + +/** + * Given a fragment shader, return a new fragment shader which + * samples a stipple texture and executes KILL. + */ +struct pipe_shader_state * +util_pstipple_create_fragment_shader(struct pipe_context *pipe, + struct pipe_shader_state *fs, + unsigned *samplerUnitOut) +{ + struct pipe_shader_state *new_fs; + struct pstip_transform_context transform; + const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS; + + new_fs = MALLOC(sizeof(*new_fs)); + if (!new_fs) + return NULL; + + new_fs->tokens = tgsi_alloc_tokens(newLen); + if (!new_fs->tokens) { + FREE(new_fs); + return NULL; + } + + memset(&transform, 0, sizeof(transform)); + transform.wincoordInput = -1; + transform.maxInput = -1; + transform.texTemp = -1; + transform.firstInstruction = TRUE; + transform.base.transform_instruction = pstip_transform_inst; + transform.base.transform_declaration = pstip_transform_decl; + transform.base.transform_immediate = pstip_transform_immed; + + tgsi_transform_shader(fs->tokens, + (struct tgsi_token *) new_fs->tokens, + newLen, &transform.base); + +#if 0 /* DEBUG */ + tgsi_dump(fs->tokens, 0); + tgsi_dump(pstip_fs.tokens, 0); +#endif + + assert(transform.freeSampler < PIPE_MAX_SAMPLERS); + *samplerUnitOut = transform.freeSampler; + + return new_fs; +} + diff --git a/src/gallium/auxiliary/util/u_pstipple.h b/src/gallium/auxiliary/util/u_pstipple.h new file mode 100644 index 00000000000..1c2f5f48af4 --- /dev/null +++ b/src/gallium/auxiliary/util/u_pstipple.h @@ -0,0 +1,56 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#ifndef U_PSTIPPLE_H +#define U_PSTIPPLE_H + +#include "pipe/p_compiler.h" + +struct pipe_context; +struct pipe_resource; +struct pipe_shader_state; + + +extern struct pipe_resource * +util_pstipple_create_stipple_texture(struct pipe_context *pipe, + const uint32_t pattern[32]); + +extern struct pipe_sampler_view * +util_pstipple_create_sampler_view(struct pipe_context *pipe, + struct pipe_resource *tex); + +extern void * +util_pstipple_create_sampler(struct pipe_context *pipe); + +extern struct pipe_shader_state * +util_pstipple_create_fragment_shader(struct pipe_context *pipe, + struct pipe_shader_state *fs, + unsigned *samplerUnitOut); + + +#endif diff --git a/src/gallium/auxiliary/util/u_resource.c b/src/gallium/auxiliary/util/u_resource.c index ea6896b430f..50a7cd4d55b 100644 --- a/src/gallium/auxiliary/util/u_resource.c +++ b/src/gallium/auxiliary/util/u_resource.c @@ -24,14 +24,6 @@ void u_resource_destroy_vtbl(struct pipe_screen *screen, ur->vtbl->resource_destroy(screen, resource); } -unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, int layer) -{ - struct u_resource *ur = u_resource(resource); - return ur->vtbl->is_resource_referenced(pipe, resource, level, layer); -} - struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context, struct pipe_resource *resource, unsigned level, diff --git a/src/gallium/auxiliary/util/u_simple_screen.h b/src/gallium/auxiliary/util/u_simple_screen.h index 7139aaabc56..7caeb75cd27 100644 --- a/src/gallium/auxiliary/util/u_simple_screen.h +++ b/src/gallium/auxiliary/util/u_simple_screen.h @@ -159,7 +159,8 @@ struct pipe_winsys */ int (*fence_finish)( struct pipe_winsys *ws, struct pipe_fence_handle *fence, - unsigned flag ); + unsigned flags, + uint64_t timeout ); }; diff --git a/src/gallium/auxiliary/util/u_surface.c b/src/gallium/auxiliary/util/u_surface.c index 4eddd3f519e..9caf76c802b 100644 --- a/src/gallium/auxiliary/util/u_surface.c +++ b/src/gallium/auxiliary/util/u_surface.c @@ -84,7 +84,7 @@ util_create_rgba_surface(struct pipe_context *pipe, /* Choose surface format */ for (i = 0; rgbaFormats[i]; i++) { if (screen->is_format_supported(screen, rgbaFormats[i], - target, 0, bind, 0)) { + target, 0, bind)) { format = rgbaFormats[i]; break; } diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c index b6c63d9642f..7e72a59ee00 100644 --- a/src/gallium/auxiliary/util/u_transfer.c +++ b/src/gallium/auxiliary/util/u_transfer.c @@ -73,13 +73,6 @@ void u_default_transfer_flush_region( struct pipe_context *pipe, */ } -unsigned u_default_is_resource_referenced( struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, int layer) -{ - return 0; -} - struct pipe_transfer * u_default_get_transfer(struct pipe_context *context, struct pipe_resource *resource, unsigned level, diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h index 8cf9c418b04..5b5ddeb4aba 100644 --- a/src/gallium/auxiliary/util/u_transfer.h +++ b/src/gallium/auxiliary/util/u_transfer.h @@ -27,10 +27,6 @@ void u_default_transfer_flush_region( struct pipe_context *pipe, struct pipe_transfer *transfer, const struct pipe_box *box); -unsigned u_default_is_resource_referenced( struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, int layer); - struct pipe_transfer * u_default_get_transfer(struct pipe_context *context, struct pipe_resource *resource, unsigned level, @@ -57,10 +53,6 @@ struct u_resource_vtbl { void (*resource_destroy)(struct pipe_screen *, struct pipe_resource *pt); - unsigned (*is_resource_referenced)(struct pipe_context *pipe, - struct pipe_resource *texture, - unsigned level, int layer); - struct pipe_transfer *(*get_transfer)(struct pipe_context *, struct pipe_resource *resource, unsigned level, @@ -104,10 +96,6 @@ boolean u_resource_get_handle_vtbl(struct pipe_screen *screen, void u_resource_destroy_vtbl(struct pipe_screen *screen, struct pipe_resource *resource); -unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, int layer); - struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context, struct pipe_resource *resource, unsigned level, diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index dcf800a1e8e..9562acb8210 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -85,9 +85,9 @@ void u_upload_flush( struct u_upload_mgr *upload ) { /* Unmap and unreference the upload buffer. */ if (upload->transfer) { - if (upload->size) { + if (upload->offset) { pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer, - 0, upload->size); + 0, upload->offset); } pipe_transfer_unmap(upload->pipe, upload->transfer); pipe_transfer_destroy(upload->pipe, upload->transfer); diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c index 7d157c99ccc..521ac07747c 100644 --- a/src/gallium/auxiliary/util/u_vbuf_mgr.c +++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c @@ -87,27 +87,27 @@ static void u_vbuf_mgr_init_format_caps(struct u_vbuf_mgr_priv *mgr) mgr->caps.format_fixed32 = screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0); + 0, PIPE_BIND_VERTEX_BUFFER); mgr->caps.format_float16 = screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0); + 0, PIPE_BIND_VERTEX_BUFFER); mgr->caps.format_float64 = screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0); + 0, PIPE_BIND_VERTEX_BUFFER); mgr->caps.format_norm32 = screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0) && + 0, PIPE_BIND_VERTEX_BUFFER) && screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0); + 0, PIPE_BIND_VERTEX_BUFFER); mgr->caps.format_scaled32 = screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0) && + 0, PIPE_BIND_VERTEX_BUFFER) && screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER, - 0, PIPE_BIND_VERTEX_BUFFER, 0); + 0, PIPE_BIND_VERTEX_BUFFER); } struct u_vbuf_mgr * @@ -170,6 +170,7 @@ static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr, /* Initialize the translate key, i.e. the recipe how vertices should be * translated. */ + memset(&key, 0, sizeof key); for (i = 0; i < mgr->ve->count; i++) { struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[mgr->ve->ve[i].vertex_buffer_index]; diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index d1ba5faf788..c54e5476f3a 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -618,7 +618,7 @@ void vl_compositor_render(struct vl_compositor *compositor, draw_layers(compositor, src_surface, src_area, dst_area); assert(!compositor->dirty_bg && !compositor->dirty_layers); - compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence); + compositor->pipe->flush(compositor->pipe, fence); } void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat) diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_context.c b/src/gallium/auxiliary/vl/vl_mpeg12_context.c index ce1c158e828..74893ab4e3a 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_context.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_context.c @@ -265,13 +265,9 @@ vl_mpeg12_is_format_supported(struct pipe_video_context *vpipe, assert(vpipe); - /* XXX: Temporary; not all paths are NPOT-tested */ - if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO) - return FALSE; - - - return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format, PIPE_TEXTURE_2D, - 0, usage, geom); + return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format, + PIPE_TEXTURE_2D, + 0, usage); } static void diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c index 0e5a21c18b6..d45b0642e3c 100644 --- a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c +++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c @@ -681,7 +681,7 @@ vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mp util_draw_arrays_instanced(renderer->pipe, PIPE_PRIM_QUADS, 0, 4, empty_start_instance, empty_num_instances); - renderer->pipe->flush(renderer->pipe, PIPE_FLUSH_RENDER_CACHE, buffer->fence); + renderer->pipe->flush(renderer->pipe, buffer->fence); /* Next time we get this surface it may have new ref frames */ pipe_surface_reference(&buffer->surface, NULL); diff --git a/src/gallium/docs/d3d11ddi.txt b/src/gallium/docs/d3d11ddi.txt index 0a9e7e50f1d..b5a06b4b943 100644 --- a/src/gallium/docs/d3d11ddi.txt +++ b/src/gallium/docs/d3d11ddi.txt @@ -453,8 +453,8 @@ SetVertexPipelineOutput (D3D10.1+ only) SetViewports - Gallium lacks support for multiple geometry-shader-selectable viewports D3D11 has -ShaderResourceViewReadAfterWriteHazard -> flush(PIPE_FLUSH_RENDER_CACHE) - - Gallium does not support specifying this per-render-target/view +ShaderResourceViewReadAfterWriteHazard + - Gallium lacks support for this SoSetTargets -> set_stream_output_buffers diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index c6812cd309e..b0229c70f20 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -408,6 +408,16 @@ The width0 is redefined to ``MAX2(width0, offset+size)``. +.. _texture_barrier + +texture_barrier +%%%%%%%%%%%%%%% + +This function flushes all pending writes to the currently-set surfaces and +invalidates all read caches of the currently-set samplers. + + + .. _pipe_transfer: PIPE_TRANSFER diff --git a/src/gallium/drivers/cell/ppu/cell_context.c b/src/gallium/drivers/cell/ppu/cell_context.c index f9b83c8666c..58e647a39fa 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.c +++ b/src/gallium/drivers/cell/ppu/cell_context.c @@ -104,18 +104,6 @@ static const struct debug_named_value cell_debug_flags[] = { DEBUG_NAMED_VALUE_END }; -static unsigned int -cell_is_resource_referenced( struct pipe_context *pipe, - struct pipe_resource *texture, - unsigned level, int layer) -{ - /** - * FIXME: Optimize. - */ - - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} - struct pipe_context * cell_create_context(struct pipe_screen *screen, @@ -140,8 +128,6 @@ cell_create_context(struct pipe_screen *screen, cell->pipe.clear = cell_clear; cell->pipe.flush = cell_flush; - cell->pipe.is_resource_referenced = cell_is_resource_referenced; - #if 0 cell->pipe.begin_query = cell_begin_query; cell->pipe.end_query = cell_end_query; diff --git a/src/gallium/drivers/cell/ppu/cell_fence.c b/src/gallium/drivers/cell/ppu/cell_fence.c index e7c9fc46d9f..181fef44f45 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.c +++ b/src/gallium/drivers/cell/ppu/cell_fence.c @@ -59,9 +59,10 @@ cell_fence_signalled(const struct cell_context *cell, } -void +boolean cell_fence_finish(const struct cell_context *cell, - const struct cell_fence *fence) + const struct cell_fence *fence, + uint64_t timeout) { while (!cell_fence_signalled(cell, fence)) { usleep(10); @@ -75,6 +76,7 @@ cell_fence_finish(const struct cell_context *cell, } } #endif + return TRUE; } diff --git a/src/gallium/drivers/cell/ppu/cell_fence.h b/src/gallium/drivers/cell/ppu/cell_fence.h index 536b4ba411a..3568230b1c0 100644 --- a/src/gallium/drivers/cell/ppu/cell_fence.h +++ b/src/gallium/drivers/cell/ppu/cell_fence.h @@ -36,12 +36,15 @@ cell_fence_init(struct cell_fence *fence); extern boolean cell_fence_signalled(const struct cell_context *cell, - const struct cell_fence *fence); + const struct cell_fence *fence, + unsigned flags); -extern void +extern boolean cell_fence_finish(const struct cell_context *cell, - const struct cell_fence *fence); + const struct cell_fence *fence, + unsigned flags, + uint64_t timeout); diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c index 8275c9dc9c7..463f4d03eb9 100644 --- a/src/gallium/drivers/cell/ppu/cell_flush.c +++ b/src/gallium/drivers/cell/ppu/cell_flush.c @@ -38,19 +38,16 @@ * Called via pipe->flush() */ void -cell_flush(struct pipe_context *pipe, unsigned flags, +cell_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence) { struct cell_context *cell = cell_context(pipe); if (fence) { *fence = NULL; - /* XXX: Implement real fencing */ - flags |= CELL_FLUSH_WAIT; } - if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_RENDER_CACHE)) - flags |= CELL_FLUSH_WAIT; + flags |= CELL_FLUSH_WAIT; draw_flush( cell->draw ); cell_flush_int(cell, flags); diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 8d2b4b96438..0ee124a24fc 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -149,8 +149,7 @@ cell_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags ) + unsigned tex_usage) { struct sw_winsys *winsys = cell_screen(screen)->winsys; diff --git a/src/gallium/drivers/failover/fo_context.c b/src/gallium/drivers/failover/fo_context.c index d60718d9716..0fefec9aaea 100644 --- a/src/gallium/drivers/failover/fo_context.c +++ b/src/gallium/drivers/failover/fo_context.c @@ -79,7 +79,7 @@ static void failover_draw_vbo( struct pipe_context *pipe, if (failover->mode == FO_SW) { if (failover->dirty) { - failover->hw->flush( failover->hw, ~0, NULL ); + failover->hw->flush( failover->hw, NULL ); failover_state_emit( failover ); } @@ -89,22 +89,10 @@ static void failover_draw_vbo( struct pipe_context *pipe, * intervening flush. Unlikely to be much performance impact to * this: */ - failover->sw->flush( failover->sw, ~0, NULL ); + failover->sw->flush( failover->sw, NULL ); } } -static unsigned int -failover_is_resource_referenced( struct pipe_context *_pipe, - struct pipe_resource *resource, - unsigned level, int layer) -{ - struct failover_context *failover = failover_context( _pipe ); - struct pipe_context *pipe = (failover->mode == FO_HW) ? - failover->hw : failover->sw; - - return pipe->is_resource_referenced(pipe, resource, level, layer); -} - struct pipe_context *failover_create( struct pipe_context *hw, struct pipe_context *sw ) { @@ -150,7 +138,6 @@ struct pipe_context *failover_create( struct pipe_context *hw, #endif failover->pipe.flush = hw->flush; - failover->pipe.is_resource_referenced = failover_is_resource_referenced; failover->dirty = 0; diff --git a/src/gallium/drivers/galahad/glhd_context.c b/src/gallium/drivers/galahad/glhd_context.c index 75e4c253dd9..813a21e2ee3 100644 --- a/src/gallium/drivers/galahad/glhd_context.c +++ b/src/gallium/drivers/galahad/glhd_context.c @@ -761,34 +761,15 @@ galahad_clear_depth_stencil(struct pipe_context *_pipe, static void galahad_flush(struct pipe_context *_pipe, - unsigned flags, struct pipe_fence_handle **fence) { struct galahad_context *glhd_pipe = galahad_context(_pipe); struct pipe_context *pipe = glhd_pipe->pipe; pipe->flush(pipe, - flags, fence); } -static unsigned int -galahad_is_resource_referenced(struct pipe_context *_pipe, - struct pipe_resource *_resource, - unsigned level, - int layer) -{ - struct galahad_context *glhd_pipe = galahad_context(_pipe); - struct galahad_resource *glhd_resource = galahad_resource(_resource); - struct pipe_context *pipe = glhd_pipe->pipe; - struct pipe_resource *resource = glhd_resource->resource; - - return pipe->is_resource_referenced(pipe, - resource, - level, - layer); -} - static struct pipe_sampler_view * galahad_context_create_sampler_view(struct pipe_context *_pipe, struct pipe_resource *_resource, @@ -1038,7 +1019,6 @@ galahad_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) glhd_pipe->base.clear_render_target = galahad_clear_render_target; glhd_pipe->base.clear_depth_stencil = galahad_clear_depth_stencil; glhd_pipe->base.flush = galahad_flush; - glhd_pipe->base.is_resource_referenced = galahad_is_resource_referenced; glhd_pipe->base.create_sampler_view = galahad_context_create_sampler_view; glhd_pipe->base.sampler_view_destroy = galahad_context_sampler_view_destroy; glhd_pipe->base.create_surface = galahad_context_create_surface; diff --git a/src/gallium/drivers/galahad/glhd_screen.c b/src/gallium/drivers/galahad/glhd_screen.c index b4825bef66d..b4edebe4920 100644 --- a/src/gallium/drivers/galahad/glhd_screen.c +++ b/src/gallium/drivers/galahad/glhd_screen.c @@ -106,8 +106,7 @@ galahad_screen_is_format_supported(struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) + unsigned tex_usage) { struct galahad_screen *glhd_screen = galahad_screen(_screen); struct pipe_screen *screen = glhd_screen->screen; @@ -120,8 +119,7 @@ galahad_screen_is_format_supported(struct pipe_screen *_screen, format, target, sample_count, - tex_usage, - geom_flags); + tex_usage); } static struct pipe_context * @@ -276,30 +274,28 @@ galahad_screen_fence_reference(struct pipe_screen *_screen, fence); } -static int +static boolean galahad_screen_fence_signalled(struct pipe_screen *_screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { struct galahad_screen *glhd_screen = galahad_screen(_screen); struct pipe_screen *screen = glhd_screen->screen; return screen->fence_signalled(screen, - fence, - flags); + fence); } -static int +static boolean galahad_screen_fence_finish(struct pipe_screen *_screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { struct galahad_screen *glhd_screen = galahad_screen(_screen); struct pipe_screen *screen = glhd_screen->screen; return screen->fence_finish(screen, fence, - flags); + timeout); } struct pipe_screen * diff --git a/src/gallium/drivers/i915/TODO b/src/gallium/drivers/i915/TODO index f4e1423fa59..fba180064c3 100644 --- a/src/gallium/drivers/i915/TODO +++ b/src/gallium/drivers/i915/TODO @@ -12,22 +12,19 @@ Random list of problems with i915g: unusable :( Upgrading xserver helped here, it doesn't crash anymore. Still broken, it doesn't update the viewport/get new buffers. -- Tends to hang the chip after a few minutes of openarena. Looks tiling related, - at the last frame rendered has tiling corruption over the complete frame. - - Kills the chip in 3D_PRIMITIVE LINELIST with mesa-demos/fbotexture in - wireframe mode. - -- Tiling is funny: If unlucky, it renders/samples all black. No clue yet what's - going on. Seems to depend on tiny details like whethever the sampler - relocation is fenced/unfenced (broken _with_ fenced reloc using tiling bits!). + wireframe mode. Changing the cullmode to cw from none mitigates the crash. As + does emitting only one line segment (2 indices) per 3D_PRIMITIVE command in + the batch. - Y-tiling is even more fun. i915c doesn't use it, maybe there's a reason? Texture sampling from Y-tiled buffers seems to work, though (save above problems). + RESOLVED: Y-tiling works with the render engine, but not with the blitter. + Use u_blitter and hw clears (PRIM3D_CLEAR_RECT). -- Need to validate buffers before usage. Currently do_exec on the batchbuffer - can fail with -ENOSPC. +- src/xvmc/i915_structs.h in xf86-video-intel has a few more bits of various + commands defined. Scavenge them and see what's useful. Other bugs can be found here: https://bugs.freedesktop.org/buglist.cgi?bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&component=Drivers/Gallium/i915g diff --git a/src/gallium/drivers/i915/i915_batch.h b/src/gallium/drivers/i915/i915_batch.h index 039c8713570..ce2691b2fd7 100644 --- a/src/gallium/drivers/i915/i915_batch.h +++ b/src/gallium/drivers/i915/i915_batch.h @@ -37,6 +37,9 @@ #define OUT_BATCH(dword) \ i915_winsys_batchbuffer_dword(i915->batch, dword) +#define OUT_BATCH_F(f) \ + i915_winsys_batchbuffer_float(i915->batch, f) + #define OUT_RELOC(buf, usage, offset) \ i915_winsys_batchbuffer_reloc(i915->batch, buf, usage, offset, false) diff --git a/src/gallium/drivers/i915/i915_batchbuffer.h b/src/gallium/drivers/i915/i915_batchbuffer.h index 9df82272604..78554034781 100644 --- a/src/gallium/drivers/i915/i915_batchbuffer.h +++ b/src/gallium/drivers/i915/i915_batchbuffer.h @@ -55,6 +55,16 @@ i915_winsys_batchbuffer_dword_unchecked(struct i915_winsys_batchbuffer *batch, } static INLINE void +i915_winsys_batchbuffer_float(struct i915_winsys_batchbuffer *batch, + float f) +{ + union { float f; unsigned int ui; } uif; + uif.f = f; + assert (i915_winsys_batchbuffer_space(batch) >= 4); + i915_winsys_batchbuffer_dword_unchecked(batch, uif.ui); +} + +static INLINE void i915_winsys_batchbuffer_dword(struct i915_winsys_batchbuffer *batch, unsigned dword) { diff --git a/src/gallium/drivers/i915/i915_clear.c b/src/gallium/drivers/i915/i915_clear.c index 6d824a507aa..4a97746e981 100644 --- a/src/gallium/drivers/i915/i915_clear.c +++ b/src/gallium/drivers/i915/i915_clear.c @@ -31,17 +31,118 @@ #include "util/u_clear.h" +#include "util/u_format.h" +#include "util/u_pack_color.h" #include "i915_context.h" +#include "i915_screen.h" +#include "i915_reg.h" +#include "i915_batch.h" +#include "i915_resource.h" +#include "i915_state.h" +void +i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil, + unsigned destx, unsigned desty, unsigned width, unsigned height) +{ + struct i915_context *i915 = i915_context(pipe); + uint32_t clear_params, clear_color, clear_depth, clear_stencil, + clear_color8888, packed_z_stencil; + union util_color u_color; + float f_depth = depth; + struct i915_texture *cbuf_tex, *depth_tex; + + cbuf_tex = depth_tex = NULL; + clear_params = 0; + + if (buffers & PIPE_CLEAR_COLOR) { + struct pipe_surface *cbuf = i915->framebuffer.cbufs[0]; + + clear_params |= CLEARPARAM_WRITE_COLOR; + cbuf_tex = i915_texture(cbuf->texture); + util_pack_color(rgba, cbuf->format, &u_color); + if (util_format_get_blocksize(cbuf_tex->b.b.format) == 4) + clear_color = u_color.ui; + else + clear_color = (u_color.ui & 0xffff) | (u_color.ui << 16); + + util_pack_color(rgba, PIPE_FORMAT_B8G8R8A8_UNORM, &u_color); + clear_color8888 = u_color.ui; + } else + clear_color = clear_color8888 = 0; + + clear_depth = clear_stencil = 0; + if (buffers & PIPE_CLEAR_DEPTH) { + struct pipe_surface *zbuf = i915->framebuffer.zsbuf; + + clear_params |= CLEARPARAM_WRITE_DEPTH; + depth_tex = i915_texture(zbuf->texture); + packed_z_stencil = util_pack_z_stencil(depth_tex->b.b.format, depth, stencil); + + if (util_format_get_blocksize(depth_tex->b.b.format) == 4) { + /* Avoid read-modify-write if there's no stencil. */ + if (buffers & PIPE_CLEAR_STENCIL + || depth_tex->b.b.format != PIPE_FORMAT_Z24_UNORM_S8_USCALED) { + clear_params |= CLEARPARAM_WRITE_STENCIL; + clear_stencil = packed_z_stencil & 0xff; + clear_depth = packed_z_stencil; + } else + clear_depth = packed_z_stencil & 0xffffff00; + } else { + clear_depth = (clear_depth & 0xffff) | (clear_depth << 16); + } + } + + if (i915->hardware_dirty) + i915_emit_hardware_state(i915); + + if (!BEGIN_BATCH(7 + 7)) { + FLUSH_BATCH(NULL); + + i915_emit_hardware_state(i915); + i915->vbo_flushed = 1; + + assert(BEGIN_BATCH(7 + 7)); + } + + OUT_BATCH(_3DSTATE_CLEAR_PARAMETERS); + OUT_BATCH(clear_params | CLEARPARAM_CLEAR_RECT); + OUT_BATCH(clear_color); + OUT_BATCH(clear_depth); + OUT_BATCH(clear_color8888); + OUT_BATCH_F(f_depth); + OUT_BATCH(clear_stencil); + + OUT_BATCH(_3DPRIMITIVE | PRIM3D_CLEAR_RECT | 5); + OUT_BATCH_F(destx + width); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty + height); + OUT_BATCH_F(destx); + OUT_BATCH_F(desty); +} /** * Clear the given buffers to the specified values. * No masking, no scissor (clear entire buffer). */ void -i915_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba, - double depth, unsigned stencil) +i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) { util_clear(pipe, &i915_context(pipe)->framebuffer, buffers, rgba, depth, stencil); } + +void +i915_clear_render(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil) +{ + struct i915_context *i915 = i915_context(pipe); + + if (i915->dirty) + i915_update_derived(i915); + + i915_clear_emit(pipe, buffers, rgba, depth, stencil, + 0, 0, i915->framebuffer.width, i915->framebuffer.height); +} diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index 84c8cb54436..7a98ef73c1f 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -103,6 +103,9 @@ static void i915_destroy(struct pipe_context *pipe) int i; draw_destroy(i915->draw); + + if (i915->blitter) + util_blitter_destroy(i915->blitter); if(i915->batch) i915->iws->batchbuffer_destroy(i915->batch); @@ -137,7 +140,10 @@ i915_create_context(struct pipe_screen *screen, void *priv) i915->base.destroy = i915_destroy; - i915->base.clear = i915_clear; + if (i915_screen(screen)->debug.use_blitter) + i915->base.clear = i915_clear_blitter; + else + i915->base.clear = i915_clear_render; i915->base.draw_vbo = i915_draw_vbo; @@ -145,6 +151,10 @@ i915_create_context(struct pipe_screen *screen, void *priv) util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer), 16, UTIL_SLAB_SINGLETHREADED); + /* Batch stream debugging is a bit hacked up at the moment: + */ + i915->batch = i915->iws->batchbuffer_create(i915->iws); + /* * Create drawing context and plug our rendering stage into it. */ @@ -164,15 +174,19 @@ i915_create_context(struct pipe_screen *screen, void *priv) draw_install_aaline_stage(i915->draw, &i915->base); draw_install_aapoint_stage(i915->draw, &i915->base); + /* augmented draw pipeline clobbers state functions */ + i915_init_fixup_state_functions(i915); + + /* Create blitter last - calls state creation functions. */ + i915->blitter = util_blitter_create(&i915->base); + assert(i915->blitter); + i915->dirty = ~0; i915->hardware_dirty = ~0; i915->immediate_dirty = ~0; i915->dynamic_dirty = ~0; + i915->static_dirty = ~0; i915->flush_dirty = 0; - /* Batch stream debugging is a bit hacked up at the moment: - */ - i915->batch = i915->iws->batchbuffer_create(i915->iws); - return &i915->base; } diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 1da637d068e..dacf50e870d 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -38,6 +38,7 @@ #include "tgsi/tgsi_scan.h" #include "util/u_slab.h" +#include "util/u_blitter.h" struct i915_winsys; @@ -185,7 +186,7 @@ struct i915_rasterizer_state { unsigned LIS7; unsigned sc[1]; - const struct pipe_rasterizer_state *templ; + struct pipe_rasterizer_state templ; union { float f; unsigned u; } ds[2]; }; @@ -244,14 +245,35 @@ struct i915_context { struct i915_state current; unsigned hardware_dirty; - unsigned immediate_dirty; - unsigned dynamic_dirty; - unsigned flush_dirty; + unsigned immediate_dirty : I915_MAX_IMMEDIATE; + unsigned dynamic_dirty : I915_MAX_DYNAMIC; + unsigned static_dirty : 4; + unsigned flush_dirty : 2; struct i915_winsys_buffer *validation_buffers[2 + 1 + I915_TEX_UNITS]; int num_validation_buffers; struct util_slab_mempool transfer_pool; + + /** blitter/hw-clear */ + struct blitter_context* blitter; + + /** State tracking needed by u_blitter for save/restore. */ + void *saved_fs; + void (*saved_bind_fs_state)(struct pipe_context *pipe, void *shader); + void *saved_vs; + struct pipe_clip_state saved_clip; + struct i915_velems_state *saved_velems; + unsigned saved_nr_vertex_buffers; + struct pipe_vertex_buffer saved_vertex_buffers[PIPE_MAX_ATTRIBS]; + unsigned saved_nr_samplers; + void *saved_samplers[PIPE_MAX_SAMPLERS]; + void (*saved_bind_sampler_states)(struct pipe_context *pipe, + unsigned num, void **sampler); + unsigned saved_nr_sampler_views; + struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; + void (*saved_set_sampler_views)(struct pipe_context *pipe, + unsigned num, struct pipe_sampler_view **views); }; /* A flag for each state_tracker state object: @@ -296,6 +318,12 @@ struct i915_context { #define I915_FLUSH_CACHE 1 #define I915_PIPELINE_FLUSH 2 +/* split up static state */ +#define I915_DST_BUF_COLOR 1 +#define I915_DST_BUF_DEPTH 2 +#define I915_DST_VARS 4 +#define I915_DST_RECT 8 + static INLINE void i915_set_flush_dirty(struct i915_context *i915, unsigned flush) { @@ -326,14 +354,20 @@ void i915_emit_hardware_state(struct i915_context *i915 ); /*********************************************************************** * i915_clear.c: */ -void i915_clear( struct pipe_context *pipe, unsigned buffers, const float *rgba, - double depth, unsigned stencil); +void i915_clear_blitter(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); +void i915_clear_render(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil); +void i915_clear_emit(struct pipe_context *pipe, unsigned buffers, const float *rgba, + double depth, unsigned stencil, + unsigned destx, unsigned desty, unsigned width, unsigned height); /*********************************************************************** * */ void i915_init_state_functions( struct i915_context *i915 ); +void i915_init_fixup_state_functions( struct i915_context *i915 ); void i915_init_flush_functions( struct i915_context *i915 ); void i915_init_string_functions( struct i915_context *i915 ); diff --git a/src/gallium/drivers/i915/i915_debug.c b/src/gallium/drivers/i915/i915_debug.c index 1713bf131f2..c4eed473e90 100644 --- a/src/gallium/drivers/i915/i915_debug.c +++ b/src/gallium/drivers/i915/i915_debug.c @@ -46,17 +46,18 @@ static const struct debug_named_value debug_options[] = { }; unsigned i915_debug = 0; -boolean i915_tiling = TRUE; DEBUG_GET_ONCE_FLAGS_OPTION(i915_debug, "I915_DEBUG", debug_options, 0) DEBUG_GET_ONCE_BOOL_OPTION(i915_no_tiling, "I915_NO_TILING", FALSE) DEBUG_GET_ONCE_BOOL_OPTION(i915_lie, "I915_LIE", FALSE) +DEBUG_GET_ONCE_BOOL_OPTION(i915_use_blitter, "I915_USE_BLITTER", FALSE) void i915_debug_init(struct i915_screen *is) { i915_debug = debug_get_option_i915_debug(); is->debug.tiling = !debug_get_option_i915_no_tiling(); is->debug.lie = debug_get_option_i915_lie(); + is->debug.use_blitter = debug_get_option_i915_use_blitter(); } diff --git a/src/gallium/drivers/i915/i915_flush.c b/src/gallium/drivers/i915/i915_flush.c index f2044d661e3..b4e81147c4f 100644 --- a/src/gallium/drivers/i915/i915_flush.c +++ b/src/gallium/drivers/i915/i915_flush.c @@ -39,34 +39,12 @@ static void i915_flush_pipe( struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); -#if 0 - /* Do we need to emit an MI_FLUSH command to flush the hardware - * caches? - */ - if (flags & (PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE)) { - unsigned flush = MI_FLUSH; - - if (!(flags & PIPE_FLUSH_RENDER_CACHE)) - flush |= INHIBIT_FLUSH_RENDER_CACHE; - - if (flags & PIPE_FLUSH_TEXTURE_CACHE) - flush |= FLUSH_MAP_CACHE; - - if (!BEGIN_BATCH(1)) { - FLUSH_BATCH(NULL); - assert(BEGIN_BATCH(1)); - } - OUT_BATCH( flush ); - } -#endif - if (i915->batch->map == i915->batch->ptr) { return; } @@ -96,6 +74,7 @@ void i915_flush(struct i915_context *i915, struct pipe_fence_handle **fence) i915->hardware_dirty = ~0; i915->immediate_dirty = ~0; i915->dynamic_dirty = ~0; + i915->static_dirty = ~0; /* kernel emits flushes in between batchbuffers */ i915->flush_dirty = 0; } diff --git a/src/gallium/drivers/i915/i915_prim_emit.c b/src/gallium/drivers/i915/i915_prim_emit.c index 276e33d4b9d..85656cd7846 100644 --- a/src/gallium/drivers/i915/i915_prim_emit.c +++ b/src/gallium/drivers/i915/i915_prim_emit.c @@ -149,7 +149,6 @@ emit_prim( struct draw_stage *stage, /* Make sure state is re-emitted after a flush: */ - i915_update_derived( i915 ); i915_emit_hardware_state( i915 ); if (!BEGIN_BATCH( 1 + nr * vertex_size / 4)) { diff --git a/src/gallium/drivers/i915/i915_prim_vbuf.c b/src/gallium/drivers/i915/i915_prim_vbuf.c index fb4c0516dd8..79db3b650eb 100644 --- a/src/gallium/drivers/i915/i915_prim_vbuf.c +++ b/src/gallium/drivers/i915/i915_prim_vbuf.c @@ -470,7 +470,6 @@ draw_arrays_fallback(struct vbuf_render *render, /* Make sure state is re-emitted after a flush: */ - i915_update_derived(i915); i915_emit_hardware_state(i915); i915->vbo_flushed = 1; @@ -519,7 +518,6 @@ i915_vbuf_render_draw_arrays(struct vbuf_render *render, /* Make sure state is re-emitted after a flush: */ - i915_update_derived(i915); i915_emit_hardware_state(i915); i915->vbo_flushed = 1; @@ -640,7 +638,6 @@ i915_vbuf_render_draw_elements(struct vbuf_render *render, /* Make sure state is re-emitted after a flush: */ - i915_update_derived(i915); i915_emit_hardware_state(i915); i915->vbo_flushed = 1; diff --git a/src/gallium/drivers/i915/i915_reg.h b/src/gallium/drivers/i915/i915_reg.h index 5e4e80ddf6b..6fe032cdb6e 100644 --- a/src/gallium/drivers/i915/i915_reg.h +++ b/src/gallium/drivers/i915/i915_reg.h @@ -148,6 +148,7 @@ /* p161 */ #define _3DSTATE_DST_BUF_VARS_CMD (CMD_3D | (0x1d<<24) | (0x85<<16)) /* Dword 1 */ +#define CLASSIC_EARLY_DEPTH (1<<31) #define TEX_DEFAULT_COLOR_OGL (0<<30) #define TEX_DEFAULT_COLOR_D3D (1<<30) #define ZR_EARLY_DEPTH (1<<29) diff --git a/src/gallium/drivers/i915/i915_resource.c b/src/gallium/drivers/i915/i915_resource.c index 499233ceb9b..7f52ba11d61 100644 --- a/src/gallium/drivers/i915/i915_resource.c +++ b/src/gallium/drivers/i915/i915_resource.c @@ -31,7 +31,6 @@ i915_resource_from_handle(struct pipe_screen * screen, void i915_init_resource_functions(struct i915_context *i915 ) { - i915->base.is_resource_referenced = u_default_is_resource_referenced; i915->base.get_transfer = u_get_transfer_vtbl; i915->base.transfer_map = u_transfer_map_vtbl; i915->base.transfer_flush_region = u_transfer_flush_region_vtbl; diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c index 51482f54fc4..77c03450b3a 100644 --- a/src/gallium/drivers/i915/i915_resource_buffer.c +++ b/src/gallium/drivers/i915/i915_resource_buffer.c @@ -123,7 +123,6 @@ struct u_resource_vtbl i915_buffer_vtbl = { i915_buffer_get_handle, /* get_handle */ i915_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ i915_get_transfer, /* get_transfer */ i915_transfer_destroy, /* transfer_destroy */ i915_buffer_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/i915/i915_resource_texture.c b/src/gallium/drivers/i915/i915_resource_texture.c index aad5235a6ad..7816925d230 100644 --- a/src/gallium/drivers/i915/i915_resource_texture.c +++ b/src/gallium/drivers/i915/i915_resource_texture.c @@ -184,7 +184,10 @@ i915_texture_tiling(struct i915_screen *is, struct i915_texture *tex) /* XXX X-tiling might make sense */ return I915_TILE_NONE; - return I915_TILE_X; + if (is->debug.use_blitter) + return I915_TILE_X; + else + return I915_TILE_Y; } @@ -756,6 +759,9 @@ i915_texture_transfer_map(struct pipe_context *pipe, assert(box->z == 0); offset = i915_texture_offset(tex, transfer->level, box->z); + /* TODO this is a sledgehammer */ + pipe->flush(pipe, NULL); + map = iws->buffer_map(iws, tex->buffer, (transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE); if (map == NULL) @@ -781,7 +787,6 @@ struct u_resource_vtbl i915_texture_vtbl = { i915_texture_get_handle, /* get_handle */ i915_texture_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ i915_texture_get_transfer, /* get_transfer */ i915_transfer_destroy, /* transfer_destroy */ i915_texture_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c index 77febbf5012..e62b609eb5a 100644 --- a/src/gallium/drivers/i915/i915_screen.c +++ b/src/gallium/drivers/i915/i915_screen.c @@ -105,6 +105,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) switch (cap) { /* Supported features (boolean caps). */ case PIPE_CAP_ANISOTROPIC_FILTER: + case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: case PIPE_CAP_NPOT_TEXTURES: case PIPE_CAP_PRIMITIVE_RESTART: /* draw module */ case PIPE_CAP_TEXTURE_MIRROR_REPEAT: @@ -115,17 +116,18 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) /* Features that should be supported (boolean caps). */ /* XXX: Just test the code */ case PIPE_CAP_BLEND_EQUATION_SEPARATE: - return 0; + /* XXX: No code but hw supports it */ + case PIPE_CAP_POINT_SPRITE: + /* Also lie about these when asked to (needed for GLSL / GL 2.0) */ + return is->debug.lie ? 1 : 0; /* Unsupported features (boolean caps). */ case PIPE_CAP_ARRAY_TEXTURES: case PIPE_CAP_DEPTH_CLAMP: - case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: /* disable for now */ - case PIPE_CAP_GLSL: case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_INDEP_BLEND_FUNC: - case PIPE_CAP_INSTANCED_DRAWING: /* draw module? */ - case PIPE_CAP_POINT_SPRITE: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: case PIPE_CAP_SHADER_STENCIL_EXPORT: case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_SWIZZLE: @@ -133,6 +135,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap cap) return 0; /* Features we can lie about (boolean caps). */ + case PIPE_CAP_GLSL: case PIPE_CAP_OCCLUSION_QUERY: return is->debug.lie ? 1 : 0; @@ -249,8 +252,7 @@ i915_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) + unsigned tex_usage) { static const enum pipe_format tex_supported[] = { PIPE_FORMAT_B8G8R8A8_UNORM, @@ -317,24 +319,23 @@ i915_fence_reference(struct pipe_screen *screen, is->iws->fence_reference(is->iws, ptr, fence); } -static int +static boolean i915_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { struct i915_screen *is = i915_screen(screen); - return is->iws->fence_signalled(is->iws, fence); + return is->iws->fence_signalled(is->iws, fence) == 0; } -static int +static boolean i915_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { struct i915_screen *is = i915_screen(screen); - return is->iws->fence_finish(is->iws, fence); + return is->iws->fence_finish(is->iws, fence) == 0; } diff --git a/src/gallium/drivers/i915/i915_screen.h b/src/gallium/drivers/i915/i915_screen.h index 60f0e2971e0..cfc585b5350 100644 --- a/src/gallium/drivers/i915/i915_screen.h +++ b/src/gallium/drivers/i915/i915_screen.h @@ -49,6 +49,7 @@ struct i915_screen struct { boolean tiling; boolean lie; + boolean use_blitter; } debug; }; diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index 58bbbd1de2c..1b57c5776f2 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -287,6 +287,17 @@ i915_create_sampler_state(struct pipe_context *pipe, return cso; } +static void i915_fixup_bind_sampler_states(struct pipe_context *pipe, + unsigned num, void **sampler) +{ + struct i915_context *i915 = i915_context(pipe); + + i915->saved_nr_samplers = num; + memcpy(&i915->saved_samplers, sampler, sizeof(void *) * num); + + i915->saved_bind_sampler_states(pipe, num, sampler); +} + static void i915_bind_sampler_states(struct pipe_context *pipe, unsigned num, void **sampler) { @@ -466,6 +477,17 @@ i915_create_fs_state(struct pipe_context *pipe, } static void +i915_fixup_bind_fs_state(struct pipe_context *pipe, void *shader) +{ + struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); + + i915->saved_fs = shader; + + i915->saved_bind_fs_state(pipe, shader); +} + +static void i915_bind_fs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); @@ -505,6 +527,8 @@ static void i915_bind_vs_state(struct pipe_context *pipe, void *shader) { struct i915_context *i915 = i915_context(pipe); + i915->saved_vs = shader; + /* just pass-through to draw module */ draw_bind_vertex_shader(i915->draw, (struct draw_vertex_shader *) shader); @@ -571,6 +595,27 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, } +static void +i915_fixup_set_fragment_sampler_views(struct pipe_context *pipe, + unsigned num, + struct pipe_sampler_view **views) +{ + struct i915_context *i915 = i915_context(pipe); + int i; + + for (i = 0; i < num; i++) + pipe_sampler_view_reference(&i915->saved_sampler_views[i], + views[i]); + + for (i = num; i < i915->saved_nr_sampler_views; i++) + pipe_sampler_view_reference(&i915->saved_sampler_views[i], + NULL); + + i915->saved_nr_sampler_views = num; + + i915->saved_set_sampler_views(pipe, num, views); +} + static void i915_set_fragment_sampler_views(struct pipe_context *pipe, unsigned num, struct pipe_sampler_view **views) @@ -642,7 +687,8 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe, i915->framebuffer.height = fb->height; i915->framebuffer.nr_cbufs = fb->nr_cbufs; for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) { - pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]); + pipe_surface_reference(&i915->framebuffer.cbufs[i], + i < fb->nr_cbufs ? fb->cbufs[i] : NULL); } pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf); @@ -657,6 +703,8 @@ static void i915_set_clip_state( struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); + i915->saved_clip = *clip; + draw_set_clip_state(i915->draw, clip); i915->dirty |= I915_NEW_CLIP; @@ -687,7 +735,7 @@ i915_create_rasterizer_state(struct pipe_context *pipe, { struct i915_rasterizer_state *cso = CALLOC_STRUCT( i915_rasterizer_state ); - cso->templ = rasterizer; + cso->templ = *rasterizer; cso->color_interp = rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR; cso->light_twoside = rasterizer->light_twoside; cso->ds[0].u = _3DSTATE_DEPTH_OFFSET_SCALE; @@ -758,7 +806,7 @@ static void i915_bind_rasterizer_state( struct pipe_context *pipe, /* pass-through to draw module */ draw_set_rasterizer_state(i915->draw, - (i915->rasterizer ? i915->rasterizer->templ : NULL), + (i915->rasterizer ? &(i915->rasterizer->templ) : NULL), raster); i915->dirty |= I915_NEW_RASTERIZER; @@ -778,6 +826,9 @@ static void i915_set_vertex_buffers(struct pipe_context *pipe, struct draw_context *draw = i915->draw; int i; + util_copy_vertex_buffers(i915->saved_vertex_buffers, + &i915->saved_nr_vertex_buffers, + buffers, count); #if 0 /* XXX doesn't look like this is needed */ /* unmap old */ @@ -818,6 +869,8 @@ i915_bind_vertex_elements_state(struct pipe_context *pipe, struct i915_context *i915 = i915_context(pipe); struct i915_velems_state *i915_velems = (struct i915_velems_state *) velems; + i915->saved_velems = velems; + /* pass-through to draw module */ if (i915_velems) { draw_set_vertex_elements(i915->draw, @@ -896,3 +949,14 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.set_index_buffer = i915_set_index_buffer; i915->base.redefine_user_buffer = u_default_redefine_user_buffer; } + +void +i915_init_fixup_state_functions( struct i915_context *i915 ) +{ + i915->saved_bind_fs_state = i915->base.bind_fs_state; + i915->base.bind_fs_state = i915_fixup_bind_fs_state; + i915->saved_bind_sampler_states = i915->base.bind_fragment_sampler_states; + i915->base.bind_fragment_sampler_states = i915_fixup_bind_sampler_states; + i915->saved_set_sampler_views = i915->base.set_fragment_sampler_views; + i915->base.set_fragment_sampler_views = i915_fixup_set_fragment_sampler_views; +} diff --git a/src/gallium/drivers/i915/i915_state.h b/src/gallium/drivers/i915/i915_state.h index b4074dc35ba..3f4e40294e6 100644 --- a/src/gallium/drivers/i915/i915_state.h +++ b/src/gallium/drivers/i915/i915_state.h @@ -48,6 +48,7 @@ extern struct i915_tracked_state i915_hw_immediate; extern struct i915_tracked_state i915_hw_dynamic; extern struct i915_tracked_state i915_hw_fs; extern struct i915_tracked_state i915_hw_framebuffer; +extern struct i915_tracked_state i915_hw_dst_buf_vars; extern struct i915_tracked_state i915_hw_constants; void i915_update_derived(struct i915_context *i915); diff --git a/src/gallium/drivers/i915/i915_state_derived.c b/src/gallium/drivers/i915/i915_state_derived.c index 1d4026a214e..59ac2f7292a 100644 --- a/src/gallium/drivers/i915/i915_state_derived.c +++ b/src/gallium/drivers/i915/i915_state_derived.c @@ -165,6 +165,7 @@ static struct i915_tracked_state *atoms[] = { &i915_hw_dynamic, &i915_hw_fs, &i915_hw_framebuffer, + &i915_hw_dst_buf_vars, &i915_hw_constants, NULL, }; diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c index 15350c0a5d7..0155cd83510 100644 --- a/src/gallium/drivers/i915/i915_state_emit.c +++ b/src/gallium/drivers/i915/i915_state_emit.c @@ -119,7 +119,7 @@ validate_immediate(struct i915_context *i915, unsigned *batch_space) 1 << I915_IMMEDIATE_S5 | 1 << I915_IMMEDIATE_S6) & i915->immediate_dirty; - if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0)) + if (i915->immediate_dirty & (1 << I915_IMMEDIATE_S0) && i915->vbo) i915->validation_buffers[i915->num_validation_buffers++] = i915->vbo; *batch_space = 1 + util_bitcount(dirty); @@ -173,25 +173,31 @@ emit_dynamic(struct i915_context *i915) static void validate_static(struct i915_context *i915, unsigned *batch_space) { - *batch_space = 2 + 5; /* including DRAW_RECT */ + *batch_space = 0; - if (i915->current.cbuf_bo) { + if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { i915->validation_buffers[i915->num_validation_buffers++] = i915->current.cbuf_bo; *batch_space += 3; } - if (i915->current.depth_bo) { + if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) { i915->validation_buffers[i915->num_validation_buffers++] = i915->current.depth_bo; *batch_space += 3; } + + if (i915->static_dirty & I915_DST_VARS) + *batch_space += 2; + + if (i915->static_dirty & I915_DST_RECT) + *batch_space += 5; } static void emit_static(struct i915_context *i915) { - if (i915->current.cbuf_bo) { + if (i915->current.cbuf_bo && (i915->static_dirty & I915_DST_BUF_COLOR)) { OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(i915->current.cbuf_flags); OUT_RELOC(i915->current.cbuf_bo, @@ -201,7 +207,7 @@ emit_static(struct i915_context *i915) /* What happens if no zbuf?? */ - if (i915->current.depth_bo) { + if (i915->current.depth_bo && (i915->static_dirty & I915_DST_BUF_DEPTH)) { OUT_BATCH(_3DSTATE_BUF_INFO_CMD); OUT_BATCH(i915->current.depth_flags); OUT_RELOC(i915->current.depth_bo, @@ -209,7 +215,7 @@ emit_static(struct i915_context *i915) 0); } - { + if (i915->static_dirty & I915_DST_VARS) { OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD); OUT_BATCH(i915->current.dst_buf_vars); } @@ -273,7 +279,7 @@ emit_sampler(struct i915_context *i915) if (i915->current.sampler_enable_nr) { int i; - OUT_BATCH( _3DSTATE_SAMPLER_STATE | + OUT_BATCH( _3DSTATE_SAMPLER_STATE | (3 * i915->current.sampler_enable_nr) ); OUT_BATCH( i915->current.sampler_enable_flags ); @@ -355,11 +361,13 @@ emit_program(struct i915_context *i915) static void emit_draw_rect(struct i915_context *i915) { - OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); - OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS); - OUT_BATCH(i915->current.draw_offset); - OUT_BATCH(i915->current.draw_size); - OUT_BATCH(i915->current.draw_offset); + if (i915->static_dirty & I915_DST_RECT) { + OUT_BATCH(_3DSTATE_DRAW_RECT_CMD); + OUT_BATCH(DRAW_RECT_DIS_DEPTH_OFS); + OUT_BATCH(i915->current.draw_offset); + OUT_BATCH(i915->current.draw_size); + OUT_BATCH(i915->current.draw_offset); + } } static boolean @@ -405,6 +413,8 @@ i915_emit_hardware_state(struct i915_context *i915 ) unsigned batch_space; uintptr_t save_ptr; + assert(i915->dirty == 0); + if (I915_DBG_ON(DBG_ATOMS)) i915_dump_hardware_dirty(i915, __FUNCTION__); @@ -444,5 +454,6 @@ i915_emit_hardware_state(struct i915_context *i915 ) i915->hardware_dirty = 0; i915->immediate_dirty = 0; i915->dynamic_dirty = 0; + i915->static_dirty = 0; i915->flush_dirty = 0; } diff --git a/src/gallium/drivers/i915/i915_state_static.c b/src/gallium/drivers/i915/i915_state_static.c index 20cd23f8f73..2865298318c 100644 --- a/src/gallium/drivers/i915/i915_state_static.c +++ b/src/gallium/drivers/i915/i915_state_static.c @@ -28,6 +28,7 @@ #include "i915_context.h" #include "i915_state.h" #include "i915_resource.h" +#include "i915_screen.h" @@ -78,38 +79,13 @@ buf_3d_tiling_bits(enum i915_winsys_buffer_tile tiling) return tiling_bits; } -/** - * Examine framebuffer state to determine width, height. - */ -static boolean -framebuffer_size(const struct pipe_framebuffer_state *fb, - uint *width, uint *height) -{ - if (fb->cbufs[0]) { - *width = fb->cbufs[0]->width; - *height = fb->cbufs[0]->height; - return TRUE; - } - else if (fb->zsbuf) { - *width = fb->zsbuf->width; - *height = fb->zsbuf->height; - return TRUE; - } - else { - *width = *height = 0; - return FALSE; - } -} - static void update_framebuffer(struct i915_context *i915) { struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; - unsigned cformat, zformat; - unsigned x, y, w, h; + unsigned x, y; int layer; - uint32_t draw_offset; - boolean ret; + uint32_t draw_offset, draw_size; if (cbuf_surface) { struct i915_texture *tex = i915_texture(cbuf_surface->texture); @@ -119,7 +95,6 @@ static void update_framebuffer(struct i915_context *i915) i915->current.cbuf_flags = BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ buf_3d_tiling_bits(tex->tiling); - cformat = cbuf_surface->format; layer = cbuf_surface->u.tex.first_layer; @@ -127,10 +102,9 @@ static void update_framebuffer(struct i915_context *i915) y = tex->image_offset[cbuf_surface->u.tex.level][layer].nblocksy; } else { i915->current.cbuf_bo = NULL; - cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */ x = y = 0; } - cformat = translate_format(cformat); + i915->static_dirty |= I915_DST_BUF_COLOR; /* What happens if no zbuf?? */ @@ -145,28 +119,23 @@ static void update_framebuffer(struct i915_context *i915) i915->current.depth_flags = BUF_3D_ID_DEPTH | BUF_3D_PITCH(tex->stride) | /* pitch in bytes */ buf_3d_tiling_bits(tex->tiling); - zformat = translate_depth_format(depth_surface->format); - } else { + } else i915->current.depth_bo = NULL; - zformat = 0; - } - - i915->current.dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ - DSTORG_VERT_BIAS(0x8) | /* .5 */ - LOD_PRECLAMP_OGL | - TEX_DEFAULT_COLOR_OGL | - cformat | - zformat; + i915->static_dirty |= I915_DST_BUF_DEPTH; /* drawing rect calculations */ draw_offset = x | (y << 16); - ret = framebuffer_size(&i915->framebuffer, &w, &h); - assert(ret); + draw_size = (i915->framebuffer.width - 1 + x) | + ((i915->framebuffer.height - 1 + y) << 16); if (i915->current.draw_offset != draw_offset) { i915->current.draw_offset = draw_offset; i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); + i915->static_dirty |= I915_DST_RECT; + } + if (i915->current.draw_size != draw_size) { + i915->current.draw_size = draw_size; + i915->static_dirty |= I915_DST_RECT; } - i915->current.draw_size = (w - 1 + x) | ((h - 1 + y) << 16); i915->hardware_dirty |= I915_HW_STATIC; @@ -179,3 +148,52 @@ struct i915_tracked_state i915_hw_framebuffer = { update_framebuffer, I915_NEW_FRAMEBUFFER }; + +static void update_dst_buf_vars(struct i915_context *i915) +{ + struct pipe_surface *cbuf_surface = i915->framebuffer.cbufs[0]; + struct pipe_surface *depth_surface = i915->framebuffer.zsbuf; + uint32_t dst_buf_vars, cformat, zformat; + uint32_t early_z = 0; + + if (cbuf_surface) + cformat = cbuf_surface->format; + else + cformat = PIPE_FORMAT_B8G8R8A8_UNORM; /* arbitrary */ + cformat = translate_format(cformat); + + if (depth_surface) { + struct i915_texture *tex = i915_texture(depth_surface->texture); + struct i915_screen *is = i915_screen(i915->base.screen); + + zformat = translate_depth_format(depth_surface->format); + + if (is->is_i945 && tex->tiling != I915_TILE_NONE + && !i915->fs->info.writes_z) + early_z = CLASSIC_EARLY_DEPTH; + } else + zformat = 0; + + dst_buf_vars = DSTORG_HORT_BIAS(0x8) | /* .5 */ + DSTORG_VERT_BIAS(0x8) | /* .5 */ + LOD_PRECLAMP_OGL | + TEX_DEFAULT_COLOR_OGL | + cformat | + zformat | + early_z; + + if (i915->current.dst_buf_vars != dst_buf_vars) { + if (early_z != (i915->current.dst_buf_vars & CLASSIC_EARLY_DEPTH)) + i915_set_flush_dirty(i915, I915_PIPELINE_FLUSH); + + i915->current.dst_buf_vars = dst_buf_vars; + i915->static_dirty |= I915_DST_VARS; + i915->hardware_dirty |= I915_HW_STATIC; + } +} + +struct i915_tracked_state i915_hw_dst_buf_vars = { + "dst buf vars", + update_dst_buf_vars, + I915_NEW_FRAMEBUFFER | I915_NEW_FS +}; diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c index becc6e93c2d..d02c420f6c2 100644 --- a/src/gallium/drivers/i915/i915_surface.c +++ b/src/gallium/drivers/i915/i915_surface.c @@ -27,6 +27,7 @@ #include "i915_surface.h" #include "i915_resource.h" +#include "i915_state.h" #include "i915_blit.h" #include "i915_reg.h" #include "i915_screen.h" @@ -37,16 +38,119 @@ #include "util/u_memory.h" #include "util/u_pack_color.h" +/* + * surface functions using the render engine + */ + +static void +i915_surface_copy_render(struct pipe_context *pipe, + struct pipe_resource *dst, unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box) +{ + struct i915_context *i915 = i915_context(pipe); + + util_blitter_save_blend(i915->blitter, (void *)i915->blend); + util_blitter_save_depth_stencil_alpha(i915->blitter, (void *)i915->depth_stencil); + util_blitter_save_stencil_ref(i915->blitter, &i915->stencil_ref); + util_blitter_save_rasterizer(i915->blitter, (void *)i915->rasterizer); + util_blitter_save_fragment_shader(i915->blitter, i915->saved_fs); + util_blitter_save_vertex_shader(i915->blitter, i915->saved_vs); + util_blitter_save_viewport(i915->blitter, &i915->viewport); + util_blitter_save_clip(i915->blitter, &i915->saved_clip); + util_blitter_save_vertex_elements(i915->blitter, i915->saved_velems); + util_blitter_save_vertex_buffers(i915->blitter, i915->saved_nr_vertex_buffers, + i915->saved_vertex_buffers); + + util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); + + util_blitter_save_fragment_sampler_states(i915->blitter, + i915->saved_nr_samplers, + i915->saved_samplers); + util_blitter_save_fragment_sampler_views(i915->blitter, + i915->saved_nr_sampler_views, + i915->saved_sampler_views); + + util_blitter_copy_region(i915->blitter, dst, dst_level, dstx, dsty, dstz, + src, src_level, src_box, TRUE); +} + +static void +i915_clear_render_target_render(struct pipe_context *pipe, + struct pipe_surface *dst, + const float *rgba, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + struct i915_context *i915 = i915_context(pipe); + struct pipe_framebuffer_state fb_state; + + util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); + + fb_state.width = dst->width; + fb_state.height = dst->height; + fb_state.nr_cbufs = 1; + fb_state.cbufs[0] = dst; + fb_state.zsbuf = NULL; + pipe->set_framebuffer_state(pipe, &fb_state); + + if (i915->dirty) + i915_update_derived(i915); + + i915_clear_emit(pipe, PIPE_CLEAR_COLOR, rgba, 0.0, 0x0, + dstx, dsty, width, height); + + pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); + util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); + i915->blitter->saved_fb_state.nr_cbufs = ~0; +} + +static void +i915_clear_depth_stencil_render(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) +{ + struct i915_context *i915 = i915_context(pipe); + struct pipe_framebuffer_state fb_state; + + util_blitter_save_framebuffer(i915->blitter, &i915->framebuffer); + + fb_state.width = dst->width; + fb_state.height = dst->height; + fb_state.nr_cbufs = 0; + fb_state.zsbuf = dst; + pipe->set_framebuffer_state(pipe, &fb_state); + + if (i915->dirty) + i915_update_derived(i915); + + i915_clear_emit(pipe, clear_flags & PIPE_CLEAR_DEPTHSTENCIL, + NULL, depth, stencil, + dstx, dsty, width, height); + + pipe->set_framebuffer_state(pipe, &i915->blitter->saved_fb_state); + util_unreference_framebuffer_state(&i915->blitter->saved_fb_state); + i915->blitter->saved_fb_state.nr_cbufs = ~0; +} + +/* + * surface functions using the blitter + */ /* Assumes all values are within bounds -- no checking at this level - * do it higher up if required. */ static void -i915_surface_copy(struct pipe_context *pipe, - struct pipe_resource *dst, unsigned dst_level, - unsigned dstx, unsigned dsty, unsigned dstz, - struct pipe_resource *src, unsigned src_level, - const struct pipe_box *src_box) +i915_surface_copy_blitter(struct pipe_context *pipe, + struct pipe_resource *dst, unsigned dst_level, + unsigned dstx, unsigned dsty, unsigned dstz, + struct pipe_resource *src, unsigned src_level, + const struct pipe_box *src_box) { struct i915_texture *dst_tex = i915_texture(dst); struct i915_texture *src_tex = i915_texture(src); @@ -66,7 +170,6 @@ i915_surface_copy(struct pipe_context *pipe, assert(src_box->z == 0); src_offset = i915_texture_offset(src_tex, src_level, src_box->z); - assert( dst != src ); assert( util_format_get_blocksize(dpt->format) == util_format_get_blocksize(spt->format) ); assert( util_format_get_blockwidth(dpt->format) == util_format_get_blockwidth(spt->format) ); assert( util_format_get_blockheight(dpt->format) == util_format_get_blockheight(spt->format) ); @@ -81,13 +184,12 @@ i915_surface_copy(struct pipe_context *pipe, (short) src_box->width, (short) src_box->height ); } - static void -i915_clear_render_target(struct pipe_context *pipe, - struct pipe_surface *dst, - const float *rgba, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height) +i915_clear_render_target_blitter(struct pipe_context *pipe, + struct pipe_surface *dst, + const float *rgba, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) { struct i915_texture *tex = i915_texture(dst->texture); struct pipe_resource *pt = &tex->b.b; @@ -109,13 +211,13 @@ i915_clear_render_target(struct pipe_context *pipe, } static void -i915_clear_depth_stencil(struct pipe_context *pipe, - struct pipe_surface *dst, - unsigned clear_flags, - double depth, - unsigned stencil, - unsigned dstx, unsigned dsty, - unsigned width, unsigned height) +i915_clear_depth_stencil_blitter(struct pipe_context *pipe, + struct pipe_surface *dst, + unsigned clear_flags, + double depth, + unsigned stencil, + unsigned dstx, unsigned dsty, + unsigned width, unsigned height) { struct i915_texture *tex = i915_texture(dst->texture); struct pipe_resource *pt = &tex->b.b; @@ -193,9 +295,15 @@ i915_surface_destroy(struct pipe_context *ctx, void i915_init_surface_functions(struct i915_context *i915) { - i915->base.resource_copy_region = i915_surface_copy; - i915->base.clear_render_target = i915_clear_render_target; - i915->base.clear_depth_stencil = i915_clear_depth_stencil; + if (i915_screen(i915->base.screen)->debug.use_blitter) { + i915->base.resource_copy_region = i915_surface_copy_blitter; + i915->base.clear_render_target = i915_clear_render_target_blitter; + i915->base.clear_depth_stencil = i915_clear_depth_stencil_blitter; + } else { + i915->base.resource_copy_region = i915_surface_copy_render; + i915->base.clear_render_target = i915_clear_render_target_render; + i915->base.clear_depth_stencil = i915_clear_depth_stencil_render; + } i915->base.create_surface = i915_create_surface; i915->base.surface_destroy = i915_surface_destroy; } diff --git a/src/gallium/drivers/i965/brw_pipe_flush.c b/src/gallium/drivers/i965/brw_pipe_flush.c index 0ae1a6be9e5..3b4a99beed2 100644 --- a/src/gallium/drivers/i965/brw_pipe_flush.c +++ b/src/gallium/drivers/i965/brw_pipe_flush.c @@ -38,7 +38,6 @@ void brw_context_flush( struct brw_context *brw ) static void brw_flush( struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence ) { brw_context_flush( brw_context( pipe ) ); diff --git a/src/gallium/drivers/i965/brw_resource_buffer.c b/src/gallium/drivers/i965/brw_resource_buffer.c index afb96ee3e7f..32dc54f2b26 100644 --- a/src/gallium/drivers/i965/brw_resource_buffer.c +++ b/src/gallium/drivers/i965/brw_resource_buffer.c @@ -91,30 +91,10 @@ brw_buffer_transfer_unmap( struct pipe_context *pipe, } -static unsigned brw_buffer_is_referenced( struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, - int layer) -{ - struct brw_context *brw = brw_context(pipe); - struct brw_winsys_buffer *batch_bo = brw->batch->buf; - struct brw_buffer *buf = brw_buffer(resource); - - if (buf->bo == NULL) - return PIPE_UNREFERENCED; - - if (!brw_screen(pipe->screen)->sws->bo_references( batch_bo, buf->bo )) - return PIPE_UNREFERENCED; - - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} - - struct u_resource_vtbl brw_buffer_vtbl = { brw_buffer_get_handle, /* get_handle */ brw_buffer_destroy, /* resource_destroy */ - brw_buffer_is_referenced, /* is_resource_referenced */ u_default_get_transfer, /* get_transfer */ u_default_transfer_destroy, /* transfer_destroy */ brw_buffer_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/i965/brw_resource_texture.c b/src/gallium/drivers/i965/brw_resource_texture.c index 0cb895f35de..71a18290248 100644 --- a/src/gallium/drivers/i965/brw_resource_texture.c +++ b/src/gallium/drivers/i965/brw_resource_texture.c @@ -225,48 +225,6 @@ static void brw_texture_destroy(struct pipe_screen *screen, } - - -static unsigned brw_texture_is_referenced( struct pipe_context *pipe, - struct pipe_resource *texture, - unsigned level, - int layer ) -{ - struct brw_context *brw = brw_context(pipe); - struct brw_screen *bscreen = brw_screen(pipe->screen); - struct brw_winsys_buffer *batch_bo = brw->batch->buf; - struct brw_texture *tex = brw_texture(texture); - struct brw_surface *surf; - int i; - - /* XXX: this is subject to false positives if the underlying - * texture BO is referenced, we can't tell whether the sub-region - * we care about participates in that. - */ - if (bscreen->sws->bo_references( batch_bo, tex->bo )) - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; - - /* Find any view on this texture for this level/layer and see if it - * is referenced: - */ - for (i = 0; i < 2; i++) { - foreach (surf, &tex->views[i]) { - if (surf->bo == tex->bo) - continue; - - if (!(layer == -1 || surf->id.bits.layer == layer) || - surf->id.bits.level != level) - continue; - - if (bscreen->sws->bo_references( batch_bo, surf->bo)) - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; - } - } - - return PIPE_UNREFERENCED; -} - - /* * Transfer functions */ @@ -347,7 +305,6 @@ struct u_resource_vtbl brw_texture_vtbl = { brw_texture_get_handle, /* get_handle */ brw_texture_destroy, /* resource_destroy */ - brw_texture_is_referenced, /* is_resource_referenced */ brw_texture_get_transfer, /* get_transfer */ u_default_transfer_destroy, /* transfer_destroy */ brw_texture_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c index bf805fd080c..25204fd088d 100644 --- a/src/gallium/drivers/i965/brw_screen.c +++ b/src/gallium/drivers/i965/brw_screen.c @@ -278,8 +278,7 @@ brw_is_format_supported(struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) + unsigned tex_usage) { static const enum pipe_format tex_supported[] = { PIPE_FORMAT_L8_UNORM, @@ -365,20 +364,19 @@ brw_fence_reference(struct pipe_screen *screen, { } -static int +static boolean brw_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { - return 0; /* XXX shouldn't this be a boolean? */ + return TRUE; } -static int +static boolean brw_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { - return 0; + return TRUE; } diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index b533abe24c6..2a9d7360155 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -668,34 +668,15 @@ identity_clear_depth_stencil(struct pipe_context *_pipe, static void identity_flush(struct pipe_context *_pipe, - unsigned flags, struct pipe_fence_handle **fence) { struct identity_context *id_pipe = identity_context(_pipe); struct pipe_context *pipe = id_pipe->pipe; pipe->flush(pipe, - flags, fence); } -static unsigned int -identity_is_resource_referenced(struct pipe_context *_pipe, - struct pipe_resource *_resource, - unsigned level, - int layer) -{ - struct identity_context *id_pipe = identity_context(_pipe); - struct identity_resource *id_resource = identity_resource(_resource); - struct pipe_context *pipe = id_pipe->pipe; - struct pipe_resource *resource = id_resource->resource; - - return pipe->is_resource_referenced(pipe, - resource, - level, - layer); -} - static struct pipe_sampler_view * identity_context_create_sampler_view(struct pipe_context *_pipe, struct pipe_resource *_resource, @@ -931,7 +912,6 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.clear_render_target = identity_clear_render_target; id_pipe->base.clear_depth_stencil = identity_clear_depth_stencil; id_pipe->base.flush = identity_flush; - id_pipe->base.is_resource_referenced = identity_is_resource_referenced; id_pipe->base.create_surface = identity_context_create_surface; id_pipe->base.surface_destroy = identity_context_surface_destroy; id_pipe->base.create_sampler_view = identity_context_create_sampler_view; diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c index 644481bb748..9bf7fd4c0ee 100644 --- a/src/gallium/drivers/identity/id_screen.c +++ b/src/gallium/drivers/identity/id_screen.c @@ -103,8 +103,7 @@ identity_screen_is_format_supported(struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) + unsigned tex_usage) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; @@ -113,8 +112,7 @@ identity_screen_is_format_supported(struct pipe_screen *_screen, format, target, sample_count, - tex_usage, - geom_flags); + tex_usage); } static struct pipe_context * @@ -242,30 +240,28 @@ identity_screen_fence_reference(struct pipe_screen *_screen, fence); } -static int +static boolean identity_screen_fence_signalled(struct pipe_screen *_screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; return screen->fence_signalled(screen, - fence, - flags); + fence); } -static int +static boolean identity_screen_fence_finish(struct pipe_screen *_screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { struct identity_screen *id_screen = identity_screen(_screen); struct pipe_screen *screen = id_screen->screen; return screen->fence_finish(screen, fence, - flags); + timeout); } struct pipe_screen * diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README index e9374cc6efa..1fc7746a834 100644 --- a/src/gallium/drivers/llvmpipe/README +++ b/src/gallium/drivers/llvmpipe/README @@ -12,7 +12,7 @@ Requirements See /proc/cpuinfo to know what your CPU supports. - - LLVM 2.6 (or later) + - LLVM. Version 2.8 recommended. 2.6 or later required. For Linux, on a recent Debian based distribution do: @@ -30,21 +30,8 @@ Requirements debug=no. This is necessary as LLVM builds as static library so the chosen MS CRT must match. - The version of LLVM from SVN ("2.7svn") from mid-March 2010 is pretty - stable and has some features not in version 2.6. - - scons (optional) - - udis86, http://udis86.sourceforge.net/ (optional). My personal repository - supports more opcodes which haven't been merged upstream yet: - - git clone git://anongit.freedesktop.org/~jrfonseca/udis86 - cd udis86 - ./autogen.sh - ./configure --with-pic - make - sudo make install - Building ======== @@ -94,13 +81,7 @@ that no tail call optimizations are done by gcc. To better profile JIT code you'll need to build LLVM with oprofile integration. - source_dir=$PWD/llvm-2.6 - build_dir=$source_dir/build/profile - install_dir=$source_dir-profile - - mkdir -p "$build_dir" - cd "$build_dir" && \ - $source_dir/configure \ + ./configure \ --prefix=$install_dir \ --enable-optimized \ --disable-profiling \ diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index 644201ddf7c..8a5655d4996 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -136,10 +136,9 @@ static void llvmpipe_destroy( struct pipe_context *pipe ) static void do_flush( struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence) { - llvmpipe_flush(pipe, flags, fence, __FUNCTION__); + llvmpipe_flush(pipe, fence, __FUNCTION__); } diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c index 849db06acdf..42430550ea6 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.c +++ b/src/gallium/drivers/llvmpipe/lp_flush.c @@ -40,12 +40,10 @@ /** - * \param flags bitmask of PIPE_FLUSH_x flags * \param fence if non-null, returns pointer to a fence which can be waited on */ void llvmpipe_flush( struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence, const char *reason) { @@ -54,7 +52,7 @@ llvmpipe_flush( struct pipe_context *pipe, draw_flush(llvmpipe->draw); /* ask the setup module to flush */ - lp_setup_flush(llvmpipe->setup, flags, fence, reason); + lp_setup_flush(llvmpipe->setup, fence, reason); if (llvmpipe_variant_count > 1000) { @@ -65,23 +63,21 @@ llvmpipe_flush( struct pipe_context *pipe, /* Enable to dump BMPs of the color/depth buffers each frame */ if (0) { - if (flags & PIPE_FLUSH_FRAME) { - static unsigned frame_no = 1; - char filename[256]; - unsigned i; - - for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { - util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); - debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[i]); - } - - if (0) { - util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); - debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); - } - - ++frame_no; + static unsigned frame_no = 1; + char filename[256]; + unsigned i; + + for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) { + util_snprintf(filename, sizeof(filename), "cbuf%u_%u", i, frame_no); + debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.cbufs[i]); + } + + if (0) { + util_snprintf(filename, sizeof(filename), "zsbuf_%u", frame_no); + debug_dump_surface_bmp(&llvmpipe->pipe, filename, llvmpipe->framebuffer.zsbuf); } + + ++frame_no; } } @@ -90,9 +86,9 @@ llvmpipe_finish( struct pipe_context *pipe, const char *reason ) { struct pipe_fence_handle *fence = NULL; - llvmpipe_flush(pipe, 0, &fence, reason); + llvmpipe_flush(pipe, &fence, reason); if (fence) { - pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_finish(pipe->screen, fence, PIPE_TIMEOUT_INFINITE); pipe->screen->fence_reference(pipe->screen, &fence, NULL); } } @@ -110,7 +106,6 @@ llvmpipe_flush_resource(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, int layer, - unsigned flush_flags, boolean read_only, boolean cpu_access, boolean do_not_block, @@ -118,10 +113,10 @@ llvmpipe_flush_resource(struct pipe_context *pipe, { unsigned referenced; - referenced = pipe->is_resource_referenced(pipe, resource, level, layer); + referenced = llvmpipe_is_resource_referenced(pipe, resource, level, layer); - if ((referenced & PIPE_REFERENCED_FOR_WRITE) || - ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { + if ((referenced & LP_REFERENCED_FOR_WRITE) || + ((referenced & LP_REFERENCED_FOR_READ) && !read_only)) { if (cpu_access) { /* @@ -136,7 +131,7 @@ llvmpipe_flush_resource(struct pipe_context *pipe, * Just flush. */ - llvmpipe_flush(pipe, flush_flags, NULL, reason); + llvmpipe_flush(pipe, NULL, reason); } } diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h index 579d24c68ad..efff94c8c0c 100644 --- a/src/gallium/drivers/llvmpipe/lp_flush.h +++ b/src/gallium/drivers/llvmpipe/lp_flush.h @@ -36,7 +36,6 @@ struct pipe_resource; void llvmpipe_flush(struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence, const char *reason); @@ -49,7 +48,6 @@ llvmpipe_flush_resource(struct pipe_context *pipe, struct pipe_resource *resource, unsigned level, int layer, - unsigned flush_flags, boolean read_only, boolean cpu_access, boolean do_not_block, diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c index 84c66dd36e8..1e2401fa84d 100644 --- a/src/gallium/drivers/llvmpipe/lp_query.c +++ b/src/gallium/drivers/llvmpipe/lp_query.c @@ -69,7 +69,7 @@ llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q) */ if (pq->fence) { if (!lp_fence_issued(pq->fence)) - llvmpipe_flush(pipe, 0, NULL, __FUNCTION__); + llvmpipe_flush(pipe, NULL, __FUNCTION__); if (!lp_fence_signalled(pq->fence)) lp_fence_wait(pq->fence); @@ -99,7 +99,7 @@ llvmpipe_get_query_result(struct pipe_context *pipe, if (!lp_fence_signalled(pq->fence)) { if (!lp_fence_issued(pq->fence)) - llvmpipe_flush(pipe, 0, NULL, __FUNCTION__); + llvmpipe_flush(pipe, NULL, __FUNCTION__); if (!wait) return FALSE; diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c index 2c32aa93cdf..521a52ad3ae 100644 --- a/src/gallium/drivers/llvmpipe/lp_screen.c +++ b/src/gallium/drivers/llvmpipe/lp_screen.c @@ -164,7 +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: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; default: return 0; @@ -224,8 +225,7 @@ llvmpipe_is_format_supported( struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bind, - unsigned geom_flags ) + unsigned bind) { struct llvmpipe_screen *screen = llvmpipe_screen(_screen); struct sw_winsys *winsys = screen->winsys; @@ -348,10 +348,9 @@ llvmpipe_fence_reference(struct pipe_screen *screen, /** * Has the fence been executed/finished? */ -static int +static boolean llvmpipe_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flag) + struct pipe_fence_handle *fence) { struct lp_fence *f = (struct lp_fence *) fence; return lp_fence_signalled(f); @@ -361,15 +360,15 @@ llvmpipe_fence_signalled(struct pipe_screen *screen, /** * Wait for the fence to finish. */ -static int +static boolean llvmpipe_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence_handle, - unsigned flag) + uint64_t timeout) { struct lp_fence *f = (struct lp_fence *) fence_handle; lp_fence_wait(f); - return 0; + return TRUE; } diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 7b7b2721ba8..3813e0ed972 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -333,12 +333,8 @@ fail: } -/** - * \param flags bitmask of PIPE_FLUSH_x flags - */ void lp_setup_flush( struct lp_setup_context *setup, - unsigned flags, struct pipe_fence_handle **fence, const char *reason) { @@ -469,7 +465,7 @@ lp_setup_clear( struct lp_setup_context *setup, unsigned flags ) { if (!lp_setup_try_clear( setup, color, depth, stencil, flags )) { - lp_setup_flush(setup, 0, NULL, __FUNCTION__); + lp_setup_flush(setup, NULL, __FUNCTION__); if (!lp_setup_try_clear( setup, color, depth, stencil, flags )) assert(0); @@ -753,20 +749,20 @@ lp_setup_is_resource_referenced( const struct lp_setup_context *setup, /* check the render targets */ for (i = 0; i < setup->fb.nr_cbufs; i++) { if (setup->fb.cbufs[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE; } if (setup->fb.zsbuf && setup->fb.zsbuf->texture == texture) { - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; + return LP_REFERENCED_FOR_READ | LP_REFERENCED_FOR_WRITE; } /* check textures referenced by the scene */ for (i = 0; i < Elements(setup->scenes); i++) { if (lp_scene_is_resource_referenced(setup->scenes[i], texture)) { - return PIPE_REFERENCED_FOR_READ; + return LP_REFERENCED_FOR_READ; } } - return PIPE_UNREFERENCED; + return LP_UNREFERENCED; } @@ -1114,7 +1110,7 @@ lp_setup_end_query(struct lp_setup_context *setup, struct llvmpipe_query *pq) if (!lp_scene_bin_everywhere(setup->scene, LP_RAST_OP_END_QUERY, dummy)) { - lp_setup_flush(setup, 0, NULL, __FUNCTION__); + lp_setup_flush(setup, NULL, __FUNCTION__); } } else { diff --git a/src/gallium/drivers/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h index 0d6e161a218..8655259d27c 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.h +++ b/src/gallium/drivers/llvmpipe/lp_setup.h @@ -64,7 +64,6 @@ lp_setup_clear(struct lp_setup_context *setup, void lp_setup_flush( struct lp_setup_context *setup, - unsigned flags, struct pipe_fence_handle **fence, const char *reason); diff --git a/src/gallium/drivers/llvmpipe/lp_state_setup.c b/src/gallium/drivers/llvmpipe/lp_state_setup.c index ad751b9ef42..9f1ec146e9d 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_state_setup.c @@ -651,7 +651,7 @@ generate_setup_variant(struct gallivm_state *gallivm, LLVMTypeRef arg_types[7]; LLVMBasicBlockRef block; LLVMBuilderRef builder = gallivm->builder; - int64_t t0, t1; + int64_t t0 = 0, t1; if (0) goto fail; diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c index e7e46a628a1..f49638acf08 100644 --- a/src/gallium/drivers/llvmpipe/lp_surface.c +++ b/src/gallium/drivers/llvmpipe/lp_surface.c @@ -69,7 +69,6 @@ lp_resource_copy(struct pipe_context *pipe, llvmpipe_flush_resource(pipe, dst, dst_level, dstz, - 0, /* flush_flags */ FALSE, /* read_only */ TRUE, /* cpu_access */ FALSE, /* do_not_block */ @@ -77,7 +76,6 @@ lp_resource_copy(struct pipe_context *pipe, llvmpipe_flush_resource(pipe, src, src_level, src_box->z, - 0, /* flush_flags */ TRUE, /* read_only */ TRUE, /* cpu_access */ FALSE, /* do_not_block */ diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 9753da5e57e..fa4ce5bf2ac 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -575,7 +575,6 @@ llvmpipe_get_transfer(struct pipe_context *pipe, if (!llvmpipe_flush_resource(pipe, resource, level, box->depth > 1 ? -1 : box->z, - 0, /* flush_flags */ read_only, TRUE, /* cpu_access */ do_not_block, @@ -695,7 +694,7 @@ llvmpipe_transfer_unmap(struct pipe_context *pipe, transfer->box.z); } -static unsigned int +unsigned int llvmpipe_is_resource_referenced( struct pipe_context *pipe, struct pipe_resource *presource, unsigned level, int layer) @@ -703,7 +702,7 @@ llvmpipe_is_resource_referenced( struct pipe_context *pipe, struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe ); if (presource->target == PIPE_BUFFER) - return PIPE_UNREFERENCED; + return LP_UNREFERENCED; return lp_setup_is_resource_referenced(llvmpipe->setup, presource); } @@ -1401,7 +1400,6 @@ llvmpipe_init_context_resource_funcs(struct pipe_context *pipe) pipe->transfer_destroy = llvmpipe_transfer_destroy; pipe->transfer_map = llvmpipe_transfer_map; pipe->transfer_unmap = llvmpipe_transfer_unmap; - pipe->is_resource_referenced = llvmpipe_is_resource_referenced; pipe->transfer_flush_region = u_default_transfer_flush_region; pipe->transfer_inline_write = u_default_transfer_inline_write; diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h index b789c0f4090..b4a0dfd1c36 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.h +++ b/src/gallium/drivers/llvmpipe/lp_texture.h @@ -243,4 +243,14 @@ llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen); extern void llvmpipe_init_context_texture_funcs(struct pipe_context *pipe); + +#define LP_UNREFERENCED 0 +#define LP_REFERENCED_FOR_READ (1 << 0) +#define LP_REFERENCED_FOR_WRITE (1 << 1) + +unsigned int +llvmpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *presource, + unsigned level, int layer); + #endif /* LP_TEXTURE_H */ diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c index 3680f4622da..496b7f5ec6d 100644 --- a/src/gallium/drivers/noop/noop_pipe.c +++ b/src/gallium/drivers/noop/noop_pipe.c @@ -87,13 +87,6 @@ struct noop_resource { struct sw_displaytarget *dt; }; -static unsigned noop_is_resource_referenced(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned level, int layer) -{ - return PIPE_UNREFERENCED; -} - static struct pipe_resource *noop_resource_create(struct pipe_screen *screen, const struct pipe_resource *templ) { @@ -267,7 +260,7 @@ static void noop_resource_copy_region(struct pipe_context *ctx, /* * context */ -static void noop_flush(struct pipe_context *ctx, unsigned flags, +static void noop_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence) { } @@ -303,7 +296,6 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen, void ctx->transfer_unmap = noop_transfer_unmap; ctx->transfer_destroy = noop_transfer_destroy; ctx->transfer_inline_write = noop_transfer_inline_write; - ctx->is_resource_referenced = noop_is_resource_referenced; noop_init_state_functions(ctx); return ctx; @@ -453,8 +445,7 @@ static boolean noop_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned usage, - unsigned geom_flags) + unsigned usage) { return true; } diff --git a/src/gallium/drivers/nouveau/nouveau_buffer.c b/src/gallium/drivers/nouveau/nouveau_buffer.c index d0cc29104b8..01d3aa46d0e 100644 --- a/src/gallium/drivers/nouveau/nouveau_buffer.c +++ b/src/gallium/drivers/nouveau/nouveau_buffer.c @@ -314,7 +314,6 @@ const struct u_resource_vtbl nouveau_buffer_vtbl = { u_default_resource_get_handle, /* get_handle */ nouveau_buffer_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ nouveau_buffer_transfer_get, /* get_transfer */ nouveau_buffer_transfer_destroy, /* transfer_destroy */ nouveau_buffer_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/nouveau/nouveau_fence.c b/src/gallium/drivers/nouveau/nouveau_fence.c index 18bdb18ad41..d8f59dce9ed 100644 --- a/src/gallium/drivers/nouveau/nouveau_fence.c +++ b/src/gallium/drivers/nouveau/nouveau_fence.c @@ -90,6 +90,9 @@ nouveau_fence_emit(struct nouveau_fence *fence) assert(fence->state == NOUVEAU_FENCE_STATE_AVAILABLE); + /* set this now, so that if fence.emit triggers a flush we don't recurse */ + fence->state = NOUVEAU_FENCE_STATE_EMITTED; + screen->fence.emit(&screen->base, fence->sequence); ++fence->ref; @@ -100,8 +103,6 @@ nouveau_fence_emit(struct nouveau_fence *fence) screen->fence.head = fence; screen->fence.tail = fence; - - fence->state = NOUVEAU_FENCE_STATE_EMITTED; } void @@ -215,6 +216,8 @@ nouveau_fence_wait(struct nouveau_fence *fence) void nouveau_fence_next(struct nouveau_screen *screen) { - nouveau_fence_emit(screen->fence.current); + if (screen->fence.current->state < NOUVEAU_FENCE_STATE_EMITTED) + nouveau_fence_emit(screen->fence.current); + nouveau_fence_new(screen, &screen->fence.current, FALSE); } diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index e6cd3064c9a..401155bba6e 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -12,6 +12,7 @@ #include <errno.h> #include "nouveau/nouveau_bo.h" +#include "nouveau/nouveau_mm.h" #include "nouveau_winsys.h" #include "nouveau_screen.h" #include "nouveau_fence.h" @@ -154,20 +155,19 @@ nouveau_screen_fence_ref(struct pipe_screen *pscreen, nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr); } -static int +static boolean nouveau_screen_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *pfence, - unsigned flags) + struct pipe_fence_handle *pfence) { - return !nouveau_fence_signalled(nouveau_fence(pfence)); + return nouveau_fence_signalled(nouveau_fence(pfence)); } -static int +static boolean nouveau_screen_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *pfence, - unsigned flags) + uint64_t timeout) { - return !nouveau_fence_wait(nouveau_fence(pfence)); + return nouveau_fence_wait(nouveau_fence(pfence)); } @@ -210,26 +210,6 @@ nouveau_screen_bo_get_handle(struct pipe_screen *pscreen, } } - -unsigned int -nouveau_reference_flags(struct nouveau_bo *bo) -{ - uint32_t bo_flags; - int flags = 0; - - bo_flags = nouveau_bo_pending(bo); - if (bo_flags & NOUVEAU_BO_RD) - flags |= PIPE_REFERENCED_FOR_READ; - if (bo_flags & NOUVEAU_BO_WR) - flags |= PIPE_REFERENCED_FOR_WRITE; - - return flags; -} - - - - - int nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) { diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h index c091abf2786..186ada39677 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.h +++ b/src/gallium/drivers/nouveau/nouveau_screen.h @@ -74,10 +74,6 @@ nouveau_screen_bo_from_handle(struct pipe_screen *pscreen, struct winsys_handle *whandle, unsigned *out_stride); -unsigned int -nouveau_reference_flags(struct nouveau_bo *bo); - - int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *); void nouveau_screen_fini(struct nouveau_screen *); diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c index 912367b8391..930cee7c1e7 100644 --- a/src/gallium/drivers/nv50/nv50_context.c +++ b/src/gallium/drivers/nv50/nv50_context.c @@ -30,25 +30,20 @@ #include "nouveau/nouveau_reloc.h" static void -nv50_flush(struct pipe_context *pipe, unsigned flags, +nv50_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence) { - struct nv50_context *nv50 = nv50_context(pipe); - struct nouveau_channel *chan = nv50->screen->base.channel; - - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - BEGIN_RING(chan, RING_3D_(NV50_GRAPH_WAIT_FOR_IDLE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 0x20); - } + struct nouveau_screen *screen = &nv50_context(pipe)->screen->base; if (fence) - nouveau_fence_ref(nv50->screen->base.fence.current, - (struct nouveau_fence **)fence); + nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence); + + /* Try to emit before firing to avoid having to flush again right after + * in case we have to wait on this fence. + */ + nouveau_fence_emit(screen->fence.current); - if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME)) - FIRE_RING(chan); + FIRE_RING(screen->channel); } void @@ -64,10 +59,34 @@ nv50_default_flush_notify(struct nouveau_channel *chan) } static void +nv50_context_unreference_resources(struct nv50_context *nv50) +{ + unsigned s, i; + + for (i = 0; i < NV50_BUFCTX_COUNT; ++i) + nv50_bufctx_reset(nv50, i); + + for (i = 0; i < nv50->num_vtxbufs; ++i) + pipe_resource_reference(&nv50->vtxbuf[i].buffer, NULL); + + pipe_resource_reference(&nv50->idxbuf.buffer, NULL); + + for (s = 0; s < 3; ++s) { + for (i = 0; i < nv50->num_textures[s]; ++i) + pipe_sampler_view_reference(&nv50->textures[s][i], NULL); + + for (i = 0; i < 16; ++i) + pipe_resource_reference(&nv50->constbuf[s][i], NULL); + } +} + +static void nv50_destroy(struct pipe_context *pipe) { struct nv50_context *nv50 = nv50_context(pipe); + nv50_context_unreference_resources(nv50); + draw_destroy(nv50->draw); if (nv50->screen->cur_ctx == nv50) { diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c index ae6b26af1eb..9eeca05ada3 100644 --- a/src/gallium/drivers/nv50/nv50_miptree.c +++ b/src/gallium/drivers/nv50/nv50_miptree.c @@ -106,7 +106,6 @@ const struct u_resource_vtbl nv50_miptree_vtbl = { nv50_miptree_get_handle, /* get_handle */ nv50_miptree_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ nv50_miptree_transfer_new, /* get_transfer */ nv50_miptree_transfer_del, /* transfer_destroy */ nv50_miptree_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/nv50/nv50_resource.c b/src/gallium/drivers/nv50/nv50_resource.c index 2a2fb0e32bc..1ae4d70a845 100644 --- a/src/gallium/drivers/nv50/nv50_resource.c +++ b/src/gallium/drivers/nv50/nv50_resource.c @@ -3,22 +3,6 @@ #include "nv50_resource.h" #include "nouveau/nouveau_screen.h" -static unsigned -nv50_resource_is_referenced(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned face, int layer) -{ - struct nv04_resource *res = nv04_resource(resource); - unsigned flags = 0; - unsigned bo_flags = nouveau_bo_pending(res->bo); - - if (bo_flags & NOUVEAU_BO_RD) - flags = PIPE_REFERENCED_FOR_READ; - if (bo_flags & NOUVEAU_BO_WR) - flags |= PIPE_REFERENCED_FOR_WRITE; - - return flags; -} static struct pipe_resource * nv50_resource_create(struct pipe_screen *screen, @@ -52,7 +36,6 @@ nv50_init_resource_functions(struct pipe_context *pcontext) pcontext->transfer_unmap = u_transfer_unmap_vtbl; pcontext->transfer_destroy = u_transfer_destroy_vtbl; pcontext->transfer_inline_write = u_transfer_inline_write_vtbl; - pcontext->is_resource_referenced = nv50_resource_is_referenced; pcontext->create_surface = nv50_miptree_surface_new; pcontext->surface_destroy = nv50_miptree_surface_del; } diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index ae0365eb5c5..7690c80eef0 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -40,7 +40,7 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bindings, unsigned geom_flags) + unsigned bindings) { if (sample_count > 1) return FALSE; @@ -127,7 +127,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: return 0; case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_INSTANCED_DRAWING: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 980bc369293..db257159698 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -796,10 +796,13 @@ nv50_set_index_buffer(struct pipe_context *pipe, { struct nv50_context *nv50 = nv50_context(pipe); - if (ib) + if (ib) { + pipe_resource_reference(&nv50->idxbuf.buffer, ib->buffer); + memcpy(&nv50->idxbuf, ib, sizeof(nv50->idxbuf)); - else - nv50->idxbuf.buffer = NULL; + } else { + pipe_resource_reference(&nv50->idxbuf.buffer, NULL); + } } static void @@ -866,5 +869,7 @@ nv50_init_state_functions(struct nv50_context *nv50) pipe->set_vertex_buffers = nv50_set_vertex_buffers; pipe->set_index_buffer = nv50_set_index_buffer; + + pipe->redefine_user_buffer = u_default_redefine_user_buffer; } diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index bf46296e7ef..f3d45eb95e0 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -43,8 +43,9 @@ nv50_validate_fb(struct nv50_context *nv50) mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; + /* only register for writing, otherwise we'd always serialize here */ nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); } if (fb->zsbuf) { @@ -74,7 +75,7 @@ nv50_validate_fb(struct nv50_context *nv50) mt->base.status &= NOUVEAU_BUFFER_STATUS_GPU_READING; nv50_bufctx_add_resident(nv50, NV50_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); } else { BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); OUT_RING (chan, 0); @@ -253,6 +254,35 @@ nv50_validate_rasterizer(struct nv50_context *nv50) OUT_RINGp(chan, nv50->rast->state, nv50->rast->size); } +static void +nv50_switch_pipe_context(struct nv50_context *ctx_to) +{ + struct nv50_context *ctx_from = ctx_to->screen->cur_ctx; + + if (ctx_from) + ctx_to->state = ctx_from->state; + + ctx_to->dirty = ~0; + + if (!ctx_to->vertex) + ctx_to->dirty &= ~(NV50_NEW_VERTEX | NV50_NEW_ARRAYS); + + if (!ctx_to->vertprog) + ctx_to->dirty &= ~NV50_NEW_VERTPROG; + if (!ctx_to->fragprog) + ctx_to->dirty &= ~NV50_NEW_FRAGPROG; + + if (!ctx_to->blend) + ctx_to->dirty &= ~NV50_NEW_BLEND; + if (!ctx_to->rast) + ctx_to->dirty &= ~NV50_NEW_RASTERIZER; + if (!ctx_to->zsa) + ctx_to->dirty &= ~NV50_NEW_ZSA; + + ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx = + ctx_to; +} + static struct state_validate { void (*func)(struct nv50_context *); uint32_t states; @@ -292,11 +322,9 @@ boolean nv50_state_validate(struct nv50_context *nv50) { unsigned i; -#if 0 - if (nv50->screen->cur_ctx != nv50) /* FIXME: not everything is valid */ - nv50->dirty = 0xffffffff; -#endif - nv50->screen->cur_ctx = nv50; + + if (nv50->screen->cur_ctx != nv50) + nv50_switch_pipe_context(nv50); if (nv50->dirty) { for (i = 0; i < validate_list_len; ++i) { diff --git a/src/gallium/drivers/nv50/nv50_stateobj.h b/src/gallium/drivers/nv50/nv50_stateobj.h index cf5b92ef1a8..515e3e78d42 100644 --- a/src/gallium/drivers/nv50/nv50_stateobj.h +++ b/src/gallium/drivers/nv50/nv50_stateobj.h @@ -49,7 +49,7 @@ struct nv50_vertex_stateobj { boolean need_conversion; unsigned vertex_size; unsigned packet_vertex_limit; - struct nv50_vertex_element element[1]; + struct nv50_vertex_element element[0]; }; #endif diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index 4f0a5018459..abdb9ce2f93 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -51,10 +51,8 @@ nv50_vertex_state_create(struct pipe_context *pipe, struct translate_key transkey; unsigned i; - assert(num_elements); - so = MALLOC(sizeof(*so) + - (num_elements - 1) * sizeof(struct nv50_vertex_element)); + num_elements * sizeof(struct nv50_vertex_element)); if (!so) return NULL; so->num_elements = num_elements; diff --git a/src/gallium/drivers/nvc0/nvc0_3d.xml.h b/src/gallium/drivers/nvc0/nvc0_3d.xml.h index 5857f7cee9e..94fa081ad7e 100644 --- a/src/gallium/drivers/nvc0/nvc0_3d.xml.h +++ b/src/gallium/drivers/nvc0/nvc0_3d.xml.h @@ -927,6 +927,15 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define NVC0_3D_ZETA_BASE_LAYER 0x0000179c +#define NVC0_3D_VERTEX_QUARANTINE_ADDRESS_HIGH 0x000017bc + +#define NVC0_3D_VERTEX_QUARANTINE_ADDRESS_LOW 0x000017c0 + +#define NVC0_3D_VERTEX_QUARANTINE_SIZE 0x000017c4 +#define NVC0_3D_VERTEX_QUARANTINE_SIZE_16K 0x00000001 +#define NVC0_3D_VERTEX_QUARANTINE_SIZE_32K 0x00000002 +#define NVC0_3D_VERTEX_QUARANTINE_SIZE_64K 0x00000003 + #define NVC0_3D_STRMOUT_UNK1780(i0) (0x00001780 + 0x4*(i0)) #define NVC0_3D_STRMOUT_UNK1780__ESIZE 0x00000004 #define NVC0_3D_STRMOUT_UNK1780__LEN 0x00000004 diff --git a/src/gallium/drivers/nvc0/nvc0_context.c b/src/gallium/drivers/nvc0/nvc0_context.c index d6de979b132..5d2168e600b 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.c +++ b/src/gallium/drivers/nvc0/nvc0_context.c @@ -30,29 +30,45 @@ #include "nouveau/nouveau_reloc.h" static void -nvc0_flush(struct pipe_context *pipe, unsigned flags, +nvc0_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence) { - struct nvc0_context *nvc0 = nvc0_context(pipe); - struct nouveau_channel *chan = nvc0->screen->base.channel; - - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { - BEGIN_RING(chan, RING_3D(SERIALIZE), 1); - OUT_RING (chan, 0); - BEGIN_RING(chan, RING_3D(TEX_CACHE_CTL), 1); - OUT_RING (chan, 0x00); - } else - if ((flags & PIPE_FLUSH_RENDER_CACHE) && !(flags & PIPE_FLUSH_FRAME)) { - BEGIN_RING(chan, RING_3D(SERIALIZE), 1); - OUT_RING (chan, 0); - } + struct nouveau_screen *screen = &nvc0_context(pipe)->screen->base; if (fence) - nouveau_fence_ref(nvc0->screen->base.fence.current, - (struct nouveau_fence **)fence); + nouveau_fence_ref(screen->fence.current, (struct nouveau_fence **)fence); + + /* Try to emit before firing to avoid having to flush again right after + * in case we have to wait on this fence. + */ + nouveau_fence_emit(screen->fence.current); + + FIRE_RING(screen->channel); +} + +static void +nvc0_context_unreference_resources(struct nvc0_context *nvc0) +{ + unsigned s, i; + + for (i = 0; i < NVC0_BUFCTX_COUNT; ++i) + nvc0_bufctx_reset(nvc0, i); + + for (i = 0; i < nvc0->num_vtxbufs; ++i) + pipe_resource_reference(&nvc0->vtxbuf[i].buffer, NULL); + + pipe_resource_reference(&nvc0->idxbuf.buffer, NULL); - if (flags & (PIPE_FLUSH_SWAPBUFFERS | PIPE_FLUSH_FRAME)) - FIRE_RING(chan); + for (s = 0; s < 5; ++s) { + for (i = 0; i < nvc0->num_textures[s]; ++i) + pipe_sampler_view_reference(&nvc0->textures[s][i], NULL); + + for (i = 0; i < 16; ++i) + pipe_resource_reference(&nvc0->constbuf[s][i], NULL); + } + + for (i = 0; i < nvc0->num_tfbbufs; ++i) + pipe_resource_reference(&nvc0->tfbbuf[i], NULL); } static void @@ -60,6 +76,8 @@ nvc0_destroy(struct pipe_context *pipe) { struct nvc0_context *nvc0 = nvc0_context(pipe); + nvc0_context_unreference_resources(nvc0); + draw_destroy(nvc0->draw); if (nvc0->screen->cur_ctx == nvc0) { diff --git a/src/gallium/drivers/nvc0/nvc0_context.h b/src/gallium/drivers/nvc0/nvc0_context.h index 67c5a1287b1..102997e4fcb 100644 --- a/src/gallium/drivers/nvc0/nvc0_context.h +++ b/src/gallium/drivers/nvc0/nvc0_context.h @@ -79,6 +79,7 @@ struct nvc0_context { uint32_t instance_base; int32_t index_bias; boolean prim_restart; + boolean early_z; uint8_t num_vtxbufs; uint8_t num_vtxelts; uint8_t num_textures[5]; @@ -135,6 +136,9 @@ struct nvc0_context { struct draw_context *draw; }; +#define NVC0_USING_EDGEFLAG(ctx) \ + ((ctx)->vertprog->vp.edgeflag < PIPE_MAX_ATTRIBS) + static INLINE struct nvc0_context * nvc0_context(struct pipe_context *pipe) { diff --git a/src/gallium/drivers/nvc0/nvc0_graph_macros.h b/src/gallium/drivers/nvc0/nvc0_graph_macros.h index 8da963a4c5b..b7d0d3eafa4 100644 --- a/src/gallium/drivers/nvc0/nvc0_graph_macros.h +++ b/src/gallium/drivers/nvc0/nvc0_graph_macros.h @@ -144,7 +144,7 @@ static const uint32_t nvc0_9097_poly_mode_back[] = 0x00180611, /* 0x05: mov $r6 0x60 */ 0x0014bf10, /* 0x06: mov $r7 and $r7 $r2 */ 0x0000f807, /* 0x07: braz $r7 0xa */ - 0x00dac021, /* 0x08: maddr 0x36b */ + 0x00db0021, /* 0x08: maddr 0x36c */ 0x00800611, /* 0x09: mov $r6 0x200 */ 0x00131f10, /* 0x0a: mov $r7 or $r3 $r4 */ 0x0014bf10, /* 0x0b: mov $r7 and $r7 $r2 */ diff --git a/src/gallium/drivers/nvc0/nvc0_miptree.c b/src/gallium/drivers/nvc0/nvc0_miptree.c index db9117c3ff1..bced3245524 100644 --- a/src/gallium/drivers/nvc0/nvc0_miptree.c +++ b/src/gallium/drivers/nvc0/nvc0_miptree.c @@ -114,7 +114,6 @@ const struct u_resource_vtbl nvc0_miptree_vtbl = { nvc0_miptree_get_handle, /* get_handle */ nvc0_miptree_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ nvc0_miptree_transfer_new, /* get_transfer */ nvc0_miptree_transfer_del, /* transfer_destroy */ nvc0_miptree_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/nvc0/nvc0_pc.c b/src/gallium/drivers/nvc0/nvc0_pc.c index f51d289e8cd..bd85a7f1ffd 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc.c +++ b/src/gallium/drivers/nvc0/nvc0_pc.c @@ -25,6 +25,14 @@ #include "nvc0_pc.h" #include "nvc0_program.h" +uint8_t +nvc0_ir_reverse_cc(uint8_t cc) +{ + static const uint8_t cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; + + return cc_swapped[cc & 7] | (cc & ~7); +} + boolean nvc0_insn_can_load(struct nv_instruction *nvi, int s, struct nv_instruction *ld) diff --git a/src/gallium/drivers/nvc0/nvc0_pc.h b/src/gallium/drivers/nvc0/nvc0_pc.h index efa073a9201..3a5612a5fac 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc.h +++ b/src/gallium/drivers/nvc0/nvc0_pc.h @@ -210,6 +210,8 @@ #define NV_CC_P 0 #define NV_CC_NOT_P 1 +uint8_t nvc0_ir_reverse_cc(uint8_t cc); + #define NV_PC_MAX_INSTRUCTIONS 2048 #define NV_PC_MAX_VALUES (NV_PC_MAX_INSTRUCTIONS * 4) @@ -219,7 +221,7 @@ struct nv_op_info { uint base; /* e.g. ADD_S32 -> ADD */ char name[12]; uint8_t type; - uint8_t mods; + uint16_t mods; unsigned flow : 1; unsigned commutative : 1; unsigned vector : 1; @@ -234,12 +236,6 @@ extern struct nv_op_info nvc0_op_info_table[]; #define NV_BASEOP(op) (nvc0_op_info_table[op].base) #define NV_OPTYPE(op) (nvc0_op_info_table[op].type) -static INLINE uint -nv_op_base(uint opcode) -{ - return nvc0_op_info_table[opcode].base; -} - static INLINE boolean nv_is_texture_op(uint opcode) { @@ -259,9 +255,9 @@ nv_op_commutative(uint opcode) } static INLINE uint8_t -nv_op_supported_src_mods(uint opcode) +nv_op_supported_src_mods(uint opcode, int s) { - return nvc0_op_info_table[opcode].mods; + return (nvc0_op_info_table[opcode].mods >> (s * 4)) & 0xf; } static INLINE uint diff --git a/src/gallium/drivers/nvc0/nvc0_pc_emit.c b/src/gallium/drivers/nvc0/nvc0_pc_emit.c index c10f920e6f1..76ad40dbcf8 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc_emit.c +++ b/src/gallium/drivers/nvc0/nvc0_pc_emit.c @@ -610,6 +610,8 @@ emit_selp(struct nv_pc *pc, struct nv_instruction *i) static void emit_slct(struct nv_pc *pc, struct nv_instruction *i) { + uint8_t cc = i->set_cond; + pc->emit[0] = 0x00000000; switch (i->opcode) { @@ -627,7 +629,10 @@ emit_slct(struct nv_pc *pc, struct nv_instruction *i) emit_form_0(pc, i); - pc->emit[1] |= i->set_cond << 23; + if (i->src[2]->mod & NV_MOD_NEG) + cc = nvc0_ir_reverse_cc(cc); + + pc->emit[1] |= cc << 23; } static void diff --git a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c index c5a7367a5fd..f7bf1680d09 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc_optimize.c +++ b/src/gallium/drivers/nvc0/nvc0_pc_optimize.c @@ -240,8 +240,6 @@ is_immd32_load(struct nv_instruction *nvi) static INLINE void check_swap_src_0_1(struct nv_instruction *nvi) { - static const uint8_t cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 }; - struct nv_ref *src0 = nvi->src[0]; struct nv_ref *src1 = nvi->src[1]; @@ -270,7 +268,7 @@ check_swap_src_0_1(struct nv_instruction *nvi) if (nvi->src[0] != src0) { if (NV_BASEOP(nvi->opcode) == NV_OP_SET) - nvi->set_cond = (nvi->set_cond & ~7) | cc_swapped[nvi->set_cond & 7]; + nvi->set_cond = nvc0_ir_reverse_cc(nvi->set_cond); else if (NV_BASEOP(nvi->opcode) == NV_OP_SLCT) nvi->set_cond = NV_CC_INVERSE(nvi->set_cond); @@ -363,7 +361,7 @@ nv_pass_lower_mods(struct nv_pass *ctx, struct nv_basic_block *b) mod = 0; } - if ((nv_op_supported_src_mods(nvi->opcode) & mod) != mod) + if ((nv_op_supported_src_mods(nvi->opcode, j) & mod) != mod) continue; nv_reference(ctx->pc, nvi, j, mi->src[0]->value); diff --git a/src/gallium/drivers/nvc0/nvc0_pc_print.c b/src/gallium/drivers/nvc0/nvc0_pc_print.c index 90c669cc4b8..1f37cb802d7 100644 --- a/src/gallium/drivers/nvc0/nvc0_pc_print.c +++ b/src/gallium/drivers/nvc0/nvc0_pc_print.c @@ -269,7 +269,11 @@ nvc0_print_instruction(struct nv_instruction *i) PRINT(" %s\n", norm); } -#define NV_MOD_SGN NV_MOD_ABS | NV_MOD_NEG +#define NV_MOD_SGN_12 ((NV_MOD_ABS | NV_MOD_NEG) | ((NV_MOD_ABS | NV_MOD_NEG) << 4)) +#define NV_MOD_NEG_123 (NV_MOD_NEG | (NV_MOD_NEG << 4) | (NV_MOD_NEG << 8)) +#define NV_MOD_NEG_3 (NV_MOD_NEG << 8) + +#define NV_MOD_SGN NV_MOD_SGN_12 struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] = { @@ -292,8 +296,8 @@ struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] = { NV_OP_SET, "set", NV_TYPE_ANY, NV_MOD_SGN, 0, 0, 0, 1, 0, 0, 0 }, { NV_OP_ADD, "add", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 }, { NV_OP_SUB, "sub", NV_TYPE_F32, NV_MOD_SGN, 0, 0, 0, 1, 0, 2, 2 }, - { NV_OP_MUL, "mul", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 }, - { NV_OP_MAD, "mad", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 }, + { NV_OP_MUL, "mul", NV_TYPE_F32, NV_MOD_NEG_123, 0, 1, 0, 1, 0, 2, 2 }, + { NV_OP_MAD, "mad", NV_TYPE_F32, NV_MOD_NEG_123, 0, 1, 0, 1, 0, 2, 2 }, { NV_OP_ABS, "abs", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 0, 0 }, { NV_OP_NEG, "neg", NV_TYPE_F32, NV_MOD_ABS, 0, 0, 0, 1, 0, 0, 0 }, { NV_OP_MAX, "max", NV_TYPE_F32, NV_MOD_SGN, 0, 1, 0, 1, 0, 2, 2 }, @@ -363,9 +367,9 @@ struct nv_op_info nvc0_op_info_table[NV_OP_COUNT + 1] = { NV_OP_SELP, "selp", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 0, 0 }, - { NV_OP_SLCT, "slct", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 2, 2 }, - { NV_OP_SLCT, "slct", NV_TYPE_S32, 0, 0, 0, 0, 1, 0, 2, 2 }, - { NV_OP_SLCT, "slct", NV_TYPE_U32, 0, 0, 0, 0, 1, 0, 2, 2 }, + { NV_OP_SLCT, "slct", NV_TYPE_F32, NV_MOD_NEG_3, 0, 0, 0, 1, 0, 2, 2 }, + { NV_OP_SLCT, "slct", NV_TYPE_S32, NV_MOD_NEG_3, 0, 0, 0, 1, 0, 2, 2 }, + { NV_OP_SLCT, "slct", NV_TYPE_U32, NV_MOD_NEG_3, 0, 0, 0, 1, 0, 2, 2 }, { NV_OP_ADD, "sub", NV_TYPE_F32, 0, 0, 0, 0, 1, 0, 1, 0 }, diff --git a/src/gallium/drivers/nvc0/nvc0_program.c b/src/gallium/drivers/nvc0/nvc0_program.c index 899fe147c6a..3c59213176e 100644 --- a/src/gallium/drivers/nvc0/nvc0_program.c +++ b/src/gallium/drivers/nvc0/nvc0_program.c @@ -202,6 +202,8 @@ nvc0_varying_location(unsigned sn, unsigned si) return 0x40; case TGSI_SEMANTIC_FACE: return 0x3fc; + case TGSI_SEMANTIC_EDGEFLAG: /* doesn't exist, set value like for an sreg */ + return 0xf00; /* case TGSI_SEMANTIC_CLIP_DISTANCE: return 0x2c0 + (si * 4); @@ -290,6 +292,8 @@ prog_decl(struct nvc0_translation_info *ti, ti->output_loc[i][c] = si * 4 + c; } } else { + if (sn == TGSI_SEMANTIC_EDGEFLAG) + ti->edgeflag_out = i; for (c = 0; c < 4; ++c) ti->output_loc[i][c] = nvc0_varying_location(sn, si) + c * 4; /* for TFB_VARYING_LOCS: */ @@ -298,6 +302,7 @@ prog_decl(struct nvc0_translation_info *ti, } break; case TGSI_FILE_SYSTEM_VALUE: + i = first; ti->sysval_loc[i] = nvc0_system_value_location(sn, si, &ti->sysval_in[i]); assert(first == last); break; @@ -426,6 +431,8 @@ nvc0_vp_gp_gen_header(struct nvc0_program *vp, struct nvc0_translation_info *ti) for (i = 0; i <= ti->scan.file_max[TGSI_FILE_OUTPUT]; ++i) { a = (ti->output_loc[i][0] - 0x40) / 4; + if (ti->output_loc[i][0] >= 0xf00) + continue; for (c = 0; c < 4; ++c, ++a) { if (!ti->output_access[i][c]) continue; @@ -528,7 +535,7 @@ nvc0_fp_gen_header(struct nvc0_program *fp, struct nvc0_translation_info *ti) } for (i = 0; i <= ti->scan.file_max[TGSI_FILE_INPUT]; ++i) { - m = ti->interp_mode[i]; + m = ti->interp_mode[i] & 3; for (c = 0; c < 4; ++c) { if (!ti->input_access[i][c]) continue; @@ -669,6 +676,8 @@ nvc0_program_translate(struct nvc0_program *prog) ti->edgeflag_out = PIPE_MAX_SHADER_OUTPUTS; + prog->vp.edgeflag = PIPE_MAX_ATTRIBS; + if (prog->type == PIPE_SHADER_VERTEX && prog->vp.num_ucps) ti->append_ucp = TRUE; diff --git a/src/gallium/drivers/nvc0/nvc0_push.c b/src/gallium/drivers/nvc0/nvc0_push.c index 68544c90d29..2e9f4c10928 100644 --- a/src/gallium/drivers/nvc0/nvc0_push.c +++ b/src/gallium/drivers/nvc0/nvc0_push.c @@ -15,9 +15,6 @@ struct push_context { void *idxbuf; - float edgeflag; - int edgeflag_attr; - uint32_t vertex_words; uint32_t packet_vertex_limit; @@ -27,8 +24,56 @@ struct push_context { uint32_t prim; uint32_t restart_index; uint32_t instance_id; + + struct { + int buffer; + float value; + uint8_t *data; + unsigned offset; + unsigned stride; + } edgeflag; }; +static void +init_push_context(struct nvc0_context *nvc0, struct push_context *ctx) +{ + struct pipe_vertex_element *ve; + + ctx->chan = nvc0->screen->base.channel; + ctx->translate = nvc0->vertex->translate; + + ctx->edgeflag.value = 0.5f; + + if (NVC0_USING_EDGEFLAG(nvc0)) { + ve = &nvc0->vertex->element[nvc0->vertprog->vp.edgeflag].pipe; + + ctx->edgeflag.buffer = ve->vertex_buffer_index; + ctx->edgeflag.offset = ve->src_offset; + + ctx->packet_vertex_limit = 1; + } else { + ctx->edgeflag.buffer = -1; + ctx->edgeflag.offset = 0; + ctx->edgeflag.stride = 0; + ctx->edgeflag.data = NULL; + + ctx->packet_vertex_limit = nvc0->vertex->vtx_per_packet_max; + } + + ctx->vertex_words = nvc0->vertex->vtx_size; +} + +static INLINE void +set_edgeflag(struct push_context *ctx, unsigned vtx_id) +{ + float f = *(float *)(ctx->edgeflag.data + vtx_id * ctx->edgeflag.stride); + + if (ctx->edgeflag.value != f) { + ctx->edgeflag.value = f; + IMMED_RING(ctx->chan, RING_3D(EDGEFLAG_ENABLE), f ? 1 : 0); + } +} + static INLINE unsigned prim_restart_search_i08(uint8_t *elts, unsigned push, uint8_t index) { @@ -62,7 +107,7 @@ prim_restart_search_i32(uint32_t *elts, unsigned push, uint32_t index) static void emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) { - uint8_t *elts = (uint8_t *)ctx->idxbuf + start; + uint8_t *restrict elts = (uint8_t *)ctx->idxbuf + start; while (count) { unsigned push = MIN2(count, ctx->packet_vertex_limit); @@ -72,6 +117,9 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) if (ctx->primitive_restart) nr = prim_restart_search_i08(elts, push, ctx->restart_index); + if (unlikely(ctx->edgeflag.buffer >= 0) && nr) + set_edgeflag(ctx, elts[0]); + size = ctx->vertex_words * nr; BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); @@ -97,7 +145,7 @@ emit_vertices_i08(struct push_context *ctx, unsigned start, unsigned count) static void emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) { - uint16_t *elts = (uint16_t *)ctx->idxbuf + start; + uint16_t *restrict elts = (uint16_t *)ctx->idxbuf + start; while (count) { unsigned push = MIN2(count, ctx->packet_vertex_limit); @@ -107,6 +155,9 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) if (ctx->primitive_restart) nr = prim_restart_search_i16(elts, push, ctx->restart_index); + if (unlikely(ctx->edgeflag.buffer >= 0) && nr) + set_edgeflag(ctx, elts[0]); + size = ctx->vertex_words * nr; BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); @@ -132,7 +183,7 @@ emit_vertices_i16(struct push_context *ctx, unsigned start, unsigned count) static void emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) { - uint32_t *elts = (uint32_t *)ctx->idxbuf + start; + uint32_t *restrict elts = (uint32_t *)ctx->idxbuf + start; while (count) { unsigned push = MIN2(count, ctx->packet_vertex_limit); @@ -142,6 +193,9 @@ emit_vertices_i32(struct push_context *ctx, unsigned start, unsigned count) if (ctx->primitive_restart) nr = prim_restart_search_i32(elts, push, ctx->restart_index); + if (unlikely(ctx->edgeflag.buffer >= 0) && nr) + set_edgeflag(ctx, elts[0]); + size = ctx->vertex_words * nr; BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); @@ -171,6 +225,9 @@ emit_vertices_seq(struct push_context *ctx, unsigned start, unsigned count) unsigned push = MIN2(count, ctx->packet_vertex_limit); unsigned size = ctx->vertex_words * push; + if (unlikely(ctx->edgeflag.buffer >= 0)) + set_edgeflag(ctx, start); + BEGIN_RING_NI(ctx->chan, RING_3D(VERTEX_DATA), size); ctx->translate->run(ctx->translate, start, push, ctx->instance_id, @@ -219,10 +276,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) unsigned inst = info->instance_count; boolean apply_bias = info->indexed && info->index_bias; - ctx.chan = nvc0->screen->base.channel; - ctx.translate = nvc0->vertex->translate; - ctx.packet_vertex_limit = nvc0->vertex->vtx_per_packet_max; - ctx.vertex_words = nvc0->vertex->vtx_size; + init_push_context(nvc0, &ctx); for (i = 0; i < nvc0->num_vtxbufs; ++i) { uint8_t *data; @@ -236,12 +290,18 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) data += info->index_bias * vb->stride; ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0); + + if (unlikely(i == ctx.edgeflag.buffer)) { + ctx.edgeflag.data = data + ctx.edgeflag.offset; + ctx.edgeflag.stride = vb->stride; + } } if (info->indexed) { - ctx.idxbuf = nouveau_resource_map_offset(&nvc0->base, - nv04_resource(nvc0->idxbuf.buffer), - nvc0->idxbuf.offset, NOUVEAU_BO_RD); + ctx.idxbuf = + nouveau_resource_map_offset(&nvc0->base, + nv04_resource(nvc0->idxbuf.buffer), + nvc0->idxbuf.offset, NOUVEAU_BO_RD); if (!ctx.idxbuf) return; index_size = nvc0->idxbuf.index_size; @@ -283,6 +343,9 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) ctx.prim |= NVC0_3D_VERTEX_BEGIN_GL_INSTANCE_NEXT; } + if (unlikely(ctx.edgeflag.value == 0.0f)) + IMMED_RING(ctx.chan, RING_3D(EDGEFLAG_ENABLE), 1); + if (info->indexed) nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer)); diff --git a/src/gallium/drivers/nvc0/nvc0_resource.c b/src/gallium/drivers/nvc0/nvc0_resource.c index fb5a496b84b..44e66314e7e 100644 --- a/src/gallium/drivers/nvc0/nvc0_resource.c +++ b/src/gallium/drivers/nvc0/nvc0_resource.c @@ -3,25 +3,6 @@ #include "nvc0_resource.h" #include "nouveau/nouveau_screen.h" -static unsigned -nvc0_resource_is_referenced(struct pipe_context *pipe, - struct pipe_resource *resource, - unsigned face, int layer) -{ - struct nv04_resource *res = nv04_resource(resource); - unsigned flags = 0; - -#ifdef NOUVEAU_USERSPACE_MM - flags = res->status; -#else - unsigned bo_flags = nouveau_bo_pending(res->bo); - if (bo_flags & NOUVEAU_BO_RD) - flags = PIPE_REFERENCED_FOR_READ; - if (bo_flags & NOUVEAU_BO_WR) - flags |= PIPE_REFERENCED_FOR_WRITE; -#endif - return flags; -} static struct pipe_resource * nvc0_resource_create(struct pipe_screen *screen, @@ -55,7 +36,6 @@ nvc0_init_resource_functions(struct pipe_context *pcontext) pcontext->transfer_unmap = u_transfer_unmap_vtbl; pcontext->transfer_destroy = u_transfer_destroy_vtbl; pcontext->transfer_inline_write = u_transfer_inline_write_vtbl; - pcontext->is_resource_referenced = nvc0_resource_is_referenced; pcontext->create_surface = nvc0_miptree_surface_new; pcontext->surface_destroy = nvc0_miptree_surface_del; } diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c b/src/gallium/drivers/nvc0/nvc0_screen.c index d430be92c51..1047ba3c337 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.c +++ b/src/gallium/drivers/nvc0/nvc0_screen.c @@ -34,7 +34,7 @@ nvc0_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bindings, unsigned geom_flags) + unsigned bindings) { if (sample_count > 1) return FALSE; @@ -111,7 +111,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_STENCIL_EXPORT: return 0; case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_INSTANCED_DRAWING: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; default: NOUVEAU_ERR("unknown PIPE_CAP %d\n", param); @@ -206,7 +207,7 @@ nvc0_screen_destroy(struct pipe_screen *pscreen) nouveau_bo_ref(NULL, &screen->tls); nouveau_bo_ref(NULL, &screen->txc); nouveau_bo_ref(NULL, &screen->fence.bo); - nouveau_bo_ref(NULL, &screen->mp_stack_bo); + nouveau_bo_ref(NULL, &screen->vfetch_cache); nouveau_resource_destroy(&screen->text_heap); @@ -495,14 +496,14 @@ nvc0_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev) OUT_RING (chan, 0); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 20, - &screen->mp_stack_bo); + &screen->vfetch_cache); if (ret) goto fail; - BEGIN_RING(chan, RING_3D_(0x17bc), 3); - 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); + BEGIN_RING(chan, RING_3D(VERTEX_QUARANTINE_ADDRESS_HIGH), 3); + OUT_RELOCh(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RELOCl(chan, screen->vfetch_cache, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + OUT_RING (chan, 3); ret = nouveau_bo_new(dev, NOUVEAU_BO_VRAM, 1 << 17, 1 << 17, &screen->txc); if (ret) @@ -634,7 +635,7 @@ nvc0_screen_make_buffers_resident(struct nvc0_screen *screen) nouveau_bo_validate(chan, screen->text, flags); nouveau_bo_validate(chan, screen->uniforms, flags); nouveau_bo_validate(chan, screen->txc, flags); - nouveau_bo_validate(chan, screen->mp_stack_bo, flags); + nouveau_bo_validate(chan, screen->vfetch_cache, flags); if (screen->cur_ctx && screen->cur_ctx->state.tls_required) nouveau_bo_validate(chan, screen->tls, flags); diff --git a/src/gallium/drivers/nvc0/nvc0_screen.h b/src/gallium/drivers/nvc0/nvc0_screen.h index 81f404ada83..94bf0cf3481 100644 --- a/src/gallium/drivers/nvc0/nvc0_screen.h +++ b/src/gallium/drivers/nvc0/nvc0_screen.h @@ -26,7 +26,7 @@ struct nvc0_screen { struct nouveau_bo *uniforms; struct nouveau_bo *tls; struct nouveau_bo *txc; /* TIC (offset 0) and TSC (65536) */ - struct nouveau_bo *mp_stack_bo; + struct nouveau_bo *vfetch_cache; uint64_t tls_size; diff --git a/src/gallium/drivers/nvc0/nvc0_shader_state.c b/src/gallium/drivers/nvc0/nvc0_shader_state.c index 79b5f3d81cc..7294eaa222e 100644 --- a/src/gallium/drivers/nvc0/nvc0_shader_state.c +++ b/src/gallium/drivers/nvc0/nvc0_shader_state.c @@ -111,8 +111,6 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0) return; nvc0_program_update_context_state(nvc0, fp, 4); - BEGIN_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), 1); - 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 f230292316f..ab68abcfb5a 100644 --- a/src/gallium/drivers/nvc0/nvc0_state.c +++ b/src/gallium/drivers/nvc0/nvc0_state.c @@ -166,6 +166,7 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe, const struct pipe_rasterizer_state *cso) { struct nvc0_rasterizer_stateobj *so; + uint32_t reg; so = CALLOC_STRUCT(nvc0_rasterizer_stateobj); if (!so) @@ -202,6 +203,13 @@ nvc0_rasterizer_state_create(struct pipe_context *pipe, SB_BEGIN_3D(so, POINT_SIZE, 1); SB_DATA (so, fui(cso->point_size)); } + + reg = (cso->sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) ? + NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT : + NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT; + + SB_BEGIN_3D(so, POINT_COORD_REPLACE, 1); + SB_DATA (so, ((cso->sprite_coord_enable & 0xff) << 3) | reg); SB_IMMED_3D(so, POINT_SPRITE_ENABLE, cso->point_quad_rasterization); SB_IMMED_3D(so, POINT_SMOOTH_ENABLE, cso->point_smooth); @@ -268,14 +276,11 @@ nvc0_zsa_state_create(struct pipe_context *pipe, so->pipe = *cso; - SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask); - SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1); + SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth.enabled); if (cso->depth.enabled) { - SB_DATA (so, 1); + SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask); SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1); SB_DATA (so, nvgl_comparison_op(cso->depth.func)); - } else { - SB_DATA (so, 0); } if (cso->stencil[0].enabled) { @@ -307,15 +312,12 @@ nvc0_zsa_state_create(struct pipe_context *pipe, if (cso->stencil[0].enabled) { SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0); } - - SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1); + + SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha.enabled); if (cso->alpha.enabled) { - SB_DATA (so, 1); SB_BEGIN_3D(so, ALPHA_TEST_REF, 2); SB_DATA (so, fui(cso->alpha.ref_value)); SB_DATA (so, nvgl_comparison_op(cso->alpha.func)); - } else { - SB_DATA (so, 0); } assert(so->size < (sizeof(so->state) / sizeof(so->state[0]))); @@ -706,10 +708,13 @@ nvc0_set_index_buffer(struct pipe_context *pipe, { struct nvc0_context *nvc0 = nvc0_context(pipe); - if (ib) - memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf)); - else - nvc0->idxbuf.buffer = NULL; + if (ib) { + pipe_resource_reference(&nvc0->idxbuf.buffer, ib->buffer); + + memcpy(&nvc0->idxbuf, ib, sizeof(nvc0->idxbuf)); + } else { + pipe_resource_reference(&nvc0->idxbuf.buffer, NULL); + } } static void diff --git a/src/gallium/drivers/nvc0/nvc0_state_validate.c b/src/gallium/drivers/nvc0/nvc0_state_validate.c index 6fd880829e4..bb81480bab9 100644 --- a/src/gallium/drivers/nvc0/nvc0_state_validate.c +++ b/src/gallium/drivers/nvc0/nvc0_state_validate.c @@ -93,8 +93,9 @@ nvc0_validate_fb(struct nvc0_context *nvc0) mt->base.status |= NOUVEAU_BUFFER_STATUS_GPU_WRITING; mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; + /* only register for writing, otherwise we'd always serialize here */ nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); } if (fb->zsbuf) { @@ -127,7 +128,7 @@ nvc0_validate_fb(struct nvc0_context *nvc0) mt->base.status &= ~NOUVEAU_BUFFER_STATUS_GPU_READING; nvc0_bufctx_add_resident(nvc0, NVC0_BUFCTX_FRAME, &mt->base, - NOUVEAU_BO_VRAM | NOUVEAU_BO_RDWR); + NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); } else { BEGIN_RING(chan, RING_3D(ZETA_ENABLE), 1); OUT_RING (chan, 0); @@ -294,32 +295,6 @@ nvc0_validate_rasterizer(struct nvc0_context *nvc0) } static void -nvc0_validate_sprite_coords(struct nvc0_context *nvc0) -{ - struct nouveau_channel *chan = nvc0->screen->base.channel; - uint32_t reg; - - if (nvc0->rast->pipe.sprite_coord_mode == PIPE_SPRITE_COORD_UPPER_LEFT) - reg = NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_UPPER_LEFT; - else - reg = NVC0_3D_POINT_COORD_REPLACE_COORD_ORIGIN_LOWER_LEFT; - - if (nvc0->rast->pipe.point_quad_rasterization) { - uint32_t en = nvc0->rast->pipe.sprite_coord_enable; - - while (en) { - int i = ffs(en) - 1; - en &= ~(1 << i); - if (i >= 0 && i < 8) - reg |= 8 << i; - } - } - - BEGIN_RING(chan, RING_3D(POINT_COORD_REPLACE), 1); - OUT_RING (chan, reg); -} - -static void nvc0_constbufs_validate(struct nvc0_context *nvc0) { struct nouveau_channel *chan = nvc0->screen->base.channel; @@ -413,6 +388,49 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0) } } +static void +nvc0_validate_derived_1(struct nvc0_context *nvc0) +{ + struct nouveau_channel *chan = nvc0->screen->base.channel; + boolean early_z; + + early_z = nvc0->fragprog->fp.early_z && !nvc0->zsa->pipe.alpha.enabled; + + if (early_z != nvc0->state.early_z) { + nvc0->state.early_z = early_z; + IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z); + } +} + +static void +nvc0_switch_pipe_context(struct nvc0_context *ctx_to) +{ + struct nvc0_context *ctx_from = ctx_to->screen->cur_ctx; + + if (ctx_from) + ctx_to->state = ctx_from->state; + + ctx_to->dirty = ~0; + + if (!ctx_to->vertex) + ctx_to->dirty &= ~(NVC0_NEW_VERTEX | NVC0_NEW_ARRAYS); + + if (!ctx_to->vertprog) + ctx_to->dirty &= ~NVC0_NEW_VERTPROG; + if (!ctx_to->fragprog) + ctx_to->dirty &= ~NVC0_NEW_FRAGPROG; + + if (!ctx_to->blend) + ctx_to->dirty &= ~NVC0_NEW_BLEND; + if (!ctx_to->rast) + ctx_to->dirty &= ~NVC0_NEW_RASTERIZER; + if (!ctx_to->zsa) + ctx_to->dirty &= ~NVC0_NEW_ZSA; + + ctx_to->screen->base.channel->user_private = ctx_to->screen->cur_ctx = + ctx_to; +} + static struct state_validate { void (*func)(struct nvc0_context *); uint32_t states; @@ -432,7 +450,7 @@ static struct state_validate { { nvc0_tevlprog_validate, NVC0_NEW_TEVLPROG }, { nvc0_gmtyprog_validate, NVC0_NEW_GMTYPROG }, { nvc0_fragprog_validate, NVC0_NEW_FRAGPROG }, - { nvc0_validate_sprite_coords, NVC0_NEW_RASTERIZER | NVC0_NEW_FRAGPROG }, + { nvc0_validate_derived_1, NVC0_NEW_FRAGPROG | NVC0_NEW_ZSA }, { nvc0_constbufs_validate, NVC0_NEW_CONSTBUF }, { nvc0_validate_textures, NVC0_NEW_TEXTURES }, { nvc0_validate_samplers, NVC0_NEW_SAMPLERS }, @@ -445,11 +463,9 @@ boolean nvc0_state_validate(struct nvc0_context *nvc0) { unsigned i; -#if 0 - if (nvc0->screen->cur_ctx != nvc0) /* FIXME: not everything is valid */ - nvc0->dirty = 0xffffffff; -#endif - nvc0->screen->cur_ctx = nvc0; + + if (nvc0->screen->cur_ctx != nvc0) + nvc0_switch_pipe_context(nvc0); if (nvc0->dirty) { for (i = 0; i < validate_list_len; ++i) { diff --git a/src/gallium/drivers/nvc0/nvc0_surface.c b/src/gallium/drivers/nvc0/nvc0_surface.c index 17fc51b8aac..fc5f45ea25d 100644 --- a/src/gallium/drivers/nvc0/nvc0_surface.c +++ b/src/gallium/drivers/nvc0/nvc0_surface.c @@ -240,7 +240,7 @@ nvc0_resource_copy_region(struct pipe_context *pipe, struct nvc0_m2mf_rect drect, srect; unsigned i; unsigned nx = util_format_get_nblocksx(src->format, src_box->width); - unsigned ny = util_format_get_nblocksx(src->format, src_box->height); + unsigned ny = util_format_get_nblocksy(src->format, src_box->height); nvc0_setup_m2mf_rect(&drect, dst, dst_level, dstx, dsty, dstz); nvc0_setup_m2mf_rect(&srect, src, src_level, diff --git a/src/gallium/drivers/nvc0/nvc0_vbo.c b/src/gallium/drivers/nvc0/nvc0_vbo.c index e7e7ce7dc22..6bbcf2447ec 100644 --- a/src/gallium/drivers/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nvc0/nvc0_vbo.c @@ -51,8 +51,6 @@ nvc0_vertex_state_create(struct pipe_context *pipe, struct translate_key transkey; unsigned i; - assert(num_elements); - so = MALLOC(sizeof(*so) + num_elements * sizeof(struct nvc0_vertex_element)); if (!so) @@ -265,7 +263,7 @@ nvc0_vertex_arrays_validate(struct nvc0_context *nvc0) struct nvc0_vertex_element *ve; unsigned i; - if (unlikely(vertex->need_conversion)) { + if (unlikely(vertex->need_conversion || NVC0_USING_EDGEFLAG(nvc0))) { nvc0->vbo_fifo = ~0; nvc0->vbo_user = 0; } else { diff --git a/src/gallium/drivers/nvfx/nvfx_context.c b/src/gallium/drivers/nvfx/nvfx_context.c index 6c8934d3a4a..2bcb93d93e3 100644 --- a/src/gallium/drivers/nvfx/nvfx_context.c +++ b/src/gallium/drivers/nvfx/nvfx_context.c @@ -7,7 +7,7 @@ #include "nvfx_resource.h" static void -nvfx_flush(struct pipe_context *pipe, unsigned flags, +nvfx_flush(struct pipe_context *pipe, struct pipe_fence_handle **fence) { struct nvfx_context *nvfx = nvfx_context(pipe); @@ -16,12 +16,13 @@ nvfx_flush(struct pipe_context *pipe, unsigned flags, struct nouveau_grobj *eng3d = screen->eng3d; /* XXX: we need to actually be intelligent here */ - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + /* XXX This flag wasn't set by the state tracker anyway. */ + /*if (flags & PIPE_FLUSH_TEXTURE_CACHE) { BEGIN_RING(chan, eng3d, 0x1fd8, 1); OUT_RING(chan, 2); BEGIN_RING(chan, eng3d, 0x1fd8, 1); OUT_RING(chan, 1); - } + }*/ FIRE_RING(chan); if (fence) diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c index 8c043b867ba..1be84b90a90 100644 --- a/src/gallium/drivers/nvfx/nvfx_miptree.c +++ b/src/gallium/drivers/nvfx/nvfx_miptree.c @@ -138,11 +138,11 @@ nvfx_miptree_create_skeleton(struct pipe_screen *pscreen, const struct pipe_reso // on our current driver (and the driver too), format support does not depend on geometry, so don't bother computing it // TODO: may want to revisit this - if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_RENDER_TARGET, 0)) + if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_RENDER_TARGET)) mt->base.base.bind &=~ PIPE_BIND_RENDER_TARGET; - if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_SAMPLER_VIEW, 0)) + if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_SAMPLER_VIEW)) mt->base.base.bind &=~ PIPE_BIND_SAMPLER_VIEW; - if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_DEPTH_STENCIL, 0)) + if(!pscreen->is_format_supported(pscreen, pt->format, pt->target, 0, PIPE_BIND_DEPTH_STENCIL)) mt->base.base.bind &=~ PIPE_BIND_DEPTH_STENCIL; return mt; diff --git a/src/gallium/drivers/nvfx/nvfx_resource.c b/src/gallium/drivers/nvfx/nvfx_resource.c index c60a7bb8b93..42e77c53621 100644 --- a/src/gallium/drivers/nvfx/nvfx_resource.c +++ b/src/gallium/drivers/nvfx/nvfx_resource.c @@ -4,13 +4,6 @@ #include "nvfx_resource.h" #include "nouveau/nouveau_screen.h" -static unsigned int -nvfx_resource_is_referenced(struct pipe_context *pipe, - struct pipe_resource *pr, - unsigned level, int layer) -{ - return !!nouveau_reference_flags(nvfx_resource(pr)->bo); -} static struct pipe_resource * nvfx_resource_create(struct pipe_screen *screen, @@ -58,8 +51,6 @@ nvfx_resource_get_handle(struct pipe_screen *pscreen, void nvfx_init_resource_functions(struct pipe_context *pipe) { - pipe->is_resource_referenced = nvfx_resource_is_referenced; - pipe->create_surface = nvfx_miptree_surface_new; pipe->surface_destroy = nvfx_miptree_surface_del; } diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c index 15db574a1d0..8742f60c163 100644 --- a/src/gallium/drivers/nvfx/nvfx_screen.c +++ b/src/gallium/drivers/nvfx/nvfx_screen.c @@ -203,7 +203,7 @@ nvfx_screen_is_format_supported(struct pipe_screen *pscreen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bind, unsigned geom_flags) + unsigned bind) { struct nvfx_screen *screen = nvfx_screen(pscreen); diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c index 40ae4f5bd21..ae9c31418c3 100644 --- a/src/gallium/drivers/nvfx/nvfx_state_emit.c +++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c @@ -426,7 +426,7 @@ nvfx_state_validate_swtnl(struct nvfx_context *nvfx) NOUVEAU_ERR("hw->swtnl 0x%08x\n", nvfx->fallback_swtnl); warned = TRUE; } - nvfx->pipe.flush(&nvfx->pipe, 0, NULL); + nvfx->pipe.flush(&nvfx->pipe, NULL); nvfx->dirty |= (NVFX_NEW_VIEWPORT | NVFX_NEW_VERTPROG | NVFX_NEW_ARRAYS); diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index 6391ea7f3be..37b635fd120 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -263,7 +263,7 @@ static void r300_clear(struct pipe_context* pipe, /* Reserve CS space. */ if (dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) { - r300->context.flush(&r300->context, 0, NULL); + r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL); } /* Emit clear packets. */ @@ -447,11 +447,11 @@ static void r300_resource_copy_region(struct pipe_context *pipe, !pipe->screen->is_format_supported(pipe->screen, src->format, src->target, src->nr_samples, - PIPE_BIND_SAMPLER_VIEW, 0) || + PIPE_BIND_SAMPLER_VIEW) || !pipe->screen->is_format_supported(pipe->screen, dst->format, dst->target, dst->nr_samples, - PIPE_BIND_RENDER_TARGET, 0))) { + PIPE_BIND_RENDER_TARGET))) { switch (util_format_get_blocksize(old_dst.format)) { case 1: new_dst.format = PIPE_FORMAT_I8_UNORM; diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index b8db6fb6c12..720d666d98c 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -78,10 +78,8 @@ static void r300_release_referenced_objects(struct r300_context *r300) NULL); } - /* The dummy VBO. */ + /* Manually-created vertex buffers. */ pipe_resource_reference(&r300->dummy_vb, NULL); - - /* The SWTCL VBO. */ pipe_resource_reference(&r300->vbo, NULL); /* If there are any queries pending or not destroyed, remove them now. */ @@ -141,11 +139,11 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300); } -void r300_flush_cb(void *data) +static void r300_flush_callback(void *data, unsigned flags) { struct r300_context* const cs_context_copy = data; - cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL); + r300_flush(&cs_context_copy->context, flags, NULL); } #define R300_INIT_ATOM(atomname, atomsize) \ @@ -455,7 +453,7 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen, r300_init_render_functions(r300); r300_init_states(&r300->context); - rws->cs_set_flush(r300->cs, r300_flush_cb, r300); + rws->cs_set_flush(r300->cs, r300_flush_callback, r300); /* The KIL opcode needs the first texture unit to be enabled * on r3xx-r4xx. In order to calm down the CS checker, we bind this diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 58e1094e339..e395f41290e 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -65,7 +65,10 @@ struct r300_aa_state { }; struct r300_blend_state { - uint32_t cb[8]; + struct pipe_blend_state state; + + uint32_t cb_clamp[8]; + uint32_t cb_noclamp[8]; uint32_t cb_no_readwrite[8]; }; @@ -610,6 +613,8 @@ struct r300_context { boolean vertex_arrays_dirty; boolean vertex_arrays_indexed; int vertex_arrays_offset; + int vertex_arrays_instance_id; + boolean instancing_enabled; }; #define foreach_atom(r300, atom) \ @@ -663,8 +668,6 @@ static INLINE void r300_mark_atom_dirty(struct r300_context *r300, struct pipe_context* r300_create_context(struct pipe_screen* screen, void *priv); -void r300_flush_cb(void *data); - /* Context initialization. */ struct draw_stage* r300_draw_stage(struct r300_context* r300); void r300_init_blit_functions(struct r300_context *r300); @@ -679,6 +682,11 @@ void r300_decompress_zmask(struct r300_context *r300); void r300_decompress_zmask_locked_unsafe(struct r300_context *r300); void r300_decompress_zmask_locked(struct r300_context *r300); +/* r300_flush.c */ +void r300_flush(struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence); + /* r300_hyperz.c */ void r300_update_hyperz_state(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index e3945b72d7a..e17a907e77e 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -45,7 +45,10 @@ void r300_emit_blend_state(struct r300_context* r300, CS_LOCALS(r300); if (fb->nr_cbufs) { - WRITE_CS_TABLE(blend->cb, size); + if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) + WRITE_CS_TABLE(blend->cb_noclamp, size); + else + WRITE_CS_TABLE(blend->cb_clamp, size); } else { WRITE_CS_TABLE(blend->cb_no_readwrite, size); } @@ -794,7 +797,8 @@ void r300_emit_textures_state(struct r300_context *r300, END_CS; } -void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed) +void r300_emit_vertex_arrays(struct r300_context* r300, int offset, + boolean indexed, int instance_id) { struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->vertex_buffer; struct pipe_resource **valid_vbuf = r300->vbuf_mgr->real_vertex_buffer; @@ -804,39 +808,92 @@ void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean inde unsigned vertex_array_count = r300->velems->count; unsigned packet_size = (vertex_array_count * 3 + 1) / 2; struct pipe_vertex_buffer *vb1, *vb2; - unsigned *hw_format_size; - unsigned size1, size2; + unsigned *hw_format_size = r300->velems->format_size; + unsigned size1, size2, offset1, offset2, stride1, stride2; CS_LOCALS(r300); BEGIN_CS(2 + packet_size + vertex_array_count * 2); OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, packet_size); OUT_CS(vertex_array_count | (!indexed ? R300_VC_FORCE_PREFETCH : 0)); - hw_format_size = r300->velems->format_size; + if (instance_id == -1) { + /* Non-instanced arrays. This ignores instance_divisor and instance_id. */ + for (i = 0; i < vertex_array_count - 1; i += 2) { + vb1 = &vbuf[velem[i].vertex_buffer_index]; + vb2 = &vbuf[velem[i+1].vertex_buffer_index]; + size1 = hw_format_size[i]; + size2 = hw_format_size[i+1]; + + OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) | + R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride)); + OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); + OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride); + } - for (i = 0; i < vertex_array_count - 1; i += 2) { - vb1 = &vbuf[velem[i].vertex_buffer_index]; - vb2 = &vbuf[velem[i+1].vertex_buffer_index]; - size1 = hw_format_size[i]; - size2 = hw_format_size[i+1]; + if (vertex_array_count & 1) { + vb1 = &vbuf[velem[i].vertex_buffer_index]; + size1 = hw_format_size[i]; - OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride) | - R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(vb2->stride)); - OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); - OUT_CS(vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride); - } + OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride)); + OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); + } - if (vertex_array_count & 1) { - vb1 = &vbuf[velem[i].vertex_buffer_index]; - size1 = hw_format_size[i]; + for (i = 0; i < vertex_array_count; i++) { + buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]); + OUT_CS_RELOC(buf); + } + } else { + /* Instanced arrays. */ + for (i = 0; i < vertex_array_count - 1; i += 2) { + vb1 = &vbuf[velem[i].vertex_buffer_index]; + vb2 = &vbuf[velem[i+1].vertex_buffer_index]; + size1 = hw_format_size[i]; + size2 = hw_format_size[i+1]; + + if (velem[i].instance_divisor) { + stride1 = 0; + offset1 = vb1->buffer_offset + velem[i].src_offset + + (instance_id / velem[i].instance_divisor) * vb1->stride; + } else { + stride1 = vb1->stride; + offset1 = vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride; + } + if (velem[i+1].instance_divisor) { + stride2 = 0; + offset2 = vb2->buffer_offset + velem[i+1].src_offset + + (instance_id / velem[i+1].instance_divisor) * vb2->stride; + } else { + stride2 = vb2->stride; + offset2 = vb2->buffer_offset + velem[i+1].src_offset + offset * vb2->stride; + } - OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(vb1->stride)); - OUT_CS(vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride); - } + OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(stride1) | + R300_VBPNTR_SIZE1(size2) | R300_VBPNTR_STRIDE1(stride2)); + OUT_CS(offset1); + OUT_CS(offset2); + } + + if (vertex_array_count & 1) { + vb1 = &vbuf[velem[i].vertex_buffer_index]; + size1 = hw_format_size[i]; + + if (velem[i].instance_divisor) { + stride1 = 0; + offset1 = vb1->buffer_offset + velem[i].src_offset + + (instance_id / velem[i].instance_divisor) * vb1->stride; + } else { + stride1 = vb1->stride; + offset1 = vb1->buffer_offset + velem[i].src_offset + offset * vb1->stride; + } - for (i = 0; i < vertex_array_count; i++) { - buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]); - OUT_CS_RELOC(buf); + OUT_CS(R300_VBPNTR_SIZE0(size1) | R300_VBPNTR_STRIDE0(stride1)); + OUT_CS(offset1); + } + + for (i = 0; i < vertex_array_count; i++) { + buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]); + OUT_CS_RELOC(buf); + } } END_CS; } @@ -1164,7 +1221,7 @@ validate: if (flushed) return FALSE; - r300->context.flush(&r300->context, 0, NULL); + r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL); flushed = TRUE; goto validate; } diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index acea51d942f..6c1c9d2fb13 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -31,7 +31,8 @@ struct r300_vertex_program_code; uint32_t pack_float24(float f); -void r300_emit_vertex_arrays(struct r300_context* r300, int offset, boolean indexed); +void r300_emit_vertex_arrays(struct r300_context* r300, int offset, + boolean indexed, int instance_id); void r300_emit_blend_state(struct r300_context* r300, unsigned size, void* state); diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c index 9c41a1383ce..b3d0d344ec4 100644 --- a/src/gallium/drivers/r300/r300_flush.c +++ b/src/gallium/drivers/r300/r300_flush.c @@ -31,9 +31,10 @@ #include "r300_cs.h" #include "r300_emit.h" -static void r300_flush(struct pipe_context* pipe, - unsigned flags, - struct pipe_fence_handle** fence) + +void r300_flush(struct pipe_context *pipe, + unsigned flags, + struct pipe_fence_handle **fence) { struct r300_context *r300 = r300_context(pipe); struct r300_atom *atom; @@ -61,7 +62,7 @@ static void r300_flush(struct pipe_context* pipe, r500_emit_index_bias(r300, 0); r300->flush_counter++; - r300->rws->cs_flush(r300->cs); + r300->rws->cs_flush(r300->cs, flags); r300->dirty_hw = 0; /* New kitchen sink, baby. */ @@ -83,20 +84,22 @@ static void r300_flush(struct pipe_context* pipe, * and we cannot emit an empty CS. We must write some regs then. */ CS_LOCALS(r300); OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0); - r300->rws->cs_flush(r300->cs); + r300->rws->cs_flush(r300->cs, flags); } else { /* Even if hw is not dirty, we should at least reset the CS in case * the space checking failed for the first draw operation. */ - r300->rws->cs_flush(r300->cs); + r300->rws->cs_flush(r300->cs, flags); } } +} - if (flags & PIPE_FLUSH_FRAME) { - r300->rws->cs_sync_flush(r300->cs); - } +static void r300_flush_wrapped(struct pipe_context *pipe, + struct pipe_fence_handle **fence) +{ + r300_flush(pipe, 0, fence); } void r300_init_flush_functions(struct r300_context* r300) { - r300->context.flush = r300_flush; + r300->context.flush = r300_flush_wrapped; } diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c index cec7473009a..4c502fefb3f 100644 --- a/src/gallium/drivers/r300/r300_fs.c +++ b/src/gallium/drivers/r300/r300_fs.c @@ -149,6 +149,8 @@ static void get_external_state( unsigned i; unsigned char *swizzle; + state->frag_clamp = 0; + for (i = 0; i < texstate->sampler_state_count; i++) { struct r300_sampler_state *s = texstate->sampler_states[i]; struct r300_sampler_view *v = texstate->sampler_views[i]; diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 0ec4a225865..26594dabe42 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -177,7 +177,7 @@ static void r300_split_index_bias(struct r300_context *r300, int index_bias, } enum r300_prepare_flags { - PREP_FIRST_DRAW = (1 << 0), /* call emit_dirty_state and friends? */ + PREP_EMIT_STATES = (1 << 0), /* call emit_dirty_state and friends? */ PREP_VALIDATE_VBOS = (1 << 1), /* validate VBOs? */ PREP_EMIT_AOS = (1 << 2), /* call emit_vertex_arrays? */ PREP_EMIT_AOS_SWTCL = (1 << 3), /* call emit_vertex_arrays_swtcl? */ @@ -193,11 +193,11 @@ enum r300_prepare_flags { * \return TRUE if the CS was flushed */ static boolean r300_reserve_cs_dwords(struct r300_context *r300, - enum r300_prepare_flags flags, - unsigned cs_dwords) + enum r300_prepare_flags flags, + unsigned cs_dwords) { boolean flushed = FALSE; - boolean first_draw = flags & PREP_FIRST_DRAW; + boolean first_draw = flags & PREP_EMIT_STATES; boolean emit_vertex_arrays = flags & PREP_EMIT_AOS; boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL; @@ -219,7 +219,7 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300, /* Reserve requested CS space. */ if (cs_dwords > (R300_MAX_CMDBUF_DWORDS - r300->cs->cdw)) { - r300->context.flush(&r300->context, 0, NULL); + r300_flush(&r300->context, R300_FLUSH_ASYNC, NULL); flushed = TRUE; } @@ -233,15 +233,16 @@ static boolean r300_reserve_cs_dwords(struct r300_context *r300, * \param index_buffer The index buffer to validate. The parameter may be NULL. * \param buffer_offset The offset passed to emit_vertex_arrays. * \param index_bias The index bias to emit. + * \param instance_id Index of instance to render * \return TRUE if rendering should be skipped */ static boolean r300_emit_states(struct r300_context *r300, enum r300_prepare_flags flags, struct pipe_resource *index_buffer, int buffer_offset, - int index_bias) + int index_bias, int instance_id) { - boolean first_draw = flags & PREP_FIRST_DRAW; + boolean first_draw = flags & PREP_EMIT_STATES; boolean emit_vertex_arrays = flags & PREP_EMIT_AOS; boolean emit_vertex_arrays_swtcl = flags & PREP_EMIT_AOS_SWTCL; boolean indexed = flags & PREP_INDEXED; @@ -267,12 +268,14 @@ static boolean r300_emit_states(struct r300_context *r300, if (emit_vertex_arrays && (r300->vertex_arrays_dirty || r300->vertex_arrays_indexed != indexed || - r300->vertex_arrays_offset != buffer_offset)) { - r300_emit_vertex_arrays(r300, buffer_offset, indexed); + r300->vertex_arrays_offset != buffer_offset || + r300->vertex_arrays_instance_id != instance_id)) { + r300_emit_vertex_arrays(r300, buffer_offset, indexed, instance_id); r300->vertex_arrays_dirty = FALSE; r300->vertex_arrays_indexed = indexed; r300->vertex_arrays_offset = buffer_offset; + r300->vertex_arrays_instance_id = instance_id; } if (emit_vertex_arrays_swtcl) @@ -291,6 +294,7 @@ static boolean r300_emit_states(struct r300_context *r300, * \param cs_dwords The number of dwords to reserve in CS. * \param buffer_offset The offset passed to emit_vertex_arrays. * \param index_bias The index bias to emit. + * \param instance_id The instance to render. * \return TRUE if rendering should be skipped */ static boolean r300_prepare_for_rendering(struct r300_context *r300, @@ -298,13 +302,15 @@ static boolean r300_prepare_for_rendering(struct r300_context *r300, struct pipe_resource *index_buffer, unsigned cs_dwords, int buffer_offset, - int index_bias) + int index_bias, + int instance_id) { + /* Make sure there is enough space in the command stream and emit states. */ if (r300_reserve_cs_dwords(r300, flags, cs_dwords)) - flags |= PREP_FIRST_DRAW; + flags |= PREP_EMIT_STATES; return r300_emit_states(r300, flags, index_buffer, buffer_offset, - index_bias); + index_bias, instance_id); } static boolean immd_is_good_idea(struct r300_context *r300, @@ -352,8 +358,7 @@ static boolean immd_is_good_idea(struct r300_context *r300, ****************************************************************************/ static void r300_draw_arrays_immediate(struct r300_context *r300, - unsigned mode, unsigned start, - unsigned count) + const struct pipe_draw_info *info) { struct pipe_vertex_element* velem; struct pipe_vertex_buffer* vbuf; @@ -364,7 +369,7 @@ static void r300_draw_arrays_immediate(struct r300_context *r300, unsigned vertex_size = r300->velems->vertex_size_dwords; /* The number of dwords for this draw operation. */ - unsigned dwords = 4 + count * vertex_size; + unsigned dwords = 4 + info->count * vertex_size; /* Size of the vertex element, in dwords. */ unsigned size[PIPE_MAX_ATTRIBS]; @@ -379,7 +384,7 @@ static void r300_draw_arrays_immediate(struct r300_context *r300, CS_LOCALS(r300); - if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0)) + if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1)) return; /* Calculate the vertex size, offsets, strides etc. and map the buffers. */ @@ -395,21 +400,21 @@ static void r300_draw_arrays_immediate(struct r300_context *r300, map[vbi] = (uint32_t*)r300->rws->buffer_map( r300_resource(r300->vbuf_mgr->real_vertex_buffer[vbi])->buf, r300->cs, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED); - map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * start; + map[vbi] += (vbuf->buffer_offset / 4) + stride[i] * info->start; } mapelem[i] = map[vbi] + (velem->src_offset / 4); } - r300_emit_draw_init(r300, mode, 0, count-1); + r300_emit_draw_init(r300, info->mode, 0, info->count-1); BEGIN_CS(dwords); OUT_CS_REG(R300_VAP_VTX_SIZE, vertex_size); - OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, count * vertex_size); - OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (count << 16) | - r300_translate_primitive(mode)); + OUT_CS_PKT3(R300_PACKET3_3D_DRAW_IMMD_2, info->count * vertex_size); + OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED | (info->count << 16) | + r300_translate_primitive(info->mode)); /* Emit vertices. */ - for (v = 0; v < count; v++) { + for (v = 0; v < info->count; v++) { for (i = 0; i < vertex_element_count; i++) { OUT_CS_TABLE(&mapelem[i][stride[i] * v], size[i]); } @@ -456,8 +461,8 @@ static void r300_emit_draw_arrays(struct r300_context *r300, static void r300_emit_draw_elements(struct r300_context *r300, struct pipe_resource* indexBuffer, unsigned indexSize, - unsigned minIndex, - unsigned maxIndex, + unsigned min_index, + unsigned max_index, unsigned mode, unsigned start, unsigned count, @@ -467,16 +472,16 @@ static void r300_emit_draw_elements(struct r300_context *r300, boolean alt_num_verts = count > 65535; CS_LOCALS(r300); - if (count >= (1 << 24) || maxIndex >= (1 << 24)) { + if (count >= (1 << 24) || max_index >= (1 << 24)) { fprintf(stderr, "r300: Got a huge number of vertices: %i, " - "refusing to render (maxIndex: %i).\n", count, maxIndex); + "refusing to render (max_index: %i).\n", count, max_index); return; } DBG(r300, DBG_DRAW, "r300: Indexbuf of %u indices, min %u max %u\n", - count, minIndex, maxIndex); + count, min_index, max_index); - r300_emit_draw_init(r300, mode, minIndex, maxIndex); + r300_emit_draw_init(r300, mode, min_index, max_index); /* If start is odd, render the first triangle with indices embedded * in the command stream. This will increase start by 3 and make it @@ -527,24 +532,23 @@ static void r300_emit_draw_elements(struct r300_context *r300, } static void r300_draw_elements_immediate(struct r300_context *r300, - int indexBias, unsigned minIndex, - unsigned maxIndex, unsigned mode, - unsigned start, unsigned count) + const struct pipe_draw_info *info) { uint8_t *ptr1; uint16_t *ptr2; uint32_t *ptr4; unsigned index_size = r300->index_buffer.index_size; - unsigned i, count_dwords = index_size == 4 ? count : (count + 1) / 2; + unsigned i, count_dwords = index_size == 4 ? info->count : + (info->count + 1) / 2; CS_LOCALS(r300); /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | - PREP_INDEXED, NULL, 2+count_dwords, 0, indexBias)) + PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | + PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1)) return; - r300_emit_draw_init(r300, mode, minIndex, maxIndex); + r300_emit_draw_init(r300, info->mode, info->min_index, info->max_index); BEGIN_CS(2 + count_dwords); OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, count_dwords); @@ -552,42 +556,42 @@ static void r300_draw_elements_immediate(struct r300_context *r300, switch (index_size) { case 1: ptr1 = r300_resource(r300->index_buffer.buffer)->b.user_ptr; - ptr1 += start; + ptr1 += info->start; - OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | - r300_translate_primitive(mode)); + OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) | + r300_translate_primitive(info->mode)); - if (indexBias && !r300->screen->caps.is_r500) { - for (i = 0; i < count-1; i += 2) - OUT_CS(((ptr1[i+1] + indexBias) << 16) | - (ptr1[i] + indexBias)); + if (info->index_bias && !r300->screen->caps.is_r500) { + for (i = 0; i < info->count-1; i += 2) + OUT_CS(((ptr1[i+1] + info->index_bias) << 16) | + (ptr1[i] + info->index_bias)); - if (count & 1) - OUT_CS(ptr1[i] + indexBias); + if (info->count & 1) + OUT_CS(ptr1[i] + info->index_bias); } else { - for (i = 0; i < count-1; i += 2) + for (i = 0; i < info->count-1; i += 2) OUT_CS(((ptr1[i+1]) << 16) | (ptr1[i] )); - if (count & 1) + if (info->count & 1) OUT_CS(ptr1[i]); } break; case 2: ptr2 = (uint16_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr; - ptr2 += start; + ptr2 += info->start; - OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | - r300_translate_primitive(mode)); + OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) | + r300_translate_primitive(info->mode)); - if (indexBias && !r300->screen->caps.is_r500) { - for (i = 0; i < count-1; i += 2) - OUT_CS(((ptr2[i+1] + indexBias) << 16) | - (ptr2[i] + indexBias)); + if (info->index_bias && !r300->screen->caps.is_r500) { + for (i = 0; i < info->count-1; i += 2) + OUT_CS(((ptr2[i+1] + info->index_bias) << 16) | + (ptr2[i] + info->index_bias)); - if (count & 1) - OUT_CS(ptr2[i] + indexBias); + if (info->count & 1) + OUT_CS(ptr2[i] + info->index_bias); } else { OUT_CS_TABLE(ptr2, count_dwords); } @@ -595,15 +599,15 @@ static void r300_draw_elements_immediate(struct r300_context *r300, case 4: ptr4 = (uint32_t*)r300_resource(r300->index_buffer.buffer)->b.user_ptr; - ptr4 += start; + ptr4 += info->start; - OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) | + OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (info->count << 16) | R300_VAP_VF_CNTL__INDEX_SIZE_32bit | - r300_translate_primitive(mode)); + r300_translate_primitive(info->mode)); - if (indexBias && !r300->screen->caps.is_r500) { - for (i = 0; i < count; i++) - OUT_CS(ptr4[i] + indexBias); + if (info->index_bias && !r300->screen->caps.is_r500) { + for (i = 0; i < info->count; i++) + OUT_CS(ptr4[i] + info->index_bias); } else { OUT_CS_TABLE(ptr4, count_dwords); } @@ -612,21 +616,23 @@ static void r300_draw_elements_immediate(struct r300_context *r300, END_CS; } -static void r300_draw_elements(struct r300_context *r300, int indexBias, - unsigned minIndex, unsigned maxIndex, - unsigned mode, unsigned start, unsigned count) +static void r300_draw_elements(struct r300_context *r300, + const struct pipe_draw_info *info, + int instance_id) { struct pipe_resource *indexBuffer = r300->index_buffer.buffer; unsigned indexSize = r300->index_buffer.index_size; struct pipe_resource* orgIndexBuffer = indexBuffer; + unsigned start = info->start; + unsigned count = info->count; boolean alt_num_verts = r300->screen->caps.is_r500 && count > 65536; unsigned short_count; int buffer_offset = 0, index_offset = 0; /* for index bias emulation */ uint16_t indices3[3]; - if (indexBias && !r300->screen->caps.is_r500) { - r300_split_index_bias(r300, indexBias, &buffer_offset, &index_offset); + if (info->index_bias && !r300->screen->caps.is_r500) { + r300_split_index_bias(r300, info->index_bias, &buffer_offset, &index_offset); } r300_translate_index_buffer(r300, &indexBuffer, &indexSize, index_offset, @@ -641,7 +647,7 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias, PIPE_TRANSFER_READ | PIPE_TRANSFER_UNSYNCHRONIZED); - if (mode == PIPE_PRIM_TRIANGLES) { + if (info->mode == PIPE_PRIM_TRIANGLES) { memcpy(indices3, ptr + start, 6); } else { /* Copy the mapped index buffer directly to the upload buffer. @@ -660,13 +666,15 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias, /* 19 dwords for emit_draw_elements. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | - PREP_INDEXED, indexBuffer, 19, buffer_offset, indexBias)) + PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS | + PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias, + instance_id)) goto done; if (alt_num_verts || count <= 65535) { - r300_emit_draw_elements(r300, indexBuffer, indexSize, - minIndex, maxIndex, mode, start, count, indices3); + r300_emit_draw_elements(r300, indexBuffer, indexSize, info->min_index, + info->max_index, info->mode, start, count, + indices3); } else { do { if (indexSize == 2 && (start & 1)) @@ -675,8 +683,8 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias, short_count = MIN2(count, 65534); r300_emit_draw_elements(r300, indexBuffer, indexSize, - minIndex, maxIndex, - mode, start, short_count, indices3); + info->min_index, info->max_index, + info->mode, start, short_count, indices3); start += short_count; count -= short_count; @@ -685,7 +693,8 @@ static void r300_draw_elements(struct r300_context *r300, int indexBias, if (count) { if (!r300_prepare_for_rendering(r300, PREP_VALIDATE_VBOS | PREP_EMIT_AOS | PREP_INDEXED, - indexBuffer, 19, buffer_offset, indexBias)) + indexBuffer, 19, buffer_offset, info->index_bias, + instance_id)) goto done; } } while (count); @@ -697,25 +706,28 @@ done: } } -static void r300_draw_arrays(struct r300_context *r300, unsigned mode, - unsigned start, unsigned count) +static void r300_draw_arrays(struct r300_context *r300, + const struct pipe_draw_info *info, + int instance_id) { boolean alt_num_verts = r300->screen->caps.is_r500 && - count > 65536; + info->count > 65536; + unsigned start = info->start; + unsigned count = info->count; unsigned short_count; /* 9 spare dwords for emit_draw_arrays. Give up if the function fails. */ if (!r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, - NULL, 9, start, 0)) + PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_AOS, + NULL, 9, start, 0, instance_id)) return; if (alt_num_verts || count <= 65535) { - r300_emit_draw_arrays(r300, mode, count); + r300_emit_draw_arrays(r300, info->mode, count); } else { do { short_count = MIN2(count, 65535); - r300_emit_draw_arrays(r300, mode, short_count); + r300_emit_draw_arrays(r300, info->mode, short_count); start += short_count; count -= short_count; @@ -724,53 +736,78 @@ static void r300_draw_arrays(struct r300_context *r300, unsigned mode, if (count) { if (!r300_prepare_for_rendering(r300, PREP_VALIDATE_VBOS | PREP_EMIT_AOS, NULL, 9, - start, 0)) + start, 0, instance_id)) return; } } while (count); } } +static void r300_draw_arrays_instanced(struct r300_context *r300, + const struct pipe_draw_info *info) +{ + int i; + + for (i = 0; i < info->instance_count; i++) + r300_draw_arrays(r300, info, i); +} + +static void r300_draw_elements_instanced(struct r300_context *r300, + const struct pipe_draw_info *info) +{ + int i; + + for (i = 0; i < info->instance_count; i++) + r300_draw_elements(r300, info, i); +} + static void r300_draw_vbo(struct pipe_context* pipe, - const struct pipe_draw_info *info) + const struct pipe_draw_info *dinfo) { struct r300_context* r300 = r300_context(pipe); - unsigned count = info->count; + struct pipe_draw_info info = *dinfo; boolean buffers_updated, uploader_flushed; - boolean indexed = info->indexed && r300->index_buffer.buffer; - unsigned start_indexed = info->start + r300->index_buffer.offset; - int max_index = MIN2(r300->vbuf_mgr->max_index, info->max_index); + + info.indexed = info.indexed && r300->index_buffer.buffer; if (r300->skip_rendering || - !u_trim_pipe_prim(info->mode, &count)) { + !u_trim_pipe_prim(info.mode, &info.count)) { return; } r300_update_derived_state(r300); /* Start the vbuf manager and update buffers if needed. */ - u_vbuf_mgr_draw_begin(r300->vbuf_mgr, info, + u_vbuf_mgr_draw_begin(r300->vbuf_mgr, &info, &buffers_updated, &uploader_flushed); if (buffers_updated) { r300->vertex_arrays_dirty = TRUE; } /* Draw. */ - if (indexed) { - if (count <= 8 && - r300_resource(r300->index_buffer.buffer)->b.user_ptr) { - r300_draw_elements_immediate(r300, info->index_bias, - info->min_index, max_index, - info->mode, start_indexed, count); + if (info.indexed) { + info.start += r300->index_buffer.offset; + info.max_index = MIN2(r300->vbuf_mgr->max_index, info.max_index); + + if (info.instance_count <= 1) { + if (info.count <= 8 && + r300_resource(r300->index_buffer.buffer)->b.user_ptr) { + r300_draw_elements_immediate(r300, &info); + } else { + r300_draw_elements(r300, &info, -1); + } } else { - r300_draw_elements(r300, info->index_bias, info->min_index, - max_index, info->mode, start_indexed, count); + r300_draw_elements_instanced(r300, &info); } } else { - if (immd_is_good_idea(r300, count)) { - r300_draw_arrays_immediate(r300, info->mode, info->start, count); + if (info.instance_count <= 1) { + if (immd_is_good_idea(r300, info.count)) { + r300_draw_arrays_immediate(r300, &info); + } else { + r300_draw_arrays(r300, &info, -1); + } } else { - r300_draw_arrays(r300, info->mode, info->start, count); + r300_draw_arrays_instanced(r300, &info); } } @@ -805,7 +842,7 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, r300_update_derived_state(r300); r300_reserve_cs_dwords(r300, - PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | + PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | (indexed ? PREP_INDEXED : 0), indexed ? 256 : 6); @@ -987,13 +1024,13 @@ static void r300_render_draw_arrays(struct vbuf_render* render, if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, - NULL, dwords, 0, 0)) + PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL, + NULL, dwords, 0, 0, -1)) return; } else { if (!r300_emit_states(r300, - PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL, - NULL, 0, 0)) + PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL, + NULL, 0, 0, -1)) return; } @@ -1027,13 +1064,13 @@ static void r300_render_draw_elements(struct vbuf_render* render, if (r300->draw_first_emitted) { if (!r300_prepare_for_rendering(r300, - PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 256, 0, 0)) + PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + NULL, 256, 0, 0, -1)) return; } else { if (!r300_emit_states(r300, - PREP_FIRST_DRAW | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 0, 0)) + PREP_EMIT_STATES | PREP_EMIT_AOS_SWTCL | PREP_INDEXED, + NULL, 0, 0, -1)) return; } @@ -1070,7 +1107,7 @@ static void r300_render_draw_elements(struct vbuf_render* render, if (count) { if (!r300_prepare_for_rendering(r300, PREP_EMIT_AOS_SWTCL | PREP_INDEXED, - NULL, 256, 0, 0)) + NULL, 256, 0, 0, -1)) return; end_cs_dwords = r300_get_num_cs_end_dwords(r300); @@ -1174,7 +1211,7 @@ static void r300_blitter_draw_rectangle(struct blitter_context *blitter, r300->clip_state.dirty = FALSE; r300->viewport_state.dirty = FALSE; - if (!r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0)) + if (!r300_prepare_for_rendering(r300, PREP_EMIT_STATES, NULL, dwords, 0, 0, -1)) goto done; DBG(r300, DBG_DRAW, "r300: draw_rectangle\n"); diff --git a/src/gallium/drivers/r300/r300_resource.c b/src/gallium/drivers/r300/r300_resource.c index f3d8c5b889f..6593474b1f0 100644 --- a/src/gallium/drivers/r300/r300_resource.c +++ b/src/gallium/drivers/r300/r300_resource.c @@ -38,13 +38,6 @@ r300_resource_create(struct pipe_screen *screen, } -static unsigned r300_resource_is_referenced_by_cs(struct pipe_context *context, - struct pipe_resource *buf, - unsigned level, int layer) -{ - return r300_buffer_is_referenced(context, buf); -} - void r300_init_resource_functions(struct r300_context *r300) { r300->context.get_transfer = u_get_transfer_vtbl; @@ -53,7 +46,6 @@ void r300_init_resource_functions(struct r300_context *r300) r300->context.transfer_unmap = u_transfer_unmap_vtbl; r300->context.transfer_destroy = u_transfer_destroy_vtbl; r300->context.transfer_inline_write = u_transfer_inline_write_vtbl; - r300->context.is_resource_referenced = r300_resource_is_referenced_by_cs; r300->context.create_surface = r300_create_surface; r300->context.surface_destroy = r300_surface_destroy; } diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 52d0247fbfd..8a69628c53e 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -24,6 +24,7 @@ #include "util/u_format.h" #include "util/u_format_s3tc.h" #include "util/u_memory.h" +#include "os/os_time.h" #include "r300_context.h" #include "r300_texture.h" @@ -112,6 +113,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MIRROR_CLAMP: case PIPE_CAP_TEXTURE_MIRROR_REPEAT: case PIPE_CAP_BLEND_EQUATION_SEPARATE: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; case PIPE_CAP_TEXTURE_SWIZZLE: return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1; @@ -124,12 +126,15 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: case PIPE_CAP_SHADER_STENCIL_EXPORT: - case PIPE_CAP_STREAM_OUTPUT: - case PIPE_CAP_PRIMITIVE_RESTART: - case PIPE_CAP_INSTANCED_DRAWING: case PIPE_CAP_ARRAY_TEXTURES: return 0; + /* SWTCL-only features. */ + case PIPE_CAP_STREAM_OUTPUT: + case PIPE_CAP_PRIMITIVE_RESTART: + case PIPE_CAP_TGSI_INSTANCEID: + return !r300screen->caps.has_tcl; + /* Texturing. */ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: case PIPE_CAP_MAX_COMBINED_SAMPLERS: @@ -301,8 +306,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned usage, - unsigned geom_flags) + unsigned usage) { struct r300_winsys_screen *rws = r300_screen(screen)->rws; uint32_t retval = 0; @@ -314,9 +318,13 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, format == PIPE_FORMAT_B10G10R10A2_UNORM || format == PIPE_FORMAT_R10SG10SB10SA2U_NORM; boolean is_ati1n = format == PIPE_FORMAT_RGTC1_UNORM || - format == PIPE_FORMAT_RGTC1_SNORM; + format == PIPE_FORMAT_RGTC1_SNORM || + format == PIPE_FORMAT_LATC1_UNORM || + format == PIPE_FORMAT_LATC1_SNORM; boolean is_ati2n = format == PIPE_FORMAT_RGTC2_UNORM || - format == PIPE_FORMAT_RGTC2_SNORM; + format == PIPE_FORMAT_RGTC2_SNORM || + format == PIPE_FORMAT_LATC2_UNORM || + format == PIPE_FORMAT_LATC2_SNORM; boolean is_half_float = format == PIPE_FORMAT_R16_FLOAT || format == PIPE_FORMAT_R16G16_FLOAT || format == PIPE_FORMAT_R16G16B16_FLOAT || @@ -414,25 +422,40 @@ static void r300_fence_reference(struct pipe_screen *screen, (struct r300_winsys_bo*)fence); } -static int r300_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags) +static boolean r300_fence_signalled(struct pipe_screen *screen, + struct pipe_fence_handle *fence) { struct r300_winsys_screen *rws = r300_screen(screen)->rws; struct r300_winsys_bo *rfence = (struct r300_winsys_bo*)fence; - return !rws->buffer_is_busy(rfence) ? 0 : 1; /* 0 == success */ + return !rws->buffer_is_busy(rfence); } -static int r300_fence_finish(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags) +static boolean r300_fence_finish(struct pipe_screen *screen, + struct pipe_fence_handle *fence, + uint64_t timeout) { struct r300_winsys_screen *rws = r300_screen(screen)->rws; struct r300_winsys_bo *rfence = (struct r300_winsys_bo*)fence; + if (timeout != PIPE_TIMEOUT_INFINITE) { + int64_t start_time = os_time_get(); + + /* Convert to microseconds. */ + timeout /= 1000; + + /* Wait in a loop. */ + while (rws->buffer_is_busy(rfence)) { + if (os_time_get() - start_time >= timeout) { + return FALSE; + } + os_time_sleep(10); + } + return TRUE; + } + rws->buffer_wait(rfence); - return 0; /* 0 == success */ + return TRUE; } struct pipe_screen* r300_screen_create(struct r300_winsys_screen *rws) diff --git a/src/gallium/drivers/r300/r300_screen_buffer.c b/src/gallium/drivers/r300/r300_screen_buffer.c index 1045911f3ae..986ae384fbf 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.c +++ b/src/gallium/drivers/r300/r300_screen_buffer.c @@ -33,21 +33,6 @@ #include "r300_screen_buffer.h" #include "r300_winsys.h" -unsigned r300_buffer_is_referenced(struct pipe_context *context, - struct pipe_resource *buf) -{ - struct r300_context *r300 = r300_context(context); - struct r300_resource *rbuf = r300_resource(buf); - - if (rbuf->b.user_ptr || rbuf->constant_buffer) - return PIPE_UNREFERENCED; - - if (r300->rws->cs_is_buffer_referenced(r300->cs, rbuf->cs_buf)) - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; - - return PIPE_UNREFERENCED; -} - void r300_upload_index_buffer(struct r300_context *r300, struct pipe_resource **index_buffer, unsigned index_size, unsigned *start, @@ -181,7 +166,6 @@ static const struct u_resource_vtbl r300_buffer_vtbl = { NULL, /* get_handle */ r300_buffer_destroy, /* resource_destroy */ - NULL, /* is_buffer_referenced */ r300_buffer_get_transfer, /* get_transfer */ r300_buffer_transfer_destroy, /* transfer_destroy */ r300_buffer_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/r300/r300_screen_buffer.h b/src/gallium/drivers/r300/r300_screen_buffer.h index 14bee460d5b..cdbc4425fcb 100644 --- a/src/gallium/drivers/r300/r300_screen_buffer.h +++ b/src/gallium/drivers/r300/r300_screen_buffer.h @@ -49,9 +49,6 @@ struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned size, unsigned bind); -unsigned r300_buffer_is_referenced(struct pipe_context *context, - struct pipe_resource *buf); - /* Inline functions. */ static INLINE struct r300_buffer *r300_buffer(struct pipe_resource *buffer) diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 2b0c8750554..ecb4fc691cc 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -188,13 +188,16 @@ static void* r300_create_blend_state(struct pipe_context* pipe, struct r300_screen* r300screen = r300_screen(pipe->screen); struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); uint32_t blend_control = 0; /* R300_RB3D_CBLEND: 0x4e04 */ + uint32_t blend_control_noclamp = 0; /* R300_RB3D_CBLEND: 0x4e04 */ uint32_t alpha_blend_control = 0; /* R300_RB3D_ABLEND: 0x4e08 */ + uint32_t alpha_blend_control_noclamp = 0; /* R300_RB3D_ABLEND: 0x4e08 */ uint32_t color_channel_mask = 0; /* R300_RB3D_COLOR_CHANNEL_MASK: 0x4e0c */ uint32_t rop = 0; /* R300_RB3D_ROPCNTL: 0x4e18 */ uint32_t dither = 0; /* R300_RB3D_DITHER_CTL: 0x4e50 */ - boolean clamp = TRUE; CB_LOCALS; + blend->state = *state; + if (state->rt[0].blend_enable) { unsigned eqRGB = state->rt[0].rgb_func; @@ -207,10 +210,14 @@ static void* r300_create_blend_state(struct pipe_context* pipe, /* despite the name, ALPHA_BLEND_ENABLE has nothing to do with alpha, * this is just the crappy D3D naming */ - blend_control = R300_ALPHA_BLEND_ENABLE | - r300_translate_blend_function(eqRGB, clamp) | + blend_control = blend_control_noclamp = + R300_ALPHA_BLEND_ENABLE | ( r300_translate_blend_factor(srcRGB) << R300_SRC_BLEND_SHIFT) | ( r300_translate_blend_factor(dstRGB) << R300_DST_BLEND_SHIFT); + blend_control |= + r300_translate_blend_function(eqRGB, TRUE); + blend_control_noclamp |= + r300_translate_blend_function(eqRGB, FALSE); /* Optimization: some operations do not require the destination color. * @@ -232,6 +239,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, srcRGB == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE) { /* Enable reading from the colorbuffer. */ blend_control |= R300_READ_ENABLE; + blend_control_noclamp |= R300_READ_ENABLE; if (r300screen->caps.is_r500) { /* Optimization: Depending on incoming pixels, we can @@ -269,8 +277,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, * * Equations other than ADD are rarely used and therefore won't be * optimized. */ - if (clamp && - (eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) && + if ((eqRGB == PIPE_BLEND_ADD || eqRGB == PIPE_BLEND_REVERSE_SUBTRACT) && (eqA == PIPE_BLEND_ADD || eqA == PIPE_BLEND_REVERSE_SUBTRACT)) { /* ADD: X+Y * REVERSE_SUBTRACT: Y-X @@ -308,10 +315,14 @@ static void* r300_create_blend_state(struct pipe_context* pipe, /* separate alpha */ if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) { blend_control |= R300_SEPARATE_ALPHA_ENABLE; - alpha_blend_control = - r300_translate_blend_function(eqA, clamp) | + blend_control_noclamp |= R300_SEPARATE_ALPHA_ENABLE; + alpha_blend_control = alpha_blend_control_noclamp = (r300_translate_blend_factor(srcA) << R300_SRC_BLEND_SHIFT) | (r300_translate_blend_factor(dstA) << R300_DST_BLEND_SHIFT); + alpha_blend_control |= + r300_translate_blend_function(eqA, TRUE); + alpha_blend_control_noclamp |= + r300_translate_blend_function(eqA, FALSE); } } @@ -348,7 +359,7 @@ static void* r300_create_blend_state(struct pipe_context* pipe, */ /* Build a command buffer. */ - BEGIN_CB(blend->cb, 8); + BEGIN_CB(blend->cb_clamp, 8); OUT_CB_REG(R300_RB3D_ROPCNTL, rop); OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3); OUT_CB(blend_control); @@ -357,6 +368,16 @@ static void* r300_create_blend_state(struct pipe_context* pipe, OUT_CB_REG(R300_RB3D_DITHER_CTL, dither); END_CB; + /* Build a command buffer. */ + BEGIN_CB(blend->cb_noclamp, 8); + OUT_CB_REG(R300_RB3D_ROPCNTL, rop); + OUT_CB_REG_SEQ(R300_RB3D_CBLEND, 3); + OUT_CB(blend_control_noclamp); + OUT_CB(alpha_blend_control_noclamp); + OUT_CB(color_channel_mask); + OUT_CB_REG(R300_RB3D_DITHER_CTL, dither); + END_CB; + /* The same as above, but with no colorbuffer reads and writes. */ BEGIN_CB(blend->cb_no_readwrite, 8); OUT_CB_REG(R300_RB3D_ROPCNTL, rop); @@ -377,6 +398,10 @@ static void r300_bind_blend_state(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); UPDATE_STATE(state, r300->blend_state); + + if (r300->fs.state && r300_pick_fragment_shader(r300)) { + r300_mark_fs_code_dirty(r300); + } } /* Free blend state. */ @@ -836,10 +861,9 @@ r300_set_framebuffer_state(struct pipe_context* pipe, } } - /* If nr_cbufs is changed from zero to non-zero or vice versa... */ - if (!!old_state->nr_cbufs != !!state->nr_cbufs) { - r300_mark_atom_dirty(r300, &r300->blend_state); - } + /* Need to reset clamping or colormask. */ + r300_mark_atom_dirty(r300, &r300->blend_state); + /* If zsbuf is set from NULL to non-NULL or vice versa.. */ if (!!old_state->zsbuf != !!state->zsbuf) { r300_mark_atom_dirty(r300, &r300->dsa_state); @@ -1593,12 +1617,6 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems) enum pipe_format format; unsigned i; - if (velems->count > 16) { - fprintf(stderr, "r300: More than 16 vertex elements are not supported," - " requested %i, using 16.\n", velems->count); - velems->count = 16; - } - /* Vertex shaders have no semantics on their inputs, * so PSC should just route stuff based on the vertex elements, * and not on attrib information. */ @@ -1649,9 +1667,12 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, dummy_attrib.src_format = PIPE_FORMAT_R8G8B8A8_UNORM; attribs = &dummy_attrib; count = 1; + } else if (count > 16) { + fprintf(stderr, "r300: More than 16 vertex elements are not supported," + " requested %i, using 16.\n", count); + count = 16; } - assert(count <= PIPE_MAX_ATTRIBS); velems = CALLOC_STRUCT(r300_vertex_element_state); if (!velems) return NULL; @@ -1849,6 +1870,14 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, } } +static void r300_texture_barrier(struct pipe_context *pipe) +{ + struct r300_context *r300 = r300_context(pipe); + + r300_mark_atom_dirty(r300, &r300->gpu_flush); + r300_mark_atom_dirty(r300, &r300->texture_cache_inval); +} + void r300_init_state_functions(struct r300_context* r300) { r300->context.create_blend_state = r300_create_blend_state; @@ -1904,4 +1933,6 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.create_vs_state = r300_create_vs_state; r300->context.bind_vs_state = r300_bind_vs_state; r300->context.delete_vs_state = r300_delete_vs_state; + + r300->context.texture_barrier = r300_texture_barrier; } diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index a1e116f4b61..ec00e2552ca 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -644,16 +644,20 @@ static uint32_t r300_get_border_color(enum pipe_format format, switch (format) { case PIPE_FORMAT_RGTC1_SNORM: case PIPE_FORMAT_RGTC1_UNORM: + case PIPE_FORMAT_LATC1_SNORM: + case PIPE_FORMAT_LATC1_UNORM: /* Add 1/32 to round the border color instead of truncating. */ /* The Y component is used for the border color. */ border_swizzled[1] = border_swizzled[2] + 1.0f/32; util_pack_color(border_swizzled, PIPE_FORMAT_B4G4R4A4_UNORM, &uc); return uc.ui; case PIPE_FORMAT_RGTC2_SNORM: + case PIPE_FORMAT_LATC2_SNORM: border_swizzled[0] = border_swizzled[2]; util_pack_color(border_swizzled, PIPE_FORMAT_R8G8B8A8_SNORM, &uc); return uc.ui; case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_LATC2_UNORM: util_pack_color(border_swizzled, PIPE_FORMAT_B8G8R8A8_UNORM, &uc); return uc.ui; default: diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 86ad0b8b8e0..c650fb7ed37 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -174,9 +174,11 @@ uint32_t r300_translate_texformat(enum pipe_format format, if (util_format_is_compressed(format) && dxtc_swizzle && format != PIPE_FORMAT_RGTC2_UNORM && - format != PIPE_FORMAT_RGTC2_SNORM) { + format != PIPE_FORMAT_RGTC2_SNORM && + format != PIPE_FORMAT_LATC2_UNORM && + format != PIPE_FORMAT_LATC2_SNORM) { result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, - dxtc_swizzle); + TRUE); } else { result |= r300_get_swizzle_combined(desc->swizzle, swizzle_view, FALSE); @@ -209,13 +211,19 @@ uint32_t r300_translate_texformat(enum pipe_format format, if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { switch (format) { case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_LATC1_SNORM: result |= sign_bit[1]; + case PIPE_FORMAT_LATC1_UNORM: case PIPE_FORMAT_RGTC1_UNORM: return R500_TX_FORMAT_ATI1N | result; + case PIPE_FORMAT_RGTC2_SNORM: + case PIPE_FORMAT_LATC2_SNORM: result |= sign_bit[2] | sign_bit[3]; case PIPE_FORMAT_RGTC2_UNORM: + case PIPE_FORMAT_LATC2_UNORM: return R400_TX_FORMAT_ATI2N | result; + default: return ~0; /* Unsupported/unknown. */ } @@ -363,6 +371,8 @@ uint32_t r500_tx_format_msb_bit(enum pipe_format format) switch (format) { case PIPE_FORMAT_RGTC1_UNORM: case PIPE_FORMAT_RGTC1_SNORM: + case PIPE_FORMAT_LATC1_UNORM: + case PIPE_FORMAT_LATC1_SNORM: case PIPE_FORMAT_X8Z24_UNORM: case PIPE_FORMAT_S8_USCALED_Z24_UNORM: return R500_TXFORMAT_MSB; @@ -742,7 +752,6 @@ static const struct u_resource_vtbl r300_texture_vtbl = { NULL, /* get_handle */ r300_texture_destroy, /* resource_destroy */ - NULL, /* is_resource_referenced */ r300_texture_get_transfer, /* get_transfer */ r300_texture_transfer_destroy, /* transfer_destroy */ r300_texture_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/r300/r300_texture_desc.c b/src/gallium/drivers/r300/r300_texture_desc.c index 3846fb8b6b3..2910666dd51 100644 --- a/src/gallium/drivers/r300/r300_texture_desc.c +++ b/src/gallium/drivers/r300/r300_texture_desc.c @@ -315,7 +315,7 @@ static unsigned r300_pixels_to_dwords(unsigned stride, unsigned height, unsigned xblock, unsigned yblock) { - return (align(stride, xblock) * align(height, yblock)) / (xblock * yblock); + return (util_align_npot(stride, xblock) * align(height, yblock)) / (xblock * yblock); } static void r300_setup_hyperz_properties(struct r300_screen *screen, @@ -390,7 +390,7 @@ static void r300_setup_hyperz_properties(struct r300_screen *screen, tex->tex.zcomp8x8[i] = zcompsize == 8; tex->tex.zmask_stride_in_pixels[i] = - align(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize); + util_align_npot(stride, zmask_blocks_x_per_dw[pipes-1] * zcompsize); } else { tex->tex.zmask_dwords[i] = 0; tex->tex.zcomp8x8[i] = FALSE; @@ -398,7 +398,7 @@ static void r300_setup_hyperz_properties(struct r300_screen *screen, } /* Now setup HIZ. */ - stride = align(stride, hiz_align_x[pipes-1]); + stride = util_align_npot(stride, hiz_align_x[pipes-1]); height = align(height, hiz_align_y[pipes-1]); /* Get the HIZ buffer size in dwords. */ diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c index 30de9ec1e32..65c5095be6a 100644 --- a/src/gallium/drivers/r300/r300_transfer.c +++ b/src/gallium/drivers/r300/r300_transfer.c @@ -72,7 +72,8 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx, transfer->box.x, transfer->box.y, transfer->box.z, &r300transfer->linear_texture->b.b.b, 0, &src_box); - ctx->flush(ctx, 0, NULL); + /* XXX remove this. */ + r300_flush(ctx, 0, NULL); } struct pipe_transfer* @@ -100,7 +101,8 @@ r300_texture_get_transfer(struct pipe_context *ctx, } blittable = desc->layout == UTIL_FORMAT_LAYOUT_PLAIN || - desc->layout == UTIL_FORMAT_LAYOUT_S3TC; + desc->layout == UTIL_FORMAT_LAYOUT_S3TC || + desc->layout == UTIL_FORMAT_LAYOUT_RGTC; trans = CALLOC_STRUCT(r300_transfer); if (trans) { @@ -151,7 +153,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, if (!trans->linear_texture) { /* Oh crap, the thing can't create the texture. * Let's flush and try again. */ - ctx->flush(ctx, 0, NULL); + r300_flush(ctx, 0, NULL); trans->linear_texture = r300_resource( ctx->screen->resource_create(ctx->screen, @@ -175,13 +177,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, assert(!trans->linear_texture->tex.microtile && !trans->linear_texture->tex.macrotile[0]); - /* Set the stride. - * - * Even though we are using an internal texture for this, - * the transfer level, box and usage parameters still reflect - * the arguments received to get_transfer. We just do the - * right thing internally. - */ + /* Set the stride. */ trans->transfer.stride = trans->linear_texture->tex.stride_in_bytes[0]; @@ -191,7 +187,7 @@ r300_texture_get_transfer(struct pipe_context *ctx, r300_copy_from_tiled_texture(ctx, trans); /* Always referenced in the blit. */ - ctx->flush(ctx, 0, NULL); + r300_flush(ctx, 0, NULL); } return &trans->transfer; } @@ -201,8 +197,9 @@ r300_texture_get_transfer(struct pipe_context *ctx, trans->transfer.stride = tex->tex.stride_in_bytes[level]; trans->offset = r300_texture_get_offset(tex, level, box->z); - if (referenced_cs) - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + if (referenced_cs && + !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) + r300_flush(ctx, 0, NULL); return &trans->transfer; } return NULL; diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index c0b66899f8b..3a6798a5423 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -35,6 +35,7 @@ #include "pipe/p_state.h" #define R300_MAX_CMDBUF_DWORDS (16 * 1024) +#define R300_FLUSH_ASYNC (1 << 0) struct winsys_handle; struct r300_winsys_screen; @@ -265,15 +266,9 @@ struct r300_winsys_screen { * Flush a command stream. * * \param cs A command stream to flush. + * \param flags, R300_FLUSH_ASYNC or 0. */ - void (*cs_flush)(struct r300_winsys_cs *cs); - - /** - * Wait until the last flush is completed. - * - * \param cs A command stream. - */ - void (*cs_sync_flush)(struct r300_winsys_cs *cs); + void (*cs_flush)(struct r300_winsys_cs *cs, unsigned flags); /** * Set a flush callback which is called from winsys when flush is @@ -284,7 +279,7 @@ struct r300_winsys_screen { * \param user A user pointer that will be passed to the flush callback. */ void (*cs_set_flush)(struct r300_winsys_cs *cs, - void (*flush)(void *), + void (*flush)(void *ctx, unsigned flags), void *user); /** diff --git a/src/gallium/drivers/r600/eg_asm.c b/src/gallium/drivers/r600/eg_asm.c index 8cb417f9731..20a319a255d 100644 --- a/src/gallium/drivers/r600/eg_asm.c +++ b/src/gallium/drivers/r600/eg_asm.c @@ -97,15 +97,3 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) } return 0; } - -void eg_cf_vtx(struct r600_vertex_element *ve) -{ - struct r600_pipe_state *rstate = &ve->rstate; - rstate->id = R600_PIPE_STATE_FETCH_SHADER; - rstate->nregs = 0; - r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS, - (r600_bo_offset(ve->fetch_shader)) >> 8, - 0xFFFFFFFF, ve->fetch_shader); -} diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c index 4206b4a201d..77432661b64 100644 --- a/src/gallium/drivers/r600/evergreen_state.c +++ b/src/gallium/drivers/r600/evergreen_state.c @@ -150,10 +150,6 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ - /* db_shader_control is 0xFFFFFFBE as Z_EXPORT_ENABLE (bit 0) will be - * set by fragment shader if it export Z and KILL_ENABLE (bit 6) will - * be set if shader use texkill instruction - */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); stencil_ref_mask = 0; stencil_ref_mask_bf = 0; @@ -210,7 +206,10 @@ static void *evergreen_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_028438_SX_ALPHA_REF, alpha_ref, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBE, NULL); + /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE, + * STENCIL_EXPORT_ENABLE and KILL_ENABLE are controlled by + * evergreen_pipe_shader_ps().*/ + r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBC, NULL); r600_pipe_state_add_reg(rstate, R_028000_DB_RENDER_CONTROL, db_render_control, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_02800C_DB_RENDER_OVERRIDE, db_render_override, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028AC0_DB_SRESULTS_COMPARE_STATE0, 0x0, 0xFFFFFFFF, NULL); @@ -1329,7 +1328,7 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader { struct r600_pipe_state *rstate = &shader->rstate; struct r600_shader *rshader = &shader->shader; - unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1; + unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control; int pos_index = -1, face_index = -1; int ninterp = 0; boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE; @@ -1337,6 +1336,7 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader rstate->nregs = 0; + db_shader_control = 0; for (i = 0; i < rshader->ninput; i++) { /* evergreen NUM_INTERP only contains values interpolated into the LDS, POSITION goes via GPRs from the SC so isn't counted */ @@ -1358,16 +1358,12 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader } for (i = 0; i < rshader->noutput; i++) { if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) - r600_pipe_state_add_reg(rstate, - R_02880C_DB_SHADER_CONTROL, - S_02880C_Z_EXPORT_ENABLE(1), - S_02880C_Z_EXPORT_ENABLE(1), NULL); + db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1); if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL) - r600_pipe_state_add_reg(rstate, - R_02880C_DB_SHADER_CONTROL, - S_02880C_STENCIL_EXPORT_ENABLE(1), - S_02880C_STENCIL_EXPORT_ENABLE(1), NULL); + db_shader_control |= S_02880C_STENCIL_EXPORT_ENABLE(1); } + if (rshader->uses_kill) + db_shader_control |= S_02880C_KILL_ENABLE(1); exports_ps = 0; num_cout = 0; @@ -1442,15 +1438,15 @@ void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader r600_pipe_state_add_reg(rstate, R_02884C_SQ_PGM_EXPORTS_PS, exports_ps, 0xFFFFFFFF, NULL); - - if (rshader->uses_kill) { - /* only set some bits here, the other bits are set in the dsa state */ - r600_pipe_state_add_reg(rstate, - R_02880C_DB_SHADER_CONTROL, - S_02880C_KILL_ENABLE(1), - S_02880C_KILL_ENABLE(1), NULL); - } - + /* FIXME: Evergreen doesn't seem to support MULTIWRITE_ENABLE. */ + /* only set some bits here, the other bits are set in the dsa state */ + r600_pipe_state_add_reg(rstate, + R_02880C_DB_SHADER_CONTROL, + db_shader_control, + S_02880C_Z_EXPORT_ENABLE(1) | + S_02880C_STENCIL_EXPORT_ENABLE(1) | + S_02880C_KILL_ENABLE(1), + NULL); r600_pipe_state_add_reg(rstate, R_03A200_SQ_LOOP_CONST_0, 0x01000FFF, 0xFFFFFFFF, NULL); @@ -1501,6 +1497,18 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader 0xFFFFFFFF, NULL); } +void evergreen_fetch_shader(struct r600_vertex_element *ve) +{ + struct r600_pipe_state *rstate = &ve->rstate; + rstate->id = R600_PIPE_STATE_FETCH_SHADER; + rstate->nregs = 0; + r600_pipe_state_add_reg(rstate, R_0288A8_SQ_PGM_RESOURCES_FS, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_START_FS, + (r600_bo_offset(ve->fetch_shader)) >> 8, + 0xFFFFFFFF, ve->fetch_shader); +} + void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx) { struct pipe_depth_stencil_alpha_state dsa; diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c index 996d9f74a60..45e614977e2 100644 --- a/src/gallium/drivers/r600/r600_asm.c +++ b/src/gallium/drivers/r600/r600_asm.c @@ -483,7 +483,9 @@ static int is_alu_mova_inst(struct r600_bc *bc, 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(bc, alu) || - is_alu_mova_inst(bc, alu); + is_alu_mova_inst(bc, alu) || + (bc->chiprev == CHIPREV_EVERGREEN && + alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_FLT_TO_INT_FLOOR); } /* alu instructions that can only execute on the trans unit */ @@ -525,8 +527,9 @@ static int is_alu_trans_unit_inst(struct r600_bc *bc, struct r600_bc_alu *alu) case CHIPREV_EVERGREEN: default: if (!alu->is_op3) - /* Note that FLT_TO_INT* instructions are vector instructions - * on Evergreen, despite what the documentation says. */ + /* Note that FLT_TO_INT_* instructions are vector-only instructions + * on Evergreen, despite what the documentation says. FLT_TO_INT + * can do both vector and scalar. */ 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_INT_TO_FLT || alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_LSHL_INT || @@ -1314,6 +1317,24 @@ static void r600_bc_remove_alu(struct r600_bc_cf *cf, struct r600_bc_alu *alu) cf->ndw -= 2; } +static unsigned r600_bc_num_tex_and_vtx_instructions(const struct r600_bc *bc) +{ + switch (bc->chiprev) { + case CHIPREV_R600: + return 8; + + case CHIPREV_R700: + return 16; + + case CHIPREV_EVERGREEN: + return 64; + + default: + R600_ERR("Unknown chiprev %d.\n", bc->chiprev); + return 8; + } +} + int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx) { struct r600_bc_vtx *nvtx = r600_bc_vtx(); @@ -1339,7 +1360,7 @@ int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx) /* each fetch use 4 dwords */ bc->cf_last->ndw += 4; bc->ndw += 4; - if ((bc->cf_last->ndw / 4) > 7) + if ((bc->cf_last->ndw / 4) >= r600_bc_num_tex_and_vtx_instructions(bc)) bc->force_add_cf = 1; return 0; } @@ -1386,7 +1407,7 @@ int r600_bc_add_tex(struct r600_bc *bc, const struct r600_bc_tex *tex) /* each texture fetch use 4 dwords */ bc->cf_last->ndw += 4; bc->ndw += 4; - if ((bc->cf_last->ndw / 4) > 7) + if ((bc->cf_last->ndw / 4) >= r600_bc_num_tex_and_vtx_instructions(bc)) bc->force_add_cf = 1; return 0; } @@ -1406,31 +1427,7 @@ int r600_bc_add_cfinst(struct r600_bc *bc, int inst) /* common to all 3 families */ static int r600_bc_vtx_build(struct r600_bc *bc, struct r600_bc_vtx *vtx, unsigned id) { - unsigned fetch_resource_start = 0; - - /* check if we are fetch shader */ - /* fetch shader can also access vertex resource, - * first fetch shader resource is at 160 - */ - if (bc->type == -1) { - switch (bc->chiprev) { - /* r600 */ - case CHIPREV_R600: - /* r700 */ - case CHIPREV_R700: - fetch_resource_start = 160; - break; - /* evergreen */ - case CHIPREV_EVERGREEN: - fetch_resource_start = 0; - break; - default: - fprintf(stderr, "%s:%s:%d unknown chiprev %d\n", - __FILE__, __func__, __LINE__, bc->chiprev); - break; - } - } - bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id + fetch_resource_start) | + bc->bytecode[id++] = S_SQ_VTX_WORD0_BUFFER_ID(vtx->buffer_id) | S_SQ_VTX_WORD0_FETCH_TYPE(vtx->fetch_type) | S_SQ_VTX_WORD0_SRC_GPR(vtx->src_gpr) | S_SQ_VTX_WORD0_SRC_SEL_X(vtx->src_sel_x) | @@ -1523,6 +1520,14 @@ static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsign return 0; } +static void r600_bc_cf_vtx_build(uint32_t *bytecode, const struct r600_bc_cf *cf) +{ + *bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); + *bytecode++ = S_SQ_CF_WORD1_CF_INST(cf->inst) | + S_SQ_CF_WORD1_BARRIER(1) | + S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1); +} + enum cf_class { CF_CLASS_ALU, @@ -1596,11 +1601,10 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf) break; case CF_CLASS_TEXTURE: case CF_CLASS_VERTEX: - bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); - bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) | - S_SQ_CF_WORD1_BARRIER(cf->barrier) | - S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1) | - S_SQ_CF_WORD1_END_OF_PROGRAM(end_of_program); + if (bc->chiprev == CHIPREV_R700) + r700_bc_cf_vtx_build(&bc->bytecode[id], cf); + else + r600_bc_cf_vtx_build(&bc->bytecode[id], cf); break; case CF_CLASS_EXPORT: bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) | @@ -2801,22 +2805,6 @@ void r600_bc_dump(struct r600_bc *bc) fprintf(stderr, "--------------------------------------\n"); } -static void r600_cf_vtx(struct r600_vertex_element *ve) -{ - struct r600_pipe_state *rstate; - - rstate = &ve->rstate; - rstate->id = R600_PIPE_STATE_FETCH_SHADER; - rstate->nregs = 0; - r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_RESOURCES_FS, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_0288DC_SQ_PGM_CF_OFFSET_FS, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS, - r600_bo_offset(ve->fetch_shader) >> 8, - 0xFFFFFFFF, ve->fetch_shader); -} - static void r600_vertex_data_type(enum pipe_format pformat, unsigned *format, unsigned *num_format, unsigned *format_comp) { @@ -2987,7 +2975,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru alu.src[0].chan = 3; alu.src[1].sel = V_SQ_ALU_SRC_LITERAL; - alu.src[1].value = (1l << 32) / elements[i].instance_divisor + 1; + alu.src[1].value = (1ll << 32) / elements[i].instance_divisor + 1; alu.dst.sel = i + 1; alu.dst.chan = 3; @@ -3075,9 +3063,9 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru r600_bc_clear(&bc); if (rctx->family >= CHIP_CEDAR) - eg_cf_vtx(ve); + evergreen_fetch_shader(ve); else - r600_cf_vtx(ve); + r600_fetch_shader(ve); return 0; } diff --git a/src/gallium/drivers/r600/r600_asm.h b/src/gallium/drivers/r600/r600_asm.h index dbd1e204b49..db8d0a4ed10 100644 --- a/src/gallium/drivers/r600/r600_asm.h +++ b/src/gallium/drivers/r600/r600_asm.h @@ -188,7 +188,6 @@ struct r600_bc { /* eg_asm.c */ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf); -void eg_cf_vtx(struct r600_vertex_element *ve); /* r600_asm.c */ int r600_bc_init(struct r600_bc *bc, enum radeon_family family); @@ -206,6 +205,7 @@ void r600_bc_dump(struct r600_bc *bc); int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, struct r600_vertex_element *ve); /* r700_asm.c */ +void r700_bc_cf_vtx_build(uint32_t *bytecode, const struct r600_bc_cf *cf); int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id); #endif diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c index 2363cd1ebc5..6ced719c8f0 100644 --- a/src/gallium/drivers/r600/r600_buffer.c +++ b/src/gallium/drivers/r600/r600_buffer.c @@ -52,14 +52,6 @@ static void r600_buffer_destroy(struct pipe_screen *screen, util_slab_free(&rscreen->pool_buffers, rbuffer); } -static unsigned r600_buffer_is_referenced_by_cs(struct pipe_context *context, - struct pipe_resource *buf, - unsigned level, int layer) -{ - /* FIXME */ - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} - static struct pipe_transfer *r600_get_transfer(struct pipe_context *ctx, struct pipe_resource *resource, unsigned level, @@ -160,7 +152,6 @@ static const struct u_resource_vtbl r600_buffer_vtbl = { u_default_resource_get_handle, /* get_handle */ r600_buffer_destroy, /* resource_destroy */ - r600_buffer_is_referenced_by_cs, /* is_buffer_referenced */ r600_get_transfer, /* get_transfer */ r600_transfer_destroy, /* transfer_destroy */ r600_buffer_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 651f994a502..4a30eddb621 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -49,7 +49,7 @@ /* * pipe_context */ -static void r600_flush(struct pipe_context *ctx, unsigned flags, +static void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -281,18 +281,28 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_BLEND_EQUATION_SEPARATE: case PIPE_CAP_SM3: case PIPE_CAP_TEXTURE_SWIZZLE: - case PIPE_CAP_INDEP_BLEND_ENABLE: case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE: case PIPE_CAP_DEPTH_CLAMP: case PIPE_CAP_SHADER_STENCIL_EXPORT: - case PIPE_CAP_INSTANCED_DRAWING: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; + case PIPE_CAP_INDEP_BLEND_ENABLE: + /* R600 doesn't support per-MRT blends */ + if (family == CHIP_R600) + return 0; + else + return 1; /* Unsupported features (boolean caps). */ case PIPE_CAP_STREAM_OUTPUT: case PIPE_CAP_PRIMITIVE_RESTART: case PIPE_CAP_INDEP_BLEND_FUNC: /* FIXME allow this */ - return 0; + /* R600 doesn't support per-MRT blends */ + if (family == CHIP_R600) + return 0; + else + return 0; case PIPE_CAP_ARRAY_TEXTURES: /* fix once the CS checker upstream is fixed */ @@ -394,7 +404,7 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e case PIPE_SHADER_CAP_MAX_ADDRS: return 1; //max native address registers/* FIXME Isn't this equal to TEMPS? */ case PIPE_SHADER_CAP_MAX_CONSTS: - return 256; //max native parameters + return R600_MAX_CONST_BUFFER_SIZE; case PIPE_SHADER_CAP_MAX_CONST_BUFFERS: return R600_MAX_CONST_BUFFERS; case PIPE_SHADER_CAP_MAX_PREDS: @@ -417,8 +427,7 @@ static boolean r600_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned usage, - unsigned geom_flags) + unsigned usage) { unsigned retval = 0; if (target >= PIPE_MAX_TEXTURE_TYPES) { diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index 5f701d87e8f..396801e4a41 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -38,6 +38,7 @@ #include "r600_resource.h" #define R600_MAX_CONST_BUFFERS 1 +#define R600_MAX_CONST_BUFFER_SIZE 4096 enum r600_pipe_state_id { R600_PIPE_STATE_BLEND = 0, @@ -175,6 +176,7 @@ void evergreen_init_state_functions(struct r600_pipe_context *rctx); void evergreen_init_config(struct r600_pipe_context *rctx); void evergreen_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); +void evergreen_fetch_shader(struct r600_vertex_element *ve); void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx); void evergreen_polygon_offset_update(struct r600_pipe_context *rctx); void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx, @@ -214,6 +216,9 @@ int r600_find_vs_semantic_index(struct r600_shader *vs, void r600_init_state_functions(struct r600_pipe_context *rctx); void r600_spi_update(struct r600_pipe_context *rctx); void r600_init_config(struct r600_pipe_context *rctx); +void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader); +void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader); +void r600_fetch_shader(struct r600_vertex_element *ve); void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx); void r600_polygon_offset_update(struct r600_pipe_context *rctx); void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx, diff --git a/src/gallium/drivers/r600/r600_query.c b/src/gallium/drivers/r600/r600_query.c index 343403f92f3..181ea3f9e49 100644 --- a/src/gallium/drivers/r600/r600_query.c +++ b/src/gallium/drivers/r600/r600_query.c @@ -62,7 +62,7 @@ static boolean r600_get_query_result(struct pipe_context *ctx, struct r600_query *rquery = (struct r600_query *)query; if (rquery->num_results) { - ctx->flush(ctx, 0, NULL); + ctx->flush(ctx, NULL); } return r600_context_query_result(&rctx->ctx, (struct r600_query *)query, wait, vresult); } diff --git a/src/gallium/drivers/r600/r600_resource.c b/src/gallium/drivers/r600/r600_resource.c index 207642ccfa9..f3ab3613c84 100644 --- a/src/gallium/drivers/r600/r600_resource.c +++ b/src/gallium/drivers/r600/r600_resource.c @@ -61,5 +61,4 @@ void r600_init_context_resource_functions(struct r600_pipe_context *r600) r600->context.transfer_unmap = u_transfer_unmap_vtbl; r600->context.transfer_destroy = u_transfer_destroy_vtbl; r600->context.transfer_inline_write = u_transfer_inline_write_vtbl; - r600->context.is_resource_referenced = u_is_resource_referenced_vtbl; } diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c index 0b4dc75e584..12786daa464 100644 --- a/src/gallium/drivers/r600/r600_shader.c +++ b/src/gallium/drivers/r600/r600_shader.c @@ -34,55 +34,6 @@ #include <stdio.h> #include <errno.h> -static void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader) -{ - struct r600_pipe_state *rstate = &shader->rstate; - struct r600_shader *rshader = &shader->shader; - unsigned spi_vs_out_id[10]; - unsigned i, tmp; - - /* clear previous register */ - rstate->nregs = 0; - - /* so far never got proper semantic id from tgsi */ - /* FIXME better to move this in config things so they get emited - * only one time per cs - */ - for (i = 0; i < 10; i++) { - spi_vs_out_id[i] = 0; - } - for (i = 0; i < 32; i++) { - tmp = i << ((i & 3) * 8); - spi_vs_out_id[i / 4] |= tmp; - } - for (i = 0; i < 10; i++) { - r600_pipe_state_add_reg(rstate, - R_028614_SPI_VS_OUT_ID_0 + i * 4, - spi_vs_out_id[i], 0xFFFFFFFF, NULL); - } - - r600_pipe_state_add_reg(rstate, - R_0286C4_SPI_VS_OUT_CONFIG, - S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2), - 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, - R_028868_SQ_PGM_RESOURCES_VS, - S_028868_NUM_GPRS(rshader->bc.ngpr) | - S_028868_STACK_SIZE(rshader->bc.nstack), - 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, - R_0288D0_SQ_PGM_CF_OFFSET_VS, - 0x00000000, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, - R_028858_SQ_PGM_START_VS, - r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo); - - r600_pipe_state_add_reg(rstate, - R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, - 0xFFFFFFFF, NULL); - -} - int r600_find_vs_semantic_index(struct r600_shader *vs, struct r600_shader *ps, int id) { @@ -97,104 +48,6 @@ int r600_find_vs_semantic_index(struct r600_shader *vs, return 0; } -static void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader) -{ - struct r600_pipe_state *rstate = &shader->rstate; - struct r600_shader *rshader = &shader->shader; - unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1; - int pos_index = -1, face_index = -1; - - rstate->nregs = 0; - - for (i = 0; i < rshader->ninput; i++) { - if (rshader->input[i].name == TGSI_SEMANTIC_POSITION) - pos_index = i; - if (rshader->input[i].name == TGSI_SEMANTIC_FACE) - face_index = i; - } - - for (i = 0; i < rshader->noutput; i++) { - if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) - r600_pipe_state_add_reg(rstate, - R_02880C_DB_SHADER_CONTROL, - S_02880C_Z_EXPORT_ENABLE(1), - S_02880C_Z_EXPORT_ENABLE(1), NULL); - if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL) - r600_pipe_state_add_reg(rstate, - R_02880C_DB_SHADER_CONTROL, - S_02880C_STENCIL_REF_EXPORT_ENABLE(1), - S_02880C_STENCIL_REF_EXPORT_ENABLE(1), NULL); - } - - exports_ps = 0; - num_cout = 0; - for (i = 0; i < rshader->noutput; i++) { - if (rshader->output[i].name == TGSI_SEMANTIC_POSITION || rshader->output[i].name == TGSI_SEMANTIC_STENCIL) - exports_ps |= 1; - else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) { - num_cout++; - } - } - exports_ps |= S_028854_EXPORT_COLORS(num_cout); - if (!exports_ps) { - /* always at least export 1 component per pixel */ - exports_ps = 2; - } - - spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) | - S_0286CC_PERSP_GRADIENT_ENA(1); - spi_input_z = 0; - if (pos_index != -1) { - spi_ps_in_control_0 |= (S_0286CC_POSITION_ENA(1) | - S_0286CC_POSITION_CENTROID(rshader->input[pos_index].centroid) | - S_0286CC_POSITION_ADDR(rshader->input[pos_index].gpr) | - S_0286CC_BARYC_SAMPLE_CNTL(1)); - spi_input_z |= 1; - } - - spi_ps_in_control_1 = 0; - if (face_index != -1) { - spi_ps_in_control_1 |= S_0286D0_FRONT_FACE_ENA(1) | - S_0286D0_FRONT_FACE_ADDR(rshader->input[face_index].gpr); - } - - r600_pipe_state_add_reg(rstate, R_0286CC_SPI_PS_IN_CONTROL_0, spi_ps_in_control_0, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_0286D0_SPI_PS_IN_CONTROL_1, spi_ps_in_control_1, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_0286D8_SPI_INPUT_Z, spi_input_z, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, - R_028840_SQ_PGM_START_PS, - r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo); - r600_pipe_state_add_reg(rstate, - R_028850_SQ_PGM_RESOURCES_PS, - S_028868_NUM_GPRS(rshader->bc.ngpr) | - S_028868_STACK_SIZE(rshader->bc.nstack), - 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, - R_028854_SQ_PGM_EXPORTS_PS, - exports_ps, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, - R_0288CC_SQ_PGM_CF_OFFSET_PS, - 0x00000000, 0xFFFFFFFF, NULL); - - if (rshader->fs_write_all) { - r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL, - S_028808_MULTIWRITE_ENABLE(1), - S_028808_MULTIWRITE_ENABLE(1), - NULL); - } - - if (rshader->uses_kill) { - /* only set some bits here, the other bits are set in the dsa state */ - r600_pipe_state_add_reg(rstate, - R_02880C_DB_SHADER_CONTROL, - S_02880C_KILL_ENABLE(1), - S_02880C_KILL_ENABLE(1), NULL); - } - r600_pipe_state_add_reg(rstate, - R_03E200_SQ_LOOP_CONST_0, 0x01000FFF, - 0xFFFFFFFF, NULL); -} - static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *shader) { struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; @@ -1706,37 +1559,15 @@ static int tgsi_tex(struct r600_shader_ctx *ctx) } if (inst->Texture.Texture == TGSI_TEXTURE_CUBE) { - int src_chan, src2_chan; + static const unsigned src0_swizzle[] = {2, 2, 0, 1}; + static const unsigned src1_swizzle[] = {1, 0, 2, 2}; /* tmp1.xyzw = CUBE(R0.zzxy, R0.yxzz) */ for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_CUBE); - switch (i) { - case 0: - src_chan = 2; - src2_chan = 1; - break; - case 1: - src_chan = 2; - src2_chan = 0; - break; - case 2: - src_chan = 0; - src2_chan = 2; - break; - case 3: - src_chan = 1; - src2_chan = 2; - break; - default: - assert(0); - src_chan = 0; - src2_chan = 0; - break; - } - r600_bc_src(&alu.src[0], &ctx->src[0], src_chan); - r600_bc_src(&alu.src[1], &ctx->src[0], src2_chan); + r600_bc_src(&alu.src[0], &ctx->src[0], src0_swizzle[i]); + r600_bc_src(&alu.src[1], &ctx->src[0], src1_swizzle[i]); alu.dst.sel = ctx->temp_reg; alu.dst.chan = i; if (i == 3) @@ -2011,6 +1842,8 @@ static int tgsi_cmp(struct r600_shader_ctx *ctx) static int tgsi_xpd(struct r600_shader_ctx *ctx) { struct tgsi_full_instruction *inst = &ctx->parse.FullToken.FullInstruction; + static const unsigned int src0_swizzle[] = {2, 0, 1}; + static const unsigned int src1_swizzle[] = {1, 2, 0}; struct r600_bc_alu alu; uint32_t use_temp = 0; int i, r; @@ -2021,33 +1854,12 @@ static int tgsi_xpd(struct r600_shader_ctx *ctx) for (i = 0; i < 4; i++) { memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL); - - switch (i) { - case 0: - r600_bc_src(&alu.src[0], &ctx->src[0], 2); - break; - case 1: - r600_bc_src(&alu.src[0], &ctx->src[0], 0); - break; - case 2: - r600_bc_src(&alu.src[0], &ctx->src[0], 1); - break; - case 3: + if (i < 3) { + r600_bc_src(&alu.src[0], &ctx->src[0], src0_swizzle[i]); + r600_bc_src(&alu.src[1], &ctx->src[1], src1_swizzle[i]); + } else { alu.src[0].sel = V_SQ_ALU_SRC_0; alu.src[0].chan = i; - } - - switch (i) { - case 0: - r600_bc_src(&alu.src[1], &ctx->src[1], 1); - break; - case 1: - r600_bc_src(&alu.src[1], &ctx->src[1], 2); - break; - case 2: - r600_bc_src(&alu.src[1], &ctx->src[1], 0); - break; - case 3: alu.src[1].sel = V_SQ_ALU_SRC_0; alu.src[1].chan = i; } @@ -2067,32 +1879,12 @@ static int tgsi_xpd(struct r600_shader_ctx *ctx) memset(&alu, 0, sizeof(struct r600_bc_alu)); alu.inst = CTX_INST(V_SQ_ALU_WORD1_OP3_SQ_OP3_INST_MULADD); - switch (i) { - case 0: - r600_bc_src(&alu.src[0], &ctx->src[0], 1); - break; - case 1: - r600_bc_src(&alu.src[0], &ctx->src[0], 2); - break; - case 2: - r600_bc_src(&alu.src[0], &ctx->src[0], 0); - break; - case 3: + if (i < 3) { + r600_bc_src(&alu.src[0], &ctx->src[0], src1_swizzle[i]); + r600_bc_src(&alu.src[1], &ctx->src[1], src0_swizzle[i]); + } else { alu.src[0].sel = V_SQ_ALU_SRC_0; alu.src[0].chan = i; - } - - switch (i) { - case 0: - r600_bc_src(&alu.src[1], &ctx->src[1], 2); - break; - case 1: - r600_bc_src(&alu.src[1], &ctx->src[1], 0); - break; - case 2: - r600_bc_src(&alu.src[1], &ctx->src[1], 1); - break; - case 3: alu.src[1].sel = V_SQ_ALU_SRC_0; alu.src[1].chan = i; } @@ -2960,7 +2752,7 @@ static struct r600_shader_tgsi_instruction eg_shader_tgsi_instruction[] = { {TGSI_OPCODE_RCP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIP_IEEE, tgsi_trans_srcx_replicate}, {TGSI_OPCODE_RSQ, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_RECIPSQRT_IEEE, tgsi_trans_srcx_replicate}, {TGSI_OPCODE_EXP, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_exp}, - {TGSI_OPCODE_LOG, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_unsupported}, + {TGSI_OPCODE_LOG, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_NOP, tgsi_log}, {TGSI_OPCODE_MUL, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MUL, tgsi_op2}, {TGSI_OPCODE_ADD, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_ADD, tgsi_op2}, {TGSI_OPCODE_DP3, 0, EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_DOT4, tgsi_dp}, diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 1be641798f7..efb68cbd139 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -117,9 +117,10 @@ static void r600_set_blend_color(struct pipe_context *ctx, static void *r600_create_blend_state(struct pipe_context *ctx, const struct pipe_blend_state *state) { + struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx; struct r600_pipe_blend *blend = CALLOC_STRUCT(r600_pipe_blend); struct r600_pipe_state *rstate; - u32 color_control, target_mask; + u32 color_control = 0, target_mask; if (blend == NULL) { return NULL; @@ -129,7 +130,10 @@ static void *r600_create_blend_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_BLEND; target_mask = 0; - color_control = S_028808_PER_MRT_BLEND(1); + + /* R600 does not support per-MRT blends */ + if (rctx->family > CHIP_R600) + color_control |= S_028808_PER_MRT_BLEND(1); if (state->logicop_enable) { color_control |= (state->logicop_func << 16) | (state->logicop_func << 20); } else { @@ -152,8 +156,9 @@ static void *r600_create_blend_state(struct pipe_context *ctx, } } blend->cb_target_mask = target_mask; + /* MULTIWRITE_ENABLE is controlled by r600_pipe_shader_ps(). */ r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL, - color_control, 0xFFFFFFFF, NULL); + color_control, 0xFFFFFFFD, NULL); for (int i = 0; i < 8; i++) { unsigned eqRGB = state->rt[i].rgb_func; @@ -179,10 +184,11 @@ static void *r600_create_blend_state(struct pipe_context *ctx, bc |= S_028804_ALPHA_DESTBLEND(r600_translate_blend_factor(dstA)); } - r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, bc, 0xFFFFFFFF, NULL); - if (i == 0) { + /* R600 does not support per-MRT blends */ + if (rctx->family > CHIP_R600) + r600_pipe_state_add_reg(rstate, R_028780_CB_BLEND0_CONTROL + i * 4, bc, 0xFFFFFFFF, NULL); + if (i == 0) r600_pipe_state_add_reg(rstate, R_028804_CB_BLEND_CONTROL, bc, 0xFFFFFFFF, NULL); - } } return rstate; } @@ -200,10 +206,6 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, rstate->id = R600_PIPE_STATE_DSA; /* depth TODO some of those db_shader_control field depend on shader adjust mask & add it to shader */ - /* db_shader_control is 0xFFFFFFBE as Z_EXPORT_ENABLE (bit 0) will be - * set by fragment shader if it export Z and KILL_ENABLE (bit 6) will - * be set if shader use texkill instruction - */ db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z); stencil_ref_mask = 0; stencil_ref_mask_bf = 0; @@ -262,7 +264,10 @@ static void *r600_create_dsa_state(struct pipe_context *ctx, r600_pipe_state_add_reg(rstate, R_0286E4_SPI_FOG_FUNC_BIAS, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_0286DC_SPI_FOG_CNTL, 0x00000000, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028800_DB_DEPTH_CONTROL, db_depth_control, 0xFFFFFFFF, NULL); - r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBE, NULL); + /* The DB_SHADER_CONTROL mask is 0xFFFFFFBC since Z_EXPORT_ENABLE, + * STENCIL_EXPORT_ENABLE and KILL_ENABLE are controlled by + * r600_pipe_shader_ps().*/ + r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, db_shader_control, 0xFFFFFFBC, NULL); r600_pipe_state_add_reg(rstate, R_028D0C_DB_RENDER_CONTROL, db_render_control, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028D10_DB_RENDER_OVERRIDE, db_render_override, 0xFFFFFFFF, NULL); r600_pipe_state_add_reg(rstate, R_028D2C_DB_SRESULTS_COMPARE_STATE1, 0x00000000, 0xFFFFFFFF, NULL); @@ -501,7 +506,8 @@ static void r600_set_vs_sampler_view(struct pipe_context *ctx, unsigned count, for (int i = 0; i < count; i++) { if (resource[i]) { - r600_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, i); + r600_context_pipe_state_set_vs_resource(&rctx->ctx, &resource[i]->state, + i + R600_MAX_CONST_BUFFERS); } } } @@ -1232,6 +1238,163 @@ void r600_init_config(struct r600_pipe_context *rctx) r600_context_pipe_state_set(&rctx->ctx, rstate); } +void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader *shader) +{ + struct r600_pipe_state *rstate = &shader->rstate; + struct r600_shader *rshader = &shader->shader; + unsigned i, exports_ps, num_cout, spi_ps_in_control_0, spi_input_z, spi_ps_in_control_1, db_shader_control; + int pos_index = -1, face_index = -1; + + rstate->nregs = 0; + + for (i = 0; i < rshader->ninput; i++) { + if (rshader->input[i].name == TGSI_SEMANTIC_POSITION) + pos_index = i; + if (rshader->input[i].name == TGSI_SEMANTIC_FACE) + face_index = i; + } + + db_shader_control = 0; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION) + db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1); + if (rshader->output[i].name == TGSI_SEMANTIC_STENCIL) + db_shader_control |= S_02880C_STENCIL_REF_EXPORT_ENABLE(1); + } + if (rshader->uses_kill) + db_shader_control |= S_02880C_KILL_ENABLE(1); + + exports_ps = 0; + num_cout = 0; + for (i = 0; i < rshader->noutput; i++) { + if (rshader->output[i].name == TGSI_SEMANTIC_POSITION || + rshader->output[i].name == TGSI_SEMANTIC_STENCIL) + exports_ps |= 1; + else if (rshader->output[i].name == TGSI_SEMANTIC_COLOR) { + num_cout++; + } + } + exports_ps |= S_028854_EXPORT_COLORS(num_cout); + if (!exports_ps) { + /* always at least export 1 component per pixel */ + exports_ps = 2; + } + + spi_ps_in_control_0 = S_0286CC_NUM_INTERP(rshader->ninput) | + S_0286CC_PERSP_GRADIENT_ENA(1); + spi_input_z = 0; + if (pos_index != -1) { + spi_ps_in_control_0 |= (S_0286CC_POSITION_ENA(1) | + S_0286CC_POSITION_CENTROID(rshader->input[pos_index].centroid) | + S_0286CC_POSITION_ADDR(rshader->input[pos_index].gpr) | + S_0286CC_BARYC_SAMPLE_CNTL(1)); + spi_input_z |= 1; + } + + spi_ps_in_control_1 = 0; + if (face_index != -1) { + spi_ps_in_control_1 |= S_0286D0_FRONT_FACE_ENA(1) | + S_0286D0_FRONT_FACE_ADDR(rshader->input[face_index].gpr); + } + + r600_pipe_state_add_reg(rstate, R_0286CC_SPI_PS_IN_CONTROL_0, spi_ps_in_control_0, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_0286D0_SPI_PS_IN_CONTROL_1, spi_ps_in_control_1, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_0286D8_SPI_INPUT_Z, spi_input_z, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, + R_028840_SQ_PGM_START_PS, + r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo); + r600_pipe_state_add_reg(rstate, + R_028850_SQ_PGM_RESOURCES_PS, + S_028868_NUM_GPRS(rshader->bc.ngpr) | + S_028868_STACK_SIZE(rshader->bc.nstack), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, + R_028854_SQ_PGM_EXPORTS_PS, + exports_ps, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, + R_0288CC_SQ_PGM_CF_OFFSET_PS, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028808_CB_COLOR_CONTROL, + S_028808_MULTIWRITE_ENABLE(!!rshader->fs_write_all), + S_028808_MULTIWRITE_ENABLE(1), + NULL); + /* only set some bits here, the other bits are set in the dsa state */ + r600_pipe_state_add_reg(rstate, R_02880C_DB_SHADER_CONTROL, + db_shader_control, + S_02880C_Z_EXPORT_ENABLE(1) | + S_02880C_STENCIL_REF_EXPORT_ENABLE(1) | + S_02880C_KILL_ENABLE(1), + NULL); + + r600_pipe_state_add_reg(rstate, + R_03E200_SQ_LOOP_CONST_0, 0x01000FFF, + 0xFFFFFFFF, NULL); +} + +void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shader) +{ + struct r600_pipe_state *rstate = &shader->rstate; + struct r600_shader *rshader = &shader->shader; + unsigned spi_vs_out_id[10]; + unsigned i, tmp; + + /* clear previous register */ + rstate->nregs = 0; + + /* so far never got proper semantic id from tgsi */ + /* FIXME better to move this in config things so they get emited + * only one time per cs + */ + for (i = 0; i < 10; i++) { + spi_vs_out_id[i] = 0; + } + for (i = 0; i < 32; i++) { + tmp = i << ((i & 3) * 8); + spi_vs_out_id[i / 4] |= tmp; + } + for (i = 0; i < 10; i++) { + r600_pipe_state_add_reg(rstate, + R_028614_SPI_VS_OUT_ID_0 + i * 4, + spi_vs_out_id[i], 0xFFFFFFFF, NULL); + } + + r600_pipe_state_add_reg(rstate, + R_0286C4_SPI_VS_OUT_CONFIG, + S_0286C4_VS_EXPORT_COUNT(rshader->noutput - 2), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, + R_028868_SQ_PGM_RESOURCES_VS, + S_028868_NUM_GPRS(rshader->bc.ngpr) | + S_028868_STACK_SIZE(rshader->bc.nstack), + 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, + R_0288D0_SQ_PGM_CF_OFFSET_VS, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, + R_028858_SQ_PGM_START_VS, + r600_bo_offset(shader->bo) >> 8, 0xFFFFFFFF, shader->bo); + + r600_pipe_state_add_reg(rstate, + R_03E200_SQ_LOOP_CONST_0 + (32 * 4), 0x01000FFF, + 0xFFFFFFFF, NULL); +} + +void r600_fetch_shader(struct r600_vertex_element *ve) +{ + struct r600_pipe_state *rstate; + + rstate = &ve->rstate; + rstate->id = R600_PIPE_STATE_FETCH_SHADER; + rstate->nregs = 0; + r600_pipe_state_add_reg(rstate, R_0288A4_SQ_PGM_RESOURCES_FS, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_0288DC_SQ_PGM_CF_OFFSET_FS, + 0x00000000, 0xFFFFFFFF, NULL); + r600_pipe_state_add_reg(rstate, R_028894_SQ_PGM_START_FS, + r600_bo_offset(ve->fetch_shader) >> 8, + 0xFFFFFFFF, ve->fetch_shader); +} + void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx) { struct pipe_depth_stencil_alpha_state dsa; diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 16b53a0b2a5..d079b571156 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -68,7 +68,7 @@ static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600 rtransfer->staging_texture, 0, &sbox); - ctx->flush(ctx, 0, NULL); + ctx->flush(ctx, NULL); } unsigned r600_texture_get_offset(struct r600_resource_texture *rtex, @@ -299,14 +299,14 @@ static boolean permit_hardware_blit(struct pipe_screen *screen, res->format, res->target, res->nr_samples, - bind, 0)) + bind)) return FALSE; if (!screen->is_format_supported(screen, res->format, res->target, res->nr_samples, - PIPE_BIND_SAMPLER_VIEW, 0)) + PIPE_BIND_SAMPLER_VIEW)) return FALSE; switch (res->usage) { @@ -349,19 +349,10 @@ static void r600_texture_destroy(struct pipe_screen *screen, FREE(rtex); } -static unsigned int r600_texture_is_referenced(struct pipe_context *context, - struct pipe_resource *texture, - unsigned level, int layer) -{ - /* FIXME */ - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} - static const struct u_resource_vtbl r600_texture_vtbl = { r600_texture_get_handle, /* get_handle */ r600_texture_destroy, /* resource_destroy */ - r600_texture_is_referenced, /* is_resource_referenced */ r600_texture_get_transfer, /* get_transfer */ r600_texture_transfer_destroy, /* transfer_destroy */ r600_texture_transfer_map, /* transfer_map */ @@ -423,10 +414,12 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, /* Would like some magic "get_bool_option_once" routine. */ if (force_tiling == -1) { - struct r600_screen *rscreen = (struct r600_screen *)screen; +#if 0 /* reenable when 2D tiling is fixed better */ - /*if (r600_get_minor_version(rscreen->radeon) >= 9) - force_tiling = debug_get_bool_option("R600_TILING", TRUE);*/ + struct r600_screen *rscreen = (struct r600_screen *)screen; + if (r600_get_minor_version(rscreen->radeon) >= 9) + force_tiling = debug_get_bool_option("R600_TILING", TRUE); +#endif force_tiling = debug_get_bool_option("R600_TILING", FALSE); } @@ -653,7 +646,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, if (usage & PIPE_TRANSFER_READ) { r600_copy_to_staging_texture(ctx, trans); /* Always referenced in the blit. */ - ctx->flush(ctx, 0, NULL); + ctx->flush(ctx, NULL); } return &trans->transfer; } diff --git a/src/gallium/drivers/r600/r700_asm.c b/src/gallium/drivers/r600/r700_asm.c index a7f2f54736e..b3c7d1494fc 100644 --- a/src/gallium/drivers/r600/r700_asm.c +++ b/src/gallium/drivers/r600/r700_asm.c @@ -26,6 +26,15 @@ #include "r600_asm.h" #include "r700_sq.h" +void r700_bc_cf_vtx_build(uint32_t *bytecode, const struct r600_bc_cf *cf) +{ + unsigned count = (cf->ndw / 4) - 1; + *bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1); + *bytecode++ = S_SQ_CF_WORD1_CF_INST(cf->inst) | + S_SQ_CF_WORD1_BARRIER(1) | + S_SQ_CF_WORD1_COUNT(count) | + S_SQ_CF_WORD1_COUNT_3(count >> 3); +} int r700_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsigned id) { diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c index 4a5d5413d8c..6e2d6ba1efa 100644 --- a/src/gallium/drivers/rbug/rbug_context.c +++ b/src/gallium/drivers/rbug/rbug_context.c @@ -44,7 +44,10 @@ rbug_destroy(struct pipe_context *_pipe) struct pipe_context *pipe = rb_pipe->pipe; remove_from_list(&rb_pipe->list); + pipe_mutex_lock(rb_pipe->call_mutex); pipe->destroy(pipe); + rb_pipe->pipe = NULL; + pipe_mutex_unlock(rb_pipe->call_mutex); FREE(rb_pipe); } @@ -112,7 +115,12 @@ rbug_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info) pipe_mutex_lock(rb_pipe->draw_mutex); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_BEFORE); - pipe->draw_vbo(pipe, info); + pipe_mutex_lock(rb_pipe->call_mutex); + if (!(rb_pipe->curr.fs && rb_pipe->curr.fs->disabled) && + !(rb_pipe->curr.gs && rb_pipe->curr.gs->disabled) && + !(rb_pipe->curr.vs && rb_pipe->curr.vs->disabled)) + pipe->draw_vbo(pipe, info); + pipe_mutex_unlock(rb_pipe->call_mutex); rbug_draw_block_locked(rb_pipe, RBUG_BLOCK_AFTER); pipe_mutex_unlock(rb_pipe->draw_mutex); @@ -125,8 +133,10 @@ rbug_create_query(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); return pipe->create_query(pipe, query_type); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -136,8 +146,10 @@ rbug_destroy_query(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->destroy_query(pipe, query); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -147,8 +159,10 @@ rbug_begin_query(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->begin_query(pipe, query); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -158,8 +172,10 @@ rbug_end_query(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->end_query(pipe, query); + pipe_mutex_unlock(rb_pipe->call_mutex); } static boolean @@ -170,11 +186,16 @@ rbug_get_query_result(struct pipe_context *_pipe, { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + boolean ret; - return pipe->get_query_result(pipe, - query, - wait, - result); + pipe_mutex_lock(rb_pipe->call_mutex); + ret = pipe->get_query_result(pipe, + query, + wait, + result); + pipe_mutex_unlock(rb_pipe->call_mutex); + + return ret; } static void * @@ -183,9 +204,14 @@ rbug_create_blend_state(struct pipe_context *_pipe, { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *ret; + + pipe_mutex_lock(rb_pipe->call_mutex); + ret = pipe->create_blend_state(pipe, + blend); + pipe_mutex_unlock(rb_pipe->call_mutex); - return pipe->create_blend_state(pipe, - blend); + return ret; } static void @@ -195,8 +221,10 @@ rbug_bind_blend_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->bind_blend_state(pipe, - blend); + blend); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -206,8 +234,10 @@ rbug_delete_blend_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->delete_blend_state(pipe, blend); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -216,9 +246,14 @@ rbug_create_sampler_state(struct pipe_context *_pipe, { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *ret; + + pipe_mutex_lock(rb_pipe->call_mutex); + ret = pipe->create_sampler_state(pipe, + sampler); + pipe_mutex_unlock(rb_pipe->call_mutex); - return pipe->create_sampler_state(pipe, - sampler); + return ret; } static void @@ -229,9 +264,11 @@ rbug_bind_fragment_sampler_states(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->bind_fragment_sampler_states(pipe, num_samplers, samplers); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -242,9 +279,11 @@ rbug_bind_vertex_sampler_states(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->bind_vertex_sampler_states(pipe, num_samplers, samplers); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -254,8 +293,10 @@ rbug_delete_sampler_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->delete_sampler_state(pipe, sampler); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -264,9 +305,14 @@ rbug_create_rasterizer_state(struct pipe_context *_pipe, { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *ret; - return pipe->create_rasterizer_state(pipe, - rasterizer); + pipe_mutex_lock(rb_pipe->call_mutex); + ret = pipe->create_rasterizer_state(pipe, + rasterizer); + pipe_mutex_unlock(rb_pipe->call_mutex); + + return ret; } static void @@ -276,8 +322,10 @@ rbug_bind_rasterizer_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->bind_rasterizer_state(pipe, rasterizer); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -287,8 +335,10 @@ rbug_delete_rasterizer_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->delete_rasterizer_state(pipe, rasterizer); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -297,9 +347,14 @@ rbug_create_depth_stencil_alpha_state(struct pipe_context *_pipe, { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *ret; + + pipe_mutex_lock(rb_pipe->call_mutex); + ret = pipe->create_depth_stencil_alpha_state(pipe, + depth_stencil_alpha); + pipe_mutex_unlock(rb_pipe->call_mutex); - return pipe->create_depth_stencil_alpha_state(pipe, - depth_stencil_alpha); + return ret; } static void @@ -309,8 +364,10 @@ rbug_bind_depth_stencil_alpha_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->bind_depth_stencil_alpha_state(pipe, depth_stencil_alpha); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -320,8 +377,10 @@ rbug_delete_depth_stencil_alpha_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->delete_depth_stencil_alpha_state(pipe, depth_stencil_alpha); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -332,7 +391,10 @@ rbug_create_fs_state(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; void *result; + pipe_mutex_lock(rb_pipe->call_mutex); result = pipe->create_fs_state(pipe, state); + pipe_mutex_unlock(rb_pipe->call_mutex); + if (!result) return NULL; @@ -347,10 +409,14 @@ rbug_bind_fs_state(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; void *fs; + pipe_mutex_lock(rb_pipe->call_mutex); + fs = rbug_shader_unwrap(_fs); rb_pipe->curr.fs = rbug_shader(_fs); pipe->bind_fs_state(pipe, fs); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -360,7 +426,9 @@ rbug_delete_fs_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct rbug_shader *rb_shader = rbug_shader(_fs); + pipe_mutex_lock(rb_pipe->call_mutex); rbug_shader_destroy(rb_pipe, rb_shader); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -371,7 +439,10 @@ rbug_create_vs_state(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; void *result; + pipe_mutex_lock(rb_pipe->call_mutex); result = pipe->create_vs_state(pipe, state); + pipe_mutex_unlock(rb_pipe->call_mutex); + if (!result) return NULL; @@ -386,10 +457,14 @@ rbug_bind_vs_state(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; void *vs; + pipe_mutex_lock(rb_pipe->call_mutex); + vs = rbug_shader_unwrap(_vs); rb_pipe->curr.vs = rbug_shader(_vs); pipe->bind_vs_state(pipe, vs); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -399,7 +474,9 @@ rbug_delete_vs_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct rbug_shader *rb_shader = rbug_shader(_vs); + pipe_mutex_unlock(rb_pipe->call_mutex); rbug_shader_destroy(rb_pipe, rb_shader); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -410,7 +487,10 @@ rbug_create_gs_state(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; void *result; + pipe_mutex_lock(rb_pipe->call_mutex); result = pipe->create_gs_state(pipe, state); + pipe_mutex_unlock(rb_pipe->call_mutex); + if (!result) return NULL; @@ -425,10 +505,14 @@ rbug_bind_gs_state(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; void *gs; + pipe_mutex_lock(rb_pipe->call_mutex); + gs = rbug_shader_unwrap(_gs); rb_pipe->curr.gs = rbug_shader(_gs); pipe->bind_gs_state(pipe, gs); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -438,7 +522,9 @@ rbug_delete_gs_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct rbug_shader *rb_shader = rbug_shader(_gs); + pipe_mutex_lock(rb_pipe->call_mutex); rbug_shader_destroy(rb_pipe, rb_shader); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -448,10 +534,15 @@ rbug_create_vertex_elements_state(struct pipe_context *_pipe, { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + void *ret; - return pipe->create_vertex_elements_state(pipe, + pipe_mutex_lock(rb_pipe->call_mutex); + ret = pipe->create_vertex_elements_state(pipe, num_elements, vertex_elements); + pipe_mutex_unlock(rb_pipe->call_mutex); + + return ret; } static void @@ -461,8 +552,10 @@ rbug_bind_vertex_elements_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->bind_vertex_elements_state(pipe, velems); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -472,8 +565,10 @@ rbug_delete_vertex_elements_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->delete_vertex_elements_state(pipe, velems); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -483,8 +578,10 @@ rbug_set_blend_color(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_blend_color(pipe, blend_color); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -494,8 +591,10 @@ rbug_set_stencil_ref(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_stencil_ref(pipe, stencil_ref); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -505,8 +604,10 @@ rbug_set_clip_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_clip_state(pipe, clip); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -526,10 +627,12 @@ rbug_set_constant_buffer(struct pipe_context *_pipe, resource = unwrapped_resource; } + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_constant_buffer(pipe, shader, index, resource); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -542,6 +645,9 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe, struct pipe_framebuffer_state *state = NULL; unsigned i; + /* must protect curr status */ + pipe_mutex_lock(rb_pipe->call_mutex); + rb_pipe->curr.nr_cbufs = 0; memset(rb_pipe->curr.cbufs, 0, sizeof(rb_pipe->curr.cbufs)); rb_pipe->curr.zsbuf = NULL; @@ -564,6 +670,8 @@ rbug_set_framebuffer_state(struct pipe_context *_pipe, pipe->set_framebuffer_state(pipe, state); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -573,8 +681,10 @@ rbug_set_polygon_stipple(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_polygon_stipple(pipe, poly_stipple); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -584,8 +694,10 @@ rbug_set_scissor_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_scissor_state(pipe, scissor); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -595,8 +707,10 @@ rbug_set_viewport_state(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_viewport_state(pipe, viewport); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -610,6 +724,9 @@ rbug_set_fragment_sampler_views(struct pipe_context *_pipe, struct pipe_sampler_view **views = NULL; unsigned i; + /* must protect curr status */ + pipe_mutex_lock(rb_pipe->call_mutex); + rb_pipe->curr.num_fs_views = 0; memset(rb_pipe->curr.fs_views, 0, sizeof(rb_pipe->curr.fs_views)); memset(rb_pipe->curr.fs_texs, 0, sizeof(rb_pipe->curr.fs_texs)); @@ -626,6 +743,8 @@ rbug_set_fragment_sampler_views(struct pipe_context *_pipe, } pipe->set_fragment_sampler_views(pipe, num, views); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -639,6 +758,9 @@ rbug_set_vertex_sampler_views(struct pipe_context *_pipe, struct pipe_sampler_view **views = NULL; unsigned i; + /* must protect curr status */ + pipe_mutex_lock(rb_pipe->call_mutex); + rb_pipe->curr.num_vs_views = 0; memset(rb_pipe->curr.vs_views, 0, sizeof(rb_pipe->curr.vs_views)); memset(rb_pipe->curr.vs_texs, 0, sizeof(rb_pipe->curr.vs_texs)); @@ -655,6 +777,8 @@ rbug_set_vertex_sampler_views(struct pipe_context *_pipe, } pipe->set_vertex_sampler_views(pipe, num, views); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -668,6 +792,8 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe, struct pipe_vertex_buffer *buffers = NULL; unsigned i; + pipe_mutex_lock(rb_pipe->call_mutex); + if (num_buffers) { memcpy(unwrapped_buffers, _buffers, num_buffers * sizeof(*_buffers)); for (i = 0; i < num_buffers; i++) @@ -678,6 +804,8 @@ rbug_set_vertex_buffers(struct pipe_context *_pipe, pipe->set_vertex_buffers(pipe, num_buffers, buffers); + + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -694,7 +822,9 @@ rbug_set_index_buffer(struct pipe_context *_pipe, ib = &unwrapped_ib; } + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_index_buffer(pipe, ib); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -704,7 +834,9 @@ rbug_set_sample_mask(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->set_sample_mask(pipe, sample_mask); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -725,6 +857,7 @@ rbug_resource_copy_region(struct pipe_context *_pipe, struct pipe_resource *dst = rb_resource_dst->resource; struct pipe_resource *src = rb_resource_src->resource; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->resource_copy_region(pipe, dst, dst_level, @@ -734,6 +867,7 @@ rbug_resource_copy_region(struct pipe_context *_pipe, src, src_level, src_box); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -746,11 +880,13 @@ rbug_clear(struct pipe_context *_pipe, struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->clear(pipe, buffers, rgba, depth, stencil); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -765,6 +901,7 @@ rbug_clear_render_target(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; struct pipe_surface *dst = rb_surface_dst->surface; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->clear_render_target(pipe, dst, rgba, @@ -772,6 +909,7 @@ rbug_clear_render_target(struct pipe_context *_pipe, dsty, width, height); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void @@ -788,6 +926,7 @@ rbug_clear_depth_stencil(struct pipe_context *_pipe, struct pipe_context *pipe = rb_pipe->pipe; struct pipe_surface *dst = rb_surface_dst->surface; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->clear_depth_stencil(pipe, dst, clear_flags, @@ -797,36 +936,20 @@ rbug_clear_depth_stencil(struct pipe_context *_pipe, dsty, width, height); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void rbug_flush(struct pipe_context *_pipe, - unsigned flags, struct pipe_fence_handle **fence) { struct rbug_context *rb_pipe = rbug_context(_pipe); struct pipe_context *pipe = rb_pipe->pipe; + pipe_mutex_lock(rb_pipe->call_mutex); pipe->flush(pipe, - flags, fence); -} - -static unsigned int -rbug_is_resource_referenced(struct pipe_context *_pipe, - struct pipe_resource *_resource, - unsigned level, - int layer) -{ - struct rbug_context *rb_pipe = rbug_context(_pipe); - struct rbug_resource *rb_resource = rbug_resource(_resource); - struct pipe_context *pipe = rb_pipe->pipe; - struct pipe_resource *resource = rb_resource->resource; - - return pipe->is_resource_referenced(pipe, - resource, - level, - layer); + pipe_mutex_unlock(rb_pipe->call_mutex); } static struct pipe_sampler_view * @@ -840,9 +963,11 @@ rbug_context_create_sampler_view(struct pipe_context *_pipe, struct pipe_resource *resource = rb_resource->resource; struct pipe_sampler_view *result; + pipe_mutex_lock(rb_pipe->call_mutex); result = pipe->create_sampler_view(pipe, resource, templ); + pipe_mutex_unlock(rb_pipe->call_mutex); if (result) return rbug_sampler_view_create(rb_pipe, rb_resource, result); @@ -868,9 +993,11 @@ rbug_context_create_surface(struct pipe_context *_pipe, struct pipe_resource *resource = rb_resource->resource; struct pipe_surface *result; + pipe_mutex_lock(rb_pipe->call_mutex); result = pipe->create_surface(pipe, resource, surf_tmpl); + pipe_mutex_unlock(rb_pipe->call_mutex); if (result) return rbug_surface_create(rb_pipe, rb_resource, result); @@ -881,8 +1008,13 @@ static void rbug_context_surface_destroy(struct pipe_context *_pipe, struct pipe_surface *_surface) { - rbug_surface_destroy(rbug_context(_pipe), - rbug_surface(_surface)); + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_surface *rb_surface = rbug_surface(_surface); + + pipe_mutex_lock(rb_pipe->call_mutex); + rbug_surface_destroy(rb_pipe, + rb_surface); + pipe_mutex_unlock(rb_pipe->call_mutex); } @@ -900,11 +1032,13 @@ rbug_context_get_transfer(struct pipe_context *_context, struct pipe_resource *resource = rb_resource->resource; struct pipe_transfer *result; + pipe_mutex_lock(rb_pipe->call_mutex); result = context->get_transfer(context, resource, level, usage, box); + pipe_mutex_unlock(rb_pipe->call_mutex); if (result) return rbug_transfer_create(rb_pipe, rb_resource, result); @@ -915,8 +1049,13 @@ static void rbug_context_transfer_destroy(struct pipe_context *_pipe, struct pipe_transfer *_transfer) { - rbug_transfer_destroy(rbug_context(_pipe), - rbug_transfer(_transfer)); + struct rbug_context *rb_pipe = rbug_context(_pipe); + struct rbug_transfer *rb_transfer =rbug_transfer(_transfer); + + pipe_mutex_lock(rb_pipe->call_mutex); + rbug_transfer_destroy(rb_pipe, + rb_transfer); + pipe_mutex_unlock(rb_pipe->call_mutex); } static void * @@ -927,9 +1066,14 @@ rbug_context_transfer_map(struct pipe_context *_context, struct rbug_transfer *rb_transfer = rbug_transfer(_transfer); struct pipe_context *context = rb_pipe->pipe; struct pipe_transfer *transfer = rb_transfer->transfer; + void *ret; - return context->transfer_map(context, + pipe_mutex_lock(rb_pipe->call_mutex); + ret = context->transfer_map(context, transfer); + pipe_mutex_unlock(rb_pipe->call_mutex); + + return ret; } @@ -944,9 +1088,11 @@ rbug_context_transfer_flush_region(struct pipe_context *_context, struct pipe_context *context = rb_pipe->pipe; struct pipe_transfer *transfer = rb_transfer->transfer; + pipe_mutex_lock(rb_pipe->call_mutex); context->transfer_flush_region(context, transfer, box); + pipe_mutex_unlock(rb_pipe->call_mutex); } @@ -959,8 +1105,10 @@ rbug_context_transfer_unmap(struct pipe_context *_context, struct pipe_context *context = rb_pipe->pipe; struct pipe_transfer *transfer = rb_transfer->transfer; + pipe_mutex_lock(rb_pipe->call_mutex); context->transfer_unmap(context, transfer); + pipe_mutex_unlock(rb_pipe->call_mutex); } @@ -979,6 +1127,7 @@ rbug_context_transfer_inline_write(struct pipe_context *_context, struct pipe_context *context = rb_pipe->pipe; struct pipe_resource *resource = rb_resource->resource; + pipe_mutex_lock(rb_pipe->call_mutex); context->transfer_inline_write(context, resource, level, @@ -987,6 +1136,7 @@ rbug_context_transfer_inline_write(struct pipe_context *_context, data, stride, layer_stride); + pipe_mutex_unlock(rb_pipe->call_mutex); } @@ -999,7 +1149,9 @@ static void rbug_redefine_user_buffer(struct pipe_context *_context, struct pipe_context *context = rb_pipe->pipe; struct pipe_resource *resource = rb_resource->resource; + pipe_mutex_lock(rb_pipe->call_mutex); context->redefine_user_buffer(context, resource, offset, size); + pipe_mutex_unlock(rb_pipe->call_mutex); } @@ -1077,7 +1229,6 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) rb_pipe->base.clear_render_target = rbug_clear_render_target; rb_pipe->base.clear_depth_stencil = rbug_clear_depth_stencil; rb_pipe->base.flush = rbug_flush; - rb_pipe->base.is_resource_referenced = rbug_is_resource_referenced; rb_pipe->base.create_sampler_view = rbug_context_create_sampler_view; rb_pipe->base.sampler_view_destroy = rbug_context_sampler_view_destroy; rb_pipe->base.create_surface = rbug_context_create_surface; diff --git a/src/gallium/drivers/rbug/rbug_core.c b/src/gallium/drivers/rbug/rbug_core.c index eb772d19d05..b80bcd4228f 100644 --- a/src/gallium/drivers/rbug/rbug_core.c +++ b/src/gallium/drivers/rbug/rbug_core.c @@ -498,7 +498,7 @@ rbug_context_flush(struct rbug_rbug *tr_rbug, struct rbug_header *header, uint32 /* protect the pipe context */ pipe_mutex_lock(rb_context->call_mutex); - rb_context->pipe->flush(rb_context->pipe, flush->flags, NULL); + rb_context->pipe->flush(rb_context->pipe, NULL); pipe_mutex_unlock(rb_context->call_mutex); pipe_mutex_unlock(rb_screen->list_mutex); diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c index d635ce575c0..7c8dfdcc12a 100644 --- a/src/gallium/drivers/rbug/rbug_screen.c +++ b/src/gallium/drivers/rbug/rbug_screen.c @@ -106,8 +106,7 @@ rbug_screen_is_format_supported(struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) + unsigned tex_usage) { struct rbug_screen *rb_screen = rbug_screen(_screen); struct pipe_screen *screen = rb_screen->screen; @@ -116,8 +115,7 @@ rbug_screen_is_format_supported(struct pipe_screen *_screen, format, target, sample_count, - tex_usage, - geom_flags); + tex_usage); } static struct pipe_context * @@ -240,30 +238,28 @@ rbug_screen_fence_reference(struct pipe_screen *_screen, fence); } -static int +static boolean rbug_screen_fence_signalled(struct pipe_screen *_screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { struct rbug_screen *rb_screen = rbug_screen(_screen); struct pipe_screen *screen = rb_screen->screen; return screen->fence_signalled(screen, - fence, - flags); + fence); } -static int +static boolean rbug_screen_fence_finish(struct pipe_screen *_screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { struct rbug_screen *rb_screen = rbug_screen(_screen); struct pipe_screen *screen = rb_screen->screen; return screen->fence_finish(screen, fence, - flags); + timeout); } boolean diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 70fdfb7ddf3..ce22f646228 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -148,13 +148,13 @@ softpipe_destroy( struct pipe_context *pipe ) /** * if (the texture is being used as a framebuffer surface) - * return PIPE_REFERENCED_FOR_WRITE + * return SP_REFERENCED_FOR_WRITE * else if (the texture is a bound texture source) - * return PIPE_REFERENCED_FOR_READ + * return SP_REFERENCED_FOR_READ * else - * return PIPE_UNREFERENCED + * return SP_UNREFERENCED */ -static unsigned int +unsigned int softpipe_is_resource_referenced( struct pipe_context *pipe, struct pipe_resource *texture, unsigned level, int layer) @@ -163,19 +163,19 @@ softpipe_is_resource_referenced( struct pipe_context *pipe, unsigned i; if (texture->target == PIPE_BUFFER) - return PIPE_UNREFERENCED; + return SP_UNREFERENCED; /* check if any of the bound drawing surfaces are this texture */ if (softpipe->dirty_render_cache) { for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) { if (softpipe->framebuffer.cbufs[i] && softpipe->framebuffer.cbufs[i]->texture == texture) { - return PIPE_REFERENCED_FOR_WRITE; + return SP_REFERENCED_FOR_WRITE; } } if (softpipe->framebuffer.zsbuf && softpipe->framebuffer.zsbuf->texture == texture) { - return PIPE_REFERENCED_FOR_WRITE; + return SP_REFERENCED_FOR_WRITE; } } @@ -183,20 +183,20 @@ softpipe_is_resource_referenced( struct pipe_context *pipe, for (i = 0; i < PIPE_MAX_SAMPLERS; i++) { if (softpipe->fragment_tex_cache[i] && softpipe->fragment_tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; + return SP_REFERENCED_FOR_READ; } for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) { if (softpipe->vertex_tex_cache[i] && softpipe->vertex_tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; + return SP_REFERENCED_FOR_READ; } for (i = 0; i < PIPE_MAX_GEOMETRY_SAMPLERS; i++) { if (softpipe->geometry_tex_cache[i] && softpipe->geometry_tex_cache[i]->texture == texture) - return PIPE_REFERENCED_FOR_READ; + return SP_REFERENCED_FOR_READ; } - return PIPE_UNREFERENCED; + return SP_UNREFERENCED; } @@ -255,9 +255,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.draw_stream_output = softpipe_draw_stream_output; softpipe->pipe.clear = softpipe_clear; - softpipe->pipe.flush = softpipe_flush; - - softpipe->pipe.is_resource_referenced = softpipe_is_resource_referenced; + softpipe->pipe.flush = softpipe_flush_wrapped; softpipe->pipe.render_condition = softpipe_render_condition; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index c91709aef06..a572ee8cf00 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -198,4 +198,13 @@ struct pipe_context * softpipe_create_context( struct pipe_screen *, void *priv ); +#define SP_UNREFERENCED 0 +#define SP_REFERENCED_FOR_READ (1 << 0) +#define SP_REFERENCED_FOR_WRITE (1 << 1) + +unsigned int +softpipe_is_resource_referenced( struct pipe_context *pipe, + struct pipe_resource *texture, + unsigned level, int layer); + #endif /* SP_CONTEXT_H */ diff --git a/src/gallium/drivers/softpipe/sp_fence.c b/src/gallium/drivers/softpipe/sp_fence.c index 66c52141132..7b79a0df4ea 100644 --- a/src/gallium/drivers/softpipe/sp_fence.c +++ b/src/gallium/drivers/softpipe/sp_fence.c @@ -41,23 +41,22 @@ softpipe_fence_reference(struct pipe_screen *screen, } -static int +static boolean softpipe_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { assert(!fence); - return 0; + return TRUE; } -static int +static boolean softpipe_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { assert(!fence); - return 0; + return TRUE; } diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c index 6f7addd441a..720fea83cb2 100644 --- a/src/gallium/drivers/softpipe/sp_flush.c +++ b/src/gallium/drivers/softpipe/sp_flush.c @@ -42,7 +42,7 @@ void softpipe_flush( struct pipe_context *pipe, - unsigned flags, + unsigned flags, struct pipe_fence_handle **fence ) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -50,7 +50,7 @@ softpipe_flush( struct pipe_context *pipe, draw_flush(softpipe->draw); - if (flags & PIPE_FLUSH_TEXTURE_CACHE) { + if (flags & SP_FLUSH_TEXTURE_CACHE) { for (i = 0; i < softpipe->num_fragment_sampler_views; i++) { sp_flush_tex_tile_cache(softpipe->fragment_tex_cache[i]); } @@ -62,34 +62,27 @@ softpipe_flush( struct pipe_context *pipe, } } - if (flags & PIPE_FLUSH_SWAPBUFFERS) { - /* If this is a swapbuffers, just flush color buffers. - * - * The zbuffer changes are not discarded, but held in the cache - * in the hope that a later clear will wipe them out. - */ - for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) - if (softpipe->cbuf_cache[i]) - sp_flush_tile_cache(softpipe->cbuf_cache[i]); - - /* Need this call for hardware buffers before swapbuffers. - * - * there should probably be another/different flush-type function - * that's called before swapbuffers because we don't always want - * to unmap surfaces when flushing. - */ - softpipe_unmap_transfers(softpipe); - } - else if (flags & PIPE_FLUSH_RENDER_CACHE) { - for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) - if (softpipe->cbuf_cache[i]) - sp_flush_tile_cache(softpipe->cbuf_cache[i]); - - if (softpipe->zsbuf_cache) - sp_flush_tile_cache(softpipe->zsbuf_cache); - - softpipe->dirty_render_cache = FALSE; - } + /* If this is a swapbuffers, just flush color buffers. + * + * The zbuffer changes are not discarded, but held in the cache + * in the hope that a later clear will wipe them out. + */ + for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) + if (softpipe->cbuf_cache[i]) + sp_flush_tile_cache(softpipe->cbuf_cache[i]); + + if (softpipe->zsbuf_cache) + sp_flush_tile_cache(softpipe->zsbuf_cache); + + softpipe->dirty_render_cache = FALSE; + + /* Need this call for hardware buffers before swapbuffers. + * + * there should probably be another/different flush-type function + * that's called before swapbuffers because we don't always want + * to unmap surfaces when flushing. + */ + softpipe_unmap_transfers(softpipe); /* Enable to dump BMPs of the color/depth buffers each frame */ #if 0 @@ -108,6 +101,13 @@ softpipe_flush( struct pipe_context *pipe, *fence = NULL; } +void +softpipe_flush_wrapped( struct pipe_context *pipe, + struct pipe_fence_handle **fence ) +{ + softpipe_flush(pipe, SP_FLUSH_TEXTURE_CACHE, fence); +} + /** * Flush context if necessary. @@ -129,21 +129,18 @@ softpipe_flush_resource(struct pipe_context *pipe, { unsigned referenced; - referenced = pipe->is_resource_referenced(pipe, texture, level, layer); + referenced = softpipe_is_resource_referenced(pipe, texture, level, layer); - if ((referenced & PIPE_REFERENCED_FOR_WRITE) || - ((referenced & PIPE_REFERENCED_FOR_READ) && !read_only)) { + if ((referenced & SP_REFERENCED_FOR_WRITE) || + ((referenced & SP_REFERENCED_FOR_READ) && !read_only)) { /* * TODO: The semantics of these flush flags are too obtuse. They should * disappear and the pipe driver should just ensure that all visible * side-effects happen when they need to happen. */ - if (referenced & PIPE_REFERENCED_FOR_WRITE) - flush_flags |= PIPE_FLUSH_RENDER_CACHE; - - if (referenced & PIPE_REFERENCED_FOR_READ) - flush_flags |= PIPE_FLUSH_TEXTURE_CACHE; + if (referenced & SP_REFERENCED_FOR_READ) + flush_flags |= SP_FLUSH_TEXTURE_CACHE; if (cpu_access) { /* @@ -155,14 +152,15 @@ softpipe_flush_resource(struct pipe_context *pipe, if (do_not_block) return FALSE; - pipe->flush(pipe, flush_flags, &fence); + softpipe_flush(pipe, flush_flags, &fence); if (fence) { /* * This is for illustrative purposes only, as softpipe does not * have fences. */ - pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_finish(pipe->screen, fence, + PIPE_TIMEOUT_INFINITE); pipe->screen->fence_reference(pipe->screen, &fence, NULL); } } else { @@ -170,7 +168,7 @@ softpipe_flush_resource(struct pipe_context *pipe, * Just flush. */ - pipe->flush(pipe, flush_flags, NULL); + softpipe_flush(pipe, flush_flags, NULL); } } diff --git a/src/gallium/drivers/softpipe/sp_flush.h b/src/gallium/drivers/softpipe/sp_flush.h index 22a5ceeb9ec..ab01c249abe 100644 --- a/src/gallium/drivers/softpipe/sp_flush.h +++ b/src/gallium/drivers/softpipe/sp_flush.h @@ -33,10 +33,17 @@ struct pipe_context; struct pipe_fence_handle; +#define SP_FLUSH_TEXTURE_CACHE 0x2 + void -softpipe_flush(struct pipe_context *pipe, unsigned flags, +softpipe_flush(struct pipe_context *pipe, + unsigned flags, struct pipe_fence_handle **fence); +void +softpipe_flush_wrapped( struct pipe_context *pipe, + struct pipe_fence_handle **fence ); + boolean softpipe_flush_resource(struct pipe_context *pipe, struct pipe_resource *texture, diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c index 401e3177b48..26f5e1b5740 100644 --- a/src/gallium/drivers/softpipe/sp_screen.c +++ b/src/gallium/drivers/softpipe/sp_screen.c @@ -125,7 +125,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: + case PIPE_CAP_TGSI_INSTANCEID: + case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return 1; case PIPE_CAP_ARRAY_TEXTURES: return 1; @@ -181,8 +182,7 @@ softpipe_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bind, - unsigned geom_flags ) + unsigned bind) { struct sw_winsys *winsys = softpipe_screen(screen)->winsys; const struct util_format_description *format_desc; diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 8a4ef934348..c09ce19559c 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1795,6 +1795,7 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, const struct pipe_sampler_state *sampler = samp->sampler; int j, k0, k1, k2, k3; float val; + float pc0, pc1, pc2, pc3; samp->mip_filter(tgsi_sampler, s, t, p, c0, control, rgba); @@ -1804,43 +1805,48 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, * RGBA channels. We look at the red channel here. */ + pc0 = CLAMP(p[0], 0.0F, 1.0F); + pc1 = CLAMP(p[1], 0.0F, 1.0F); + pc2 = CLAMP(p[2], 0.0F, 1.0F); + pc3 = CLAMP(p[3], 0.0F, 1.0F); + /* compare four texcoords vs. four texture samples */ switch (sampler->compare_func) { case PIPE_FUNC_LESS: - k0 = p[0] < rgba[0][0]; - k1 = p[1] < rgba[0][1]; - k2 = p[2] < rgba[0][2]; - k3 = p[3] < rgba[0][3]; + k0 = pc0 < rgba[0][0]; + k1 = pc1 < rgba[0][1]; + k2 = pc2 < rgba[0][2]; + k3 = pc3 < rgba[0][3]; break; case PIPE_FUNC_LEQUAL: - k0 = p[0] <= rgba[0][0]; - k1 = p[1] <= rgba[0][1]; - k2 = p[2] <= rgba[0][2]; - k3 = p[3] <= rgba[0][3]; + k0 = pc0 <= rgba[0][0]; + k1 = pc1 <= rgba[0][1]; + k2 = pc2 <= rgba[0][2]; + k3 = pc3 <= rgba[0][3]; break; case PIPE_FUNC_GREATER: - k0 = p[0] > rgba[0][0]; - k1 = p[1] > rgba[0][1]; - k2 = p[2] > rgba[0][2]; - k3 = p[3] > rgba[0][3]; + k0 = pc0 > rgba[0][0]; + k1 = pc1 > rgba[0][1]; + k2 = pc2 > rgba[0][2]; + k3 = pc3 > rgba[0][3]; break; case PIPE_FUNC_GEQUAL: - k0 = p[0] >= rgba[0][0]; - k1 = p[1] >= rgba[0][1]; - k2 = p[2] >= rgba[0][2]; - k3 = p[3] >= rgba[0][3]; + k0 = pc0 >= rgba[0][0]; + k1 = pc1 >= rgba[0][1]; + k2 = pc2 >= rgba[0][2]; + k3 = pc3 >= rgba[0][3]; break; case PIPE_FUNC_EQUAL: - k0 = p[0] == rgba[0][0]; - k1 = p[1] == rgba[0][1]; - k2 = p[2] == rgba[0][2]; - k3 = p[3] == rgba[0][3]; + k0 = pc0 == rgba[0][0]; + k1 = pc1 == rgba[0][1]; + k2 = pc2 == rgba[0][2]; + k3 = pc3 == rgba[0][3]; break; case PIPE_FUNC_NOTEQUAL: - k0 = p[0] != rgba[0][0]; - k1 = p[1] != rgba[0][1]; - k2 = p[2] != rgba[0][2]; - k3 = p[3] != rgba[0][3]; + k0 = pc0 != rgba[0][0]; + k1 = pc1 != rgba[0][1]; + k2 = pc2 != rgba[0][2]; + k3 = pc3 != rgba[0][3]; break; case PIPE_FUNC_ALWAYS: k0 = k1 = k2 = k3 = 1; diff --git a/src/gallium/drivers/svga/svga_cmd.c b/src/gallium/drivers/svga/svga_cmd.c index 05eab8a517d..1ed1d5d25bb 100644 --- a/src/gallium/drivers/svga/svga_cmd.c +++ b/src/gallium/drivers/svga/svga_cmd.c @@ -422,7 +422,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, struct svga_transfer *st, // IN SVGA3dTransferType transfer, // IN const SVGA3dCopyBox *boxes, // IN - uint32 numBoxes) // IN + uint32 numBoxes, // IN + SVGA3dSurfaceDMAFlags flags) // IN { struct svga_texture *texture = svga_texture(st->base.resource); SVGA3dCmdSurfaceDMA *cmd; @@ -465,7 +466,7 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, pSuffix = (SVGA3dCmdSurfaceDMASuffix *)((uint8_t*)cmd + sizeof *cmd + boxesSize); pSuffix->suffixSize = sizeof *pSuffix; pSuffix->maximumOffset = st->hw_nblocksy*st->base.stride; - memset(&pSuffix->flags, 0, sizeof pSuffix->flags); + pSuffix->flags = flags; swc->commit(swc); diff --git a/src/gallium/drivers/svga/svga_cmd.h b/src/gallium/drivers/svga/svga_cmd.h index 0e568d78e65..223ab17df81 100644 --- a/src/gallium/drivers/svga/svga_cmd.h +++ b/src/gallium/drivers/svga/svga_cmd.h @@ -102,7 +102,8 @@ SVGA3D_SurfaceDMA(struct svga_winsys_context *swc, struct svga_transfer *st, SVGA3dTransferType transfer, const SVGA3dCopyBox *boxes, - uint32 numBoxes); + uint32 numBoxes, + SVGA3dSurfaceDMAFlags flags); enum pipe_error SVGA3D_BufferDMA(struct svga_winsys_context *swc, diff --git a/src/gallium/drivers/svga/svga_context.c b/src/gallium/drivers/svga/svga_context.c index f0f875b2b23..4782b4bf70e 100644 --- a/src/gallium/drivers/svga/svga_context.c +++ b/src/gallium/drivers/svga/svga_context.c @@ -241,7 +241,8 @@ void svga_context_flush( struct svga_context *svga, if (SVGA_DEBUG & DEBUG_SYNC) { if (fence) - svga->pipe.screen->fence_finish( svga->pipe.screen, fence, 0); + svga->pipe.screen->fence_finish( svga->pipe.screen, fence, + PIPE_TIMEOUT_INFINITE); } if(pfence) diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index d98b9b0e000..2093bcae101 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -73,12 +73,6 @@ retry_draw_range_elements( struct svga_context *svga, if (ret) goto retry; - if (svga->curr.any_user_vertex_buffers) { - ret = svga_hwtnl_flush( svga->hwtnl ); - if (ret) - goto retry; - } - return PIPE_OK; retry: @@ -122,12 +116,6 @@ retry_draw_arrays( struct svga_context *svga, if (ret) goto retry; - if (svga->curr.any_user_vertex_buffers) { - ret = svga_hwtnl_flush( svga->hwtnl ); - if (ret) - goto retry; - } - return 0; retry: @@ -161,7 +149,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) /* We're switching between SW and HW drawing. Do a flush to avoid * mixing HW and SW rendering with the same vertex buffer. */ - pipe->flush(pipe, ~0, NULL); + pipe->flush(pipe, NULL); svga->prev_draw_swtnl = svga->state.sw.need_swtnl; } diff --git a/src/gallium/drivers/svga/svga_pipe_flush.c b/src/gallium/drivers/svga/svga_pipe_flush.c index 9357d827f28..4578c136cb8 100644 --- a/src/gallium/drivers/svga/svga_pipe_flush.c +++ b/src/gallium/drivers/svga/svga_pipe_flush.c @@ -32,7 +32,6 @@ static void svga_flush( struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence ) { struct svga_context *svga = svga_context(pipe); @@ -45,29 +44,27 @@ static void svga_flush( struct pipe_context *pipe, */ svga_context_flush(svga, fence); - SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s flags %x fence_ptr %p\n", - __FUNCTION__, flags, fence ? *fence : 0x0); + SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", + __FUNCTION__, fence ? *fence : 0x0); /* Enable to dump BMPs of the color/depth buffers each frame */ if (0) { - if (flags & PIPE_FLUSH_FRAME) { - struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; - static unsigned frame_no = 1; - char filename[256]; - unsigned i; + struct pipe_framebuffer_state *fb = &svga->curr.framebuffer; + static unsigned frame_no = 1; + char filename[256]; + unsigned i; - for (i = 0; i < fb->nr_cbufs; i++) { - util_snprintf(filename, sizeof(filename), "cbuf%u_%04u", i, frame_no); - debug_dump_surface_bmp(&svga->pipe, filename, fb->cbufs[i]); - } - - if (0 && fb->zsbuf) { - util_snprintf(filename, sizeof(filename), "zsbuf_%04u", frame_no); - debug_dump_surface_bmp(&svga->pipe, filename, fb->zsbuf); - } + for (i = 0; i < fb->nr_cbufs; i++) { + util_snprintf(filename, sizeof(filename), "cbuf%u_%04u", i, frame_no); + debug_dump_surface_bmp(&svga->pipe, filename, fb->cbufs[i]); + } - ++frame_no; + if (0 && fb->zsbuf) { + util_snprintf(filename, sizeof(filename), "zsbuf_%04u", frame_no); + debug_dump_surface_bmp(&svga->pipe, filename, fb->zsbuf); } + + ++frame_no; } } diff --git a/src/gallium/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c index bed15ec02e5..6e0622a312b 100644 --- a/src/gallium/drivers/svga/svga_resource.c +++ b/src/gallium/drivers/svga/svga_resource.c @@ -33,7 +33,6 @@ svga_resource_from_handle(struct pipe_screen * screen, void svga_init_resource_functions(struct svga_context *svga) { - svga->pipe.is_resource_referenced = u_is_resource_referenced_vtbl; svga->pipe.get_transfer = u_get_transfer_vtbl; svga->pipe.transfer_map = u_transfer_map_vtbl; svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl; diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c index e1f07d655b9..34ab9e143e6 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.c +++ b/src/gallium/drivers/svga/svga_resource_buffer.c @@ -51,53 +51,114 @@ svga_buffer_needs_hw_storage(unsigned usage) } -static unsigned int -svga_buffer_is_referenced( struct pipe_context *pipe, - struct pipe_resource *buf, - unsigned level, int layer) +/** + * Create a buffer transfer. + * + * Unlike texture DMAs (which are written immediately to the command buffer and + * therefore inherently serialized with other context operations), for buffers + * we try to coalesce multiple range mappings (i.e, multiple calls to this + * function) into a single DMA command, for better efficiency in command + * processing. This means we need to exercise extra care here to ensure that + * the end result is exactly the same as if one DMA was used for every mapped + * range. + */ +static struct pipe_transfer * +svga_buffer_get_transfer(struct pipe_context *pipe, + struct pipe_resource *resource, + unsigned level, + unsigned usage, + const struct pipe_box *box) { + struct svga_context *svga = svga_context(pipe); struct svga_screen *ss = svga_screen(pipe->screen); - struct svga_buffer *sbuf = svga_buffer(buf); + struct svga_buffer *sbuf = svga_buffer(resource); + struct pipe_transfer *transfer; - /** - * XXX: Check this. - * The screen may cache buffer writes, but when we map, we map out - * of those cached writes, so we don't need to set a - * PIPE_REFERENCED_FOR_WRITE flag for cached buffers. - */ + transfer = CALLOC_STRUCT(pipe_transfer); + if (transfer == NULL) { + return NULL; + } - if (!sbuf->handle || ss->sws->surface_is_flushed(ss->sws, sbuf->handle)) - return PIPE_UNREFERENCED; + transfer->resource = resource; + transfer->level = level; + transfer->usage = usage; + transfer->box = *box; - /** - * sws->surface_is_flushed() does not distinguish between read references - * and write references. So assume a reference is both, - * however, we make an exception for index- and vertex buffers, to avoid - * a flush in st_bufferobj_get_subdata, during display list replay. - */ + if (usage & PIPE_TRANSFER_WRITE) { + if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { + /* + * Finish writing any pending DMA commands, and tell the host to discard + * the buffer contents on the next DMA operation. + */ - if (sbuf->b.b.bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) - return PIPE_REFERENCED_FOR_READ; + if (sbuf->dma.pending) { + svga_buffer_upload_flush(svga, sbuf); - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} + /* + * Instead of flushing the context command buffer, simply discard + * the current hwbuf, and start a new one. + */ + svga_buffer_destroy_hw_storage(ss, sbuf); + } + sbuf->map.num_ranges = 0; + sbuf->dma.flags.discard = TRUE; + } + if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) { + if (!sbuf->map.num_ranges) { + /* + * No pending ranges to upload so far, so we can tell the host to + * not synchronize on the next DMA command. + */ + sbuf->dma.flags.unsynchronized = TRUE; + } + } else { + /* + * Synchronizing, so finish writing any pending DMA command, and + * ensure the next DMA will be done in order. + */ + if (sbuf->dma.pending) { + svga_buffer_upload_flush(svga, sbuf); + + if (sbuf->hwbuf) { + /* + * We have a pending DMA upload from a hardware buffer, therefore + * we need to ensure that the host finishes processing that DMA + * command before the state tracker can start overwriting the + * hardware buffer. + * + * XXX: This could be avoided by tying the hardware buffer to + * the transfer (just as done with textures), which would allow + * overlapping DMAs commands to be queued on the same context + * buffer. However, due to the likelihood of software vertex + * processing, it is more convenient to hold on to the hardware + * buffer, allowing to quickly access the contents from the CPU + * without having to do a DMA download from the host. + */ + + if (usage & PIPE_TRANSFER_DONTBLOCK) { + /* + * Flushing the command buffer here will most likely cause + * the map of the hwbuf below to block, so preemptively + * return NULL here if DONTBLOCK is set to prevent unnecessary + * command buffer flushes. + */ + + FREE(transfer); + return NULL; + } + + svga_context_flush(svga, NULL); + } + } -static void * -svga_buffer_map_range( struct pipe_screen *screen, - struct pipe_resource *buf, - unsigned offset, - unsigned length, - unsigned usage ) -{ - struct svga_screen *ss = svga_screen(screen); - struct svga_winsys_screen *sws = ss->sws; - struct svga_buffer *sbuf = svga_buffer( buf ); - void *map; + sbuf->dma.flags.unsynchronized = FALSE; + } + } if (!sbuf->swbuf && !sbuf->hwbuf) { if (svga_buffer_create_hw_storage(ss, sbuf) != PIPE_OK) { @@ -113,86 +174,120 @@ svga_buffer_map_range( struct pipe_screen *screen, } sbuf->swbuf = align_malloc(sbuf->b.b.width0, 16); + if (!sbuf->swbuf) { + FREE(transfer); + return NULL; + } } } + return transfer; +} + + +/** + * Map a range of a buffer. + */ +static void * +svga_buffer_transfer_map( struct pipe_context *pipe, + struct pipe_transfer *transfer ) +{ + struct svga_buffer *sbuf = svga_buffer(transfer->resource); + + uint8_t *map; + if (sbuf->swbuf) { /* User/malloc buffer */ map = sbuf->swbuf; } else if (sbuf->hwbuf) { - map = sws->buffer_map(sws, sbuf->hwbuf, usage); + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_winsys_screen *sws = ss->sws; + + map = sws->buffer_map(sws, sbuf->hwbuf, transfer->usage); } else { map = NULL; } - if(map) { + if (map) { ++sbuf->map.count; - - if (usage & PIPE_TRANSFER_WRITE) { - assert(sbuf->map.count <= 1); - sbuf->map.writing = TRUE; - if (usage & PIPE_TRANSFER_FLUSH_EXPLICIT) - sbuf->map.flush_explicit = TRUE; - } + map += transfer->box.x; } return map; } - -static void -svga_buffer_flush_mapped_range( struct pipe_screen *screen, - struct pipe_resource *buf, - unsigned offset, unsigned length) +static void +svga_buffer_transfer_flush_region( struct pipe_context *pipe, + struct pipe_transfer *transfer, + const struct pipe_box *box) { - struct svga_buffer *sbuf = svga_buffer( buf ); - struct svga_screen *ss = svga_screen(screen); - + struct svga_screen *ss = svga_screen(pipe->screen); + struct svga_buffer *sbuf = svga_buffer(transfer->resource); + + unsigned offset = transfer->box.x + box->x; + unsigned length = box->width; + + assert(transfer->usage & PIPE_TRANSFER_WRITE); + assert(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT); + pipe_mutex_lock(ss->swc_mutex); - assert(sbuf->map.writing); - if(sbuf->map.writing) { - assert(sbuf->map.flush_explicit); - svga_buffer_add_range(sbuf, offset, offset + length); - } + svga_buffer_add_range(sbuf, offset, offset + length); pipe_mutex_unlock(ss->swc_mutex); } -static void -svga_buffer_unmap( struct pipe_screen *screen, - struct pipe_resource *buf) + +static void +svga_buffer_transfer_unmap( struct pipe_context *pipe, + struct pipe_transfer *transfer ) { - struct svga_screen *ss = svga_screen(screen); + struct svga_screen *ss = svga_screen(pipe->screen); struct svga_winsys_screen *sws = ss->sws; - struct svga_buffer *sbuf = svga_buffer( buf ); + struct svga_buffer *sbuf = svga_buffer(transfer->resource); pipe_mutex_lock(ss->swc_mutex); assert(sbuf->map.count); - if(sbuf->map.count) + if (sbuf->map.count) { --sbuf->map.count; + } - if(sbuf->hwbuf) + if (sbuf->hwbuf) { sws->buffer_unmap(sws, sbuf->hwbuf); + } + + if (transfer->usage & PIPE_TRANSFER_WRITE) { + if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) { + /* + * Mapped range not flushed explicitly, so flush the whole buffer, + * and tell the host to discard the contents when processing the DMA + * command. + */ - if(sbuf->map.writing) { - if(!sbuf->map.flush_explicit) { - /* No mapped range was flushed -- flush the whole buffer */ SVGA_DBG(DEBUG_DMA, "flushing the whole buffer\n"); + sbuf->dma.flags.discard = TRUE; + svga_buffer_add_range(sbuf, 0, sbuf->b.b.width0); } - - sbuf->map.writing = FALSE; - sbuf->map.flush_explicit = FALSE; } pipe_mutex_unlock(ss->swc_mutex); } +/** + * Destroy transfer + */ +static void +svga_buffer_transfer_destroy(struct pipe_context *pipe, + struct pipe_transfer *transfer) +{ + FREE(transfer); +} + static void svga_buffer_destroy( struct pipe_screen *screen, @@ -221,62 +316,12 @@ svga_buffer_destroy( struct pipe_screen *screen, } -/* Keep the original code more or less intact, implement transfers in - * terms of the old functions. - */ -static void * -svga_buffer_transfer_map( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - uint8_t *map = svga_buffer_map_range( pipe->screen, - transfer->resource, - transfer->box.x, - transfer->box.width, - transfer->usage ); - if (map == NULL) - return NULL; - - /* map_buffer() returned a pointer to the beginning of the buffer, - * but transfers are expected to return a pointer to just the - * region specified in the box. - */ - return map + transfer->box.x; -} - - - -static void svga_buffer_transfer_flush_region( struct pipe_context *pipe, - struct pipe_transfer *transfer, - const struct pipe_box *box) -{ - assert(box->x + box->width <= transfer->box.width); - - svga_buffer_flush_mapped_range(pipe->screen, - transfer->resource, - transfer->box.x + box->x, - box->width); -} - -static void svga_buffer_transfer_unmap( struct pipe_context *pipe, - struct pipe_transfer *transfer ) -{ - svga_buffer_unmap(pipe->screen, - transfer->resource); -} - - - - - - - struct u_resource_vtbl svga_buffer_vtbl = { u_default_resource_get_handle, /* get_handle */ svga_buffer_destroy, /* resource_destroy */ - svga_buffer_is_referenced, /* is_resource_referenced */ - u_default_get_transfer, /* get_transfer */ - u_default_transfer_destroy, /* transfer_destroy */ + svga_buffer_get_transfer, /* get_transfer */ + svga_buffer_transfer_destroy, /* transfer_destroy */ svga_buffer_transfer_map, /* transfer_map */ svga_buffer_transfer_flush_region, /* transfer_flush_region */ svga_buffer_transfer_unmap, /* transfer_unmap */ diff --git a/src/gallium/drivers/svga/svga_resource_buffer.h b/src/gallium/drivers/svga/svga_resource_buffer.h index c559f70ec12..95032213fa5 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer.h +++ b/src/gallium/drivers/svga/svga_resource_buffer.h @@ -90,7 +90,9 @@ struct svga_buffer * Host surface handle. * * This is a platform independent abstraction for host SID. We create when - * trying to bind + * trying to bind. + * + * Only set for non-user buffers. */ struct svga_winsys_surface *handle; @@ -100,24 +102,10 @@ struct svga_buffer struct { /** * Number of concurrent mappings. - * - * XXX: It is impossible to guarantee concurrent maps work in all - * circumstances -- pipe_buffers really need transfer objects too. */ unsigned count; /** - * Whether this buffer is currently mapped for writing. - */ - boolean writing; - - /** - * Whether the application will tell us explicity which ranges it touched - * or not. - */ - boolean flush_explicit; - - /** * Dirty ranges. * * Ranges that were touched by the application and need to be uploaded to @@ -149,6 +137,8 @@ struct svga_buffer * A piece of GMR memory, with the same size of the buffer. It is created * when mapping the buffer, and will be used to upload vertex data to the * host. + * + * Only set for non-user buffers. */ struct svga_winsys_buffer *hwbuf; diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.c b/src/gallium/drivers/svga/svga_resource_buffer_upload.c index b7d54605e66..e5fcec08d6e 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.c +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.c @@ -131,6 +131,8 @@ enum pipe_error svga_buffer_create_host_surface(struct svga_screen *ss, struct svga_buffer *sbuf) { + assert(!sbuf->user); + if(!sbuf->handle) { sbuf->key.flags = 0; @@ -252,7 +254,7 @@ svga_buffer_upload_command(struct svga_context *svga, * Patch up the upload DMA command reserved by svga_buffer_upload_command * with the final ranges. */ -static void +void svga_buffer_upload_flush(struct svga_context *svga, struct svga_buffer *sbuf) { @@ -260,6 +262,10 @@ svga_buffer_upload_flush(struct svga_context *svga, unsigned i; struct pipe_resource *dummy; + if (!sbuf->dma.pending) { + return; + } + assert(sbuf->handle); assert(sbuf->hwbuf); assert(sbuf->map.num_ranges); @@ -296,6 +302,8 @@ svga_buffer_upload_flush(struct svga_context *svga, sbuf->head.next = sbuf->head.prev = NULL; #endif sbuf->dma.pending = FALSE; + sbuf->dma.flags.discard = FALSE; + sbuf->dma.flags.unsynchronized = FALSE; sbuf->dma.svga = NULL; sbuf->dma.boxes = NULL; @@ -306,7 +314,6 @@ svga_buffer_upload_flush(struct svga_context *svga, } - /** * Note a dirty range. * @@ -337,12 +344,6 @@ svga_buffer_add_range(struct svga_buffer *sbuf, /* * Try to grow one of the ranges. - * - * Note that it is not this function task to care about overlapping ranges, - * as the GMR was already given so it is too late to do anything. Situations - * where overlapping ranges may pose a problem should be detected via - * pipe_context::is_resource_referenced and the context that refers to the - * buffer should be flushed. */ for(i = 0; i < sbuf->map.num_ranges; ++i) { @@ -357,6 +358,11 @@ svga_buffer_add_range(struct svga_buffer *sbuf, if (dist <= 0) { /* * Ranges are contiguous or overlapping -- extend this one and return. + * + * Note that it is not this function's task to prevent overlapping + * ranges, as the GMR was already given so it is too late to do + * anything. If the ranges overlap here it must surely be because + * PIPE_TRANSFER_UNSYNCHRONIZED was set. */ sbuf->map.ranges[i].start = MIN2(sbuf->map.ranges[i].start, start); @@ -380,8 +386,7 @@ svga_buffer_add_range(struct svga_buffer *sbuf, * pending DMA upload and start clean. */ - if(sbuf->dma.pending) - svga_buffer_upload_flush(sbuf->dma.svga, sbuf); + svga_buffer_upload_flush(sbuf->dma.svga, sbuf); assert(!sbuf->dma.pending); assert(!sbuf->dma.svga); @@ -662,6 +667,9 @@ svga_redefine_user_buffer(struct pipe_context *pipe, struct svga_buffer *sbuf = svga_buffer(resource); assert(sbuf->user); + assert(!sbuf->dma.pending); + assert(!sbuf->handle); + assert(!sbuf->hwbuf); /* * Release any uploaded user buffer. @@ -674,29 +682,9 @@ svga_redefine_user_buffer(struct pipe_context *pipe, pipe_mutex_lock(ss->swc_mutex); - if (offset + size > resource->width0) { - /* - * User buffers shouldn't have DMA directly, unless - * SVGA_COMBINE_USERBUFFERS is not set. - */ - - if (sbuf->dma.pending) { - svga_buffer_upload_flush(svga, sbuf); - } - - if (sbuf->handle) { - svga_buffer_destroy_host_surface(ss, sbuf); - } - - if (sbuf->hwbuf) { - svga_buffer_destroy_hw_storage(ss, sbuf); - } - - sbuf->key.size.width = sbuf->b.b.width0 = offset + size; - } + sbuf->key.size.width = sbuf->b.b.width0 = offset + size; pipe_mutex_unlock(ss->swc_mutex); - svga->curr.any_user_vertex_buffers = TRUE; svga->dirty |= SVGA_NEW_VBUFFER | SVGA_NEW_VELEMENT; } diff --git a/src/gallium/drivers/svga/svga_resource_buffer_upload.h b/src/gallium/drivers/svga/svga_resource_buffer_upload.h index 11df3065263..13d8f3e299b 100644 --- a/src/gallium/drivers/svga/svga_resource_buffer_upload.h +++ b/src/gallium/drivers/svga/svga_resource_buffer_upload.h @@ -28,6 +28,10 @@ void +svga_buffer_upload_flush(struct svga_context *svga, + struct svga_buffer *sbuf); + +void svga_buffer_add_range(struct svga_buffer *sbuf, unsigned start, unsigned end); diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 994f30719ae..b61f85955a2 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -48,31 +48,6 @@ #define SVGA3D_SURFACE_HINT_SCANOUT (1 << 9) -static unsigned int -svga_texture_is_referenced( struct pipe_context *pipe, - struct pipe_resource *texture, - unsigned level, int layer) -{ - struct svga_texture *tex = svga_texture(texture); - struct svga_screen *ss = svga_screen(pipe->screen); - - /** - * The screen does not cache texture writes. - */ - - if (!tex->handle || ss->sws->surface_is_flushed(ss->sws, tex->handle)) - return PIPE_UNREFERENCED; - - /** - * sws->surface_is_flushed() does not distinguish between read references - * and write references. So assume a reference is both. - */ - - return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE; -} - - - /* * Helper function and arrays */ @@ -156,7 +131,8 @@ static INLINE void svga_transfer_dma_band(struct svga_context *svga, struct svga_transfer *st, SVGA3dTransferType transfer, - unsigned y, unsigned h, unsigned srcy) + unsigned y, unsigned h, unsigned srcy, + SVGA3dSurfaceDMAFlags flags) { struct svga_texture *texture = svga_texture(st->base.resource); SVGA3dCopyBox box; @@ -192,10 +168,10 @@ svga_transfer_dma_band(struct svga_context *svga, util_format_get_blocksize(texture->b.b.format) * 8 / (util_format_get_blockwidth(texture->b.b.format)*util_format_get_blockheight(texture->b.b.format))); - ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1); + ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags); if(ret != PIPE_OK) { svga_context_flush(svga, NULL); - ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1); + ret = SVGA3D_SurfaceDMA(svga->swc, st, transfer, &box, 1, flags); assert(ret == PIPE_OK); } } @@ -204,7 +180,8 @@ svga_transfer_dma_band(struct svga_context *svga, static INLINE void svga_transfer_dma(struct svga_context *svga, struct svga_transfer *st, - SVGA3dTransferType transfer) + SVGA3dTransferType transfer, + SVGA3dSurfaceDMAFlags flags) { struct svga_texture *texture = svga_texture(st->base.resource); struct svga_screen *screen = svga_screen(texture->b.b.screen); @@ -223,7 +200,9 @@ svga_transfer_dma(struct svga_context *svga, if(!st->swbuf) { /* Do the DMA transfer in a single go */ - svga_transfer_dma_band(svga, st, transfer, st->base.box.y, st->base.box.height, 0); + svga_transfer_dma_band(svga, st, transfer, + st->base.box.y, st->base.box.height, 0, + flags); if(transfer == SVGA3D_READ_HOST_VRAM) { svga_context_flush(svga, &fence); @@ -269,7 +248,14 @@ svga_transfer_dma(struct svga_context *svga, } } - svga_transfer_dma_band(svga, st, transfer, y, h, srcy); + svga_transfer_dma_band(svga, st, transfer, y, h, srcy, flags); + + /* + * Prevent the texture contents to be discarded on the next band + * upload. + */ + + flags.discard = FALSE; if(transfer == SVGA3D_READ_HOST_VRAM) { svga_context_flush(svga, &fence); @@ -398,8 +384,11 @@ svga_texture_get_transfer(struct pipe_context *pipe, goto no_swbuf; } - if (usage & PIPE_TRANSFER_READ) - svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM); + if (usage & PIPE_TRANSFER_READ) { + SVGA3dSurfaceDMAFlags flags; + memset(&flags, 0, sizeof flags); + svga_transfer_dma(svga, st, SVGA3D_READ_HOST_VRAM, flags); + } return &st->base; @@ -458,7 +447,17 @@ svga_texture_transfer_destroy(struct pipe_context *pipe, struct svga_transfer *st = svga_transfer(transfer); if (st->base.usage & PIPE_TRANSFER_WRITE) { - svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM); + SVGA3dSurfaceDMAFlags flags; + + memset(&flags, 0, sizeof flags); + if (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) { + flags.discard = TRUE; + } + if (transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) { + flags.unsynchronized = TRUE; + } + + svga_transfer_dma(svga, st, SVGA3D_WRITE_HOST_VRAM, flags); ss->texture_timestamp++; tex->view_age[transfer->level] = ++(tex->age); if (transfer->resource->target == PIPE_TEXTURE_CUBE) @@ -481,7 +480,6 @@ struct u_resource_vtbl svga_texture_vtbl = { svga_texture_get_handle, /* get_handle */ svga_texture_destroy, /* resource_destroy */ - svga_texture_is_referenced, /* is_resource_referenced */ svga_texture_get_transfer, /* get_transfer */ svga_texture_transfer_destroy, /* transfer_destroy */ svga_texture_transfer_map, /* transfer_map */ diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index ef1d3098d51..6c987abe056 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -342,8 +342,7 @@ svga_is_format_supported( struct pipe_screen *screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags ) + unsigned tex_usage) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; SVGA3dDevCapIndex index; @@ -412,27 +411,26 @@ svga_fence_reference(struct pipe_screen *screen, } -static int +static boolean svga_fence_signalled(struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flag) + struct pipe_fence_handle *fence) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; - return sws->fence_signalled(sws, fence, flag); + return sws->fence_signalled(sws, fence, 0) == 0; } -static int +static boolean svga_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, - unsigned flag) + uint64_t timeout) { struct svga_winsys_screen *sws = svga_screen(screen)->sws; SVGA_DBG(DEBUG_DMA|DEBUG_PERF, "%s fence_ptr %p\n", __FUNCTION__, fence); - return sws->fence_finish(sws, fence, flag); + return sws->fence_finish(sws, fence, 0) == 0; } @@ -498,6 +496,12 @@ svga_screen_create(struct svga_winsys_screen *sws) svga_init_screen_resource_functions(svgascreen); + if (sws->get_hw_version) { + svgascreen->hw_version = sws->get_hw_version(sws); + } else { + svgascreen->hw_version = SVGA3D_HWVERSION_WS65_B1; + } + svgascreen->use_ps30 = sws->get_cap(sws, SVGA3D_DEVCAP_FRAGMENT_SHADER_VERSION, &result) && result.u >= SVGA3DPSVERSION_30 ? TRUE : FALSE; diff --git a/src/gallium/drivers/svga/svga_screen.h b/src/gallium/drivers/svga/svga_screen.h index 86ec89d88c1..6d8d287ce95 100644 --- a/src/gallium/drivers/svga/svga_screen.h +++ b/src/gallium/drivers/svga/svga_screen.h @@ -39,8 +39,6 @@ struct svga_winsys_screen; struct svga_winsys_context; struct SVGACmdMemory; -#define SVGA_COMBINE_USERBUFFERS 1 - /** * Subclass of pipe_screen */ @@ -49,6 +47,8 @@ struct svga_screen struct pipe_screen screen; struct svga_winsys_screen *sws; + SVGA3dHardwareVersion hw_version; + unsigned use_ps30; unsigned use_vs30; diff --git a/src/gallium/drivers/svga/svga_state_vdecl.c b/src/gallium/drivers/svga/svga_state_vdecl.c index 958d00393f2..7c393a1da8d 100644 --- a/src/gallium/drivers/svga/svga_state_vdecl.c +++ b/src/gallium/drivers/svga/svga_state_vdecl.c @@ -78,7 +78,6 @@ upload_user_buffers( struct svga_context *svga ) buffer->b.b.width0); } - pipe_resource_reference( &svga->curr.vb[i].buffer, buffer->uploaded.buffer ); svga->curr.vb[i].buffer_offset = buffer->uploaded.offset; } } @@ -110,6 +109,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, for (i = 0; i < svga->curr.velems->count; i++) { const struct pipe_vertex_buffer *vb = &svga->curr.vb[ve[i].vertex_buffer_index]; unsigned usage, index; + struct svga_buffer *buffer = svga_buffer(vb->buffer); svga_generate_vdecl_semantics( i, &usage, &index ); @@ -127,6 +127,7 @@ static int emit_hw_vs_vdecl( struct svga_context *svga, svga_hwtnl_vdecl( svga->hwtnl, i, &decl, + buffer->uploaded.buffer ? buffer->uploaded.buffer : vb->buffer ); } @@ -148,14 +149,10 @@ static int emit_hw_vdecl( struct svga_context *svga, * userbuffers now and try to combine multiple userbuffers from * multiple draw calls into a single host buffer for performance. */ - if (svga->curr.any_user_vertex_buffers && - SVGA_COMBINE_USERBUFFERS) - { + if (svga->curr.any_user_vertex_buffers) { ret = upload_user_buffers( svga ); if (ret) return ret; - - svga->curr.any_user_vertex_buffers = FALSE; } return emit_hw_vs_vdecl( svga, dirty ); diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index 5e4bdeff2ee..ae61cea083f 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -136,6 +136,9 @@ struct svga_winsys_screen void (*destroy)(struct svga_winsys_screen *sws); + SVGA3dHardwareVersion + (*get_hw_version)(struct svga_winsys_screen *sws); + boolean (*get_cap)(struct svga_winsys_screen *sws, SVGA3dDevCapIndex index, @@ -243,12 +246,12 @@ struct svga_winsys_screen /** * Map the entire data store of a buffer object into the client's address. - * flags is a bitmaks of PIPE_TRANSFER_* + * usage is a bitmask of PIPE_TRANSFER_* */ void * (*buffer_map)( struct svga_winsys_screen *sws, struct svga_winsys_buffer *buf, - unsigned flags ); + unsigned usage ); void (*buffer_unmap)( struct svga_winsys_screen *sws, diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index d24cc623c2e..4db7619c424 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -1184,7 +1184,6 @@ trace_context_clear_depth_stencil(struct pipe_context *_pipe, static INLINE void trace_context_flush(struct pipe_context *_pipe, - unsigned flags, struct pipe_fence_handle **fence) { struct trace_context *tr_ctx = trace_context(_pipe); @@ -1193,9 +1192,8 @@ trace_context_flush(struct pipe_context *_pipe, trace_dump_call_begin("pipe_context", "flush"); trace_dump_arg(ptr, pipe); - trace_dump_arg(uint, flags); - pipe->flush(pipe, flags, fence); + pipe->flush(pipe, fence); if(fence) trace_dump_ret(ptr, *fence); @@ -1219,31 +1217,6 @@ trace_context_destroy(struct pipe_context *_pipe) FREE(tr_ctx); } -static unsigned int -trace_is_resource_referenced( struct pipe_context *_pipe, - struct pipe_resource *_resource, - unsigned level, int layer) -{ - struct trace_context *tr_ctx = trace_context(_pipe); - struct trace_resource *tr_tex = trace_resource(_resource); - struct pipe_context *pipe = tr_ctx->pipe; - struct pipe_resource *texture = tr_tex->resource; - unsigned int referenced; - - trace_dump_call_begin("pipe_context", "is_resource_referenced"); - trace_dump_arg(ptr, pipe); - trace_dump_arg(ptr, texture); - trace_dump_arg(uint, level); - trace_dump_arg(int, layer); - - referenced = pipe->is_resource_referenced(pipe, texture, level, layer); - - trace_dump_ret(uint, referenced); - trace_dump_call_end(); - - return referenced; -} - /******************************************************************** * transfer @@ -1520,7 +1493,6 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.clear_render_target = trace_context_clear_render_target; tr_ctx->base.clear_depth_stencil = trace_context_clear_depth_stencil; tr_ctx->base.flush = trace_context_flush; - tr_ctx->base.is_resource_referenced = trace_is_resource_referenced; tr_ctx->base.get_transfer = trace_context_get_transfer; tr_ctx->base.transfer_destroy = trace_context_transfer_destroy; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 51a4ea96335..8a4ec20fb84 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -60,10 +60,9 @@ static struct os_stream *stream = NULL; static unsigned refcount = 0; -static pipe_mutex call_mutex; +pipe_static_mutex(call_mutex); static long unsigned call_no = 0; static boolean dumping = FALSE; -static boolean initialized = FALSE; static INLINE void @@ -225,26 +224,13 @@ trace_dump_trace_close(void) stream = NULL; refcount = 0; call_no = 0; - pipe_mutex_destroy(call_mutex); } } -void trace_dump_init() -{ - if (initialized) - return; - - pipe_mutex_init(call_mutex); - dumping = FALSE; - initialized = TRUE; -} - boolean trace_dump_trace_begin() { const char *filename; - assert(initialized); - filename = debug_get_option("GALLIUM_TRACE", NULL); if(!filename) return FALSE; diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h index 74c5e83e9e1..62b4fe429b1 100644 --- a/src/gallium/drivers/trace/tr_dump.h +++ b/src/gallium/drivers/trace/tr_dump.h @@ -43,11 +43,6 @@ struct pipe_transfer; struct pipe_box; /* - * Call before use. - */ -void trace_dump_init(void); - -/* * Low level dumping controls. * * Opening the trace file and checking if that is opened. diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c index c2de2daa883..42180c4f19e 100644 --- a/src/gallium/drivers/trace/tr_screen.c +++ b/src/gallium/drivers/trace/tr_screen.c @@ -158,8 +158,7 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned tex_usage, - unsigned geom_flags) + unsigned tex_usage) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; @@ -172,10 +171,9 @@ trace_screen_is_format_supported(struct pipe_screen *_screen, trace_dump_arg(int, target); trace_dump_arg(uint, sample_count); trace_dump_arg(uint, tex_usage); - trace_dump_arg(uint, geom_flags); result = screen->is_format_supported(screen, format, target, sample_count, - tex_usage, geom_flags); + tex_usage); trace_dump_ret(bool, result); @@ -393,10 +391,9 @@ trace_screen_fence_reference(struct pipe_screen *_screen, } -static int +static boolean trace_screen_fence_signalled(struct pipe_screen *_screen, - struct pipe_fence_handle *fence, - unsigned flags) + struct pipe_fence_handle *fence) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; @@ -406,11 +403,10 @@ trace_screen_fence_signalled(struct pipe_screen *_screen, trace_dump_arg(ptr, screen); trace_dump_arg(ptr, fence); - trace_dump_arg(uint, flags); - result = screen->fence_signalled(screen, fence, flags); + result = screen->fence_signalled(screen, fence); - trace_dump_ret(int, result); + trace_dump_ret(bool, result); trace_dump_call_end(); @@ -418,10 +414,10 @@ trace_screen_fence_signalled(struct pipe_screen *_screen, } -static int +static boolean trace_screen_fence_finish(struct pipe_screen *_screen, struct pipe_fence_handle *fence, - unsigned flags) + uint64_t timeout) { struct trace_screen *tr_scr = trace_screen(_screen); struct pipe_screen *screen = tr_scr->screen; @@ -431,11 +427,11 @@ trace_screen_fence_finish(struct pipe_screen *_screen, trace_dump_arg(ptr, screen); trace_dump_arg(ptr, fence); - trace_dump_arg(uint, flags); + trace_dump_arg(uint, timeout); - result = screen->fence_finish(screen, fence, flags); + result = screen->fence_finish(screen, fence, timeout); - trace_dump_ret(int, result); + trace_dump_ret(bool, result); trace_dump_call_end(); @@ -472,8 +468,6 @@ trace_enabled(void) return trace; firstrun = FALSE; - trace_dump_init(); - if(trace_dump_trace_begin()) { trace_dumping_start(); trace = TRUE; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 24ee3fe1175..d8de3bac0ec 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -312,29 +312,12 @@ struct pipe_context { unsigned dstx, unsigned dsty, unsigned width, unsigned height); - /** Flush rendering - * \param flags bitmask of PIPE_FLUSH_x tokens) + /** Flush draw commands */ void (*flush)( struct pipe_context *pipe, - unsigned flags, struct pipe_fence_handle **fence ); /** - * Check whether a texture is referenced by an unflushed hw command. - * The state-tracker uses this function to avoid unnecessary flushes. - * It is safe (but wasteful) to always return - * PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE. - * \param pipe context whose unflushed hw commands will be checked. - * \param texture texture to check. - * \param level mipmap level. - * \param layer cubemap face, 2d array or 3d slice, 0 otherwise. Use -1 for any layer. - * \return mask of PIPE_REFERENCED_FOR_READ/WRITE or PIPE_UNREFERENCED - */ - unsigned int (*is_resource_referenced)(struct pipe_context *pipe, - struct pipe_resource *texture, - unsigned level, int layer); - - /** * Create a view on a texture to be used by a shader stage. */ struct pipe_sampler_view * (*create_sampler_view)(struct pipe_context *ctx, @@ -407,6 +390,11 @@ struct pipe_context { struct pipe_resource *, unsigned offset, unsigned size); + + /** + * Flush any pending framebuffer writes and invalidate texture caches. + */ + void (*texture_barrier)(struct pipe_context *); }; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 8cf738fa2c0..e9d47983e1b 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -337,25 +337,6 @@ enum pipe_transfer_usage { #define PIPE_USAGE_STAGING 5 /* supports data transfers from the GPU to the CPU */ -/* These are intended to be used in calls to is_format_supported, but - * no driver actually uses these flags, and only the glx/xlib state - * tracker issues them. - * - * Deprecate? - */ -#define PIPE_TEXTURE_GEOM_NON_SQUARE 0x1 -#define PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO 0x2 - - -/** - * Flush types: - */ -#define PIPE_FLUSH_RENDER_CACHE 0x1 -#define PIPE_FLUSH_TEXTURE_CACHE 0x2 -#define PIPE_FLUSH_SWAPBUFFERS 0x4 -#define PIPE_FLUSH_FRAME 0x8 /**< Mark the end of a frame */ - - /** * Shaders */ @@ -426,6 +407,8 @@ enum pipe_transfer_usage { #define PIPE_SWIZZLE_ONE 5 +#define PIPE_TIMEOUT_INFINITE 0xffffffffffffffffull + /** * Implementation capabilities/limits which are queried through * pipe_screen::get_param() and pipe_screen::get_paramf(). @@ -478,7 +461,8 @@ enum pipe_cap { PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER, PIPE_CAP_DEPTH_CLAMP, PIPE_CAP_SHADER_STENCIL_EXPORT, - PIPE_CAP_INSTANCED_DRAWING, + PIPE_CAP_TGSI_INSTANCEID, + PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR, }; /* Shader caps not specific to any single stage */ @@ -504,13 +488,6 @@ enum pipe_shader_cap PIPE_SHADER_CAP_SUBROUTINES, /* BGNSUB, ENDSUB, CAL, RET */ }; -/** - * Referenced query flags. - */ - -#define PIPE_UNREFERENCED 0 -#define PIPE_REFERENCED_FOR_READ (1 << 0) -#define PIPE_REFERENCED_FOR_WRITE (1 << 1) enum pipe_video_codec { diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index e2cc32222de..f3b1e5561cf 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -218,6 +218,11 @@ enum pipe_format { PIPE_FORMAT_A16_UNORM = 148, PIPE_FORMAT_I16_UNORM = 149, + PIPE_FORMAT_LATC1_UNORM = 143, + PIPE_FORMAT_LATC1_SNORM = 144, + PIPE_FORMAT_LATC2_UNORM = 145, + PIPE_FORMAT_LATC2_SNORM = 146, + PIPE_FORMAT_COUNT }; diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index 2a6acecb726..0d1b1094550 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -104,14 +104,12 @@ struct pipe_screen { * Check if the given pipe_format is supported as a texture or * drawing surface. * \param bindings bitmask of PIPE_BIND_* - * \param geom_flags bitmask of PIPE_TEXTURE_GEOM_* */ boolean (*is_format_supported)( struct pipe_screen *, enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bindings, - unsigned geom_flags ); + unsigned bindings ); /** * Create a new texture object, using the given template info. @@ -188,21 +186,17 @@ struct pipe_screen { /** * Checks whether the fence has been signalled. - * \param flags driver-specific meaning - * \return zero on success. */ - int (*fence_signalled)( struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags ); + boolean (*fence_signalled)( struct pipe_screen *screen, + struct pipe_fence_handle *fence ); /** * Wait for the fence to finish. - * \param flags driver-specific meaning - * \return zero on success. + * \param timeout in nanoseconds */ - int (*fence_finish)( struct pipe_screen *screen, - struct pipe_fence_handle *fence, - unsigned flags ); + boolean (*fence_finish)( struct pipe_screen *screen, + struct pipe_fence_handle *fence, + uint64_t timeout ); }; diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h index 73f03d58ea6..2d59741ec18 100644 --- a/src/gallium/include/pipe/p_video_context.h +++ b/src/gallium/include/pipe/p_video_context.h @@ -69,8 +69,7 @@ struct pipe_video_context */ boolean (*is_format_supported)(struct pipe_video_context *vpipe, enum pipe_format format, - unsigned usage, - unsigned geom); + unsigned usage); void (*destroy)(struct pipe_video_context *vpipe); diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h index 1c2148b78f2..d4973a10cc7 100644 --- a/src/gallium/include/state_tracker/st_api.h +++ b/src/gallium/include/state_tracker/st_api.h @@ -121,6 +121,11 @@ enum st_context_resource_type { }; /** + * Flush flags. + */ +#define ST_FLUSH_FRONT (1 << 0) + +/** * Value to st_manager->get_param function. */ enum st_manager_param { diff --git a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp index 2e45f3f43e9..741a97f897d 100644 --- a/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp +++ b/src/gallium/state_trackers/d3d1x/dxgi/src/dxgi_native.cpp @@ -1234,7 +1234,7 @@ struct GalliumDXGISwapChain : public GalliumDXGIObject<IDXGISwapChain, GalliumDX if(dst_surface) pipe->surface_destroy(pipe, dst_surface); - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, 0); + pipe->flush(pipe, 0); att = (db) ? NATIVE_ATTACHMENT_BACK_LEFT : NATIVE_ATTACHMENT_FRONT_LEFT; if(!surface->present(surface, att, FALSE, 0)) diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h index 542d6591293..12f2aaddc91 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_context.h @@ -1823,7 +1823,7 @@ changed: virtual void STDMETHODCALLTYPE Flush(void) { SYNCHRONIZED; - pipe->flush(pipe, PIPE_FLUSH_FRAME, 0); + pipe->flush(pipe, 0); } /* In Direct3D 10, if the reference count of an object drops to 0, it is automatically diff --git a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h index 9cfdc837d8e..f678ac7f733 100644 --- a/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h +++ b/src/gallium/state_trackers/d3d1x/gd3d11/d3d11_screen.h @@ -299,25 +299,25 @@ struct GalliumD3D11ScreenImpl : public GalliumD3D11Screen sampler_view |= D3D11_FORMAT_SUPPORT_SHADER_SAMPLE_COMPARISON; /* TODO: do this properly when Gallium drivers actually support index/vertex format queries */ - if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER, 0) - || (screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_INDEX_BUFFER, 0) + if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_VERTEX_BUFFER) + || (screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_INDEX_BUFFER) || format == PIPE_FORMAT_R8_UNORM)) support |= buffer; - if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT, 0)) + if(screen->is_format_supported(screen, format, PIPE_BUFFER, 0, PIPE_BIND_STREAM_OUTPUT)) support |= buffer | D3D11_FORMAT_SUPPORT_SO_BUFFER; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_1D, 0, PIPE_BIND_SAMPLER_VIEW)) support |= D3D11_FORMAT_SUPPORT_TEXTURE1D | sampler_view; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW)) support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_CUBE, 0, PIPE_BIND_SAMPLER_VIEW)) support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | sampler_view; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_3D, 0, PIPE_BIND_SAMPLER_VIEW)) support |= D3D11_FORMAT_SUPPORT_TEXTURE3D | sampler_view; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_BLENDABLE; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) support |= D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_DEPTH_STENCIL; - if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET, 0)) + if(screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, 0, PIPE_BIND_DISPLAY_TARGET)) support |= D3D11_FORMAT_SUPPORT_DISPLAY; format_support[format] = support; } diff --git a/src/gallium/state_trackers/dri/common/dri_context.c b/src/gallium/state_trackers/dri/common/dri_context.c index fc68ee13eaa..e23c1bcafaf 100644 --- a/src/gallium/state_trackers/dri/common/dri_context.c +++ b/src/gallium/state_trackers/dri/common/dri_context.c @@ -149,7 +149,7 @@ dri_unbind_context(__DRIcontext * cPriv) if (--ctx->bind_count == 0) { if (ctx->st == ctx->stapi->get_current(ctx->stapi)) { - ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); stapi->make_current(stapi, NULL, NULL, NULL); draw->context = NULL; read->context = NULL; @@ -171,7 +171,7 @@ dri_make_current(__DRIcontext * cPriv, struct st_context_iface *old_st = ctx->stapi->get_current(ctx->stapi); if (old_st && old_st != ctx->st) - old_st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL); + old_st->flush(old_st, ST_FLUSH_FRONT, NULL); ++ctx->bind_count; diff --git a/src/gallium/state_trackers/dri/common/dri_screen.c b/src/gallium/state_trackers/dri/common/dri_screen.c index 69c2e7e9ec8..5931df993b0 100644 --- a/src/gallium/state_trackers/dri/common/dri_screen.c +++ b/src/gallium/state_trackers/dri/common/dri_screen.c @@ -81,34 +81,34 @@ dri_fill_in_modes(struct dri_screen *screen, pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET, 0); + PIPE_BIND_RENDER_TARGET); pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET, 0); + PIPE_BIND_RENDER_TARGET); pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET, 0); + PIPE_BIND_RENDER_TARGET); /* We can only get a 16 or 32 bit depth buffer with getBuffersWithFormat */ if (dri_with_format(screen->sPriv)) { pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); } else { pf_z16 = FALSE; pf_z32 = FALSE; @@ -142,7 +142,7 @@ dri_fill_in_modes(struct dri_screen *screen, for (i = 1; i < 5; i++) { if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B5G6R5_UNORM, PIPE_TEXTURE_2D, i*2, - PIPE_BIND_RENDER_TARGET, 0)) { + PIPE_BIND_RENDER_TARGET)) { msaa_samples_array[msaa_samples_factor] = i * 2; msaa_samples_factor++; } @@ -161,7 +161,7 @@ dri_fill_in_modes(struct dri_screen *screen, for (i = 1; i < 5; i++) { if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_TEXTURE_2D, i*2, - PIPE_BIND_RENDER_TARGET, 0)) { + PIPE_BIND_RENDER_TARGET)) { msaa_samples_array[msaa_samples_factor] = i * 2; msaa_samples_factor++; } @@ -183,7 +183,7 @@ dri_fill_in_modes(struct dri_screen *screen, for (i = 1; i < 5; i++) { if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_TEXTURE_2D, i*2, - PIPE_BIND_RENDER_TARGET, 0)) { + PIPE_BIND_RENDER_TARGET)) { msaa_samples_array[msaa_samples_factor] = i * 2; msaa_samples_factor++; } diff --git a/src/gallium/state_trackers/dri/drm/dri2.c b/src/gallium/state_trackers/dri/drm/dri2.c index a5c94b4166b..30326a23d6c 100644 --- a/src/gallium/state_trackers/dri/drm/dri2.c +++ b/src/gallium/state_trackers/dri/drm/dri2.c @@ -270,7 +270,7 @@ dri2_allocate_buffer(__DRIscreen *sPriv, struct pipe_resource templ; enum st_attachment_type statt; enum pipe_format pf; - unsigned bind; + unsigned bind = 0; struct winsys_handle whandle; switch (attachment) { diff --git a/src/gallium/state_trackers/dri/sw/drisw.c b/src/gallium/state_trackers/dri/sw/drisw.c index 30088b09685..ac11f7c47f6 100644 --- a/src/gallium/state_trackers/dri/sw/drisw.c +++ b/src/gallium/state_trackers/dri/sw/drisw.c @@ -139,7 +139,7 @@ drisw_swap_buffers(__DRIdrawable *dPriv) ptex = drawable->textures[ST_ATTACHMENT_BACK_LEFT]; if (ptex) { - ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); drisw_copy_to_front(dPriv, ptex); } @@ -233,6 +233,7 @@ drisw_allocate_textures(struct dri_drawable *drawable, */ static const __DRIextension *drisw_screen_extensions[] = { + &driTexBufferExtension.base, NULL }; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index e60a56074dd..2c7f3bde4f0 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -368,7 +368,7 @@ egl_g3d_fill_depth_stencil_formats(_EGLDisplay *dpy, /* pick the first supported format */ for (i = 0; i < n; i++) { if (screen->is_format_supported(screen, fmt[i], - PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) { + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) { formats[count++] = fmt[i]; break; } diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index 2068256dff2..f1568329ecf 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -528,8 +528,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, old_gctx = egl_g3d_context(old_ctx); if (old_gctx) { /* flush old context */ - old_gctx->stctxi->flush(old_gctx->stctxi, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + old_gctx->stctxi->flush(old_gctx->stctxi, ST_FLUSH_FRONT, NULL); } if (gctx) { @@ -606,8 +605,7 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) /* flush if the surface is current */ if (gctx) { - gctx->stctxi->flush(gctx->stctxi, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); } return gsurf->native->present(gsurf->native, @@ -652,8 +650,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, /* flush if the surface is current */ if (ctx && ctx->DrawSurface == &gsurf->base) { struct egl_g3d_context *gctx = egl_g3d_context(ctx); - gctx->stctxi->flush(gctx->stctxi, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); } pipe = ndpy_get_copy_context(gdpy->native); @@ -667,7 +664,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, u_box_origin_2d(ptex->width0, ptex->height0, &src_box); pipe->resource_copy_region(pipe, ptex, 0, 0, 0, 0, gsurf->render_texture, 0, &src_box); - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + pipe->flush(pipe, NULL); nsurf->present(nsurf, NATIVE_ATTACHMENT_FRONT_LEFT, FALSE, 0); pipe_resource_reference(&ptex, NULL); @@ -686,10 +683,9 @@ egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) struct pipe_screen *screen = gdpy->native->screen; struct pipe_fence_handle *fence = NULL; - gctx->stctxi->flush(gctx->stctxi, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); + gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, &fence); if (fence) { - screen->fence_finish(screen, fence, 0); + screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE); screen->fence_reference(screen, &fence, NULL); } @@ -758,8 +754,7 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, /* flush properly if the surface is bound */ if (gsurf->base.CurrentContext) { gctx = egl_g3d_context(gsurf->base.CurrentContext); - gctx->stctxi->flush(gctx->stctxi, - PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); } gctx = egl_g3d_context(es1); diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c index 4e6d944c151..dd07af140a7 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_sync.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_sync.c @@ -109,7 +109,7 @@ egl_g3d_wait_fence_sync(struct egl_g3d_sync *gsync, EGLTimeKHR timeout) _eglUnlockMutex(&dpy->Mutex); /* no timed finish? */ - screen->fence_finish(screen, fence, 0x0); + screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE); ret = EGL_CONDITION_SATISFIED_KHR; _eglLockMutex(&dpy->Mutex); @@ -234,7 +234,7 @@ egl_g3d_client_wait_sync(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSync *sync, struct egl_g3d_context *gctx = egl_g3d_context(ctx); if (gctx) - gctx->stctxi->flush(gctx->stctxi, PIPE_FLUSH_RENDER_CACHE , NULL); + gctx->stctxi->flush(gctx->stctxi, ST_FLUSH_FRONT, NULL); } if (timeout) { diff --git a/src/gallium/state_trackers/egl/common/native_helper.c b/src/gallium/state_trackers/egl/common/native_helper.c index be6713d03a8..ee18cb2025b 100644 --- a/src/gallium/state_trackers/egl/common/native_helper.c +++ b/src/gallium/state_trackers/egl/common/native_helper.c @@ -333,7 +333,7 @@ resource_surface_throttle(struct resource_surface *rsurf) struct pipe_fence_handle *fence = swap_fences_pop_front(rsurf); if (fence) { - (void) screen->fence_finish(screen, fence, 0); + (void) screen->fence_finish(screen, fence, PIPE_TIMEOUT_INFINITE); screen->fence_reference(screen, &fence, NULL); return TRUE; } @@ -352,7 +352,7 @@ resource_surface_flush(struct resource_surface *rsurf, if (!pipe) return FALSE; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &fence); + pipe->flush(pipe, &fence); if (fence == NULL) return FALSE; diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index cdbb304c5ee..9863329ff40 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -43,7 +43,7 @@ drm_display_is_format_supported(struct native_display *ndpy, return ndpy->screen->is_format_supported(ndpy->screen, fmt, PIPE_TEXTURE_2D, 0, (is_color) ? PIPE_BIND_RENDER_TARGET : - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); } static const struct native_config ** diff --git a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c index 4a96039ac39..e2fde00e975 100644 --- a/src/gallium/state_trackers/egl/fbdev/native_fbdev.c +++ b/src/gallium/state_trackers/egl/fbdev/native_fbdev.c @@ -422,7 +422,7 @@ fbdev_display_init(struct native_display *ndpy) if (fbdpy->base.screen) { if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen, fbdpy->config.color_format, PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET, 0)) { + PIPE_BIND_RENDER_TARGET)) { fbdpy->base.screen->destroy(fbdpy->base.screen); fbdpy->base.screen = NULL; } diff --git a/src/gallium/state_trackers/egl/gdi/native_gdi.c b/src/gallium/state_trackers/egl/gdi/native_gdi.c index 3c2475f84d8..5d0045f92ee 100644 --- a/src/gallium/state_trackers/egl/gdi/native_gdi.c +++ b/src/gallium/state_trackers/egl/gdi/native_gdi.c @@ -285,7 +285,7 @@ fill_color_formats(struct native_display *ndpy, enum pipe_format formats[8]) for (i = 0; i < Elements(candidates); i++) { if (screen->is_format_supported(screen, candidates[i], - PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET, 0)) + PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET)) formats[count++] = candidates[i]; } diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index b18c3132c57..5afca67a4d4 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -541,7 +541,7 @@ is_format_supported(struct pipe_screen *screen, { return screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D, sample_count, (is_color) ? PIPE_BIND_RENDER_TARGET : - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); } static boolean diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c index 205a7e3c19a..351267bae4d 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_api.c +++ b/src/gallium/state_trackers/glx/xlib/glx_api.c @@ -1367,8 +1367,8 @@ glXSwapBuffers( Display *dpy, GLXDrawable drawable ) /*** GLX_MESA_copy_sub_buffer ***/ PUBLIC void -glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable, - int x, int y, int width, int height ) +glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, + int x, int y, int width, int height) { XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable ); if (buffer) { @@ -1718,8 +1718,8 @@ glXGetClientString( Display *dpy, int name ) PUBLIC int -glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config, - int attribute, int *value ) +glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, + int attribute, int *value) { XMesaVisual v = (XMesaVisual) config; (void) dpy; @@ -1763,8 +1763,8 @@ glXGetFBConfigs( Display *dpy, int screen, int *nelements ) PUBLIC GLXFBConfig * -glXChooseFBConfig( Display *dpy, int screen, - const int *attribList, int *nitems ) +glXChooseFBConfig(Display *dpy, int screen, + const int *attribList, int *nitems) { XMesaVisual xmvis; @@ -1814,8 +1814,8 @@ glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config ) PUBLIC GLXWindow -glXCreateWindow( Display *dpy, GLXFBConfig config, Window win, - const int *attribList ) +glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, + const int *attribList) { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf; @@ -1845,8 +1845,8 @@ glXDestroyWindow( Display *dpy, GLXWindow window ) /* XXX untested */ PUBLIC GLXPixmap -glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, - const int *attribList ) +glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, + const int *attribList) { XMesaVisual v = (XMesaVisual) config; XMesaBuffer b; @@ -1965,8 +1965,7 @@ glXDestroyPixmap( Display *dpy, GLXPixmap pixmap ) PUBLIC GLXPbuffer -glXCreatePbuffer( Display *dpy, GLXFBConfig config, - const int *attribList ) +glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList) { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf; @@ -2038,8 +2037,8 @@ glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf ) PUBLIC void -glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, - unsigned int *value ) +glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, + unsigned int *value) { GLuint width, height; XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw); @@ -2085,7 +2084,7 @@ glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, PUBLIC GLXContext glXCreateNewContext( Display *dpy, GLXFBConfig config, - int renderType, GLXContext shareList, Bool direct ) + int renderType, GLXContext shareList, Bool direct ) { GLXContext glxCtx; GLXContext shareCtx = shareList; @@ -2156,8 +2155,7 @@ glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask ) PUBLIC void -glXGetSelectedEvent( Display *dpy, GLXDrawable drawable, - unsigned long *mask ) +glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); if (xmbuf) @@ -2209,7 +2207,8 @@ glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count) /*** GLX_SGI_make_current_read ***/ PUBLIC Bool -glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) +glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, + GLXContext ctx) { return glXMakeContextCurrent( dpy, draw, read, ctx ); } @@ -2227,7 +2226,8 @@ glXGetCurrentReadDrawableSGI(void) #if defined(_VL_H) PUBLIC GLXVideoSourceSGIX -glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode) +glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, + VLPath path, int nodeClass, VLNode drainNode) { (void) dpy; (void) screen; @@ -2273,7 +2273,8 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID) } PUBLIC int -glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value) +glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, + int *value) { (void) dpy; (void) context; @@ -2287,20 +2288,24 @@ glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *val /*** GLX_SGIX_fbconfig ***/ PUBLIC int -glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value) +glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, + int attribute, int *value) { return glXGetFBConfigAttrib(dpy, config, attribute, value); } PUBLIC GLXFBConfigSGIX * -glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements) +glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, + int *nelements) { - return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements); + return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, + attrib_list, nelements); } PUBLIC GLXPixmap -glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap) +glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, + Pixmap pixmap) { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0); @@ -2309,7 +2314,9 @@ glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pi PUBLIC GLXContext -glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct) +glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, + int render_type, GLXContext share_list, + Bool direct) { XMesaVisual xmvis = (XMesaVisual) config; GLXContext glxCtx; @@ -2362,8 +2369,8 @@ glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis) PUBLIC GLXPbufferSGIX glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, - unsigned int width, unsigned int height, - int *attribList) + unsigned int width, unsigned int height, + int *attribList) { XMesaVisual xmvis = (XMesaVisual) config; XMesaBuffer xmbuf; @@ -2410,7 +2417,8 @@ glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf) PUBLIC int -glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value) +glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, + unsigned int *value) { const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf); @@ -2454,7 +2462,8 @@ glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask) PUBLIC void -glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask) +glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, + unsigned long *mask) { XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable); if (xmbuf) { @@ -2482,7 +2491,8 @@ glXCushionSGI(Display *dpy, Window win, float cushion) /*** GLX_SGIX_video_resize ***/ PUBLIC int -glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window) +glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel, + Window window) { (void) dpy; (void) screen; @@ -2492,7 +2502,8 @@ glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window } PUBLIC int -glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h) +glXChannelRectSGIX(Display *dpy, int screen, int channel, + int x, int y, int w, int h) { (void) dpy; (void) screen; @@ -2505,7 +2516,8 @@ glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, i } PUBLIC int -glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h) +glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, + int *x, int *y, int *w, int *h) { (void) dpy; (void) screen; @@ -2518,7 +2530,8 @@ glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, i } PUBLIC int -glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh) +glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, + int *dx, int *dy, int *dw, int *dh) { (void) dpy; (void) screen; @@ -2546,7 +2559,8 @@ glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype) #if defined(_DM_BUFFER_H_) PUBLIC Bool -glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer) +glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, + DMparams *params, DMbuffer dmbuffer) { (void) dpy; (void) pbuffer; @@ -2593,7 +2607,8 @@ glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max) /*** GLX_SUN_get_transparent_index ***/ PUBLIC Status -glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent) +glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, + long *pTransparent) { (void) dpy; (void) overlay; diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index 7c47a25ceba..3b35cbc890c 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -376,8 +376,6 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) { const enum pipe_texture_target target = PIPE_TEXTURE_2D; const unsigned tex_usage = PIPE_BIND_DEPTH_STENCIL; - const unsigned geom_flags = (PIPE_TEXTURE_GEOM_NON_SQUARE | - PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO); const unsigned sample_count = 0; enum pipe_format formats[8], fmt; int count, i; @@ -403,7 +401,7 @@ choose_depth_stencil_format(XMesaDisplay xmdpy, int depth, int stencil) for (i = 0; i < count; i++) { if (xmdpy->screen->is_format_supported(xmdpy->screen, formats[i], target, sample_count, - tex_usage, geom_flags)) { + tex_usage)) { fmt = formats[i]; break; } @@ -1195,11 +1193,7 @@ void XMesaSwapBuffers( XMesaBuffer b ) XMesaContext xmctx = XMesaGetCurrentContext(); if (xmctx && xmctx->xm_buffer == b) { - xmctx->st->flush( xmctx->st, - PIPE_FLUSH_RENDER_CACHE | - PIPE_FLUSH_SWAPBUFFERS | - PIPE_FLUSH_FRAME, - NULL); + xmctx->st->flush( xmctx->st, ST_FLUSH_FRONT, NULL); } xmesa_swap_st_framebuffer(b->stfb); @@ -1225,9 +1219,10 @@ void XMesaFlush( XMesaContext c ) XMesaDisplay xmdpy = xmesa_init_display(c->xm_visual->display); struct pipe_fence_handle *fence = NULL; - c->st->flush(c->st, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); + c->st->flush(c->st, ST_FLUSH_FRONT, &fence); if (fence) { - xmdpy->screen->fence_finish(xmdpy->screen, fence, 0); + xmdpy->screen->fence_finish(xmdpy->screen, fence, + PIPE_TIMEOUT_INFINITE); xmdpy->screen->fence_reference(xmdpy->screen, &fence, NULL); } XFlush( c->xm_visual->display ); diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index b30050bf6d4..17d25ad0aa6 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -400,10 +400,10 @@ error1: void flush(unsigned flags = 0) { struct pipe_fence_handle *fence = NULL; - $self->pipe->flush($self->pipe, flags | PIPE_FLUSH_RENDER_CACHE, &fence); + $self->pipe->flush($self->pipe, &fence); if(fence) { /* TODO: allow asynchronous operation */ - $self->pipe->screen->fence_finish( $self->pipe->screen, fence, 0 ); + $self->pipe->screen->fence_finish( $self->pipe->screen, fence, PIPE_TIMEOUT_INFINITE ); $self->pipe->screen->fence_reference( $self->pipe->screen, &fence, NULL ); } } diff --git a/src/gallium/state_trackers/python/p_device.i b/src/gallium/state_trackers/python/p_device.i index cc67da937cd..61f6b3bb739 100644 --- a/src/gallium/state_trackers/python/p_device.i +++ b/src/gallium/state_trackers/python/p_device.i @@ -86,8 +86,7 @@ struct st_device { int is_format_supported( enum pipe_format format, enum pipe_texture_target target, unsigned sample_count, - unsigned bind, - unsigned geom_flags ) { + unsigned bind ) { /* We can't really display surfaces with the python statetracker so mask * out that usage */ bind &= ~PIPE_BIND_DISPLAY_TARGET; @@ -96,8 +95,7 @@ struct st_device { format, target, sample_count, - bind, - geom_flags ); + bind ); } struct st_context * diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c index 8bc54d7fc7d..048cfe819f0 100644 --- a/src/gallium/state_trackers/vdpau/decode.c +++ b/src/gallium/state_trackers/vdpau/decode.c @@ -134,24 +134,15 @@ vlVdpCreateSurfaceTarget(vlVdpDecoder *vldecoder, vlVdpSurface *vlsurf) vctx = vldecoder->vctx->vpipe; + if (!vctx->is_format_supported(vctx, tmplt.format, PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) + return VDP_STATUS_RESOURCES; + memset(&tmplt, 0, sizeof(struct pipe_resource)); tmplt.target = PIPE_TEXTURE_2D; tmplt.format = vctx->get_param(vctx,PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT); tmplt.last_level = 0; - - if (vctx->is_format_supported(vctx, tmplt.format, - PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET, - PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) { - tmplt.width0 = vlsurf->width; - tmplt.height0 = vlsurf->height; - } else { - assert(vctx->is_format_supported(vctx, tmplt.format, - PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET, - PIPE_TEXTURE_GEOM_NON_SQUARE)); - tmplt.width0 = util_next_power_of_two(vlsurf->width); - tmplt.height0 = util_next_power_of_two(vlsurf->height); - } - + tmplt.width0 = vlsurf->width; + tmplt.height0 = vlsurf->height; tmplt.depth0 = 1; tmplt.usage = PIPE_USAGE_DEFAULT; tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; diff --git a/src/gallium/state_trackers/vdpau/query.c b/src/gallium/state_trackers/vdpau/query.c index 74a3bd925cf..e971b6dc02e 100644 --- a/src/gallium/state_trackers/vdpau/query.c +++ b/src/gallium/state_trackers/vdpau/query.c @@ -123,8 +123,7 @@ vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaTyp FormatToPipe(bits_ycbcr_format), PIPE_TEXTURE_2D, 1, - PIPE_BIND_RENDER_TARGET, - PIPE_TEXTURE_GEOM_NON_SQUARE); + PIPE_BIND_RENDER_TARGET); vl_screen_destroy(vlscreen); diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c index d6bbda5e075..19e42dd1562 100644 --- a/src/gallium/state_trackers/vega/api_context.c +++ b/src/gallium/state_trackers/vega/api_context.c @@ -56,7 +56,7 @@ void vegaFlush(void) return; pipe = ctx->pipe; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + pipe->flush(pipe, NULL); vg_manager_flush_frontbuffer(ctx); } @@ -72,9 +72,10 @@ void vegaFinish(void) pipe = ctx->pipe; - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); + pipe->flush(pipe, &fence); if (fence) { - pipe->screen->fence_finish(pipe->screen, fence, 0); + pipe->screen->fence_finish(pipe->screen, fence, + PIPE_TIMEOUT_INFINITE); pipe->screen->fence_reference(pipe->screen, &fence, NULL); } } diff --git a/src/gallium/state_trackers/vega/api_images.c b/src/gallium/state_trackers/vega/api_images.c index b993ba62c26..2cb5622f817 100644 --- a/src/gallium/state_trackers/vega/api_images.c +++ b/src/gallium/state_trackers/vega/api_images.c @@ -356,7 +356,6 @@ void vegaWritePixels(const void * data, VGint dataStride, VGint width, VGint height) { struct vg_context *ctx = vg_current_context(); - struct pipe_context *pipe = ctx->pipe; if (!supported_image_format(dataFormat)) { vg_set_error(ctx, VG_UNSUPPORTED_IMAGE_FORMAT_ERROR); @@ -387,8 +386,6 @@ void vegaWritePixels(const void * data, VGint dataStride, #endif image_destroy(img); } - /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); } void vegaReadPixels(void * data, VGint dataStride, @@ -421,8 +418,6 @@ void vegaReadPixels(void * data, VGint dataStride, return; } - /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); if (sx < 0) { xoffset = -sx; xoffset *= _vega_size_for_format(dataFormat); diff --git a/src/gallium/state_trackers/vega/image.c b/src/gallium/state_trackers/vega/image.c index 73351b671f9..44480876b6e 100644 --- a/src/gallium/state_trackers/vega/image.c +++ b/src/gallium/state_trackers/vega/image.c @@ -257,7 +257,7 @@ struct vg_image * image_create(VGImageFormat format, image->sampler.normalized_coords = 1; assert(screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D, - 0, PIPE_BIND_SAMPLER_VIEW, 0)); + 0, PIPE_BIND_SAMPLER_VIEW)); memset(&pt, 0, sizeof(pt)); pt.target = PIPE_TEXTURE_2D; @@ -518,8 +518,6 @@ void image_copy(struct vg_image *dst, VGint dx, VGint dy, vg_set_error(ctx, VG_ILLEGAL_ARGUMENT_ERROR); return; } - /* make sure rendering has completed */ - ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); vg_copy_texture(ctx, dst->sampler_view->texture, dst->x + dx, dst->y + dy, src->sampler_view, src->x + sx, src->y + sy, width, height); } @@ -569,9 +567,6 @@ void image_set_pixels(VGint dx, VGint dy, struct pipe_surface *surf, surf_tmpl; struct st_renderbuffer *strb = ctx->draw_buffer->strb; - /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); u_surface_default_template(&surf_tmpl, image_texture(src), 0 /* no bind flag - not a surface*/); @@ -595,9 +590,6 @@ void image_get_pixels(struct vg_image *dst, VGint dx, VGint dy, /* flip the y coordinates */ /*dy = dst->height - dy - height;*/ - /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - memset(&surf_tmpl, 0, sizeof(surf_tmpl)); u_surface_default_template(&surf_tmpl, image_texture(dst), PIPE_BIND_RENDER_TARGET); diff --git a/src/gallium/state_trackers/vega/mask.c b/src/gallium/state_trackers/vega/mask.c index dfd0600e444..10590e29cd2 100644 --- a/src/gallium/state_trackers/vega/mask.c +++ b/src/gallium/state_trackers/vega/mask.c @@ -111,8 +111,6 @@ static void read_alpha_mask(void * data, VGint dataStride, VGubyte *dst = (VGubyte *)data; VGint xoffset = 0, yoffset = 0; - /* make sure rendering has completed */ - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); if (sx < 0) { xoffset = -sx; xoffset *= _vega_size_for_format(dataFormat); diff --git a/src/gallium/state_trackers/vega/renderer.c b/src/gallium/state_trackers/vega/renderer.c index 9de2cb1014d..5715073e2d9 100644 --- a/src/gallium/state_trackers/vega/renderer.c +++ b/src/gallium/state_trackers/vega/renderer.c @@ -140,7 +140,7 @@ static VGboolean renderer_can_support(struct renderer *renderer, struct pipe_screen *screen = renderer->pipe->screen; return screen->is_format_supported(screen, - res->format, res->target, 0, bindings, 0); + res->format, res->target, 0, bindings); } /** @@ -1463,11 +1463,11 @@ void renderer_copy_surface(struct renderer *ctx, } assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, - 0, PIPE_BIND_SAMPLER_VIEW, 0)); + 0, PIPE_BIND_SAMPLER_VIEW)); assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - 0, PIPE_BIND_SAMPLER_VIEW, 0)); + 0, PIPE_BIND_SAMPLER_VIEW)); assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D, - 0, PIPE_BIND_RENDER_TARGET, 0)); + 0, PIPE_BIND_RENDER_TARGET)); /* * XXX for now we're always creating a temporary texture. diff --git a/src/gallium/state_trackers/vega/vg_context.c b/src/gallium/state_trackers/vega/vg_context.c index 83b42609e03..c2ab56455b1 100644 --- a/src/gallium/state_trackers/vega/vg_context.c +++ b/src/gallium/state_trackers/vega/vg_context.c @@ -69,7 +69,7 @@ choose_depth_stencil_format(struct vg_context *ctx) for (fmt = formats; *fmt != PIPE_FORMAT_NONE; fmt++) { if (screen->is_format_supported(screen, *fmt, - PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL, 0)) + PIPE_TEXTURE_2D, 0, PIPE_BIND_DEPTH_STENCIL)) break; } diff --git a/src/gallium/state_trackers/vega/vg_manager.c b/src/gallium/state_trackers/vega/vg_manager.c index 44d2996bb45..eeea68677de 100644 --- a/src/gallium/state_trackers/vega/vg_manager.c +++ b/src/gallium/state_trackers/vega/vg_manager.c @@ -142,8 +142,8 @@ vg_context_flush(struct st_context_iface *stctxi, unsigned flags, struct pipe_fence_handle **fence) { struct vg_context *ctx = (struct vg_context *) stctxi; - ctx->pipe->flush(ctx->pipe, flags, fence); - if (flags & PIPE_FLUSH_RENDER_CACHE) + ctx->pipe->flush(ctx->pipe, fence); + if (flags & ST_FLUSH_FRONT) vg_manager_flush_frontbuffer(ctx); } diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c index cd4f3c8b3e2..5608d4f4ce7 100644 --- a/src/gallium/state_trackers/wgl/stw_context.c +++ b/src/gallium/state_trackers/wgl/stw_context.c @@ -277,7 +277,7 @@ stw_make_current( return TRUE; } } else { - curctx->st->flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + curctx->st->flush(curctx->st, ST_FLUSH_FRONT, NULL); } } @@ -351,11 +351,7 @@ stw_flush_current_locked( struct stw_framebuffer *fb ) struct stw_context *ctx = stw_current_context(); if (ctx && ctx->current_framebuffer == fb) { - ctx->st->flush(ctx->st, - PIPE_FLUSH_RENDER_CACHE | - PIPE_FLUSH_SWAPBUFFERS | - PIPE_FLUSH_FRAME, - NULL); + ctx->st->flush(ctx->st, ST_FLUSH_FRONT, NULL); } } diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c index 4ece4e4979a..e65e71dc15f 100644 --- a/src/gallium/state_trackers/wgl/stw_device.c +++ b/src/gallium/state_trackers/wgl/stw_device.c @@ -41,8 +41,6 @@ #include "stw_framebuffer.h" #include "stw_st.h" -extern _glthread_Mutex OneTimeLock; - struct stw_device *stw_dev = NULL; @@ -50,7 +48,19 @@ static int stw_get_param(struct st_manager *smapi, enum st_manager_param param) { - return 0; + switch (param) { + case ST_MANAGER_BROKEN_INVALIDATE: + /* + * Force framebuffer validation on glViewport. + * + * Certain applications, like Rhinoceros 4, uses glReadPixels + * exclusively (never uses SwapBuffers), so framebuffers never get + * resized unless we check on glViewport. + */ + return 1; + default: + return 0; + } } boolean @@ -74,8 +84,6 @@ stw_init(const struct stw_winsys *stw_winsys) stw_dev->stw_winsys = stw_winsys; - _glthread_INIT_MUTEX(OneTimeLock); - stw_dev->stapi = stw_st_create_api(); stw_dev->smapi = CALLOC_STRUCT(st_manager); if (!stw_dev->stapi || !stw_dev->smapi) @@ -168,8 +176,6 @@ stw_cleanup(void) stw_dev->screen->destroy(stw_dev->screen); - _glthread_DESTROY_MUTEX(OneTimeLock); - /* glapi is statically linked: we can call the local destroy function. */ #ifdef _GLAPI_NO_EXPORTS _glapi_destroy_multithread(); diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index 5ede1d43220..333f50c25f6 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -225,7 +225,7 @@ stw_pixelformat_init( void ) if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D, 0, PIPE_BIND_RENDER_TARGET | - PIPE_BIND_DISPLAY_TARGET, 0)) + PIPE_BIND_DISPLAY_TARGET)) continue; for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) { @@ -235,7 +235,7 @@ stw_pixelformat_init( void ) const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[l]; if(!screen->is_format_supported(screen, depth->format, PIPE_TEXTURE_2D, - 0, PIPE_BIND_DEPTH_STENCIL, 0)) + 0, PIPE_BIND_DEPTH_STENCIL)) continue; stw_pixelformat_add( stw_dev, color, depth, 0, doublebuffer, samples ); diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 17c34b7eac8..6f2c52eabb6 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -336,7 +336,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, /* pixmap glXWaitX */ if (pSrcBuffer->attachment == DRI2BufferFrontLeft && pDestBuffer->attachment == DRI2BufferFakeFrontLeft) { - ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, NULL); + ms->ctx->flush(ms->ctx, NULL); return; } /* pixmap glXWaitGL */ @@ -362,7 +362,8 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, if (extents->x1 == 0 && extents->y1 == 0 && extents->x2 == pDraw->width && extents->y2 == pDraw->height) { - ms->screen->fence_finish(ms->screen, dst_priv->fence, 0); + ms->screen->fence_finish(ms->screen, dst_priv->fence, + PIPE_TIMEOUT_INFINITE); ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL); } } @@ -388,7 +389,7 @@ dri2_copy_region(DrawablePtr pDraw, RegionPtr pRegion, FreeScratchGC(gc); - ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, + ms->ctx->flush(ms->ctx, (pDestBuffer->attachment == DRI2BufferFrontLeft && ms->swapThrottling) ? &dst_priv->fence : NULL); @@ -451,12 +452,12 @@ xorg_dri2_init(ScreenPtr pScreen) ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24X8_UNORM, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); ms->ds_depth_bits_last = ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_TEXTURE_2D, 0, - PIPE_BIND_DEPTH_STENCIL, 0); + PIPE_BIND_DEPTH_STENCIL); return DRI2ScreenInit(pScreen, &dri2info); } diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 33bcacdcc2e..19e9bf84656 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -334,7 +334,8 @@ drv_cleanup_fences(ScrnInfoPtr pScrn) for (i = 0; i < XORG_NR_FENCES; i++) { if (ms->fence[i]) { - ms->screen->fence_finish(ms->screen, ms->fence[i], 0); + ms->screen->fence_finish(ms->screen, ms->fence[i], + PIPE_TIMEOUT_INFINITE); ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL); } } @@ -547,7 +548,7 @@ void xorg_flush(ScreenPtr pScreen) if (ms->ctx) { int j; - ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, + ms->ctx->flush(ms->ctx, ms->dirtyThrottling ? &ms->fence[XORG_NR_FENCES-1] : NULL); @@ -555,7 +556,8 @@ void xorg_flush(ScreenPtr pScreen) if (ms->dirtyThrottling) { if (ms->fence[0]) ms->ctx->screen->fence_finish(ms->ctx->screen, - ms->fence[0], 0); + ms->fence[0], + PIPE_TIMEOUT_INFINITE); /* The amount of rendering generated by a block handler can be * quite small. Let us get a fair way ahead of hardware before diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 718a3453939..e7d6a93e5ca 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -349,7 +349,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, 0, - PIPE_BIND_RENDER_TARGET, 0)) { + PIPE_BIND_RENDER_TARGET)) { XORG_FALLBACK("format %s", util_format_name(priv->tex->format)); } @@ -430,12 +430,12 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, 0, - PIPE_BIND_RENDER_TARGET, 0)) + PIPE_BIND_RENDER_TARGET)) XORG_FALLBACK("pDst format %s", util_format_name(priv->tex->format)); if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, src_priv->tex->target, 0, - PIPE_BIND_SAMPLER_VIEW, 0)) + PIPE_BIND_SAMPLER_VIEW)) XORG_FALLBACK("pSrc format %s", util_format_name(src_priv->tex->format)); exa->copy.src = src_priv; @@ -630,7 +630,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, 0, - PIPE_BIND_RENDER_TARGET, 0)) + PIPE_BIND_RENDER_TARGET)) XORG_FALLBACK("pDst format: %s", util_format_name(priv->tex->format)); if (priv->picture_format != pDstPicture->format) @@ -645,7 +645,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, 0, - PIPE_BIND_SAMPLER_VIEW, 0)) + PIPE_BIND_SAMPLER_VIEW)) XORG_FALLBACK("pSrc format: %s", util_format_name(priv->tex->format)); if (!picture_check_formats(priv, pSrcPicture)) @@ -662,7 +662,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, 0, - PIPE_BIND_SAMPLER_VIEW, 0)) + PIPE_BIND_SAMPLER_VIEW)) XORG_FALLBACK("pMask format: %s", util_format_name(priv->tex->format)); if (!picture_check_formats(priv, pMaskPicture)) @@ -1072,19 +1072,20 @@ xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv) } -void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, +void xorg_exa_flush(struct exa_context *exa, struct pipe_fence_handle **fence) { - exa->pipe->flush(exa->pipe, pipeFlushFlags, fence); + exa->pipe->flush(exa->pipe, fence); } void xorg_exa_finish(struct exa_context *exa) { struct pipe_fence_handle *fence = NULL; - xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence); + xorg_exa_flush(exa, &fence); - exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0); + exa->pipe->screen->fence_finish(exa->pipe->screen, fence, + PIPE_TIMEOUT_INFINITE); exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL); } diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h index 1f78f60be74..30b6f0ce460 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.h +++ b/src/gallium/state_trackers/xorg/xorg_exa.h @@ -74,7 +74,7 @@ do { \ struct pipe_surface * xorg_gpu_surface(struct pipe_context *pipe, struct exa_pixmap_priv *priv); -void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags, +void xorg_exa_flush(struct exa_context *exa, struct pipe_fence_handle **fence); void xorg_exa_finish(struct exa_context *exa); diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c index 3b3ae455c0b..6b799af90c8 100644 --- a/src/gallium/state_trackers/xorg/xorg_renderer.c +++ b/src/gallium/state_trackers/xorg/xorg_renderer.c @@ -450,8 +450,7 @@ void renderer_copy_prepare(struct xorg_renderer *r, assert(screen->is_format_supported(screen, dst_surface->format, PIPE_TEXTURE_2D, 0, - PIPE_BIND_RENDER_TARGET, - 0)); + PIPE_BIND_RENDER_TARGET)); (void) screen; @@ -519,14 +518,10 @@ renderer_clone_texture(struct xorg_renderer *r, struct pipe_resource *pt; struct pipe_resource templ; - if (pipe->is_resource_referenced(pipe, src, 0, 0) & - PIPE_REFERENCED_FOR_WRITE) - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - /* the coming in texture should already have that invariance */ debug_assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D, 0, - PIPE_BIND_SAMPLER_VIEW, 0)); + PIPE_BIND_SAMPLER_VIEW)); format = src->format; diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c index c72ba9ef8db..234574b968e 100644 --- a/src/gallium/state_trackers/xorg/xorg_xv.c +++ b/src/gallium/state_trackers/xorg/xorg_xv.c @@ -461,20 +461,6 @@ bind_shaders(struct xorg_xv_port_priv *port) cso_set_fragment_shader_handle(port->r->cso, shader.fs); } -static INLINE void -conditional_flush(struct pipe_context *pipe, struct pipe_resource **tex, - int num) -{ - int i; - for (i = 0; i < num; ++i) { - if (tex[i] && pipe->is_resource_referenced(pipe, tex[i], 0, 0) & - PIPE_REFERENCED_FOR_WRITE) { - pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); - return; - } - } -} - static void bind_samplers(struct xorg_xv_port_priv *port) { @@ -485,8 +471,6 @@ bind_samplers(struct xorg_xv_port_priv *port) memset(&sampler, 0, sizeof(struct pipe_sampler_state)); - conditional_flush(port->r->pipe, dst, 3); - sampler.wrap_s = PIPE_TEX_WRAP_CLAMP; sampler.wrap_t = PIPE_TEX_WRAP_CLAMP; sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR; diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c index c90ad409c10..799dac2efc8 100644 --- a/src/gallium/state_trackers/xorg/xvmc/surface.c +++ b/src/gallium/state_trackers/xorg/xvmc/surface.c @@ -226,20 +226,14 @@ Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surfac memset(&template, 0, sizeof(struct pipe_resource)); template.target = PIPE_TEXTURE_2D; template.format = (enum pipe_format)vpipe->get_param(vpipe, PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT); - template.last_level = 0; - if (vpipe->is_format_supported(vpipe, template.format, - PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET, - PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) { - template.width0 = context->width; - template.height0 = context->height; - } - else { - assert(vpipe->is_format_supported(vpipe, template.format, - PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET, - PIPE_TEXTURE_GEOM_NON_SQUARE)); - template.width0 = util_next_power_of_two(context->width); - template.height0 = util_next_power_of_two(context->height); + if (!vpipe->is_format_supported(vpipe, template.format, + PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET)) { + FREE(surface_priv); + return BadAlloc; } + template.last_level = 0; + template.width0 = util_next_power_of_two(context->width); + template.height0 = util_next_power_of_two(context->height); template.depth0 = 1; template.array_size = 1; template.usage = PIPE_USAGE_DEFAULT; diff --git a/src/gallium/targets/graw-gdi/graw_gdi.c b/src/gallium/targets/graw-gdi/graw_gdi.c index 17ca2a761ca..99d8641d6b1 100644 --- a/src/gallium/targets/graw-gdi/graw_gdi.c +++ b/src/gallium/targets/graw-gdi/graw_gdi.c @@ -66,7 +66,7 @@ graw_create_window_and_screen(int x, { struct sw_winsys *winsys = NULL; struct pipe_screen *screen = NULL; - WNDCLASSEX wc = {sizeof(wc)}; + WNDCLASSEX wc; UINT style = WS_VISIBLE | WS_TILEDWINDOW; RECT rect; HWND hWnd = NULL; @@ -83,6 +83,8 @@ graw_create_window_and_screen(int x, if (screen == NULL) goto fail; + memset(&wc, 0, sizeof wc); + wc.cbSize = sizeof wc; wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = window_proc; wc.lpszClassName = "graw-gdi"; diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript index 565fa5279cd..ad44d54c855 100644 --- a/src/gallium/tests/graw/SConscript +++ b/src/gallium/tests/graw/SConscript @@ -8,7 +8,7 @@ env.Prepend(LIBPATH = [graw.dir]) env.Prepend(LIBS = ['graw']) -if env['platform'] in ('freebsd8', 'sunos5'): +if env['platform'] in ('freebsd8', 'sunos'): env.Append(LIBS = ['m']) if env['platform'] == 'freebsd8': diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c index 55cc0087a09..392d1503f19 100644 --- a/src/gallium/tests/graw/clear.c +++ b/src/gallium/tests/graw/clear.c @@ -29,7 +29,7 @@ static void draw( void ) float clear_color[4] = {1,0,1,1}; ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c index ff82b607110..fda23bd7c9f 100644 --- a/src/gallium/tests/graw/fs-test.c +++ b/src/gallium/tests/graw/fs-test.c @@ -276,7 +276,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c index cc05889dd05..ebb26d2f3f4 100644 --- a/src/gallium/tests/graw/gs-test.c +++ b/src/gallium/tests/graw/gs-test.c @@ -339,7 +339,7 @@ static void draw( void ) else util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c index 3c6458b434e..6903046cf0e 100644 --- a/src/gallium/tests/graw/quad-sample.c +++ b/src/gallium/tests/graw/quad-sample.c @@ -150,7 +150,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c index 4e66813b301..fd01cb3f84f 100644 --- a/src/gallium/tests/graw/quad-tex.c +++ b/src/gallium/tests/graw/quad-tex.c @@ -147,7 +147,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/shader-leak.c b/src/gallium/tests/graw/shader-leak.c index a23ca73ac1d..004b1691b6b 100644 --- a/src/gallium/tests/graw/shader-leak.c +++ b/src/gallium/tests/graw/shader-leak.c @@ -149,7 +149,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, 1); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); ctx->bind_fs_state(ctx, NULL); ctx->delete_fs_state(ctx, fs); diff --git a/src/gallium/tests/graw/tri-gs.c b/src/gallium/tests/graw/tri-gs.c index 47b76530c6b..ab0116bed73 100644 --- a/src/gallium/tests/graw/tri-gs.c +++ b/src/gallium/tests/graw/tri-gs.c @@ -163,7 +163,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); screen->flush_frontbuffer(screen, tex, 0, 0, window); } diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index 259b3d9527c..bed34374666 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -211,7 +211,7 @@ static void draw( void ) ctx->draw_vbo(ctx, &info); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/tri.c b/src/gallium/tests/graw/tri.c index 4266c0394d8..30ead999a47 100644 --- a/src/gallium/tests/graw/tri.c +++ b/src/gallium/tests/graw/tri.c @@ -140,7 +140,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_TRIANGLES, 0, 3); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c index dd64d8b9301..18e056dcb35 100644 --- a/src/gallium/tests/graw/vs-test.c +++ b/src/gallium/tests/graw/vs-test.c @@ -227,7 +227,7 @@ static void draw( void ) ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0); util_draw_arrays(ctx, PIPE_PRIM_POINTS, 0, Elements(vertices)); - ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->flush(ctx, NULL); graw_save_surface_to_file(ctx, surf, NULL); diff --git a/src/gallium/tests/trivial/quad-tex.c b/src/gallium/tests/trivial/quad-tex.c index af93e09d8d4..3a64b1c8d96 100644 --- a/src/gallium/tests/trivial/quad-tex.c +++ b/src/gallium/tests/trivial/quad-tex.c @@ -335,7 +335,7 @@ static void draw(struct program *p) 4, /* verts */ 2); /* attribs/vert */ - p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + p->pipe->flush(p->pipe, NULL); debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]); } diff --git a/src/gallium/tests/trivial/tri.c b/src/gallium/tests/trivial/tri.c index b89cfe0d989..bfd2f3ca9a3 100644 --- a/src/gallium/tests/trivial/tri.c +++ b/src/gallium/tests/trivial/tri.c @@ -264,7 +264,7 @@ static void draw(struct program *p) 3, /* verts */ 2); /* attribs/vert */ - p->pipe->flush(p->pipe, PIPE_FLUSH_RENDER_CACHE, NULL); + p->pipe->flush(p->pipe, NULL); debug_dump_surface_bmp(p->pipe, "result.bmp", p->framebuffer.cbufs[0]); } diff --git a/src/gallium/tests/unit/SConscript b/src/gallium/tests/unit/SConscript new file mode 100644 index 00000000000..49f28c03691 --- /dev/null +++ b/src/gallium/tests/unit/SConscript @@ -0,0 +1,33 @@ +Import('*') + +env = env.Clone() + +env.Prepend(LIBS = [gallium]) + +if env['platform'] in ('freebsd8', 'sunos'): + env.Append(LIBS = ['m']) + +if env['platform'] == 'freebsd8': + env.Append(LIBS = ['pthread']) + +progs = [ + 'pipe_barrier_test', + 'u_cache_test', + 'u_format_test', + 'u_format_compatible_test', + 'u_half_test', + 'translate_test' +] + +for prog in progs: + prog = env.Program( + target = prog, + source = prog + '.c', + ) + + env.InstallProgram(prog) + + # http://www.scons.org/wiki/UnitTests + test_alias = env.Alias('unit', [prog], prog[0].abspath) + AlwaysBuild(test_alias) + diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c index 06e8f6910f3..40d6ec4c625 100644 --- a/src/gallium/winsys/r600/drm/r600_bo.c +++ b/src/gallium/winsys/r600/drm/r600_bo.c @@ -133,7 +133,7 @@ void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, voi return NULL; } if (ctx) { - pctx->flush(pctx, 0, NULL); + pctx->flush(pctx, NULL); } } diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c index cd0aa318be5..c081abb4dcd 100644 --- a/src/gallium/winsys/r600/drm/r600_drm.c +++ b/src/gallium/winsys/r600/drm/r600_drm.c @@ -363,9 +363,6 @@ struct radeon *radeon_decref(struct radeon *radeon) if (radeon->bomgr) r600_bomgr_destroy(radeon->bomgr); - if (radeon->fd >= 0) - drmClose(radeon->fd); - free(radeon); return NULL; } diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 6b3baa2c909..a7c21784e51 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -760,6 +760,17 @@ out_err: return r; } +static void rv6xx_context_surface_base_update(struct r600_context *ctx, + unsigned base_update_flags) +{ + /* need to emit surface base update on rv6xx */ + if ((ctx->radeon->family > CHIP_R600) && + (ctx->radeon->family < CHIP_RV770)) { + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_SURFACE_BASE_UPDATE, 0, 0); + ctx->pm4[ctx->pm4_cdwords++] = base_update_flags; + } +} + void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags, unsigned flush_mask, struct r600_bo *rbo) { @@ -991,6 +1002,7 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) unsigned ndwords = 9; struct r600_block *dirty_block = NULL; struct r600_block *next_block; + unsigned rv6xx_surface_base_update = 0; if (draw->indices) { ndwords = 13; @@ -1013,10 +1025,14 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) for (int i = 0; i < 8; i++) { if (cb[i]) { ndwords += 7; + rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_COLOR(i); } } - if (db) + if (db) { ndwords += 7; + rv6xx_surface_base_update |= SURFACE_BASE_UPDATE_DEPTH; + } + /* XXX also need to update SURFACE_BASE_UPDATE_STRMOUT when we support it */ /* queries need some special values */ if (ctx->num_query_running) { @@ -1043,10 +1059,14 @@ void r600_context_draw(struct r600_context *ctx, const struct r600_draw *draw) } /* enough room to copy packet */ - LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty,list) { + LIST_FOR_EACH_ENTRY_SAFE(dirty_block, next_block, &ctx->dirty, list) { r600_context_block_emit_dirty(ctx, dirty_block); } + /* rv6xx surface base udpate */ + if (rv6xx_surface_base_update) + rv6xx_context_surface_base_update(ctx, rv6xx_surface_base_update); + /* draw packet */ ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_INDEX_TYPE, 0, ctx->predicate_drawing); ctx->pm4[ctx->pm4_cdwords++] = draw->vgt_index_type; diff --git a/src/gallium/winsys/r600/drm/r600d.h b/src/gallium/winsys/r600/drm/r600d.h index cb12865ff01..80424818044 100644 --- a/src/gallium/winsys/r600/drm/r600d.h +++ b/src/gallium/winsys/r600/drm/r600d.h @@ -90,6 +90,9 @@ #define PKT3_SET_SAMPLER 0x6E #define PKT3_SET_CTL_CONST 0x6F #define PKT3_SURFACE_BASE_UPDATE 0x73 +#define SURFACE_BASE_UPDATE_DEPTH (1 << 0) +#define SURFACE_BASE_UPDATE_COLOR(x) (2 << (x)) +#define SURFACE_BASE_UPDATE_STRMOUT(x) (0x200 << (x)) #define EVENT_TYPE_PS_PARTIAL_FLUSH 0x10 #define EVENT_TYPE_CACHE_FLUSH_AND_INV_TS_EVENT 0x14 diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c index 3094337a3cd..9eb833454df 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_bo.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_bo.c @@ -172,7 +172,7 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, /* DONTBLOCK doesn't make sense with UNSYNCHRONIZED. */ if (flags & PB_USAGE_DONTBLOCK) { if (radeon_bo_is_referenced_by_cs(cs, bo)) { - cs->flush_cs(cs->flush_data); + cs->flush_cs(cs->flush_data, R300_FLUSH_ASYNC); return NULL; } @@ -181,7 +181,11 @@ static void *radeon_bo_map_internal(struct pb_buffer *_buf, } } else { if (radeon_bo_is_referenced_by_cs(cs, bo)) { - cs->flush_cs(cs->flush_data); + cs->flush_cs(cs->flush_data, 0); + } else { + /* Try to avoid busy-waiting in radeon_bo_wait. */ + if (p_atomic_read(&bo->num_active_ioctls)) + radeon_drm_cs_sync_flush(cs); } radeon_bo_wait((struct r300_winsys_bo*)bo); @@ -406,8 +410,7 @@ static void radeon_bo_set_tiling(struct r300_winsys_bo *_buf, /* Tiling determines how DRM treats the buffer data. * We must flush CS when changing it if the buffer is referenced. */ if (cs && radeon_bo_is_referenced_by_cs(cs, bo)) { - radeon_drm_cs_flush(rcs); - radeon_drm_cs_sync_flush(rcs); + cs->flush_cs(cs->flush_data, 0); } while (p_atomic_read(&bo->num_active_ioctls)) { diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c index 9ee800f5950..951791a1727 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c @@ -355,10 +355,8 @@ static PIPE_THREAD_ROUTINE(radeon_drm_cs_emit_ioctl, param) return NULL; } -void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs) +void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs) { - struct radeon_drm_cs *cs = radeon_drm_cs(rcs); - /* Wait for any pending ioctl to complete. */ if (cs->thread) { pipe_thread_wait(cs->thread); @@ -368,12 +366,12 @@ void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs) DEBUG_GET_ONCE_BOOL_OPTION(thread, "RADEON_THREAD", TRUE) -void radeon_drm_cs_flush(struct r300_winsys_cs *rcs) +static void radeon_drm_cs_flush(struct r300_winsys_cs *rcs, unsigned flags) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); struct radeon_cs_context *tmp; - radeon_drm_cs_sync_flush(rcs); + radeon_drm_cs_sync_flush(cs); /* If the CS is not empty, emit it in a newly-spawned thread. */ if (cs->base.cdw) { @@ -384,7 +382,8 @@ void radeon_drm_cs_flush(struct r300_winsys_cs *rcs) for (i = 0; i < crelocs; i++) p_atomic_inc(&cs->csc->relocs_bo[i]->num_active_ioctls); - if (cs->ws->num_cpus > 1 && debug_get_option_thread()) { + if (cs->ws->num_cpus > 1 && debug_get_option_thread() && + (flags & R300_FLUSH_ASYNC)) { cs->thread = pipe_thread_create(radeon_drm_cs_emit_ioctl, cs->csc); assert(cs->thread); } else { @@ -407,7 +406,7 @@ void radeon_drm_cs_flush(struct r300_winsys_cs *rcs) static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); - radeon_drm_cs_sync_flush(rcs); + radeon_drm_cs_sync_flush(cs); radeon_cs_context_cleanup(&cs->csc1); radeon_cs_context_cleanup(&cs->csc2); p_atomic_dec(&cs->ws->num_cs); @@ -417,7 +416,8 @@ static void radeon_drm_cs_destroy(struct r300_winsys_cs *rcs) } static void radeon_drm_cs_set_flush(struct r300_winsys_cs *rcs, - void (*flush)(void *), void *user) + void (*flush)(void *ctx, unsigned flags), + void *user) { struct radeon_drm_cs *cs = radeon_drm_cs(rcs); cs->flush_cs = flush; @@ -441,7 +441,6 @@ void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws) ws->base.cs_validate = radeon_drm_cs_validate; ws->base.cs_write_reloc = radeon_drm_cs_write_reloc; ws->base.cs_flush = radeon_drm_cs_flush; - ws->base.cs_sync_flush = radeon_drm_cs_sync_flush; ws->base.cs_set_flush = radeon_drm_cs_set_flush; ws->base.cs_is_buffer_referenced = radeon_bo_is_referenced; } diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h index 4cc97f37e09..dfaa161c318 100644 --- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.h +++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.h @@ -70,7 +70,7 @@ struct radeon_drm_cs { struct radeon_drm_winsys *ws; /* Flush CS. */ - void (*flush_cs)(void *); + void (*flush_cs)(void *ctx, unsigned flags); void *flush_data; pipe_thread thread; @@ -96,8 +96,7 @@ static INLINE boolean radeon_bo_is_referenced_by_any_cs(struct radeon_bo *bo) return bo->num_cs_references; } -void radeon_drm_cs_flush(struct r300_winsys_cs *rcs); -void radeon_drm_cs_sync_flush(struct r300_winsys_cs *rcs); +void radeon_drm_cs_sync_flush(struct radeon_drm_cs *cs); void radeon_drm_cs_init_functions(struct radeon_drm_winsys *ws); #endif diff --git a/src/gallium/winsys/sw/dri/SConscript b/src/gallium/winsys/sw/dri/SConscript index b255d725f95..f8e1fa6cfd8 100644 --- a/src/gallium/winsys/sw/dri/SConscript +++ b/src/gallium/winsys/sw/dri/SConscript @@ -4,7 +4,7 @@ Import('*') -if env['platform'] == 'linux': +if env['platform'] in ('linux', 'sunos'): env = env.Clone() diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c index 4ecfdbf3915..51245766d1c 100644 --- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c +++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c @@ -246,7 +246,7 @@ wsw_dt_unmap(struct sw_winsys *ws, pipe->transfer_unmap(pipe, wdt->transfer); pipe->transfer_destroy(pipe, wdt->transfer); - pipe->flush(pipe, 0, NULL); + pipe->flush(pipe, NULL); wdt->transfer = NULL; } diff --git a/src/gallium/winsys/sw/xlib/SConscript b/src/gallium/winsys/sw/xlib/SConscript index df01a9ec2bf..e9c274059bd 100644 --- a/src/gallium/winsys/sw/xlib/SConscript +++ b/src/gallium/winsys/sw/xlib/SConscript @@ -4,7 +4,7 @@ Import('*') -if env['platform'] in ('cygwin', 'linux'): +if env['platform'] in ('cygwin', 'linux', 'sunos'): env = env.Clone() |