summaryrefslogtreecommitdiff
path: root/src/gallium
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/gallivm/Makefile4
-rw-r--r--src/gallium/auxiliary/gallivm/gallivm.cpp2
-rw-r--r--src/gallium/auxiliary/gallivm/gallivm_builtins.cpp2
-rw-r--r--src/gallium/auxiliary/gallivm/gallivm_cpu.cpp2
-rw-r--r--src/gallium/auxiliary/gallivm/instructions.cpp2
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.cpp9
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp2
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c123
-rw-r--r--src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h81
-rw-r--r--src/gallium/auxiliary/util/u_memory.h2
-rw-r--r--src/gallium/drivers/cell/common.h43
-rw-r--r--src/gallium/drivers/cell/ppu/cell_batch.c73
-rw-r--r--src/gallium/drivers/cell/ppu/cell_batch.h9
-rw-r--r--src/gallium/drivers/cell/ppu/cell_clear.c5
-rw-r--r--src/gallium/drivers/cell/ppu/cell_flush.c13
-rw-r--r--src/gallium/drivers/cell/ppu/cell_gen_fragment.c834
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_emit.c43
-rw-r--r--src/gallium/drivers/cell/ppu/cell_vbuf.c16
-rw-r--r--src/gallium/drivers/cell/spu/spu_command.c52
-rw-r--r--src/gallium/drivers/cell/spu/spu_shuffle.h2
-rw-r--r--src/gallium/drivers/cell/spu/spu_tri.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h14
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c160
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c38
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c84
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c14
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c26
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c33
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c43
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h3
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c4
-rw-r--r--src/gallium/include/pipe/p_defines.h1
-rw-r--r--src/gallium/include/state_tracker/drm_api.h33
-rw-r--r--src/gallium/state_trackers/egl/Makefile29
-rw-r--r--src/gallium/state_trackers/egl/egl_context.c194
-rw-r--r--src/gallium/state_trackers/egl/egl_surface.c418
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.c217
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.h191
-rw-r--r--src/gallium/state_trackers/egl/egl_visual.c85
-rw-r--r--src/gallium/state_trackers/g3dvl/vl_basic_csc.c54
-rw-r--r--src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c70
-rw-r--r--src/gallium/state_trackers/g3dvl/vl_surface.c8
-rw-r--r--src/gallium/winsys/drm/Makefile.template4
-rw-r--r--src/gallium/winsys/drm/intel/Makefile2
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile10
-rw-r--r--src/gallium/winsys/drm/intel/egl/SConscript39
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_api.c10
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_api.h14
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h24
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_context.c211
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_context.h118
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_device.c145
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_device.h50
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_egl.c796
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_egl.h53
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_reg.h53
-rw-r--r--src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c111
-rw-r--r--src/gallium/winsys/drm/intel/gem/Makefile18
-rw-r--r--src/gallium/winsys/drm/intel/gem/Makefile.template64
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c139
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h55
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c78
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.h48
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c267
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h74
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_fence.h38
-rw-r--r--src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c13
-rw-r--r--src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c2
68 files changed, 3147 insertions, 2329 deletions
diff --git a/src/gallium/auxiliary/gallivm/Makefile b/src/gallium/auxiliary/gallivm/Makefile
index c3f7bfba93..5a96d94ec3 100644
--- a/src/gallium/auxiliary/gallivm/Makefile
+++ b/src/gallium/auxiliary/gallivm/Makefile
@@ -66,12 +66,12 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(INC_SOURCES)
gallivm_builtins.cpp: llvm_builtins.c
clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp1.bin
- (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@
+ (echo "static const unsigned char llvm_builtins_data[] = {"; od -txC temp1.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
rm temp1.bin
gallivmsoabuiltins.cpp: soabuiltins.c
clang --emit-llvm < $< |llvm-as|opt -std-compile-opts > temp2.bin
- (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/};/") >$@
+ (echo "static const unsigned char soabuiltins_data[] = {"; od -txC temp2.bin | sed -e "s/^[0-9]*//" -e s"/ \([0-9a-f][0-9a-f]\)/0x\1,/g" -e"\$$d" | sed -e"\$$s/,$$/,0x00};/") >$@
rm temp2.bin
# Emacs tags
diff --git a/src/gallium/auxiliary/gallivm/gallivm.cpp b/src/gallium/auxiliary/gallivm/gallivm.cpp
index 29adeea47d..f4af5cc8ad 100644
--- a/src/gallium/auxiliary/gallivm/gallivm.cpp
+++ b/src/gallium/auxiliary/gallivm/gallivm.cpp
@@ -53,7 +53,7 @@
#include <llvm/ModuleProvider.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
-#include <llvm/ParameterAttributes.h>
+#include <llvm/Attributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
diff --git a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp
index fcc5c05794..634bac0150 100644
--- a/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp
+++ b/src/gallium/auxiliary/gallivm/gallivm_builtins.cpp
@@ -137,4 +137,4 @@ static const unsigned char llvm_builtins_data[] = {
0x58,0x85,0x05,0x14,0xbe,0x34,0x45,0xb5,0x21,0x10,0x82,0x23,0x15,0x46,0x30,0x2c,
0xc8,0x64,0x02,0x06,0xf0,0x3c,0x91,0x73,0x19,0x00,0xe1,0x4b,0x53,0x64,0x0a,0x84,
0x84,0x34,0x85,0x25,0x0c,0x92,0x20,0x59,0xc1,0x20,0x30,0x8f,0x2d,0x10,0x95,0x84,
-0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp
index 93a9748bdb..1bd00a0c2a 100644
--- a/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp
+++ b/src/gallium/auxiliary/gallivm/gallivm_cpu.cpp
@@ -56,7 +56,7 @@
#include <llvm/ModuleProvider.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
-#include <llvm/ParameterAttributes.h>
+#include <llvm/Attributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
diff --git a/src/gallium/auxiliary/gallivm/instructions.cpp b/src/gallium/auxiliary/gallivm/instructions.cpp
index 599975d5ad..ee8162efce 100644
--- a/src/gallium/auxiliary/gallivm/instructions.cpp
+++ b/src/gallium/auxiliary/gallivm/instructions.cpp
@@ -43,7 +43,7 @@
#include <llvm/Function.h>
#include <llvm/InstrTypes.h>
#include <llvm/Instructions.h>
-#include <llvm/ParameterAttributes.h>
+#include <llvm/Attributes.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
index d5600fd22d..925e948763 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
@@ -37,7 +37,7 @@
#include <llvm/Function.h>
#include <llvm/Instructions.h>
#include <llvm/Transforms/Utils/Cloning.h>
-#include <llvm/ParameterAttributes.h>
+#include <llvm/Attributes.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Bitcode/ReaderWriter.h>
@@ -206,11 +206,12 @@ llvm::Module * InstructionsSoa::currentModule() const
void InstructionsSoa::createBuiltins()
{
+ std::string ErrMsg;
MemoryBuffer *buffer = MemoryBuffer::getMemBuffer(
(const char*)&soabuiltins_data[0],
- (const char*)&soabuiltins_data[Elements(soabuiltins_data)]);
- m_builtins = ParseBitcodeFile(buffer);
- std::cout<<"Builtins created at "<<m_builtins<<std::endl;
+ (const char*)&soabuiltins_data[Elements(soabuiltins_data) - 1]);
+ m_builtins = ParseBitcodeFile(buffer, &ErrMsg);
+ std::cout<<"Builtins created at "<<m_builtins<<" ("<<ErrMsg<<")"<<std::endl;
assert(m_builtins);
createDependencies();
}
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index c11b88af9e..6b18a68fe6 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -25,7 +25,7 @@
#include <llvm/ModuleProvider.h>
#include <llvm/Pass.h>
#include <llvm/PassManager.h>
-#include <llvm/ParameterAttributes.h>
+#include <llvm/Attributes.h>
#include <llvm/Support/PatternMatch.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/Interpreter.h>
diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c
index 071bc2015c..53a0e722cf 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c
+++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.c
@@ -213,8 +213,8 @@ emit_instruction(struct spe_function *p, uint32_t inst_bits)
-static void emit_RR(struct spe_function *p, unsigned op, unsigned rT,
- unsigned rA, unsigned rB, const char *name)
+static void emit_RR(struct spe_function *p, unsigned op, int rT,
+ int rA, int rB, const char *name)
{
union spe_inst_RR inst;
inst.inst.op = op;
@@ -230,8 +230,8 @@ static void emit_RR(struct spe_function *p, unsigned op, unsigned rT,
}
-static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT,
- unsigned rA, unsigned rB, unsigned rC, const char *name)
+static void emit_RRR(struct spe_function *p, unsigned op, int rT,
+ int rA, int rB, int rC, const char *name)
{
union spe_inst_RRR inst;
inst.inst.op = op;
@@ -248,8 +248,8 @@ static void emit_RRR(struct spe_function *p, unsigned op, unsigned rT,
}
-static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT,
- unsigned rA, int imm, const char *name)
+static void emit_RI7(struct spe_function *p, unsigned op, int rT,
+ int rA, int imm, const char *name)
{
union spe_inst_RI7 inst;
inst.inst.op = op;
@@ -266,8 +266,8 @@ static void emit_RI7(struct spe_function *p, unsigned op, unsigned rT,
-static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT,
- unsigned rA, int imm, const char *name)
+static void emit_RI8(struct spe_function *p, unsigned op, int rT,
+ int rA, int imm, const char *name)
{
union spe_inst_RI8 inst;
inst.inst.op = op;
@@ -284,8 +284,8 @@ static void emit_RI8(struct spe_function *p, unsigned op, unsigned rT,
-static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT,
- unsigned rA, int imm, const char *name)
+static void emit_RI10(struct spe_function *p, unsigned op, int rT,
+ int rA, int imm, const char *name)
{
union spe_inst_RI10 inst;
inst.inst.op = op;
@@ -302,8 +302,8 @@ static void emit_RI10(struct spe_function *p, unsigned op, unsigned rT,
/** As above, but do range checking on signed immediate value */
-static void emit_RI10s(struct spe_function *p, unsigned op, unsigned rT,
- unsigned rA, int imm, const char *name)
+static void emit_RI10s(struct spe_function *p, unsigned op, int rT,
+ int rA, int imm, const char *name)
{
assert(imm <= 511);
assert(imm >= -512);
@@ -311,7 +311,7 @@ static void emit_RI10s(struct spe_function *p, unsigned op, unsigned rT,
}
-static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT,
+static void emit_RI16(struct spe_function *p, unsigned op, int rT,
int imm, const char *name)
{
union spe_inst_RI16 inst;
@@ -326,7 +326,7 @@ static void emit_RI16(struct spe_function *p, unsigned op, unsigned rT,
}
-static void emit_RI18(struct spe_function *p, unsigned op, unsigned rT,
+static void emit_RI18(struct spe_function *p, unsigned op, int rT,
int imm, const char *name)
{
union spe_inst_RI18 inst;
@@ -348,61 +348,61 @@ void _name (struct spe_function *p) \
}
#define EMIT_(_name, _op) \
-void _name (struct spe_function *p, unsigned rT) \
+void _name (struct spe_function *p, int rT) \
{ \
emit_RR(p, _op, rT, 0, 0, __FUNCTION__); \
}
#define EMIT_R(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA) \
+void _name (struct spe_function *p, int rT, int rA) \
{ \
emit_RR(p, _op, rT, rA, 0, __FUNCTION__); \
}
#define EMIT_RR(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB) \
+void _name (struct spe_function *p, int rT, int rA, int rB) \
{ \
emit_RR(p, _op, rT, rA, rB, __FUNCTION__); \
}
#define EMIT_RRR(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA, unsigned rB, unsigned rC) \
+void _name (struct spe_function *p, int rT, int rA, int rB, int rC) \
{ \
emit_RRR(p, _op, rT, rA, rB, rC, __FUNCTION__); \
}
#define EMIT_RI7(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
+void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI7(p, _op, rT, rA, imm, __FUNCTION__); \
}
#define EMIT_RI8(_name, _op, bias) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
+void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI8(p, _op, rT, rA, bias - imm, __FUNCTION__); \
}
#define EMIT_RI10(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
+void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI10(p, _op, rT, rA, imm, __FUNCTION__); \
}
#define EMIT_RI10s(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, unsigned rA, int imm) \
+void _name (struct spe_function *p, int rT, int rA, int imm) \
{ \
emit_RI10s(p, _op, rT, rA, imm, __FUNCTION__); \
}
#define EMIT_RI16(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, int imm) \
+void _name (struct spe_function *p, int rT, int imm) \
{ \
emit_RI16(p, _op, rT, imm, __FUNCTION__); \
}
#define EMIT_RI18(_name, _op) \
-void _name (struct spe_function *p, unsigned rT, int imm) \
+void _name (struct spe_function *p, int rT, int imm) \
{ \
emit_RI18(p, _op, rT, imm, __FUNCTION__); \
}
@@ -424,7 +424,7 @@ void _name (struct spe_function *p, int imm) \
*/
void spe_init_func(struct spe_function *p, unsigned code_size)
{
- unsigned int i;
+ uint i;
if (!code_size)
code_size = 64;
@@ -503,6 +503,7 @@ int spe_allocate_register(struct spe_function *p, int reg)
*/
void spe_release_register(struct spe_function *p, int reg)
{
+ assert(reg >= 0);
assert(reg < SPE_NUM_REGS);
assert(p->regs[reg] == 1);
@@ -517,7 +518,7 @@ void spe_release_register(struct spe_function *p, int reg)
*/
void spe_allocate_register_set(struct spe_function *p)
{
- unsigned int i;
+ uint i;
/* Keep track of the set count. If it ever wraps around to 0,
* we're in trouble.
@@ -538,7 +539,7 @@ void spe_allocate_register_set(struct spe_function *p)
void spe_release_register_set(struct spe_function *p)
{
- unsigned int i;
+ uint i;
/* If the set count drops below zero, we're in trouble. */
assert(p->set_count > 0);
@@ -599,7 +600,7 @@ spe_comment(struct spe_function *p, int rel_indent, const char *s)
* Load quad word.
* NOTE: offset is in bytes and the least significant 4 bits must be zero!
*/
-void spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
+void spe_lqd(struct spe_function *p, int rT, int rA, int offset)
{
const boolean pSave = p->print;
@@ -624,7 +625,7 @@ void spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
* Store quad word.
* NOTE: offset is in bytes and the least significant 4 bits must be zero!
*/
-void spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
+void spe_stqd(struct spe_function *p, int rT, int rA, int offset)
{
const boolean pSave = p->print;
@@ -653,51 +654,51 @@ void spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset)
*/
/** Branch Indirect to address in rA */
-void spe_bi(struct spe_function *p, unsigned rA, int d, int e)
+void spe_bi(struct spe_function *p, int rA, int d, int e)
{
emit_RI7(p, 0x1a8, 0, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Interupt Return */
-void spe_iret(struct spe_function *p, unsigned rA, int d, int e)
+void spe_iret(struct spe_function *p, int rA, int d, int e)
{
emit_RI7(p, 0x1aa, 0, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect and set link on external data */
-void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA, int d,
+void spe_bisled(struct spe_function *p, int rT, int rA, int d,
int e)
{
emit_RI7(p, 0x1ab, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect and set link. Save PC in rT, jump to rA. */
-void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA, int d,
+void spe_bisl(struct spe_function *p, int rT, int rA, int d,
int e)
{
emit_RI7(p, 0x1a9, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if zero word. If rT.word[0]==0, jump to rA. */
-void spe_biz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
+void spe_biz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x128, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if non-zero word. If rT.word[0]!=0, jump to rA. */
-void spe_binz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
+void spe_binz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x129, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if zero halfword. If rT.halfword[1]==0, jump to rA. */
-void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
+void spe_bihz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x12a, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
/** Branch indirect if non-zero halfword. If rT.halfword[1]!=0, jump to rA. */
-void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA, int d, int e)
+void spe_bihnz(struct spe_function *p, int rT, int rA, int d, int e)
{
emit_RI7(p, 0x12b, rT, rA, (d << 5) | (e << 4), __FUNCTION__);
}
@@ -733,7 +734,7 @@ EMIT_R (spe_mtspr, 0x10c);
void
-spe_load_float(struct spe_function *p, unsigned rT, float x)
+spe_load_float(struct spe_function *p, int rT, float x)
{
if (x == 0.0f) {
spe_il(p, rT, 0x0);
@@ -760,7 +761,7 @@ spe_load_float(struct spe_function *p, unsigned rT, float x)
void
-spe_load_int(struct spe_function *p, unsigned rT, int i)
+spe_load_int(struct spe_function *p, int rT, int i)
{
if (-32768 <= i && i <= 32767) {
spe_il(p, rT, i);
@@ -772,7 +773,7 @@ spe_load_int(struct spe_function *p, unsigned rT, int i)
}
}
-void spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui)
+void spe_load_uint(struct spe_function *p, int rT, uint ui)
{
/* If the whole value is in the lower 18 bits, use ila, which
* doesn't sign-extend. Otherwise, if the two halfwords of
@@ -793,7 +794,7 @@ void spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui)
((ui & 0x00ff0000) == 0 || (ui & 0x00ff0000) == 0x00ff0000) &&
((ui & 0xff000000) == 0 || (ui & 0xff000000) == 0xff000000)
) {
- unsigned int mask = 0;
+ uint mask = 0;
/* fsmbi duplicates each bit in the given mask eight times,
* using a 16-bit value to initialize a 16-byte quadword.
* Each 4-bit nybble of the mask corresponds to a full word
@@ -822,7 +823,7 @@ void spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui)
* Changes to one should be made in the other.
*/
void
-spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
+spe_and_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If we can, emit a single instruction, either And Byte Immediate
* (which uses the same constant across each byte), And Halfword Immediate
@@ -832,7 +833,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
*
* Otherwise, we'll need to use a temporary register.
*/
- unsigned int tmp;
+ uint tmp;
/* If the upper 23 bits are all 0s or all 1s, sign extension
* will work and we can use And Word Immediate
@@ -863,7 +864,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
}
/* Otherwise, we'll have to use a temporary register. */
- unsigned int tmp_reg = spe_allocate_available_register(p);
+ int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_and(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
@@ -875,7 +876,7 @@ spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
* Changes to one should be made in the other.
*/
void
-spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
+spe_xor_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If we can, emit a single instruction, either Exclusive Or Byte
* Immediate (which uses the same constant across each byte), Exclusive
@@ -885,7 +886,7 @@ spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
*
* Otherwise, we'll need to use a temporary register.
*/
- unsigned int tmp;
+ uint tmp;
/* If the upper 23 bits are all 0s or all 1s, sign extension
* will work and we can use Exclusive Or Word Immediate
@@ -916,14 +917,14 @@ spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
}
/* Otherwise, we'll have to use a temporary register. */
- unsigned int tmp_reg = spe_allocate_available_register(p);
+ int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_xor(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
}
void
-spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
+spe_compare_equal_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If the comparison value is 9 bits or less, it fits inside a
* Compare Equal Word Immediate instruction.
@@ -933,7 +934,7 @@ spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigne
}
/* Otherwise, we're going to have to load a word first. */
else {
- unsigned int tmp_reg = spe_allocate_available_register(p);
+ int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_ceq(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
@@ -941,7 +942,7 @@ spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigne
}
void
-spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui)
+spe_compare_greater_uint(struct spe_function *p, int rT, int rA, uint ui)
{
/* If the comparison value is 10 bits or less, it fits inside a
* Compare Logical Greater Than Word Immediate instruction.
@@ -951,7 +952,7 @@ spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsig
}
/* Otherwise, we're going to have to load a word first. */
else {
- unsigned int tmp_reg = spe_allocate_available_register(p);
+ int tmp_reg = spe_allocate_available_register(p);
spe_load_uint(p, tmp_reg, ui);
spe_clgt(p, rT, rA, tmp_reg);
spe_release_register(p, tmp_reg);
@@ -959,10 +960,10 @@ spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsig
}
void
-spe_splat(struct spe_function *p, unsigned rT, unsigned rA)
+spe_splat(struct spe_function *p, int rT, int rA)
{
/* Use a temporary, just in case rT == rA */
- unsigned int tmp_reg = spe_allocate_available_register(p);
+ int tmp_reg = spe_allocate_available_register(p);
/* Duplicate bytes 0, 1, 2, and 3 across the whole register */
spe_ila(p, tmp_reg, 0x00010203);
spe_shufb(p, rT, rA, rA, tmp_reg);
@@ -971,14 +972,14 @@ spe_splat(struct spe_function *p, unsigned rT, unsigned rA)
void
-spe_complement(struct spe_function *p, unsigned rT, unsigned rA)
+spe_complement(struct spe_function *p, int rT, int rA)
{
spe_nor(p, rT, rA, rA);
}
void
-spe_move(struct spe_function *p, unsigned rT, unsigned rA)
+spe_move(struct spe_function *p, int rT, int rA)
{
/* Use different instructions depending on the instruction address
* to take advantage of the dual pipelines.
@@ -991,14 +992,14 @@ spe_move(struct spe_function *p, unsigned rT, unsigned rA)
void
-spe_zero(struct spe_function *p, unsigned rT)
+spe_zero(struct spe_function *p, int rT)
{
spe_xor(p, rT, rT, rT);
}
void
-spe_splat_word(struct spe_function *p, unsigned rT, unsigned rA, int word)
+spe_splat_word(struct spe_function *p, int rT, int rA, int word)
{
assert(word >= 0);
assert(word <= 3);
@@ -1038,9 +1039,9 @@ spe_splat_word(struct spe_function *p, unsigned rT, unsigned rA, int word)
* like "x = min(x, a)", we always allocate a new register to be safe.
*/
void
-spe_float_min(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB)
+spe_float_min(struct spe_function *p, int rT, int rA, int rB)
{
- unsigned int compare_reg = spe_allocate_available_register(p);
+ int compare_reg = spe_allocate_available_register(p);
spe_fcgt(p, compare_reg, rA, rB);
spe_selb(p, rT, rA, rB, compare_reg);
spe_release_register(p, compare_reg);
@@ -1055,9 +1056,9 @@ spe_float_min(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB)
* so that the larger of the two is selected instead of the smaller.
*/
void
-spe_float_max(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB)
+spe_float_max(struct spe_function *p, int rT, int rA, int rB)
{
- unsigned int compare_reg = spe_allocate_available_register(p);
+ int compare_reg = spe_allocate_available_register(p);
spe_fcgt(p, compare_reg, rA, rB);
spe_selb(p, rT, rB, rA, compare_reg);
spe_release_register(p, compare_reg);
diff --git a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h
index f9ad2acacd..65d9c77415 100644
--- a/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h
+++ b/src/gallium/auxiliary/rtasm/rtasm_ppc_spe.h
@@ -79,9 +79,9 @@ struct spe_function
};
-extern void spe_init_func(struct spe_function *p, unsigned code_size);
+extern void spe_init_func(struct spe_function *p, uint code_size);
extern void spe_release_func(struct spe_function *p);
-extern unsigned spe_code_size(const struct spe_function *p);
+extern uint spe_code_size(const struct spe_function *p);
extern int spe_allocate_available_register(struct spe_function *p);
extern int spe_allocate_register(struct spe_function *p, int reg);
@@ -89,8 +89,7 @@ extern void spe_release_register(struct spe_function *p, int reg);
extern void spe_allocate_register_set(struct spe_function *p);
extern void spe_release_register_set(struct spe_function *p);
-extern unsigned
-spe_get_registers_used(const struct spe_function *p, ubyte used[]);
+extern uint spe_get_registers_used(const struct spe_function *p, ubyte used[]);
extern void spe_print_code(struct spe_function *p, boolean enable);
extern void spe_indent(struct spe_function *p, int spaces);
@@ -103,31 +102,25 @@ extern void spe_comment(struct spe_function *p, int rel_indent, const char *s);
#define EMIT(_name, _op) \
extern void _name (struct spe_function *p);
#define EMIT_(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT);
+ extern void _name (struct spe_function *p, int rT);
#define EMIT_R(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA);
+ extern void _name (struct spe_function *p, int rT, int rA);
#define EMIT_RR(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
- unsigned rB);
+ extern void _name (struct spe_function *p, int rT, int rA, int rB);
#define EMIT_RRR(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
- unsigned rB, unsigned rC);
+ extern void _name (struct spe_function *p, int rT, int rA, int rB, int rC);
#define EMIT_RI7(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
- int imm);
+ extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI8(_name, _op, bias) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
- int imm);
+ extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI10(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
- int imm);
+ extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI10s(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, unsigned rA, \
- int imm);
+ extern void _name (struct spe_function *p, int rT, int rA, int imm);
#define EMIT_RI16(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, int imm);
+ extern void _name (struct spe_function *p, int rT, int imm);
#define EMIT_RI18(_name, _op) \
- extern void _name (struct spe_function *p, unsigned rT, int imm);
+ extern void _name (struct spe_function *p, int rT, int imm);
#define EMIT_I16(_name, _op) \
extern void _name (struct spe_function *p, int imm);
#define UNDEF_EMIT_MACROS
@@ -301,82 +294,82 @@ EMIT_RI16(spe_brhz, 0x044)
EMIT (spe_lnop, 0x001)
extern void
-spe_lqd(struct spe_function *p, unsigned rT, unsigned rA, int offset);
+spe_lqd(struct spe_function *p, int rT, int rA, int offset);
extern void
-spe_stqd(struct spe_function *p, unsigned rT, unsigned rA, int offset);
+spe_stqd(struct spe_function *p, int rT, int rA, int offset);
-extern void spe_bi(struct spe_function *p, unsigned rA, int d, int e);
-extern void spe_iret(struct spe_function *p, unsigned rA, int d, int e);
-extern void spe_bisled(struct spe_function *p, unsigned rT, unsigned rA,
+extern void spe_bi(struct spe_function *p, int rA, int d, int e);
+extern void spe_iret(struct spe_function *p, int rA, int d, int e);
+extern void spe_bisled(struct spe_function *p, int rT, int rA,
int d, int e);
-extern void spe_bisl(struct spe_function *p, unsigned rT, unsigned rA,
+extern void spe_bisl(struct spe_function *p, int rT, int rA,
int d, int e);
-extern void spe_biz(struct spe_function *p, unsigned rT, unsigned rA,
+extern void spe_biz(struct spe_function *p, int rT, int rA,
int d, int e);
-extern void spe_binz(struct spe_function *p, unsigned rT, unsigned rA,
+extern void spe_binz(struct spe_function *p, int rT, int rA,
int d, int e);
-extern void spe_bihz(struct spe_function *p, unsigned rT, unsigned rA,
+extern void spe_bihz(struct spe_function *p, int rT, int rA,
int d, int e);
-extern void spe_bihnz(struct spe_function *p, unsigned rT, unsigned rA,
+extern void spe_bihnz(struct spe_function *p, int rT, int rA,
int d, int e);
/** Load/splat immediate float into rT. */
extern void
-spe_load_float(struct spe_function *p, unsigned rT, float x);
+spe_load_float(struct spe_function *p, int rT, float x);
/** Load/splat immediate int into rT. */
extern void
-spe_load_int(struct spe_function *p, unsigned rT, int i);
+spe_load_int(struct spe_function *p, int rT, int i);
/** Load/splat immediate unsigned int into rT. */
extern void
-spe_load_uint(struct spe_function *p, unsigned rT, unsigned int ui);
+spe_load_uint(struct spe_function *p, int rT, uint ui);
/** And immediate value into rT. */
extern void
-spe_and_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
+spe_and_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Xor immediate value into rT. */
extern void
-spe_xor_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
+spe_xor_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Compare equal with immediate value. */
extern void
-spe_compare_equal_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
+spe_compare_equal_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Compare greater with immediate value. */
extern void
-spe_compare_greater_uint(struct spe_function *p, unsigned rT, unsigned rA, unsigned int ui);
+spe_compare_greater_uint(struct spe_function *p, int rT, int rA, uint ui);
/** Replicate word 0 of rA across rT. */
extern void
-spe_splat(struct spe_function *p, unsigned rT, unsigned rA);
+spe_splat(struct spe_function *p, int rT, int rA);
/** rT = complement_all_bits(rA). */
extern void
-spe_complement(struct spe_function *p, unsigned rT, unsigned rA);
+spe_complement(struct spe_function *p, int rT, int rA);
/** rT = rA. */
extern void
-spe_move(struct spe_function *p, unsigned rT, unsigned rA);
+spe_move(struct spe_function *p, int rT, int rA);
/** rT = {0,0,0,0}. */
extern void
-spe_zero(struct spe_function *p, unsigned rT);
+spe_zero(struct spe_function *p, int rT);
/** rT = splat(rA, word) */
extern void
-spe_splat_word(struct spe_function *p, unsigned rT, unsigned rA, int word);
+spe_splat_word(struct spe_function *p, int rT, int rA, int word);
/** rT = float min(rA, rB) */
extern void
-spe_float_min(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB);
+spe_float_min(struct spe_function *p, int rT, int rA, int rB);
/** rT = float max(rA, rB) */
extern void
-spe_float_max(struct spe_function *p, unsigned rT, unsigned rA, unsigned rB);
+spe_float_max(struct spe_function *p, int rT, int rA, int rB);
/* Floating-point instructions
diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h
index 626b13af83..1a6b596421 100644
--- a/src/gallium/auxiliary/util/u_memory.h
+++ b/src/gallium/auxiliary/util/u_memory.h
@@ -52,7 +52,7 @@ extern "C" {
#endif
-#if defined(PIPE_OS_WINDOWS) && defined(DEBUG)
+#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) && defined(DEBUG)
/* memory debugging */
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index 98554d7f52..1f6860da11 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -49,6 +49,15 @@
}
+
+#define JOIN(x, y) JOIN_AGAIN(x, y)
+#define JOIN_AGAIN(x, y) x ## y
+
+#define STATIC_ASSERT(e) \
+{typedef char JOIN(assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1];}
+
+
+
/** for sanity checking */
#define ASSERT_ALIGN16(ptr) \
ASSERT((((unsigned long) (ptr)) & 0xf) == 0);
@@ -134,6 +143,11 @@ struct cell_fence
volatile uint status[CELL_MAX_SPUS][4];
};
+#ifdef __SPU__
+typedef vector unsigned int opcode_t;
+#else
+typedef unsigned int opcode_t[4];
+#endif
/**
* Fence command sent to SPUs. In response, the SPUs will write
@@ -141,8 +155,9 @@ struct cell_fence
*/
struct cell_command_fence
{
- uint64_t opcode; /**< CELL_CMD_FENCE */
+ opcode_t opcode; /**< CELL_CMD_FENCE */
struct cell_fence *fence;
+ uint32_t pad_[3];
};
@@ -163,7 +178,7 @@ struct cell_command_fence
*/
struct cell_command_fragment_ops
{
- uint64_t opcode; /**< CELL_CMD_STATE_FRAGMENT_OPS */
+ opcode_t opcode; /**< CELL_CMD_STATE_FRAGMENT_OPS */
/* Fields for the fallback case */
struct pipe_depth_stencil_alpha_state dsa;
@@ -189,8 +204,9 @@ struct cell_command_fragment_ops
*/
struct cell_command_fragment_program
{
- uint64_t opcode; /**< CELL_CMD_STATE_FRAGMENT_PROGRAM */
+ opcode_t opcode; /**< CELL_CMD_STATE_FRAGMENT_PROGRAM */
uint num_inst; /**< Number of instructions */
+ uint32_t pad[3];
unsigned code[SPU_MAX_FRAGMENT_PROGRAM_INSTS];
};
@@ -200,10 +216,11 @@ struct cell_command_fragment_program
*/
struct cell_command_framebuffer
{
- uint64_t opcode; /**< CELL_CMD_STATE_FRAMEBUFFER */
+ opcode_t opcode; /**< CELL_CMD_STATE_FRAMEBUFFER */
int width, height;
void *color_start, *depth_start;
enum pipe_format color_format, depth_format;
+ uint32_t pad_[2];
};
@@ -212,7 +229,7 @@ struct cell_command_framebuffer
*/
struct cell_command_rasterizer
{
- uint64_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
+ opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
struct pipe_rasterizer_state rasterizer;
};
@@ -222,9 +239,10 @@ struct cell_command_rasterizer
*/
struct cell_command_clear_surface
{
- uint64_t opcode; /**< CELL_CMD_CLEAR_SURFACE */
+ opcode_t opcode; /**< CELL_CMD_CLEAR_SURFACE */
uint surface; /**< Temporary: 0=color, 1=Z */
uint value;
+ uint32_t pad[2];
};
@@ -271,7 +289,7 @@ struct cell_shader_info
#define SPU_VERTS_PER_BATCH 64
struct cell_command_vs
{
- uint64_t opcode; /**< CELL_CMD_VS_EXECUTE */
+ opcode_t opcode; /**< CELL_CMD_VS_EXECUTE */
uint64_t vOut[SPU_VERTS_PER_BATCH];
unsigned num_elts;
unsigned elts[SPU_VERTS_PER_BATCH];
@@ -283,7 +301,7 @@ struct cell_command_vs
struct cell_command_render
{
- uint64_t opcode; /**< CELL_CMD_RENDER */
+ opcode_t opcode; /**< CELL_CMD_RENDER */
uint prim_type; /**< PIPE_PRIM_x */
uint num_verts;
uint vertex_size; /**< bytes per vertex */
@@ -292,27 +310,30 @@ struct cell_command_render
float xmin, ymin, xmax, ymax; /* XXX another dummy field */
uint min_index;
boolean inline_verts;
+ uint32_t pad_[1];
};
struct cell_command_release_verts
{
- uint64_t opcode; /**< CELL_CMD_RELEASE_VERTS */
+ opcode_t opcode; /**< CELL_CMD_RELEASE_VERTS */
uint vertex_buf; /**< in [0, CELL_NUM_BUFFERS-1] */
+ uint32_t pad_[3];
};
struct cell_command_sampler
{
- uint64_t opcode; /**< CELL_CMD_STATE_SAMPLER */
+ opcode_t opcode; /**< CELL_CMD_STATE_SAMPLER */
uint unit;
struct pipe_sampler_state state;
+ uint32_t pad_[1];
};
struct cell_command_texture
{
- uint64_t opcode; /**< CELL_CMD_STATE_TEXTURE */
+ opcode_t opcode; /**< CELL_CMD_STATE_TEXTURE */
uint target; /**< PIPE_TEXTURE_x */
uint unit;
void *start[CELL_MAX_TEXTURE_LEVELS]; /**< Address in main memory */
diff --git a/src/gallium/drivers/cell/ppu/cell_batch.c b/src/gallium/drivers/cell/ppu/cell_batch.c
index 962775cd33..fe144f8b84 100644
--- a/src/gallium/drivers/cell/ppu/cell_batch.c
+++ b/src/gallium/drivers/cell/ppu/cell_batch.c
@@ -108,15 +108,16 @@ emit_fence(struct cell_context *cell)
fence->status[i][0] = CELL_FENCE_EMITTED;
}
+ STATIC_ASSERT(sizeof(struct cell_command_fence) % 16 == 0);
+ ASSERT(size % 16 == 0);
ASSERT(size + sizeof(struct cell_command_fence) <= CELL_BUFFER_SIZE);
fence_cmd = (struct cell_command_fence *) (cell->buffer[batch] + size);
- fence_cmd->opcode = CELL_CMD_FENCE;
+ fence_cmd->opcode[0] = CELL_CMD_FENCE;
fence_cmd->fence = fence;
/* update batch buffer size */
cell->buffer_size[batch] = size + sizeof(struct cell_command_fence);
- assert(sizeof(struct cell_command_fence) % 8 == 0);
}
@@ -192,69 +193,18 @@ cell_batch_free_space(const struct cell_context *cell)
/**
- * Append data to the current batch buffer.
- * \param data address of block of bytes to append
- * \param bytes size of block of bytes
- */
-void
-cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
-{
- uint size;
-
- ASSERT(bytes % 8 == 0);
- ASSERT(bytes <= CELL_BUFFER_SIZE);
- ASSERT(cell->cur_batch >= 0);
-
-#ifdef ASSERT
- {
- uint spu;
- for (spu = 0; spu < cell->num_spus; spu++) {
- ASSERT(cell->buffer_status[spu][cell->cur_batch][0]
- == CELL_BUFFER_STATUS_USED);
- }
- }
-#endif
-
- size = cell->buffer_size[cell->cur_batch];
-
- if (bytes > cell_batch_free_space(cell)) {
- cell_batch_flush(cell);
- size = 0;
- }
-
- ASSERT(size + bytes <= CELL_BUFFER_SIZE);
-
- memcpy(cell->buffer[cell->cur_batch] + size, data, bytes);
-
- cell->buffer_size[cell->cur_batch] = size + bytes;
-}
-
-
-/**
* Allocate space in the current batch buffer for 'bytes' space.
+ * Bytes must be a multiple of 16 bytes. Allocation will be 16 byte aligned.
* \return address in batch buffer to put data
*/
void *
-cell_batch_alloc(struct cell_context *cell, uint bytes)
-{
- return cell_batch_alloc_aligned(cell, bytes, 1);
-}
-
-
-/**
- * Same as \sa cell_batch_alloc, but return an address at a particular
- * alignment.
- */
-void *
-cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
- uint alignment)
+cell_batch_alloc16(struct cell_context *cell, uint bytes)
{
void *pos;
- uint size, padbytes;
+ uint size;
- ASSERT(bytes % 8 == 0);
+ ASSERT(bytes % 16 == 0);
ASSERT(bytes <= CELL_BUFFER_SIZE);
- ASSERT(alignment > 0);
ASSERT(cell->cur_batch >= 0);
#ifdef ASSERT
@@ -269,17 +219,12 @@ cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
size = cell->buffer_size[cell->cur_batch];
- padbytes = (alignment - (size % alignment)) % alignment;
-
- if (padbytes + bytes > cell_batch_free_space(cell)) {
+ if (bytes > cell_batch_free_space(cell)) {
cell_batch_flush(cell);
size = 0;
}
- else {
- size += padbytes;
- }
- ASSERT(size % alignment == 0);
+ ASSERT(size % 16 == 0);
ASSERT(size + bytes <= CELL_BUFFER_SIZE);
pos = (void *) (cell->buffer[cell->cur_batch] + size);
diff --git a/src/gallium/drivers/cell/ppu/cell_batch.h b/src/gallium/drivers/cell/ppu/cell_batch.h
index f74dd60079..290136031a 100644
--- a/src/gallium/drivers/cell/ppu/cell_batch.h
+++ b/src/gallium/drivers/cell/ppu/cell_batch.h
@@ -44,15 +44,8 @@ cell_batch_flush(struct cell_context *cell);
extern uint
cell_batch_free_space(const struct cell_context *cell);
-extern void
-cell_batch_append(struct cell_context *cell, const void *data, uint bytes);
-
-extern void *
-cell_batch_alloc(struct cell_context *cell, uint bytes);
-
extern void *
-cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
- uint alignment);
+cell_batch_alloc16(struct cell_context *cell, uint bytes);
extern void
cell_init_batch_buffers(struct cell_context *cell);
diff --git a/src/gallium/drivers/cell/ppu/cell_clear.c b/src/gallium/drivers/cell/ppu/cell_clear.c
index 037635e466..c2e276988c 100644
--- a/src/gallium/drivers/cell/ppu/cell_clear.c
+++ b/src/gallium/drivers/cell/ppu/cell_clear.c
@@ -99,10 +99,11 @@ cell_clear_surface(struct pipe_context *pipe, struct pipe_surface *ps,
/* Build a CLEAR command and place it in the current batch buffer */
{
+ STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0);
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *)
- cell_batch_alloc(cell, sizeof(*clr));
- clr->opcode = CELL_CMD_CLEAR_SURFACE;
+ cell_batch_alloc16(cell, sizeof(*clr));
+ clr->opcode[0] = CELL_CMD_CLEAR_SURFACE;
clr->surface = surfIndex;
clr->value = clearValue;
}
diff --git a/src/gallium/drivers/cell/ppu/cell_flush.c b/src/gallium/drivers/cell/ppu/cell_flush.c
index a64967b4b9..8275c9dc9c 100644
--- a/src/gallium/drivers/cell/ppu/cell_flush.c
+++ b/src/gallium/drivers/cell/ppu/cell_flush.c
@@ -72,8 +72,9 @@ cell_flush_int(struct cell_context *cell, unsigned flags)
flushing = TRUE;
if (flags & CELL_FLUSH_WAIT) {
- uint64_t *cmd = (uint64_t *) cell_batch_alloc(cell, sizeof(uint64_t));
- *cmd = CELL_CMD_FINISH;
+ STATIC_ASSERT(sizeof(opcode_t) % 16 == 0);
+ opcode_t *cmd = (opcode_t*) cell_batch_alloc16(cell, sizeof(opcode_t));
+ *cmd[0] = CELL_CMD_FINISH;
}
cell_batch_flush(cell);
@@ -101,11 +102,11 @@ void
cell_flush_buffer_range(struct cell_context *cell, void *ptr,
unsigned size)
{
- uint64_t batch[1 + (ROUNDUP8(sizeof(struct cell_buffer_range)) / 8)];
- struct cell_buffer_range *br = (struct cell_buffer_range *) & batch[1];
-
+ STATIC_ASSERT((sizeof(opcode_t) + sizeof(struct cell_buffer_range)) % 16 == 0);
+ uint32_t *batch = (uint32_t*)cell_batch_alloc16(cell,
+ sizeof(opcode_t) + sizeof(struct cell_buffer_range));
+ struct cell_buffer_range *br = (struct cell_buffer_range *) &batch[4];
batch[0] = CELL_CMD_FLUSH_BUFFER_RANGE;
br->base = (uintptr_t) ptr;
br->size = size;
- cell_batch_append(cell, batch, sizeof(batch));
}
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
index 2c64eb1bcc..0ea8f017ef 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c
@@ -2,6 +2,7 @@
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
+ * 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
@@ -25,11 +26,10 @@
*
**************************************************************************/
-
-
/**
* Generate SPU per-fragment code (actually per-quad code).
* \author Brian Paul
+ * \author Bob Ellison
*/
@@ -55,7 +55,7 @@
* \param ifbZ_reg register containing integer frame buffer Z values (in/out)
* \param zmask_reg register containing result of Z test/comparison (out)
*
- * Returns true if the Z-buffer needs to be updated.
+ * Returns TRUE if the Z-buffer needs to be updated.
*/
static boolean
gen_depth_test(struct spe_function *f,
@@ -134,10 +134,10 @@ gen_depth_test(struct spe_function *f,
* framebufferZ = (ztest_passed ? fragmentZ : framebufferZ;
*/
spe_selb(f, ifbZ_reg, ifbZ_reg, ifragZ_reg, mask_reg);
- return true;
+ return TRUE;
}
- return false;
+ return FALSE;
}
@@ -237,41 +237,136 @@ gen_alpha_test(const struct pipe_depth_stencil_alpha_state *dsa,
spe_release_register(f, amask_reg);
}
-/* This pair of functions is used inline to allocate and deallocate
+
+/**
+ * This pair of functions is used inline to allocate and deallocate
* optional constant registers. Once a constant is discovered to be
* needed, we will likely need it again, so we don't want to deallocate
* it and have to allocate and load it again unnecessarily.
*/
-static inline void
-setup_optional_register(struct spe_function *f, boolean *is_already_set, unsigned int *r)
+static INLINE void
+setup_optional_register(struct spe_function *f,
+ int *r)
{
- if (*is_already_set) return;
- *r = spe_allocate_available_register(f);
- *is_already_set = true;
+ if (*r < 0)
+ *r = spe_allocate_available_register(f);
}
-static inline void
-release_optional_register(struct spe_function *f, boolean *is_already_set, unsigned int r)
+static INLINE void
+release_optional_register(struct spe_function *f,
+ int r)
{
- if (!*is_already_set) return;
- spe_release_register(f, r);
- *is_already_set = false;
+ if (r >= 0)
+ spe_release_register(f, r);
}
-static inline void
-setup_const_register(struct spe_function *f, boolean *is_already_set, unsigned int *r, float value)
+static INLINE void
+setup_const_register(struct spe_function *f,
+ int *r,
+ float value)
{
- if (*is_already_set) return;
- setup_optional_register(f, is_already_set, r);
+ if (*r >= 0)
+ return;
+ setup_optional_register(f, r);
spe_load_float(f, *r, value);
}
-static inline void
-release_const_register(struct spe_function *f, boolean *is_already_set, unsigned int r)
+static INLINE void
+release_const_register(struct spe_function *f,
+ int r)
{
- release_optional_register(f, is_already_set, r);
+ release_optional_register(f, r);
}
+
+
+/**
+ * Unpack/convert framebuffer colors from four 32-bit packed colors
+ * (fbRGBA) to four float RGBA vectors (fbR, fbG, fbB, fbA).
+ * Each 8-bit color component is expanded into a float in [0.0, 1.0].
+ */
+static void
+unpack_colors(struct spe_function *f,
+ enum pipe_format color_format,
+ int fbRGBA_reg,
+ int fbR_reg, int fbG_reg, int fbB_reg, int fbA_reg)
+{
+ int mask0_reg = spe_allocate_available_register(f);
+ int mask1_reg = spe_allocate_available_register(f);
+ int mask2_reg = spe_allocate_available_register(f);
+ int mask3_reg = spe_allocate_available_register(f);
+
+ spe_load_int(f, mask0_reg, 0xff);
+ spe_load_int(f, mask1_reg, 0xff00);
+ spe_load_int(f, mask2_reg, 0xff0000);
+ spe_load_int(f, mask3_reg, 0xff000000);
+
+ spe_comment(f, 0, "Unpack framebuffer colors, convert to floats");
+
+ switch (color_format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ /* fbB = fbRGBA & mask */
+ spe_and(f, fbB_reg, fbRGBA_reg, mask0_reg);
+
+ /* fbG = fbRGBA & mask */
+ spe_and(f, fbG_reg, fbRGBA_reg, mask1_reg);
+
+ /* fbR = fbRGBA & mask */
+ spe_and(f, fbR_reg, fbRGBA_reg, mask2_reg);
+
+ /* fbA = fbRGBA & mask */
+ spe_and(f, fbA_reg, fbRGBA_reg, mask3_reg);
+
+ /* fbG = fbG >> 8 */
+ spe_roti(f, fbG_reg, fbG_reg, -8);
+
+ /* fbR = fbR >> 16 */
+ spe_roti(f, fbR_reg, fbR_reg, -16);
+
+ /* fbA = fbA >> 24 */
+ spe_roti(f, fbA_reg, fbA_reg, -24);
+ break;
+
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ /* fbA = fbRGBA & mask */
+ spe_and(f, fbA_reg, fbRGBA_reg, mask0_reg);
+
+ /* fbR = fbRGBA & mask */
+ spe_and(f, fbR_reg, fbRGBA_reg, mask1_reg);
+
+ /* fbG = fbRGBA & mask */
+ spe_and(f, fbG_reg, fbRGBA_reg, mask2_reg);
+
+ /* fbB = fbRGBA & mask */
+ spe_and(f, fbB_reg, fbRGBA_reg, mask3_reg);
+
+ /* fbR = fbR >> 8 */
+ spe_roti(f, fbR_reg, fbR_reg, -8);
+
+ /* fbG = fbG >> 16 */
+ spe_roti(f, fbG_reg, fbG_reg, -16);
+
+ /* fbB = fbB >> 24 */
+ spe_roti(f, fbB_reg, fbB_reg, -24);
+ break;
+
+ default:
+ ASSERT(0);
+ }
+
+ /* convert int[4] in [0,255] to float[4] in [0.0, 1.0] */
+ spe_cuflt(f, fbR_reg, fbR_reg, 8);
+ spe_cuflt(f, fbG_reg, fbG_reg, 8);
+ spe_cuflt(f, fbB_reg, fbB_reg, 8);
+ spe_cuflt(f, fbA_reg, fbA_reg, 8);
+
+ spe_release_register(f, mask0_reg);
+ spe_release_register(f, mask1_reg);
+ spe_release_register(f, mask2_reg);
+ spe_release_register(f, mask3_reg);
+}
+
+
/**
* Generate SPE code to implement the given blend mode for a quad of pixels.
* \param f SPE function to append instruction onto.
@@ -310,90 +405,14 @@ gen_blend(const struct pipe_blend_state *blend,
* if we do use them, make sure we only allocate them once by
* keeping a flag on each one.
*/
- boolean one_reg_set = false;
- unsigned int one_reg;
- boolean constR_reg_set = false, constG_reg_set = false,
- constB_reg_set = false, constA_reg_set = false;
- unsigned int constR_reg, constG_reg, constB_reg, constA_reg;
+ int one_reg = -1;
+ int constR_reg = -1, constG_reg = -1, constB_reg = -1, constA_reg = -1;
ASSERT(blend->blend_enable);
- /* Unpack/convert framebuffer colors from four 32-bit packed colors
- * (fbRGBA) to four float RGBA vectors (fbR, fbG, fbB, fbA).
- * Each 8-bit color component is expanded into a float in [0.0, 1.0].
- */
- {
- int mask_reg = spe_allocate_available_register(f);
-
- /* mask = {0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff} */
- spe_load_int(f, mask_reg, 0xff);
-
- /* XXX there may be more clever ways to implement the following code */
- switch (color_format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- /* fbB = fbB & mask */
- spe_and(f, fbB_reg, fbRGBA_reg, mask_reg);
- /* mask = mask << 8 */
- spe_roti(f, mask_reg, mask_reg, 8);
-
- /* fbG = fbRGBA & mask */
- spe_and(f, fbG_reg, fbRGBA_reg, mask_reg);
- /* fbG = fbG >> 8 */
- spe_roti(f, fbG_reg, fbG_reg, -8);
- /* mask = mask << 8 */
- spe_roti(f, mask_reg, mask_reg, 8);
-
- /* fbR = fbRGBA & mask */
- spe_and(f, fbR_reg, fbRGBA_reg, mask_reg);
- /* fbR = fbR >> 16 */
- spe_roti(f, fbR_reg, fbR_reg, -16);
- /* mask = mask << 8 */
- spe_roti(f, mask_reg, mask_reg, 8);
-
- /* fbA = fbRGBA & mask */
- spe_and(f, fbA_reg, fbRGBA_reg, mask_reg);
- /* fbA = fbA >> 24 */
- spe_roti(f, fbA_reg, fbA_reg, -24);
- break;
-
- case PIPE_FORMAT_B8G8R8A8_UNORM:
- /* fbA = fbA & mask */
- spe_and(f, fbA_reg, fbRGBA_reg, mask_reg);
- /* mask = mask << 8 */
- spe_roti(f, mask_reg, mask_reg, 8);
-
- /* fbR = fbRGBA & mask */
- spe_and(f, fbR_reg, fbRGBA_reg, mask_reg);
- /* fbR = fbR >> 8 */
- spe_roti(f, fbR_reg, fbR_reg, -8);
- /* mask = mask << 8 */
- spe_roti(f, mask_reg, mask_reg, 8);
-
- /* fbG = fbRGBA & mask */
- spe_and(f, fbG_reg, fbRGBA_reg, mask_reg);
- /* fbG = fbG >> 16 */
- spe_roti(f, fbG_reg, fbG_reg, -16);
- /* mask = mask << 8 */
- spe_roti(f, mask_reg, mask_reg, 8);
-
- /* fbB = fbRGBA & mask */
- spe_and(f, fbB_reg, fbRGBA_reg, mask_reg);
- /* fbB = fbB >> 24 */
- spe_roti(f, fbB_reg, fbB_reg, -24);
- break;
-
- default:
- ASSERT(0);
- }
-
- /* convert int[4] in [0,255] to float[4] in [0.0, 1.0] */
- spe_cuflt(f, fbR_reg, fbR_reg, 8);
- spe_cuflt(f, fbG_reg, fbG_reg, 8);
- spe_cuflt(f, fbB_reg, fbB_reg, 8);
- spe_cuflt(f, fbA_reg, fbA_reg, 8);
-
- spe_release_register(f, mask_reg);
- }
+ /* packed RGBA -> float colors */
+ unpack_colors(f, color_format, fbRGBA_reg,
+ fbR_reg, fbG_reg, fbB_reg, fbA_reg);
/*
* Compute Src RGB terms. We're actually looking for the value
@@ -476,9 +495,9 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
/* We need the optional constant color registers */
- setup_const_register(f, &constR_reg_set, &constR_reg, blend_color->color[0]);
- setup_const_register(f, &constG_reg_set, &constG_reg, blend_color->color[1]);
- setup_const_register(f, &constB_reg_set, &constB_reg, blend_color->color[2]);
+ setup_const_register(f, &constR_reg, blend_color->color[0]);
+ setup_const_register(f, &constG_reg, blend_color->color[1]);
+ setup_const_register(f, &constB_reg, blend_color->color[2]);
/* now, factor = (Rc,Gc,Bc), so term = (R*Rc,G*Gc,B*Bc) */
spe_fm(f, term1R_reg, fragR_reg, constR_reg);
spe_fm(f, term1G_reg, fragG_reg, constG_reg);
@@ -486,7 +505,7 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_CONST_ALPHA:
/* we'll need the optional constant alpha register */
- setup_const_register(f, &constA_reg_set, &constA_reg, blend_color->color[3]);
+ setup_const_register(f, &constA_reg, blend_color->color[3]);
/* factor = (Ac,Ac,Ac), so term = (R*Ac,G*Ac,B*Ac) */
spe_fm(f, term1R_reg, fragR_reg, constA_reg);
spe_fm(f, term1G_reg, fragG_reg, constA_reg);
@@ -494,9 +513,9 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
/* We need the optional constant color registers */
- setup_const_register(f, &constR_reg_set, &constR_reg, blend_color->color[0]);
- setup_const_register(f, &constG_reg_set, &constG_reg, blend_color->color[1]);
- setup_const_register(f, &constB_reg_set, &constB_reg, blend_color->color[2]);
+ setup_const_register(f, &constR_reg, blend_color->color[0]);
+ setup_const_register(f, &constG_reg, blend_color->color[1]);
+ setup_const_register(f, &constB_reg, blend_color->color[2]);
/* factor = (1-Rc,1-Gc,1-Bc), so term = (R*(1-Rc),G*(1-Gc),B*(1-Bc))
* or term = (R-R*Rc, G-G*Gc, B-B*Bc)
* fnms(a,b,c,d) computes a = d - b*c
@@ -507,9 +526,9 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
/* We need the optional constant color registers */
- setup_const_register(f, &constR_reg_set, &constR_reg, blend_color->color[0]);
- setup_const_register(f, &constG_reg_set, &constG_reg, blend_color->color[1]);
- setup_const_register(f, &constB_reg_set, &constB_reg, blend_color->color[2]);
+ setup_const_register(f, &constR_reg, blend_color->color[0]);
+ setup_const_register(f, &constG_reg, blend_color->color[1]);
+ setup_const_register(f, &constB_reg, blend_color->color[2]);
/* factor = (1-Ac,1-Ac,1-Ac), so term = (R*(1-Ac),G*(1-Ac),B*(1-Ac))
* or term = (R-R*Ac,G-G*Ac,B-B*Ac)
* fnms(a,b,c,d) computes a = d - b*c
@@ -520,7 +539,7 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
/* We'll need the optional {1,1,1,1} register */
- setup_const_register(f, &one_reg_set, &one_reg, 1.0f);
+ setup_const_register(f, &one_reg, 1.0f);
/* factor = (min(A,1-Afb),min(A,1-Afb),min(A,1-Afb)), so
* term = (R*min(A,1-Afb), G*min(A,1-Afb), B*min(A,1-Afb))
* We could expand the term (as a*min(b,c) == min(a*b,a*c)
@@ -598,7 +617,7 @@ gen_blend(const struct pipe_blend_state *blend,
case PIPE_BLENDFACTOR_CONST_ALPHA: /* fall through */
case PIPE_BLENDFACTOR_CONST_COLOR:
/* We need the optional constA_reg register */
- setup_const_register(f, &constA_reg_set, &constA_reg, blend_color->color[3]);
+ setup_const_register(f, &constA_reg, blend_color->color[3]);
/* factor = Ac, so term = A*Ac */
spe_fm(f, term1A_reg, fragA_reg, constA_reg);
break;
@@ -606,7 +625,7 @@ gen_blend(const struct pipe_blend_state *blend,
case PIPE_BLENDFACTOR_INV_CONST_ALPHA: /* fall through */
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
/* We need the optional constA_reg register */
- setup_const_register(f, &constA_reg_set, &constA_reg, blend_color->color[3]);
+ setup_const_register(f, &constA_reg, blend_color->color[3]);
/* factor = 1-Ac, so term = A*(1-Ac) = A-A*Ac */
/* fnms(a,b,c,d) computes a = d - b*c */
spe_fnms(f, term1A_reg, fragA_reg, constA_reg, fragA_reg);
@@ -703,9 +722,9 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
/* We need the optional constant color registers */
- setup_const_register(f, &constR_reg_set, &constR_reg, blend_color->color[0]);
- setup_const_register(f, &constG_reg_set, &constG_reg, blend_color->color[1]);
- setup_const_register(f, &constB_reg_set, &constB_reg, blend_color->color[2]);
+ setup_const_register(f, &constR_reg, blend_color->color[0]);
+ setup_const_register(f, &constG_reg, blend_color->color[1]);
+ setup_const_register(f, &constB_reg, blend_color->color[2]);
/* now, factor = (Rc,Gc,Bc), so term = (Rfb*Rc,Gfb*Gc,Bfb*Bc) */
spe_fm(f, term2R_reg, fbR_reg, constR_reg);
spe_fm(f, term2G_reg, fbG_reg, constG_reg);
@@ -713,7 +732,7 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_CONST_ALPHA:
/* we'll need the optional constant alpha register */
- setup_const_register(f, &constA_reg_set, &constA_reg, blend_color->color[3]);
+ setup_const_register(f, &constA_reg, blend_color->color[3]);
/* factor = (Ac,Ac,Ac), so term = (Rfb*Ac,Gfb*Ac,Bfb*Ac) */
spe_fm(f, term2R_reg, fbR_reg, constA_reg);
spe_fm(f, term2G_reg, fbG_reg, constA_reg);
@@ -721,9 +740,9 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
/* We need the optional constant color registers */
- setup_const_register(f, &constR_reg_set, &constR_reg, blend_color->color[0]);
- setup_const_register(f, &constG_reg_set, &constG_reg, blend_color->color[1]);
- setup_const_register(f, &constB_reg_set, &constB_reg, blend_color->color[2]);
+ setup_const_register(f, &constR_reg, blend_color->color[0]);
+ setup_const_register(f, &constG_reg, blend_color->color[1]);
+ setup_const_register(f, &constB_reg, blend_color->color[2]);
/* factor = (1-Rc,1-Gc,1-Bc), so term = (Rfb*(1-Rc),Gfb*(1-Gc),Bfb*(1-Bc))
* or term = (Rfb-Rfb*Rc, Gfb-Gfb*Gc, Bfb-Bfb*Bc)
* fnms(a,b,c,d) computes a = d - b*c
@@ -734,9 +753,9 @@ gen_blend(const struct pipe_blend_state *blend,
break;
case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
/* We need the optional constant color registers */
- setup_const_register(f, &constR_reg_set, &constR_reg, blend_color->color[0]);
- setup_const_register(f, &constG_reg_set, &constG_reg, blend_color->color[1]);
- setup_const_register(f, &constB_reg_set, &constB_reg, blend_color->color[2]);
+ setup_const_register(f, &constR_reg, blend_color->color[0]);
+ setup_const_register(f, &constG_reg, blend_color->color[1]);
+ setup_const_register(f, &constB_reg, blend_color->color[2]);
/* factor = (1-Ac,1-Ac,1-Ac), so term = (Rfb*(1-Ac),Gfb*(1-Ac),Bfb*(1-Ac))
* or term = (Rfb-Rfb*Ac,Gfb-Gfb*Ac,Bfb-Bfb*Ac)
* fnms(a,b,c,d) computes a = d - b*c
@@ -806,7 +825,7 @@ gen_blend(const struct pipe_blend_state *blend,
case PIPE_BLENDFACTOR_CONST_ALPHA: /* fall through */
case PIPE_BLENDFACTOR_CONST_COLOR:
/* We need the optional constA_reg register */
- setup_const_register(f, &constA_reg_set, &constA_reg, blend_color->color[3]);
+ setup_const_register(f, &constA_reg, blend_color->color[3]);
/* factor = Ac, so term = Afb*Ac */
spe_fm(f, term2A_reg, fbA_reg, constA_reg);
break;
@@ -814,7 +833,7 @@ gen_blend(const struct pipe_blend_state *blend,
case PIPE_BLENDFACTOR_INV_CONST_ALPHA: /* fall through */
case PIPE_BLENDFACTOR_INV_CONST_COLOR:
/* We need the optional constA_reg register */
- setup_const_register(f, &constA_reg_set, &constA_reg, blend_color->color[3]);
+ setup_const_register(f, &constA_reg, blend_color->color[3]);
/* factor = 1-Ac, so term = Afb*(1-Ac) = Afb-Afb*Ac */
/* fnms(a,b,c,d) computes a = d - b*c */
spe_fnms(f, term2A_reg, fbA_reg, constA_reg, fbA_reg);
@@ -910,11 +929,11 @@ gen_blend(const struct pipe_blend_state *blend,
spe_release_register(f, tmp_reg);
/* Free any optional registers that actually got used */
- release_const_register(f, &one_reg_set, one_reg);
- release_const_register(f, &constR_reg_set, constR_reg);
- release_const_register(f, &constG_reg_set, constG_reg);
- release_const_register(f, &constB_reg_set, constB_reg);
- release_const_register(f, &constA_reg_set, constA_reg);
+ release_const_register(f, one_reg);
+ release_const_register(f, constR_reg);
+ release_const_register(f, constG_reg);
+ release_const_register(f, constB_reg);
+ release_const_register(f, constA_reg);
}
@@ -1055,6 +1074,7 @@ gen_pack_colors(struct spe_function *f,
spe_release_register(f, ba_reg);
}
+
static void
gen_colormask(struct spe_function *f,
uint colormask,
@@ -1067,10 +1087,10 @@ gen_colormask(struct spe_function *f,
* are packed according to the given color format, not
* necessarily RGBA...
*/
- unsigned int r_mask;
- unsigned int g_mask;
- unsigned int b_mask;
- unsigned int a_mask;
+ uint r_mask;
+ uint g_mask;
+ uint b_mask;
+ uint a_mask;
/* Calculate exactly where the bits for any particular color
* end up, so we can mask them correctly.
@@ -1111,11 +1131,13 @@ gen_colormask(struct spe_function *f,
a_mask = 0;
}
- /* Get a temporary register to hold the mask that will be applied to the fragment */
+ /* Get a temporary register to hold the mask that will be applied
+ * to the fragment
+ */
int colormask_reg = spe_allocate_available_register(f);
- /* The actual mask we're going to use is an OR of the remaining R, G, B, and A
- * masks. Load the result value into our temporary register.
+ /* The actual mask we're going to use is an OR of the remaining R, G, B,
+ * and A masks. Load the result value into our temporary register.
*/
spe_load_uint(f, colormask_reg, r_mask | g_mask | b_mask | a_mask);
@@ -1135,7 +1157,9 @@ gen_colormask(struct spe_function *f,
spe_release_register(f, colormask_reg);
}
-/* This function is annoyingly similar to gen_depth_test(), above, except
+
+/**
+ * This function is annoyingly similar to gen_depth_test(), above, except
* that instead of comparing two varying values (i.e. fragment and buffer),
* we're comparing a varying value with a static value. As such, we have
* access to the Compare Immediate instructions where we don't in
@@ -1146,16 +1170,20 @@ gen_colormask(struct spe_function *f,
*
* The return value in the stencil_pass_reg is a bitmask of valid
* fragments that also passed the stencil test. The bitmask of valid
- * fragments that failed would be found in (fragment_mask_reg & ~stencil_pass_reg).
+ * fragments that failed would be found in
+ * (fragment_mask_reg & ~stencil_pass_reg).
*/
static void
-gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
- unsigned int stencil_max_value,
- unsigned int fragment_mask_reg, unsigned int fbS_reg,
- unsigned int stencil_pass_reg)
+gen_stencil_test(struct spe_function *f,
+ const struct pipe_stencil_state *state,
+ uint stencil_max_value,
+ int fragment_mask_reg,
+ int fbS_reg,
+ int stencil_pass_reg)
{
- /* Generate code that puts the set of passing fragments into the stencil_pass_reg
- * register, taking into account whether each fragment was active to begin with.
+ /* Generate code that puts the set of passing fragments into the
+ * stencil_pass_reg register, taking into account whether each fragment
+ * was active to begin with.
*/
switch (state->func) {
case PIPE_FUNC_EQUAL:
@@ -1166,9 +1194,10 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
}
else {
/* stencil_pass = fragment_mask & ((s&mask) == (reference&mask)) */
- unsigned int tmp_masked_stencil = spe_allocate_available_register(f);
+ uint tmp_masked_stencil = spe_allocate_available_register(f);
spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->value_mask);
- spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil, state->value_mask & state->ref_value);
+ spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil,
+ state->value_mask & state->ref_value);
spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
spe_release_register(f, tmp_masked_stencil);
}
@@ -1182,9 +1211,10 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
}
else {
/* stencil_pass = fragment_mask & ~((s&mask) == (reference&mask)) */
- unsigned int tmp_masked_stencil = spe_allocate_available_register(f);
+ int tmp_masked_stencil = spe_allocate_available_register(f);
spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->value_mask);
- spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil, state->value_mask & state->ref_value);
+ spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil,
+ state->value_mask & state->ref_value);
spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
spe_release_register(f, tmp_masked_stencil);
}
@@ -1198,9 +1228,10 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
}
else {
/* stencil_pass = fragment_mask & ((reference&mask) < (s & mask)) */
- unsigned int tmp_masked_stencil = spe_allocate_available_register(f);
+ int tmp_masked_stencil = spe_allocate_available_register(f);
spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->value_mask);
- spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil, state->value_mask & state->ref_value);
+ spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil,
+ state->value_mask & state->ref_value);
spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
spe_release_register(f, tmp_masked_stencil);
}
@@ -1214,7 +1245,7 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
* comparing directly. Compare Logical Greater Than Word (clgt)
* treats its operands as unsigned - no sign extension.
*/
- unsigned int tmp_reg = spe_allocate_available_register(f);
+ int tmp_reg = spe_allocate_available_register(f);
spe_load_uint(f, tmp_reg, state->ref_value);
spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg);
spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
@@ -1222,8 +1253,8 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
}
else {
/* stencil_pass = fragment_mask & ((reference&mask) > (s&mask)) */
- unsigned int tmp_reg = spe_allocate_available_register(f);
- unsigned int tmp_masked_stencil = spe_allocate_available_register(f);
+ int tmp_reg = spe_allocate_available_register(f);
+ int tmp_masked_stencil = spe_allocate_available_register(f);
spe_load_uint(f, tmp_reg, state->value_mask & state->ref_value);
spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->value_mask);
spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil);
@@ -1237,14 +1268,16 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
if (state->value_mask == stencil_max_value) {
/* stencil_pass = fragment_mask & (reference >= s)
* = fragment_mask & ~(s > reference) */
- spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, state->ref_value);
+ spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg,
+ state->ref_value);
spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
}
else {
/* stencil_pass = fragment_mask & ~((s&mask) > (reference&mask)) */
- unsigned int tmp_masked_stencil = spe_allocate_available_register(f);
+ int tmp_masked_stencil = spe_allocate_available_register(f);
spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->value_mask);
- spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil, state->value_mask & state->ref_value);
+ spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil,
+ state->value_mask & state->ref_value);
spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
spe_release_register(f, tmp_masked_stencil);
}
@@ -1255,7 +1288,7 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
/* stencil_pass = fragment_mask & (reference <= s) ]
* = fragment_mask & ~(reference > s) */
/* As above, we have to do this by loading a register */
- unsigned int tmp_reg = spe_allocate_available_register(f);
+ int tmp_reg = spe_allocate_available_register(f);
spe_load_uint(f, tmp_reg, state->ref_value);
spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg);
spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg);
@@ -1263,8 +1296,8 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
}
else {
/* stencil_pass = fragment_mask & ~((reference&mask) > (s&mask)) */
- unsigned int tmp_reg = spe_allocate_available_register(f);
- unsigned int tmp_masked_stencil = spe_allocate_available_register(f);
+ int tmp_reg = spe_allocate_available_register(f);
+ int tmp_masked_stencil = spe_allocate_available_register(f);
spe_load_uint(f, tmp_reg, state->ref_value & state->value_mask);
spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->value_mask);
spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil);
@@ -1290,7 +1323,9 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
*/
}
-/* This function generates code that calculates a set of new stencil values
+
+/**
+ * This function generates code that calculates a set of new stencil values
* given the earlier values and the operation to apply. It does not
* apply any tests. It is intended to be called up to 3 times
* (for the stencil fail operation, for the stencil pass-z fail operation,
@@ -1302,9 +1337,12 @@ gen_stencil_test(struct spe_function *f, const struct pipe_stencil_state *state,
* in the stencil buffer - in other words, it should be usable as a mask.
*/
static void
-gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
- unsigned int stencil_ref_value, unsigned int stencil_max_value,
- unsigned int fbS_reg, unsigned int newS_reg)
+gen_stencil_values(struct spe_function *f,
+ uint stencil_op,
+ uint stencil_ref_value,
+ uint stencil_max_value,
+ int fbS_reg,
+ int newS_reg)
{
/* The code below assumes that newS_reg and fbS_reg are not the same
* register; if they can be, the calculations below will have to use
@@ -1346,7 +1384,7 @@ gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
case PIPE_STENCIL_OP_INCR: {
/* newS = (s == max ? max : s + 1) */
- unsigned int equals_reg = spe_allocate_available_register(f);
+ int equals_reg = spe_allocate_available_register(f);
spe_compare_equal_uint(f, equals_reg, fbS_reg, stencil_max_value);
/* Add Word Immediate computes rT = rA + 10-bit signed immediate */
@@ -1359,7 +1397,7 @@ gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
}
case PIPE_STENCIL_OP_DECR: {
/* newS = (s == 0 ? 0 : s - 1) */
- unsigned int equals_reg = spe_allocate_available_register(f);
+ int equals_reg = spe_allocate_available_register(f);
spe_compare_equal_uint(f, equals_reg, fbS_reg, 0);
/* Add Word Immediate with a (-1) value works */
@@ -1397,7 +1435,8 @@ gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
}
-/* This function generates code to get all the necessary possible
+/**
+ * This function generates code to get all the necessary possible
* stencil values. For each of the output registers (fail_reg,
* zfail_reg, and zpass_reg), it either allocates a new register
* and calculates a new set of values based on the stencil operation,
@@ -1412,13 +1451,15 @@ gen_stencil_values(struct spe_function *f, unsigned int stencil_op,
* and released by the corresponding spe_release_register_set() call.
*/
static void
-gen_get_stencil_values(struct spe_function *f, const struct pipe_stencil_state *stencil,
- const unsigned int depth_enabled,
- unsigned int fbS_reg,
- unsigned int *fail_reg, unsigned int *zfail_reg,
- unsigned int *zpass_reg)
+gen_get_stencil_values(struct spe_function *f,
+ const struct pipe_stencil_state *stencil,
+ const uint depth_enabled,
+ int fbS_reg,
+ int *fail_reg,
+ int *zfail_reg,
+ int *zpass_reg)
{
- unsigned zfail_op;
+ uint zfail_op;
/* Stenciling had better be enabled here */
ASSERT(stencil->enabled);
@@ -1480,7 +1521,8 @@ gen_get_stencil_values(struct spe_function *f, const struct pipe_stencil_state *
}
}
-/* Note that fbZ_reg may *not* be set on entry, if in fact
+/**
+ * Note that fbZ_reg may *not* be set on entry, if in fact
* the depth test is not enabled. This function must not use
* the register if depth is not enabled.
*/
@@ -1494,7 +1536,7 @@ gen_stencil_depth_test(struct spe_function *f,
/* True if we've generated code that could require writeback to the
* depth and/or stencil buffers
*/
- boolean modified_buffers = false;
+ boolean modified_buffers = FALSE;
boolean need_to_calculate_stencil_values;
boolean need_to_writemask_stencil_values;
@@ -1504,11 +1546,11 @@ gen_stencil_depth_test(struct spe_function *f,
/* Registers. We may or may not actually allocate these, depending
* on whether the state values indicate that we need them.
*/
- unsigned int stencil_pass_reg, stencil_fail_reg;
- unsigned int stencil_fail_values, stencil_pass_depth_fail_values, stencil_pass_depth_pass_values;
- unsigned int stencil_writemask_reg;
- unsigned int zmask_reg;
- unsigned int newS_reg;
+ int stencil_pass_reg, stencil_fail_reg;
+ int stencil_fail_values, stencil_pass_depth_fail_values, stencil_pass_depth_pass_values;
+ int stencil_writemask_reg;
+ int zmask_reg;
+ int newS_reg;
/* Stenciling is quite complex: up to six different configurable stencil
* operations/calculations can be required (three each for front-facing
@@ -1555,27 +1597,27 @@ gen_stencil_depth_test(struct spe_function *f,
if (stencil->fail_op == PIPE_STENCIL_OP_KEEP &&
stencil->zfail_op == PIPE_STENCIL_OP_KEEP &&
stencil->zpass_op == PIPE_STENCIL_OP_KEEP) {
- need_to_calculate_stencil_values = false;
- need_to_writemask_stencil_values = false;
+ need_to_calculate_stencil_values = FALSE;
+ need_to_writemask_stencil_values = FALSE;
}
else if (stencil->write_mask == 0x0) {
/* All changes are writemasked out, so no need to calculate
* what those changes might be, and no need to write anything back.
*/
- need_to_calculate_stencil_values = false;
- need_to_writemask_stencil_values = false;
+ need_to_calculate_stencil_values = FALSE;
+ need_to_writemask_stencil_values = FALSE;
}
else if (stencil->write_mask == 0xff) {
/* Still trivial, but a little less so. We need to write the stencil
* values, but we don't need to mask them.
*/
- need_to_calculate_stencil_values = true;
- need_to_writemask_stencil_values = false;
+ need_to_calculate_stencil_values = TRUE;
+ need_to_writemask_stencil_values = FALSE;
}
else {
/* The general case: calculate, mask, and write */
- need_to_calculate_stencil_values = true;
- need_to_writemask_stencil_values = true;
+ need_to_calculate_stencil_values = TRUE;
+ need_to_writemask_stencil_values = TRUE;
/* While we're here, generate code that calculates what the
* writemask should be. If backface stenciling is enabled,
@@ -1633,7 +1675,9 @@ gen_stencil_depth_test(struct spe_function *f,
* This function will allocate a variant number of registers that
* will be released as part of the register set.
*/
- spe_comment(f, 0, facing == CELL_FACING_FRONT ? "Computing front-facing stencil values" : "Computing back-facing stencil values");
+ spe_comment(f, 0, facing == CELL_FACING_FRONT
+ ? "Computing front-facing stencil values"
+ : "Computing back-facing stencil values");
gen_get_stencil_values(f, stencil, dsa->depth.enabled, fbS_reg,
&stencil_fail_values, &stencil_pass_depth_fail_values,
&stencil_pass_depth_pass_values);
@@ -1652,7 +1696,8 @@ gen_stencil_depth_test(struct spe_function *f,
if (dsa->depth.enabled) {
spe_comment(f, 0, "Running stencil depth test");
zmask_reg = spe_allocate_available_register(f);
- modified_buffers |= gen_depth_test(f, dsa, mask_reg, fragZ_reg, fbZ_reg, zmask_reg);
+ modified_buffers |= gen_depth_test(f, dsa, mask_reg, fragZ_reg,
+ fbZ_reg, zmask_reg);
}
if (need_to_calculate_stencil_values) {
@@ -1675,7 +1720,7 @@ gen_stencil_depth_test(struct spe_function *f,
if (stencil_fail_values != fbS_reg) {
spe_comment(f, 0, "Loading stencil fail values");
spe_selb(f, newS_reg, newS_reg, stencil_fail_values, stencil_fail_reg);
- modified_buffers = true;
+ modified_buffers = TRUE;
}
/* Same for the stencil pass/depth fail values. If this calculation
@@ -1689,14 +1734,17 @@ gen_stencil_depth_test(struct spe_function *f,
* depth passing mask. Note that zmask_reg *must* have been
* set above if we're here.
*/
- unsigned int stencil_pass_depth_fail_mask = spe_allocate_available_register(f);
+ uint stencil_pass_depth_fail_mask =
+ spe_allocate_available_register(f);
+
spe_comment(f, 0, "Loading stencil pass/depth fail values");
spe_andc(f, stencil_pass_depth_fail_mask, stencil_pass_reg, zmask_reg);
- spe_selb(f, newS_reg, newS_reg, stencil_pass_depth_fail_values, stencil_pass_depth_fail_mask);
+ spe_selb(f, newS_reg, newS_reg, stencil_pass_depth_fail_values,
+ stencil_pass_depth_fail_mask);
spe_release_register(f, stencil_pass_depth_fail_mask);
- modified_buffers = true;
+ modified_buffers = TRUE;
}
/* Same for the stencil pass/depth pass mask. Note that we
@@ -1707,7 +1755,7 @@ gen_stencil_depth_test(struct spe_function *f,
*/
if (stencil_pass_depth_pass_values != fbS_reg) {
if (dsa->depth.enabled) {
- unsigned int stencil_pass_depth_pass_mask = spe_allocate_available_register(f);
+ uint stencil_pass_depth_pass_mask = spe_allocate_available_register(f);
/* We'll need a separate register */
spe_comment(f, 0, "Loading stencil pass/depth pass values");
spe_and(f, stencil_pass_depth_pass_mask, stencil_pass_reg, zmask_reg);
@@ -1719,7 +1767,7 @@ gen_stencil_depth_test(struct spe_function *f,
spe_comment(f, 0, "Loading stencil pass values");
spe_selb(f, newS_reg, newS_reg, stencil_pass_depth_pass_values, stencil_pass_reg);
}
- modified_buffers = true;
+ modified_buffers = TRUE;
}
/* Almost done. If we need to writemask, do it now, leaving the
@@ -1749,7 +1797,7 @@ gen_stencil_depth_test(struct spe_function *f,
spe_comment(f, 0, "Releasing stencil register set");
spe_release_register_set(f);
- /* Return true if we could have modified the stencil and/or
+ /* Return TRUE if we could have modified the stencil and/or
* depth buffers.
*/
return modified_buffers;
@@ -1757,6 +1805,200 @@ gen_stencil_depth_test(struct spe_function *f,
/**
+ * Generate depth and/or stencil test code.
+ * \param cell context
+ * \param dsa depth/stencil/alpha state
+ * \param f spe function to emit
+ * \param facing either CELL_FACING_FRONT or CELL_FACING_BACK
+ * \param mask_reg register containing the pixel alive/dead mask
+ * \param depth_tile_reg register containing address of z/stencil tile
+ * \param quad_offset_reg offset to quad from start of tile
+ * \param fragZ_reg register containg fragment Z values
+ */
+static void
+gen_depth_stencil(struct cell_context *cell,
+ const struct pipe_depth_stencil_alpha_state *dsa,
+ struct spe_function *f,
+ uint facing,
+ int mask_reg,
+ int depth_tile_reg,
+ int quad_offset_reg,
+ int fragZ_reg)
+
+{
+ const enum pipe_format zs_format = cell->framebuffer.zsbuf->format;
+ boolean write_depth_stencil;
+
+ /* framebuffer's combined z/stencil values register */
+ int fbZS_reg = spe_allocate_available_register(f);
+
+ /* Framebufer Z values register */
+ int fbZ_reg = spe_allocate_available_register(f);
+
+ /* Framebuffer stencil values register (may not be used) */
+ int fbS_reg = spe_allocate_available_register(f);
+
+ /* 24-bit mask register (may not be used) */
+ int zmask_reg = spe_allocate_available_register(f);
+
+ /**
+ * The following code:
+ * 1. fetch quad of packed Z/S values from the framebuffer tile.
+ * 2. extract the separate the Z and S values from packed values
+ * 3. convert fragment Z values from float in [0,1] to 32/24/16-bit ints
+ *
+ * The instructions for doing this are interleaved for better performance.
+ */
+ spe_comment(f, 0, "Fetch Z/stencil quad from tile");
+
+ switch(zs_format) {
+ case PIPE_FORMAT_S8Z24_UNORM: /* fall through */
+ case PIPE_FORMAT_X8Z24_UNORM:
+ /* prepare mask to extract Z vals from ZS vals */
+ spe_load_uint(f, zmask_reg, 0x00ffffff);
+
+ /* convert fragment Z from [0,1] to 32-bit ints */
+ spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
+
+ /* Load: fbZS_reg = memory[depth_tile_reg + offset_reg] */
+ spe_lqx(f, fbZS_reg, depth_tile_reg, quad_offset_reg);
+
+ /* right shift 32-bit fragment Z to 24 bits */
+ spe_rotmi(f, fragZ_reg, fragZ_reg, -8);
+
+ /* extract 24-bit Z values from ZS values by masking */
+ spe_and(f, fbZ_reg, fbZS_reg, zmask_reg);
+
+ /* extract 8-bit stencil values by shifting */
+ spe_rotmi(f, fbS_reg, fbZS_reg, -24);
+ break;
+
+ case PIPE_FORMAT_Z24S8_UNORM: /* fall through */
+ case PIPE_FORMAT_Z24X8_UNORM:
+ /* convert fragment Z from [0,1] to 32-bit ints */
+ spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
+
+ /* Load: fbZS_reg = memory[depth_tile_reg + offset_reg] */
+ spe_lqx(f, fbZS_reg, depth_tile_reg, quad_offset_reg);
+
+ /* right shift 32-bit fragment Z to 24 bits */
+ spe_rotmi(f, fragZ_reg, fragZ_reg, -8);
+
+ /* extract 24-bit Z values from ZS values by shifting */
+ spe_rotmi(f, fbZ_reg, fbZS_reg, -8);
+
+ /* extract 8-bit stencil values by masking */
+ spe_and_uint(f, fbS_reg, fbZS_reg, 0x000000ff);
+ break;
+
+ case PIPE_FORMAT_Z32_UNORM:
+ /* Load: fbZ_reg = memory[depth_tile_reg + offset_reg] */
+ spe_lqx(f, fbZ_reg, depth_tile_reg, quad_offset_reg);
+
+ /* convert fragment Z from [0,1] to 32-bit ints */
+ spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
+
+ /* No stencil, so can't do anything there */
+ break;
+
+ case PIPE_FORMAT_Z16_UNORM:
+ /* XXX This code for 16bpp Z is broken! */
+
+ /* Load: fbZS_reg = memory[depth_tile_reg + offset_reg] */
+ spe_lqx(f, fbZS_reg, depth_tile_reg, quad_offset_reg);
+
+ /* Copy over 4 32-bit values */
+ spe_move(f, fbZ_reg, fbZS_reg);
+
+ /* convert Z from [0,1] to 16-bit ints */
+ spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
+ spe_rotmi(f, fragZ_reg, fragZ_reg, -16);
+ /* No stencil */
+ break;
+
+ default:
+ ASSERT(0); /* invalid format */
+ }
+
+ /* If stencil is enabled, use the stencil-specific code
+ * generator to generate both the stencil and depth (if needed)
+ * tests. Otherwise, if only depth is enabled, generate
+ * a quick depth test. The test generators themselves will
+ * report back whether the depth/stencil buffer has to be
+ * written back.
+ */
+ if (dsa->stencil[0].enabled) {
+ /* This will perform the stencil and depth tests, and update
+ * the mask_reg, fbZ_reg, and fbS_reg as required by the
+ * tests.
+ */
+ ASSERT(fbS_reg >= 0);
+ spe_comment(f, 0, "Perform stencil test");
+
+ /* Note that fbZ_reg may not be set on entry, if stenciling
+ * is enabled but there's no Z-buffer. The
+ * gen_stencil_depth_test() function must ignore the
+ * fbZ_reg register if depth is not enabled.
+ */
+ write_depth_stencil = gen_stencil_depth_test(f, dsa, facing,
+ mask_reg, fragZ_reg,
+ fbZ_reg, fbS_reg);
+ }
+ else if (dsa->depth.enabled) {
+ int zmask_reg = spe_allocate_available_register(f);
+ ASSERT(fbZ_reg >= 0);
+ spe_comment(f, 0, "Perform depth test");
+ write_depth_stencil = gen_depth_test(f, dsa, mask_reg, fragZ_reg,
+ fbZ_reg, zmask_reg);
+ spe_release_register(f, zmask_reg);
+ }
+ else {
+ write_depth_stencil = FALSE;
+ }
+
+ if (write_depth_stencil) {
+ /* Merge latest Z and Stencil values into fbZS_reg.
+ * fbZ_reg has four Z vals in bits [23..0] or bits [15..0].
+ * fbS_reg has four 8-bit Z values in bits [7..0].
+ */
+ spe_comment(f, 0, "Store quad's depth/stencil values in tile");
+ if (zs_format == PIPE_FORMAT_S8Z24_UNORM ||
+ zs_format == PIPE_FORMAT_X8Z24_UNORM) {
+ spe_shli(f, fbS_reg, fbS_reg, 24); /* fbS = fbS << 24 */
+ spe_or(f, fbZS_reg, fbS_reg, fbZ_reg); /* fbZS = fbS | fbZ */
+ }
+ else if (zs_format == PIPE_FORMAT_Z24S8_UNORM ||
+ zs_format == PIPE_FORMAT_Z24X8_UNORM) {
+ spe_shli(f, fbZ_reg, fbZ_reg, 8); /* fbZ = fbZ << 8 */
+ spe_or(f, fbZS_reg, fbS_reg, fbZ_reg); /* fbZS = fbS | fbZ */
+ }
+ else if (zs_format == PIPE_FORMAT_Z32_UNORM) {
+ spe_move(f, fbZS_reg, fbZ_reg); /* fbZS = fbZ */
+ }
+ else if (zs_format == PIPE_FORMAT_Z16_UNORM) {
+ spe_move(f, fbZS_reg, fbZ_reg); /* fbZS = fbZ */
+ }
+ else if (zs_format == PIPE_FORMAT_S8_UNORM) {
+ ASSERT(0); /* XXX to do */
+ }
+ else {
+ ASSERT(0); /* bad zs_format */
+ }
+
+ /* Store: memory[depth_tile_reg + quad_offset_reg] = fbZS */
+ spe_stqx(f, fbZS_reg, depth_tile_reg, quad_offset_reg);
+ }
+
+ /* Don't need these any more */
+ spe_release_register(f, fbZS_reg);
+ spe_release_register(f, fbZ_reg);
+ spe_release_register(f, fbS_reg);
+ spe_release_register(f, zmask_reg);
+}
+
+
+
+/**
* Generate SPE code to implement the fragment operations (alpha test,
* depth test, stencil test, blending, colormask, and final
* framebuffer write) as specified by the current context state.
@@ -1782,7 +2024,9 @@ gen_stencil_depth_test(struct spe_function *f,
* the fragment ops appended.
*/
void
-cell_gen_fragment_function(struct cell_context *cell, const uint facing, struct spe_function *f)
+cell_gen_fragment_function(struct cell_context *cell,
+ const uint facing,
+ struct spe_function *f)
{
const struct pipe_depth_stencil_alpha_state *dsa = cell->depth_stencil;
const struct pipe_blend_state *blend = cell->blend;
@@ -1809,12 +2053,13 @@ cell_gen_fragment_function(struct cell_context *cell, const uint facing, struct
int quad_offset_reg;
int fbRGBA_reg; /**< framebuffer's RGBA colors for quad */
- int fbZS_reg; /**< framebuffer's combined z/stencil values for quad */
if (cell->debug_flags & CELL_DEBUG_ASM) {
- spe_print_code(f, true);
+ spe_print_code(f, TRUE);
spe_indent(f, 8);
- spe_comment(f, -4, facing == CELL_FACING_FRONT ? "Begin front-facing per-fragment ops": "Begin back-facing per-fragment ops");
+ spe_comment(f, -4, facing == CELL_FACING_FRONT
+ ? "Begin front-facing per-fragment ops"
+ : "Begin back-facing per-fragment ops");
}
spe_allocate_register(f, x_reg);
@@ -1830,7 +2075,6 @@ cell_gen_fragment_function(struct cell_context *cell, const uint facing, struct
quad_offset_reg = spe_allocate_available_register(f);
fbRGBA_reg = spe_allocate_available_register(f);
- fbZS_reg = spe_allocate_available_register(f);
/* compute offset of quad from start of tile, in bytes */
{
@@ -1855,177 +2099,14 @@ cell_gen_fragment_function(struct cell_context *cell, const uint facing, struct
gen_alpha_test(dsa, f, mask_reg, fragA_reg);
}
- /* If we need the stencil buffers (because one- or two-sided stencil is
- * enabled) or the depth buffer (because the depth test is enabled),
- * go grab them. Note that if either one- or two-sided stencil is
- * enabled, dsa->stencil[0].enabled will be true.
- */
+ /* generate depth and/or stencil test code */
if (dsa->depth.enabled || dsa->stencil[0].enabled) {
- const enum pipe_format zs_format = cell->framebuffer.zsbuf->format;
- boolean write_depth_stencil;
-
- /* We may or may not need to allocate a register for Z or stencil values */
- boolean fbS_reg_set = false, fbZ_reg_set = false;
- unsigned int fbS_reg, fbZ_reg = 0;
-
- spe_comment(f, 0, "Fetching Z/stencil quad from tile");
-
- /* fetch quad of depth/stencil values from tile at (x,y) */
- /* Load: fbZS_reg = memory[depth_tile_reg + offset_reg] */
- /* XXX Not sure this is allowed if we've only got a 16-bit Z buffer... */
- spe_lqx(f, fbZS_reg, depth_tile_reg, quad_offset_reg);
-
- /* From the Z/stencil buffer format, pull out the bits we need for
- * Z and/or stencil. We'll also convert the incoming fragment Z
- * value in fragZ_reg from a floating point value in [0.0..1.0] to
- * an unsigned integer value with the appropriate resolution.
- * Note that even if depth or stencil is *not* enabled, if it's
- * present in the buffer, we pull it out and put it back later;
- * otherwise, we can inadvertently destroy the contents of
- * buffers we're not supposed to touch (e.g., if the user is
- * clearing the depth buffer but not the stencil buffer, a
- * quad of constant depth is drawn over the surface; the stencil
- * buffer must be maintained).
- */
- switch(zs_format) {
-
- case PIPE_FORMAT_S8Z24_UNORM: /* fall through */
- case PIPE_FORMAT_X8Z24_UNORM:
- /* Pull out both Z and stencil */
- setup_optional_register(f, &fbZ_reg_set, &fbZ_reg);
- setup_optional_register(f, &fbS_reg_set, &fbS_reg);
-
- /* four 24-bit Z values in the low-order bits */
- spe_and_uint(f, fbZ_reg, fbZS_reg, 0x00ffffff);
-
- /* Incoming fragZ_reg value is a float in 0.0...1.0; convert
- * to a 24-bit unsigned integer
- */
- spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
- spe_rotmi(f, fragZ_reg, fragZ_reg, -8);
-
- /* four 8-bit stencil values in the high-order bits */
- spe_rotmi(f, fbS_reg, fbZS_reg, -24);
- break;
-
- case PIPE_FORMAT_Z24S8_UNORM: /* fall through */
- case PIPE_FORMAT_Z24X8_UNORM:
- setup_optional_register(f, &fbZ_reg_set, &fbZ_reg);
- setup_optional_register(f, &fbS_reg_set, &fbS_reg);
-
- /* shift by 8 to get the upper 24-bit values */
- spe_rotmi(f, fbS_reg, fbZS_reg, -8);
-
- /* Incoming fragZ_reg value is a float in 0.0...1.0; convert
- * to a 24-bit unsigned integer
- */
- spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
- spe_rotmi(f, fragZ_reg, fragZ_reg, -8);
-
- /* 8-bit stencil in the low-order bits - mask them out */
- spe_and_uint(f, fbS_reg, fbZS_reg, 0x000000ff);
- break;
-
- case PIPE_FORMAT_Z32_UNORM:
- setup_optional_register(f, &fbZ_reg_set, &fbZ_reg);
- /* Copy over 4 32-bit values */
- spe_move(f, fbZ_reg, fbZS_reg);
-
- /* Incoming fragZ_reg value is a float in 0.0...1.0; convert
- * to a 32-bit unsigned integer
- */
- spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
- /* No stencil, so can't do anything there */
- break;
-
- case PIPE_FORMAT_Z16_UNORM:
- /* XXX Not sure this is correct, but it was here before, so we're
- * going with it for now
- */
- setup_optional_register(f, &fbZ_reg_set, &fbZ_reg);
- /* Copy over 4 32-bit values */
- spe_move(f, fbZ_reg, fbZS_reg);
-
- /* Incoming fragZ_reg value is a float in 0.0...1.0; convert
- * to a 16-bit unsigned integer
- */
- spe_cfltu(f, fragZ_reg, fragZ_reg, 32);
- spe_rotmi(f, fragZ_reg, fragZ_reg, -16);
- /* No stencil */
-
- default:
- ASSERT(0); /* invalid format */
- }
-
- /* If stencil is enabled, use the stencil-specific code
- * generator to generate both the stencil and depth (if needed)
- * tests. Otherwise, if only depth is enabled, generate
- * a quick depth test. The test generators themselves will
- * report back whether the depth/stencil buffer has to be
- * written back.
- */
- if (dsa->stencil[0].enabled) {
- /* This will perform the stencil and depth tests, and update
- * the mask_reg, fbZ_reg, and fbS_reg as required by the
- * tests.
- */
- ASSERT(fbS_reg_set);
- spe_comment(f, 0, "Perform stencil test");
-
- /* Note that fbZ_reg may not be set on entry, if stenciling
- * is enabled but there's no Z-buffer. The
- * gen_stencil_depth_test() function must ignore the
- * fbZ_reg register if depth is not enabled.
- */
- write_depth_stencil = gen_stencil_depth_test(f, dsa, facing, mask_reg, fragZ_reg, fbZ_reg, fbS_reg);
- }
- else if (dsa->depth.enabled) {
- int zmask_reg = spe_allocate_available_register(f);
- ASSERT(fbZ_reg_set);
- spe_comment(f, 0, "Perform depth test");
- write_depth_stencil = gen_depth_test(f, dsa, mask_reg, fragZ_reg, fbZ_reg, zmask_reg);
- spe_release_register(f, zmask_reg);
- }
- else {
- write_depth_stencil = false;
- }
-
- if (write_depth_stencil) {
- /* Merge latest Z and Stencil values into fbZS_reg.
- * fbZ_reg has four Z vals in bits [23..0] or bits [15..0].
- * fbS_reg has four 8-bit Z values in bits [7..0].
- */
- spe_comment(f, 0, "Store quad's depth/stencil values in tile");
- if (zs_format == PIPE_FORMAT_S8Z24_UNORM ||
- zs_format == PIPE_FORMAT_X8Z24_UNORM) {
- spe_shli(f, fbS_reg, fbS_reg, 24); /* fbS = fbS << 24 */
- spe_or(f, fbZS_reg, fbS_reg, fbZ_reg); /* fbZS = fbS | fbZ */
- }
- else if (zs_format == PIPE_FORMAT_Z24S8_UNORM ||
- zs_format == PIPE_FORMAT_Z24X8_UNORM) {
- spe_shli(f, fbZ_reg, fbZ_reg, 8); /* fbZ = fbZ << 8 */
- spe_or(f, fbZS_reg, fbS_reg, fbZ_reg); /* fbZS = fbS | fbZ */
- }
- else if (zs_format == PIPE_FORMAT_Z32_UNORM) {
- spe_move(f, fbZS_reg, fbZ_reg); /* fbZS = fbZ */
- }
- else if (zs_format == PIPE_FORMAT_Z16_UNORM) {
- spe_move(f, fbZS_reg, fbZ_reg); /* fbZS = fbZ */
- }
- else if (zs_format == PIPE_FORMAT_S8_UNORM) {
- ASSERT(0); /* XXX to do */
- }
- else {
- ASSERT(0); /* bad zs_format */
- }
-
- /* Store: memory[depth_tile_reg + quad_offset_reg] = fbZS */
- spe_stqx(f, fbZS_reg, depth_tile_reg, quad_offset_reg);
- }
-
- /* Don't need these any more */
- release_optional_register(f, &fbZ_reg_set, fbZ_reg);
- release_optional_register(f, &fbS_reg_set, fbS_reg);
+ gen_depth_stencil(cell, dsa, f,
+ facing,
+ mask_reg,
+ depth_tile_reg,
+ quad_offset_reg,
+ fragZ_reg);
}
/* Get framebuffer quad/colors. We'll need these for blending,
@@ -2089,7 +2170,6 @@ cell_gen_fragment_function(struct cell_context *cell, const uint facing, struct
spe_bi(f, SPE_REG_RA, 0, 0); /* return from function call */
spe_release_register(f, fbRGBA_reg);
- spe_release_register(f, fbZS_reg);
spe_release_register(f, quad_offset_reg);
if (cell->debug_flags & CELL_DEBUG_ASM) {
diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c
index 0a0af81f53..39b85faeb8 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_emit.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c
@@ -133,7 +133,7 @@ lookup_fragment_ops(struct cell_context *cell)
*/
ops = CALLOC_VARIANT_LENGTH_STRUCT(cell_command_fragment_ops, total_code_size);
/* populate the new cell_command_fragment_ops object */
- ops->opcode = CELL_CMD_STATE_FRAGMENT_OPS;
+ ops->opcode[0] = CELL_CMD_STATE_FRAGMENT_OPS;
ops->total_code_size = total_code_size;
ops->front_code_index = 0;
memcpy(ops->code, spe_code_front.store, front_code_size);
@@ -178,10 +178,10 @@ static void
emit_state_cmd(struct cell_context *cell, uint cmd,
const void *state, uint state_size)
{
- uint64_t *dst = (uint64_t *)
- cell_batch_alloc(cell, ROUNDUP8(sizeof(uint64_t) + state_size));
+ uint32_t *dst = (uint32_t *)
+ cell_batch_alloc16(cell, ROUNDUP16(sizeof(opcode_t) + state_size));
*dst = cmd;
- memcpy(dst + 1, state, state_size);
+ memcpy(dst + 4, state, state_size);
}
@@ -195,9 +195,10 @@ cell_emit_state(struct cell_context *cell)
if (cell->dirty & CELL_NEW_FRAMEBUFFER) {
struct pipe_surface *cbuf = cell->framebuffer.cbufs[0];
struct pipe_surface *zbuf = cell->framebuffer.zsbuf;
+ STATIC_ASSERT(sizeof(struct cell_command_framebuffer) % 16 == 0);
struct cell_command_framebuffer *fb
- = cell_batch_alloc(cell, sizeof(*fb));
- fb->opcode = CELL_CMD_STATE_FRAMEBUFFER;
+ = cell_batch_alloc16(cell, sizeof(*fb));
+ fb->opcode[0] = CELL_CMD_STATE_FRAMEBUFFER;
fb->color_start = cell->cbuf_map[0];
fb->color_format = cbuf->format;
fb->depth_start = cell->zsbuf_map;
@@ -211,17 +212,19 @@ cell_emit_state(struct cell_context *cell)
}
if (cell->dirty & (CELL_NEW_RASTERIZER)) {
+ STATIC_ASSERT(sizeof(struct cell_command_rasterizer) % 16 == 0);
struct cell_command_rasterizer *rast =
- cell_batch_alloc(cell, sizeof(*rast));
- rast->opcode = CELL_CMD_STATE_RASTERIZER;
+ cell_batch_alloc16(cell, sizeof(*rast));
+ rast->opcode[0] = CELL_CMD_STATE_RASTERIZER;
rast->rasterizer = *cell->rasterizer;
}
if (cell->dirty & (CELL_NEW_FS)) {
/* Send new fragment program to SPUs */
+ STATIC_ASSERT(sizeof(struct cell_command_fragment_program) % 16 == 0);
struct cell_command_fragment_program *fp
- = cell_batch_alloc(cell, sizeof(*fp));
- fp->opcode = CELL_CMD_STATE_FRAGMENT_PROGRAM;
+ = cell_batch_alloc16(cell, sizeof(*fp));
+ fp->opcode[0] = CELL_CMD_STATE_FRAGMENT_PROGRAM;
fp->num_inst = cell->fs->code.num_inst;
memcpy(&fp->code, cell->fs->code.store,
SPU_MAX_FRAGMENT_PROGRAM_INSTS * SPE_INST_SIZE);
@@ -238,14 +241,14 @@ cell_emit_state(struct cell_context *cell)
const uint shader = PIPE_SHADER_FRAGMENT;
const uint num_const = cell->constants[shader].size / sizeof(float);
uint i, j;
- float *buf = cell_batch_alloc(cell, 16 + num_const * sizeof(float));
- uint64_t *ibuf = (uint64_t *) buf;
+ float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float)));
+ uint32_t *ibuf = (uint32_t *) buf;
const float *constants = pipe_buffer_map(cell->pipe.screen,
cell->constants[shader].buffer,
PIPE_BUFFER_USAGE_CPU_READ);
ibuf[0] = CELL_CMD_STATE_FS_CONSTANTS;
- ibuf[1] = num_const;
- j = 4;
+ ibuf[4] = num_const;
+ j = 8;
for (i = 0; i < num_const; i++) {
buf[j++] = constants[i];
}
@@ -258,7 +261,7 @@ cell_emit_state(struct cell_context *cell)
struct cell_command_fragment_ops *fops, *fops_cmd;
/* Note that cell_command_fragment_ops is a variant-sized record */
fops = lookup_fragment_ops(cell);
- fops_cmd = cell_batch_alloc(cell, sizeof(*fops_cmd) + fops->total_code_size);
+ fops_cmd = cell_batch_alloc16(cell, ROUNDUP16(sizeof(*fops_cmd) + fops->total_code_size));
memcpy(fops_cmd, fops, sizeof(*fops) + fops->total_code_size);
}
@@ -267,9 +270,10 @@ cell_emit_state(struct cell_context *cell)
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
if (cell->dirty_samplers & (1 << i)) {
if (cell->sampler[i]) {
+ STATIC_ASSERT(sizeof(struct cell_command_sampler) % 16 == 0);
struct cell_command_sampler *sampler
- = cell_batch_alloc(cell, sizeof(*sampler));
- sampler->opcode = CELL_CMD_STATE_SAMPLER;
+ = cell_batch_alloc16(cell, sizeof(*sampler));
+ sampler->opcode[0] = CELL_CMD_STATE_SAMPLER;
sampler->unit = i;
sampler->state = *cell->sampler[i];
}
@@ -282,9 +286,10 @@ cell_emit_state(struct cell_context *cell)
uint i;
for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
if (cell->dirty_textures & (1 << i)) {
+ STATIC_ASSERT(sizeof(struct cell_command_texture) % 16 == 0);
struct cell_command_texture *texture
- = cell_batch_alloc(cell, sizeof(*texture));
- texture->opcode = CELL_CMD_STATE_TEXTURE;
+ = (struct cell_command_texture *)cell_batch_alloc16(cell, sizeof(*texture));
+ texture->opcode[0] = CELL_CMD_STATE_TEXTURE;
texture->unit = i;
if (cell->texture[i]) {
uint level;
diff --git a/src/gallium/drivers/cell/ppu/cell_vbuf.c b/src/gallium/drivers/cell/ppu/cell_vbuf.c
index 65ba51b6bb..ab54e79689 100644
--- a/src/gallium/drivers/cell/ppu/cell_vbuf.c
+++ b/src/gallium/drivers/cell/ppu/cell_vbuf.c
@@ -116,10 +116,11 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
/* Tell SPUs they can release the vert buf */
if (cvbr->vertex_buf != ~0U) {
+ STATIC_ASSERT(sizeof(struct cell_command_release_verts) % 16 == 0);
struct cell_command_release_verts *release
= (struct cell_command_release_verts *)
- cell_batch_alloc(cell, sizeof(struct cell_command_release_verts));
- release->opcode = CELL_CMD_RELEASE_VERTS;
+ cell_batch_alloc16(cell, sizeof(struct cell_command_release_verts));
+ release->opcode[0] = CELL_CMD_RELEASE_VERTS;
release->vertex_buf = cvbr->vertex_buf;
}
@@ -210,15 +211,16 @@ cell_vbuf_draw(struct vbuf_render *vbr,
/* build/insert batch RENDER command */
{
- const uint index_bytes = ROUNDUP8(nr_indices * 2);
- const uint vertex_bytes = nr_vertices * 4 * cell->vertex_info.size;
+ const uint index_bytes = ROUNDUP16(nr_indices * 2);
+ const uint vertex_bytes = ROUNDUP16(nr_vertices * 4 * cell->vertex_info.size);
+ STATIC_ASSERT(sizeof(struct cell_command_render) % 16 == 0);
const uint batch_size = sizeof(struct cell_command_render) + index_bytes;
struct cell_command_render *render
= (struct cell_command_render *)
- cell_batch_alloc(cell, batch_size);
+ cell_batch_alloc16(cell, batch_size);
- render->opcode = CELL_CMD_RENDER;
+ render->opcode[0] = CELL_CMD_RENDER;
render->prim_type = cvbr->prim;
render->num_indexes = nr_indices;
@@ -236,7 +238,7 @@ cell_vbuf_draw(struct vbuf_render *vbr,
min_index == 0 &&
vertex_bytes + 16 <= cell_batch_free_space(cell)) {
/* vertex data inlined, after indices, at 16-byte boundary */
- void *dst = cell_batch_alloc_aligned(cell, vertex_bytes, 16);
+ void *dst = cell_batch_alloc16(cell, vertex_bytes);
memcpy(dst, vertices, vertex_bytes);
render->inline_verts = TRUE;
render->vertex_buf = ~0;
diff --git a/src/gallium/drivers/cell/spu/spu_command.c b/src/gallium/drivers/cell/spu/spu_command.c
index 8500d19754..5c0179d954 100644
--- a/src/gallium/drivers/cell/spu/spu_command.c
+++ b/src/gallium/drivers/cell/spu/spu_command.c
@@ -292,10 +292,10 @@ cmd_state_fragment_program(const struct cell_command_fragment_program *fp)
static uint
-cmd_state_fs_constants(const uint64_t *buffer, uint pos)
+cmd_state_fs_constants(const qword *buffer, uint pos)
{
- const uint num_const = buffer[pos + 1];
- const float *constants = (const float *) &buffer[pos + 2];
+ const uint num_const = spu_extract((vector unsigned int)buffer[pos+1], 0);
+ const float *constants = (const float *) &buffer[pos+2];
uint i;
D_PRINTF(CELL_DEBUG_CMD, "CMD_STATE_FS_CONSTANTS (%u)\n", num_const);
@@ -306,8 +306,8 @@ cmd_state_fs_constants(const uint64_t *buffer, uint pos)
spu.constants[i] = spu_splats(constants[i]);
}
- /* return new buffer pos (in 8-byte words) */
- return pos + 2 + num_const / 2;
+ /* return new buffer pos (in 16-byte words) */
+ return pos + 2 + (ROUNDUP16(num_const * sizeof(float)) / 16);
}
@@ -547,8 +547,8 @@ cmd_batch(uint opcode)
{
const uint buf = (opcode >> 8) & 0xff;
uint size = (opcode >> 16);
- uint64_t buffer[CELL_BUFFER_SIZE / 8] ALIGN16_ATTRIB;
- const unsigned usize = size / sizeof(buffer[0]);
+ qword buffer[CELL_BUFFER_SIZE / 16] ALIGN16_ATTRIB;
+ const unsigned usize = ROUNDUP16(size) / sizeof(buffer[0]);
uint pos;
D_PRINTF(CELL_DEBUG_CMD, "BATCH buffer %u, len %u, from %p\n",
@@ -578,7 +578,7 @@ cmd_batch(uint opcode)
* Loop over commands in the batch buffer
*/
for (pos = 0; pos < usize; /* no incr */) {
- switch (buffer[pos]) {
+ switch (si_to_uint(buffer[pos])) {
/*
* rendering commands
*/
@@ -587,7 +587,7 @@ cmd_batch(uint opcode)
struct cell_command_clear_surface *clr
= (struct cell_command_clear_surface *) &buffer[pos];
cmd_clear_surface(clr);
- pos += sizeof(*clr) / 8;
+ pos += sizeof(*clr) / 16;
}
break;
case CELL_CMD_RENDER:
@@ -596,7 +596,7 @@ cmd_batch(uint opcode)
= (struct cell_command_render *) &buffer[pos];
uint pos_incr;
cmd_render(render, &pos_incr);
- pos += pos_incr;
+ pos += ((pos_incr+1)&~1) / 2; // should 'fix' cmd_render return
}
break;
/*
@@ -607,7 +607,7 @@ cmd_batch(uint opcode)
struct cell_command_framebuffer *fb
= (struct cell_command_framebuffer *) &buffer[pos];
cmd_state_framebuffer(fb);
- pos += sizeof(*fb) / 8;
+ pos += sizeof(*fb) / 16;
}
break;
case CELL_CMD_STATE_FRAGMENT_OPS:
@@ -616,7 +616,7 @@ cmd_batch(uint opcode)
= (struct cell_command_fragment_ops *) &buffer[pos];
cmd_state_fragment_ops(fops);
/* This is a variant-sized command */
- pos += (sizeof(*fops) + fops->total_code_size)/ 8;
+ pos += ROUNDUP16(sizeof(*fops) + fops->total_code_size) / 16;
}
break;
case CELL_CMD_STATE_FRAGMENT_PROGRAM:
@@ -624,7 +624,7 @@ cmd_batch(uint opcode)
struct cell_command_fragment_program *fp
= (struct cell_command_fragment_program *) &buffer[pos];
cmd_state_fragment_program(fp);
- pos += sizeof(*fp) / 8;
+ pos += sizeof(*fp) / 16;
}
break;
case CELL_CMD_STATE_FS_CONSTANTS:
@@ -635,7 +635,7 @@ cmd_batch(uint opcode)
struct cell_command_rasterizer *rast =
(struct cell_command_rasterizer *) &buffer[pos];
spu.rasterizer = rast->rasterizer;
- pos += sizeof(*rast) / 8;
+ pos += sizeof(*rast) / 16;
}
break;
case CELL_CMD_STATE_SAMPLER:
@@ -643,7 +643,7 @@ cmd_batch(uint opcode)
struct cell_command_sampler *sampler
= (struct cell_command_sampler *) &buffer[pos];
cmd_state_sampler(sampler);
- pos += sizeof(*sampler) / 8;
+ pos += sizeof(*sampler) / 16;
}
break;
case CELL_CMD_STATE_TEXTURE:
@@ -651,37 +651,37 @@ cmd_batch(uint opcode)
struct cell_command_texture *texture
= (struct cell_command_texture *) &buffer[pos];
cmd_state_texture(texture);
- pos += sizeof(*texture) / 8;
+ pos += sizeof(*texture) / 16;
}
break;
case CELL_CMD_STATE_VERTEX_INFO:
cmd_state_vertex_info((struct vertex_info *) &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct vertex_info)) / 8);
+ pos += 1 + ROUNDUP16(sizeof(struct vertex_info)) / 16;
break;
case CELL_CMD_STATE_VIEWPORT:
(void) memcpy(& draw.viewport, &buffer[pos+1],
sizeof(struct pipe_viewport_state));
- pos += (1 + ROUNDUP8(sizeof(struct pipe_viewport_state)) / 8);
+ pos += 1 + ROUNDUP16(sizeof(struct pipe_viewport_state)) / 16;
break;
case CELL_CMD_STATE_UNIFORMS:
- draw.constants = (const float (*)[4]) (uintptr_t) buffer[pos + 1];
+ draw.constants = (const float (*)[4]) (uintptr_t)spu_extract((vector unsigned int)buffer[pos+1],0);
pos += 2;
break;
case CELL_CMD_STATE_VS_ARRAY_INFO:
cmd_state_vs_array_info((struct cell_array_info *) &buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct cell_array_info)) / 8);
+ pos += 1 + ROUNDUP16(sizeof(struct cell_array_info)) / 16;
break;
case CELL_CMD_STATE_BIND_VS:
#if 0
spu_bind_vertex_shader(&draw,
(struct cell_shader_info *) &buffer[pos+1]);
#endif
- pos += (1 + ROUNDUP8(sizeof(struct cell_shader_info)) / 8);
+ pos += 1 + ROUNDUP16(sizeof(struct cell_shader_info)) / 16;
break;
case CELL_CMD_STATE_ATTRIB_FETCH:
cmd_state_attrib_fetch((struct cell_attribute_fetch_code *)
&buffer[pos+1]);
- pos += (1 + ROUNDUP8(sizeof(struct cell_attribute_fetch_code)) / 8);
+ pos += 1 + ROUNDUP16(sizeof(struct cell_attribute_fetch_code)) / 16;
break;
/*
* misc commands
@@ -695,7 +695,7 @@ cmd_batch(uint opcode)
struct cell_command_fence *fence_cmd =
(struct cell_command_fence *) &buffer[pos];
cmd_fence(fence_cmd);
- pos += sizeof(*fence_cmd) / 8;
+ pos += sizeof(*fence_cmd) / 16;
}
break;
case CELL_CMD_RELEASE_VERTS:
@@ -703,7 +703,7 @@ cmd_batch(uint opcode)
struct cell_command_release_verts *release
= (struct cell_command_release_verts *) &buffer[pos];
cmd_release_verts(release);
- pos += sizeof(*release) / 8;
+ pos += sizeof(*release) / 16;
}
break;
case CELL_CMD_FLUSH_BUFFER_RANGE: {
@@ -711,11 +711,11 @@ cmd_batch(uint opcode)
&buffer[pos+1];
spu_dcache_mark_dirty((unsigned) br->base, br->size);
- pos += (1 + ROUNDUP8(sizeof(struct cell_buffer_range)) / 8);
+ pos += 1 + ROUNDUP16(sizeof(struct cell_buffer_range)) / 16;
break;
}
default:
- printf("SPU %u: bad opcode: 0x%llx\n", spu.init.id, buffer[pos]);
+ printf("SPU %u: bad opcode: 0x%x\n", spu.init.id, si_to_uint(buffer[pos]));
ASSERT(0);
break;
}
diff --git a/src/gallium/drivers/cell/spu/spu_shuffle.h b/src/gallium/drivers/cell/spu/spu_shuffle.h
index 7cbdb814d2..74f2a0b6d2 100644
--- a/src/gallium/drivers/cell/spu/spu_shuffle.h
+++ b/src/gallium/drivers/cell/spu/spu_shuffle.h
@@ -171,7 +171,7 @@
SHUFFLE_PATTERN_16_##M##__, \
SHUFFLE_PATTERN_16_##N##__, \
SHUFFLE_PATTERN_16_##O##__, \
- SHUFFLE_PATTERN_16_##P
+ SHUFFLE_PATTERN_16_##P##__
#define SHUFFLE16(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) \
((const vector unsigned char){ \
diff --git a/src/gallium/drivers/cell/spu/spu_tri.c b/src/gallium/drivers/cell/spu/spu_tri.c
index 322be1252e..0d9fcb9997 100644
--- a/src/gallium/drivers/cell/spu/spu_tri.c
+++ b/src/gallium/drivers/cell/spu/spu_tri.c
@@ -57,7 +57,7 @@ struct vertex_header {
/* XXX fix this */
#undef CEILF
-#define CEILF(X) ((float) (int) ((X) + 0.99999))
+#define CEILF(X) ((float) (int) ((X) + 0.99999f))
#define QUAD_TOP_LEFT 0
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 0958bba334..061a4c064b 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -67,11 +67,18 @@ struct nv50_rasterizer_stateobj {
struct nouveau_stateobj *so;
};
+struct nv50_miptree_level {
+ struct pipe_buffer **image;
+ int *image_offset;
+ unsigned image_dirty_cpu[512/32];
+ unsigned image_dirty_gpu[512/32];
+};
+
struct nv50_miptree {
struct pipe_texture base;
struct pipe_buffer *buffer;
- int *image_offset;
+ struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
int image_nr;
int total_size;
};
@@ -84,7 +91,6 @@ nv50_miptree(struct pipe_texture *pt)
struct nv50_surface {
struct pipe_surface base;
- struct pipe_buffer *untiled;
};
static INLINE struct nv50_surface *
@@ -186,4 +192,8 @@ extern boolean nv50_state_validate(struct nv50_context *nv50);
/* nv50_tex.c */
extern void nv50_tex_validate(struct nv50_context *);
+/* nv50_miptree.c */
+extern void nv50_miptree_sync(struct pipe_screen *, struct nv50_miptree *,
+ unsigned level, unsigned image);
+
#endif
diff --git a/src/gallium/drivers/nv50/nv50_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 2497371232..63a23d06b8 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -27,14 +27,16 @@
#include "nv50_context.h"
static struct pipe_texture *
-nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
+nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
{
struct pipe_winsys *ws = pscreen->winsys;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
- unsigned usage, width = pt->width[0], height = pt->height[0];
- int i;
+ struct pipe_texture *pt = &mt->base;
+ unsigned usage, width = tmp->width[0], height = tmp->height[0];
+ unsigned depth = tmp->depth[0];
+ int i, l;
- mt->base = *pt;
+ mt->base = *tmp;
mt->base.refcount = 1;
mt->base.screen = pscreen;
@@ -59,17 +61,38 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
mt->image_nr = 1;
break;
}
- mt->image_offset = CALLOC(mt->image_nr, sizeof(int));
+
+ for (l = 0; l <= pt->last_level; l++) {
+ struct nv50_miptree_level *lvl = &mt->level[l];
+
+ pt->width[l] = width;
+ pt->height[l] = height;
+ pt->depth[l] = depth;
+ pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
+ pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
+
+ lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
+ lvl->image = CALLOC(mt->image_nr, sizeof(struct pipe_buffer *));
+
+ width = MAX2(1, width >> 1);
+ height = MAX2(1, height >> 1);
+ depth = MAX2(1, depth >> 1);
+ }
for (i = 0; i < mt->image_nr; i++) {
- int image_size;
+ for (l = 0; l <= pt->last_level; l++) {
+ struct nv50_miptree_level *lvl = &mt->level[l];
+ int size;
+
+ size = align(pt->width[l], 8) * pt->block.size;
+ size = align(size, 64);
+ size *= align(pt->height[l], 8) * pt->block.size;
- image_size = align(width, 8) * pt->block.size;
- image_size = align(image_size, 64);
- image_size *= align(height, 8) * pt->block.size;
+ lvl->image[i] = ws->buffer_create(ws, 256, 0, size);
+ lvl->image_offset[i] = mt->total_size;
- mt->image_offset[i] = mt->total_size;
- mt->total_size += image_size;
+ mt->total_size += size;
+ }
}
mt->buffer = ws->buffer_create(ws, 256, usage, mt->total_size);
@@ -81,6 +104,24 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
return &mt->base;
}
+static INLINE void
+mark_dirty(uint32_t *flags, unsigned image)
+{
+ flags[image / 32] |= (1 << (image % 32));
+}
+
+static INLINE void
+mark_clean(uint32_t *flags, unsigned image)
+{
+ flags[image / 32] &= ~(1 << (image % 32));
+}
+
+static INLINE int
+is_dirty(uint32_t *flags, unsigned image)
+{
+ return !!(flags[image / 32] & (1 << (image % 32)));
+}
+
static void
nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
{
@@ -96,12 +137,86 @@ nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
}
}
+void
+nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt,
+ unsigned level, unsigned image)
+{
+ struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
+ struct nv50_miptree_level *lvl = &mt->level[level];
+ struct pipe_surface *dst, *src;
+ unsigned face = 0, zslice = 0;
+
+ if (!is_dirty(lvl->image_dirty_cpu, image))
+ return;
+
+ if (mt->base.target == PIPE_TEXTURE_CUBE)
+ face = image;
+ else
+ if (mt->base.target == PIPE_TEXTURE_3D)
+ zslice = image;
+
+ /* Mark as clean already - so we don't continually call this function
+ * trying to get a GPU_WRITE pipe_surface!
+ */
+ mark_clean(lvl->image_dirty_cpu, image);
+
+ /* Pretend we're doing CPU access so we get the backing pipe_surface
+ * and not a view into the larger miptree.
+ */
+ src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ /* Pretend we're only reading with the GPU so surface doesn't get marked
+ * as dirtied by the GPU.
+ */
+ dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
+ PIPE_BUFFER_USAGE_GPU_READ);
+
+ nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height);
+
+ pscreen->tex_surface_release(pscreen, &dst);
+ pscreen->tex_surface_release(pscreen, &src);
+}
+
+/* The reverse of the above */
+void
+nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt,
+ unsigned level, unsigned image)
+{
+ struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
+ struct nv50_miptree_level *lvl = &mt->level[level];
+ struct pipe_surface *dst, *src;
+ unsigned face = 0, zslice = 0;
+
+ if (!is_dirty(lvl->image_dirty_gpu, image))
+ return;
+
+ if (mt->base.target == PIPE_TEXTURE_CUBE)
+ face = image;
+ else
+ if (mt->base.target == PIPE_TEXTURE_3D)
+ zslice = image;
+
+ mark_clean(lvl->image_dirty_gpu, image);
+
+ src = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
+ PIPE_BUFFER_USAGE_GPU_READ);
+ dst = pscreen->get_tex_surface(pscreen, &mt->base, face, level, zslice,
+ PIPE_BUFFER_USAGE_CPU_READ);
+
+ nvws->surface_copy(nvws, dst, 0, 0, src, 0, 0, dst->width, dst->height);
+
+ pscreen->tex_surface_release(pscreen, &dst);
+ pscreen->tex_surface_release(pscreen, &src);
+}
+
static struct pipe_surface *
nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
unsigned face, unsigned level, unsigned zslice,
unsigned flags)
{
struct nv50_miptree *mt = nv50_miptree(pt);
+ struct nv50_miptree_level *lvl = &mt->level[level];
struct nv50_surface *s;
struct pipe_surface *ps;
int img;
@@ -128,12 +243,29 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ps->nblocksx = pt->nblocksx[level];
ps->nblocksy = pt->nblocksy[level];
ps->stride = ps->width * ps->block.size;
- ps->offset = mt->image_offset[img];
ps->usage = flags;
ps->status = PIPE_SURFACE_STATUS_DEFINED;
- pipe_texture_reference(&ps->texture, pt);
- pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer);
+ if (flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
+ assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
+ nv50_miptree_sync_cpu(pscreen, mt, level, img);
+
+ ps->offset = 0;
+ pipe_texture_reference(&ps->texture, pt);
+ pipe_buffer_reference(pscreen, &ps->buffer, lvl->image[img]);
+
+ if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
+ mark_dirty(lvl->image_dirty_cpu, img);
+ } else {
+ nv50_miptree_sync(pscreen, mt, level, img);
+
+ ps->offset = lvl->image_offset[img];
+ pipe_texture_reference(&ps->texture, pt);
+ pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer);
+
+ if (flags & PIPE_BUFFER_USAGE_GPU_WRITE)
+ mark_dirty(lvl->image_dirty_gpu, img);
+ }
return ps;
}
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index d66e1d0949..7686f746eb 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -32,7 +32,7 @@
#include "nv50_context.h"
#define NV50_SU_MAX_TEMP 64
-#define NV50_PROGRAM_DUMP
+//#define NV50_PROGRAM_DUMP
/* ARL - gallium craps itself on progs/vp/arl.txt
*
@@ -841,6 +841,28 @@ emit_neg(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
emit(pc, e);
}
+static void
+emit_kil(struct nv50_pc *pc, struct nv50_reg *src)
+{
+ struct nv50_program_exec *e;
+ const int r_pred = 1;
+
+ /* Sets predicate reg ? */
+ e = exec(pc);
+ e->inst[0] = 0xa00001fd;
+ e->inst[1] = 0xc4014788;
+ set_src_0(pc, src, e);
+ set_pred_wr(pc, 1, r_pred, e);
+ emit(pc, e);
+
+ /* This is probably KILP */
+ e = exec(pc);
+ e->inst[0] = 0x000001fe;
+ set_long(pc, e);
+ set_pred(pc, 1 /* LT? */, r_pred, e);
+ emit(pc, e);
+}
+
static struct nv50_reg *
tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
{
@@ -1069,6 +1091,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
free_temp(pc, temp);
break;
+ case TGSI_OPCODE_KIL:
+ emit_kil(pc, src[0][0]);
+ emit_kil(pc, src[0][1]);
+ emit_kil(pc, src[0][2]);
+ emit_kil(pc, src[0][3]);
+ break;
case TGSI_OPCODE_LIT:
emit_lit(pc, &dst[0], mask, &src[0][0]);
break;
@@ -1602,13 +1630,19 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
if (!upload)
return;
+#ifdef NV50_PROGRAM_DUMP
NOUVEAU_ERR("-------\n");
up = ptr = MALLOC(p->exec_size * 4);
for (e = p->exec_head; e; e = e->next) {
NOUVEAU_ERR("0x%08x\n", e->inst[0]);
if (is_long(e))
NOUVEAU_ERR("0x%08x\n", e->inst[1]);
+ }
+#endif
+
+ up = ptr = MALLOC(p->exec_size * 4);
+ for (e = p->exec_head; e; e = e->next) {
*(ptr++) = e->inst[0];
if (is_long(e))
*(ptr++) = e->inst[1];
@@ -1705,7 +1739,7 @@ nv50_fragprog_validate(struct nv50_context *nv50)
so_reloc (so, p->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
so_method(so, tesla, 0x1904, 4);
- so_data (so, 0x01040404); /* p: 0x01000404 */
+ so_data (so, 0x00040404); /* p: 0x01000404 */
so_data (so, 0x00000004);
so_data (so, 0x00000000);
so_data (so, 0x00000000);
diff --git a/src/gallium/drivers/nv50/nv50_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 777e77906d..b923c820eb 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -21,41 +21,101 @@
*/
#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
#include "nv50_context.h"
+struct nv50_query {
+ struct pipe_buffer *buffer;
+ unsigned type;
+ boolean ready;
+ uint64_t result;
+};
+
+static INLINE struct nv50_query *
+nv50_query(struct pipe_query *pipe)
+{
+ return (struct nv50_query *)pipe;
+}
+
static struct pipe_query *
nv50_query_create(struct pipe_context *pipe, unsigned type)
{
- NOUVEAU_ERR("unimplemented\n");
- return NULL;
+ struct pipe_winsys *ws = pipe->winsys;
+ struct nv50_query *q = CALLOC_STRUCT(nv50_query);
+
+ assert (q->type == PIPE_QUERY_OCCLUSION_COUNTER);
+ q->type = type;
+
+ q->buffer = ws->buffer_create(ws, 256, 0, 16);
+ if (!q->buffer) {
+ FREE(q);
+ return NULL;
+ }
+
+ return (struct pipe_query *)q;
}
static void
-nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *q)
+nv50_query_destroy(struct pipe_context *pipe, struct pipe_query *pq)
{
- NOUVEAU_ERR("unimplemented\n");
+ struct nv50_query *q = nv50_query(pq);
+
+ if (q) {
+ pipe_buffer_reference(pipe, &q->buffer, NULL);
+ FREE(q);
+ }
}
static void
-nv50_query_begin(struct pipe_context *pipe, struct pipe_query *q)
+nv50_query_begin(struct pipe_context *pipe, struct pipe_query *pq)
{
- NOUVEAU_ERR("unimplemented\n");
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nv50_query *q = nv50_query(pq);
+
+ BEGIN_RING(tesla, 0x1530, 1);
+ OUT_RING (1);
+ BEGIN_RING(tesla, 0x1514, 1);
+ OUT_RING (1);
+
+ q->ready = FALSE;
}
static void
-nv50_query_end(struct pipe_context *pipe, struct pipe_query *q)
+nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
{
- NOUVEAU_ERR("unimplemented\n");
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nv50_query *q = nv50_query(pq);
+
+ BEGIN_RING(tesla, 0x1b00, 4);
+ OUT_RELOCh(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(q->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RING (0x00000000);
+ OUT_RING (0x0100f002);
+ FIRE_RING (NULL);
}
static boolean
-nv50_query_result(struct pipe_context *pipe, struct pipe_query *q,
+nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, uint64_t *result)
{
- NOUVEAU_ERR("unimplemented\n");
- *result = 0xdeadcafe;
- return TRUE;
+ struct pipe_winsys *ws = pipe->winsys;
+ struct nv50_query *q = nv50_query(pq);
+
+ /*XXX: Want to be able to return FALSE here instead of blocking
+ * until the result is available..
+ */
+
+ if (!q->ready) {
+ uint32_t *map = ws->buffer_map(ws, q->buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ q->result = map[1];
+ q->ready = TRUE;
+ ws->buffer_unmap(ws, q->buffer);
+ }
+
+ *result = q->result;
+ return q->ready;
}
void
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index 52f6a40688..ef46233f83 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -57,6 +57,10 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
case PIPE_FORMAT_A8L8_UNORM:
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
return TRUE;
default:
break;
@@ -90,23 +94,23 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return 32;
case PIPE_CAP_NPOT_TEXTURES:
- return 0;
+ return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
return 1;
case PIPE_CAP_GLSL:
return 0;
case PIPE_CAP_S3TC:
- return 0;
+ return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
- return 0;
+ return 1;
case PIPE_CAP_POINT_SPRITE:
return 0;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 8;
case PIPE_CAP_OCCLUSION_QUERY:
- return 0;
+ return 1;
case PIPE_CAP_TEXTURE_SHADOW_MAP:
- return 0;
+ return 1;
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 13;
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 95f9d408b5..38c1d938b8 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -175,6 +175,32 @@ nv50_sampler_state_create(struct pipe_context *pipe,
break;
}
+ if (cso->max_anisotropy >= 16.0)
+ tsc[0] |= (7 << 20);
+ else
+ if (cso->max_anisotropy >= 12.0)
+ tsc[0] |= (6 << 20);
+ else
+ if (cso->max_anisotropy >= 10.0)
+ tsc[0] |= (5 << 20);
+ else
+ if (cso->max_anisotropy >= 8.0)
+ tsc[0] |= (4 << 20);
+ else
+ if (cso->max_anisotropy >= 6.0)
+ tsc[0] |= (3 << 20);
+ else
+ if (cso->max_anisotropy >= 4.0)
+ tsc[0] |= (2 << 20);
+ else
+ if (cso->max_anisotropy >= 2.0)
+ tsc[0] |= (1 << 20);
+
+ if (cso->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
+ tsc[0] |= (1 << 8);
+ tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7);
+ }
+
return (void *)tsc;
}
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 5bf97d3a6b..3f45a2fe18 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -63,48 +63,17 @@ static void *
nv50_surface_map(struct pipe_screen *screen, struct pipe_surface *ps,
unsigned flags )
{
- struct nouveau_winsys *nvws = nv50_screen(screen)->nvws;
struct pipe_winsys *ws = screen->winsys;
- struct nv50_surface *s = nv50_surface(ps);
- struct nv50_surface m = *s;
- void *map;
- if (!s->untiled) {
- s->untiled = ws->buffer_create(ws, 0, 0, ps->buffer->size);
-
- m.base.buffer = s->untiled;
- nvws->surface_copy(nvws, &m.base, 0, 0, &s->base, 0, 0,
- ps->width, ps->height);
- }
-
- /* Map original tiled surface to disallow it being validated while
- * untiled mirror is mapped.
- */
- ws->buffer_map(ws, ps->buffer, flags);
-
- map = ws->buffer_map(ws, s->untiled, flags);
- if (!map)
- return NULL;
-
- return map;
+ return ws->buffer_map(ws, ps->buffer, flags);
}
static void
nv50_surface_unmap(struct pipe_screen *pscreen, struct pipe_surface *ps)
{
- struct nouveau_winsys *nvws = nv50_screen(pscreen)->nvws;
struct pipe_winsys *ws = pscreen->winsys;
- struct nv50_surface *s = nv50_surface(ps);
- struct nv50_surface m = *s;
- ws->buffer_unmap(ws, s->untiled);
ws->buffer_unmap(ws, ps->buffer);
-
- m.base.buffer = s->untiled;
- nvws->surface_copy(nvws, &s->base, 0, 0, &m.base, 0, 0,
- ps->width, ps->height);
-
- pipe_buffer_reference(pscreen, &s->untiled, NULL);
}
void
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index fde3c97c05..239407c92b 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -85,6 +85,34 @@ nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt)
NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_8_8);
break;
+ case PIPE_FORMAT_DXT1_RGB:
+ so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM |
+ NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
+ NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_FMT_DXT1);
+ break;
+ case PIPE_FORMAT_DXT1_RGBA:
+ so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
+ NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
+ NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_FMT_DXT1);
+ break;
+ case PIPE_FORMAT_DXT3_RGBA:
+ so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
+ NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
+ NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_FMT_DXT3);
+ break;
+ case PIPE_FORMAT_DXT5_RGBA:
+ so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
+ NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
+ NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_FMT_DXT5);
+ break;
default:
return 1;
}
@@ -105,14 +133,23 @@ nv50_tex_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nouveau_stateobj *so;
- int i;
+ int unit, level, image;
so = so_new(nv50->miptree_nr * 8 + 3, nv50->miptree_nr * 2);
so_method(so, tesla, 0x0f00, 1);
so_data (so, NV50_CB_TIC);
so_method(so, tesla, 0x40000f04, nv50->miptree_nr * 8);
- for (i = 0; i < nv50->miptree_nr; i++) {
- if (nv50_tex_construct(so, nv50->miptree[i])) {
+ for (unit = 0; unit < nv50->miptree_nr; unit++) {
+ struct nv50_miptree *mt = nv50->miptree[unit];
+
+ for (level = 0; level <= mt->base.last_level; level++) {
+ for (image = 0; image < mt->image_nr; image++) {
+ nv50_miptree_sync(&nv50->screen->pipe, mt,
+ level, image);
+ }
+ }
+
+ if (nv50_tex_construct(so, mt)) {
NOUVEAU_ERR("failed tex validate\n");
so_ref(NULL, &so);
return;
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
index 6861d67b4d..aca622c73b 100644
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ b/src/gallium/drivers/nv50/nv50_texture.h
@@ -50,6 +50,9 @@
#define NV50TIC_0_0_FMT_5_6_5 0x00000015
#define NV50TIC_0_0_FMT_8_8 0x00000018
#define NV50TIC_0_0_FMT_8 0x0000001d
+#define NV50TIC_0_0_FMT_DXT1 0x00000024
+#define NV50TIC_0_0_FMT_DXT3 0x00000025
+#define NV50TIC_0_0_FMT_DXT5 0x00000026
#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff
#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index 584336682e..435dc9777d 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -60,6 +60,10 @@ nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
OUT_RING (0);
BEGIN_RING(tesla, 0x142c, 1);
OUT_RING (0);
+ BEGIN_RING(tesla, 0x1440, 1);
+ OUT_RING (0);
+ BEGIN_RING(tesla, 0x1334, 1);
+ OUT_RING (0);
BEGIN_RING(tesla, NV50TCL_VERTEX_BEGIN, 1);
OUT_RING (nv50_prim(mode));
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 5c6a92b53b..4f0b301f31 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -204,6 +204,7 @@ enum pipe_texture_target {
#define PIPE_BUFFER_USAGE_VERTEX (1 << 5)
#define PIPE_BUFFER_USAGE_INDEX (1 << 6)
#define PIPE_BUFFER_USAGE_CONSTANT (1 << 7)
+#define PIPE_BUFFER_USAGE_DISCARD (1 << 8)
/** Pipe driver custom usage flags should be greater or equal to this value */
#define PIPE_BUFFER_USAGE_CUSTOM (1 << 16)
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
new file mode 100644
index 0000000000..54480fa047
--- /dev/null
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -0,0 +1,33 @@
+
+#ifndef _DRM_API_H_
+#define _DRM_API_H_
+
+struct pipe_screen;
+struct pipe_winsys;
+struct pipe_context;
+
+struct drm_api
+{
+ /**
+ * Special buffer function
+ */
+ /*@{*/
+ struct pipe_screen* (*create_screen)(int drmFB, int pciID);
+ struct pipe_context* (*create_context)(struct pipe_screen *screen);
+ /*@}*/
+
+ /**
+ * Special buffer function
+ */
+ /*@{*/
+ struct pipe_buffer* (*buffer_from_handle)(struct pipe_winsys *winsys, const char *name, unsigned handle);
+ unsigned (*handle_from_buffer)(struct pipe_winsys *winsys, struct pipe_buffer *buffer);
+ /*@}*/
+};
+
+/**
+ * A driver needs to export this symbol
+ */
+extern struct drm_api drm_api_hocks;
+
+#endif
diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile
new file mode 100644
index 0000000000..17d1a7a8e4
--- /dev/null
+++ b/src/gallium/state_trackers/egl/Makefile
@@ -0,0 +1,29 @@
+TARGET = libegldrm.a
+CFILES = $(wildcard ./*.c)
+OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
+GALLIUMDIR = ../..
+TOP = ../../../..
+
+include ${TOP}/configs/current
+
+CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \
+ $(shell pkg-config --cflags pixman-1 xorg-server) \
+ -I${GALLIUMDIR}/include \
+ -I${GALLIUMDIR}/auxiliary \
+ -I${TOP}/src/mesa/drivers/dri/common \
+ -I${TOP}/src/mesa \
+ -I$(TOP)/include \
+ -I$(TOP)/src/egl/main \
+ ${LIBDRM_CFLAGS}
+
+#############################################
+
+.PHONY = all clean
+
+all: ${TARGET}
+
+${TARGET}: ${OBJECTS}
+ ar rcs $@ $^
+
+clean:
+ rm -rf ${OBJECTS} ${TARGET}
diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c
new file mode 100644
index 0000000000..217fe00338
--- /dev/null
+++ b/src/gallium/state_trackers/egl/egl_context.c
@@ -0,0 +1,194 @@
+
+#include "utils.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "egl_tracker.h"
+
+#include "egllog.h"
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_winsys.h"
+
+#include "state_tracker/st_public.h"
+#include "state_tracker/drm_api.h"
+
+#include "GL/internal/glcore.h"
+
+#define need_GL_ARB_multisample
+#define need_GL_ARB_point_parameters
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_window_pos
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_equation_separate
+#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_cull_vertex
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_multi_draw_arrays
+#define need_GL_EXT_secondary_color
+#define need_GL_NV_vertex_program
+#include "extension_helper.h"
+
+/**
+ * TODO HACK! FUGLY!
+ * Copied for intel extentions.
+ */
+const struct dri_extension card_extensions[] = {
+ {"GL_ARB_multisample", GL_ARB_multisample_functions},
+ {"GL_ARB_multitexture", NULL},
+ {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
+ {"GL_ARB_texture_border_clamp", NULL},
+ {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
+ {"GL_ARB_texture_cube_map", NULL},
+ {"GL_ARB_texture_env_add", NULL},
+ {"GL_ARB_texture_env_combine", NULL},
+ {"GL_ARB_texture_env_dot3", NULL},
+ {"GL_ARB_texture_mirrored_repeat", NULL},
+ {"GL_ARB_texture_rectangle", NULL},
+ {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
+ {"GL_ARB_pixel_buffer_object", NULL},
+ {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
+ {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
+ {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
+ {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
+ {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
+ {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
+ {"GL_EXT_blend_subtract", NULL},
+ {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
+ {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
+ {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
+ {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
+ {"GL_EXT_packed_depth_stencil", NULL},
+ {"GL_EXT_pixel_buffer_object", NULL},
+ {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
+ {"GL_EXT_stencil_wrap", NULL},
+ {"GL_EXT_texture_edge_clamp", NULL},
+ {"GL_EXT_texture_env_combine", NULL},
+ {"GL_EXT_texture_env_dot3", NULL},
+ {"GL_EXT_texture_filter_anisotropic", NULL},
+ {"GL_EXT_texture_lod_bias", NULL},
+ {"GL_3DFX_texture_compression_FXT1", NULL},
+ {"GL_APPLE_client_storage", NULL},
+ {"GL_MESA_pack_invert", NULL},
+ {"GL_MESA_ycbcr_texture", NULL},
+ {"GL_NV_blend_square", NULL},
+ {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
+ {"GL_NV_vertex_program1_1", NULL},
+ {"GL_SGIS_generate_mipmap", NULL },
+ {NULL, NULL}
+};
+
+EGLContext
+drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+{
+ struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_context *ctx;
+ struct drm_context *share = NULL;
+ struct st_context *st_share = NULL;
+ _EGLConfig *conf;
+ int i;
+ __GLcontextModes *visual;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreateContext");
+ return EGL_NO_CONTEXT;
+ }
+
+ for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
+ switch (attrib_list[i]) {
+ /* no attribs defined for now */
+ default:
+ _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
+ return EGL_NO_CONTEXT;
+ }
+ }
+
+ ctx = (struct drm_context *) calloc(1, sizeof(struct drm_context));
+ if (!ctx)
+ goto err_c;
+
+ _eglInitContext(drv, dpy, &ctx->base, config, attrib_list);
+
+ ctx->pipe = drm_api_hocks.create_context(dev->screen);
+ if (!ctx->pipe)
+ goto err_pipe;
+
+ if (share)
+ st_share = share->st;
+
+ visual = drm_visual_from_config(conf);
+ ctx->st = st_create_context(ctx->pipe, visual, st_share);
+ drm_visual_modes_destroy(visual);
+
+ if (!ctx->st)
+ goto err_gl;
+
+ /* generate handle and insert into hash table */
+ _eglSaveContext(&ctx->base);
+ assert(_eglGetContextHandle(&ctx->base));
+
+ return _eglGetContextHandle(&ctx->base);
+
+err_gl:
+ ctx->pipe->destroy(ctx->pipe);
+err_pipe:
+ free(ctx);
+err_c:
+ return EGL_NO_CONTEXT;
+}
+
+EGLBoolean
+drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+{
+ struct drm_context *c = lookup_drm_context(context);
+ _eglRemoveContext(&c->base);
+ if (c->base.IsBound) {
+ c->base.DeletePending = EGL_TRUE;
+ } else {
+ st_destroy_context(c->st);
+ c->pipe->destroy(c->pipe);
+ free(c);
+ }
+ return EGL_TRUE;
+}
+
+EGLBoolean
+drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+{
+ struct drm_surface *readSurf = lookup_drm_surface(read);
+ struct drm_surface *drawSurf = lookup_drm_surface(draw);
+ struct drm_context *ctx = lookup_drm_context(context);
+ EGLBoolean b;
+
+ b = _eglMakeCurrent(drv, dpy, draw, read, context);
+ if (!b)
+ return EGL_FALSE;
+
+ if (ctx) {
+ if (!drawSurf || !readSurf)
+ return EGL_FALSE;
+
+ drawSurf->user = ctx;
+ readSurf->user = ctx;
+
+ st_make_current(ctx->st, drawSurf->stfb, readSurf->stfb);
+
+ /* st_resize_framebuffer needs a bound context to work */
+ st_resize_framebuffer(drawSurf->stfb, drawSurf->w, drawSurf->h);
+ st_resize_framebuffer(readSurf->stfb, readSurf->w, readSurf->h);
+ } else {
+ drawSurf->user = NULL;
+ readSurf->user = NULL;
+
+ st_make_current(NULL, NULL, NULL);
+ }
+
+ return EGL_TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
new file mode 100644
index 0000000000..71292bf2a9
--- /dev/null
+++ b/src/gallium/state_trackers/egl/egl_surface.c
@@ -0,0 +1,418 @@
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "egl_tracker.h"
+
+#include "egllog.h"
+
+#include "pipe/p_inlines.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+
+#include "state_tracker/drm_api.h"
+
+/*
+ * Util functions
+ */
+
+static struct drm_mode_modeinfo *
+drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
+{
+ int i;
+ struct drm_mode_modeinfo *m = NULL;
+
+ for (i = 0; i < connector->count_modes; i++) {
+ m = &connector->modes[i];
+ if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
+ break;
+ m = &connector->modes[0]; /* if we can't find one, return first */
+ }
+
+ return m;
+}
+
+static struct st_framebuffer *
+drm_create_framebuffer(const __GLcontextModes *visual,
+ unsigned width,
+ unsigned height,
+ void *priv)
+{
+ enum pipe_format colorFormat, depthFormat, stencilFormat;
+
+ if (visual->redBits == 5)
+ colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
+ else
+ colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
+
+ if (visual->depthBits == 16)
+ depthFormat = PIPE_FORMAT_Z16_UNORM;
+ else if (visual->depthBits == 24)
+ depthFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ depthFormat = PIPE_FORMAT_NONE;
+
+ if (visual->stencilBits == 8)
+ stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
+ else
+ stencilFormat = PIPE_FORMAT_NONE;
+
+ return st_create_framebuffer(visual,
+ colorFormat,
+ depthFormat,
+ stencilFormat,
+ width,
+ height,
+ priv);
+}
+
+static void
+drm_create_texture(_EGLDriver *drv,
+ struct drm_screen *scrn,
+ unsigned w, unsigned h)
+{
+ struct drm_device *dev = (struct drm_device *)drv;
+ struct pipe_screen *screen = dev->screen;
+ struct pipe_surface *surface;
+ struct pipe_texture *texture;
+ struct pipe_texture templat;
+ struct pipe_buffer *buf;
+ unsigned stride = 1024;
+ unsigned pitch = 0;
+ unsigned size = 0;
+ void *ptr;
+
+ /* ugly */
+ if (stride < w)
+ stride = 2048;
+
+ pitch = stride * 4;
+ size = h * 2 * pitch;
+
+ buf = pipe_buffer_create(screen,
+ 0, /* alignment */
+ PIPE_BUFFER_USAGE_GPU_READ_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ_WRITE,
+ size);
+
+ if (!buf)
+ goto err_buf;
+
+#if DEBUG
+ ptr = pipe_buffer_map(screen, buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ memset(ptr, 0xFF, size);
+ pipe_buffer_unmap(screen, buf);
+#else
+ (void)ptr;
+#endif
+
+ memset(&templat, 0, sizeof(templat));
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.target = PIPE_TEXTURE_2D;
+ templat.last_level = 0;
+ templat.depth[0] = 1;
+ templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templat.width[0] = w;
+ templat.height[0] = h;
+ pf_get_block(templat.format, &templat.block);
+
+ texture = screen->texture_blanket(dev->screen,
+ &templat,
+ &pitch,
+ buf);
+ if (!texture)
+ goto err_tex;
+
+ surface = screen->get_tex_surface(screen,
+ texture,
+ 0,
+ 0,
+ 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ if (!surface)
+ goto err_surf;
+
+
+ scrn->tex = texture;
+ scrn->surface = surface;
+ scrn->buffer = buf;
+ scrn->front.width = w;
+ scrn->front.height = h;
+ scrn->front.pitch = pitch;
+ scrn->front.handle = drm_api_hocks.handle_from_buffer(dev->winsys, scrn->buffer);
+ if (0)
+ goto err_handle;
+
+ return;
+
+err_handle:
+ pipe_surface_reference(&surface, NULL);
+err_surf:
+ pipe_texture_reference(&texture, NULL);
+err_tex:
+ pipe_buffer_reference(screen, &buf, NULL);
+err_buf:
+ return;
+}
+
+/*
+ * Exported functions
+ */
+
+void
+drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
+{
+ struct drm_device *dev = (struct drm_device *)drv;
+
+ screen->surf = NULL;
+
+ drmModeSetCrtc(
+ dev->drmFD,
+ screen->crtcID,
+ 0, // FD
+ 0, 0,
+ NULL, 0, // List of output ids
+ NULL);
+
+ drmModeRmFB(dev->drmFD, screen->fbID);
+ drmModeFreeFB(screen->fb);
+ screen->fb = NULL;
+
+ pipe_surface_reference(&screen->surface, NULL);
+ pipe_texture_reference(&screen->tex, NULL);
+ pipe_buffer_reference(dev->screen, &screen->buffer, NULL);
+
+ screen->shown = 0;
+}
+
+EGLSurface
+drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+{
+ return EGL_NO_SURFACE;
+}
+
+
+EGLSurface
+drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+{
+ return EGL_NO_SURFACE;
+}
+
+
+EGLSurface
+drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
+{
+ int i;
+ int width = -1;
+ int height = -1;
+ struct drm_surface *surf = NULL;
+ __GLcontextModes *visual;
+ _EGLConfig *conf;
+
+ conf = _eglLookupConfig(drv, dpy, config);
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
+ return EGL_NO_CONTEXT;
+ }
+
+ for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
+ switch (attrib_list[i]) {
+ case EGL_WIDTH:
+ width = attrib_list[++i];
+ break;
+ case EGL_HEIGHT:
+ height = attrib_list[++i];
+ break;
+ default:
+ _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+ }
+
+ if (width < 1 || height < 1) {
+ _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
+ return EGL_NO_SURFACE;
+ }
+
+ surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
+ if (!surf)
+ goto err;
+
+ if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
+ goto err_surf;
+
+ surf->w = width;
+ surf->h = height;
+
+ visual = drm_visual_from_config(conf);
+ surf->stfb = drm_create_framebuffer(visual,
+ width,
+ height,
+ (void*)surf);
+ drm_visual_modes_destroy(visual);
+
+ _eglSaveSurface(&surf->base);
+ return surf->base.Handle;
+
+err_surf:
+ free(surf);
+err:
+ return EGL_NO_SURFACE;
+}
+
+EGLSurface
+drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
+ const EGLint *attrib_list)
+{
+ EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
+
+ return surf;
+}
+
+EGLBoolean
+drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
+ EGLScreenMESA screen,
+ EGLSurface surface, EGLModeMESA m)
+{
+ struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_surface *surf = lookup_drm_surface(surface);
+ struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
+ _EGLMode *mode = _eglLookupMode(dpy, m);
+ int ret;
+ unsigned int i, k;
+
+ if (scrn->shown)
+ drm_takedown_shown_screen(drv, scrn);
+
+
+ drm_create_texture(drv, scrn, mode->Width, mode->Height);
+ if (!scrn->buffer)
+ return EGL_FALSE;
+
+ ret = drmModeAddFB(dev->drmFD,
+ scrn->front.width, scrn->front.height,
+ 32, 32, scrn->front.pitch,
+ scrn->front.handle,
+ &scrn->fbID);
+
+ if (ret)
+ goto err_bo;
+
+ scrn->fb = drmModeGetFB(dev->drmFD, scrn->fbID);
+ if (!scrn->fb)
+ goto err_bo;
+
+ /* find a fitting crtc */
+ {
+ drmModeConnector *con = scrn->connector;
+
+ scrn->mode = drm_find_mode(con, mode);
+ if (!scrn->mode)
+ goto err_fb;
+
+ for (k = 0; k < con->count_encoders; k++) {
+ drmModeEncoder *enc = drmModeGetEncoder(dev->drmFD, con->encoders[k]);
+ for (i = 0; i < dev->res->count_crtcs; i++) {
+ if (enc->possible_crtcs & (1<<i)) {
+ /* save the ID */
+ scrn->crtcID = dev->res->crtcs[i];
+
+ /* skip the rest */
+ i = dev->res->count_crtcs;
+ k = dev->res->count_encoders;
+ }
+ }
+ drmModeFreeEncoder(enc);
+ }
+ }
+
+ ret = drmModeSetCrtc(dev->drmFD,
+ scrn->crtcID,
+ scrn->fbID,
+ 0, 0,
+ &scrn->connectorID, 1,
+ scrn->mode);
+
+ if (ret)
+ goto err_crtc;
+
+ surf->screen = scrn;
+
+ scrn->surf = surf;
+ scrn->shown = 1;
+
+ return EGL_TRUE;
+
+err_crtc:
+ scrn->crtcID = 0;
+
+err_fb:
+ drmModeRmFB(dev->drmFD, scrn->fbID);
+ drmModeFreeFB(scrn->fb);
+ scrn->fb = NULL;
+
+err_bo:
+ pipe_surface_reference(&scrn->surface, NULL);
+ pipe_texture_reference(&scrn->tex, NULL);
+ pipe_buffer_reference(dev->screen, &scrn->buffer, NULL);
+
+ return EGL_FALSE;
+}
+
+EGLBoolean
+drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+{
+ struct drm_surface *surf = lookup_drm_surface(surface);
+ _eglRemoveSurface(&surf->base);
+ if (surf->base.IsBound) {
+ surf->base.DeletePending = EGL_TRUE;
+ } else {
+ if (surf->screen)
+ drm_takedown_shown_screen(drv, surf->screen);
+ st_unreference_framebuffer(surf->stfb);
+ free(surf);
+ }
+ return EGL_TRUE;
+}
+
+EGLBoolean
+drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+{
+ struct drm_surface *surf = lookup_drm_surface(draw);
+ struct pipe_surface *back_surf;
+
+ if (!surf)
+ return EGL_FALSE;
+
+ /* error checking */
+ if (!_eglSwapBuffers(drv, dpy, draw))
+ return EGL_FALSE;
+
+ back_surf = st_get_framebuffer_surface(surf->stfb,
+ ST_SURFACE_BACK_LEFT);
+
+ if (back_surf) {
+
+ st_notify_swapbuffers(surf->stfb);
+
+ if (surf->screen) {
+ surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
+ surf->user->pipe->surface_copy(surf->user->pipe,
+ 0,
+ surf->screen->surface,
+ 0, 0,
+ back_surf,
+ 0, 0,
+ surf->w, surf->h);
+ surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
+ /* TODO stuff here */
+ }
+
+ st_notify_swapbuffers_complete(surf->stfb);
+ }
+
+ return EGL_TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
new file mode 100644
index 0000000000..3ca5acb68b
--- /dev/null
+++ b/src/gallium/state_trackers/egl/egl_tracker.c
@@ -0,0 +1,217 @@
+
+#include "utils.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "egl_tracker.h"
+
+#include "egllog.h"
+#include "state_tracker/drm_api.h"
+
+#include "pipe/p_screen.h"
+#include "pipe/p_winsys.h"
+
+/** HACK */
+void* driDriverAPI;
+extern const struct dri_extension card_extensions[];
+
+
+/*
+ * Exported functions
+ */
+
+/**
+ * The bootstrap function. Return a new drm_driver object and
+ * plug in API functions.
+ */
+_EGLDriver *
+_eglMain(_EGLDisplay *dpy, const char *args)
+{
+ struct drm_device *drm;
+
+ drm = (struct drm_device *) calloc(1, sizeof(struct drm_device));
+ if (!drm) {
+ return NULL;
+ }
+
+ /* First fill in the dispatch table with defaults */
+ _eglInitDriverFallbacks(&drm->base);
+ /* then plug in our Drm-specific functions */
+ drm->base.API.Initialize = drm_initialize;
+ drm->base.API.Terminate = drm_terminate;
+ drm->base.API.CreateContext = drm_create_context;
+ drm->base.API.MakeCurrent = drm_make_current;
+ drm->base.API.CreateWindowSurface = drm_create_window_surface;
+ drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
+ drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
+ drm->base.API.DestroySurface = drm_destroy_surface;
+ drm->base.API.DestroyContext = drm_destroy_context;
+ drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
+ drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
+ drm->base.API.SwapBuffers = drm_swap_buffers;
+
+ drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+ drm->base.Name = "DRM/Gallium/Win";
+
+ /* enable supported extensions */
+ drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
+ drm->base.Extensions.MESA_copy_context = EGL_TRUE;
+
+ return &drm->base;
+}
+
+static void
+drm_get_device_id(struct drm_device *device)
+{
+ char path[512];
+ FILE *file;
+
+ /* TODO get the real minor */
+ int minor = 0;
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
+ file = fopen(path, "r");
+ if (!file) {
+ _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
+ return;
+ }
+
+ fgets(path, sizeof( path ), file);
+ sscanf(path, "%x", &device->deviceID);
+ fclose(file);
+}
+
+static void
+drm_update_res(struct drm_device *dev)
+{
+ drmModeFreeResources(dev->res);
+ dev->res = drmModeGetResources(dev->drmFD);
+}
+
+static void
+drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
+{
+ struct drm_mode_modeinfo *m;
+ int i;
+
+ for (i = 0; i < connector->count_modes; i++) {
+ m = &connector->modes[i];
+ _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
+ }
+}
+
+EGLBoolean
+drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_screen *screen = NULL;
+ drmModeConnectorPtr connector = NULL;
+ drmModeResPtr res = NULL;
+ unsigned count_connectors = 0;
+ int num_screens = 0;
+ EGLint i;
+ int fd;
+
+ fd = drmOpen("i915", NULL);
+ if (fd < 0)
+ goto err_fd;
+
+ dev->drmFD = fd;
+ drm_get_device_id(dev);
+
+ dev->screen = drm_api_hocks.create_screen(dev->drmFD, dev->deviceID);
+ if (!dev->screen)
+ goto err_screen;
+ dev->winsys = dev->screen->winsys;
+
+ /* TODO HACK */
+ driInitExtensions(NULL, card_extensions, GL_FALSE);
+
+ drm_update_res(dev);
+ res = dev->res;
+ if (res)
+ count_connectors = res->count_connectors;
+ else
+ _eglLog(_EGL_WARNING, "Could not retrive kms information\n");
+
+ for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
+ connector = drmModeGetConnector(fd, res->connectors[i]);
+
+ if (!connector)
+ continue;
+
+ if (connector->connection != DRM_MODE_CONNECTED) {
+ drmModeFreeConnector(connector);
+ continue;
+ }
+
+ screen = malloc(sizeof(struct drm_screen));
+ memset(screen, 0, sizeof(*screen));
+ screen->connector = connector;
+ screen->connectorID = connector->connector_id;
+ _eglInitScreen(&screen->base);
+ _eglAddScreen(disp, &screen->base);
+ drm_add_modes_from_connector(&screen->base, connector);
+ dev->screens[num_screens++] = screen;
+ }
+ dev->count_screens = num_screens;
+
+ /* for now we only have one config */
+ _EGLConfig *config = calloc(1, sizeof(*config));
+ memset(config, 1, sizeof(*config));
+ _eglInitConfig(config, 1);
+ _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
+ _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
+ _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
+ _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
+ _eglAddConfig(disp, config);
+
+ drv->Initialized = EGL_TRUE;
+
+ *major = 1;
+ *minor = 4;
+
+ return EGL_TRUE;
+
+err_screen:
+ drmClose(fd);
+err_fd:
+ return EGL_FALSE;
+}
+
+EGLBoolean
+drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
+{
+ struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_screen *screen;
+ int i = 0;
+
+ drmFreeVersion(dev->version);
+
+ for (i = 0; i < dev->count_screens; i++) {
+ screen = dev->screens[i];
+
+ if (screen->shown)
+ drm_takedown_shown_screen(drv, screen);
+
+ drmModeFreeConnector(screen->connector);
+ _eglDestroyScreen(&screen->base);
+ dev->screens[i] = NULL;
+ }
+
+ dev->screen->destroy(dev->screen);
+ dev->winsys = NULL;
+
+ drmClose(dev->drmFD);
+
+ _eglCleanupDisplay(_eglLookupDisplay(dpy));
+ free(dev);
+
+ return EGL_TRUE;
+}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h
new file mode 100644
index 0000000000..0b4dd9797d
--- /dev/null
+++ b/src/gallium/state_trackers/egl/egl_tracker.h
@@ -0,0 +1,191 @@
+
+#ifndef _EGL_TRACKER_H_
+#define _EGL_TRACKER_H_
+
+#include <stdint.h>
+
+#include "eglconfig.h"
+#include "eglcontext.h"
+#include "egldisplay.h"
+#include "egldriver.h"
+#include "eglglobals.h"
+#include "eglmode.h"
+#include "eglscreen.h"
+#include "eglsurface.h"
+
+#include "xf86drm.h"
+#include "xf86drmMode.h"
+
+#include "pipe/p_compiler.h"
+
+#include "state_tracker/st_public.h"
+
+#define MAX_SCREENS 16
+
+struct pipe_winsys;
+struct pipe_screen;
+struct pipe_context;
+struct state_tracker;
+
+struct drm_screen;
+struct drm_context;
+
+struct drm_device
+{
+ _EGLDriver base; /* base class/object */
+
+ /*
+ * pipe
+ */
+
+ struct pipe_winsys *winsys;
+ struct pipe_screen *screen;
+
+ /*
+ * drm
+ */
+
+ int drmFD;
+ drmVersionPtr version;
+ int deviceID;
+
+ drmModeResPtr res;
+
+ struct drm_screen *screens[MAX_SCREENS];
+ size_t count_screens;
+};
+
+struct drm_surface
+{
+ _EGLSurface base; /* base class/object */
+
+ /*
+ * pipe
+ */
+
+
+ struct st_framebuffer *stfb;
+
+ /*
+ * drm
+ */
+
+ struct drm_context *user;
+ struct drm_screen *screen;
+
+ int w;
+ int h;
+};
+
+struct drm_context
+{
+ _EGLContext base; /* base class/object */
+
+ /* pipe */
+
+ struct pipe_context *pipe;
+ struct st_context *st;
+};
+
+struct drm_screen
+{
+ _EGLScreen base;
+
+ /*
+ * pipe
+ */
+
+ struct pipe_buffer *buffer;
+ struct pipe_texture *tex;
+ struct pipe_surface *surface;
+
+ /*
+ * drm
+ */
+
+ struct {
+ unsigned height;
+ unsigned width;
+ unsigned pitch;
+ unsigned handle;
+ } front;
+
+ /* currently only support one connector */
+ drmModeConnectorPtr connector;
+ uint32_t connectorID;
+
+ /* Has this screen been shown */
+ int shown;
+
+ /* Surface that is currently attached to this screen */
+ struct drm_surface *surf;
+
+ /* framebuffer */
+ drmModeFBPtr fb;
+ uint32_t fbID;
+
+ /* crtc and mode used */
+ /*drmModeCrtcPtr crtc;*/
+ uint32_t crtcID;
+
+ struct drm_mode_modeinfo *mode;
+};
+
+
+static INLINE struct drm_context *
+lookup_drm_context(EGLContext context)
+{
+ _EGLContext *c = _eglLookupContext(context);
+ return (struct drm_context *) c;
+}
+
+
+static INLINE struct drm_surface *
+lookup_drm_surface(EGLSurface surface)
+{
+ _EGLSurface *s = _eglLookupSurface(surface);
+ return (struct drm_surface *) s;
+}
+
+static INLINE struct drm_screen *
+lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
+{
+ _EGLScreen *s = _eglLookupScreen(dpy, screen);
+ return (struct drm_screen *) s;
+}
+
+/**
+ * egl_visual.h
+ */
+/*@{*/
+void drm_visual_modes_destroy(__GLcontextModes *modes);
+__GLcontextModes* drm_visual_modes_create(unsigned count, size_t minimum_size);
+__GLcontextModes* drm_visual_from_config(_EGLConfig *conf);
+/*@}*/
+
+/**
+ * egl_surface.h
+ */
+/*@{*/
+void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen);
+/*@}*/
+
+/**
+ * All function exported to the egl side.
+ */
+/*@{*/
+EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor);
+EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy);
+EGLContext drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
+EGLBoolean drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context);
+EGLSurface drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
+EGLSurface drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
+EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+EGLSurface drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, const EGLint *attrib_list);
+EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA m);
+EGLBoolean drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
+EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context);
+EGLBoolean drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
+/*@}*/
+
+#endif
diff --git a/src/gallium/state_trackers/egl/egl_visual.c b/src/gallium/state_trackers/egl/egl_visual.c
new file mode 100644
index 0000000000..e59f893851
--- /dev/null
+++ b/src/gallium/state_trackers/egl/egl_visual.c
@@ -0,0 +1,85 @@
+
+#include "egl_tracker.h"
+
+#include "egllog.h"
+
+void
+drm_visual_modes_destroy(__GLcontextModes *modes)
+{
+ _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
+
+ while (modes) {
+ __GLcontextModes * const next = modes->next;
+ free(modes);
+ modes = next;
+ }
+}
+
+__GLcontextModes *
+drm_visual_modes_create(unsigned count, size_t minimum_size)
+{
+ /* This code copied from libGLX, and modified */
+ const size_t size = (minimum_size > sizeof(__GLcontextModes))
+ ? minimum_size : sizeof(__GLcontextModes);
+ __GLcontextModes * head = NULL;
+ __GLcontextModes ** next;
+ unsigned i;
+
+ _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
+
+ next = & head;
+ for (i = 0 ; i < count ; i++) {
+ *next = (__GLcontextModes *) calloc(1, size);
+ if (*next == NULL) {
+ drm_visual_modes_destroy(head);
+ head = NULL;
+ break;
+ }
+
+ (*next)->doubleBufferMode = 1;
+ (*next)->visualID = GLX_DONT_CARE;
+ (*next)->visualType = GLX_DONT_CARE;
+ (*next)->visualRating = GLX_NONE;
+ (*next)->transparentPixel = GLX_NONE;
+ (*next)->transparentRed = GLX_DONT_CARE;
+ (*next)->transparentGreen = GLX_DONT_CARE;
+ (*next)->transparentBlue = GLX_DONT_CARE;
+ (*next)->transparentAlpha = GLX_DONT_CARE;
+ (*next)->transparentIndex = GLX_DONT_CARE;
+ (*next)->xRenderable = GLX_DONT_CARE;
+ (*next)->fbconfigID = GLX_DONT_CARE;
+ (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ (*next)->bindToTextureRgb = GLX_DONT_CARE;
+ (*next)->bindToTextureRgba = GLX_DONT_CARE;
+ (*next)->bindToMipmapTexture = GLX_DONT_CARE;
+ (*next)->bindToTextureTargets = 0;
+ (*next)->yInverted = GLX_DONT_CARE;
+
+ next = & ((*next)->next);
+ }
+
+ return head;
+}
+
+__GLcontextModes *
+drm_visual_from_config(_EGLConfig *conf)
+{
+ __GLcontextModes *visual;
+ (void)conf;
+
+ visual = drm_visual_modes_create(1, sizeof(*visual));
+ visual->redBits = 8;
+ visual->greenBits = 8;
+ visual->blueBits = 8;
+ visual->alphaBits = 8;
+
+ visual->rgbBits = 32;
+ visual->doubleBufferMode = 1;
+
+ visual->depthBits = 24;
+ visual->haveDepthBuffer = visual->depthBits > 0;
+ visual->stencilBits = 8;
+ visual->haveStencilBuffer = visual->stencilBits > 0;
+
+ return visual;
+}
diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
index 3ce93cf49d..da119ff1bd 100644
--- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
+++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
@@ -71,7 +71,10 @@ static int vlResizeFrameBuffer
basic_csc->viewport.translate[3] = 0;
if (basic_csc->framebuffer_tex)
- pipe_texture_release(&basic_csc->framebuffer_tex);
+ {
+ pipe_surface_reference(&basic_csc->framebuffer.cbufs[0], NULL);
+ pipe_texture_reference(&basic_csc->framebuffer_tex, NULL);
+ }
memset(&template, 0, sizeof(struct pipe_texture));
template.target = PIPE_TEXTURE_2D;
@@ -153,11 +156,11 @@ static int vlPutPictureCSC
basic_csc = (struct vlBasicCSC*)csc;
pipe = basic_csc->pipe;
- vs_consts = pipe->winsys->buffer_map
+ vs_consts = pipe_buffer_map
(
- pipe->winsys,
+ pipe->screen,
basic_csc->vs_const_buf.buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
vs_consts->dst_scale.x = destw / (float)basic_csc->framebuffer.cbufs[0]->width;
@@ -178,7 +181,7 @@ static int vlPutPictureCSC
vs_consts->src_trans.z = 0;
vs_consts->src_trans.w = 0;
- pipe->winsys->buffer_unmap(pipe->winsys, basic_csc->vs_const_buf.buffer);
+ pipe_buffer_unmap(pipe->screen, basic_csc->vs_const_buf.buffer);
pipe->set_sampler_textures(pipe, 1, &surface->texture);
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
@@ -225,17 +228,20 @@ static int vlDestroy
pipe = basic_csc->pipe;
if (basic_csc->framebuffer_tex)
- pipe_texture_release(&basic_csc->framebuffer_tex);
+ {
+ pipe_surface_reference(&basic_csc->framebuffer.cbufs[0], NULL);
+ pipe_texture_reference(&basic_csc->framebuffer_tex, NULL);
+ }
pipe->delete_sampler_state(pipe, basic_csc->sampler);
pipe->delete_vs_state(pipe, basic_csc->vertex_shader);
pipe->delete_fs_state(pipe, basic_csc->fragment_shader);
for (i = 0; i < 2; ++i)
- pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vertex_bufs[i].buffer);
+ pipe_buffer_reference(pipe->screen, &basic_csc->vertex_bufs[i].buffer, NULL);
- pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->vs_const_buf.buffer);
- pipe->winsys->buffer_destroy(pipe->winsys, basic_csc->fs_const_buf.buffer);
+ pipe_buffer_reference(pipe->screen, &basic_csc->vs_const_buf.buffer, NULL);
+ pipe_buffer_reference(pipe->screen, &basic_csc->fs_const_buf.buffer, NULL);
FREE(basic_csc);
@@ -542,9 +548,9 @@ static int vlCreateDataBufs
csc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f);
csc->vertex_bufs[0].max_index = 3;
csc->vertex_bufs[0].buffer_offset = 0;
- csc->vertex_bufs[0].buffer = pipe->winsys->buffer_create
+ csc->vertex_bufs[0].buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
1,
PIPE_BUFFER_USAGE_VERTEX,
sizeof(struct vlVertex2f) * 4
@@ -552,12 +558,12 @@ static int vlCreateDataBufs
memcpy
(
- pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+ pipe_buffer_map(pipe->screen, csc->vertex_bufs[0].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
surface_verts,
sizeof(struct vlVertex2f) * 4
);
- pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[0].buffer);
+ pipe_buffer_unmap(pipe->screen, csc->vertex_bufs[0].buffer);
csc->vertex_elems[0].src_offset = 0;
csc->vertex_elems[0].vertex_buffer_index = 0;
@@ -571,9 +577,9 @@ static int vlCreateDataBufs
csc->vertex_bufs[1].pitch = sizeof(struct vlVertex2f);
csc->vertex_bufs[1].max_index = 3;
csc->vertex_bufs[1].buffer_offset = 0;
- csc->vertex_bufs[1].buffer = pipe->winsys->buffer_create
+ csc->vertex_bufs[1].buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
1,
PIPE_BUFFER_USAGE_VERTEX,
sizeof(struct vlVertex2f) * 4
@@ -581,12 +587,12 @@ static int vlCreateDataBufs
memcpy
(
- pipe->winsys->buffer_map(pipe->winsys, csc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+ pipe_buffer_map(pipe->screen, csc->vertex_bufs[1].buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
surface_texcoords,
sizeof(struct vlVertex2f) * 4
);
- pipe->winsys->buffer_unmap(pipe->winsys, csc->vertex_bufs[1].buffer);
+ pipe_buffer_unmap(pipe->screen, csc->vertex_bufs[1].buffer);
csc->vertex_elems[1].src_offset = 0;
csc->vertex_elems[1].vertex_buffer_index = 1;
@@ -598,11 +604,11 @@ static int vlCreateDataBufs
* Const buffer contains scaling and translation vectors
*/
csc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
- csc->vs_const_buf.buffer = pipe->winsys->buffer_create
+ csc->vs_const_buf.buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
1,
- PIPE_BUFFER_USAGE_CONSTANT,
+ PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
csc->vs_const_buf.size
);
@@ -611,9 +617,9 @@ static int vlCreateDataBufs
* Const buffer contains the color conversion matrix and bias vectors
*/
csc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
- csc->fs_const_buf.buffer = pipe->winsys->buffer_create
+ csc->fs_const_buf.buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
1,
PIPE_BUFFER_USAGE_CONSTANT,
csc->fs_const_buf.size
@@ -625,12 +631,12 @@ static int vlCreateDataBufs
*/
memcpy
(
- pipe->winsys->buffer_map(pipe->winsys, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+ pipe_buffer_map(pipe->screen, csc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
&bt_601_full,
sizeof(struct vlFragmentShaderConsts)
);
- pipe->winsys->buffer_unmap(pipe->winsys, csc->fs_const_buf.buffer);
+ pipe_buffer_unmap(pipe->screen, csc->fs_const_buf.buffer);
return 0;
}
diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c
index c5a73b2bf2..f0f8294473 100644
--- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c
+++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf.c
@@ -297,6 +297,7 @@ static inline int vlGrabMacroBlock
{
assert(mc);
assert(macroblock);
+ assert(mc->num_macroblocks < mc->macroblocks_per_picture);
mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx;
mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby;
@@ -330,6 +331,7 @@ static inline int vlGrabMacroBlock
}
#define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \
+ do { \
(vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \
(vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \
(vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \
@@ -392,7 +394,8 @@ static inline int vlGrabMacroBlock
(vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \
(vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \
(vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
- }
+ } \
+ } while (0)
static inline int vlGenMacroblockVerts
(
@@ -409,6 +412,7 @@ static inline int vlGenMacroblockVerts
assert(mc);
assert(macroblock);
assert(ycbcr_vb);
+ assert(pos < mc->macroblocks_per_picture);
switch (macroblock->mb_type)
{
@@ -581,6 +585,8 @@ static int vlFlush
if (mc->num_macroblocks < mc->macroblocks_per_picture)
return 0;
+ assert(mc->num_macroblocks <= mc->macroblocks_per_picture);
+
pipe = mc->pipe;
for (i = 0; i < mc->num_macroblocks; ++i)
@@ -599,19 +605,19 @@ static int vlFlush
struct vlMacroBlockVertexStream0 *ycbcr_vb;
struct vlVertex2f *ref_vb[2];
- ycbcr_vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
+ ycbcr_vb = (struct vlMacroBlockVertexStream0*)pipe_buffer_map
(
- mc->pipe->winsys,
+ pipe->screen,
mc->vertex_bufs.ycbcr.buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
for (i = 0; i < 2; ++i)
- ref_vb[i] = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
+ ref_vb[i] = (struct vlVertex2f*)pipe_buffer_map
(
- mc->pipe->winsys,
+ pipe->screen,
mc->vertex_bufs.ref[i].buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
for (i = 0; i < mc->num_macroblocks; ++i)
@@ -623,15 +629,15 @@ static int vlFlush
offset[mb_type_ex]++;
}
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ycbcr.buffer);
+ pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ycbcr.buffer);
for (i = 0; i < 2; ++i)
- mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs.ref[i].buffer);
+ pipe_buffer_unmap(pipe->screen, mc->vertex_bufs.ref[i].buffer);
}
for (i = 0; i < 3; ++i)
{
pipe_surface_unmap(mc->tex_surface[i]);
- mc->pipe->screen->tex_surface_release(mc->pipe->screen, &mc->tex_surface[i]);
+ pipe_surface_reference(&mc->tex_surface[i], NULL);
}
mc->render_target.cbufs[0] = pipe->screen->get_tex_surface
@@ -647,13 +653,13 @@ static int vlFlush
(
pipe->winsys,
mc->vs_const_buf.buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE
+ PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
vs_consts->denorm.x = mc->buffered_surface->texture->width[0];
vs_consts->denorm.y = mc->buffered_surface->texture->height[0];
- pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer);
+ pipe_buffer_unmap(pipe->screen, mc->vs_const_buf.buffer);
pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf);
pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf);
@@ -757,7 +763,7 @@ static int vlFlush
}
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
- pipe->screen->tex_surface_release(pipe->screen, &mc->render_target.cbufs[0]);
+ pipe_surface_reference(&mc->render_target.cbufs[0], NULL);
for (i = 0; i < 3; ++i)
mc->zero_block[i].x = -1.0f;
@@ -808,10 +814,10 @@ static int vlRenderMacroBlocksMpeg2R16SnormBuffered
(
mc->pipe->screen,
mc->textures.all[i],
- 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
+ 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD
);
- mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE);
+ mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_DISCARD);
}
}
@@ -849,11 +855,11 @@ static int vlDestroy
pipe->delete_sampler_state(pipe, mc->samplers.all[i]);
for (i = 0; i < 3; ++i)
- pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs.all[i].buffer);
+ pipe_buffer_reference(pipe->screen, &mc->vertex_bufs.all[i].buffer, NULL);
/* Textures 3 & 4 are not created directly, no need to release them here */
for (i = 0; i < 3; ++i)
- pipe_texture_release(&mc->textures.all[i]);
+ pipe_texture_reference(&mc->textures.all[i], NULL);
pipe->delete_vs_state(pipe, mc->i_vs);
pipe->delete_fs_state(pipe, mc->i_fs);
@@ -866,8 +872,8 @@ static int vlDestroy
pipe->delete_fs_state(pipe, mc->b_fs[i]);
}
- pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
- pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
+ pipe_buffer_reference(pipe->screen, &mc->vs_const_buf.buffer, NULL);
+ pipe_buffer_reference(pipe->screen, &mc->fs_const_buf.buffer, NULL);
FREE(mc->macroblocks);
FREE(mc);
@@ -909,11 +915,11 @@ static int vlCreateDataBufs
mc->vertex_bufs.ycbcr.pitch = sizeof(struct vlVertex2f) * 4;
mc->vertex_bufs.ycbcr.max_index = 24 * mc->macroblocks_per_picture - 1;
mc->vertex_bufs.ycbcr.buffer_offset = 0;
- mc->vertex_bufs.ycbcr.buffer = pipe->winsys->buffer_create
+ mc->vertex_bufs.ycbcr.buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_VERTEX,
+ PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
sizeof(struct vlVertex2f) * 4 * 24 * mc->macroblocks_per_picture
);
@@ -922,11 +928,11 @@ static int vlCreateDataBufs
mc->vertex_bufs.all[i].pitch = sizeof(struct vlVertex2f) * 2;
mc->vertex_bufs.all[i].max_index = 24 * mc->macroblocks_per_picture - 1;
mc->vertex_bufs.all[i].buffer_offset = 0;
- mc->vertex_bufs.all[i].buffer = pipe->winsys->buffer_create
+ mc->vertex_bufs.all[i].buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_VERTEX,
+ PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_DISCARD,
sizeof(struct vlVertex2f) * 2 * 24 * mc->macroblocks_per_picture
);
}
@@ -981,18 +987,18 @@ static int vlCreateDataBufs
/* Create our constant buffer */
mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
- mc->vs_const_buf.buffer = pipe->winsys->buffer_create
+ mc->vs_const_buf.buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
DEFAULT_BUF_ALIGNMENT,
- PIPE_BUFFER_USAGE_CONSTANT,
+ PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD,
mc->vs_const_buf.size
);
mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
- mc->fs_const_buf.buffer = pipe->winsys->buffer_create
+ mc->fs_const_buf.buffer = pipe_buffer_create
(
- pipe->winsys,
+ pipe->screen,
DEFAULT_BUF_ALIGNMENT,
PIPE_BUFFER_USAGE_CONSTANT,
mc->fs_const_buf.size
@@ -1000,12 +1006,12 @@ static int vlCreateDataBufs
memcpy
(
- pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
+ pipe_buffer_map(pipe->screen, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
&fs_consts,
sizeof(struct vlFragmentShaderConsts)
);
- pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
+ pipe_buffer_unmap(pipe->screen, mc->fs_const_buf.buffer);
mc->macroblocks = MALLOC(sizeof(struct vlMpeg2MacroBlock) * mc->macroblocks_per_picture);
diff --git a/src/gallium/state_trackers/g3dvl/vl_surface.c b/src/gallium/state_trackers/g3dvl/vl_surface.c
index 911469f966..0fa7b25b92 100644
--- a/src/gallium/state_trackers/g3dvl/vl_surface.c
+++ b/src/gallium/state_trackers/g3dvl/vl_surface.c
@@ -51,6 +51,12 @@ int vlCreateSurface
sfc->texture = vlGetPipeScreen(screen)->texture_create(vlGetPipeScreen(screen), &template);
+ if (!sfc->texture)
+ {
+ FREE(sfc);
+ return 1;
+ }
+
*surface = sfc;
return 0;
@@ -63,7 +69,7 @@ int vlDestroySurface
{
assert(surface);
- pipe_texture_release(&surface->texture);
+ pipe_texture_reference(&surface->texture, NULL);
FREE(surface);
return 0;
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template
index 80e817b808..211f4d875e 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/winsys/drm/Makefile.template
@@ -84,14 +84,14 @@ default: depend symlinks $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(LIBNAME_EGL)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
$(TOP)/bin/mklib -noprefix -o $@ \
- $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS)
+ $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS)
$(TOP)/bin/mklib -o $(LIBNAME_EGL) \
-linker "$(CC)" \
-noprefix \
$(OBJECTS) $(MKLIB_OPTIONS) $(WINSYS_OBJECTS) $(PIPE_DRIVERS) $(WINOBJ) $(DRI_LIB_DEPS) \
- --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive
+ --whole-archive $(LIBS) $(GALLIUM_AUXILIARIES) --no-whole-archive $(DRIVER_EXTRAS)
$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME)
$(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR)
diff --git a/src/gallium/winsys/drm/intel/Makefile b/src/gallium/winsys/drm/intel/Makefile
index a670ac044d..eede9fc866 100644
--- a/src/gallium/winsys/drm/intel/Makefile
+++ b/src/gallium/winsys/drm/intel/Makefile
@@ -2,7 +2,7 @@ TOP = ../../../../..
include $(TOP)/configs/current
-SUBDIRS = common dri egl
+SUBDIRS = gem egl
default: subdirs
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
index f0b5a44389..4b22d17ccf 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -6,21 +6,23 @@ LIBNAME = EGL_i915.so
PIPE_DRIVERS = \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
- ../common/libinteldrm.a
+ $(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
+ ../gem/libinteldrm.a
DRIVER_SOURCES = \
- intel_swapbuffers.c \
intel_context.c \
intel_device.c \
- intel_egl.c
+ intel_api.c
C_SOURCES = \
$(COMMON_GALLIUM_SOURCES) \
$(DRIVER_SOURCES)
+DRIVER_EXTRAS = -ldrm_intel
+
ASM_SOURCES =
-DRIVER_DEFINES = -I../common $(shell pkg-config libdrm --atleast-version=2.3.1 \
+DRIVER_DEFINES = -I../gem $(shell pkg-config libdrm --atleast-version=2.3.1 \
&& echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
include ../../Makefile.template
diff --git a/src/gallium/winsys/drm/intel/egl/SConscript b/src/gallium/winsys/drm/intel/egl/SConscript
deleted file mode 100644
index 0ad19d42a8..0000000000
--- a/src/gallium/winsys/drm/intel/egl/SConscript
+++ /dev/null
@@ -1,39 +0,0 @@
-Import('*')
-
-env = drienv.Clone()
-
-env.Append(CPPPATH = [
- '../intel',
- 'server'
-])
-
-#MINIGLX_SOURCES = server/intel_dri.c
-
-DRIVER_SOURCES = [
- 'intel_winsys_pipe.c',
- 'intel_winsys_softpipe.c',
- 'intel_winsys_i915.c',
- 'intel_batchbuffer.c',
- 'intel_swapbuffers.c',
- 'intel_context.c',
- 'intel_lock.c',
- 'intel_screen.c',
- 'intel_batchpool.c',
-]
-
-sources = \
- COMMON_GALLIUM_SOURCES + \
- COMMON_BM_SOURCES + \
- DRIVER_SOURCES
-
-drivers = [
- softpipe,
- i915simple
-]
-
-# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions
-env.SharedLibrary(
- target ='i915tex_dri.so',
- source = sources,
- LIBS = drivers + mesa + auxiliaries + env['LIBS'],
-) \ No newline at end of file
diff --git a/src/gallium/winsys/drm/intel/egl/intel_api.c b/src/gallium/winsys/drm/intel/egl/intel_api.c
new file mode 100644
index 0000000000..5dc4a7b052
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_api.c
@@ -0,0 +1,10 @@
+
+#include "intel_api.h"
+
+struct drm_api drm_api_hocks =
+{
+ .create_screen = intel_create_screen,
+ .create_context = intel_create_context,
+ .buffer_from_handle = intel_be_buffer_from_handle,
+ .handle_from_buffer = intel_be_handle_from_buffer,
+};
diff --git a/src/gallium/winsys/drm/intel/egl/intel_api.h b/src/gallium/winsys/drm/intel/egl/intel_api.h
new file mode 100644
index 0000000000..8ec165ab01
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/egl/intel_api.h
@@ -0,0 +1,14 @@
+
+#ifndef _INTEL_API_H_
+#define _INTEL_API_H_
+
+#include "pipe/p_compiler.h"
+
+#include "state_tracker/drm_api.h"
+
+#include "intel_be_device.h"
+
+struct pipe_screen *intel_create_screen(int drmFD, int pciID);
+struct pipe_context *intel_create_context(struct pipe_screen *screen);
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h b/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h
deleted file mode 100644
index 3e95326168..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_batchbuffer.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef INTEL_BATCHBUFFER_H
-#define INTEL_BATCHBUFFER_H
-
-#include "intel_be_batchbuffer.h"
-
-/*
- * Need to redefine the BATCH defines
- */
-
-#undef BEGIN_BATCH
-#define BEGIN_BATCH(dwords, relocs) \
- (i915_batchbuffer_check(&intel->base.batch->base, dwords, relocs))
-
-#undef OUT_BATCH
-#define OUT_BATCH(d) \
- i915_batchbuffer_dword(&intel->base.batch->base, d)
-
-#undef OUT_RELOC
-#define OUT_RELOC(buf,flags,mask,delta) do { \
- assert((delta) >= 0); \
- intel_be_offset_relocation(intel->base.batch, delta, buf, flags, mask); \
-} while (0)
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.c b/src/gallium/winsys/drm/intel/egl/intel_context.c
index 927addb834..57e5ff7bc1 100644
--- a/src/gallium/winsys/drm/intel/egl/intel_context.c
+++ b/src/gallium/winsys/drm/intel/egl/intel_context.c
@@ -1,119 +1,21 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
#include "i915simple/i915_screen.h"
-#include "intel_device.h"
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
+#include "intel_be_device.h"
+#include "intel_be_context.h"
-#include "state_tracker/st_public.h"
#include "pipe/p_defines.h"
#include "pipe/p_context.h"
-#include "intel_egl.h"
-#include "utils.h"
-#ifdef DEBUG
-int __intel_debug = 0;
-#endif
+#include "intel_api.h"
+struct intel_context
+{
+ struct intel_be_context base;
-#define need_GL_ARB_multisample
-#define need_GL_ARB_point_parameters
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_ARB_vertex_program
-#define need_GL_ARB_window_pos
-#define need_GL_EXT_blend_color
-#define need_GL_EXT_blend_equation_separate
-#define need_GL_EXT_blend_func_separate
-#define need_GL_EXT_blend_minmax
-#define need_GL_EXT_cull_vertex
-#define need_GL_EXT_fog_coord
-#define need_GL_EXT_framebuffer_object
-#define need_GL_EXT_multi_draw_arrays
-#define need_GL_EXT_secondary_color
-#define need_GL_NV_vertex_program
-#include "extension_helper.h"
-
-
-/**
- * Extension strings exported by the intel driver.
- *
- * \note
- * It appears that ARB_texture_env_crossbar has "disappeared" compared to the
- * old i830-specific driver.
- */
-const struct dri_extension card_extensions[] = {
- {"GL_ARB_multisample", GL_ARB_multisample_functions},
- {"GL_ARB_multitexture", NULL},
- {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
- {"GL_ARB_texture_border_clamp", NULL},
- {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions},
- {"GL_ARB_texture_cube_map", NULL},
- {"GL_ARB_texture_env_add", NULL},
- {"GL_ARB_texture_env_combine", NULL},
- {"GL_ARB_texture_env_dot3", NULL},
- {"GL_ARB_texture_mirrored_repeat", NULL},
- {"GL_ARB_texture_rectangle", NULL},
- {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
- {"GL_ARB_pixel_buffer_object", NULL},
- {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions},
- {"GL_ARB_window_pos", GL_ARB_window_pos_functions},
- {"GL_EXT_blend_color", GL_EXT_blend_color_functions},
- {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions},
- {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions},
- {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions},
- {"GL_EXT_blend_subtract", NULL},
- {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions},
- {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions},
- {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions},
- {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions},
- {"GL_EXT_packed_depth_stencil", NULL},
- {"GL_EXT_pixel_buffer_object", NULL},
- {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
- {"GL_EXT_stencil_wrap", NULL},
- {"GL_EXT_texture_edge_clamp", NULL},
- {"GL_EXT_texture_env_combine", NULL},
- {"GL_EXT_texture_env_dot3", NULL},
- {"GL_EXT_texture_filter_anisotropic", NULL},
- {"GL_EXT_texture_lod_bias", NULL},
- {"GL_3DFX_texture_compression_FXT1", NULL},
- {"GL_APPLE_client_storage", NULL},
- {"GL_MESA_pack_invert", NULL},
- {"GL_MESA_ycbcr_texture", NULL},
- {"GL_NV_blend_square", NULL},
- {"GL_NV_vertex_program", GL_NV_vertex_program_functions},
- {"GL_NV_vertex_program1_1", NULL},
- {"GL_SGIS_generate_mipmap", NULL },
- {NULL, NULL}
+ /* stuff */
};
-
/*
* Hardware lock functions.
* Doesn't do anything in EGL
@@ -142,101 +44,40 @@ intel_locked_hardware(struct intel_be_context *context)
/*
* Misc functions.
*/
+static void
+intel_destroy_be_context(struct i915_winsys *winsys)
+{
+ struct intel_context *intel = (struct intel_context *)winsys;
+
+ intel_be_destroy_context(&intel->base);
+ free(intel);
+}
-int
-intel_create_context(struct egl_drm_context *egl_context, const __GLcontextModes *visual, void *sharedContextPrivate)
+struct pipe_context *
+intel_create_context(struct pipe_screen *screen)
{
- struct intel_context *intel = CALLOC_STRUCT(intel_context);
- struct intel_device *device = (struct intel_device *)egl_context->device->priv;
+ struct intel_context *intel;
struct pipe_context *pipe;
- struct st_context *st_share = NULL;
+ struct intel_be_device *device = (struct intel_be_device *)screen->winsys;
- egl_context->priv = intel;
-
- intel->intel_device = device;
- intel->egl_context = egl_context;
- intel->egl_device = egl_context->device;
+ intel = (struct intel_context *)malloc(sizeof(*intel));
+ memset(intel, 0, sizeof(*intel));
intel->base.hardware_lock = intel_lock_hardware;
intel->base.hardware_unlock = intel_unlock_hardware;
intel->base.hardware_locked = intel_locked_hardware;
- intel_be_init_context(&intel->base, &device->base);
+ intel_be_init_context(&intel->base, device);
+
+ intel->base.base.destroy = intel_destroy_be_context;
#if 0
pipe = intel_create_softpipe(intel, screen->winsys);
#else
- pipe = i915_create_context(device->pipe, &device->base.base, &intel->base.base);
+ pipe = i915_create_context(screen, &device->base, &intel->base.base);
#endif
pipe->priv = intel;
- intel->st = st_create_context(pipe, visual, st_share);
-
- device->dummy = intel;
-
- return TRUE;
-}
-
-int
-intel_destroy_context(struct egl_drm_context *egl_context)
-{
- struct intel_context *intel = egl_context->priv;
-
- if (intel->intel_device->dummy == intel)
- intel->intel_device->dummy = NULL;
-
- st_destroy_context(intel->st);
- intel_be_destroy_context(&intel->base);
- free(intel);
- return TRUE;
-}
-
-void
-intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read)
-{
- if (context) {
- struct intel_context *intel = (struct intel_context *)context->priv;
- struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
- struct intel_framebuffer *read_fb = (struct intel_framebuffer *)read->priv;
-
- assert(draw_fb->stfb);
- assert(read_fb->stfb);
-
- st_make_current(intel->st, draw_fb->stfb, read_fb->stfb);
-
- intel->egl_drawable = draw;
-
- st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
-
- if (draw != read)
- st_resize_framebuffer(read_fb->stfb, read->w, read->h);
-
- } else {
- st_make_current(NULL, NULL, NULL);
- }
-}
-
-void
-intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front)
-{
- struct intel_device *device = (struct intel_device *)draw->device->priv;
- struct intel_framebuffer *draw_fb = (struct intel_framebuffer *)draw->priv;
-
- if (draw_fb->front_buffer)
- driBOUnReference(draw_fb->front_buffer);
-
- draw_fb->front_buffer = NULL;
- draw_fb->front = NULL;
-
- /* to unbind just call this function with front == NULL */
- if (!front)
- return;
-
- draw_fb->front = front;
-
- driGenBuffers(device->base.staticPool, "front", 1, &draw_fb->front_buffer, 0, 0, 0);
- driBOSetReferenced(draw_fb->front_buffer, front->handle);
-
- st_resize_framebuffer(draw_fb->stfb, draw->w, draw->h);
+ return pipe;
}
diff --git a/src/gallium/winsys/drm/intel/egl/intel_context.h b/src/gallium/winsys/drm/intel/egl/intel_context.h
deleted file mode 100644
index 477fdec7f7..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_context.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 INTEL_CONTEXT_H
-#define INTEL_CONTEXT_H
-
-#include "pipe/p_debug.h"
-#include "intel_be_context.h"
-
-
-struct st_context;
-struct egl_drm_device;
-struct egl_drm_context;
-struct egl_drm_frontbuffer;
-
-
-/**
- * Intel rendering context, contains a state tracker and intel-specific info.
- */
-struct intel_context
-{
- struct intel_be_context base;
-
- struct st_context *st;
-
- struct intel_device *intel_device;
-
- /* new egl stuff */
- struct egl_drm_device *egl_device;
- struct egl_drm_context *egl_context;
- struct egl_drm_drawable *egl_drawable;
-};
-
-
-
-/**
- * Intel framebuffer.
- */
-struct intel_framebuffer
-{
- struct st_framebuffer *stfb;
-
- struct intel_device *device;
- struct _DriBufferObject *front_buffer;
- struct egl_drm_frontbuffer *front;
-};
-
-
-
-
-/* These are functions now:
- */
-void LOCK_HARDWARE( struct intel_context *intel );
-void UNLOCK_HARDWARE( struct intel_context *intel );
-
-extern char *__progname;
-
-
-
-/* ================================================================
- * Debugging:
- */
-#ifdef DEBUG
-extern int __intel_debug;
-
-#define DEBUG_SWAP 0x1
-#define DEBUG_LOCK 0x2
-#define DEBUG_IOCTL 0x4
-#define DEBUG_BATCH 0x8
-
-#define DBG(flag, ...) do { \
- if (__intel_debug & (DEBUG_##flag)) \
- printf(__VA_ARGS__); \
-} while(0)
-
-#else
-#define DBG(flag, ...)
-#endif
-
-
-#define PCI_CHIP_845_G 0x2562
-#define PCI_CHIP_I830_M 0x3577
-#define PCI_CHIP_I855_GM 0x3582
-#define PCI_CHIP_I865_G 0x2572
-#define PCI_CHIP_I915_G 0x2582
-#define PCI_CHIP_I915_GM 0x2592
-#define PCI_CHIP_I945_G 0x2772
-#define PCI_CHIP_I945_GM 0x27A2
-#define PCI_CHIP_I945_GME 0x27AE
-#define PCI_CHIP_G33_G 0x29C2
-#define PCI_CHIP_Q35_G 0x29B2
-#define PCI_CHIP_Q33_G 0x29D2
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.c b/src/gallium/winsys/drm/intel/egl/intel_device.c
index 1964745c99..6b281402d5 100644
--- a/src/gallium/winsys/drm/intel/egl/intel_device.c
+++ b/src/gallium/winsys/drm/intel/egl/intel_device.c
@@ -1,137 +1,48 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "utils.h"
-
-#include "state_tracker/st_public.h"
+#include <stdio.h>
+#include "pipe/p_defines.h"
+#include "intel_be_device.h"
#include "i915simple/i915_screen.h"
-#include "intel_context.h"
-#include "intel_device.h"
-#include "intel_batchbuffer.h"
-#include "intel_egl.h"
-
-
-extern const struct dri_extension card_extensions[];
-
+#include "intel_api.h"
-int
-intel_create_device(struct egl_drm_device *device)
+struct intel_device
{
- struct intel_device *intel_device;
-
- /* Allocate the private area */
- intel_device = CALLOC_STRUCT(intel_device);
- if (!intel_device)
- return FALSE;
-
- device->priv = (void *)intel_device;
- intel_device->device = device;
-
- intel_device->deviceID = device->deviceID;
-
- intel_be_init_device(&intel_device->base, device->drmFD, intel_device->deviceID);
+ struct intel_be_device base;
- intel_device->pipe = i915_create_screen(&intel_device->base.base, intel_device->deviceID);
+ int deviceID;
+};
- /* hack */
- driInitExtensions(NULL, card_extensions, GL_FALSE);
-
- return TRUE;
-}
-
-int
-intel_destroy_device(struct egl_drm_device *device)
+static void
+intel_destroy_winsys(struct pipe_winsys *winsys)
{
- struct intel_device *intel_device = (struct intel_device *)device->priv;
-
- intel_be_destroy_device(&intel_device->base);
+ struct intel_device *dev = (struct intel_device *)winsys;
- free(intel_device);
- device->priv = NULL;
+ intel_be_destroy_device(&dev->base);
- return TRUE;
+ free(dev);
}
-int
-intel_create_drawable(struct egl_drm_drawable *drawable,
- const __GLcontextModes * visual)
+struct pipe_screen *
+intel_create_screen(int drmFD, int deviceID)
{
- enum pipe_format colorFormat, depthFormat, stencilFormat;
- struct intel_framebuffer *intelfb = CALLOC_STRUCT(intel_framebuffer);
-
- if (!intelfb)
- return GL_FALSE;
-
- intelfb->device = drawable->device->priv;
+ struct intel_device *dev;
+ struct pipe_screen *screen;
- if (visual->redBits == 5)
- colorFormat = PIPE_FORMAT_R5G6B5_UNORM;
- else
- colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM;
-
- if (visual->depthBits == 16)
- depthFormat = PIPE_FORMAT_Z16_UNORM;
- else if (visual->depthBits == 24)
- depthFormat = PIPE_FORMAT_S8Z24_UNORM;
- else
- depthFormat = PIPE_FORMAT_NONE;
+ /* Allocate the private area */
+ dev = malloc(sizeof(*dev));
+ if (!dev)
+ return NULL;
+ memset(dev, 0, sizeof(*dev));
- if (visual->stencilBits == 8)
- stencilFormat = PIPE_FORMAT_S8Z24_UNORM;
- else
- stencilFormat = PIPE_FORMAT_NONE;
+ dev->deviceID = deviceID;
- intelfb->stfb = st_create_framebuffer(visual,
- colorFormat,
- depthFormat,
- stencilFormat,
- drawable->w,
- drawable->h,
- (void*) intelfb);
+ intel_be_init_device(&dev->base, drmFD, deviceID);
- if (!intelfb->stfb) {
- free(intelfb);
- return GL_FALSE;
- }
+ /* we need to hock our own destroy function in here */
+ dev->base.base.destroy = intel_destroy_winsys;
- drawable->priv = (void *) intelfb;
- return GL_TRUE;
-}
-
-int
-intel_destroy_drawable(struct egl_drm_drawable *drawable)
-{
- struct intel_framebuffer *intelfb = (struct intel_framebuffer *)drawable->priv;
- drawable->priv = NULL;
+ screen = i915_create_screen(&dev->base.base, deviceID);
- assert(intelfb->stfb);
- st_unreference_framebuffer(intelfb->stfb);
- free(intelfb);
- return TRUE;
+ return screen;
}
diff --git a/src/gallium/winsys/drm/intel/egl/intel_device.h b/src/gallium/winsys/drm/intel/egl/intel_device.h
deleted file mode 100644
index 323a7c2aef..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_device.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 _INTEL_SCREEN_H_
-#define _INTEL_SCREEN_H_
-
-#include "intel_be_device.h"
-
-#include "pipe/p_compiler.h"
-
-struct pipe_screen;
-struct egl_drm_device;
-struct intel_context;
-
-struct intel_device
-{
- struct intel_be_device base;
- struct pipe_screen *pipe;
-
- int deviceID;
- struct egl_drm_device *device;
-
- struct intel_context *dummy;
-};
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.c b/src/gallium/winsys/drm/intel/egl/intel_egl.c
deleted file mode 100644
index ed464076ee..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_egl.c
+++ /dev/null
@@ -1,796 +0,0 @@
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#include "eglconfig.h"
-#include "eglcontext.h"
-#include "egldisplay.h"
-#include "egldriver.h"
-#include "eglglobals.h"
-#include "eglmode.h"
-#include "eglscreen.h"
-#include "eglsurface.h"
-#include "egllog.h"
-
-#include "intel_egl.h"
-
-#include "xf86drm.h"
-#include "xf86drmMode.h"
-
-#include "intel_context.h"
-
-#include "state_tracker/st_public.h"
-
-#define MAX_SCREENS 16
-
-static void
-drm_get_device_id(struct egl_drm_device *device)
-{
- char path[512];
- FILE *file;
-
- /* TODO get the real minor */
- int minor = 0;
-
- snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", minor);
- file = fopen(path, "r");
- if (!file) {
- _eglLog(_EGL_WARNING, "Could not retrive device ID\n");
- return;
- }
-
- fgets(path, sizeof( path ), file);
- sscanf(path, "%x", &device->deviceID);
- fclose(file);
-}
-
-static struct egl_drm_device*
-egl_drm_create_device(int drmFD)
-{
- struct egl_drm_device *device = malloc(sizeof(*device));
- memset(device, 0, sizeof(*device));
- device->drmFD = drmFD;
-
- device->version = drmGetVersion(device->drmFD);
-
- drm_get_device_id(device);
-
- if (!intel_create_device(device)) {
- free(device);
- return NULL;
- }
-
- return device;
-}
-
-static void
-_egl_context_modes_destroy(__GLcontextModes *modes)
-{
- _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
-
- while (modes) {
- __GLcontextModes * const next = modes->next;
- free(modes);
- modes = next;
- }
-}
-/**
- * Create a linked list of 'count' GLcontextModes.
- * These are used during the client/server visual negotiation phase,
- * then discarded.
- */
-static __GLcontextModes *
-_egl_context_modes_create(unsigned count, size_t minimum_size)
-{
- /* This code copied from libGLX, and modified */
- const size_t size = (minimum_size > sizeof(__GLcontextModes))
- ? minimum_size : sizeof(__GLcontextModes);
- __GLcontextModes * head = NULL;
- __GLcontextModes ** next;
- unsigned i;
-
- _eglLog(_EGL_DEBUG, "%s %d %d", __FUNCTION__, count, minimum_size);
-
- next = & head;
- for (i = 0 ; i < count ; i++) {
- *next = (__GLcontextModes *) calloc(1, size);
- if (*next == NULL) {
- _egl_context_modes_destroy(head);
- head = NULL;
- break;
- }
-
- (*next)->doubleBufferMode = 1;
- (*next)->visualID = GLX_DONT_CARE;
- (*next)->visualType = GLX_DONT_CARE;
- (*next)->visualRating = GLX_NONE;
- (*next)->transparentPixel = GLX_NONE;
- (*next)->transparentRed = GLX_DONT_CARE;
- (*next)->transparentGreen = GLX_DONT_CARE;
- (*next)->transparentBlue = GLX_DONT_CARE;
- (*next)->transparentAlpha = GLX_DONT_CARE;
- (*next)->transparentIndex = GLX_DONT_CARE;
- (*next)->xRenderable = GLX_DONT_CARE;
- (*next)->fbconfigID = GLX_DONT_CARE;
- (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
- (*next)->bindToTextureRgb = GLX_DONT_CARE;
- (*next)->bindToTextureRgba = GLX_DONT_CARE;
- (*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = 0;
- (*next)->yInverted = GLX_DONT_CARE;
-
- next = & ((*next)->next);
- }
-
- return head;
-}
-
-struct drm_screen;
-
-struct drm_driver
-{
- _EGLDriver base; /* base class/object */
-
- drmModeResPtr res;
-
- struct drm_screen *screens[MAX_SCREENS];
- size_t count_screens;
-
- struct egl_drm_device *device;
-};
-
-struct drm_surface
-{
- _EGLSurface base; /* base class/object */
-
- struct egl_drm_drawable *drawable;
-};
-
-struct drm_context
-{
- _EGLContext base; /* base class/object */
-
- struct egl_drm_context *context;
-};
-
-struct drm_screen
-{
- _EGLScreen base;
-
- /* currently only support one connector */
- drmModeConnectorPtr connector;
-
- /* Has this screen been shown */
- int shown;
-
- /* Surface that is currently attached to this screen */
- struct drm_surface *surf;
-
- /* backing buffer */
- drmBO buffer;
-
- /* framebuffer */
- drmModeFBPtr fb;
- uint32_t fbID;
-
- /* crtc and mode used */
- drmModeCrtcPtr crtc;
- uint32_t crtcID;
-
- struct drm_mode_modeinfo *mode;
-
- /* geometry of the screen */
- struct egl_drm_frontbuffer front;
-};
-
-static void
-drm_update_res(struct drm_driver *drm_drv)
-{
- drmModeFreeResources(drm_drv->res);
- drm_drv->res = drmModeGetResources(drm_drv->device->drmFD);
-}
-
-static void
-drm_add_modes_from_connector(_EGLScreen *screen, drmModeConnectorPtr connector)
-{
- struct drm_mode_modeinfo *m;
- int i;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- _eglAddNewMode(screen, m->hdisplay, m->vdisplay, m->vrefresh, m->name);
- }
-}
-
-
-static EGLBoolean
-drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
-{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- struct drm_driver *drm_drv = (struct drm_driver *)drv;
- struct drm_screen *screen = NULL;
- drmModeConnectorPtr connector = NULL;
- drmModeResPtr res = NULL;
- unsigned count_connectors = 0;
- int num_screens = 0;
-
- EGLint i;
- int fd;
-
- fd = drmOpen("i915", NULL);
- if (fd < 0) {
- return EGL_FALSE;
- }
-
- drm_drv->device = egl_drm_create_device(fd);
- if (!drm_drv->device) {
- drmClose(fd);
- return EGL_FALSE;
- }
-
- drm_update_res(drm_drv);
- res = drm_drv->res;
- if (res)
- count_connectors = res->count_connectors;
-
- for(i = 0; i < count_connectors && i < MAX_SCREENS; i++) {
- connector = drmModeGetConnector(fd, res->connectors[i]);
-
- if (!connector)
- continue;
-
- if (connector->connection != DRM_MODE_CONNECTED) {
- drmModeFreeConnector(connector);
- continue;
- }
-
- screen = malloc(sizeof(struct drm_screen));
- memset(screen, 0, sizeof(*screen));
- screen->connector = connector;
- _eglInitScreen(&screen->base);
- _eglAddScreen(disp, &screen->base);
- drm_add_modes_from_connector(&screen->base, connector);
- drm_drv->screens[num_screens++] = screen;
- }
- drm_drv->count_screens = num_screens;
-
- /* for now we only have one config */
- _EGLConfig *config = calloc(1, sizeof(*config));
- memset(config, 1, sizeof(*config));
- _eglInitConfig(config, 1);
- _eglSetConfigAttrib(config, EGL_RED_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_GREEN_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_BLUE_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_ALPHA_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_BUFFER_SIZE, 32);
- _eglSetConfigAttrib(config, EGL_DEPTH_SIZE, 24);
- _eglSetConfigAttrib(config, EGL_STENCIL_SIZE, 8);
- _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
- _eglAddConfig(disp, config);
-
- drv->Initialized = EGL_TRUE;
-
- *major = 1;
- *minor = 4;
-
- return EGL_TRUE;
-}
-
-static void
-drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
-{
- struct drm_driver *drm_drv = (struct drm_driver *)drv;
- unsigned int i;
-
- intel_bind_frontbuffer(screen->surf->drawable, NULL);
- screen->surf = NULL;
-
- for (i = 0; i < drm_drv->res->count_crtcs; i++) {
- drmModeSetCrtc(
- drm_drv->device->drmFD,
- drm_drv->res->crtcs[i],
- 0, // FD
- 0, 0,
- NULL, 0, // List of output ids
- NULL);
- }
-
- drmModeRmFB(drm_drv->device->drmFD, screen->fbID);
- drmModeFreeFB(screen->fb);
- screen->fb = NULL;
-
- drmBOUnreference(drm_drv->device->drmFD, &screen->buffer);
-
- screen->shown = 0;
-}
-
-static EGLBoolean
-drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
-{
- struct drm_driver *drm_drv = (struct drm_driver *)drv;
- struct drm_screen *screen;
- int i = 0;
-
- intel_destroy_device(drm_drv->device);
- drmFreeVersion(drm_drv->device->version);
-
- for (i = 0; i < drm_drv->count_screens; i++) {
- screen = drm_drv->screens[i];
-
- if (screen->shown)
- drm_takedown_shown_screen(drv, screen);
-
- drmModeFreeConnector(screen->connector);
- _eglDestroyScreen(&screen->base);
- drm_drv->screens[i] = NULL;
- }
-
- drmClose(drm_drv->device->drmFD);
-
- free(drm_drv->device);
-
- _eglCleanupDisplay(_eglLookupDisplay(dpy));
- free(drm_drv);
-
- return EGL_TRUE;
-}
-
-
-static struct drm_context *
-lookup_drm_context(EGLContext context)
-{
- _EGLContext *c = _eglLookupContext(context);
- return (struct drm_context *) c;
-}
-
-
-static struct drm_surface *
-lookup_drm_surface(EGLSurface surface)
-{
- _EGLSurface *s = _eglLookupSurface(surface);
- return (struct drm_surface *) s;
-}
-
-static struct drm_screen *
-lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
-{
- _EGLScreen *s = _eglLookupScreen(dpy, screen);
- return (struct drm_screen *) s;
-}
-
-static __GLcontextModes*
-visual_from_config(_EGLConfig *conf)
-{
- __GLcontextModes *visual;
- (void)conf;
-
- visual = _egl_context_modes_create(1, sizeof(*visual));
- visual->redBits = 8;
- visual->greenBits = 8;
- visual->blueBits = 8;
- visual->alphaBits = 8;
-
- visual->rgbBits = 32;
- visual->doubleBufferMode = 1;
-
- visual->depthBits = 24;
- visual->haveDepthBuffer = visual->depthBits > 0;
- visual->stencilBits = 8;
- visual->haveStencilBuffer = visual->stencilBits > 0;
-
- return visual;
-}
-
-
-
-static EGLContext
-drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
-{
- struct drm_driver *drm_drv = (struct drm_driver *)drv;
- struct drm_context *c;
- struct drm_egl_context *share = NULL;
- _EGLConfig *conf;
- int i;
- int ret;
- __GLcontextModes *visual;
- struct egl_drm_context *context;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
-
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- /* no attribs defined for now */
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
- }
-
- c = (struct drm_context *) calloc(1, sizeof(struct drm_context));
- if (!c)
- return EGL_NO_CONTEXT;
-
- _eglInitContext(drv, dpy, &c->base, config, attrib_list);
-
- context = malloc(sizeof(*context));
- memset(context, 0, sizeof(*context));
-
- if (!context)
- goto err_c;
-
- context->device = drm_drv->device;
- visual = visual_from_config(conf);
-
- ret = intel_create_context(context, visual, share);
- free(visual);
-
- if (!ret)
- goto err_gl;
-
- c->context = context;
-
- /* generate handle and insert into hash table */
- _eglSaveContext(&c->base);
- assert(_eglGetContextHandle(&c->base));
-
- return _eglGetContextHandle(&c->base);
-err_gl:
- free(context);
-err_c:
- free(c);
- return EGL_NO_CONTEXT;
-}
-
-static EGLBoolean
-drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
-{
- struct drm_context *fc = lookup_drm_context(context);
- _eglRemoveContext(&fc->base);
- if (fc->base.IsBound) {
- fc->base.DeletePending = EGL_TRUE;
- } else {
- intel_destroy_context(fc->context);
- free(fc->context);
- free(fc);
- }
- return EGL_TRUE;
-}
-
-
-static EGLSurface
-drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
-{
- return EGL_NO_SURFACE;
-}
-
-
-static EGLSurface
-drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
-{
- return EGL_NO_SURFACE;
-}
-
-
-static EGLSurface
-drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- const EGLint *attrib_list)
-{
- struct drm_driver *drm_drv = (struct drm_driver *)drv;
- int i;
- int ret;
- int width = -1;
- int height = -1;
- struct drm_surface *surf = NULL;
- struct egl_drm_drawable *drawable = NULL;
- __GLcontextModes *visual;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
- return EGL_NO_CONTEXT;
- }
-
- for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
- switch (attrib_list[i]) {
- case EGL_WIDTH:
- width = attrib_list[++i];
- break;
- case EGL_HEIGHT:
- height = attrib_list[++i];
- break;
- default:
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
- }
- }
-
- if (width < 1 || height < 1) {
- _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
- }
-
- surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
- if (!surf)
- goto err;
-
- if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
- goto err_surf;
-
- drawable = malloc(sizeof(*drawable));
- memset(drawable, 0, sizeof(*drawable));
-
- drawable->w = width;
- drawable->h = height;
-
- visual = visual_from_config(conf);
-
- drawable->device = drm_drv->device;
- ret = intel_create_drawable(drawable, visual);
- free(visual);
-
- if (!ret)
- goto err_draw;
-
- surf->drawable = drawable;
-
- _eglSaveSurface(&surf->base);
- return surf->base.Handle;
-
-err_draw:
- free(drawable);
-err_surf:
- free(surf);
-err:
- return EGL_NO_SURFACE;
-}
-
-static EGLSurface
-drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
- const EGLint *attrib_list)
-{
- EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
-
- return surf;
-}
-
-static struct drm_mode_modeinfo *
-drm_find_mode(drmModeConnectorPtr connector, _EGLMode *mode)
-{
- int i;
- struct drm_mode_modeinfo *m = NULL;
-
- for (i = 0; i < connector->count_modes; i++) {
- m = &connector->modes[i];
- if (m->hdisplay == mode->Width && m->vdisplay == mode->Height && m->vrefresh == mode->RefreshRate)
- break;
- m = &connector->modes[0]; /* if we can't find one, return first */
- }
-
- return m;
-}
-static void
-draw(size_t x, size_t y, size_t w, size_t h, size_t pitch, size_t v, unsigned int *ptr)
-{
- int i, j;
-
- for (i = x; i < x + w; i++)
- for(j = y; j < y + h; j++)
- ptr[(i * pitch / 4) + j] = v;
-
-}
-
-static void
-prettyColors(int fd, unsigned int handle, size_t pitch)
-{
- drmBO bo;
- unsigned int *ptr;
- void *p;
- int i;
-
- drmBOReference(fd, handle, &bo);
- drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &p);
- ptr = (unsigned int*)p;
-
- for (i = 0; i < (bo.size / 4); i++)
- ptr[i] = 0xFFFFFFFF;
-
- for (i = 0; i < 4; i++)
- draw(i * 40, i * 40, 40, 40, pitch, 0, ptr);
-
-
- draw(200, 100, 40, 40, pitch, 0xff00ff, ptr);
- draw(100, 200, 40, 40, pitch, 0xff00ff, ptr);
-
- drmBOUnmap(fd, &bo);
-}
-
-static EGLBoolean
-drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen,
- EGLSurface surface, EGLModeMESA m)
-{
- struct drm_driver *drm_drv = (struct drm_driver *)drv;
- struct drm_surface *surf = lookup_drm_surface(surface);
- struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
- _EGLMode *mode = _eglLookupMode(dpy, m);
- size_t pitch = mode->Width * 4;
- size_t size = mode->Height * pitch;
- int ret;
- unsigned int i,j,k;
-
- if (scrn->shown)
- drm_takedown_shown_screen(drv, scrn);
-
- ret = drmBOCreate(drm_drv->device->drmFD, size, 0, 0,
- DRM_BO_FLAG_READ |
- DRM_BO_FLAG_WRITE |
- DRM_BO_FLAG_MEM_TT |
- DRM_BO_FLAG_MEM_VRAM |
- DRM_BO_FLAG_NO_EVICT,
- DRM_BO_HINT_DONT_FENCE, &scrn->buffer);
-
- if (ret)
- return EGL_FALSE;
-
- prettyColors(drm_drv->device->drmFD, scrn->buffer.handle, pitch);
-
- ret = drmModeAddFB(drm_drv->device->drmFD, mode->Width, mode->Height,
- 32, 32, pitch,
- scrn->buffer.handle,
- &scrn->fbID);
-
- if (ret)
- goto err_bo;
-
- scrn->fb = drmModeGetFB(drm_drv->device->drmFD, scrn->fbID);
- if (!scrn->fb)
- goto err_bo;
-
- for (j = 0; j < drm_drv->res->count_connectors; j++) {
- drmModeConnector *con = drmModeGetConnector(drm_drv->device->drmFD, drm_drv->res->connectors[j]);
- scrn->mode = drm_find_mode(con, mode);
- if (!scrn->mode)
- goto err_fb;
-
- for (k = 0; k < con->count_encoders; k++) {
- drmModeEncoder *enc = drmModeGetEncoder(drm_drv->device->drmFD, con->encoders[k]);
- for (i = 0; i < drm_drv->res->count_crtcs; i++) {
- if (enc->possible_crtcs & (1<<i)) {
- ret = drmModeSetCrtc(
- drm_drv->device->drmFD,
- drm_drv->res->crtcs[i],
- scrn->fbID,
- 0, 0,
- &drm_drv->res->connectors[j], 1,
- scrn->mode);
- /* skip the other crtcs now */
- i = drm_drv->res->count_crtcs;
- }
- }
- }
- }
-
- scrn->front.handle = scrn->buffer.handle;
- scrn->front.pitch = pitch;
- scrn->front.width = mode->Width;
- scrn->front.height = mode->Height;
-
- scrn->surf = surf;
- intel_bind_frontbuffer(surf->drawable, &scrn->front);
-
- scrn->shown = 1;
-
- return EGL_TRUE;
-
-err_fb:
- /* TODO remove fb */
-
-err_bo:
- drmBOUnreference(drm_drv->device->drmFD, &scrn->buffer);
- return EGL_FALSE;
-}
-
-static EGLBoolean
-drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
-{
- struct drm_surface *fs = lookup_drm_surface(surface);
- _eglRemoveSurface(&fs->base);
- if (fs->base.IsBound) {
- fs->base.DeletePending = EGL_TRUE;
- } else {
- intel_bind_frontbuffer(fs->drawable, NULL);
- intel_destroy_drawable(fs->drawable);
- free(fs->drawable);
- free(fs);
- }
- return EGL_TRUE;
-}
-
-
-static EGLBoolean
-drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
-{
- struct drm_surface *readSurf = lookup_drm_surface(read);
- struct drm_surface *drawSurf = lookup_drm_surface(draw);
- struct drm_context *ctx = lookup_drm_context(context);
- EGLBoolean b;
-
- b = _eglMakeCurrent(drv, dpy, draw, read, context);
- if (!b)
- return EGL_FALSE;
-
- if (ctx) {
- if (!drawSurf || !readSurf)
- return EGL_FALSE;
-
- intel_make_current(ctx->context, drawSurf->drawable, readSurf->drawable);
- } else {
- intel_make_current(NULL, NULL, NULL);
- }
-
- return EGL_TRUE;
-}
-
-static EGLBoolean
-drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
-{
- struct drm_surface *surf = lookup_drm_surface(draw);
- if (!surf)
- return EGL_FALSE;
-
- /* error checking */
- if (!_eglSwapBuffers(drv, dpy, draw))
- return EGL_FALSE;
-
- intel_swap_buffers(surf->drawable);
- return EGL_TRUE;
-}
-
-
-/**
- * The bootstrap function. Return a new drm_driver object and
- * plug in API functions.
- */
-_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
-{
- struct drm_driver *drm;
-
- drm = (struct drm_driver *) calloc(1, sizeof(struct drm_driver));
- if (!drm) {
- return NULL;
- }
-
- /* First fill in the dispatch table with defaults */
- _eglInitDriverFallbacks(&drm->base);
- /* then plug in our Drm-specific functions */
- drm->base.API.Initialize = drm_initialize;
- drm->base.API.Terminate = drm_terminate;
- drm->base.API.CreateContext = drm_create_context;
- drm->base.API.MakeCurrent = drm_make_current;
- drm->base.API.CreateWindowSurface = drm_create_window_surface;
- drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
- drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
- drm->base.API.DestroySurface = drm_destroy_surface;
- drm->base.API.DestroyContext = drm_destroy_context;
- drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
- drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
- drm->base.API.SwapBuffers = drm_swap_buffers;
-
- drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
- drm->base.Name = "DRM/Gallium";
-
- /* enable supported extensions */
- drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
- drm->base.Extensions.MESA_copy_context = EGL_TRUE;
-
- return &drm->base;
-}
diff --git a/src/gallium/winsys/drm/intel/egl/intel_egl.h b/src/gallium/winsys/drm/intel/egl/intel_egl.h
deleted file mode 100644
index 1ee27e0847..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_egl.h
+++ /dev/null
@@ -1,53 +0,0 @@
-
-#ifndef _INTEL_EGL_H_
-#define _INTEL_EGL_H_
-
-#include <xf86drm.h>
-
-struct egl_drm_device
-{
- void *priv;
- int drmFD;
-
- drmVersionPtr version;
- int deviceID;
-};
-
-struct egl_drm_context
-{
- void *priv;
- struct egl_drm_device *device;
-};
-
-struct egl_drm_drawable
-{
- void *priv;
- struct egl_drm_device *device;
- size_t h;
- size_t w;
-};
-
-struct egl_drm_frontbuffer
-{
- uint32_t handle;
- uint32_t pitch;
- uint32_t width;
- uint32_t height;
-};
-
-#include "GL/internal/glcore.h"
-
-int intel_create_device(struct egl_drm_device *device);
-int intel_destroy_device(struct egl_drm_device *device);
-
-int intel_create_context(struct egl_drm_context *context, const __GLcontextModes *visual, void *sharedContextPrivate);
-int intel_destroy_context(struct egl_drm_context *context);
-
-int intel_create_drawable(struct egl_drm_drawable *drawable, const __GLcontextModes * visual);
-int intel_destroy_drawable(struct egl_drm_drawable *drawable);
-
-void intel_make_current(struct egl_drm_context *context, struct egl_drm_drawable *draw, struct egl_drm_drawable *read);
-void intel_swap_buffers(struct egl_drm_drawable *draw);
-void intel_bind_frontbuffer(struct egl_drm_drawable *draw, struct egl_drm_frontbuffer *front);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_reg.h b/src/gallium/winsys/drm/intel/egl/intel_reg.h
deleted file mode 100644
index 4f33bee438..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_reg.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * 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 _INTEL_REG_H_
-#define _INTEL_REG_H_
-
-
-#define BR00_BITBLT_CLIENT 0x40000000
-#define BR00_OP_COLOR_BLT 0x10000000
-#define BR00_OP_SRC_COPY_BLT 0x10C00000
-#define BR13_SOLID_PATTERN 0x80000000
-
-#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
-#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
-#define XY_COLOR_BLT_WRITE_RGB (1<<20)
-
-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
-
-#define MI_WAIT_FOR_EVENT ((0x3<<23))
-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
-
-#define MI_BATCH_BUFFER_END (0xA<<23)
-
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c b/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c
deleted file mode 100644
index 2edcbc79ff..0000000000
--- a/src/gallium/winsys/drm/intel/egl/intel_swapbuffers.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "intel_device.h"
-#include "intel_context.h"
-#include "intel_batchbuffer.h"
-#include "intel_reg.h"
-
-#include "pipe/p_context.h"
-#include "state_tracker/st_public.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_cb_fbo.h"
-#include "intel_egl.h"
-
-
-static void
-intel_display_surface(struct egl_drm_drawable *draw,
- struct pipe_surface *surf);
-
-void intel_swap_buffers(struct egl_drm_drawable *draw)
-{
- struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
- struct pipe_surface *back_surf;
-
- assert(intel_fb);
- assert(intel_fb->stfb);
-
- back_surf = st_get_framebuffer_surface(intel_fb->stfb, ST_SURFACE_BACK_LEFT);
- if (back_surf) {
- st_notify_swapbuffers(intel_fb->stfb);
- if (intel_fb->front)
- intel_display_surface(draw, back_surf);
- st_notify_swapbuffers_complete(intel_fb->stfb);
- }
-}
-
-static void
-intel_display_surface(struct egl_drm_drawable *draw,
- struct pipe_surface *surf)
-{
- struct intel_context *intel = NULL;
- struct intel_framebuffer *intel_fb = (struct intel_framebuffer *)draw->priv;
- struct _DriFenceObject *fence;
-
- //const int srcWidth = surf->width;
- //const int srcHeight = surf->height;
-
- intel = intel_fb->device->dummy;
- if (!intel) {
- printf("No dummy context\n");
- return;
- }
-
- const int dstWidth = intel_fb->front->width;
- const int dstHeight = intel_fb->front->height;
- const int dstPitch = intel_fb->front->pitch / 4;//draw->front.cpp;
-
- const int cpp = 4;//intel_fb->front->cpp;
- const int srcPitch = surf->stride / cpp;
-
- int BR13, CMD;
- //int i;
-
- BR13 = (dstPitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
- CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
-
- BEGIN_BATCH(8, 2);
- OUT_BATCH(CMD);
- OUT_BATCH(BR13);
- OUT_BATCH((0 << 16) | 0);
- OUT_BATCH((dstHeight << 16) | dstWidth);
-
- OUT_RELOC(intel_fb->front_buffer,
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_WRITE,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_WRITE, 0);
-
- OUT_BATCH((0 << 16) | 0);
- OUT_BATCH((srcPitch * cpp) & 0xffff);
- OUT_RELOC(dri_bo(surf->buffer),
- DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ,
- DRM_BO_MASK_MEM | DRM_BO_FLAG_READ, 0);
-
- fence = intel_be_batchbuffer_flush(intel->base.batch);
- driFenceUnReference(&fence);
- intel_be_batchbuffer_finish(intel->base.batch);
-}
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/drm/intel/gem/Makefile
new file mode 100644
index 0000000000..b25fc258f4
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/Makefile
@@ -0,0 +1,18 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = inteldrm
+
+C_SOURCES = \
+ intel_be_batchbuffer.c \
+ intel_be_context.c \
+ intel_be_device.c
+
+
+include ./Makefile.template
+
+DRIVER_DEFINES = $(shell pkg-config libdrm --cflags \
+ && pkg-config libdrm --atleast-version=2.3.1 \
+ && echo "-DDRM_VBLANK_FLIP=DRM_VBLANK_FLIP")
+symlinks:
+
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile.template b/src/gallium/winsys/drm/intel/gem/Makefile.template
new file mode 100644
index 0000000000..557070ae02
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/Makefile.template
@@ -0,0 +1,64 @@
+# -*-makefile-*-
+
+
+# We still have a dependency on the "dri" buffer manager. Most likely
+# the interface can be reused in non-dri environments, and also as a
+# frontend to simpler memory managers.
+#
+COMMON_SOURCES =
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(CPP_SOURCES:.cpp=.o) \
+ $(ASM_SOURCES:.S=.o)
+
+
+### Include directories
+INCLUDES = \
+ -I. \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/include \
+ $(DRIVER_INCLUDES)
+
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@
+
+
+##### TARGETS #####
+
+default: depend symlinks $(LIBNAME)
+
+
+$(LIBNAME): $(OBJECTS) Makefile Makefile.template
+ $(TOP)/bin/mklib -o $@ -static $(OBJECTS) $(DRIVER_LIBS)
+
+
+depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) \
+ $(ASM_SOURCES) 2> /dev/null
+
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+
+# Remove .o and backup files
+clean::
+ -rm -f *.o */*.o *~ *.so *.a *~ server/*.o $(SYMLINKS)
+ -rm -f depend depend.bak
+
+
+include depend
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
new file mode 100644
index 0000000000..e83a4c42cd
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
@@ -0,0 +1,139 @@
+
+#include "intel_be_batchbuffer.h"
+#include "intel_be_context.h"
+#include "intel_be_device.h"
+#include "intel_be_fence.h"
+#include <errno.h>
+
+#include "util/u_memory.h"
+
+struct intel_be_batchbuffer *
+intel_be_batchbuffer_alloc(struct intel_be_context *intel)
+{
+ struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer);
+
+
+ batch->base.buffer = NULL;
+ batch->base.winsys = &intel->base;
+ batch->base.map = NULL;
+ batch->base.ptr = NULL;
+ batch->base.size = 0;
+ batch->base.actual_size = intel->device->max_batch_size;
+ batch->base.relocs = 0;
+ batch->base.max_relocs = INTEL_DEFAULT_RELOCS;
+
+ batch->base.map = malloc(batch->base.actual_size);
+ memset(batch->base.map, 0, batch->base.actual_size);
+
+ batch->base.ptr = batch->base.map;
+
+ intel_be_batchbuffer_reset(batch);
+
+ return batch;
+}
+
+void
+intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
+{
+ struct intel_be_context *intel = intel_be_context(batch->base.winsys);
+ struct intel_be_device *dev = intel->device;
+
+ if (batch->bo)
+ drm_intel_bo_unreference(batch->bo);
+
+ memset(batch->base.map, 0, batch->base.actual_size);
+ batch->base.ptr = batch->base.map;
+ batch->base.size = batch->base.actual_size - BATCH_RESERVED;
+
+ batch->base.relocs = 0;
+ batch->base.max_relocs = INTEL_DEFAULT_RELOCS;
+
+ batch->bo = drm_intel_bo_alloc(dev->pools.gem,
+ "gallium3d_batch_buffer",
+ batch->base.actual_size, 0);
+}
+
+int
+intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
+ unsigned pre_add,
+ drm_intel_bo *bo,
+ uint32_t read_domains,
+ uint32_t write_domain)
+{
+ unsigned offset;
+ int ret = 0;
+
+ assert(batch->base.relocs < batch->base.max_relocs);
+
+ offset = (unsigned)(batch->base.ptr - batch->base.map);
+ batch->base.ptr += 4;
+
+ ret = drm_intel_bo_emit_reloc(bo, pre_add,
+ batch->bo, offset,
+ read_domains,
+ write_domain);
+
+ if (!ret)
+ batch->base.relocs++;
+
+ return ret;
+}
+
+void
+intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
+ struct intel_be_fence **fence)
+{
+ struct i915_batchbuffer *i915 = &batch->base;
+ unsigned used = 0;
+ int ret = 0;
+
+ assert(i915_batchbuffer_space(i915) >= 0);
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 3) == 0);
+
+ if (used & 4) {
+ ((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
+ ((uint32_t *) batch->base.ptr)[1] = 0;
+ ((uint32_t *) batch->base.ptr)[2] = (0xA<<23); // MI_BATCH_BUFFER_END;
+ batch->base.ptr += 12;
+ } else {
+ ((uint32_t *) batch->base.ptr)[0] = ((0<<29)|(4<<23)); // MI_FLUSH;
+ ((uint32_t *) batch->base.ptr)[1] = (0xA<<23); // MI_BATCH_BUFFER_END;
+ batch->base.ptr += 8;
+ }
+
+ used = batch->base.ptr - batch->base.map;
+
+ drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+
+ assert(ret == 0);
+
+ intel_be_batchbuffer_reset(batch);
+
+ if (fence) {
+ if (*fence)
+ intel_be_fence_unreference(*fence);
+
+ (*fence) = CALLOC_STRUCT(intel_be_fence);
+ (*fence)->refcount = 1;
+ (*fence)->bo = NULL;
+ }
+}
+
+void
+intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch)
+{
+
+}
+
+void
+intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
+{
+ if (batch->bo)
+ drm_intel_bo_unreference(batch->bo);
+
+ free(batch->base.map);
+ free(batch);
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
new file mode 100644
index 0000000000..195bf8dee7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
@@ -0,0 +1,55 @@
+
+#ifndef INTEL_BE_BATCHBUFFER_H
+#define INTEL_BE_BATCHBUFFER_H
+
+#include "i915simple/i915_batch.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+#define BATCH_RESERVED 16
+
+#define INTEL_DEFAULT_RELOCS 100
+#define INTEL_MAX_RELOCS 400
+
+#define INTEL_BATCH_NO_CLIPRECTS 0x1
+#define INTEL_BATCH_CLIPRECTS 0x2
+
+struct intel_be_context;
+struct intel_be_device;
+struct intel_be_fence;
+
+struct intel_be_batchbuffer
+{
+ struct i915_batchbuffer base;
+
+ struct intel_be_context *intel;
+ struct intel_be_device *device;
+
+ drm_intel_bo *bo;
+};
+
+struct intel_be_batchbuffer *
+intel_be_batchbuffer_alloc(struct intel_be_context *intel);
+
+void
+intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch);
+
+void
+intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch);
+
+void
+intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
+ struct intel_be_fence **fence);
+
+void
+intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch);
+
+int
+intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
+ unsigned pre_add,
+ drm_intel_bo *bo,
+ uint32_t read_domains,
+ uint32_t write_doman);
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
new file mode 100644
index 0000000000..3e472e1e43
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
@@ -0,0 +1,78 @@
+
+#include "intel_be_device.h"
+#include "intel_be_context.h"
+#include "intel_be_batchbuffer.h"
+
+#include "i915_drm.h"
+
+static struct i915_batchbuffer *
+intel_be_batch_get(struct i915_winsys *sws)
+{
+ struct intel_be_context *intel = intel_be_context(sws);
+ return &intel->batch->base;
+}
+
+static void
+intel_be_batch_reloc(struct i915_winsys *sws,
+ struct pipe_buffer *buf,
+ unsigned access_flags,
+ unsigned delta)
+{
+ struct intel_be_context *intel = intel_be_context(sws);
+ drm_intel_bo *bo = intel_bo(buf);
+ int ret;
+ uint32_t read = 0;
+ uint32_t write = 0;
+
+ if (access_flags & I915_BUFFER_ACCESS_WRITE) {
+ write = I915_GEM_DOMAIN_RENDER;
+ }
+
+ if (access_flags & I915_BUFFER_ACCESS_READ) {
+ read = I915_GEM_DOMAIN_SAMPLER |
+ I915_GEM_DOMAIN_VERTEX;
+ }
+
+ ret = intel_be_offset_relocation(intel->batch,
+ delta,
+ bo,
+ read,
+ write);
+ /* TODO change return type */
+ /* return ret; */
+}
+
+static void
+intel_be_batch_flush(struct i915_winsys *sws,
+ struct pipe_fence_handle **fence)
+{
+ struct intel_be_context *intel = intel_be_context(sws);
+ struct intel_be_fence **f = (struct intel_be_fence **)fence;
+
+ if (fence && *fence)
+ assert(0);
+
+ intel_be_batchbuffer_flush(intel->batch, f);
+}
+
+boolean
+intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device)
+{
+ assert(intel);
+ assert(device);
+ intel->device = device;
+
+ intel->base.batch_get = intel_be_batch_get;
+ intel->base.batch_reloc = intel_be_batch_reloc;
+ intel->base.batch_flush = intel_be_batch_flush;
+
+ intel->batch = intel_be_batchbuffer_alloc(intel);
+
+ return true;
+}
+
+void
+intel_be_destroy_context(struct intel_be_context *intel)
+{
+ intel_be_batchbuffer_free(intel->batch);
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.h b/src/gallium/winsys/drm/intel/gem/intel_be_context.h
new file mode 100644
index 0000000000..9cee1a4e52
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_context.h
@@ -0,0 +1,48 @@
+
+#ifndef INTEL_BE_CONTEXT_H
+#define INTEL_BE_CONTEXT_H
+
+#include "i915simple/i915_winsys.h"
+
+struct intel_be_context
+{
+ /** Interface to i915simple driver */
+ struct i915_winsys base;
+
+ struct intel_be_device *device;
+ struct intel_be_batchbuffer *batch;
+
+ /*
+ * Hardware lock functions.
+ *
+ * Needs to be filled in by the winsys.
+ */
+ void (*hardware_lock)(struct intel_be_context *context);
+ void (*hardware_unlock)(struct intel_be_context *context);
+ boolean (*hardware_locked)(struct intel_be_context *context);
+};
+
+static INLINE struct intel_be_context *
+intel_be_context(struct i915_winsys *sws)
+{
+ return (struct intel_be_context *)sws;
+}
+
+/**
+ * Intialize a allocated intel_be_context struct.
+ *
+ * Remember to set the hardware_* functions.
+ */
+boolean
+intel_be_init_context(struct intel_be_context *intel,
+ struct intel_be_device *device);
+
+/**
+ * Destroy a intel_be_context.
+ *
+ * Does not free the struct that is up to the winsys.
+ */
+void
+intel_be_destroy_context(struct intel_be_context *intel);
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
new file mode 100644
index 0000000000..201a485049
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
@@ -0,0 +1,267 @@
+
+#include "intel_be_device.h"
+
+#include "pipe/p_winsys.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
+
+#include "intel_be_fence.h"
+
+#include "i915simple/i915_screen.h"
+
+
+/**
+ * Turn a pipe winsys into an intel/pipe winsys:
+ */
+static INLINE struct intel_be_device *
+intel_be_device(struct pipe_winsys *winsys)
+{
+ return (struct intel_be_device *)winsys;
+}
+
+/*
+ * Buffer
+ */
+
+static void *
+intel_be_buffer_map(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ drm_intel_bo *bo = intel_bo(buf);
+ int write = 0;
+ int ret;
+
+ if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
+ write = 1;
+
+ ret = drm_intel_bo_map(bo, write);
+
+ if (ret)
+ return NULL;
+
+ return bo->virtual;
+}
+
+static void
+intel_be_buffer_unmap(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ drm_intel_bo_unmap(intel_bo(buf));
+}
+
+static void
+intel_be_buffer_destroy(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ drm_intel_bo_unreference(intel_bo(buf));
+ free(buf);
+}
+
+static struct pipe_buffer *
+intel_be_buffer_create(struct pipe_winsys *winsys,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
+ struct intel_be_device *dev = intel_be_device(winsys);
+ drm_intel_bufmgr *pool;
+ char *name;
+
+ if (!buffer)
+ return NULL;
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
+ /* Local buffer */
+ name = "gallium3d_local";
+ pool = dev->pools.gem;
+ } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
+ /* For vertex buffers */
+ name = "gallium3d_internal_vertex";
+ pool = dev->pools.gem;
+ } else {
+ /* Regular buffers */
+ name = "gallium3d_regular";
+ pool = dev->pools.gem;
+ }
+
+ buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+
+ if (!buffer->bo)
+ goto err;
+
+ return &buffer->base;
+
+err:
+ free(buffer);
+ return NULL;
+}
+
+static struct pipe_buffer *
+intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
+{
+ struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
+ struct intel_be_device *dev = intel_be_device(winsys);
+ int ret;
+
+ if (!buffer)
+ return NULL;
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = 0;
+ buffer->base.usage = 0;
+ buffer->base.size = bytes;
+
+ buffer->bo = drm_intel_bo_alloc(dev->pools.gem,
+ "gallium3d_user_buffer",
+ bytes, 0);
+
+ if (!buffer->bo)
+ goto err;
+
+ ret = drm_intel_bo_subdata(buffer->bo,
+ 0, bytes, ptr);
+
+ if (ret)
+ goto err;
+
+ return &buffer->base;
+
+err:
+ free(buffer);
+ return NULL;
+}
+
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct pipe_winsys *winsys,
+ const char* name, unsigned handle)
+{
+ struct intel_be_device *dev = intel_be_device(winsys);
+ struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
+
+ if (!buffer)
+ return NULL;
+
+ buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle);
+
+ if (!buffer->bo)
+ goto err;
+
+ buffer->base.refcount = 1;
+ buffer->base.alignment = buffer->bo->align;
+ buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE |
+ PIPE_BUFFER_USAGE_CPU_READ |
+ PIPE_BUFFER_USAGE_CPU_WRITE;
+ buffer->base.size = buffer->bo->size;
+
+ return &buffer->base;
+
+err:
+ free(buffer);
+ return NULL;
+}
+
+unsigned
+intel_be_handle_from_buffer(struct pipe_winsys *winsys,
+ struct pipe_buffer *buf)
+{
+ drm_intel_bo *bo = intel_bo(buf);
+ return bo->handle;
+}
+
+/*
+ * Fence
+ */
+
+static void
+intel_be_fence_refunref(struct pipe_winsys *sws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ struct intel_be_fence **p = (struct intel_be_fence **)ptr;
+ struct intel_be_fence *f = (struct intel_be_fence *)fence;
+
+ assert(p);
+
+ if (f)
+ intel_be_fence_reference(f);
+
+ if (*p)
+ intel_be_fence_unreference(*p);
+
+ *p = f;
+}
+
+static int
+intel_be_fence_signalled(struct pipe_winsys *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ assert(0);
+
+ return 0;
+}
+
+static int
+intel_be_fence_finish(struct pipe_winsys *sws,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ struct intel_be_fence *f = (struct intel_be_fence *)fence;
+
+ /* fence already expired */
+ if (!f->bo)
+ return 0;
+
+ drm_intel_bo_wait_rendering(f->bo);
+ drm_intel_bo_unreference(f->bo);
+ f->bo = NULL;
+
+ return 0;
+}
+
+/*
+ * Misc functions
+ */
+
+boolean
+intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
+{
+ dev->fd = fd;
+ dev->max_batch_size = 16 * 4096;
+ dev->max_vertex_size = 128 * 4096;
+
+ dev->base.buffer_create = intel_be_buffer_create;
+ dev->base.user_buffer_create = intel_be_user_buffer_create;
+ dev->base.buffer_map = intel_be_buffer_map;
+ dev->base.buffer_unmap = intel_be_buffer_unmap;
+ dev->base.buffer_destroy = intel_be_buffer_destroy;
+
+ /* Not used anymore */
+ dev->base.surface_alloc = NULL;
+ dev->base.surface_alloc_storage = NULL;
+ dev->base.surface_release = NULL;
+
+ dev->base.fence_reference = intel_be_fence_refunref;
+ dev->base.fence_signalled = intel_be_fence_signalled;
+ dev->base.fence_finish = intel_be_fence_finish;
+
+ dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
+
+ return true;
+}
+
+void
+intel_be_destroy_device(struct intel_be_device *dev)
+{
+ drm_intel_bufmgr_destroy(dev->pools.gem);
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
new file mode 100644
index 0000000000..96e94c47e7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
@@ -0,0 +1,74 @@
+
+#ifndef INTEL_DRM_DEVICE_H
+#define INTEL_DRM_DEVICE_H
+
+#include "pipe/p_winsys.h"
+#include "pipe/p_context.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+/*
+ * Device
+ */
+
+struct intel_be_device
+{
+ struct pipe_winsys base;
+
+ int fd; /**< Drm file discriptor */
+
+ size_t max_batch_size;
+ size_t max_vertex_size;
+
+ struct {
+ drm_intel_bufmgr *gem;
+ } pools;
+};
+
+boolean
+intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
+
+void
+intel_be_destroy_device(struct intel_be_device *dev);
+
+/*
+ * Buffer
+ */
+
+struct intel_be_buffer {
+ struct pipe_buffer base;
+ drm_intel_bo *bo;
+};
+
+/**
+ * Create a be buffer from a drm bo handle.
+ *
+ * Takes a reference.
+ */
+struct pipe_buffer *
+intel_be_buffer_from_handle(struct pipe_winsys *winsys,
+ const char* name, unsigned handle);
+
+/**
+ * Gets a handle from a buffer.
+ *
+ * If buffer is destroyed handle may become invalid.
+ */
+unsigned
+intel_be_handle_from_buffer(struct pipe_winsys *winsys,
+ struct pipe_buffer *buffer);
+
+static INLINE struct intel_be_buffer *
+intel_be_buffer(struct pipe_buffer *buf)
+{
+ return (struct intel_be_buffer *)buf;
+}
+
+static INLINE drm_intel_bo *
+intel_bo(struct pipe_buffer *buf)
+{
+ return intel_be_buffer(buf)->bo;
+}
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
new file mode 100644
index 0000000000..0fe18f66f8
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
@@ -0,0 +1,38 @@
+
+#ifndef INTEL_BE_FENCE_H
+#define INTEL_BE_FENCE_H
+
+#include "pipe/p_defines.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+/**
+ * Because gem does not have fence's we have to create our own fences.
+ *
+ * They work by keeping the batchbuffer around and checking if that has
+ * been idled. If bo is NULL fence has expired.
+ */
+struct intel_be_fence
+{
+ uint32_t refcount;
+ drm_intel_bo *bo;
+};
+
+static INLINE void
+intel_be_fence_reference(struct intel_be_fence *f)
+{
+ f->refcount++;
+}
+
+static INLINE void
+intel_be_fence_unreference(struct intel_be_fence *f)
+{
+ if (!--f->refcount) {
+ if (f->bo)
+ drm_intel_bo_unreference(f->bo);
+ free(f);
+ }
+}
+
+#endif
diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
index 6895137506..5b3101fbba 100644
--- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
+++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c
@@ -69,7 +69,7 @@ nouveau_pipe_bo_create(struct pipe_winsys *pws, unsigned alignment,
nvbuf->base.usage = usage;
nvbuf->base.size = size;
- flags = nouveau_flags_from_usage(nv, flags);
+ flags = nouveau_flags_from_usage(nv, usage);
if (nouveau_bo_new(dev, flags, alignment, size, &nvbuf->bo)) {
FREE(nvbuf);
@@ -121,14 +121,9 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
map_flags |= NOUVEAU_BO_WR;
- /* XXX: Technically incorrect. If the client maps a buffer for write-only
- * and leaves part of the buffer untouched it probably expects those parts
- * to remain intact. This is violated because we allocate a whole new buffer
- * and don't copy the previous buffer's contents, so this optimization is
- * only valid if the client intends to overwrite the whole buffer.
- */
- if ((map_flags & NOUVEAU_BO_RDWR) == NOUVEAU_BO_WR &&
- !nouveau_bo_busy(nvbuf->bo, map_flags)) {
+ if (flags & PIPE_BUFFER_USAGE_DISCARD &&
+ !(flags & PIPE_BUFFER_USAGE_CPU_READ) &&
+ nouveau_bo_busy(nvbuf->bo, map_flags)) {
struct nouveau_pipe_winsys *nvpws = (struct nouveau_pipe_winsys *)pws;
struct nouveau_context *nv = nvpws->nv;
struct nouveau_device *dev = nv->nv_screen->device;
diff --git a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
index 006978b182..aacfe984d1 100644
--- a/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
+++ b/src/gallium/winsys/drm/nouveau/dri/nouveau_context_dri.c
@@ -42,7 +42,7 @@ nouveau_context_create(const __GLcontextModes *glVis,
if (nouveau_context_init(&nv_screen->base, driContextPriv->hHWContext,
(drmLock *)&driScrnPriv->pSAREA->lock,
- nv_share, &nv->base)) {
+ &nv_share->base, &nv->base)) {
return GL_FALSE;
}