Conflicts: src/gallium/state_trackers/wgl/icd/stw_icd.ctags/mesa_20090313
@@ -46,9 +46,9 @@ common.AddOptions(opts) | |||
opts.Add(ListOption('statetrackers', 'state trackers to build', default_statetrackers, | |||
['mesa', 'python'])) | |||
opts.Add(ListOption('drivers', 'pipe drivers to build', default_drivers, | |||
['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace'])) | |||
['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300'])) | |||
opts.Add(ListOption('winsys', 'winsys drivers to build', default_winsys, | |||
['xlib', 'intel', 'gdi'])) | |||
['xlib', 'intel', 'gdi', 'amd'])) | |||
opts.Add(EnumOption('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0'))) | |||
@@ -55,11 +55,17 @@ LIB_DIR = @LIB_DIR@ | |||
SRC_DIRS = @SRC_DIRS@ | |||
GLU_DIRS = @GLU_DIRS@ | |||
DRIVER_DIRS = @DRIVER_DIRS@ | |||
GALLIUM_AUXILIARY_DIRS = @GALLIUM_AUXILIARY_DIRS@ | |||
GALLIUM_DRIVER_DIRS = @GALLIUM_DRIVER_DIRS@ | |||
GALLIUM_WINSYS_DIRS = @GALLIUM_WINSYS_DIRS@ | |||
GALLIUM_AUXILIARIES = $(foreach DIR,$(GALLIUM_AUXILIARY_DIRS),$(TOP)/src/gallium/auxiliary/$(DIR)/lib$(DIR).a) | |||
GALLIUM_DRIVERS = $(foreach DIR,$(GALLIUM_DRIVER_DIRS),$(TOP)/src/gallium/drivers/$(DIR)/lib$(DIR).a) | |||
# Which subdirs under $(TOP)/progs/ to enter: | |||
PROGRAM_DIRS = @PROGRAM_DIRS@ | |||
# Driver specific build vars | |||
DRI_DIRS = @DRI_DIRS@ | |||
#DRI_DIRS = @DRI_DIRS@ | |||
WINDOW_SYSTEM = @WINDOW_SYSTEM@ | |||
USING_EGL = @USING_EGL@ | |||
@@ -291,7 +291,7 @@ if test "x$enable_asm" = xyes; then | |||
case "$asm_arch" in | |||
x86) | |||
ASM_FLAGS="-DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM" | |||
dnl ASM_FLAGS="-DUSE_X86_ASM -DUSE_MMX_ASM -DUSE_3DNOW_ASM -DUSE_SSE_ASM" | |||
ASM_SOURCES='$(X86_SOURCES)' | |||
ASM_API='$(X86_API)' | |||
AC_MSG_RESULT([yes, x86]) | |||
@@ -389,17 +389,22 @@ esac | |||
dnl | |||
dnl Driver specific build directories | |||
dnl | |||
SRC_DIRS="mesa" | |||
SRC_DIRS="mesa gallium egl gallium/winsys" | |||
GLU_DIRS="sgi" | |||
WINDOW_SYSTEM="" | |||
GALLIUM_WINSYS_DIRS="" | |||
GALLIUM_AUXILIARY_DIRS="draw translate cso_cache pipebuffer tgsi sct rtasm util" | |||
GALLIUM_DRIVER_DIRS="softpipe failover" | |||
case "$mesa_driver" in | |||
xlib) | |||
DRIVER_DIRS="x11" | |||
;; | |||
dri) | |||
SRC_DIRS="glx/x11 $SRC_DIRS" | |||
DRIVER_DIRS="dri" | |||
DRIVER_DIRS="" | |||
WINDOW_SYSTEM="dri" | |||
GALLIUM_WINSYS_DIRS="drm $GALLIUM_WINSYS_DIRS" | |||
GALLIUM_DRIVER_DIRS="$GALLIUM_DRIVER_DIRS i915simple i965simple nv04 nv10 nv20 nv30 nv40 nv50" | |||
;; | |||
osmesa) | |||
DRIVER_DIRS="osmesa" | |||
@@ -409,6 +414,9 @@ AC_SUBST([SRC_DIRS]) | |||
AC_SUBST([GLU_DIRS]) | |||
AC_SUBST([DRIVER_DIRS]) | |||
AC_SUBST([WINDOW_SYSTEM]) | |||
AC_SUBST([GALLIUM_WINSYS_DIRS]) | |||
AC_SUBST([GALLIUM_DRIVER_DIRS]) | |||
AC_SUBST([GALLIUM_AUXILIARY_DIRS]) | |||
dnl | |||
dnl User supplied program configuration | |||
@@ -656,10 +664,10 @@ if test "$mesa_driver" = dri; then | |||
case "$host_os" in | |||
linux*) | |||
DEFINES="$DEFINES -DUSE_EXTERNAL_DXTN_LIB=1 -DIN_DRI_DRIVER" | |||
DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS" | |||
if test "x$driglx_direct" = xyes; then | |||
DEFINES="$DEFINES -DGLX_DIRECT_RENDERING" | |||
fi | |||
DEFINES="$DEFINES -DGLX_INDIRECT_RENDERING -DHAVE_ALIAS" | |||
case "$host_cpu" in | |||
x86_64) |
@@ -163,6 +163,25 @@ def createInstallMethods(env): | |||
env.AddMethod(install_shared_library, 'InstallSharedLibrary') | |||
def num_jobs(): | |||
try: | |||
return int(os.environ['NUMBER_OF_PROCESSORS']) | |||
except (ValueError, KeyError): | |||
pass | |||
try: | |||
return os.sysconf('SC_NPROCESSORS_ONLN') | |||
except (ValueError, OSError, AttributeError): | |||
pass | |||
try: | |||
return int(os.popen2("sysctl -n hw.ncpu")[1].read()) | |||
except ValueError: | |||
pass | |||
return 1 | |||
def generate(env): | |||
"""Common environment generation code""" | |||
@@ -207,6 +226,10 @@ def generate(env): | |||
env.SConsignFile(os.path.join(build_dir, '.sconsign')) | |||
env.CacheDir('build/cache') | |||
# Parallel build | |||
if env.GetOption('num_jobs') <= 1: | |||
env.SetOption('num_jobs', num_jobs()) | |||
# C preprocessor options | |||
cppdefines = [] | |||
if debug: |
@@ -206,6 +206,25 @@ _bool_map = { | |||
} | |||
def num_jobs(): | |||
try: | |||
return int(os.environ['NUMBER_OF_PROCESSORS']) | |||
except (ValueError, KeyError): | |||
pass | |||
try: | |||
return os.sysconf('SC_NPROCESSORS_ONLN') | |||
except (ValueError, OSError, AttributeError): | |||
pass | |||
try: | |||
return int(os.popen2("sysctl -n hw.ncpu")[1].read()) | |||
except ValueError: | |||
pass | |||
return 1 | |||
def generate(env): | |||
"""Common environment generation code""" | |||
@@ -266,6 +285,10 @@ def generate(env): | |||
# different scons versions building the same source file | |||
env.SConsignFile(os.path.join(env['build'], '.sconsign')) | |||
# Parallel build | |||
if env.GetOption('num_jobs') <= 1: | |||
env.SetOption('num_jobs', num_jobs()) | |||
# Summary | |||
print ' platform=%s' % env['platform'] | |||
@@ -274,6 +297,7 @@ def generate(env): | |||
print ' debug=%s' % ['no', 'yes'][env['debug']] | |||
print ' profile=%s' % ['no', 'yes'][env['profile']] | |||
print ' build=%s' % env['build'] | |||
print ' %s jobs' % env.GetOption('num_jobs') | |||
# Load tool chain |
@@ -256,7 +256,7 @@ pstip_transform_inst(struct tgsi_transform_context *ctx, | |||
struct tgsi_full_immediate immed; | |||
uint size = 4; | |||
immed = tgsi_default_full_immediate(); | |||
immed.Immediate.Size = 1 + size; /* one for the token itself */ | |||
immed.Immediate.NrTokens = 1 + size; /* one for the token itself */ | |||
immed.u.Pointer = (void *) value; | |||
ctx->emit_immediate(ctx, &immed); | |||
} |
@@ -1870,7 +1870,7 @@ static boolean note_immediate( struct aos_compilation *cp, | |||
unsigned pos = cp->num_immediates++; | |||
unsigned j; | |||
for (j = 0; j < imm->Immediate.Size; j++) { | |||
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) { | |||
cp->vaos->machine->immediate[pos][j] = imm->u.ImmediateFloat32[j].Float; | |||
} | |||
@@ -160,7 +160,7 @@ translate_immediate(Storage *storage, | |||
{ | |||
float vec[4]; | |||
int i; | |||
for (i = 0; i < imm->Immediate.Size - 1; ++i) { | |||
for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) { | |||
switch (imm->Immediate.DataType) { | |||
case TGSI_IMM_FLOAT32: | |||
vec[i] = imm->u.ImmediateFloat32[i].Float; | |||
@@ -179,7 +179,7 @@ translate_immediateir(StorageSoa *storage, | |||
{ | |||
float vec[4]; | |||
int i; | |||
for (i = 0; i < imm->Immediate.Size - 1; ++i) { | |||
for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) { | |||
switch (imm->Immediate.DataType) { | |||
case TGSI_IMM_FLOAT32: | |||
vec[i] = imm->u.ImmediateFloat32[i].Float; |
@@ -157,7 +157,7 @@ def preamble(intype, outtype, inpv, outpv, prim): | |||
print ' void *_out )' | |||
print '{' | |||
if intype != GENERATE: | |||
print ' const ' + intype + '*in = (const ' + intype + '*)in;' | |||
print ' const ' + intype + '*in = (const ' + intype + '*)_in;' | |||
print ' ' + outtype + ' *out = (' + outtype + '*)_out;' | |||
print ' unsigned i, j;' | |||
print ' (void)j;' |
@@ -44,7 +44,6 @@ | |||
#include "pipe/p_compiler.h" | |||
#include "pipe/p_error.h" | |||
#include "pipe/p_debug.h" | |||
#include "pipe/internal/p_winsys_screen.h" | |||
#include "pipe/p_thread.h" | |||
#include "util/u_memory.h" | |||
#include "util/u_double_list.h" | |||
@@ -64,7 +63,7 @@ struct fenced_buffer_list | |||
{ | |||
pipe_mutex mutex; | |||
struct pipe_winsys *winsys; | |||
struct pb_fence_ops *ops; | |||
size_t numDelayed; | |||
@@ -140,12 +139,12 @@ static INLINE void | |||
_fenced_buffer_remove(struct fenced_buffer_list *fenced_list, | |||
struct fenced_buffer *fenced_buf) | |||
{ | |||
struct pipe_winsys *winsys = fenced_list->winsys; | |||
struct pb_fence_ops *ops = fenced_list->ops; | |||
assert(fenced_buf->fence); | |||
assert(fenced_buf->list == fenced_list); | |||
winsys->fence_reference(winsys, &fenced_buf->fence, NULL); | |||
ops->fence_reference(ops, &fenced_buf->fence, NULL); | |||
fenced_buf->flags &= ~PIPE_BUFFER_USAGE_GPU_READ_WRITE; | |||
assert(fenced_buf->head.prev); | |||
@@ -168,7 +167,7 @@ static INLINE enum pipe_error | |||
_fenced_buffer_finish(struct fenced_buffer *fenced_buf) | |||
{ | |||
struct fenced_buffer_list *fenced_list = fenced_buf->list; | |||
struct pipe_winsys *winsys = fenced_list->winsys; | |||
struct pb_fence_ops *ops = fenced_list->ops; | |||
#if 0 | |||
debug_warning("waiting for GPU"); | |||
@@ -176,7 +175,7 @@ _fenced_buffer_finish(struct fenced_buffer *fenced_buf) | |||
assert(fenced_buf->fence); | |||
if(fenced_buf->fence) { | |||
if(winsys->fence_finish(winsys, fenced_buf->fence, 0) != 0) { | |||
if(ops->fence_finish(ops, fenced_buf->fence, 0) != 0) { | |||
return PIPE_ERROR; | |||
} | |||
/* Remove from the fenced list */ | |||
@@ -196,7 +195,7 @@ static void | |||
_fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, | |||
int wait) | |||
{ | |||
struct pipe_winsys *winsys = fenced_list->winsys; | |||
struct pb_fence_ops *ops = fenced_list->ops; | |||
struct list_head *curr, *next; | |||
struct fenced_buffer *fenced_buf; | |||
struct pipe_fence_handle *prev_fence = NULL; | |||
@@ -209,15 +208,15 @@ _fenced_buffer_list_check_free(struct fenced_buffer_list *fenced_list, | |||
if(fenced_buf->fence != prev_fence) { | |||
int signaled; | |||
if (wait) | |||
signaled = winsys->fence_finish(winsys, fenced_buf->fence, 0); | |||
signaled = ops->fence_finish(ops, fenced_buf->fence, 0); | |||
else | |||
signaled = winsys->fence_signalled(winsys, fenced_buf->fence, 0); | |||
signaled = ops->fence_signalled(ops, fenced_buf->fence, 0); | |||
if (signaled != 0) | |||
break; | |||
prev_fence = fenced_buf->fence; | |||
} | |||
else { | |||
assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); | |||
assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0); | |||
} | |||
_fenced_buffer_remove(fenced_list, fenced_buf); | |||
@@ -237,14 +236,14 @@ fenced_buffer_destroy(struct pb_buffer *buf) | |||
pipe_mutex_lock(fenced_list->mutex); | |||
assert(fenced_buf->base.base.refcount == 0); | |||
if (fenced_buf->fence) { | |||
struct pipe_winsys *winsys = fenced_list->winsys; | |||
if(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0) { | |||
struct pb_fence_ops *ops = fenced_list->ops; | |||
if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) { | |||
struct list_head *curr, *prev; | |||
curr = &fenced_buf->head; | |||
prev = curr->prev; | |||
do { | |||
fenced_buf = LIST_ENTRY(struct fenced_buffer, curr, head); | |||
assert(winsys->fence_signalled(winsys, fenced_buf->fence, 0) == 0); | |||
assert(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0); | |||
_fenced_buffer_remove(fenced_list, fenced_buf); | |||
curr = prev; | |||
prev = curr->prev; | |||
@@ -366,11 +365,11 @@ fenced_buffer_fence(struct pb_buffer *buf, | |||
{ | |||
struct fenced_buffer *fenced_buf; | |||
struct fenced_buffer_list *fenced_list; | |||
struct pipe_winsys *winsys; | |||
struct pb_fence_ops *ops; | |||
fenced_buf = fenced_buffer(buf); | |||
fenced_list = fenced_buf->list; | |||
winsys = fenced_list->winsys; | |||
ops = fenced_list->ops; | |||
if(fence == fenced_buf->fence) { | |||
/* Nothing to do */ | |||
@@ -384,7 +383,7 @@ fenced_buffer_fence(struct pb_buffer *buf, | |||
if (fenced_buf->fence) | |||
_fenced_buffer_remove(fenced_list, fenced_buf); | |||
if (fence) { | |||
winsys->fence_reference(winsys, &fenced_buf->fence, fence); | |||
ops->fence_reference(ops, &fenced_buf->fence, fence); | |||
fenced_buf->flags |= fenced_buf->validation_flags; | |||
_fenced_buffer_add(fenced_buf); | |||
} | |||
@@ -447,7 +446,7 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list, | |||
struct fenced_buffer_list * | |||
fenced_buffer_list_create(struct pipe_winsys *winsys) | |||
fenced_buffer_list_create(struct pb_fence_ops *ops) | |||
{ | |||
struct fenced_buffer_list *fenced_list; | |||
@@ -455,7 +454,7 @@ fenced_buffer_list_create(struct pipe_winsys *winsys) | |||
if (!fenced_list) | |||
return NULL; | |||
fenced_list->winsys = winsys; | |||
fenced_list->ops = ops; | |||
LIST_INITHEAD(&fenced_list->delayed); | |||
@@ -494,6 +493,8 @@ fenced_buffer_list_destroy(struct fenced_buffer_list *fenced_list) | |||
pipe_mutex_unlock(fenced_list->mutex); | |||
fenced_list->ops->destroy(fenced_list->ops); | |||
FREE(fenced_list); | |||
} | |||
@@ -59,7 +59,6 @@ extern "C" { | |||
#endif | |||
struct pipe_winsys; | |||
struct pipe_buffer; | |||
struct pipe_fence_handle; | |||
@@ -70,13 +69,42 @@ struct pipe_fence_handle; | |||
struct fenced_buffer_list; | |||
struct pb_fence_ops | |||
{ | |||
void (*destroy)( struct pb_fence_ops *ops ); | |||
/** Set ptr = fence, with reference counting */ | |||
void (*fence_reference)( struct pb_fence_ops *ops, | |||
struct pipe_fence_handle **ptr, | |||
struct pipe_fence_handle *fence ); | |||
/** | |||
* Checks whether the fence has been signalled. | |||
* \param flags driver-specific meaning | |||
* \return zero on success. | |||
*/ | |||
int (*fence_signalled)( struct pb_fence_ops *ops, | |||
struct pipe_fence_handle *fence, | |||
unsigned flag ); | |||
/** | |||
* Wait for the fence to finish. | |||
* \param flags driver-specific meaning | |||
* \return zero on success. | |||
*/ | |||
int (*fence_finish)( struct pb_fence_ops *ops, | |||
struct pipe_fence_handle *fence, | |||
unsigned flag ); | |||
}; | |||
/** | |||
* Create a fenced buffer list. | |||
* | |||
* See also fenced_bufmgr_create for a more convenient way to use this. | |||
*/ | |||
struct fenced_buffer_list * | |||
fenced_buffer_list_create(struct pipe_winsys *winsys); | |||
fenced_buffer_list_create(struct pb_fence_ops *ops); | |||
/** |
@@ -61,7 +61,6 @@ extern "C" { | |||
struct pb_desc; | |||
struct pipe_buffer; | |||
struct pipe_winsys; | |||
/** | |||
@@ -163,6 +162,8 @@ pb_cache_manager_create(struct pb_manager *provider, | |||
unsigned usecs); | |||
struct pb_fence_ops; | |||
/** | |||
* Fenced buffer manager. | |||
* | |||
@@ -174,7 +175,7 @@ pb_cache_manager_create(struct pb_manager *provider, | |||
*/ | |||
struct pb_manager * | |||
fenced_bufmgr_create(struct pb_manager *provider, | |||
struct pipe_winsys *winsys); | |||
struct pb_fence_ops *ops); | |||
struct pb_manager * |
@@ -122,7 +122,7 @@ fenced_bufmgr_destroy(struct pb_manager *mgr) | |||
struct pb_manager * | |||
fenced_bufmgr_create(struct pb_manager *provider, | |||
struct pipe_winsys *winsys) | |||
struct pb_fence_ops *ops) | |||
{ | |||
struct fenced_pb_manager *fenced_mgr; | |||
@@ -138,7 +138,7 @@ fenced_bufmgr_create(struct pb_manager *provider, | |||
fenced_mgr->base.flush = fenced_bufmgr_flush; | |||
fenced_mgr->provider = provider; | |||
fenced_mgr->fenced_list = fenced_buffer_list_create(winsys); | |||
fenced_mgr->fenced_list = fenced_buffer_list_create(ops); | |||
if(!fenced_mgr->fenced_list) { | |||
FREE(fenced_mgr); | |||
return NULL; |
@@ -114,7 +114,7 @@ tgsi_default_declaration( void ) | |||
struct tgsi_declaration declaration; | |||
declaration.Type = TGSI_TOKEN_TYPE_DECLARATION; | |||
declaration.Size = 1; | |||
declaration.NrTokens = 1; | |||
declaration.File = TGSI_FILE_NULL; | |||
declaration.UsageMask = TGSI_WRITEMASK_XYZW; | |||
declaration.Interpolate = TGSI_INTERPOLATE_CONSTANT; | |||
@@ -160,9 +160,9 @@ declaration_grow( | |||
struct tgsi_declaration *declaration, | |||
struct tgsi_header *header ) | |||
{ | |||
assert( declaration->Size < 0xFF ); | |||
assert( declaration->NrTokens < 0xFF ); | |||
declaration->Size++; | |||
declaration->NrTokens++; | |||
header_bodysize_grow( header ); | |||
} | |||
@@ -308,7 +308,7 @@ tgsi_default_immediate( void ) | |||
struct tgsi_immediate immediate; | |||
immediate.Type = TGSI_TOKEN_TYPE_IMMEDIATE; | |||
immediate.Size = 1; | |||
immediate.NrTokens = 1; | |||
immediate.DataType = TGSI_IMM_FLOAT32; | |||
immediate.Padding = 0; | |||
immediate.Extended = 0; | |||
@@ -345,9 +345,9 @@ immediate_grow( | |||
struct tgsi_immediate *immediate, | |||
struct tgsi_header *header ) | |||
{ | |||
assert( immediate->Size < 0xFF ); | |||
assert( immediate->NrTokens < 0xFF ); | |||
immediate->Size++; | |||
immediate->NrTokens++; | |||
header_bodysize_grow( header ); | |||
} | |||
@@ -384,7 +384,7 @@ tgsi_build_full_immediate( | |||
*immediate = tgsi_build_immediate( header ); | |||
for( i = 0; i < full_imm->Immediate.Size - 1; i++ ) { | |||
for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) { | |||
struct tgsi_immediate_float32 *if32; | |||
if( maxsize <= size ) | |||
@@ -411,7 +411,7 @@ tgsi_default_instruction( void ) | |||
struct tgsi_instruction instruction; | |||
instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION; | |||
instruction.Size = 1; | |||
instruction.NrTokens = 1; | |||
instruction.Opcode = TGSI_OPCODE_MOV; | |||
instruction.Saturate = TGSI_SAT_NONE; | |||
instruction.NumDstRegs = 1; | |||
@@ -453,9 +453,9 @@ instruction_grow( | |||
struct tgsi_instruction *instruction, | |||
struct tgsi_header *header ) | |||
{ | |||
assert (instruction->Size < 0xFF); | |||
assert (instruction->NrTokens < 0xFF); | |||
instruction->Size++; | |||
instruction->NrTokens++; | |||
header_bodysize_grow( header ); | |||
} |
@@ -285,7 +285,7 @@ iter_immediate( | |||
ENM( imm->Immediate.DataType, immediate_type_names ); | |||
TXT( " { " ); | |||
for (i = 0; i < imm->Immediate.Size - 1; i++) { | |||
for (i = 0; i < imm->Immediate.NrTokens - 1; i++) { | |||
switch (imm->Immediate.DataType) { | |||
case TGSI_IMM_FLOAT32: | |||
FLT( imm->u.ImmediateFloat32[i].Float ); | |||
@@ -294,7 +294,7 @@ iter_immediate( | |||
assert( 0 ); | |||
} | |||
if (i < imm->Immediate.Size - 2) | |||
if (i < imm->Immediate.NrTokens - 2) | |||
TXT( ", " ); | |||
} | |||
TXT( " }" ); |
@@ -283,7 +283,7 @@ dump_immediate_verbose( | |||
UIX( imm->Immediate.Padding ); | |||
} | |||
for( i = 0; i < imm->Immediate.Size - 1; i++ ) { | |||
for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) { | |||
EOL(); | |||
switch( imm->Immediate.DataType ) { | |||
case TGSI_IMM_FLOAT32: | |||
@@ -675,7 +675,7 @@ tgsi_dump_c( | |||
ENM( parse.FullToken.Token.Type, TGSI_TOKEN_TYPES ); | |||
if( ignored ) { | |||
TXT( "\nSize : " ); | |||
UID( parse.FullToken.Token.Size ); | |||
UID( parse.FullToken.Token.NrTokens ); | |||
if( deflt || parse.FullToken.Token.Extended ) { | |||
TXT( "\nExtended : " ); | |||
UID( parse.FullToken.Token.Extended ); |
@@ -202,7 +202,7 @@ tgsi_exec_machine_bind_shader( | |||
case TGSI_TOKEN_TYPE_IMMEDIATE: | |||
{ | |||
uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; | |||
uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1; | |||
assert( size % 4 == 0 ); | |||
assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES ); | |||
@@ -155,8 +155,8 @@ tgsi_parse_token( | |||
switch (imm->Immediate.DataType) { | |||
case TGSI_IMM_FLOAT32: | |||
imm->u.Pointer = MALLOC( | |||
sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.Size - 1) ); | |||
for( i = 0; i < imm->Immediate.Size - 1; i++ ) { | |||
sizeof( struct tgsi_immediate_float32 ) * (imm->Immediate.NrTokens - 1) ); | |||
for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) { | |||
next_token( ctx, (struct tgsi_immediate_float32 *) &imm->u.ImmediateFloat32[i] ); | |||
} | |||
break; |
@@ -1327,7 +1327,7 @@ tgsi_emit_ppc(const struct tgsi_token *tokens, | |||
case TGSI_TOKEN_TYPE_IMMEDIATE: | |||
/* splat each immediate component into a float[4] vector for SoA */ | |||
{ | |||
const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; | |||
const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1; | |||
uint i; | |||
assert(size <= 4); | |||
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); |
@@ -2671,7 +2671,7 @@ tgsi_emit_sse2( | |||
case TGSI_TOKEN_TYPE_IMMEDIATE: | |||
/* simply copy the immediate values into the next immediates[] slot */ | |||
{ | |||
const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1; | |||
const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1; | |||
uint i; | |||
assert(size <= 4); | |||
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES); |
@@ -1023,7 +1023,7 @@ static boolean parse_immediate( struct translate_ctx *ctx ) | |||
ctx->cur++; | |||
imm = tgsi_default_full_immediate(); | |||
imm.Immediate.Size += 4; | |||
imm.Immediate.NrTokens += 4; | |||
imm.Immediate.DataType = TGSI_IMM_FLOAT32; | |||
imm.u.Pointer = values; | |||
@@ -51,7 +51,7 @@ cell_map_constant_buffers(struct cell_context *sp) | |||
struct pipe_winsys *ws = sp->pipe.winsys; | |||
uint i; | |||
for (i = 0; i < 2; i++) { | |||
if (sp->constants[i].size) { | |||
if (sp->constants[i].buffer && sp->constants[i].buffer->size) { | |||
sp->mapped_constants[i] = ws->buffer_map(ws, sp->constants[i].buffer, | |||
PIPE_BUFFER_USAGE_CPU_READ); | |||
cell_flush_buffer_range(sp, sp->mapped_constants[i], | |||
@@ -61,7 +61,7 @@ cell_map_constant_buffers(struct cell_context *sp) | |||
draw_set_mapped_constant_buffer(sp->draw, | |||
sp->mapped_constants[PIPE_SHADER_VERTEX], | |||
sp->constants[PIPE_SHADER_VERTEX].size); | |||
sp->constants[PIPE_SHADER_VERTEX].buffer->size); | |||
} | |||
static void | |||
@@ -70,7 +70,7 @@ cell_unmap_constant_buffers(struct cell_context *sp) | |||
struct pipe_winsys *ws = sp->pipe.winsys; | |||
uint i; | |||
for (i = 0; i < 2; i++) { | |||
if (sp->constants[i].size) | |||
if (sp->constants[i].buffer && sp->constants[i].buffer->size) | |||
ws->buffer_unmap(ws, sp->constants[i].buffer); | |||
sp->mapped_constants[i] = NULL; | |||
} |
@@ -161,7 +161,7 @@ gen_alpha_test(const struct pipe_depth_stencil_alpha_state *dsa, | |||
if ((dsa->alpha.func != PIPE_FUNC_NEVER) && | |||
(dsa->alpha.func != PIPE_FUNC_ALWAYS)) { | |||
/* load/splat the alpha reference float value */ | |||
spe_load_float(f, ref_reg, dsa->alpha.ref); | |||
spe_load_float(f, ref_reg, dsa->alpha.ref_value); | |||
} | |||
/* emit code to do the alpha comparison, updating 'mask' */ |
@@ -239,7 +239,7 @@ cell_emit_state(struct cell_context *cell) | |||
if (cell->dirty & (CELL_NEW_FS_CONSTANTS)) { | |||
const uint shader = PIPE_SHADER_FRAGMENT; | |||
const uint num_const = cell->constants[shader].size / sizeof(float); | |||
const uint num_const = cell->constants[shader].buffer->size / sizeof(float); | |||
uint i, j; | |||
float *buf = cell_batch_alloc16(cell, ROUNDUP16(32 + num_const * sizeof(float))); | |||
uint32_t *ibuf = (uint32_t *) buf; |
@@ -186,7 +186,6 @@ cell_set_constant_buffer(struct pipe_context *pipe, | |||
const struct pipe_constant_buffer *buf) | |||
{ | |||
struct cell_context *cell = cell_context(pipe); | |||
struct pipe_winsys *ws = pipe->winsys; | |||
assert(shader < PIPE_SHADER_TYPES); | |||
assert(index == 0); | |||
@@ -197,7 +196,6 @@ cell_set_constant_buffer(struct pipe_context *pipe, | |||
pipe_buffer_reference(pipe->screen, | |||
&cell->constants[shader].buffer, | |||
buf->buffer); | |||
cell->constants[shader].size = buf->size; | |||
if (shader == PIPE_SHADER_VERTEX) | |||
cell->dirty |= CELL_NEW_VS_CONSTANTS; |
@@ -307,9 +307,8 @@ cell_twiddle_texture(struct pipe_screen *screen, | |||
const uint texHeight = ct->base.height[level]; | |||
const uint bufWidth = align(texWidth, TILE_SIZE); | |||
const uint bufHeight = align(texHeight, TILE_SIZE); | |||
const void *map = pipe_buffer_map(screen, surface->buffer, | |||
PIPE_BUFFER_USAGE_CPU_READ); | |||
const uint *src = (const uint *) ((const ubyte *) map + surface->offset); | |||
const void *map = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_READ); | |||
const uint *src = (const uint *) map; | |||
switch (ct->base.format) { | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
@@ -324,12 +323,12 @@ cell_twiddle_texture(struct pipe_screen *screen, | |||
/* allocate buffer for tiled data now */ | |||
struct pipe_winsys *ws = screen->winsys; | |||
uint bytes = bufWidth * bufHeight * 4 * numFaces; | |||
ct->tiled_buffer[level] = ws->buffer_create(ws, 16, | |||
PIPE_BUFFER_USAGE_PIXEL, | |||
bytes); | |||
ct->tiled_buffer[level] = | |||
ws->buffer_create(ws, 16, PIPE_BUFFER_USAGE_PIXEL, bytes); | |||
/* and map it */ | |||
ct->tiled_mapped[level] = ws->buffer_map(ws, ct->tiled_buffer[level], | |||
PIPE_BUFFER_USAGE_GPU_READ); | |||
ct->tiled_mapped[level] = | |||
ws->buffer_map(ws, ct->tiled_buffer[level], | |||
PIPE_BUFFER_USAGE_GPU_READ); | |||
} | |||
dst = (uint *) ((ubyte *) ct->tiled_mapped[level] + offset); | |||
@@ -338,11 +337,11 @@ cell_twiddle_texture(struct pipe_screen *screen, | |||
} | |||
break; | |||
default: | |||
printf("Cell: twiddle unsupported texture format %s\n", pf_name(ct->base.format)); | |||
; | |||
printf("Cell: twiddle unsupported texture format %s\n", | |||
pf_name(ct->base.format)); | |||
} | |||
pipe_buffer_unmap(screen, surface->buffer); | |||
screen->surface_unmap(screen, surface); | |||
} | |||
@@ -357,8 +356,7 @@ cell_untwiddle_texture(struct pipe_screen *screen, | |||
const uint level = surface->level; | |||
const uint texWidth = ct->base.width[level]; | |||
const uint texHeight = ct->base.height[level]; | |||
const void *map = pipe_buffer_map(screen, surface->buffer, | |||
PIPE_BUFFER_USAGE_CPU_READ); | |||
const void *map = screen->surface_map(screen, surface, PIPE_BUFFER_USAGE_CPU_READ); | |||
const uint *src = (const uint *) ((const ubyte *) map + surface->offset); | |||
switch (ct->base.format) { | |||
@@ -384,11 +382,12 @@ cell_untwiddle_texture(struct pipe_screen *screen, | |||
default: | |||
{ | |||
ct->untiled_data[level] = NULL; | |||
printf("Cell: untwiddle unsupported texture format %s\n", pf_name(ct->base.format)); | |||
printf("Cell: untwiddle unsupported texture format %s\n", | |||
pf_name(ct->base.format)); | |||
} | |||
} | |||
pipe_buffer_unmap(screen, surface->buffer); | |||
screen->surface_unmap(screen, surface); | |||
} | |||
@@ -398,15 +397,13 @@ cell_get_tex_surface(struct pipe_screen *screen, | |||
unsigned face, unsigned level, unsigned zslice, | |||
unsigned usage) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct cell_texture *ct = cell_texture(pt); | |||
struct pipe_surface *ps; | |||
ps = ws->surface_alloc(ws); | |||
ps = CALLOC_STRUCT(pipe_surface); | |||
if (ps) { | |||
assert(ps->refcount); | |||
assert(ps->winsys); | |||
pipe_buffer_reference(screen, &ps->buffer, ct->buffer); | |||
ps->refcount = 1; | |||
pipe_texture_reference(&ps->texture, pt); | |||
ps->format = pt->format; | |||
ps->block = pt->block; | |||
ps->width = pt->width[level]; | |||
@@ -425,9 +422,9 @@ cell_get_tex_surface(struct pipe_screen *screen, | |||
ps->zslice = zslice; | |||
if (pt->target == PIPE_TEXTURE_CUBE || pt->target == PIPE_TEXTURE_3D) { | |||
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * | |||
ps->nblocksy * | |||
ps->stride; | |||
ps->offset += ((pt->target == PIPE_TEXTURE_CUBE) ? face : zslice) * | |||
ps->nblocksy * | |||
ps->stride; | |||
} | |||
else { | |||
assert(face == 0); | |||
@@ -449,18 +446,27 @@ cell_tex_surface_release(struct pipe_screen *screen, | |||
{ | |||
struct cell_texture *ct = cell_texture((*s)->texture); | |||
const uint level = (*s)->level; | |||
struct pipe_surface *surf = *s; | |||
if (((*s)->usage & PIPE_BUFFER_USAGE_CPU_READ) && (ct->untiled_data[level])) | |||
if ((surf->usage & PIPE_BUFFER_USAGE_CPU_READ) && (ct->untiled_data[level])) | |||
{ | |||
align_free(ct->untiled_data[level]); | |||
ct->untiled_data[level] = NULL; | |||
} | |||
/* XXX if done rendering to teximage, re-tile */ | |||
if ((ct->base.tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) && | |||
(surf->usage & PIPE_BUFFER_USAGE_CPU_WRITE)) { | |||
/* convert from linear to tiled layout */ | |||
cell_twiddle_texture(screen, surf); | |||
} | |||
pipe_texture_reference(&(*s)->texture, NULL); | |||
/* XXX if done rendering to teximage, re-tile */ | |||
screen->winsys->surface_release(screen->winsys, s); | |||
if (--surf->refcount == 0) { | |||
pipe_texture_reference(&surf->texture, NULL); | |||
FREE(surf); | |||
} | |||
*s = NULL; | |||
} | |||
@@ -475,17 +481,20 @@ cell_surface_map(struct pipe_screen *screen, | |||
assert(ct); | |||
#if 0 | |||
if (flags & ~surface->usage) { | |||
assert(0); | |||
return NULL; | |||
} | |||
#endif | |||
map = pipe_buffer_map( screen, surface->buffer, flags ); | |||
if (map == NULL) | |||
map = pipe_buffer_map( screen, ct->buffer, flags ); | |||
if (map == NULL) { | |||
return NULL; | |||
else | |||
{ | |||
if ((surface->usage & PIPE_BUFFER_USAGE_CPU_READ) && (ct->untiled_data[level])) { | |||
} | |||
else { | |||
if ((surface->usage & PIPE_BUFFER_USAGE_CPU_READ) && | |||
(ct->untiled_data[level])) { | |||
return (void *) ((ubyte *) ct->untiled_data[level] + surface->offset); | |||
} | |||
else { | |||
@@ -503,13 +512,7 @@ cell_surface_unmap(struct pipe_screen *screen, | |||
assert(ct); | |||
if ((ct->base.tex_usage & PIPE_TEXTURE_USAGE_SAMPLER) && | |||
(surface->usage & PIPE_BUFFER_USAGE_CPU_WRITE)) { | |||
/* convert from linear to tiled layout */ | |||
cell_twiddle_texture(screen, surface); | |||
} | |||
pipe_buffer_unmap( screen, surface->buffer ); | |||
pipe_buffer_unmap( screen, ct->buffer ); | |||
} | |||
@@ -85,7 +85,7 @@ spu_fallback_fragment_ops(uint x, uint y, | |||
* Do alpha test | |||
*/ | |||
if (spu.depth_stencil_alpha.alpha.enabled) { | |||
vector float ref = spu_splats(spu.depth_stencil_alpha.alpha.ref); | |||
vector float ref = spu_splats(spu.depth_stencil_alpha.alpha.ref_value); | |||
vector unsigned int amask; | |||
switch (spu.depth_stencil_alpha.alpha.func) { |
@@ -964,7 +964,7 @@ i915_translate_instructions(struct i915_fp_compile *p, | |||
= &parse.FullToken.FullImmediate; | |||
const uint pos = p->num_immediates++; | |||
uint j; | |||
for (j = 0; j < imm->Immediate.Size; j++) { | |||
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) { | |||
p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float; | |||
} | |||
} |
@@ -1293,7 +1293,7 @@ void brw_vs_emit(struct brw_vs_compile *c) | |||
break; | |||
case TGSI_TOKEN_TYPE_IMMEDIATE: { | |||
struct tgsi_full_immediate *imm = &parse.FullToken.FullImmediate; | |||
/*assert(imm->Immediate.Size == 4);*/ | |||
assert(imm->Immediate.NrTokens == 4 + 1); | |||
c->prog_data.imm_buf[c->prog_data.num_imm][0] = imm->u.ImmediateFloat32[0].Float; | |||
c->prog_data.imm_buf[c->prog_data.num_imm][1] = imm->u.ImmediateFloat32[1].Float; | |||
c->prog_data.imm_buf[c->prog_data.num_imm][2] = imm->u.ImmediateFloat32[2].Float; |
@@ -87,6 +87,7 @@ nv04_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, | |||
mt->base = *pt; | |||
mt->base.refcount = 1; | |||
mt->base.screen = pscreen; | |||
mt->level[0].pitch = stride[0]; | |||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | |||
pipe_buffer_reference(pscreen, &mt->buffer, pb); |
@@ -47,6 +47,7 @@ nv04_surface_copy(struct pipe_context *pipe, boolean do_flip, | |||
eng2d->copy(eng2d, dest, destx, desty--, src, | |||
srcx, srcy++, width, 1); | |||
} | |||
return; | |||
} | |||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); |
@@ -1,6 +1,7 @@ | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_format.h" | |||
#include "util/u_memory.h" | |||
#include "util/u_math.h" | |||
#include "nouveau/nouveau_winsys.h" | |||
#include "nouveau/nouveau_util.h" | |||
@@ -103,10 +104,7 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, | |||
struct nouveau_bo *dst_bo = ctx->nvws->get_bo(ctx->buf(dst)); | |||
const unsigned max_w = 1024; | |||
const unsigned max_h = 1024; | |||
const unsigned sub_w = w > max_w ? max_w : w; | |||
const unsigned sub_h = h > max_h ? max_h : h; | |||
unsigned cx = 0; | |||
unsigned cy = 0; | |||
int i, src_offset = src->offset, dst_offset = dst->offset, src_stride = src->stride; | |||
/* POT or GTFO */ | |||
assert(!(w & (w - 1)) && !(h & (h - 1))); | |||
@@ -114,10 +112,6 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, | |||
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1); | |||
OUT_RELOCo(chan, dst_bo, | |||
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); | |||
OUT_RING (chan, nv04_surface_format(dst->format) | | |||
log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | | |||
log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); | |||
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); | |||
OUT_RELOCo(chan, src_bo, | |||
@@ -125,34 +119,56 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx, | |||
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); | |||
OUT_RING (chan, swzsurf->handle); | |||
for (cy = 0; cy < h; cy += sub_h) { | |||
for (cx = 0; cx < w; cx += sub_w) { | |||
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); | |||
OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx, cy) * | |||
dst->block.size, NOUVEAU_BO_GART | | |||
NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); | |||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); | |||
OUT_RING (chan, nv04_scaled_image_format(src->format)); | |||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); | |||
OUT_RING (chan, 0); | |||
OUT_RING (chan, sub_h << 16 | sub_w); | |||
OUT_RING (chan, 0); | |||
OUT_RING (chan, sub_h << 16 | sub_w); | |||
OUT_RING (chan, 1 << 20); | |||
OUT_RING (chan, 1 << 20); | |||
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); | |||
OUT_RING (chan, sub_h << 16 | sub_w); | |||
OUT_RING (chan, src->stride | | |||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | | |||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); | |||
OUT_RELOCl(chan, src_bo, src->offset + cy * src->stride + | |||
cx * src->block.size, NOUVEAU_BO_GART | | |||
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); | |||
OUT_RING (chan, 0); | |||
} | |||
/* Upload, then swizzle each mipmap level in turn */ | |||
for (i=0; i<src->texture->last_level; i++) { | |||
unsigned sub_w, sub_h; | |||
unsigned cx, cy; | |||
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_FORMAT, 1); | |||
OUT_RING (chan, nv04_surface_format(dst->format) | | |||
log2i(w) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_U_SHIFT | | |||
log2i(h) << NV04_SWIZZLED_SURFACE_FORMAT_BASE_SIZE_V_SHIFT); | |||
sub_w = w > max_w ? max_w : w; | |||
sub_h = h > max_h ? max_h : h; | |||
for (cy = 0; cy < h; cy += sub_h) { | |||
for (cx = 0; cx < w; cx += sub_w) { | |||
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1); | |||
OUT_RELOCl(chan, dst_bo, dst_offset + nv04_swizzle_bits(cx, cy) * | |||
dst->block.size, NOUVEAU_BO_GART | | |||
NOUVEAU_BO_VRAM | NOUVEAU_BO_WR); | |||
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9); | |||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_TRUNCATE); | |||
OUT_RING (chan, nv04_scaled_image_format(src->format)); | |||
OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY); | |||
OUT_RING (chan, 0); | |||
OUT_RING (chan, sub_h << 16 | sub_w); | |||
OUT_RING (chan, 0); | |||
OUT_RING (chan, sub_h << 16 | sub_w); | |||
OUT_RING (chan, 1 << 20); | |||
OUT_RING (chan, 1 << 20); | |||
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_SIZE, 4); | |||
OUT_RING (chan, sub_h << 16 | sub_w); | |||
OUT_RING (chan, src_stride | | |||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER | | |||
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE); | |||
OUT_RELOCl(chan, src_bo, src_offset + cy * src_stride + | |||
cx * src->block.size, NOUVEAU_BO_GART | | |||
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD); | |||
OUT_RING (chan, 0); | |||
} | |||
} | |||
/* FIXME: need to find next offset for source */ | |||
/*src_offset += w * h * src->block.size;*/ | |||
dst_offset += w * h * dst->block.size; | |||
src_stride >>= 1; | |||
w >>= 1; | |||
h >>= 1; | |||
} | |||
return 0; | |||
@@ -277,7 +293,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst, | |||
cs2d_format = nv04_surface_format(dst->format); | |||
assert(cs2d_format >= 0); | |||
gdirect_format = nv04_surface_format(dst->format); | |||
gdirect_format = nv04_rect_format(dst->format); | |||
assert(gdirect_format >= 0); | |||
WAIT_RING (chan, 16); | |||
@@ -391,7 +407,7 @@ nv04_surface_2d_init(struct nouveau_winsys *nvws) | |||
BEGIN_RING(chan, ctx->rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1); | |||
OUT_RING (chan, ctx->ntfy->handle); | |||
BEGIN_RING(chan, ctx->rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); | |||
OUT_RING (chan, ctx->ntfy->handle); | |||
OUT_RING (chan, ctx->surf2d->handle); | |||
BEGIN_RING(chan, ctx->rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); | |||
OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_SRCCOPY); | |||
BEGIN_RING(chan, ctx->rect, |
@@ -68,6 +68,7 @@ nv10_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, | |||
mt->base = *pt; | |||
mt->base.refcount = 1; | |||
mt->base.screen = pscreen; | |||
mt->level[0].pitch = stride[0]; | |||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | |||
pipe_buffer_reference(pscreen, &mt->buffer, pb); |
@@ -47,6 +47,7 @@ nv10_surface_copy(struct pipe_context *pipe, boolean do_flip, | |||
eng2d->copy(eng2d, dest, destx, desty--, src, | |||
srcx, srcy++, width, 1); | |||
} | |||
return; | |||
} | |||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); |
@@ -68,6 +68,7 @@ nv20_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, | |||
mt->base = *pt; | |||
mt->base.refcount = 1; | |||
mt->base.screen = pscreen; | |||
mt->level[0].pitch = stride[0]; | |||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | |||
pipe_buffer_reference(pscreen, &mt->buffer, pb); | |||
@@ -79,6 +80,8 @@ nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct nv20_miptree *mt; | |||
unsigned buf_usage = PIPE_BUFFER_USAGE_PIXEL | | |||
NOUVEAU_BUFFER_USAGE_TEXTURE; | |||
mt = MALLOC(sizeof(struct nv20_miptree)); | |||
if (!mt) | |||
@@ -87,10 +90,35 @@ nv20_miptree_create(struct pipe_screen *screen, const struct pipe_texture *pt) | |||
mt->base.refcount = 1; | |||
mt->base.screen = screen; | |||
/* Swizzled textures must be POT */ | |||
if (pt->width[0] & (pt->width[0] - 1) || | |||
pt->height[0] & (pt->height[0] - 1)) | |||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||
else | |||
if (pt->tex_usage & (PIPE_TEXTURE_USAGE_PRIMARY | | |||
PIPE_TEXTURE_USAGE_DISPLAY_TARGET)) | |||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||
else | |||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) | |||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||
else { | |||
switch (pt->format) { | |||
/* TODO: Figure out which formats can be swizzled */ | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
case PIPE_FORMAT_X8R8G8B8_UNORM: | |||
case PIPE_FORMAT_R16_SNORM: | |||
break; | |||
default: | |||
mt->base.tex_usage |= NOUVEAU_TEXTURE_USAGE_LINEAR; | |||
} | |||
} | |||
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DYNAMIC) | |||
buf_usage |= PIPE_BUFFER_USAGE_CPU_READ_WRITE; | |||
nv20_miptree_layout(mt); | |||
mt->buffer = ws->buffer_create(ws, 256, PIPE_BUFFER_USAGE_PIXEL, | |||
mt->total_size); | |||
mt->buffer = ws->buffer_create(ws, 256, buf_usage, mt->total_size); | |||
if (!mt->buffer) { | |||
FREE(mt); | |||
return NULL; |
@@ -47,6 +47,7 @@ nv20_surface_copy(struct pipe_context *pipe, boolean do_flip, | |||
eng2d->copy(eng2d, dest, destx, desty--, src, | |||
srcx, srcy++, width, 1); | |||
} | |||
return; | |||
} | |||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); |
@@ -613,7 +613,7 @@ nv20_vertprog_translate(struct nv20_context *nv20, | |||
imm = &parse.FullToken.FullImmediate; | |||
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); | |||
// assert(imm->Immediate.Size == 4); | |||
assert(imm->Immediate.NrTokens == 4 + 1); | |||
vpc->imm[vpc->nr_imm++] = | |||
constant(vpc, -1, | |||
imm->u.ImmediateFloat32[0].Float, |
@@ -123,6 +123,7 @@ nv30_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, | |||
mt->base = *pt; | |||
mt->base.refcount = 1; | |||
mt->base.screen = pscreen; | |||
mt->level[0].pitch = stride[0]; | |||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | |||
pipe_buffer_reference(pscreen, &mt->buffer, pb); |
@@ -127,6 +127,14 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen, | |||
return FALSE; | |||
} | |||
static struct pipe_buffer * | |||
nv30_surface_buffer(struct pipe_surface *surf) | |||
{ | |||
struct nv30_miptree *mt = (struct nv30_miptree *)surf->texture; | |||
return mt->buffer; | |||
} | |||
static void * | |||
nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, | |||
unsigned flags ) | |||
@@ -134,7 +142,6 @@ nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct pipe_surface *surface_to_map; | |||
void *map; | |||
struct nv30_miptree *nv30mt = (struct nv30_miptree *)surface->texture; | |||
if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { | |||
struct nv30_miptree *mt = (struct nv30_miptree *)surface->texture; | |||
@@ -163,7 +170,7 @@ nv30_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, | |||
assert(surface_to_map); | |||
map = ws->buffer_map(ws, nv30mt->buffer, flags); | |||
map = ws->buffer_map(ws, nv30_surface_buffer(surface_to_map), flags); | |||
if (!map) | |||
return NULL; | |||
@@ -175,7 +182,6 @@ nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct pipe_surface *surface_to_unmap; | |||
struct nv30_miptree *nv30mt = (struct nv30_miptree *)surface->texture; | |||
/* TODO: Copy from shadow just before push buffer is flushed instead. | |||
There are probably some programs that map/unmap excessively | |||
@@ -192,15 +198,14 @@ nv30_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) | |||
assert(surface_to_unmap); | |||
ws->buffer_unmap(ws, nv30mt->buffer); | |||
ws->buffer_unmap(ws, nv30_surface_buffer(surface_to_unmap)); | |||
if (surface_to_unmap != surface) { | |||
struct nv30_screen *nvscreen = nv30_screen(screen); | |||
nvscreen->nvws->surface_copy(nvscreen->nvws, | |||
surface, 0, 0, | |||
surface_to_unmap, 0, 0, | |||
surface->width, surface->height); | |||
nvscreen->eng2d->copy(nvscreen->eng2d, surface, 0, 0, | |||
surface_to_unmap, 0, 0, | |||
surface->width, surface->height); | |||
} | |||
} | |||
@@ -220,14 +225,6 @@ nv30_screen_destroy(struct pipe_screen *pscreen) | |||
FREE(pscreen); | |||
} | |||
static struct pipe_buffer * | |||
nv30_surface_buffer(struct pipe_surface *surf) | |||
{ | |||
struct nv30_miptree *mt = (struct nv30_miptree *)surf->texture; | |||
return mt->buffer; | |||
} | |||
struct pipe_screen * | |||
nv30_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) | |||
{ |
@@ -47,6 +47,7 @@ nv30_surface_copy(struct pipe_context *pipe, boolean do_flip, | |||
eng2d->copy(eng2d, dest, destx, desty--, src, | |||
srcx, srcy++, width, 1); | |||
} | |||
return; | |||
} | |||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); |
@@ -613,7 +613,7 @@ nv30_vertprog_translate(struct nv30_context *nv30, | |||
imm = &parse.FullToken.FullImmediate; | |||
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); | |||
// assert(imm->Immediate.Size == 4); | |||
assert(imm->Immediate.NrTokens == 4 + 1); | |||
vpc->imm[vpc->nr_imm++] = | |||
constant(vpc, -1, | |||
imm->u.ImmediateFloat32[0].Float, |
@@ -124,6 +124,7 @@ nv40_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt, | |||
mt->base = *pt; | |||
mt->base.refcount = 1; | |||
mt->base.screen = pscreen; | |||
mt->level[0].pitch = stride[0]; | |||
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned)); | |||
pipe_buffer_reference(pscreen, &mt->buffer, pb); |
@@ -136,6 +136,14 @@ nv40_screen_surface_format_supported(struct pipe_screen *pscreen, | |||
return FALSE; | |||
} | |||
static struct pipe_buffer * | |||
nv40_surface_buffer(struct pipe_surface *surf) | |||
{ | |||
struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture; | |||
return mt->buffer; | |||
} | |||
static void * | |||
nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, | |||
unsigned flags ) | |||
@@ -143,7 +151,6 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct pipe_surface *surface_to_map; | |||
void *map; | |||
struct nv40_miptree *mt; | |||
if (!(surface->texture->tex_usage & NOUVEAU_TEXTURE_USAGE_LINEAR)) { | |||
struct nv40_miptree *mt = (struct nv40_miptree *)surface->texture; | |||
@@ -171,8 +178,7 @@ nv40_surface_map(struct pipe_screen *screen, struct pipe_surface *surface, | |||
surface_to_map = surface; | |||
assert(surface_to_map); | |||
mt = (struct nv40_miptree *)surface_to_map->texture; | |||
map = ws->buffer_map(ws, mt->buffer, flags); | |||
map = ws->buffer_map(ws, nv40_surface_buffer(surface_to_map), flags); | |||
if (!map) | |||
return NULL; | |||
@@ -184,7 +190,6 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) | |||
{ | |||
struct pipe_winsys *ws = screen->winsys; | |||
struct pipe_surface *surface_to_unmap; | |||
struct nv40_miptree *mt; | |||
/* TODO: Copy from shadow just before push buffer is flushed instead. | |||
There are probably some programs that map/unmap excessively | |||
@@ -201,16 +206,14 @@ nv40_surface_unmap(struct pipe_screen *screen, struct pipe_surface *surface) | |||
assert(surface_to_unmap); | |||
mt = (struct nv40_miptree *)surface_to_unmap->texture; | |||
ws->buffer_unmap(ws, mt->buffer); | |||
ws->buffer_unmap(ws, nv40_surface_buffer(surface_to_unmap)); | |||
if (surface_to_unmap != surface) { | |||
struct nv40_screen *nvscreen = nv40_screen(screen); | |||
nvscreen->nvws->surface_copy(nvscreen->nvws, | |||
surface, 0, 0, | |||
surface_to_unmap, 0, 0, | |||
surface->width, surface->height); | |||
nvscreen->eng2d->copy(nvscreen->eng2d, surface, 0, 0, | |||
surface_to_unmap, 0, 0, | |||
surface->width, surface->height); | |||
} | |||
} | |||
@@ -230,14 +233,6 @@ nv40_screen_destroy(struct pipe_screen *pscreen) | |||
FREE(pscreen); | |||
} | |||
static struct pipe_buffer * | |||
nv40_surface_buffer(struct pipe_surface *surf) | |||
{ | |||
struct nv40_miptree *mt = (struct nv40_miptree *)surf->texture; | |||
return mt->buffer; | |||
} | |||
struct pipe_screen * | |||
nv40_screen_create(struct pipe_winsys *ws, struct nouveau_winsys *nvws) | |||
{ |
@@ -47,6 +47,7 @@ nv40_surface_copy(struct pipe_context *pipe, boolean do_flip, | |||
eng2d->copy(eng2d, dest, destx, desty--, src, | |||
srcx, srcy++, width, 1); | |||
} | |||
return; | |||
} | |||
eng2d->copy(eng2d, dest, destx, desty, src, srcx, srcy, width, height); |
@@ -784,7 +784,7 @@ nv40_vertprog_translate(struct nv40_context *nv40, | |||
imm = &parse.FullToken.FullImmediate; | |||
assert(imm->Immediate.DataType == TGSI_IMM_FLOAT32); | |||
// assert(imm->Immediate.Size == 4); | |||
assert(imm->Immediate.NrTokens == 4 + 1); | |||
vpc->imm[vpc->nr_imm++] = | |||
constant(vpc, -1, | |||
imm->u.ImmediateFloat32[0].Float, |
@@ -167,6 +167,11 @@ extern void nv50_init_query_functions(struct nv50_context *nv50); | |||
extern void nv50_screen_init_miptree_functions(struct pipe_screen *pscreen); | |||
extern int | |||
nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, | |||
int dx, int dy, struct pipe_surface *src, int sx, int sy, | |||
int w, int h); | |||
/* nv50_draw.c */ | |||
extern struct draw_stage *nv50_draw_render_stage(struct nv50_context *nv50); | |||
@@ -166,7 +166,7 @@ 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_screen *nvscreen = nv50_screen(pscreen); | |||
struct nv50_miptree_level *lvl = &mt->level[level]; | |||
struct pipe_surface *dst, *src; | |||
unsigned face = 0, zslice = 0; | |||
@@ -197,7 +197,7 @@ nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt, | |||
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); | |||
nv50_surface_do_copy(nvscreen, dst, 0, 0, src, 0, 0, dst->width, dst->height); | |||
pscreen->tex_surface_release(pscreen, &dst); | |||
pscreen->tex_surface_release(pscreen, &src); | |||
@@ -208,7 +208,7 @@ static 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_screen *nvscreen = nv50_screen(pscreen); | |||
struct nv50_miptree_level *lvl = &mt->level[level]; | |||
struct pipe_surface *dst, *src; | |||
unsigned face = 0, zslice = 0; | |||
@@ -229,7 +229,7 @@ nv50_miptree_sync_cpu(struct pipe_screen *pscreen, struct nv50_miptree *mt, | |||
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); | |||
nv50_surface_do_copy(nvscreen, dst, 0, 0, src, 0, 0, dst->width, dst->height); | |||
pscreen->tex_surface_release(pscreen, &dst); | |||
pscreen->tex_surface_release(pscreen, &src); |
@@ -102,7 +102,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst) | |||
return 0; | |||
} | |||
static int | |||
int | |||
nv50_surface_do_copy(struct nv50_screen *screen, struct pipe_surface *dst, | |||
int dx, int dy, struct pipe_surface *src, int sx, int sy, | |||
int w, int h) |
@@ -0,0 +1,21 @@ | |||
TOP = ../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = r300 | |||
C_SOURCES = \ | |||
r300_chipset.c \ | |||
r300_clear.c \ | |||
r300_context.c \ | |||
r300_emit.c \ | |||
r300_flush.c \ | |||
r300_screen.c \ | |||
r300_state.c \ | |||
r300_state_shader.c \ | |||
r300_surface.c \ | |||
r300_swtcl_emit.c \ | |||
r300_texture.c | |||
include ../../Makefile.template | |||
symlinks: |
@@ -0,0 +1,17 @@ | |||
Import('*') | |||
env = env.Clone() | |||
r300 = env.ConvenienceLibrary( | |||
target = 'r300', | |||
source = [ | |||
'r300_blit.c', | |||
'r300_clear.c', | |||
'r300_context.c', | |||
'r300_screen.c', | |||
'r300_state.c', | |||
'r300_surface.c', | |||
]) | |||
Export('r300') | |||
@@ -0,0 +1,348 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_chipset.h" | |||
#include "pipe/p_debug.h" | |||
/* r300_chipset: A file all to itself for deducing the various properties of | |||
* Radeons. */ | |||
/* Parse a PCI ID and fill an r300_capabilities struct with information. */ | |||
void r300_parse_chipset(struct r300_capabilities* caps) | |||
{ | |||
/* Reasonable defaults */ | |||
caps->has_tcl = TRUE; | |||
caps->is_r500 = FALSE; | |||
caps->num_vert_fpus = 4; | |||
/* Note: These are not ordered by PCI ID. I leave that task to GCC, | |||
* which will perform the ordering while collating jump tables. Instead, | |||
* I've tried to group them according to capabilities and age. */ | |||
switch (caps->pci_id) { | |||
case 0x4144: | |||
caps->family = CHIP_FAMILY_R300; | |||
break; | |||
case 0x4145: | |||
case 0x4146: | |||
case 0x4147: | |||
case 0x4E44: | |||
case 0x4E45: | |||
case 0x4E46: | |||
case 0x4E47: | |||
caps->family = CHIP_FAMILY_R300; | |||
break; | |||
case 0x4150: | |||
case 0x4151: | |||
case 0x4152: | |||
case 0x4153: | |||
case 0x4154: | |||
case 0x4155: | |||
case 0x4156: | |||
case 0x4E50: | |||
case 0x4E51: | |||
case 0x4E52: | |||
case 0x4E53: | |||
case 0x4E54: | |||
case 0x4E56: | |||
caps->family = CHIP_FAMILY_RV350; | |||
break; | |||
case 0x4148: | |||
case 0x4149: | |||
case 0x414A: | |||
case 0x414B: | |||
case 0x4E48: | |||
case 0x4E49: | |||
case 0x4E4B: | |||
caps->family = CHIP_FAMILY_R350; | |||
break; | |||
case 0x4E4A: | |||
caps->family = CHIP_FAMILY_R360; | |||
break; | |||
case 0x5460: | |||
case 0x5462: | |||
case 0x5464: | |||
case 0x5B60: | |||
case 0x5B62: | |||
case 0x5B63: | |||
case 0x5B64: | |||
case 0x5B65: | |||
caps->family = CHIP_FAMILY_RV370; | |||
break; | |||
case 0x3150: | |||
case 0x3152: | |||
case 0x3154: | |||
case 0x3E50: | |||
case 0x3E54: | |||
caps->family = CHIP_FAMILY_RV380; | |||
break; | |||
case 0x4A48: | |||
case 0x4A49: | |||
case 0x4A4A: | |||
case 0x4A4B: | |||
case 0x4A4C: | |||
case 0x4A4D: | |||
case 0x4A4E: | |||
case 0x4A4F: | |||
case 0x4A50: | |||
case 0x4A54: | |||
caps->family = CHIP_FAMILY_R420; | |||
caps->num_vert_fpus = 6; | |||
break; | |||
case 0x5548: | |||
case 0x5549: | |||
case 0x554A: | |||
case 0x554B: | |||
case 0x5550: | |||
case 0x5551: | |||
case 0x5552: | |||
case 0x5554: | |||
case 0x5D57: | |||
caps->family = CHIP_FAMILY_R423; | |||
caps->num_vert_fpus = 6; | |||
break; | |||
case 0x554C: | |||
case 0x554D: | |||
case 0x554E: | |||
case 0x554F: | |||
case 0x5D48: | |||
case 0x5D49: | |||
case 0x5D4A: | |||
caps->family = CHIP_FAMILY_R430; | |||
caps->num_vert_fpus = 6; | |||
break; | |||
case 0x5D4C: | |||
case 0x5D4D: | |||
case 0x5D4E: | |||
case 0x5D4F: | |||
case 0x5D50: | |||
case 0x5D52: | |||
caps->family = CHIP_FAMILY_R480; | |||
caps->num_vert_fpus = 6; | |||
break; | |||
case 0x4B49: | |||
case 0x4B4A: | |||
case 0x4B4B: | |||
case 0x4B4C: | |||
caps->family = CHIP_FAMILY_R481; | |||
caps->num_vert_fpus = 6; | |||
break; | |||
case 0x5E4C: | |||
case 0x5E4F: | |||
case 0x564A: | |||
case 0x564B: | |||
case 0x564F: | |||
case 0x5652: | |||
case 0x5653: | |||
case 0x5657: | |||
case 0x5E48: | |||
case 0x5E4A: | |||
case 0x5E4B: | |||
case 0x5E4D: | |||
caps->family = CHIP_FAMILY_RV410; | |||
caps->num_vert_fpus = 6; | |||
break; | |||
case 0x5954: | |||
case 0x5955: | |||
caps->family = CHIP_FAMILY_RS480; | |||
caps->has_tcl = FALSE; | |||
break; | |||
case 0x5974: | |||
case 0x5975: | |||
caps->family = CHIP_FAMILY_RS482; | |||
caps->has_tcl = FALSE; | |||
break; | |||
case 0x5A41: | |||
case 0x5A42: | |||
caps->family = CHIP_FAMILY_RS400; | |||
caps->has_tcl = FALSE; | |||
break; | |||
case 0x5A61: | |||
case 0x5A62: | |||
caps->family = CHIP_FAMILY_RC410; | |||
caps->has_tcl = FALSE; | |||
break; | |||
case 0x791E: | |||
case 0x791F: | |||
caps->family = CHIP_FAMILY_RS690; | |||
caps->has_tcl = FALSE; | |||
break; | |||
case 0x796C: | |||
case 0x796D: | |||
case 0x796E: | |||
case 0x796F: | |||
caps->family = CHIP_FAMILY_RS740; | |||
caps->has_tcl = FALSE; | |||
break; | |||
case 0x7100: | |||
case 0x7101: | |||
case 0x7102: | |||
case 0x7103: | |||
case 0x7104: | |||
case 0x7105: | |||
case 0x7106: | |||
case 0x7108: | |||
case 0x7109: | |||
case 0x710A: | |||
case 0x710B: | |||
case 0x710C: | |||
case 0x710E: | |||
case 0x710F: | |||
caps->family = CHIP_FAMILY_R520; | |||
caps->num_vert_fpus = 8; | |||
caps->is_r500 = TRUE; | |||
break; | |||
case 0x7140: | |||
case 0x7141: | |||
case 0x7142: | |||
case 0x7143: | |||
case 0x7144: | |||
case 0x7145: | |||
case 0x7146: | |||
case 0x7147: | |||
case 0x7149: | |||
case 0x714A: | |||
case 0x714B: | |||
case 0x714C: | |||
case 0x714D: | |||
case 0x714E: | |||
case 0x714F: | |||
case 0x7151: | |||
case 0x7152: | |||
case 0x7153: | |||
case 0x715E: | |||
case 0x715F: | |||
case 0x7180: | |||
case 0x7181: | |||
case 0x7183: | |||
case 0x7186: | |||
case 0x7187: | |||
case 0x7188: | |||
case 0x718A: | |||
case 0x718B: | |||
case 0x718C: | |||
case 0x718D: | |||
case 0x718F: | |||
case 0x7193: | |||
case 0x7196: | |||
case 0x719B: | |||
case 0x719F: | |||
case 0x7200: | |||
case 0x7210: | |||
case 0x7211: | |||
caps->family = CHIP_FAMILY_RV515; | |||
caps->num_vert_fpus = 2; | |||
caps->is_r500 = TRUE; | |||
break; | |||
case 0x71C0: | |||
case 0x71C1: | |||
case 0x71C2: | |||
case 0x71C3: | |||
case 0x71C4: | |||
case 0x71C5: | |||
case 0x71C6: | |||
case 0x71C7: | |||
case 0x71CD: | |||
case 0x71CE: | |||
case 0x71D2: | |||
case 0x71D4: | |||
case 0x71D5: | |||
case 0x71D6: | |||
case 0x71DA: | |||
case 0x71DE: | |||
caps->family = CHIP_FAMILY_RV530; | |||
caps->num_vert_fpus = 5; | |||
caps->is_r500 = TRUE; | |||
break; | |||
case 0x7240: | |||
case 0x7243: | |||
case 0x7244: | |||
case 0x7245: | |||
case 0x7246: | |||
case 0x7247: | |||
case 0x7248: | |||
case 0x7249: | |||
case 0x724A: | |||
case 0x724B: | |||
case 0x724C: | |||
case 0x724D: | |||
case 0x724E: | |||
case 0x724F: | |||
case 0x7284: | |||
caps->family = CHIP_FAMILY_R580; | |||
caps->num_vert_fpus = 8; | |||
caps->is_r500 = TRUE; | |||
break; | |||
case 0x7280: | |||
caps->family = CHIP_FAMILY_RV570; | |||
caps->num_vert_fpus = 5; | |||
caps->is_r500 = TRUE; | |||
break; | |||
case 0x7281: | |||
case 0x7283: | |||
case 0x7287: | |||
case 0x7288: | |||
case 0x7289: | |||
case 0x728B: | |||
case 0x728C: | |||
case 0x7290: | |||
case 0x7291: | |||
case 0x7293: | |||
case 0x7297: | |||
caps->family = CHIP_FAMILY_RV560; | |||
caps->num_vert_fpus = 5; | |||
caps->is_r500 = TRUE; | |||
break; | |||
default: | |||
debug_printf("r300: Warning: Unknown chipset 0x%x\n", | |||
caps->pci_id); | |||
break; | |||
} | |||
/* Force off TCL for now */ | |||
caps->has_tcl = FALSE; | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_CHIPSET_H | |||
#define R300_CHIPSET_H | |||
#include "pipe/p_compiler.h" | |||
/* Structure containing all the possible information about a specific Radeon | |||
* in the R3xx, R4xx, and R5xx families. */ | |||
struct r300_capabilities { | |||
/* PCI ID */ | |||
uint32_t pci_id; | |||
/* Chipset family */ | |||
int family; | |||
/* The number of vertex floating-point units */ | |||
int num_vert_fpus; | |||
/* The number of fragment pipes */ | |||
int num_frag_pipes; | |||
/* Whether or not TCL is physically present */ | |||
boolean has_tcl; | |||
/* Whether or not this is an RV515 or newer; R500s have many differences | |||
* that require extra consideration, compared to their R3xx cousins: | |||
* - Extra bit of width and height on texture sizes | |||
* - Blend color is split across two registers | |||
* - Universal Shader (US) block used for fragment shaders */ | |||
boolean is_r500; | |||
}; | |||
/* Enumerations for legibility and telling which card we're running on. */ | |||
enum { | |||
CHIP_FAMILY_R300 = 0, | |||
CHIP_FAMILY_R350, | |||
CHIP_FAMILY_R360, | |||
CHIP_FAMILY_RV350, | |||
CHIP_FAMILY_RV370, | |||
CHIP_FAMILY_RV380, | |||
CHIP_FAMILY_R420, | |||
CHIP_FAMILY_R423, | |||
CHIP_FAMILY_R430, | |||
CHIP_FAMILY_R480, | |||
CHIP_FAMILY_R481, | |||
CHIP_FAMILY_RV410, | |||
CHIP_FAMILY_RS400, | |||
CHIP_FAMILY_RC410, | |||
CHIP_FAMILY_RS480, | |||
CHIP_FAMILY_RS482, | |||
CHIP_FAMILY_RS690, | |||
CHIP_FAMILY_RS740, | |||
CHIP_FAMILY_RV515, | |||
CHIP_FAMILY_R520, | |||
CHIP_FAMILY_RV530, | |||
CHIP_FAMILY_R580, | |||
CHIP_FAMILY_RV560, | |||
CHIP_FAMILY_RV570 | |||
}; | |||
void r300_parse_chipset(struct r300_capabilities* caps); | |||
#endif /* R300_CHIPSET_H */ |
@@ -0,0 +1,33 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_clear.h" | |||
/* This gets its own file because Intel's is in its own file. | |||
* I assume there's a good reason. */ | |||
void r300_clear(struct pipe_context* pipe, | |||
struct pipe_surface* ps, | |||
unsigned color) | |||
{ | |||
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color); | |||
ps->status = PIPE_SURFACE_STATUS_DEFINED; | |||
} |
@@ -0,0 +1,27 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "pipe/p_context.h" | |||
void r300_clear(struct pipe_context* pipe, | |||
struct pipe_surface* ps, | |||
unsigned color); |
@@ -0,0 +1,68 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_context.h" | |||
static void r300_destroy_context(struct pipe_context* context) { | |||
struct r300_context* r300 = r300_context(context); | |||
draw_destroy(r300->draw); | |||
FREE(r300->blend_color_state); | |||
FREE(r300->scissor_state); | |||
FREE(r300); | |||
} | |||
struct pipe_context* r300_create_context(struct pipe_screen* screen, | |||
struct pipe_winsys* winsys, | |||
struct r300_winsys* r300_winsys) | |||
{ | |||
struct r300_context* r300 = CALLOC_STRUCT(r300_context); | |||
if (!r300) | |||
return NULL; | |||
r300->winsys = r300_winsys; | |||
r300->context.winsys = winsys; | |||
r300->context.screen = r300_create_screen(winsys, r300_winsys); | |||
r300->context.destroy = r300_destroy_context; | |||
r300->context.clear = r300_clear; | |||
r300->draw = draw_create(); | |||
/*XXX draw_set_rasterize_stage(r300->draw, r300_draw_swtcl_stage(r300));*/ | |||
r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state); | |||
r300->scissor_state = CALLOC_STRUCT(r300_scissor_state); | |||
r300_init_flush_functions(r300); | |||
r300_init_surface_functions(r300); | |||
r300_init_state_functions(r300); | |||
r300->dirty_state = R300_NEW_KITCHEN_SINK; | |||
r300->dirty_hw++; | |||
return &r300->context; | |||
} |
@@ -0,0 +1,190 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_CONTEXT_H | |||
#define R300_CONTEXT_H | |||
#include "draw/draw_context.h" | |||
#include "pipe/p_context.h" | |||
#include "tgsi/tgsi_scan.h" | |||
#include "util/u_memory.h" | |||
#include "r300_clear.h" | |||
#include "r300_screen.h" | |||
#include "r300_winsys.h" | |||
struct r300_blend_state { | |||
uint32_t blend_control; /* R300_RB3D_CBLEND: 0x4e04 */ | |||
uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */ | |||
uint32_t rop; /* R300_RB3D_ROPCNTL: 0x4e18 */ | |||
uint32_t dither; /* R300_RB3D_DITHER_CTL: 0x4e50 */ | |||
}; | |||
struct r300_blend_color_state { | |||
/* RV515 and earlier */ | |||
uint32_t blend_color; /* R300_RB3D_BLEND_COLOR: 0x4e10 */ | |||
/* R520 and newer */ | |||
uint32_t blend_color_red_alpha; /* R500_RB3D_CONSTANT_COLOR_AR: 0x4ef8 */ | |||
uint32_t blend_color_green_blue; /* R500_RB3D_CONSTANT_COLOR_GB: 0x4efc */ | |||
}; | |||
struct r300_dsa_state { | |||
uint32_t alpha_function; /* R300_FG_ALPHA_FUNC: 0x4bd4 */ | |||
uint32_t alpha_reference; /* R500_FG_ALPHA_VALUE: 0x4be0 */ | |||
uint32_t z_buffer_control; /* R300_ZB_CNTL: 0x4f00 */ | |||
uint32_t z_stencil_control; /* R300_ZB_ZSTENCILCNTL: 0x4f04 */ | |||
uint32_t stencil_ref_mask; /* R300_ZB_STENCILREFMASK: 0x4f08 */ | |||
uint32_t z_buffer_top; /* R300_ZB_ZTOP: 0x4f14 */ | |||
uint32_t stencil_ref_bf; /* R500_ZB_STENCILREFMASK_BF: 0x4fd4 */ | |||
}; | |||
struct r300_rs_state { | |||
uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ | |||
uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ | |||
uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ | |||
uint32_t depth_scale_front; /* R300_SU_POLY_OFFSET_FRONT_SCALE: 0x42a4 */ | |||
uint32_t depth_offset_front;/* R300_SU_POLY_OFFSET_FRONT_OFFSET: 0x42a8 */ | |||
uint32_t depth_scale_back; /* R300_SU_POLY_OFFSET_BACK_SCALE: 0x42ac */ | |||
uint32_t depth_offset_back; /* R300_SU_POLY_OFFSET_BACK_OFFSET: 0x42b0 */ | |||
uint32_t polygon_offset_enable; /* R300_SU_POLY_OFFSET_ENABLE: 0x42b4 */ | |||
uint32_t cull_mode; /* R300_SU_CULL_MODE: 0x42b8 */ | |||
uint32_t line_stipple_config; /* R300_GA_LINE_STIPPLE_CONFIG: 0x4328 */ | |||
uint32_t line_stipple_value; /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */ | |||
}; | |||
struct r300_sampler_state { | |||
uint32_t filter0; /* R300_TX_FILTER0: 0x4400 */ | |||
uint32_t filter1; /* R300_TX_FILTER1: 0x4440 */ | |||
uint32_t border_color; /* R300_TX_BORDER_COLOR: 0x45c0 */ | |||
}; | |||
struct r300_scissor_state { | |||
uint32_t scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */ | |||
uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */ | |||
}; | |||
struct r300_texture_state { | |||
}; | |||
#define R300_NEW_BLEND 0x000001 | |||
#define R300_NEW_BLEND_COLOR 0x000002 | |||
#define R300_NEW_DSA 0x000004 | |||
#define R300_NEW_FRAMEBUFFERS 0x000008 | |||
#define R300_NEW_FRAGMENT_SHADER 0x000010 | |||
#define R300_NEW_RASTERIZER 0x000020 | |||
#define R300_NEW_SAMPLER 0x000040 | |||
#define R300_NEW_SCISSOR 0x004000 | |||
#define R300_NEW_TEXTURE 0x008000 | |||
#define R300_NEW_VERTEX_SHADER 0x800000 | |||
#define R300_NEW_KITCHEN_SINK 0xffffff | |||
/* The next several objects are not pure Radeon state; they inherit from | |||
* various Gallium classes. */ | |||
struct r3xx_fragment_shader { | |||
/* Parent class */ | |||
struct pipe_shader_state state; | |||
struct tgsi_shader_info info; | |||
/* Has this shader been translated yet? */ | |||
boolean translated; | |||
}; | |||
struct r300_fragment_shader { | |||
/* Parent class */ | |||
struct r3xx_fragment_shader shader; | |||
}; | |||
struct r500_fragment_shader { | |||
/* Parent class */ | |||
struct r3xx_fragment_shader shader; | |||
}; | |||
struct r300_texture { | |||
/* Parent class */ | |||
struct pipe_texture tex; | |||
/* Offsets into the buffer. */ | |||
unsigned offset[PIPE_MAX_TEXTURE_LEVELS]; | |||
/* Total size of this texture, in bytes. */ | |||
unsigned size; | |||
/* Pipe buffer backing this texture. */ | |||
struct pipe_buffer* buffer; | |||
}; | |||
struct r300_context { | |||
/* Parent class */ | |||
struct pipe_context context; | |||
/* The interface to the windowing system, etc. */ | |||
struct r300_winsys* winsys; | |||
/* Draw module. Used mostly for SW TCL. */ | |||
struct draw_context* draw; | |||
/* Various CSO state objects. */ | |||
/* Blend state. */ | |||
struct r300_blend_state* blend_state; | |||
/* Blend color state. */ | |||
struct r300_blend_color_state* blend_color_state; | |||
/* Depth, stencil, and alpha state. */ | |||
struct r300_dsa_state* dsa_state; | |||
/* Fragment shader. */ | |||
struct r3xx_fragment_shader* fs; | |||
/* Framebuffer state. We currently don't need our own version of this. */ | |||
struct pipe_framebuffer_state framebuffer_state; | |||
/* Rasterizer state. */ | |||
struct r300_rs_state* rs_state; | |||
/* Sampler states. */ | |||
struct r300_sampler_state* sampler_states[8]; | |||
int sampler_count; | |||
/* Scissor state. */ | |||
struct r300_scissor_state* scissor_state; | |||
/* Texture states. */ | |||
struct r300_texture* textures[8]; | |||
struct r300_texture_state* texture_states[8]; | |||
int texture_count; | |||
/* Bitmask of dirty state objects. */ | |||
uint32_t dirty_state; | |||
/* Flag indicating whether or not the HW is dirty. */ | |||
uint32_t dirty_hw; | |||
}; | |||
/* Convenience cast wrapper. */ | |||
static struct r300_context* r300_context(struct pipe_context* context) { | |||
return (struct r300_context*)context; | |||
} | |||
/* Context initialization. */ | |||
void r300_init_state_functions(struct r300_context* r300); | |||
void r300_init_surface_functions(struct r300_context* r300); | |||
/* Fun with includes: r300_winsys also declares this prototype. | |||
* We'll just step out in that case... */ | |||
#ifndef R300_WINSYS_H | |||
struct pipe_context* r300_create_context(struct pipe_screen* screen, | |||
struct pipe_winsys* winsys, | |||
struct r300_winsys* r300_winsys); | |||
#endif | |||
#endif /* R300_CONTEXT_H */ |
@@ -0,0 +1,129 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_CS_H | |||
#define R300_CS_H | |||
#include "r300_reg.h" | |||
#include "r300_winsys.h" | |||
/* Pack a 32-bit float into a dword. */ | |||
static uint32_t pack_float_32(float f) | |||
{ | |||
union { | |||
float f; | |||
uint32_t u; | |||
} u; | |||
u.f = f; | |||
return u.u; | |||
} | |||
/* Yes, I know macros are ugly. However, they are much prettier than the code | |||
* that they neatly hide away, and don't have the cost of function setup,so | |||
* we're going to use them. */ | |||
#define MAX_CS_SIZE 64 * 1024 / 4 | |||
/* XXX stolen from radeon_drm.h */ | |||
#define RADEON_GEM_DOMAIN_CPU 0x1 | |||
#define RADEON_GEM_DOMAIN_GTT 0x2 | |||
#define RADEON_GEM_DOMAIN_VRAM 0x4 | |||
/* XXX stolen from radeon_reg.h */ | |||
#define RADEON_CP_PACKET0 0x0 | |||
#define CP_PACKET0(register, count) \ | |||
(RADEON_CP_PACKET0 | ((count) << 16) | ((register) >> 2)) | |||
#define CP_PACKET3(op, count) \ | |||
(RADEON_CP_PACKET3 | (op) | ((count) << 16)) | |||
#define CS_LOCALS(context) \ | |||
struct r300_winsys* cs_winsys = context->winsys; \ | |||
struct radeon_cs* cs = cs_winsys->cs; \ | |||
int cs_count = 0; | |||
#define CHECK_CS(size) \ | |||
cs_winsys->check_cs(cs, (size)) | |||
#define BEGIN_CS(size) do { \ | |||
CHECK_CS(size); \ | |||
debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \ | |||
size, __FUNCTION__, __FILE__, __LINE__); \ | |||
cs_winsys->begin_cs(cs, (size), __FILE__, __FUNCTION__, __LINE__); \ | |||
cs_count = size; \ | |||
} while (0) | |||
#define OUT_CS(value) do { \ | |||
cs_winsys->write_cs_dword(cs, (value)); \ | |||
cs_count--; \ | |||
} while (0) | |||
#define OUT_CS_32F(value) do { \ | |||
cs_winsys->write_cs_dword(cs, pack_float_32(value)); \ | |||
cs_count--; \ | |||
} while (0) | |||
#define OUT_CS_REG(register, value) do { \ | |||
debug_printf("r300: writing 0x%08X to register 0x%04X\n", \ | |||
value, register); \ | |||
assert(register); \ | |||
OUT_CS(CP_PACKET0(register, 0)); \ | |||
OUT_CS(value); \ | |||
} while (0) | |||
/* Note: This expects count to be the number of registers, | |||
* not the actual packet0 count! */ | |||
#define OUT_CS_REG_SEQ(register, count) do { \ | |||
debug_printf("r300: writing register sequence of %d to 0x%04X\n", \ | |||
count, register); \ | |||
assert(register); \ | |||
OUT_CS(CP_PACKET0(register, ((count) - 1))); \ | |||
} while (0) | |||
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \ | |||
debug_printf("r300: writing relocation for buffer %p, offset %d\n", \ | |||
bo, offset); \ | |||
assert(bo); \ | |||
OUT_CS(offset); \ | |||
cs_winsys->write_cs_reloc(cs, bo, rd, wd, flags); \ | |||
cs_count -= 2; \ | |||
} while (0) | |||
#define END_CS do { \ | |||
debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \ | |||
__LINE__); \ | |||
if (cs_count != 0) \ | |||
debug_printf("r300: Warning: cs_count off by %d\n", cs_count); \ | |||
cs_winsys->end_cs(cs, __FILE__, __FUNCTION__, __LINE__); \ | |||
} while (0) | |||
#define FLUSH_CS do { \ | |||
debug_printf("r300: FLUSH_CS in %s (%s:%d)\n", __FUNCTION__, __FILE__, \ | |||
__LINE__); \ | |||
cs_winsys->flush_cs(cs); \ | |||
} while (0) | |||
#include "r300_cs_inlines.h" | |||
#endif /* R300_CS_H */ |
@@ -0,0 +1,37 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
/* r300_cs_inlines: This is just a handful of useful inlines for sending | |||
* (very) common instructions to the CS buffer. Should only be included from | |||
* r300_cs.h, probably. */ | |||
#ifdef R300_CS_H | |||
#define R300_PACIFY do { \ | |||
OUT_CS_REG(R300_SC_SCREENDOOR, 0x0); \ | |||
OUT_CS_REG(RADEON_WAIT_UNTIL, (1 << 15) | (1 << 17) | \ | |||
(1 << 18) | (1 << 31)); \ | |||
OUT_CS_REG(R300_SC_SCREENDOOR, 0xffffff); \ | |||
} while (0) | |||
#endif /* R300_CS_H */ |
@@ -0,0 +1,155 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
/* r300_emit: Functions for emitting state. */ | |||
#include "r300_emit.h" | |||
void r300_emit_blend_state(struct r300_context* r300, | |||
struct r300_blend_state* blend) | |||
{ | |||
CS_LOCALS(r300); | |||
BEGIN_CS(7); | |||
OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 2); | |||
OUT_CS(blend->blend_control); | |||
OUT_CS(blend->alpha_blend_control); | |||
OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop); | |||
OUT_CS_REG(R300_RB3D_DITHER_CTL, blend->dither); | |||
END_CS; | |||
} | |||
void r300_emit_blend_color_state(struct r300_context* r300, | |||
struct r300_blend_color_state* bc) | |||
{ | |||
struct r300_screen* r300screen = | |||
(struct r300_screen*)r300->context.screen; | |||
CS_LOCALS(r300); | |||
if (r300screen->caps->is_r500) { | |||
BEGIN_CS(3); | |||
OUT_CS_REG_SEQ(R500_RB3D_CONSTANT_COLOR_AR, 2); | |||
OUT_CS(bc->blend_color_red_alpha); | |||
OUT_CS(bc->blend_color_green_blue); | |||
END_CS; | |||
} else { | |||
BEGIN_CS(2); | |||
OUT_CS_REG(R300_RB3D_BLEND_COLOR, bc->blend_color); | |||
END_CS; | |||
} | |||
} | |||
void r300_emit_dsa_state(struct r300_context* r300, | |||
struct r300_dsa_state* dsa) | |||
{ | |||
struct r300_screen* r300screen = | |||
(struct r300_screen*)r300->context.screen; | |||
CS_LOCALS(r300); | |||
BEGIN_CS(r300screen->caps->is_r500 ? 8 : 8); | |||
OUT_CS_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); | |||
/* XXX figure out the r300 counterpart for this */ | |||
if (r300screen->caps->is_r500) { | |||
/* OUT_CS_REG(R500_FG_ALPHA_VALUE, dsa->alpha_reference); */ | |||
} | |||
OUT_CS_REG_SEQ(R300_ZB_CNTL, 3); | |||
OUT_CS(dsa->z_buffer_control); | |||
OUT_CS(dsa->z_stencil_control); | |||
OUT_CS(dsa->stencil_ref_mask); | |||
OUT_CS_REG(R300_ZB_ZTOP, dsa->z_buffer_top); | |||
if (r300screen->caps->is_r500) { | |||
/* OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); */ | |||
} | |||
END_CS; | |||
} | |||
/* XXX add pitch, stride, z/stencil buf */ | |||
void r300_emit_fb_state(struct r300_context* r300, | |||
struct pipe_framebuffer_state* fb) | |||
{ | |||
CS_LOCALS(r300); | |||
struct r300_texture* tex; | |||
int i; | |||
BEGIN_CS((3 * fb->nr_cbufs) + 6); | |||
for (i = 0; i < fb->nr_cbufs; i++) { | |||
tex = (struct r300_texture*)fb->cbufs[i]->texture; | |||
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); | |||
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); | |||
} | |||
R300_PACIFY; | |||
END_CS; | |||
} | |||
void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs) | |||
{ | |||
struct r300_screen* r300screen = | |||
(struct r300_screen*)r300->context.screen; | |||
CS_LOCALS(r300); | |||
BEGIN_CS(14); | |||
OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status); | |||
OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6); | |||
OUT_CS(rs->depth_scale_front); | |||
OUT_CS(rs->depth_offset_front); | |||
OUT_CS(rs->depth_scale_back); | |||
OUT_CS(rs->depth_offset_back); | |||
OUT_CS(rs->polygon_offset_enable); | |||
OUT_CS(rs->cull_mode); | |||
OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config); | |||
OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value); | |||
END_CS; | |||
} | |||
static void r300_emit_dirty_state(struct r300_context* r300) | |||
{ | |||
struct r300_screen* r300screen = | |||
(struct r300_screen*)r300->context.screen; | |||
CS_LOCALS(r300); | |||
if (!(r300->dirty_state) && !(r300->dirty_hw)) { | |||
return; | |||
} | |||
/* XXX check size */ | |||
if (r300->dirty_state & R300_NEW_BLEND) { | |||
r300_emit_blend_state(r300, r300->blend_state); | |||
} | |||
if (r300->dirty_state & R300_NEW_BLEND_COLOR) { | |||
r300_emit_blend_color_state(r300, r300->blend_color_state); | |||
} | |||
if (r300->dirty_state & R300_NEW_DSA) { | |||
r300_emit_dsa_state(r300, r300->dsa_state); | |||
} | |||
if (r300->dirty_state & R300_NEW_RASTERIZER) { | |||
r300_emit_rs_state(r300, r300->rs_state); | |||
} | |||
if (r300->dirty_state & R300_NEW_SCISSOR) { | |||
struct r300_scissor_state* scissor = r300->scissor_state; | |||
/* XXX next two are contiguous regs */ | |||
OUT_CS_REG(R300_SC_SCISSORS_TL, scissor->scissor_top_left); | |||
OUT_CS_REG(R300_SC_SCISSORS_BR, scissor->scissor_bottom_right); | |||
} | |||
r300->dirty_state = 0; | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_context.h" | |||
#include "r300_cs.h" | |||
#include "r300_screen.h" | |||
void r300_emit_blend_state(struct r300_context* r300, | |||
struct r300_blend_state* blend); | |||
void r300_emit_blend_color_state(struct r300_context* r300, | |||
struct r300_blend_color_state* bc); | |||
void r300_emit_dsa_state(struct r300_context* r300, | |||
struct r300_dsa_state* dsa); | |||
void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs); |
@@ -0,0 +1,42 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_flush.h" | |||
static void r300_flush(struct pipe_context* pipe, | |||
unsigned flags, | |||
struct pipe_fence_handle** fence) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
CS_LOCALS(r300); | |||
if (r300->dirty_hw) { | |||
FLUSH_CS; | |||
r300->dirty_state = R300_NEW_KITCHEN_SINK; | |||
r300->dirty_hw = 0; | |||
} | |||
} | |||
void r300_init_flush_functions(struct r300_context* r300) | |||
{ | |||
r300->context.flush = r300_flush; | |||
} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_FLUSH_H | |||
#define R300_FLUSH_H | |||
#include "pipe/p_context.h" | |||
#include "r300_context.h" | |||
#include "r300_cs.h" | |||
void r300_init_flush_functions(struct r300_context* r300); | |||
#endif /* R300_FLUSH_H */ |
@@ -0,0 +1,271 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_screen.h" | |||
/* Return the identifier behind whom the brave coders responsible for this | |||
* amalgamation of code, sweat, and duct tape, routinely obscure their names. | |||
* | |||
* ...I should have just put "Corbin Simpson", but I'm not that cool. | |||
* | |||
* (Or egotistical. Yet.) */ | |||
static const char* r300_get_vendor(struct pipe_screen* pscreen) | |||
{ | |||
return "X.Org R300 Project"; | |||
} | |||
static const char* chip_families[] = { | |||
"R300", | |||
"R350", | |||
"R360", | |||
"RV350", | |||
"RV370", | |||
"RV380", | |||
"R420", | |||
"R423", | |||
"R430", | |||
"R480", | |||
"R481", | |||
"RV410", | |||
"RS400", | |||
"RC410", | |||
"RS480", | |||
"RS482", | |||
"RS690", | |||
"RS740", | |||
"RV515", | |||
"R520", | |||
"RV530", | |||
"R580", | |||
"RV560", | |||
"RV570" | |||
}; | |||
static const char* r300_get_name(struct pipe_screen* pscreen) | |||
{ | |||
struct r300_screen* r300screen = r300_screen(pscreen); | |||
return chip_families[r300screen->caps->family]; | |||
} | |||
static int r300_get_param(struct pipe_screen* pscreen, int param) | |||
{ | |||
struct r300_screen* r300screen = r300_screen(pscreen); | |||
switch (param) { | |||
/* XXX cases marked "IN THEORY" are possible on the hardware, | |||
* but haven't been implemented yet. */ | |||
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: | |||
/* XXX I'm told this goes up to 16 */ | |||
return 8; | |||
case PIPE_CAP_NPOT_TEXTURES: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_TWO_SIDED_STENCIL: | |||
if (r300screen->caps->is_r500) { | |||
return 1; | |||
} else { | |||
return 0; | |||
} | |||
return 0; | |||
case PIPE_CAP_GLSL: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_S3TC: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_ANISOTROPIC_FILTER: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_POINT_SPRITE: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_MAX_RENDER_TARGETS: | |||
/* XXX 4 eventually */ | |||
return 1; | |||
case PIPE_CAP_OCCLUSION_QUERY: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_TEXTURE_SHADOW_MAP: | |||
/* IN THEORY */ | |||
return 0; | |||
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: | |||
if (r300screen->caps->is_r500) { | |||
/* 13 == 4096x4096 */ | |||
return 13; | |||
} else { | |||
/* 12 == 2048x2048 */ | |||
return 12; | |||
} | |||
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: | |||
/* So, technically, the limit is the same as above, but some math | |||
* shows why this is silly. Assuming RGBA, 4cpp, we can see that | |||
* 4096*4096*4096 = 64.0 GiB exactly, so it's not exactly | |||
* practical. However, if at some point a game really wants this, | |||
* then we can remove this limit. */ | |||
if (r300screen->caps->is_r500) { | |||
/* 9 == 256x256x256 */ | |||
return 9; | |||
} else { | |||
/* 8 == 128*128*128 */ | |||
return 8; | |||
} | |||
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: | |||
if (r300screen->caps->is_r500) { | |||
/* 13 == 4096x4096 */ | |||
return 13; | |||
} else { | |||
/* 12 == 2048x2048 */ | |||
return 12; | |||
} | |||
case PIPE_CAP_TEXTURE_MIRROR_CLAMP: | |||
return 1; | |||
case PIPE_CAP_TEXTURE_MIRROR_REPEAT: | |||
return 1; | |||
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: | |||
/* XXX guessing */ | |||
return 2; | |||
default: | |||
debug_printf("r300: Implementation error: Bad param %d\n", | |||
param); | |||
return 0; | |||
} | |||
} | |||
static float r300_get_paramf(struct pipe_screen* pscreen, int param) | |||
{ | |||
switch (param) { | |||
case PIPE_CAP_MAX_LINE_WIDTH: | |||
case PIPE_CAP_MAX_LINE_WIDTH_AA: | |||
/* XXX this is the biggest thing that will fit in that register. | |||
* Perhaps the actual rendering limits are less? */ | |||
return 10922.0f; | |||
case PIPE_CAP_MAX_POINT_WIDTH: | |||
case PIPE_CAP_MAX_POINT_WIDTH_AA: | |||
/* XXX this is the biggest thing that will fit in that register. | |||
* Perhaps the actual rendering limits are less? */ | |||
return 10922.0f; | |||
case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: | |||
return 16.0f; | |||
case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: | |||
return 16.0f; | |||
default: | |||
debug_printf("r300: Implementation error: Bad paramf %d\n", | |||
param); | |||
return 0.0f; | |||
} | |||
} | |||
/* XXX moar formats */ | |||
static boolean check_tex_2d_format(enum pipe_format format) | |||
{ | |||
switch (format) { | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
case PIPE_FORMAT_I8_UNORM: | |||
return TRUE; | |||
default: | |||
debug_printf("r300: Warning: Got unknown format: %s, in %s\n", | |||
pf_name(format), __FUNCTION__); | |||
break; | |||
} | |||
return FALSE; | |||
} | |||
/* XXX moar targets */ | |||
static boolean r300_is_format_supported(struct pipe_screen* pscreen, | |||
enum pipe_format format, | |||
enum pipe_texture_target target, | |||
unsigned tex_usage, | |||
unsigned geom_flags) | |||
{ | |||
switch (target) { | |||
case PIPE_TEXTURE_2D: | |||
return check_tex_2d_format(format); | |||
default: | |||
debug_printf("r300: Warning: Got unknown format target: %d\n", | |||
format); | |||
break; | |||
} | |||
return FALSE; | |||
} | |||
static void* r300_surface_map(struct pipe_screen* screen, | |||
struct pipe_surface* surface, | |||
unsigned flags) | |||
{ | |||
struct r300_texture* tex = (struct r300_texture*)surface->texture; | |||
char* map = pipe_buffer_map(screen, tex->buffer, flags); | |||
if (!map) { | |||
return NULL; | |||
} | |||
return map + surface->offset; | |||
} | |||
static void r300_surface_unmap(struct pipe_screen* screen, | |||
struct pipe_surface* surface) | |||
{ | |||
struct r300_texture* tex = (struct r300_texture*)surface->texture; | |||
pipe_buffer_unmap(screen, tex->buffer); | |||
} | |||
static void r300_destroy_screen(struct pipe_screen* pscreen) | |||
{ | |||
struct r300_screen* r300screen = r300_screen(pscreen); | |||
FREE(r300screen->caps); | |||
FREE(r300screen); | |||
} | |||
struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys, | |||
struct r300_winsys* r300_winsys) | |||
{ | |||
struct r300_screen* r300screen = CALLOC_STRUCT(r300_screen); | |||
struct r300_capabilities* caps = CALLOC_STRUCT(r300_capabilities); | |||
if (!r300screen || !caps) | |||
return NULL; | |||
caps->pci_id = r300_winsys->pci_id; | |||
caps->num_frag_pipes = r300_winsys->gb_pipes; | |||
r300_parse_chipset(caps); | |||
r300screen->caps = caps; | |||
r300screen->screen.winsys = winsys; | |||
r300screen->screen.destroy = r300_destroy_screen; | |||
r300screen->screen.get_name = r300_get_name; | |||
r300screen->screen.get_vendor = r300_get_vendor; | |||
r300screen->screen.get_param = r300_get_param; | |||
r300screen->screen.get_paramf = r300_get_paramf; | |||
r300screen->screen.is_format_supported = r300_is_format_supported; | |||
r300screen->screen.surface_map = r300_surface_map; | |||
r300screen->screen.surface_unmap = r300_surface_unmap; | |||
r300_init_screen_texture_functions(&r300screen->screen); | |||
u_simple_screen_init(&r300screen->screen); | |||
return &r300screen->screen; | |||
} |
@@ -0,0 +1,52 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_SCREEN_H | |||
#define R300_SCREEN_H | |||
#include "pipe/p_inlines.h" | |||
#include "pipe/p_screen.h" | |||
#include "util/u_memory.h" | |||
#include "util/u_simple_screen.h" | |||
#include "r300_chipset.h" | |||
#include "r300_texture.h" | |||
#include "r300_winsys.h" | |||
struct r300_screen { | |||
/* Parent class */ | |||
struct pipe_screen screen; | |||
/* Chipset capabilities */ | |||
struct r300_capabilities* caps; | |||
}; | |||
/* Convenience cast wrapper. */ | |||
static struct r300_screen* r300_screen(struct pipe_screen* screen) { | |||
return (struct r300_screen*)screen; | |||
} | |||
/* Creates a new r300 screen. */ | |||
struct pipe_screen* r300_create_screen(struct pipe_winsys* winsys, | |||
struct r300_winsys* r300_winsys); | |||
#endif /* R300_SCREEN_H */ |
@@ -0,0 +1,826 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "util/u_math.h" | |||
#include "util/u_pack_color.h" | |||
#include "pipe/p_debug.h" | |||
#include "r300_context.h" | |||
#include "r300_reg.h" | |||
/* r300_state: Functions used to intialize state context by translating | |||
* Gallium state objects into semi-native r300 state objects. | |||
* | |||
* XXX break this file up into pieces if it gets too big! */ | |||
/* Pack a float into a dword. */ | |||
static uint32_t pack_float_32(float f) | |||
{ | |||
union { | |||
float f; | |||
uint32_t u; | |||
} u; | |||
u.f = f; | |||
return u.u; | |||
} | |||
static uint32_t translate_blend_function(int blend_func) { | |||
switch (blend_func) { | |||
case PIPE_BLEND_ADD: | |||
return R300_COMB_FCN_ADD_CLAMP; | |||
case PIPE_BLEND_SUBTRACT: | |||
return R300_COMB_FCN_SUB_CLAMP; | |||
case PIPE_BLEND_REVERSE_SUBTRACT: | |||
return R300_COMB_FCN_RSUB_CLAMP; | |||
case PIPE_BLEND_MIN: | |||
return R300_COMB_FCN_MIN; | |||
case PIPE_BLEND_MAX: | |||
return R300_COMB_FCN_MAX; | |||
default: | |||
debug_printf("r300: Unknown blend function %d\n", blend_func); | |||
break; | |||
} | |||
return 0; | |||
} | |||
/* XXX we can also offer the D3D versions of some of these... */ | |||
static uint32_t translate_blend_factor(int blend_fact) { | |||
switch (blend_fact) { | |||
case PIPE_BLENDFACTOR_ONE: | |||
return R300_BLEND_GL_ONE; | |||
case PIPE_BLENDFACTOR_SRC_COLOR: | |||
return R300_BLEND_GL_SRC_COLOR; | |||
case PIPE_BLENDFACTOR_SRC_ALPHA: | |||
return R300_BLEND_GL_SRC_ALPHA; | |||
case PIPE_BLENDFACTOR_DST_ALPHA: | |||
return R300_BLEND_GL_DST_ALPHA; | |||
case PIPE_BLENDFACTOR_DST_COLOR: | |||
return R300_BLEND_GL_DST_COLOR; | |||
case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: | |||
return R300_BLEND_GL_SRC_ALPHA_SATURATE; | |||
case PIPE_BLENDFACTOR_CONST_COLOR: | |||
return R300_BLEND_GL_CONST_COLOR; | |||
case PIPE_BLENDFACTOR_CONST_ALPHA: | |||
return R300_BLEND_GL_CONST_ALPHA; | |||
/* XXX WTF are these? | |||
case PIPE_BLENDFACTOR_SRC1_COLOR: | |||
case PIPE_BLENDFACTOR_SRC1_ALPHA: */ | |||
case PIPE_BLENDFACTOR_ZERO: | |||
return R300_BLEND_GL_ZERO; | |||
case PIPE_BLENDFACTOR_INV_SRC_COLOR: | |||
return R300_BLEND_GL_ONE_MINUS_SRC_COLOR; | |||
case PIPE_BLENDFACTOR_INV_SRC_ALPHA: | |||
return R300_BLEND_GL_ONE_MINUS_SRC_ALPHA; | |||
case PIPE_BLENDFACTOR_INV_DST_ALPHA: | |||
return R300_BLEND_GL_ONE_MINUS_DST_ALPHA; | |||
case PIPE_BLENDFACTOR_INV_DST_COLOR: | |||
return R300_BLEND_GL_ONE_MINUS_DST_COLOR; | |||
case PIPE_BLENDFACTOR_INV_CONST_COLOR: | |||
return R300_BLEND_GL_ONE_MINUS_CONST_COLOR; | |||
case PIPE_BLENDFACTOR_INV_CONST_ALPHA: | |||
return R300_BLEND_GL_ONE_MINUS_CONST_ALPHA; | |||
/* XXX see above | |||
case PIPE_BLENDFACTOR_INV_SRC1_COLOR: | |||
case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: */ | |||
default: | |||
debug_printf("r300: Unknown blend factor %d\n", blend_fact); | |||
break; | |||
} | |||
return 0; | |||
} | |||
/* Create a new blend state based on the CSO blend state. | |||
* | |||
* This encompasses alpha blending, logic/raster ops, and blend dithering. */ | |||
static void* r300_create_blend_state(struct pipe_context* pipe, | |||
const struct pipe_blend_state* state) | |||
{ | |||
struct r300_blend_state* blend = CALLOC_STRUCT(r300_blend_state); | |||
if (state->blend_enable) { | |||
/* XXX for now, always do separate alpha... | |||
* is it faster to do it with one reg? */ | |||
blend->blend_control = R300_ALPHA_BLEND_ENABLE | | |||
R300_SEPARATE_ALPHA_ENABLE | | |||
R300_READ_ENABLE | | |||
translate_blend_function(state->rgb_func) | | |||
(translate_blend_factor(state->rgb_src_factor) << | |||
R300_SRC_BLEND_SHIFT) | | |||
(translate_blend_factor(state->rgb_dst_factor) << | |||
R300_DST_BLEND_SHIFT); | |||
blend->alpha_blend_control = | |||
translate_blend_function(state->alpha_func) | | |||
(translate_blend_factor(state->alpha_src_factor) << | |||
R300_SRC_BLEND_SHIFT) | | |||
(translate_blend_factor(state->alpha_dst_factor) << | |||
R300_DST_BLEND_SHIFT); | |||
} | |||
/* PIPE_LOGICOP_* don't need to be translated, fortunately. */ | |||
/* XXX are logicops still allowed if blending's disabled? | |||
* Does Gallium take care of it for us? */ | |||
if (state->logicop_enable) { | |||
blend->rop = R300_RB3D_ROPCNTL_ROP_ENABLE | | |||
(state->logicop_func) << R300_RB3D_ROPCNTL_ROP_SHIFT; | |||
} | |||
if (state->dither) { | |||
blend->dither = R300_RB3D_DITHER_CTL_DITHER_MODE_LUT | | |||
R300_RB3D_DITHER_CTL_ALPHA_DITHER_MODE_LUT; | |||
} | |||
return (void*)blend; | |||
} | |||
/* Bind blend state. */ | |||
static void r300_bind_blend_state(struct pipe_context* pipe, | |||
void* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
r300->blend_state = (struct r300_blend_state*)state; | |||
r300->dirty_state |= R300_NEW_BLEND; | |||
} | |||
/* Free blend state. */ | |||
static void r300_delete_blend_state(struct pipe_context* pipe, | |||
void* state) | |||
{ | |||
FREE(state); | |||
} | |||
/* Set blend color. | |||
* Setup both R300 and R500 registers, figure out later which one to write. */ | |||
static void r300_set_blend_color(struct pipe_context* pipe, | |||
const struct pipe_blend_color* color) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
uint32_t r, g, b, a; | |||
ubyte ur, ug, ub, ua; | |||
r = util_iround(color->color[0] * 1023.0f); | |||
g = util_iround(color->color[1] * 1023.0f); | |||
b = util_iround(color->color[2] * 1023.0f); | |||
a = util_iround(color->color[3] * 1023.0f); | |||
ur = float_to_ubyte(color->color[0]); | |||
ug = float_to_ubyte(color->color[1]); | |||
ub = float_to_ubyte(color->color[2]); | |||
ua = float_to_ubyte(color->color[3]); | |||
r300->blend_color_state->blend_color = (a << 24) | (r << 16) | (g << 8) | b; | |||
r300->blend_color_state->blend_color_red_alpha = ur | (ua << 16); | |||
r300->blend_color_state->blend_color_green_blue = ub | (ug << 16); | |||
r300->dirty_state |= R300_NEW_BLEND_COLOR; | |||
} | |||
static void r300_set_clip_state(struct pipe_context* pipe, | |||
const struct pipe_clip_state* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
/* XXX Draw */ | |||
draw_flush(r300->draw); | |||
draw_set_clip_state(r300->draw, state); | |||
} | |||
static void | |||
r300_set_constant_buffer(struct pipe_context* pipe, | |||
uint shader, uint index, | |||
const struct pipe_constant_buffer* buffer) | |||
{ | |||
/* XXX */ | |||
} | |||
static uint32_t translate_depth_stencil_function(int zs_func) { | |||
switch (zs_func) { | |||
case PIPE_FUNC_NEVER: | |||
return R300_ZS_NEVER; | |||
case PIPE_FUNC_LESS: | |||
return R300_ZS_LESS; | |||
case PIPE_FUNC_EQUAL: | |||
return R300_ZS_EQUAL; | |||
case PIPE_FUNC_LEQUAL: | |||
return R300_ZS_LEQUAL; | |||
case PIPE_FUNC_GREATER: | |||
return R300_ZS_GREATER; | |||
case PIPE_FUNC_NOTEQUAL: | |||
return R300_ZS_NOTEQUAL; | |||
case PIPE_FUNC_GEQUAL: | |||
return R300_ZS_GEQUAL; | |||
case PIPE_FUNC_ALWAYS: | |||
return R300_ZS_ALWAYS; | |||
default: | |||
debug_printf("r300: Unknown depth/stencil function %d\n", | |||
zs_func); | |||
break; | |||
} | |||
return 0; | |||
} | |||
static uint32_t translate_stencil_op(int s_op) { | |||
switch (s_op) { | |||
case PIPE_STENCIL_OP_KEEP: | |||
return R300_ZS_KEEP; | |||
case PIPE_STENCIL_OP_ZERO: | |||
return R300_ZS_ZERO; | |||
case PIPE_STENCIL_OP_REPLACE: | |||
return R300_ZS_REPLACE; | |||
case PIPE_STENCIL_OP_INCR: | |||
return R300_ZS_INCR; | |||
case PIPE_STENCIL_OP_DECR: | |||
return R300_ZS_DECR; | |||
case PIPE_STENCIL_OP_INCR_WRAP: | |||
return R300_ZS_INCR_WRAP; | |||
case PIPE_STENCIL_OP_DECR_WRAP: | |||
return R300_ZS_DECR_WRAP; | |||
case PIPE_STENCIL_OP_INVERT: | |||
return R300_ZS_INVERT; | |||
default: | |||
debug_printf("r300: Unknown stencil op %d", s_op); | |||
break; | |||
} | |||
return 0; | |||
} | |||
static uint32_t translate_alpha_function(int alpha_func) { | |||
switch (alpha_func) { | |||
case PIPE_FUNC_NEVER: | |||
return R300_FG_ALPHA_FUNC_NEVER; | |||
case PIPE_FUNC_LESS: | |||
return R300_FG_ALPHA_FUNC_LESS; | |||
case PIPE_FUNC_EQUAL: | |||
return R300_FG_ALPHA_FUNC_EQUAL; | |||
case PIPE_FUNC_LEQUAL: | |||
return R300_FG_ALPHA_FUNC_LE; | |||
case PIPE_FUNC_GREATER: | |||
return R300_FG_ALPHA_FUNC_GREATER; | |||
case PIPE_FUNC_NOTEQUAL: | |||
return R300_FG_ALPHA_FUNC_NOTEQUAL; | |||
case PIPE_FUNC_GEQUAL: | |||
return R300_FG_ALPHA_FUNC_GE; | |||
case PIPE_FUNC_ALWAYS: | |||
return R300_FG_ALPHA_FUNC_ALWAYS; | |||
default: | |||
debug_printf("r300: Unknown alpha function %d", alpha_func); | |||
break; | |||
} | |||
return 0; | |||
} | |||
/* Create a new depth, stencil, and alpha state based on the CSO dsa state. | |||
* | |||
* This contains the depth buffer, stencil buffer, alpha test, and such. | |||
* On the Radeon, depth and stencil buffer setup are intertwined, which is | |||
* the reason for some of the strange-looking assignments across registers. */ | |||
static void* | |||
r300_create_dsa_state(struct pipe_context* pipe, | |||
const struct pipe_depth_stencil_alpha_state* state) | |||
{ | |||
struct r300_dsa_state* dsa = CALLOC_STRUCT(r300_dsa_state); | |||
/* Depth test setup. */ | |||
if (state->depth.enabled) { | |||
dsa->z_buffer_control |= R300_Z_ENABLE; | |||
if (state->depth.writemask) { | |||
dsa->z_buffer_control |= R300_Z_WRITE_ENABLE; | |||
} | |||
dsa->z_stencil_control |= | |||
(translate_depth_stencil_function(state->depth.func) << | |||
R300_Z_FUNC_SHIFT); | |||
} | |||
/* Stencil buffer setup. */ | |||
if (state->stencil[0].enabled) { | |||
dsa->z_buffer_control |= R300_STENCIL_ENABLE; | |||
dsa->z_stencil_control |= | |||
(translate_depth_stencil_function(state->stencil[0].func) << | |||
R300_S_FRONT_FUNC_SHIFT) | | |||
(translate_stencil_op(state->stencil[0].fail_op) << | |||
R300_S_FRONT_SFAIL_OP_SHIFT) | | |||
(translate_stencil_op(state->stencil[0].zpass_op) << | |||
R300_S_FRONT_ZPASS_OP_SHIFT) | | |||
(translate_stencil_op(state->stencil[0].zfail_op) << | |||
R300_S_FRONT_ZFAIL_OP_SHIFT); | |||
dsa->stencil_ref_mask = (state->stencil[0].ref_value) | | |||
(state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | | |||
(state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); | |||
if (state->stencil[1].enabled) { | |||
dsa->z_buffer_control |= R300_STENCIL_FRONT_BACK; | |||
dsa->z_stencil_control |= | |||
(translate_depth_stencil_function(state->stencil[1].func) << | |||
R300_S_BACK_FUNC_SHIFT) | | |||
(translate_stencil_op(state->stencil[1].fail_op) << | |||
R300_S_BACK_SFAIL_OP_SHIFT) | | |||
(translate_stencil_op(state->stencil[1].zpass_op) << | |||
R300_S_BACK_ZPASS_OP_SHIFT) | | |||
(translate_stencil_op(state->stencil[1].zfail_op) << | |||
R300_S_BACK_ZFAIL_OP_SHIFT); | |||
dsa->stencil_ref_bf = (state->stencil[1].ref_value) | | |||
(state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) | | |||
(state->stencil[1].writemask << R300_STENCILWRITEMASK_SHIFT); | |||
} | |||
} | |||
/* Alpha test setup. */ | |||
if (state->alpha.enabled) { | |||
dsa->alpha_function = translate_alpha_function(state->alpha.func) | | |||
R300_FG_ALPHA_FUNC_ENABLE; | |||
dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f, | |||
0, 1023); | |||
} else { | |||
dsa->z_buffer_top = R300_ZTOP_ENABLE; | |||
} | |||
return (void*)dsa; | |||
} | |||
/* Bind DSA state. */ | |||
static void r300_bind_dsa_state(struct pipe_context* pipe, | |||
void* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
r300->dsa_state = (struct r300_dsa_state*)state; | |||
r300->dirty_state |= R300_NEW_DSA; | |||
} | |||
/* Free DSA state. */ | |||
static void r300_delete_dsa_state(struct pipe_context* pipe, | |||
void* state) | |||
{ | |||
FREE(state); | |||
} | |||
static void r300_set_edgeflags(struct pipe_context* pipe, | |||
const unsigned* bitfield) | |||
{ | |||
/* XXX you know it's bad when i915 has this blank too */ | |||
} | |||
static void | |||
r300_set_framebuffer_state(struct pipe_context* pipe, | |||
const struct pipe_framebuffer_state* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
draw_flush(r300->draw); | |||
r300->framebuffer_state = *state; | |||
r300->dirty_state |= R300_NEW_FRAMEBUFFERS; | |||
} | |||
/* Create fragment shader state. */ | |||
static void* r300_create_fs_state(struct pipe_context* pipe, | |||
const struct pipe_shader_state* shader) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
struct r3xx_fragment_shader* fs = NULL; | |||
if (r300_screen(r300->context.screen)->caps->is_r500) { | |||
fs = | |||
(struct r3xx_fragment_shader*)CALLOC_STRUCT(r500_fragment_shader); | |||
} else { | |||
fs = | |||
(struct r3xx_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader); | |||
} | |||
/* Copy state directly into shader. */ | |||
fs->state = *shader; | |||
return (void*)fs; | |||
} | |||
/* Bind fragment shader state. */ | |||
static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
struct r3xx_fragment_shader* fs = (struct r3xx_fragment_shader*)shader; | |||
if (!fs->translated) { | |||
if (r300_screen(r300->context.screen)->caps->is_r500) { | |||
r500_translate_shader(r300, fs); | |||
} else { | |||
r300_translate_shader(r300, fs); | |||
} | |||
} | |||
r300->fs = fs; | |||
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER; | |||
} | |||
/* Delete fragment shader state. */ | |||
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader) | |||
{ | |||
FREE(shader); | |||
} | |||
static void r300_set_polygon_stipple(struct pipe_context* pipe, | |||
const struct pipe_poly_stipple* state) | |||
{ | |||
/* XXX */ | |||
} | |||
static INLINE int pack_float_16_6x(float f) { | |||
return ((int)(f * 6.0) & 0xffff); | |||
} | |||
/* Create a new rasterizer state based on the CSO rasterizer state. | |||
* | |||
* This is a very large chunk of state, and covers most of the graphics | |||
* backend (GB), geometry assembly (GA), and setup unit (SU) blocks. | |||
* | |||
* In a not entirely unironic sidenote, this state has nearly nothing to do | |||
* with the actual block on the Radeon called the rasterizer (RS). */ | |||
static void* r300_create_rs_state(struct pipe_context* pipe, | |||
const struct pipe_rasterizer_state* state) | |||
{ | |||
struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); | |||
/* XXX this is part of HW TCL */ | |||
/* XXX endian control */ | |||
rs->vap_control_status = R300_VAP_TCL_BYPASS; | |||
rs->point_size = pack_float_16_6x(state->point_size) | | |||
(pack_float_16_6x(state->point_size) << R300_POINTSIZE_X_SHIFT); | |||
rs->line_control = pack_float_16_6x(state->line_width) | | |||
R300_GA_LINE_CNTL_END_TYPE_COMP; | |||
/* Radeons don't think in "CW/CCW", they think in "front/back". */ | |||
if (state->front_winding == PIPE_WINDING_CW) { | |||
rs->cull_mode = R300_FRONT_FACE_CW; | |||
if (state->offset_cw) { | |||
rs->polygon_offset_enable |= R300_FRONT_ENABLE; | |||
} | |||
if (state->offset_ccw) { | |||
rs->polygon_offset_enable |= R300_BACK_ENABLE; | |||
} | |||
} else { | |||
rs->cull_mode = R300_FRONT_FACE_CCW; | |||
if (state->offset_ccw) { | |||
rs->polygon_offset_enable |= R300_FRONT_ENABLE; | |||
} | |||
if (state->offset_cw) { | |||
rs->polygon_offset_enable |= R300_BACK_ENABLE; | |||
} | |||
} | |||
if (state->front_winding & state->cull_mode) { | |||
rs->cull_mode |= R300_CULL_FRONT; | |||
} | |||
if (~(state->front_winding) & state->cull_mode) { | |||
rs->cull_mode |= R300_CULL_BACK; | |||
} | |||
if (rs->polygon_offset_enable) { | |||
rs->depth_offset_front = rs->depth_offset_back = | |||
pack_float_32(state->offset_units); | |||
rs->depth_scale_front = rs->depth_scale_back = | |||
pack_float_32(state->offset_scale); | |||
} | |||
if (state->line_stipple_enable) { | |||
rs->line_stipple_config = | |||
R300_GA_LINE_STIPPLE_CONFIG_LINE_RESET_LINE | | |||
(pack_float_32((float)state->line_stipple_factor) & | |||
R300_GA_LINE_STIPPLE_CONFIG_STIPPLE_SCALE_MASK); | |||
/* XXX this might need to be scaled up */ | |||
rs->line_stipple_value = state->line_stipple_pattern; | |||
} | |||
return (void*)rs; | |||
} | |||
/* Bind rasterizer state. */ | |||
static void r300_bind_rs_state(struct pipe_context* pipe, void* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
r300->rs_state = (struct r300_rs_state*)state; | |||
r300->dirty_state |= R300_NEW_RASTERIZER; | |||
} | |||
/* Free rasterizer state. */ | |||
static void r300_delete_rs_state(struct pipe_context* pipe, void* state) | |||
{ | |||
FREE(state); | |||
} | |||
static uint32_t translate_wrap(int wrap) { | |||
switch (wrap) { | |||
case PIPE_TEX_WRAP_REPEAT: | |||
return R300_TX_REPEAT; | |||
case PIPE_TEX_WRAP_CLAMP: | |||
return R300_TX_CLAMP; | |||
case PIPE_TEX_WRAP_CLAMP_TO_EDGE: | |||
return R300_TX_CLAMP_TO_EDGE; | |||
case PIPE_TEX_WRAP_CLAMP_TO_BORDER: | |||
return R300_TX_CLAMP_TO_BORDER; | |||
case PIPE_TEX_WRAP_MIRROR_REPEAT: | |||
return R300_TX_REPEAT | R300_TX_MIRRORED; | |||
case PIPE_TEX_WRAP_MIRROR_CLAMP: | |||
return R300_TX_CLAMP | R300_TX_MIRRORED; | |||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE: | |||
return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; | |||
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: | |||
return R300_TX_CLAMP_TO_EDGE | R300_TX_MIRRORED; | |||
default: | |||
debug_printf("r300: Unknown texture wrap %d", wrap); | |||
return 0; | |||
} | |||
} | |||
static uint32_t translate_tex_filters(int min, int mag, int mip) { | |||
uint32_t retval = 0; | |||
switch (min) { | |||
case PIPE_TEX_FILTER_NEAREST: | |||
retval |= R300_TX_MIN_FILTER_NEAREST; | |||
case PIPE_TEX_FILTER_LINEAR: | |||
retval |= R300_TX_MIN_FILTER_LINEAR; | |||
case PIPE_TEX_FILTER_ANISO: | |||
retval |= R300_TX_MIN_FILTER_ANISO; | |||
default: | |||
debug_printf("r300: Unknown texture filter %d", min); | |||
break; | |||
} | |||
switch (mag) { | |||
case PIPE_TEX_FILTER_NEAREST: | |||
retval |= R300_TX_MAG_FILTER_NEAREST; | |||
case PIPE_TEX_FILTER_LINEAR: | |||
retval |= R300_TX_MAG_FILTER_LINEAR; | |||
case PIPE_TEX_FILTER_ANISO: | |||
retval |= R300_TX_MAG_FILTER_ANISO; | |||
default: | |||
debug_printf("r300: Unknown texture filter %d", mag); | |||
break; | |||
} | |||
switch (mip) { | |||
case PIPE_TEX_MIPFILTER_NONE: | |||
retval |= R300_TX_MIN_FILTER_MIP_NONE; | |||
case PIPE_TEX_MIPFILTER_NEAREST: | |||
retval |= R300_TX_MIN_FILTER_MIP_NEAREST; | |||
case PIPE_TEX_MIPFILTER_LINEAR: | |||
retval |= R300_TX_MIN_FILTER_MIP_LINEAR; | |||
default: | |||
debug_printf("r300: Unknown texture filter %d", mip); | |||
break; | |||
} | |||
return retval; | |||
} | |||
static uint32_t anisotropy(float max_aniso) { | |||
if (max_aniso >= 16.0f) { | |||
return R300_TX_MAX_ANISO_16_TO_1; | |||
} else if (max_aniso >= 8.0f) { | |||
return R300_TX_MAX_ANISO_8_TO_1; | |||
} else if (max_aniso >= 4.0f) { | |||
return R300_TX_MAX_ANISO_4_TO_1; | |||
} else if (max_aniso >= 2.0f) { | |||
return R300_TX_MAX_ANISO_2_TO_1; | |||
} else { | |||
return R300_TX_MAX_ANISO_1_TO_1; | |||
} | |||
} | |||
static void* | |||
r300_create_sampler_state(struct pipe_context* pipe, | |||
const struct pipe_sampler_state* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); | |||
int lod_bias; | |||
sampler->filter0 |= | |||
(translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | | |||
(translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | | |||
(translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); | |||
sampler->filter0 |= translate_tex_filters(state->min_img_filter, | |||
state->mag_img_filter, | |||
state->min_mip_filter); | |||
lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); | |||
sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; | |||
sampler->filter1 |= anisotropy(state->max_anisotropy); | |||
util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, | |||
&sampler->border_color); | |||
/* R500-specific fixups and optimizations */ | |||
if (r300_screen(r300->context.screen)->caps->is_r500) { | |||
sampler->filter1 |= R500_BORDER_FIX; | |||
} | |||
return (void*)sampler; | |||
} | |||
static void r300_bind_sampler_states(struct pipe_context* pipe, | |||
unsigned count, | |||
void** states) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
int i; | |||
if (count > 8) { | |||
return; | |||
} | |||
for (i = 0; i < count; i++) { | |||
if (r300->sampler_states[i] != states[i]) { | |||
r300->sampler_states[i] = (struct r300_sampler_state*)states[i]; | |||
r300->dirty_state |= (R300_NEW_SAMPLER << i); | |||
} | |||
} | |||
r300->sampler_count = count; | |||
} | |||
static void r300_delete_sampler_state(struct pipe_context* pipe, void* state) | |||
{ | |||
FREE(state); | |||
} | |||
static void r300_set_sampler_textures(struct pipe_context* pipe, | |||
unsigned count, | |||
struct pipe_texture** texture) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
int i; | |||
/* XXX magic num */ | |||
if (count > 8) { | |||
return; | |||
} | |||
for (i = 0; i < count; i++) { | |||
if (r300->textures[i] != (struct r300_texture*)texture[i]) { | |||
pipe_texture_reference((struct pipe_texture**)&r300->textures[i], | |||
texture[i]); | |||
r300->dirty_state |= (R300_NEW_TEXTURE << i); | |||
} | |||
} | |||
for (i = count; i < 8; i++) { | |||
if (r300->textures[i]) { | |||
pipe_texture_reference((struct pipe_texture**)&r300->textures[i], | |||
NULL); | |||
r300->dirty_state |= (R300_NEW_TEXTURE << i); | |||
} | |||
} | |||
r300->texture_count = count; | |||
} | |||
static void r300_set_scissor_state(struct pipe_context* pipe, | |||
const struct pipe_scissor_state* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
draw_flush(r300->draw); | |||
uint32_t left, top, right, bottom; | |||
/* So, a bit of info. The scissors are offset by R300_SCISSORS_OFFSET in | |||
* both directions for all values, and can only be 13 bits wide. Why? | |||
* We may never know. */ | |||
left = (state->minx + R300_SCISSORS_OFFSET) & 0x1fff; | |||
top = (state->miny + R300_SCISSORS_OFFSET) & 0x1fff; | |||
right = (state->maxx + R300_SCISSORS_OFFSET) & 0x1fff; | |||
bottom = (state->maxy + R300_SCISSORS_OFFSET) & 0x1fff; | |||
r300->scissor_state->scissor_top_left = (left << R300_SCISSORS_X_SHIFT) | | |||
(top << R300_SCISSORS_Y_SHIFT); | |||
r300->scissor_state->scissor_bottom_right = | |||
(right << R300_SCISSORS_X_SHIFT) | (bottom << R300_SCISSORS_Y_SHIFT); | |||
r300->dirty_state |= R300_NEW_SCISSOR; | |||
} | |||
static void r300_set_viewport_state(struct pipe_context* pipe, | |||
const struct pipe_viewport_state* state) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
/* XXX handing this off to Draw for now */ | |||
draw_set_viewport_state(r300->draw, state); | |||
} | |||
static void r300_set_vertex_buffers(struct pipe_context* pipe, | |||
unsigned count, | |||
const struct pipe_vertex_buffer* buffers) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
/* XXX Draw */ | |||
draw_flush(r300->draw); | |||
draw_set_vertex_buffers(r300->draw, count, buffers); | |||
} | |||
static void r300_set_vertex_elements(struct pipe_context* pipe, | |||
unsigned count, | |||
const struct pipe_vertex_element* elements) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
/* XXX Draw */ | |||
draw_flush(r300->draw); | |||
draw_set_vertex_elements(r300->draw, count, elements); | |||
} | |||
static void* r300_create_vs_state(struct pipe_context* pipe, | |||
const struct pipe_shader_state* state) | |||
{ | |||
struct r300_context* context = r300_context(pipe); | |||
/* XXX handing this off to Draw for now */ | |||
return draw_create_vertex_shader(context->draw, state); | |||
} | |||
static void r300_bind_vs_state(struct pipe_context* pipe, void* state) { | |||
struct r300_context* context = r300_context(pipe); | |||
/* XXX handing this off to Draw for now */ | |||
draw_bind_vertex_shader(context->draw, (struct draw_vertex_shader*)state); | |||
} | |||
static void r300_delete_vs_state(struct pipe_context* pipe, void* state) | |||
{ | |||
struct r300_context* context = r300_context(pipe); | |||
/* XXX handing this off to Draw for now */ | |||
draw_delete_vertex_shader(context->draw, (struct draw_vertex_shader*)state); | |||
} | |||
void r300_init_state_functions(struct r300_context* r300) | |||
{ | |||
r300->context.create_blend_state = r300_create_blend_state; | |||
r300->context.bind_blend_state = r300_bind_blend_state; | |||
r300->context.delete_blend_state = r300_delete_blend_state; | |||
r300->context.set_blend_color = r300_set_blend_color; | |||
r300->context.set_clip_state = r300_set_clip_state; | |||
r300->context.set_constant_buffer = r300_set_constant_buffer; | |||
r300->context.create_depth_stencil_alpha_state = r300_create_dsa_state; | |||
r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; | |||
r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; | |||
r300->context.set_edgeflags = r300_set_edgeflags; | |||
r300->context.set_framebuffer_state = r300_set_framebuffer_state; | |||
r300->context.create_fs_state = r300_create_fs_state; | |||
r300->context.bind_fs_state = r300_bind_fs_state; | |||
r300->context.delete_fs_state = r300_delete_fs_state; | |||
r300->context.set_polygon_stipple = r300_set_polygon_stipple; | |||
r300->context.create_rasterizer_state = r300_create_rs_state; | |||
r300->context.bind_rasterizer_state = r300_bind_rs_state; | |||
r300->context.delete_rasterizer_state = r300_delete_rs_state; | |||
r300->context.create_sampler_state = r300_create_sampler_state; | |||
r300->context.bind_sampler_states = r300_bind_sampler_states; | |||
r300->context.delete_sampler_state = r300_delete_sampler_state; | |||
r300->context.set_sampler_textures = r300_set_sampler_textures; | |||
r300->context.set_scissor_state = r300_set_scissor_state; | |||
r300->context.set_viewport_state = r300_set_viewport_state; | |||
r300->context.set_vertex_buffers = r300_set_vertex_buffers; | |||
r300->context.set_vertex_elements = r300_set_vertex_elements; | |||
r300->context.create_vs_state = r300_create_vs_state; | |||
r300->context.bind_vs_state = r300_bind_vs_state; | |||
r300->context.delete_vs_state = r300_delete_vs_state; | |||
} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_state_shader.h" | |||
void r300_translate_shader(struct r300_context* r300, | |||
struct r300_fragment_shader* fs) | |||
{ | |||
} | |||
void r500_translate_shader(struct r300_context* r300, | |||
struct r500_fragment_shader* fs) | |||
{ | |||
} |
@@ -0,0 +1,35 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_STATE_SHADER_H | |||
#define R300_STATE_SHADER_H | |||
#include "r300_context.h" | |||
#include "r300_screen.h" | |||
void r300_translate_shader(struct r300_context* r300, | |||
struct r300_fragment_shader* fs); | |||
void r500_translate_shader(struct r300_context* r300, | |||
struct r500_fragment_shader* fs); | |||
#endif /* R300_STATE_SHADER_H */ |
@@ -0,0 +1,352 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_surface.h" | |||
/* Provides pipe_context's "surface_fill". Commonly used for clearing | |||
* buffers. */ | |||
static void r300_surface_fill(struct pipe_context* pipe, | |||
struct pipe_surface* dest, | |||
unsigned x, unsigned y, | |||
unsigned w, unsigned h, | |||
unsigned color) | |||
{ | |||
struct r300_context* r300 = r300_context(pipe); | |||
CS_LOCALS(r300); | |||
struct r300_capabilities* caps = ((struct r300_screen*)pipe->screen)->caps; | |||
struct r300_texture* tex = (struct r300_texture*)dest->texture; | |||
int i; | |||
float r, g, b, a; | |||
r = (float)((color >> 16) & 0xff) / 255.0f; | |||
g = (float)((color >> 8) & 0xff) / 255.0f; | |||
b = (float)((color >> 0) & 0xff) / 255.0f; | |||
debug_printf("r300: Filling surface %p at (%d,%d)," | |||
" dimensions %dx%d (stride %d), color 0x%x\n", | |||
dest, x, y, w, h, dest->stride, color); | |||
/* Fallback? */ | |||
if (0) { | |||
debug_printf("r300: Falling back on surface clear..."); | |||
void* map = pipe->screen->surface_map(pipe->screen, dest, | |||
PIPE_BUFFER_USAGE_CPU_WRITE); | |||
pipe_fill_rect(map, &dest->block, &dest->stride, x, y, w, h, color); | |||
pipe->screen->surface_unmap(pipe->screen, dest); | |||
return; | |||
} | |||
BEGIN_CS((caps->is_r500) ? 309 : 280); | |||
R300_PACIFY; | |||
OUT_CS_REG(R300_TX_INVALTAGS, 0x0); | |||
R300_PACIFY; | |||
/* Flush PVS. */ | |||
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0); | |||
OUT_CS_REG(R300_SE_VTE_CNTL, R300_VPORT_X_SCALE_ENA | | |||
R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA | | |||
R300_VPORT_Y_OFFSET_ENA | R300_VPORT_Z_SCALE_ENA | | |||
R300_VPORT_Z_OFFSET_ENA | R300_VTX_W0_FMT); | |||
/* Vertex size. */ | |||
OUT_CS_REG(R300_VAP_VTX_SIZE, 0x8); | |||
/* Max and min vertex index clamp. */ | |||
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, 0xFFFFFF); | |||
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0x0); | |||
/* XXX endian */ | |||
OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VC_NO_SWAP); | |||
OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, 0x0); | |||
/* XXX magic number not in r300_reg */ | |||
OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0xAAAAAAAA); | |||
OUT_CS_REG(R300_VAP_CLIP_CNTL, 0x0); | |||
OUT_CS_REG_SEQ(R300_VAP_GB_VERT_CLIP_ADJ, 4); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F(1.0); | |||
/* XXX is this too long? */ | |||
OUT_CS_REG(VAP_PVS_VTX_TIMEOUT_REG, 0xFFFF); | |||
OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | | |||
R300_GB_LINE_STUFF_ENABLE | R300_GB_TRIANGLE_STUFF_ENABLE); | |||
/* XXX more magic numbers */ | |||
OUT_CS_REG(R300_GB_MSPOS0, 0x66666666); | |||
OUT_CS_REG(R300_GB_MSPOS1, 0x66666666); | |||
/* XXX why doesn't classic Mesa write the number of pipes, too? */ | |||
OUT_CS_REG(R300_GB_TILE_CONFIG, R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16); | |||
OUT_CS_REG(R300_GB_SELECT, R300_GB_FOG_SELECT_1_1_W); | |||
OUT_CS_REG(R300_GB_AA_CONFIG, 0x0); | |||
/* XXX point tex stuffing */ | |||
OUT_CS_REG_SEQ(R300_GA_POINT_S0, 1); | |||
OUT_CS_32F(0.0); | |||
OUT_CS_REG_SEQ(R300_GA_POINT_S1, 1); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_REG(R300_GA_TRIANGLE_STIPPLE, 0x5 | | |||
(0x5 << R300_GA_TRIANGLE_STIPPLE_Y_SHIFT_SHIFT)); | |||
/* XXX should this be related to the actual point size? */ | |||
OUT_CS_REG(R300_GA_POINT_MINMAX, 0x6 | | |||
(0x1800 << R300_GA_POINT_MINMAX_MAX_SHIFT)); | |||
/* XXX this big chunk should be refactored into rs_state */ | |||
OUT_CS_REG(R300_GA_LINE_CNTL, 0x00030006); | |||
OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, 0x3BAAAAAB); | |||
OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, 0x00000000); | |||
OUT_CS_REG(R300_GA_LINE_S0, 0x00000000); | |||
OUT_CS_REG(R300_GA_LINE_S1, 0x3F800000); | |||
OUT_CS_REG(R300_GA_ENHANCE, 0x00000002); | |||
OUT_CS_REG(R300_GA_COLOR_CONTROL, 0x0003AAAA); | |||
OUT_CS_REG(R300_GA_SOLID_RG, 0x00000000); | |||
OUT_CS_REG(R300_GA_SOLID_BA, 0x00000000); | |||
OUT_CS_REG(R300_GA_POLY_MODE, 0x00000000); | |||
OUT_CS_REG(R300_GA_ROUND_MODE, 0x00000001); | |||
OUT_CS_REG(R300_GA_OFFSET, 0x00000000); | |||
OUT_CS_REG(R300_GA_FOG_SCALE, 0x3DBF1412); | |||
OUT_CS_REG(R300_GA_FOG_OFFSET, 0x00000000); | |||
OUT_CS_REG(R300_SU_TEX_WRAP, 0x00000000); | |||
OUT_CS_REG(R300_SU_POLY_OFFSET_FRONT_SCALE, 0x00000000); | |||
OUT_CS_REG(R300_SU_POLY_OFFSET_FRONT_OFFSET, 0x00000000); | |||
OUT_CS_REG(R300_SU_POLY_OFFSET_BACK_SCALE, 0x00000000); | |||
OUT_CS_REG(R300_SU_POLY_OFFSET_BACK_OFFSET, 0x00000000); | |||
OUT_CS_REG(R300_SU_POLY_OFFSET_ENABLE, 0x00000000); | |||
OUT_CS_REG(R300_SU_CULL_MODE, 0x00000000); | |||
OUT_CS_REG(R300_SU_DEPTH_SCALE, 0x4B7FFFFF); | |||
OUT_CS_REG(R300_SU_DEPTH_OFFSET, 0x00000000); | |||
OUT_CS_REG(R300_SC_HYPERZ, 0x0000001C); | |||
OUT_CS_REG(R300_SC_EDGERULE, 0x2DA49525); | |||
OUT_CS_REG(R300_SC_SCREENDOOR, 0x00FFFFFF); | |||
OUT_CS_REG(R300_FG_FOG_BLEND, 0x00000002); | |||
OUT_CS_REG(R300_FG_FOG_COLOR_R, 0x00000000); | |||
OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x00000000); | |||
OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x00000000); | |||
OUT_CS_REG(R300_FG_DEPTH_SRC, 0x00000000); | |||
OUT_CS_REG(R300_FG_DEPTH_SRC, 0x00000000); | |||
OUT_CS_REG(R300_RB3D_CCTL, 0x00000000); | |||
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F); | |||
/* XXX: Oh the wonderful unknown */ | |||
OUT_CS_REG_SEQ(0x4E54, 8); | |||
for (i = 0; i < 8; i++) | |||
OUT_CS(0x00000000); | |||
OUT_CS_REG(R300_RB3D_AARESOLVE_CTL, 0x00000000); | |||
OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 0x00000000); | |||
OUT_CS_REG(R500_RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD, 0xFFFFFFFF); | |||
OUT_CS_REG(R300_ZB_FORMAT, 0x00000002); | |||
OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, 0x00000003); | |||
OUT_CS_REG(R300_ZB_BW_CNTL, 0x00000000); | |||
OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000); | |||
OUT_CS_REG(0x4F30, 0x00000000); | |||
OUT_CS_REG(0x4F34, 0x00000000); | |||
OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000); | |||
OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000); | |||
R300_PACIFY; | |||
if (caps->has_tcl) { | |||
OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, | |||
(R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | | |||
((R300_LAST_VEC | (1 << R300_DST_VEC_LOC_SHIFT) | | |||
R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); | |||
} else { | |||
OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_0, | |||
(R300_DATA_TYPE_FLOAT_4 << R300_DATA_TYPE_0_SHIFT) | | |||
((R300_LAST_VEC | (2 << R300_DST_VEC_LOC_SHIFT) | | |||
R300_DATA_TYPE_FLOAT_4) << R300_DATA_TYPE_1_SHIFT)); | |||
} | |||
OUT_CS_REG(R300_FG_FOG_BLEND, 0x00000000); | |||
OUT_CS_REG(R300_VAP_PROG_STREAM_CNTL_EXT_0, 0xF688F688); | |||
OUT_CS_REG(R300_VAP_VTX_STATE_CNTL, 0x1); | |||
OUT_CS_REG(R300_VAP_VSM_VTX_ASSM, 0x405); | |||
OUT_CS_REG(R300_SE_VTE_CNTL, 0x0000043F); | |||
OUT_CS_REG(R300_VAP_VTX_SIZE, 0x00000008); | |||
OUT_CS_REG(R300_VAP_PSC_SGN_NORM_CNTL, 0xAAAAAAAA); | |||
OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_0, 0x00000003); | |||
OUT_CS_REG(R300_VAP_OUTPUT_VTX_FMT_1, 0x00000000); | |||
OUT_CS_REG(R300_TX_ENABLE, 0x0); | |||
/* XXX viewport setup */ | |||
OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F((float)x); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F((float)y); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F(0.0); | |||
if (caps->has_tcl) { | |||
OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE | | |||
R300_PS_UCP_MODE_CLIP_AS_TRIFAN); | |||
} | |||
OUT_CS_REG(R300_GA_POINT_SIZE, ((h * 6) & R300_POINTSIZE_Y_MASK) | | |||
((w * 6) << R300_POINTSIZE_X_SHIFT)); | |||
/* XXX RS block and fp setup */ | |||
if (caps->is_r500) { | |||
OUT_CS_REG_SEQ(R500_RS_IP_0, 8); | |||
for (i = 0; i < 8; i++) { | |||
/* I like the operator macros more than the shift macros... */ | |||
OUT_CS((R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_S_SHIFT) | | |||
(R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_T_SHIFT) | | |||
(R500_RS_IP_PTR_K0 << R500_RS_IP_TEX_PTR_R_SHIFT) | | |||
(R500_RS_IP_PTR_K1 << R500_RS_IP_TEX_PTR_Q_SHIFT)); | |||
} | |||
/* XXX */ | |||
OUT_CS_REG_SEQ(R300_RS_COUNT, 2); | |||
OUT_CS((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); | |||
OUT_CS(0x0); | |||
OUT_CS_REG(R500_RS_INST_0, R500_RS_INST_COL_CN_WRITE); | |||
OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO); | |||
OUT_CS_REG(R500_US_PIXSIZE, 0x00000000); | |||
OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) | | |||
R500_US_CODE_END_ADDR(1)); | |||
OUT_CS_REG(R500_US_CODE_RANGE, R500_US_CODE_RANGE_ADDR(0) | | |||
R500_US_CODE_RANGE_SIZE(1)); | |||
OUT_CS_REG(R500_US_CODE_OFFSET, R500_US_CODE_OFFSET_ADDR(0)); | |||
R300_PACIFY; | |||
OUT_CS_REG(R500_GA_US_VECTOR_INDEX, | |||
0 | R500_GA_US_VECTOR_INDEX_TYPE_INSTR); | |||
OUT_CS_REG(R500_GA_US_VECTOR_DATA, | |||
R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT | R500_INST_LAST | | |||
R500_INST_RGB_OMASK_R | R500_INST_RGB_OMASK_G | R500_INST_RGB_OMASK_B | | |||
R500_INST_ALPHA_OMASK | R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP); | |||
OUT_CS_REG(R500_GA_US_VECTOR_DATA, | |||
R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST | | |||
R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST); | |||
OUT_CS_REG(R500_GA_US_VECTOR_DATA, | |||
R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST | | |||
R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST); | |||
OUT_CS_REG(R500_GA_US_VECTOR_DATA, | |||
R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R | | |||
R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B | | |||
R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R | | |||
R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B); | |||
OUT_CS_REG(R500_GA_US_VECTOR_DATA, | |||
R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A); | |||
OUT_CS_REG(R500_GA_US_VECTOR_DATA, | |||
R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 | | |||
R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 | | |||
R500_ALU_RGBA_A_SWIZ_0); | |||
} else { | |||
OUT_CS_REG_SEQ(R300_RS_IP_0, 8); | |||
for (i = 0; i < 8; i++) { | |||
OUT_CS(R300_RS_SEL_T(R300_RS_SEL_K0) | | |||
R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1)); | |||
} | |||
/* XXX */ | |||
OUT_CS_REG_SEQ(R300_RS_COUNT, 2); | |||
OUT_CS((1 << R300_IC_COUNT_SHIFT) | R300_HIRES_EN); | |||
OUT_CS(1); | |||
OUT_CS_REG(R300_RS_INST_0, R300_RS_INST_COL_CN_WRITE); | |||
/* XXX magic numbers */ | |||
OUT_CS_REG(R300_US_CONFIG, 0); | |||
OUT_CS_REG(R300_US_PIXSIZE, 2); | |||
OUT_CS_REG(R300_US_CODE_OFFSET, 0x0); | |||
OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0); | |||
OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0); | |||
OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0); | |||
OUT_CS_REG(R300_US_CODE_ADDR_3, 0x400000); | |||
OUT_CS_REG(R300_US_ALU_RGB_INST_0, 0x50A80); | |||
OUT_CS_REG(R300_US_ALU_RGB_ADDR_0, 0x1C000000); | |||
OUT_CS_REG(R300_US_ALU_ALPHA_INST_0, 0x40889); | |||
OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0, 0x1000000); | |||
OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4); | |||
OUT_CS(R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A); | |||
OUT_CS(R300_US_OUT_FMT_UNUSED); | |||
OUT_CS(R300_US_OUT_FMT_UNUSED); | |||
OUT_CS(R300_US_OUT_FMT_UNUSED); | |||
OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0); | |||
} | |||
/* XXX these magic numbers should be explained when | |||
* this becomes a cached state object */ | |||
if (caps->has_tcl) { | |||
OUT_CS_REG(R300_VAP_CNTL, 0xA | | |||
(0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | | |||
(0xB << R300_VF_MAX_VTX_NUM_SHIFT) | | |||
(caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); | |||
OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_0, 0x00100000); | |||
OUT_CS_REG(R300_VAP_PVS_CONST_CNTL, 0x00000000); | |||
OUT_CS_REG(R300_VAP_PVS_CODE_CNTL_1, 0x00000001); | |||
R300_PACIFY; | |||
/* XXX translate these back into normal instructions */ | |||
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x1); | |||
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0x0); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xF00203); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xD10001); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x1248001); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x0); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xF02203); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0xD10021); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x1248021); | |||
OUT_CS_REG(R300_VAP_PVS_UPLOAD_DATA, 0x0); | |||
} else { | |||
OUT_CS_REG(R300_VAP_CNTL, 0xA | | |||
(0x5 << R300_PVS_NUM_CNTLRS_SHIFT) | | |||
(0x5 << R300_VF_MAX_VTX_NUM_SHIFT) | | |||
(caps->num_vert_fpus << R300_PVS_NUM_FPUS_SHIFT)); | |||
} | |||
R300_PACIFY; | |||
END_CS; | |||
r300_emit_blend_state(r300, &blend_clear_state); | |||
r300_emit_blend_color_state(r300, &blend_color_clear_state); | |||
r300_emit_dsa_state(r300, &dsa_clear_state); | |||
BEGIN_CS(36); | |||
R300_PACIFY; | |||
/* Flush colorbuffer and blend caches. */ | |||
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, | |||
R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D | | |||
R300_RB3D_DSTCACHE_CTLSTAT_DC_FINISH_SIGNAL); | |||
OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, | |||
R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | | |||
R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); | |||
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1); | |||
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); | |||
/* XXX this should not be so rigid and it still doesn't work right */ | |||
OUT_CS_REG(R300_RB3D_COLORPITCH0, (dest->stride >> 2) | R300_COLOR_FORMAT_ARGB8888); | |||
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0x0000000F); | |||
/* XXX Packet3 */ | |||
OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); | |||
OUT_CS(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING | | |||
(1 << R300_PRIM_NUM_VERTICES_SHIFT)); | |||
OUT_CS_32F(w / 2.0); | |||
OUT_CS_32F(h / 2.0); | |||
/* XXX this should be the depth value to clear to */ | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F(1.0); | |||
OUT_CS_32F(r); | |||
OUT_CS_32F(g); | |||
OUT_CS_32F(b); | |||
OUT_CS_32F(1.0); | |||
/* XXX figure out why this is 0xA and not 0x2 */ | |||
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, 0xA); | |||
/* XXX OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, | |||
R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | | |||
R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); */ | |||
R300_PACIFY; | |||
END_CS; | |||
FLUSH_CS; | |||
r300->dirty_state = R300_NEW_KITCHEN_SINK; | |||
} | |||
void r300_init_surface_functions(struct r300_context* r300) | |||
{ | |||
r300->context.surface_fill = r300_surface_fill; | |||
} |
@@ -0,0 +1,58 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_SURFACE_H | |||
#define R300_SURFACE_H | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_screen.h" | |||
#include "util/u_rect.h" | |||
#include "r300_context.h" | |||
#include "r300_cs.h" | |||
#include "r300_emit.h" | |||
const struct r300_blend_state blend_clear_state = { | |||
.blend_control = 0x0, | |||
.alpha_blend_control = 0x0, | |||
.rop = 0x0, | |||
.dither = 0x0, | |||
}; | |||
const struct r300_blend_color_state blend_color_clear_state = { | |||
.blend_color = 0x0, | |||
.blend_color_red_alpha = 0x0, | |||
.blend_color_green_blue = 0x0, | |||
}; | |||
const struct r300_dsa_state dsa_clear_state = { | |||
.alpha_function = 0x0, | |||
.alpha_reference = 0x0, | |||
.z_buffer_control = 0x0, | |||
.z_stencil_control = 0x0, | |||
.stencil_ref_mask = R300_STENCILWRITEMASK_MASK, | |||
.z_buffer_top = R300_ZTOP_ENABLE, | |||
.stencil_ref_bf = 0x0, | |||
}; | |||
#endif /* R300_SURFACE_H */ |
@@ -0,0 +1,129 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "draw/draw_pipe.h" | |||
#include "util/u_memory.h" | |||
#include "r300_cs.h" | |||
#include "r300_context.h" | |||
#include "r300_reg.h" | |||
/* r300_swtcl_emit: Primitive vertex emission using an immediate | |||
* vertex buffer and no HW TCL. */ | |||
struct swtcl_stage { | |||
/* Parent class */ | |||
struct draw_stage draw; | |||
struct r300_context* r300; | |||
}; | |||
static INLINE struct swtcl_stage* swtcl_stage(struct draw_stage* draw) { | |||
return (struct swtcl_stage*)draw; | |||
} | |||
static void r300_emit_vertex(struct r300_context* r300, | |||
const struct vertex_header* vertex) | |||
{ | |||
/* XXX */ | |||
} | |||
static INLINE void r300_emit_prim(struct draw_stage* draw, | |||
struct prim_header* prim, | |||
unsigned hwprim, | |||
unsigned count) | |||
{ | |||
struct r300_context* r300 = swtcl_stage(draw)->r300; | |||
CS_LOCALS(r300); | |||
int i; | |||
r300_emit_dirty_state(r300); | |||
/* XXX should be count * vtx size */ | |||
BEGIN_CS(2 + count + 6); | |||
OUT_CS(CP_PACKET3(R200_3D_DRAW_IMMD_2, count)); | |||
OUT_CS(hwprim | R300_PRIM_WALK_RING | | |||
(count << R300_PRIM_NUM_VERTICES_SHIFT)); | |||
for (i = 0; i < count; i++) { | |||
r300_emit_vertex(r300, prim->v[i]); | |||
} | |||
R300_PACIFY; | |||
END_CS; | |||
} | |||
/* Just as an aside... | |||
* | |||
* Radeons can do many more primitives: | |||
* - Line strip | |||
* - Triangle fan | |||
* - Triangle strip | |||
* - Line loop | |||
* - Quads | |||
* - Quad strip | |||
* - Polygons | |||
* | |||
* The following were just the only ones in Draw. */ | |||
static void r300_emit_point(struct draw_stage* draw, struct prim_header* prim) | |||
{ | |||
r300_emit_prim(draw, prim, R300_PRIM_TYPE_POINT, 1); | |||
} | |||
static void r300_emit_line(struct draw_stage* draw, struct prim_header* prim) | |||
{ | |||
r300_emit_prim(draw, prim, R300_PRIM_TYPE_LINE, 2); | |||
} | |||
static void r300_emit_tri(struct draw_stage* draw, struct prim_header* prim) | |||
{ | |||
r300_emit_prim(draw, prim, R300_PRIM_TYPE_TRI_LIST, 3); | |||
} | |||
static void r300_swtcl_flush(struct draw_stage* draw, unsigned flags) | |||
{ | |||
} | |||
static void r300_reset_stipple(struct draw_stage* draw) | |||
{ | |||
/* XXX */ | |||
} | |||
static void r300_swtcl_destroy(struct draw_stage* draw) | |||
{ | |||
FREE(draw); | |||
} | |||
struct draw_stage* r300_draw_swtcl_stage(struct r300_context* r300) | |||
{ | |||
struct swtcl_stage* swtcl = CALLOC_STRUCT(swtcl_stage); | |||
swtcl->r300 = r300; | |||
swtcl->draw.point = r300_emit_point; | |||
swtcl->draw.line = r300_emit_line; | |||
swtcl->draw.tri = r300_emit_tri; | |||
swtcl->draw.flush = r300_swtcl_flush; | |||
swtcl->draw.reset_stipple_counter = r300_reset_stipple; | |||
swtcl->draw.destroy = r300_swtcl_destroy; | |||
return &swtcl->draw; | |||
} |
@@ -0,0 +1,193 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "r300_texture.h" | |||
static int minify(int i) | |||
{ | |||
return MAX2(1, i >> 1); | |||
} | |||
static void r300_setup_miptree(struct r300_texture* tex) | |||
{ | |||
struct pipe_texture* base = &tex->tex; | |||
int stride, size, offset; | |||
for (int i = 0; i <= base->last_level; i++) { | |||
if (i > 0) { | |||
base->width[i] = minify(base->width[i-1]); | |||
base->height[i] = minify(base->height[i-1]); | |||
base->depth[i] = minify(base->depth[i-1]); | |||
} | |||
base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]); | |||
base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]); | |||
/* Radeons enjoy things in multiples of 32. */ | |||
/* XXX NPOT -> 64, not 32 */ | |||
stride = (base->nblocksx[i] * base->block.size + 63) & ~63; | |||
size = stride * base->nblocksy[i] * base->depth[i]; | |||
/* XXX 64 for NPOT */ | |||
tex->offset[i] = (tex->size + 63) & ~63; | |||
tex->size = tex->offset[i] + size; | |||
} | |||
} | |||
/* Create a new texture. */ | |||
static struct pipe_texture* | |||
r300_texture_create(struct pipe_screen* screen, | |||
const struct pipe_texture* template) | |||
{ | |||
/* XXX struct r300_screen* r300screen = r300_screen(screen); */ | |||
struct r300_texture* tex = CALLOC_STRUCT(r300_texture); | |||
if (!tex) { | |||
return NULL; | |||
} | |||
tex->tex = *template; | |||
tex->tex.refcount = 1; | |||
tex->tex.screen = screen; | |||
r300_setup_miptree(tex); | |||
tex->buffer = screen->buffer_create(screen, 63, | |||
PIPE_BUFFER_USAGE_PIXEL, | |||
tex->size); | |||
if (!tex->buffer) { | |||
FREE(tex); | |||
return NULL; | |||
} | |||
return (struct pipe_texture*)tex; | |||
} | |||
static void r300_texture_release(struct pipe_screen* screen, | |||
struct pipe_texture** texture) | |||
{ | |||
if (!*texture) { | |||
return; | |||
} | |||
(*texture)->refcount--; | |||
if ((*texture)->refcount <= 0) { | |||
struct r300_texture* tex = (struct r300_texture*)*texture; | |||
pipe_buffer_reference(screen, &tex->buffer, NULL); | |||
FREE(tex); | |||
} | |||
*texture = NULL; | |||
} | |||
static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, | |||
struct pipe_texture* texture, | |||
unsigned face, | |||
unsigned level, | |||
unsigned zslice, | |||
unsigned flags) | |||
{ | |||
struct r300_texture* tex = (struct r300_texture*)texture; | |||
struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface); | |||
unsigned offset; | |||
/* XXX this is certainly dependent on tex target */ | |||
offset = tex->offset[level]; | |||
if (surface) { | |||
surface->refcount = 1; | |||
pipe_texture_reference(&surface->texture, texture); | |||
surface->format = texture->format; | |||
surface->width = texture->width[level]; | |||
surface->height = texture->height[level]; | |||
surface->block = texture->block; | |||
surface->nblocksx = texture->nblocksx[level]; | |||
surface->nblocksy = texture->nblocksy[level]; | |||
/* XXX save the actual stride instead plz kthnxbai */ | |||
surface->stride = | |||
(texture->nblocksx[level] * texture->block.size + 63) & ~63; | |||
surface->offset = offset; | |||
surface->usage = flags; | |||
surface->status = PIPE_SURFACE_STATUS_DEFINED; | |||
} | |||
return surface; | |||
} | |||
static void r300_tex_surface_release(struct pipe_screen* screen, | |||
struct pipe_surface** surface) | |||
{ | |||
struct pipe_surface* s = *surface; | |||
s->refcount--; | |||
if (s->refcount <= 0) { | |||
pipe_texture_reference(&s->texture, NULL); | |||
FREE(s); | |||
} | |||
*surface = NULL; | |||
} | |||
static struct pipe_texture* | |||
r300_texture_blanket(struct pipe_screen* screen, | |||
const struct pipe_texture* base, | |||
const unsigned* stride, | |||
struct pipe_buffer* buffer) | |||
{ | |||
struct r300_texture* tex; | |||
if (base->target != PIPE_TEXTURE_2D || | |||
base->last_level != 0 || | |||
base->depth[0] != 1) { | |||
return NULL; | |||
} | |||
tex = CALLOC_STRUCT(r300_texture); | |||
if (!tex) { | |||
return NULL; | |||
} | |||
tex->tex = *base; | |||
tex->tex.refcount = 1; | |||
tex->tex.screen = screen; | |||
/* XXX tex->stride = *stride; */ | |||
pipe_buffer_reference(screen, &tex->buffer, buffer); | |||
return (struct pipe_texture*)tex; | |||
} | |||
void r300_init_screen_texture_functions(struct pipe_screen* screen) | |||
{ | |||
screen->texture_create = r300_texture_create; | |||
screen->texture_release = r300_texture_release; | |||
screen->get_tex_surface = r300_get_tex_surface; | |||
screen->tex_surface_release = r300_tex_surface_release; | |||
screen->texture_blanket = r300_texture_blanket; | |||
} |
@@ -0,0 +1,34 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_TEXTURE_H | |||
#define R300_TEXTURE_H | |||
#include "pipe/p_screen.h" | |||
#include "util/u_math.h" | |||
#include "r300_context.h" | |||
void r300_init_screen_texture_functions(struct pipe_screen* screen); | |||
#endif /* R300_TEXTURE_H */ |
@@ -0,0 +1,94 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#ifndef R300_WINSYS_H | |||
#define R300_WINSYS_H | |||
#ifdef __cplusplus | |||
extern "C" { | |||
#endif | |||
/* The public interface header for the r300 pipe driver. | |||
* Any winsys hosting this pipe needs to implement r300_winsys and then | |||
* call r300_create_context to start things. */ | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_state.h" | |||
struct radeon_cs; | |||
struct r300_winsys { | |||
/* PCI ID */ | |||
uint32_t pci_id; | |||
/* GB pipe count */ | |||
uint32_t gb_pipes; | |||
/* CS object. This is very much like Intel's batchbuffer. | |||
* Fill it full of dwords and relocs and then submit. | |||
* Repeat as needed. */ | |||
/* Note: Unlike Mesa's version of this, we don't keep a copy of the CSM | |||
* that was used to create this CS. Is this a good idea? */ | |||
/* Note: The pipe driver doesn't know how to use this. This is purely | |||
* for the winsys. */ | |||
struct radeon_cs* cs; | |||
/* Check to see if there's room for commands. */ | |||
boolean (*check_cs)(struct radeon_cs* cs, int size); | |||
/* Start a command emit. */ | |||
void (*begin_cs)(struct radeon_cs* cs, | |||
int size, | |||
const char* file, | |||
const char* function, | |||
int line); | |||
/* Write a dword to the command buffer. */ | |||
void (*write_cs_dword)(struct radeon_cs* cs, uint32_t dword); | |||
/* Write a relocated dword to the command buffer. */ | |||
void (*write_cs_reloc)(struct radeon_cs* cs, | |||
struct pipe_buffer* bo, | |||
uint32_t rd, | |||
uint32_t wd, | |||
uint32_t flags); | |||
/* Finish a command emit. */ | |||
void (*end_cs)(struct radeon_cs* cs, | |||
const char* file, | |||
const char* function, | |||
int line); | |||
/* Flush the CS. */ | |||
void (*flush_cs)(struct radeon_cs* cs); | |||
}; | |||
struct pipe_context* r300_create_context(struct pipe_screen* screen, | |||
struct pipe_winsys* winsys, | |||
struct r300_winsys* r300_winsys); | |||
#ifdef __cplusplus | |||
} | |||
#endif | |||
#endif /* R300_WINSYS_H */ |
@@ -270,7 +270,7 @@ softpipe_tex_surface_release(struct pipe_screen *screen, | |||
* needed post-processing to put them into hardware layout, this is | |||
* where it would happen. For softpipe, nothing to do. | |||
*/ | |||
assert ((*s)->texture); | |||
assert(surf->texture); | |||
if (--surf->refcount == 0) { | |||
pipe_texture_reference(&surf->texture, NULL); | |||
FREE(surf); |
@@ -64,7 +64,7 @@ struct tgsi_processor | |||
struct tgsi_token | |||
{ | |||
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_x */ | |||
unsigned Size : 8; /**< UINT */ | |||
unsigned NrTokens : 8; /**< UINT */ | |||
unsigned Padding : 19; | |||
unsigned Extended : 1; /**< BOOL */ | |||
}; | |||
@@ -107,7 +107,7 @@ enum tgsi_file_type { | |||
struct tgsi_declaration | |||
{ | |||
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_DECLARATION */ | |||
unsigned Size : 8; /**< UINT */ | |||
unsigned NrTokens : 8; /**< UINT */ | |||
unsigned File : 4; /**< one of TGSI_FILE_x */ | |||
unsigned UsageMask : 4; /**< bitmask of TGSI_WRITEMASK_x flags */ | |||
unsigned Interpolate : 4; /**< one of TGSI_INTERPOLATE_x */ | |||
@@ -145,7 +145,7 @@ struct tgsi_declaration_semantic | |||
struct tgsi_immediate | |||
{ | |||
unsigned Type : 4; /**< TGSI_TOKEN_TYPE_IMMEDIATE */ | |||
unsigned Size : 8; /**< UINT */ | |||
unsigned NrTokens : 8; /**< UINT */ | |||
unsigned DataType : 4; /**< one of TGSI_IMM_x */ | |||
unsigned Padding : 15; | |||
unsigned Extended : 1; /**< BOOL */ | |||
@@ -442,7 +442,7 @@ struct tgsi_immediate_float32 | |||
struct tgsi_instruction | |||
{ | |||
unsigned Type : 4; /* TGSI_TOKEN_TYPE_INSTRUCTION */ | |||
unsigned Size : 8; /* UINT */ | |||
unsigned NrTokens : 8; /* UINT */ | |||
unsigned Opcode : 8; /* TGSI_OPCODE_ */ | |||
unsigned Saturate : 2; /* TGSI_SAT_ */ | |||
unsigned NumDstRegs : 2; /* UINT */ | |||
@@ -458,7 +458,7 @@ struct tgsi_instruction | |||
* | |||
* Then, tgsi_instruction::NumSrcRegs of tgsi_src_register follow. | |||
* | |||
* tgsi_instruction::Size contains the total number of words that make the | |||
* tgsi_instruction::NrTokens contains the total number of words that make the | |||
* instruction, including the instruction word. | |||
*/ | |||
@@ -544,7 +544,7 @@ static int vlCreateDataBufs | |||
* to display a rendered surface | |||
* Quad is rendered as a tri strip | |||
*/ | |||
csc->vertex_bufs[0].pitch = sizeof(struct vlVertex2f); | |||
csc->vertex_bufs[0].stride = sizeof(struct vlVertex2f); | |||
csc->vertex_bufs[0].max_index = 3; | |||
csc->vertex_bufs[0].buffer_offset = 0; | |||
csc->vertex_bufs[0].buffer = pipe_buffer_create | |||
@@ -573,7 +573,7 @@ static int vlCreateDataBufs | |||
* Create our texcoord buffer and texcoord buffer element | |||
* Texcoord buffer contains the TCs for mapping the rendered surface to the 4 vertices | |||
*/ | |||
csc->vertex_bufs[1].pitch = sizeof(struct vlVertex2f); | |||
csc->vertex_bufs[1].stride = sizeof(struct vlVertex2f); | |||
csc->vertex_bufs[1].max_index = 3; | |||
csc->vertex_bufs[1].buffer_offset = 0; | |||
csc->vertex_bufs[1].buffer = pipe_buffer_create | |||
@@ -602,26 +602,24 @@ static int vlCreateDataBufs | |||
* Create our vertex shader's constant buffer | |||
* Const buffer contains scaling and translation vectors | |||
*/ | |||
csc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); | |||
csc->vs_const_buf.buffer = pipe_buffer_create | |||
( | |||
pipe->screen, | |||
1, | |||
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD, | |||
csc->vs_const_buf.size | |||
sizeof(struct vlVertexShaderConsts) | |||
); | |||
/* | |||
* Create our fragment shader's constant buffer | |||
* Const buffer contains the color conversion matrix and bias vectors | |||
*/ | |||
csc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts); | |||
csc->fs_const_buf.buffer = pipe_buffer_create | |||
( | |||
pipe->screen, | |||
1, | |||
PIPE_BUFFER_USAGE_CONSTANT, | |||
csc->fs_const_buf.size | |||
sizeof(struct vlFragmentShaderConsts) | |||
); | |||
/* |
@@ -86,7 +86,7 @@ static int vlInitCommon(struct vlContext *context) | |||
} | |||
dsa.alpha.enabled = 0; | |||
dsa.alpha.func = PIPE_FUNC_ALWAYS; | |||
dsa.alpha.ref = 0; | |||
dsa.alpha.ref_value = 0; | |||
context->dsa = pipe->create_depth_stencil_alpha_state(pipe, &dsa); | |||
pipe->bind_depth_stencil_alpha_state(pipe, context->dsa); | |||
@@ -911,7 +911,7 @@ static int vlCreateDataBufs | |||
mc->macroblocks_per_picture = mbw * mbh; | |||
/* Create our vertex buffers */ | |||
mc->vertex_bufs.ycbcr.pitch = sizeof(struct vlVertex2f) * 4; | |||
mc->vertex_bufs.ycbcr.stride = 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_buffer_create | |||
@@ -924,7 +924,7 @@ static int vlCreateDataBufs | |||
for (i = 1; i < 3; ++i) | |||
{ | |||
mc->vertex_bufs.all[i].pitch = sizeof(struct vlVertex2f) * 2; | |||
mc->vertex_bufs.all[i].stride = 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_buffer_create | |||
@@ -985,22 +985,20 @@ static int vlCreateDataBufs | |||
mc->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT; | |||
/* Create our constant buffer */ | |||
mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts); | |||
mc->vs_const_buf.buffer = pipe_buffer_create | |||
( | |||
pipe->screen, | |||
DEFAULT_BUF_ALIGNMENT, | |||
PIPE_BUFFER_USAGE_CONSTANT | PIPE_BUFFER_USAGE_DISCARD, | |||
mc->vs_const_buf.size | |||
sizeof(struct vlVertexShaderConsts) | |||
); | |||
mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts); | |||
mc->fs_const_buf.buffer = pipe_buffer_create | |||
( | |||
pipe->screen, | |||
DEFAULT_BUF_ALIGNMENT, | |||
PIPE_BUFFER_USAGE_CONSTANT, | |||
mc->fs_const_buf.size | |||
sizeof(struct vlFragmentShaderConsts) | |||
); | |||
memcpy |
@@ -152,9 +152,9 @@ int vlPutPicture | |||
bind_pipe_drawable(pipe, drawable); | |||
pipe->winsys->flush_frontbuffer | |||
pipe->screen->flush_frontbuffer | |||
( | |||
pipe->winsys, | |||
pipe->screen, | |||
csc->vlGetFrameBuffer(csc), | |||
pipe->priv | |||
); | |||
@@ -172,13 +172,13 @@ int vlSurfaceGetStatus | |||
assert(surface->context); | |||
assert(status); | |||
if (surface->render_fence && !surface->context->pipe->winsys->fence_signalled(surface->context->pipe->winsys, surface->render_fence, 0)) | |||
if (surface->render_fence && !surface->context->pipe->screen->fence_signalled(surface->context->pipe->screen, surface->render_fence, 0)) | |||
{ | |||
*status = vlResourceStatusRendering; | |||
return 0; | |||
} | |||
if (surface->disp_fence && !surface->context->pipe->winsys->fence_signalled(surface->context->pipe->winsys, surface->disp_fence, 0)) | |||
if (surface->disp_fence && !surface->context->pipe->screen->fence_signalled(surface->context->pipe->screen, surface->disp_fence, 0)) | |||
{ | |||
*status = vlResourceStatusDisplaying; | |||
return 0; | |||
@@ -211,7 +211,7 @@ int vlSurfaceSync | |||
assert(surface->context); | |||
assert(surface->render_fence); | |||
surface->context->pipe->winsys->fence_finish(surface->context->pipe->winsys, surface->render_fence, 0); | |||
surface->context->pipe->screen->fence_finish(surface->context->pipe->screen, surface->render_fence, 0); | |||
return 0; | |||
} |
@@ -101,6 +101,9 @@ lookup_context( struct stw_icd *icd, | |||
dhglrc >= DRV_CONTEXT_MAX) | |||
return NULL; | |||
if (icd == NULL) | |||
return NULL; | |||
return icd->ctx_array[dhglrc - 1].ctx; | |||
} | |||
@@ -221,7 +224,7 @@ DrvDescribePixelFormat( | |||
r = stw_pixelformat_describe( hdc, iPixelFormat, cjpfd, ppfd ); | |||
debug_printf( "%s( 0x%p, %d, %u, 0x%p ) = %d\n", | |||
debug_printf( "%s( %p, %d, %u, %p ) = %d\n", | |||
__FUNCTION__, hdc, iPixelFormat, cjpfd, ppfd, r ); | |||
return r; | |||
@@ -248,7 +251,7 @@ DrvGetProcAddress( | |||
r = stw_get_proc_address( lpszProc ); | |||
debug_printf( "%s( \", __FUNCTION__%s\" ) = 0x%p\n", lpszProc, r ); | |||
debug_printf( "%s( \", __FUNCTION__%s\" ) = %p\n", lpszProc, r ); | |||
return r; | |||
} | |||
@@ -298,7 +301,7 @@ DrvSetCallbackProcs( | |||
INT nProcs, | |||
PROC *pProcs ) | |||
{ | |||
debug_printf( "%s( %d, 0x%p )\n", __FUNCTION__, nProcs, pProcs ); | |||
debug_printf( "%s( %d, %p )\n", __FUNCTION__, nProcs, pProcs ); | |||
return; | |||
} | |||
@@ -709,7 +712,7 @@ DrvSetPixelFormat( | |||
r = stw_pixelformat_set( hdc, iPixelFormat ); | |||
debug_printf( "%s( 0x%p, %d ) = %s\n", __FUNCTION__, hdc, iPixelFormat, r ? "TRUE" : "FALSE" ); | |||
debug_printf( "%s( %p, %d ) = %s\n", __FUNCTION__, hdc, iPixelFormat, r ? "TRUE" : "FALSE" ); | |||
return r; | |||
} | |||
@@ -728,7 +731,7 @@ BOOL APIENTRY | |||
DrvSwapBuffers( | |||
HDC hdc ) | |||
{ | |||
debug_printf( "%s( 0x%p )\n", __FUNCTION__, hdc ); | |||
debug_printf( "%s( %p )\n", __FUNCTION__, hdc ); | |||
return stw_swap_buffers( hdc ); | |||
} | |||
@@ -749,5 +752,7 @@ DrvValidateVersion( | |||
{ | |||
debug_printf( "%s( %u )\n", __FUNCTION__, ulVersion ); | |||
/* TODO: get the expected version from the winsys */ | |||
return ulVersion == 1; | |||
} |
@@ -256,6 +256,14 @@ stw_pixelformat_set( | |||
return FALSE; | |||
currentpixelformat = iPixelFormat; | |||
/* Some applications mistakenly use the undocumented wglSetPixelFormat | |||
* function instead of SetPixelFormat, so we call SetPixelFormat here to | |||
* avoid opengl32.dll's wglCreateContext to fail */ | |||
if (GetPixelFormat(hdc) == 0) { | |||
SetPixelFormat(hdc, iPixelFormat, NULL); | |||
} | |||
return TRUE; | |||
} | |||
@@ -0,0 +1,32 @@ | |||
TOP = ../../../../.. | |||
include $(TOP)/configs/current | |||
LIBNAME = radeon_dri.so | |||
MINIGLX_SOURCES = | |||
PIPE_DRIVERS = \ | |||
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \ | |||
$(TOP)/src/gallium/drivers/r300/libr300.a | |||
DRIVER_SOURCES = \ | |||
radeon_buffer.c \ | |||
radeon_context.c \ | |||
radeon_r300.c \ | |||
radeon_screen.c \ | |||
radeon_winsys_softpipe.c | |||
C_SOURCES = \ | |||
$(COMMON_GALLIUM_SOURCES) \ | |||
$(DRIVER_SOURCES) | |||
ASM_SOURCES = | |||
DRIVER_DEFINES = -I../../../drivers/r300 | |||
include ../Makefile.template | |||
DRI_LIB_DEPS += -ldrm_radeon | |||
symlinks: |
@@ -0,0 +1,29 @@ | |||
Import('*') | |||
if 'mesa' in env['statetrackers']: | |||
env = drienv.Clone() | |||
DRIVER_SOURCES = [ | |||
'radeon_buffer.c', | |||
'radeon_context.c', | |||
'radeon_screen.c', | |||
'radeon_winsys_softpipe.c', | |||
] | |||
sources = \ | |||
COMMON_GALLIUM_SOURCES + \ | |||
DRIVER_SOURCES | |||
drivers = [ | |||
softpipe, | |||
r300 | |||
] | |||
# TODO: write a wrapper function http://www.scons.org/wiki/WrapperFunctions | |||
env.SharedLibrary( | |||
target ='radeon_dri.so', | |||
source = sources, | |||
LIBS = drivers + mesa + auxiliaries + env['LIBS'], | |||
) | |||
@@ -0,0 +1,239 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#include <stdio.h> | |||
#include "dri_util.h" | |||
#include "state_tracker/st_public.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_inlines.h" | |||
#include "radeon_buffer.h" | |||
#include "radeon_screen.h" | |||
#include "radeon_context.h" | |||
#include "radeon_bo.h" | |||
#include "radeon_drm.h" | |||
static const char *radeon_get_name(struct pipe_winsys *ws) | |||
{ | |||
return "RADEON/DRI2"; | |||
} | |||
static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws, | |||
unsigned alignment, | |||
unsigned usage, | |||
unsigned size) | |||
{ | |||
struct radeon_pipe_winsys *radeon_ws = (struct radeon_pipe_winsys *)ws; | |||
struct radeon_pipe_buffer *radeon_buffer; | |||
uint32_t domain; | |||
radeon_buffer = calloc(1, sizeof(*radeon_buffer)); | |||
if (radeon_buffer == NULL) { | |||
return NULL; | |||
} | |||
radeon_buffer->base.refcount = 1; | |||
radeon_buffer->base.alignment = alignment; | |||
radeon_buffer->base.usage = usage; | |||
radeon_buffer->base.size = size; | |||
domain = 0; | |||
if (usage & PIPE_BUFFER_USAGE_PIXEL) { | |||
domain |= RADEON_GEM_DOMAIN_VRAM; | |||
} | |||
if (usage & PIPE_BUFFER_USAGE_VERTEX) { | |||
domain |= RADEON_GEM_DOMAIN_GTT; | |||
} | |||
if (usage & PIPE_BUFFER_USAGE_INDEX) { | |||
domain |= RADEON_GEM_DOMAIN_GTT; | |||
} | |||
radeon_buffer->bo = radeon_bo_open(radeon_ws->radeon_screen->bom, 0, | |||
size, alignment, domain, 0); | |||
if (radeon_buffer->bo == NULL) { | |||
free(radeon_buffer); | |||
} | |||
return &radeon_buffer->base; | |||
} | |||
static struct pipe_buffer *radeon_buffer_user_create(struct pipe_winsys *ws, | |||
void *ptr, | |||
unsigned bytes) | |||
{ | |||
struct radeon_pipe_buffer *radeon_buffer; | |||
radeon_buffer = (struct radeon_pipe_buffer*)radeon_buffer_create(ws, 0, 0, bytes); | |||
if (radeon_buffer == NULL) { | |||
return NULL; | |||
} | |||
radeon_bo_map(radeon_buffer->bo, 1); | |||
memcpy(radeon_buffer->bo->ptr, ptr, bytes); | |||
radeon_bo_unmap(radeon_buffer->bo); | |||
return &radeon_buffer->base; | |||
} | |||
static void radeon_buffer_del(struct pipe_winsys *ws, struct pipe_buffer *buffer) | |||
{ | |||
struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; | |||
radeon_bo_unref(radeon_buffer->bo); | |||
free(radeon_buffer); | |||
} | |||
static void *radeon_buffer_map(struct pipe_winsys *ws, | |||
struct pipe_buffer *buffer, | |||
unsigned flags) | |||
{ | |||
struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; | |||
int write = 0; | |||
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) { | |||
write = 1; | |||
} | |||
if (radeon_bo_map(radeon_buffer->bo, write)) | |||
return NULL; | |||
return radeon_buffer->bo->ptr; | |||
} | |||
static void radeon_buffer_unmap(struct pipe_winsys *ws, struct pipe_buffer *buffer) | |||
{ | |||
struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; | |||
radeon_bo_unmap(radeon_buffer->bo); | |||
} | |||
static void radeon_fence_reference(struct pipe_winsys *ws, | |||
struct pipe_fence_handle **ptr, | |||
struct pipe_fence_handle *pfence) | |||
{ | |||
} | |||
static int radeon_fence_signalled(struct pipe_winsys *ws, | |||
struct pipe_fence_handle *pfence, | |||
unsigned flag) | |||
{ | |||
return 1; | |||
} | |||
static int radeon_fence_finish(struct pipe_winsys *ws, | |||
struct pipe_fence_handle *pfence, | |||
unsigned flag) | |||
{ | |||
return 0; | |||
} | |||
static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys, | |||
struct pipe_surface *pipe_surface, | |||
void *context_private) | |||
{ | |||
/* TODO: call dri2CopyRegion */ | |||
} | |||
struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen) | |||
{ | |||
struct radeon_pipe_winsys *radeon_ws; | |||
radeon_ws = calloc(1, sizeof(struct radeon_pipe_winsys)); | |||
if (radeon_ws == NULL) { | |||
return NULL; | |||
} | |||
radeon_ws->radeon_screen = radeon_screen; | |||
radeon_ws->winsys.flush_frontbuffer = radeon_flush_frontbuffer; | |||
radeon_ws->winsys.buffer_create = radeon_buffer_create; | |||
radeon_ws->winsys.buffer_destroy = radeon_buffer_del; | |||
radeon_ws->winsys.user_buffer_create = radeon_buffer_user_create; | |||
radeon_ws->winsys.buffer_map = radeon_buffer_map; | |||
radeon_ws->winsys.buffer_unmap = radeon_buffer_unmap; | |||
radeon_ws->winsys.fence_reference = radeon_fence_reference; | |||
radeon_ws->winsys.fence_signalled = radeon_fence_signalled; | |||
radeon_ws->winsys.fence_finish = radeon_fence_finish; | |||
radeon_ws->winsys.get_name = radeon_get_name; | |||
return &radeon_ws->winsys; | |||
} | |||
static struct pipe_buffer *radeon_buffer_from_handle(struct radeon_screen *radeon_screen, | |||
uint32_t handle) | |||
{ | |||
struct radeon_pipe_buffer *radeon_buffer; | |||
struct radeon_bo *bo = NULL; | |||
bo = radeon_bo_open(radeon_screen->bom, handle, 0, 0, 0, 0); | |||
if (bo == NULL) { | |||
return NULL; | |||
} | |||
radeon_buffer = calloc(1, sizeof(struct radeon_pipe_buffer)); | |||
if (radeon_buffer == NULL) { | |||
radeon_bo_unref(bo); | |||
return NULL; | |||
} | |||
radeon_buffer->base.refcount = 1; | |||
radeon_buffer->base.usage = PIPE_BUFFER_USAGE_PIXEL; | |||
radeon_buffer->bo = bo; | |||
return &radeon_buffer->base; | |||
} | |||
struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, | |||
uint32_t handle, | |||
enum pipe_format format, | |||
int w, int h, int pitch) | |||
{ | |||
struct pipe_screen *pipe_screen = radeon_context->pipe_screen; | |||
struct pipe_winsys *pipe_winsys = radeon_context->pipe_winsys; | |||
struct pipe_texture tmpl; | |||
struct pipe_surface *ps; | |||
struct pipe_texture *pt; | |||
struct pipe_buffer *pb; | |||
pb = radeon_buffer_from_handle(radeon_context->radeon_screen, handle); | |||
if (pb == NULL) { | |||
return NULL; | |||
} | |||
memset(&tmpl, 0, sizeof(tmpl)); | |||
tmpl.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET; | |||
tmpl.target = PIPE_TEXTURE_2D; | |||
tmpl.width[0] = w; | |||
tmpl.height[0] = h; | |||
tmpl.depth[0] = 1; | |||
tmpl.format = format; | |||
pf_get_block(tmpl.format, &tmpl.block); | |||
tmpl.nblocksx[0] = pf_get_nblocksx(&tmpl.block, w); | |||
tmpl.nblocksy[0] = pf_get_nblocksy(&tmpl.block, h); | |||
pt = pipe_screen->texture_blanket(pipe_screen, &tmpl, &pitch, pb); | |||
if (pt == NULL) { | |||
pipe_buffer_reference(pipe_screen, &pb, NULL); | |||
} | |||
ps = pipe_screen->get_tex_surface(pipe_screen, pt, 0, 0, 0, | |||
PIPE_BUFFER_USAGE_GPU_WRITE); | |||
return ps; | |||
} |
@@ -0,0 +1,54 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#ifndef RADEON_BUFFER_H | |||
#define RADEON_BUFFER_H | |||
#include "pipe/internal/p_winsys_screen.h" | |||
#include "radeon_screen.h" | |||
#include "radeon_context.h" | |||
#include "radeon_bo.h" | |||
struct radeon_pipe_buffer { | |||
struct pipe_buffer base; | |||
struct radeon_bo *bo; | |||
}; | |||
struct radeon_pipe_winsys { | |||
struct pipe_winsys winsys; | |||
struct radeon_screen *radeon_screen; | |||
}; | |||
struct pipe_winsys *radeon_pipe_winsys(struct radeon_screen *radeon_screen); | |||
struct pipe_surface *radeon_surface_from_handle(struct radeon_context *radeon_context, | |||
uint32_t handle, | |||
enum pipe_format format, | |||
int w, int h, int pitch); | |||
#endif |
@@ -0,0 +1,306 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#include <stdio.h> | |||
#include "dri_util.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_inlines.h" | |||
#include "state_tracker/st_public.h" | |||
#include "state_tracker/st_context.h" | |||
#include "radeon_screen.h" | |||
#include "radeon_context.h" | |||
#include "radeon_buffer.h" | |||
#include "radeon_winsys_softpipe.h" | |||
#define need_GL_ARB_fragment_program | |||
#define need_GL_ARB_multisample | |||
#define need_GL_ARB_point_parameters | |||
#define need_GL_ARB_shader_objects | |||
#define need_GL_ARB_texture_compression | |||
#define need_GL_ARB_vertex_buffer_object | |||
#define need_GL_ARB_vertex_program | |||
#define need_GL_ARB_vertex_shader | |||
#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_compiled_vertex_array | |||
#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_VERSION_2_0 | |||
#define need_GL_VERSION_2_1 | |||
#include "extension_helper.h" | |||
/** | |||
* Extension strings exported by the radeon driver. | |||
*/ | |||
const struct dri_extension radeon_card_extensions[] = { | |||
{"GL_ARB_multitexture", NULL}, | |||
{"GL_ARB_texture_border_clamp", NULL}, | |||
{"GL_ARB_texture_rectangle", NULL}, | |||
{"GL_ARB_pixel_buffer_object", NULL}, | |||
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, | |||
{"GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, | |||
{"GL_ARB_shading_language_100", GL_VERSION_2_0_functions}, | |||
{"GL_ARB_shading_language_120", GL_VERSION_2_1_functions}, | |||
{"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, | |||
{"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, | |||
{"GL_ARB_vertex_shader", GL_ARB_vertex_shader_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_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions}, | |||
{"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}, | |||
{NULL, NULL} | |||
}; | |||
static void radeon_update_renderbuffers(__DRIcontext *dri_context, | |||
__DRIdrawable *dri_drawable) | |||
{ | |||
struct radeon_framebuffer *radeon_fb; | |||
struct radeon_context *radeon_context; | |||
unsigned attachments[10]; | |||
__DRIbuffer *buffers; | |||
__DRIscreen *screen; | |||
int i, count; | |||
radeon_context = dri_context->driverPrivate; | |||
screen = dri_drawable->driScreenPriv; | |||
radeon_fb = dri_drawable->driverPrivate; | |||
for (count = 0, i = 0; count < 6; count++) { | |||
if (radeon_fb->attachments & (1 << count)) { | |||
attachments[i++] = count; | |||
} | |||
} | |||
buffers = (*screen->dri2.loader->getBuffers)(dri_drawable, | |||
&dri_drawable->w, | |||
&dri_drawable->h, | |||
attachments, | |||
i, | |||
&count, | |||
dri_drawable->loaderPrivate); | |||
if (buffers == NULL) { | |||
return; | |||
} | |||
/* set one cliprect to cover the whole dri_drawable */ | |||
dri_drawable->x = 0; | |||
dri_drawable->y = 0; | |||
dri_drawable->backX = 0; | |||
dri_drawable->backY = 0; | |||
dri_drawable->numClipRects = 1; | |||
dri_drawable->pClipRects[0].x1 = 0; | |||
dri_drawable->pClipRects[0].y1 = 0; | |||
dri_drawable->pClipRects[0].x2 = dri_drawable->w; | |||
dri_drawable->pClipRects[0].y2 = dri_drawable->h; | |||
dri_drawable->numBackClipRects = 1; | |||
dri_drawable->pBackClipRects[0].x1 = 0; | |||
dri_drawable->pBackClipRects[0].y1 = 0; | |||
dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; | |||
dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; | |||
for (i = 0; i < count; i++) { | |||
struct pipe_surface *ps; | |||
enum pipe_format format = 0; | |||
int index = 0; | |||
switch (buffers[i].attachment) { | |||
case __DRI_BUFFER_FRONT_LEFT: | |||
index = ST_SURFACE_FRONT_LEFT; | |||
switch (buffers[i].cpp) { | |||
case 4: | |||
format = PIPE_FORMAT_A8R8G8B8_UNORM; | |||
break; | |||
case 2: | |||
format = PIPE_FORMAT_R5G6B5_UNORM; | |||
break; | |||
default: | |||
/* FIXME: error */ | |||
return; | |||
} | |||
break; | |||
case __DRI_BUFFER_BACK_LEFT: | |||
index = ST_SURFACE_BACK_LEFT; | |||
switch (buffers[i].cpp) { | |||
case 4: | |||
format = PIPE_FORMAT_A8R8G8B8_UNORM; | |||
break; | |||
case 2: | |||
format = PIPE_FORMAT_R5G6B5_UNORM; | |||
break; | |||
default: | |||
/* FIXME: error */ | |||
return; | |||
} | |||
break; | |||
case __DRI_BUFFER_STENCIL: | |||
case __DRI_BUFFER_DEPTH: | |||
index = ST_SURFACE_DEPTH; | |||
switch (buffers[i].cpp) { | |||
case 4: | |||
format = PIPE_FORMAT_Z24S8_UNORM; | |||
break; | |||
case 2: | |||
format = PIPE_FORMAT_Z16_UNORM; | |||
break; | |||
default: | |||
/* FIXME: error */ | |||
return; | |||
} | |||
break; | |||
case __DRI_BUFFER_ACCUM: | |||
default: | |||
fprintf(stderr, | |||
"unhandled buffer attach event, attacment type %d\n", | |||
buffers[i].attachment); | |||
return; | |||
} | |||
ps = radeon_surface_from_handle(radeon_context, | |||
buffers[i].name, | |||
format, | |||
dri_drawable->w, | |||
dri_drawable->h, | |||
buffers[i].pitch); | |||
assert(ps); | |||
st_set_framebuffer_surface(radeon_fb->st_framebuffer, index, ps); | |||
} | |||
st_resize_framebuffer(radeon_fb->st_framebuffer, | |||
dri_drawable->w, | |||
dri_drawable->h); | |||
} | |||
GLboolean radeon_context_create(const __GLcontextModes *visual, | |||
__DRIcontextPrivate *dri_context, | |||
void *shared_context) | |||
{ | |||
__DRIscreenPrivate *dri_screen; | |||
struct radeon_context *radeon_context; | |||
struct radeon_screen *radeon_screen; | |||
struct pipe_context *pipe; | |||
struct st_context *shared_st_context = NULL; | |||
dri_context->driverPrivate = NULL; | |||
radeon_context = calloc(1, sizeof(struct radeon_context)); | |||
if (radeon_context == NULL) { | |||
return GL_FALSE; | |||
} | |||
if (shared_context) { | |||
shared_st_context = ((struct radeon_context*)shared_context)->st_context; | |||
} | |||
dri_screen = dri_context->driScreenPriv; | |||
radeon_screen = dri_screen->private; | |||
radeon_context->dri_screen = dri_screen; | |||
radeon_context->radeon_screen = radeon_screen; | |||
radeon_context->drm_fd = dri_screen->fd; | |||
radeon_context->pipe_winsys = radeon_pipe_winsys(radeon_screen); | |||
if (radeon_context->pipe_winsys == NULL) { | |||
free(radeon_context); | |||
return GL_FALSE; | |||
} | |||
if (!getenv("RADEON_SOFTPIPE")) { | |||
fprintf(stderr, "Creating r300 context...\n"); | |||
pipe = | |||
r300_create_context(NULL, | |||
radeon_context->pipe_winsys, | |||
radeon_create_r300_winsys(radeon_context->drm_fd)); | |||
radeon_context->pipe_screen = pipe->screen; | |||
} else { | |||
pipe = radeon_create_softpipe(radeon_context); | |||
} | |||
radeon_context->st_context = st_create_context(pipe, visual, | |||
shared_st_context); | |||
driInitExtensions(radeon_context->st_context->ctx, | |||
radeon_card_extensions, GL_TRUE); | |||
dri_context->driverPrivate = radeon_context; | |||
return GL_TRUE; | |||
} | |||
void radeon_context_destroy(__DRIcontextPrivate *dri_context) | |||
{ | |||
struct radeon_context *radeon_context; | |||
radeon_context = dri_context->driverPrivate; | |||
st_finish(radeon_context->st_context); | |||
st_destroy_context(radeon_context->st_context); | |||
free(radeon_context); | |||
} | |||
GLboolean radeon_context_bind(__DRIcontextPrivate *dri_context, | |||
__DRIdrawablePrivate *dri_drawable, | |||
__DRIdrawablePrivate *dri_readable) | |||
{ | |||
struct radeon_framebuffer *drawable; | |||
struct radeon_framebuffer *readable; | |||
struct radeon_context *radeon_context; | |||
if (dri_context == NULL) { | |||
st_make_current(NULL, NULL, NULL); | |||
return GL_TRUE; | |||
} | |||
radeon_context = dri_context->driverPrivate; | |||
drawable = dri_drawable->driverPrivate; | |||
readable = dri_readable->driverPrivate; | |||
st_make_current(radeon_context->st_context, | |||
drawable->st_framebuffer, | |||
readable->st_framebuffer); | |||
radeon_update_renderbuffers(dri_context, dri_drawable); | |||
if (dri_drawable != dri_readable) { | |||
radeon_update_renderbuffers(dri_context, dri_readable); | |||
} | |||
return GL_TRUE; | |||
} | |||
GLboolean radeon_context_unbind(__DRIcontextPrivate *dri_context) | |||
{ | |||
struct radeon_context *radeon_context; | |||
radeon_context = dri_context->driverPrivate; | |||
st_flush(radeon_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL); | |||
return GL_TRUE; | |||
} |
@@ -0,0 +1,70 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#ifndef RADEON_CONTEXT_H | |||
#define RADEON_CONTEXT_H | |||
#include "dri_util.h" | |||
#include "state_tracker/st_public.h" | |||
#include "state_tracker/st_context.h" | |||
#include "radeon_screen.h" | |||
#include "radeon_r300.h" | |||
struct radeon_framebuffer { | |||
struct st_framebuffer *st_framebuffer; | |||
unsigned attachments; | |||
}; | |||
struct radeon_context { | |||
/* st */ | |||
struct st_context *st_context; | |||
/* pipe */ | |||
struct pipe_screen *pipe_screen; | |||
struct pipe_winsys *pipe_winsys; | |||
/* DRI */ | |||
__DRIscreenPrivate *dri_screen; | |||
__DRIdrawablePrivate *dri_drawable; | |||
__DRIdrawablePrivate *dri_readable; | |||
/* DRM */ | |||
int drm_fd; | |||
/* RADEON */ | |||
struct radeon_screen *radeon_screen; | |||
}; | |||
GLboolean radeon_context_create(const __GLcontextModes*, | |||
__DRIcontextPrivate*, | |||
void*); | |||
void radeon_context_destroy(__DRIcontextPrivate*); | |||
GLboolean radeon_context_bind(__DRIcontextPrivate*, | |||
__DRIdrawablePrivate*, | |||
__DRIdrawablePrivate*); | |||
GLboolean radeon_context_unbind(__DRIcontextPrivate*); | |||
#endif |
@@ -0,0 +1,96 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
#include "radeon_r300.h" | |||
static boolean radeon_r300_check_cs(struct radeon_cs* cs, int size) | |||
{ | |||
/* XXX check size here, lazy ass! */ | |||
return TRUE; | |||
} | |||
static void radeon_r300_write_cs_reloc(struct radeon_cs* cs, | |||
struct pipe_buffer* pbuffer, | |||
uint32_t rd, | |||
uint32_t wd, | |||
uint32_t flags) | |||
{ | |||
radeon_cs_write_reloc(cs, ((struct radeon_pipe_buffer*)pbuffer)->bo, rd, wd, flags); | |||
} | |||
static void radeon_r300_flush_cs(struct radeon_cs* cs) | |||
{ | |||
radeon_cs_emit(cs); | |||
radeon_cs_erase(cs); | |||
} | |||
/* Helper function to do the ioctls needed for setup and init. */ | |||
static void do_ioctls(struct r300_winsys* winsys, int fd) | |||
{ | |||
drm_radeon_getparam_t gp; | |||
uint32_t target; | |||
int retval; | |||
/* XXX is this cast safe? */ | |||
gp.value = (int*)⌖ | |||
/* First, get PCI ID */ | |||
gp.param = RADEON_PARAM_DEVICE_ID; | |||
retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); | |||
if (retval) { | |||
fprintf(stderr, "%s: Failed to get PCI ID, error number %d", | |||
__FUNCTION__, retval); | |||
exit(1); | |||
} | |||
winsys->pci_id = target; | |||
/* Then, get the number of pixel pipes */ | |||
gp.param = RADEON_PARAM_NUM_GB_PIPES; | |||
retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp, sizeof(gp)); | |||
if (retval) { | |||
fprintf(stderr, "%s: Failed to get GB pipe count, error number %d", | |||
__FUNCTION__, retval); | |||
exit(1); | |||
} | |||
winsys->gb_pipes = target; | |||
} | |||
struct r300_winsys* radeon_create_r300_winsys(int fd) | |||
{ | |||
struct r300_winsys* winsys = calloc(1, sizeof(struct r300_winsys)); | |||
do_ioctls(winsys, fd); | |||
struct radeon_cs_manager* csm = radeon_cs_manager_gem_ctor(fd); | |||
winsys->cs = radeon_cs_create(csm, 1024 * 64 / 4); | |||
winsys->check_cs = radeon_r300_check_cs; | |||
winsys->begin_cs = radeon_cs_begin; | |||
winsys->write_cs_dword = radeon_cs_write_dword; | |||
winsys->write_cs_reloc = radeon_r300_write_cs_reloc; | |||
winsys->end_cs = radeon_cs_end; | |||
winsys->flush_cs = radeon_r300_flush_cs; | |||
return winsys; | |||
} |
@@ -0,0 +1,34 @@ | |||
/* | |||
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the "Software"), | |||
* to deal in the Software without restriction, including without limitation | |||
* on the rights to use, copy, modify, merge, publish, distribute, sub | |||
* license, and/or sell copies of the Software, and to permit persons to whom | |||
* the Software is furnished to do so, subject to the following conditions: | |||
* | |||
* The above copyright notice and this permission notice (including the next | |||
* paragraph) shall be included in all copies or substantial portions of the | |||
* Software. | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. */ | |||
/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */ | |||
#include <stdint.h> | |||
#include <stdlib.h> | |||
#include "drm.h" | |||
#include "radeon_drm.h" | |||
#include "radeon_cs.h" | |||
#include "r300_winsys.h" | |||
#include "radeon_buffer.h" | |||
struct r300_winsys* radeon_create_r300_winsys(int fd); |
@@ -0,0 +1,288 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#include <stdio.h> | |||
#include "pipe/p_screen.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_inlines.h" | |||
#include "pipe/p_context.h" | |||
#include "pipe/p_state.h" | |||
#include "state_tracker/st_public.h" | |||
#include "state_tracker/st_context.h" | |||
#include "utils.h" | |||
#include "xf86drm.h" | |||
#include "drm.h" | |||
#include "dri_util.h" | |||
#include "radeon_screen.h" | |||
#include "radeon_context.h" | |||
#include "radeon_buffer.h" | |||
#include "radeon_bo.h" | |||
#include "radeon_bo_gem.h" | |||
#include "radeon_drm.h" | |||
extern const struct dri_extension radeon_card_extensions[]; | |||
static const __DRIextension *radeon_screen_extensions[] = { | |||
&driReadDrawableExtension, | |||
&driCopySubBufferExtension.base, | |||
&driSwapControlExtension.base, | |||
&driFrameTrackingExtension.base, | |||
&driMediaStreamCounterExtension.base, | |||
NULL | |||
}; | |||
static __DRIconfig **radeon_fill_in_modes(unsigned pixel_bits, | |||
unsigned depth_bits, | |||
GLboolean have_back_buffer) | |||
{ | |||
__DRIconfig **configs; | |||
unsigned depth_buffer_factor; | |||
unsigned back_buffer_factor; | |||
unsigned num_modes; | |||
GLenum fb_format; | |||
GLenum fb_type; | |||
uint8_t depth_bits_array[3]; | |||
uint8_t stencil_bits_array[3]; | |||
uint8_t msaa_samples_array[1]; | |||
/* TODO: pageflipping ? */ | |||
static const GLenum back_buffer_modes[] = { | |||
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML | |||
}; | |||
stencil_bits_array[0] = 0; | |||
stencil_bits_array[1] = 0; | |||
if (depth_bits == 24) { | |||
stencil_bits_array[2] = 8; | |||
num_modes = 3; | |||
} | |||
depth_bits_array[0] = 0; | |||
depth_bits_array[1] = depth_bits; | |||
depth_bits_array[2] = depth_bits; | |||
depth_buffer_factor = (depth_bits == 24) ? 3 : 2; | |||
back_buffer_factor = (have_back_buffer) ? 3 : 1; | |||
msaa_samples_array[0] = 0; | |||
if (pixel_bits == 16) { | |||
fb_format = GL_RGB; | |||
fb_type = GL_UNSIGNED_SHORT_5_6_5; | |||
} else { | |||
fb_format = GL_BGRA; | |||
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; | |||
} | |||
configs = (__DRIconfig **)driCreateConfigs(fb_format, | |||
fb_type, | |||
depth_bits_array, | |||
stencil_bits_array, | |||
depth_buffer_factor, | |||
back_buffer_modes, | |||
back_buffer_factor, | |||
msaa_samples_array, | |||
1); | |||
if (configs == NULL) { | |||
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", | |||
__FILE__, __LINE__); | |||
return NULL; | |||
} | |||
return configs; | |||
} | |||
static void radeon_screen_destroy(__DRIscreenPrivate *dri_screen) | |||
{ | |||
struct radeon_screen *radeon_screen = (struct radeon_screen*)dri_screen->private; | |||
radeon_bo_manager_gem_dtor(radeon_screen->bom); | |||
dri_screen = NULL; | |||
free(radeon_screen); | |||
} | |||
static const __DRIconfig **radeon_screen_init(__DRIscreenPrivate *dri_screen) | |||
{ | |||
struct radeon_screen *radeon_screen; | |||
/* Calling driInitExtensions here, with a NULL context pointer, | |||
* does not actually enable the extensions. It just makes sure | |||
* that all the dispatch offsets for all the extensions that | |||
* *might* be enables are known. This is needed because the | |||
* dispatch offsets need to be known when _mesa_context_create is | |||
* called, but we can't enable the extensions until we have a | |||
* context pointer. | |||
* | |||
* Hello chicken. Hello egg. How are you two today? | |||
*/ | |||
driInitExtensions(NULL, radeon_card_extensions, GL_FALSE); | |||
radeon_screen = calloc(1, sizeof(struct radeon_screen)); | |||
if (radeon_screen == NULL) { | |||
fprintf(stderr, "\nERROR! Allocating private area failed\n"); | |||
return NULL; | |||
} | |||
dri_screen->private = (void*)radeon_screen; | |||
dri_screen->extensions = radeon_screen_extensions; | |||
radeon_screen->dri_screen = dri_screen; | |||
radeon_screen->bom = radeon_bo_manager_gem_ctor(dri_screen->fd); | |||
if (radeon_screen->bom == NULL) { | |||
radeon_screen_destroy(dri_screen); | |||
return NULL; | |||
} | |||
return driConcatConfigs(radeon_fill_in_modes(16, 16, 1), | |||
radeon_fill_in_modes(32, 24, 1)); | |||
} | |||
static boolean radeon_buffer_create(__DRIscreenPrivate *dri_screen, | |||
__DRIdrawablePrivate *dri_drawable, | |||
const __GLcontextModes *visual, | |||
boolean is_pixmap) | |||
{ | |||
if (is_pixmap) { | |||
/* TODO: implement ? */ | |||
return GL_FALSE; | |||
} else { | |||
enum pipe_format color_format, depth_format, stencil_format; | |||
struct radeon_framebuffer *radeon_fb; | |||
radeon_fb = calloc(1, sizeof(struct radeon_framebuffer)); | |||
if (radeon_fb == NULL) { | |||
return GL_FALSE; | |||
} | |||
switch (visual->redBits) { | |||
case 5: | |||
color_format = PIPE_FORMAT_R5G6B5_UNORM; | |||
break; | |||
default: | |||
color_format = PIPE_FORMAT_A8R8G8B8_UNORM; | |||
break; | |||
} | |||
switch (visual->depthBits) { | |||
case 24: | |||
depth_format = PIPE_FORMAT_S8Z24_UNORM; | |||
break; | |||
case 16: | |||
depth_format = PIPE_FORMAT_Z16_UNORM; | |||
break; | |||
default: | |||
depth_format = PIPE_FORMAT_NONE; | |||
break; | |||
} | |||
switch (visual->stencilBits) { | |||
case 8: | |||
/* force depth format */ | |||
depth_format = PIPE_FORMAT_S8Z24_UNORM; | |||
stencil_format = PIPE_FORMAT_S8Z24_UNORM; | |||
break; | |||
default: | |||
stencil_format = PIPE_FORMAT_NONE; | |||
break; | |||
} | |||
radeon_fb->st_framebuffer = st_create_framebuffer(visual, | |||
color_format, | |||
depth_format, | |||
stencil_format, | |||
dri_drawable->w, | |||
dri_drawable->h, | |||
(void*)radeon_fb); | |||
if (radeon_fb->st_framebuffer == NULL) { | |||
free(radeon_fb); | |||
return GL_FALSE; | |||
} | |||
dri_drawable->driverPrivate = (void *) radeon_fb; | |||
radeon_fb->attachments = (1 << __DRI_BUFFER_FRONT_LEFT); | |||
if (visual->doubleBufferMode) { | |||
radeon_fb->attachments |= (1 << __DRI_BUFFER_BACK_LEFT); | |||
} | |||
if (visual->depthBits || visual->stencilBits) { | |||
radeon_fb->attachments |= (1 << __DRI_BUFFER_DEPTH); | |||
} | |||
return GL_TRUE; | |||
} | |||
} | |||
static void radeon_buffer_destroy(__DRIdrawablePrivate * dri_drawable) | |||
{ | |||
struct radeon_framebuffer *radeon_fb; | |||
radeon_fb = dri_drawable->driverPrivate; | |||
assert(radeon_fb->st_framebuffer); | |||
st_unreference_framebuffer(radeon_fb->st_framebuffer); | |||
free(radeon_fb); | |||
} | |||
static void radeon_swap_buffers(__DRIdrawablePrivate *dri_drawable) | |||
{ | |||
struct radeon_framebuffer *radeon_fb; | |||
struct pipe_surface *back_surf = NULL; | |||
radeon_fb = dri_drawable->driverPrivate; | |||
assert(radeon_fb); | |||
assert(radeon_fb->st_framebuffer); | |||
st_get_framebuffer_surface(radeon_fb->st_framebuffer, | |||
ST_SURFACE_BACK_LEFT, | |||
&back_surf); | |||
if (back_surf) { | |||
st_notify_swapbuffers(radeon_fb->st_framebuffer); | |||
/* TODO: do we want to do anythings ? */ | |||
st_notify_swapbuffers_complete(radeon_fb->st_framebuffer); | |||
} | |||
} | |||
/** | |||
* Called via glXCopySubBufferMESA() to copy a subrect of the back | |||
* buffer to the front buffer/screen. | |||
*/ | |||
static void radeon_copy_sub_buffer(__DRIdrawablePrivate *dri_drawable, | |||
int x, int y, int w, int h) | |||
{ | |||
/* TODO: ... */ | |||
} | |||
const struct __DriverAPIRec driDriverAPI = { | |||
.InitScreen = NULL, | |||
.DestroyScreen = radeon_screen_destroy, | |||
.CreateContext = radeon_context_create, | |||
.DestroyContext = radeon_context_destroy, | |||
.CreateBuffer = radeon_buffer_create, | |||
.DestroyBuffer = radeon_buffer_destroy, | |||
.SwapBuffers = radeon_swap_buffers, | |||
.MakeCurrent = radeon_context_bind, | |||
.UnbindContext = radeon_context_unbind, | |||
.CopySubBuffer = radeon_copy_sub_buffer, | |||
.InitScreen2 = radeon_screen_init, | |||
}; |
@@ -0,0 +1,41 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#ifndef RADEON_SCREEN_H | |||
#define RADEON_SCREEN_H | |||
#include "dri_util.h" | |||
#include "radeon_bo.h" | |||
struct radeon_screen { | |||
__DRIscreenPrivate *dri_screen; | |||
struct radeon_bo_manager *bom; | |||
}; | |||
#endif |
@@ -0,0 +1,77 @@ | |||
/************************************************************************** | |||
* | |||
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining a | |||
* copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL | |||
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, | |||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | |||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
* | |||
* | |||
**************************************************************************/ | |||
/* | |||
* Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com> | |||
*/ | |||
#include <stdio.h> | |||
#include "imports.h" | |||
#include "pipe/p_defines.h" | |||
#include "pipe/p_format.h" | |||
#include "softpipe/sp_winsys.h" | |||
#include "radeon_context.h" | |||
#include "radeon_winsys_softpipe.h" | |||
struct radeon_softpipe_winsys { | |||
struct softpipe_winsys sp_winsys; | |||
struct radeon_context *radeon_context; | |||
}; | |||
/** | |||
* Return list of surface formats supported by this driver. | |||
*/ | |||
static boolean radeon_is_format_supported(struct softpipe_winsys *sws, uint format) | |||
{ | |||
switch (format) { | |||
case PIPE_FORMAT_A8R8G8B8_UNORM: | |||
case PIPE_FORMAT_R5G6B5_UNORM: | |||
case PIPE_FORMAT_Z24S8_UNORM: | |||
return TRUE; | |||
default: | |||
break; | |||
}; | |||
return FALSE; | |||
} | |||
struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context) | |||
{ | |||
struct radeon_softpipe_winsys *radeon_sp_ws; | |||
struct pipe_screen *pipe_screen; | |||
pipe_screen = softpipe_create_screen(radeon_context->pipe_winsys); | |||
radeon_sp_ws = CALLOC_STRUCT(radeon_softpipe_winsys); | |||
if (radeon_sp_ws == NULL) { | |||
return NULL; | |||
} | |||
radeon_context->pipe_screen = pipe_screen; | |||
radeon_sp_ws->radeon_context = radeon_context; | |||
radeon_sp_ws->sp_winsys.is_format_supported = radeon_is_format_supported; | |||
return softpipe_create(pipe_screen, | |||
radeon_context->pipe_winsys, | |||
&radeon_sp_ws->sp_winsys); | |||
} |
@@ -0,0 +1,37 @@ | |||
/* | |||
* Copyright © 2008 Jérôme Glisse | |||
* All Rights Reserved. | |||
* | |||
* Permission is hereby granted, free of charge, to any person obtaining | |||
* a copy of this software and associated documentation files (the | |||
* "Software"), to deal in the Software without restriction, including | |||
* without limitation the rights to use, copy, modify, merge, publish, | |||
* distribute, sub license, and/or sell copies of the Software, and to | |||
* permit persons to whom the Software is furnished to do so, subject to | |||
* the following conditions: | |||
* | |||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS | |||
* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | |||
* USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
* | |||
* The above copyright notice and this permission notice (including the | |||
* next paragraph) shall be included in all copies or substantial portions | |||
* of the Software. | |||
*/ | |||
/* | |||
* Authors: | |||
* Jérôme Glisse <glisse@freedesktop.org> | |||
*/ | |||
#ifndef RADEON_WINSYS_SOFTPIPE_H | |||
#define RADEON_WINSYS_SOFTPIPE_H | |||
#include "radeon_context.h" | |||
struct pipe_context *radeon_create_softpipe(struct radeon_context *radeon_context); | |||
#endif |
@@ -11,6 +11,7 @@ CFLAGS += -g -Wall -Werror=implicit-function-declaration -fPIC \ | |||
-I${GALLIUMDIR}/winsys/drm/nouveau \ | |||
-I${DRMDIR}/include \ | |||
-I${DRMDIR}/include/drm \ | |||
-I${DRMDIR}/include/nouveau \ | |||
-I${GALLIUMDIR}/drivers \ | |||
-I${GALLIUMDIR}/auxiliary \ | |||
-I${DRIDIR}/include | |||
@@ -23,13 +24,14 @@ LDFLAGS += -L${DRMDIR}/lib \ | |||
-L${GALLIUMDIR}/auxiliary/translate \ | |||
-L${GALLIUMDIR}/auxiliary/rtasm \ | |||
-L${GALLIUMDIR}/auxiliary/cso_cache \ | |||
-L${GALLIUMDIR}/drivers/nv04 \ | |||
-L${GALLIUMDIR}/drivers/nv10 \ | |||
-L${GALLIUMDIR}/drivers/nv20 \ | |||
-L${GALLIUMDIR}/drivers/nv30 \ | |||
-L${GALLIUMDIR}/drivers/nv40 \ | |||
-L${GALLIUMDIR}/drivers/nv50 | |||
LIBS += -lnouveaudrm -ldriclient -ldrm -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm | |||
LIBS += -lnouveaudrm -ldriclient -ldrm_nouveau -ldrm -lnv04 -lnv10 -lnv20 -lnv30 -lnv40 -lnv50 -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lm | |||
############################################# | |||
@@ -4,7 +4,7 @@ | |||
#include <common/nouveau_dri.h> | |||
#include <common/nouveau_local.h> | |||
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 11 | |||
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 12 | |||
#error nouveau_drm.h version does not match expected version | |||
#endif | |||
@@ -9,6 +9,7 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, | |||
const drm_clip_rect_t *rect) | |||
{ | |||
struct nouveau_context_vl *nv = dri_drawable->private; | |||
struct pipe_context *pipe = nv->base.nvc->pctx[nv->base.pctx_id]; | |||
drm_clip_rect_t *pbox; | |||
int nbox, i; | |||
@@ -20,7 +21,6 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, | |||
pbox = dri_drawable->cliprects; | |||
nbox = dri_drawable->num_cliprects; | |||
nv->base.surface_copy_prep(&nv->base, nv->base.frontbuffer, surf); | |||
for (i = 0; i < nbox; i++, pbox++) { | |||
int sx, sy, dx, dy, w, h; | |||
@@ -31,7 +31,8 @@ nouveau_copy_buffer(dri_drawable_t *dri_drawable, struct pipe_surface *surf, | |||
w = pbox->x2 - pbox->x1; | |||
h = pbox->y2 - pbox->y1; | |||
nv->base.surface_copy(&nv->base, dx, dy, sx, sy, w, h); | |||
pipe->surface_copy(pipe, FALSE, nv->base.frontbuffer, | |||
dx, dy, surf, sx, sy, w, h); | |||
} | |||
FIRE_RING(nv->base.nvc->channel); |
@@ -325,6 +325,7 @@ xlib_create_brw_winsys( void ) | |||
static struct pipe_screen * | |||
xlib_create_brw_screen( void ) | |||
{ | |||
#ifndef GALLIUM_CELL | |||
struct pipe_winsys *winsys; | |||
struct pipe_screen *screen; | |||
@@ -342,6 +343,7 @@ fail: | |||
if (winsys) | |||
winsys->destroy( winsys ); | |||
#endif | |||
return NULL; | |||
} | |||