Merge commit 'origin/master' into gallium-msaa

This commit is contained in:
Roland Scheidegger 2010-04-30 15:27:13 +02:00
commit 7662e3519b
217 changed files with 58452 additions and 2980 deletions

View file

@ -13,7 +13,10 @@ CC = gcc
CXX = g++
PIC_FLAGS = -fPIC
DEFINES = -D_DARWIN_C_SOURCE -DPTHREADS -D_GNU_SOURCE \
-DGLX_ALIAS_UNSUPPORTED -DGLX_INDIRECT_RENDERING
-DGLX_ALIAS_UNSUPPORTED \
-DGLX_DIRECT_RENDERING -DGLX_USE_APPLEGL
# -DGLX_INDIRECT_RENDERING \
# -D_GNU_SOURCE - for src/mesa/main ...
# -DGLX_DIRECT_RENDERING - pulls in libdrm stuff in glx
@ -49,7 +52,7 @@ GLW_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -L$(INSTALL_DIR)/$(LIB_DIR) -L$(X
APP_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) -L$(INSTALL_DIR)/$(LIB_DIR) -L$(X11_DIR)/$(LIB_DIR) -lX11 -lXmu -lXt -lXi -lm
# omit glw lib for now:
SRC_DIRS = glsl glx mesa gallium glu glut/glx glew
SRC_DIRS = glsl glx/apple mesa gallium glu glut/glx glew
GLU_DIRS = sgi
DRIVER_DIRS = osmesa
#DRIVER_DIRS = dri

View file

@ -52,7 +52,7 @@ GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
# Directories
SRC_DIRS := glx egl $(SRC_DIRS)
PROGRAM_DIRS := egl/opengl $(PROGRAM_DIRS)
PROGRAM_DIRS := egl/eglut egl/opengl $(PROGRAM_DIRS)
# EGL directories
EGL_DRIVERS_DIRS = glx

View file

@ -48,7 +48,7 @@ GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lXxf86vm -lXdamage -lXfixes \
# Directories
SRC_DIRS = gallium mesa gallium/winsys gallium/targets glu egl
PROGRAM_DIRS = egl/opengl
PROGRAM_DIRS = egl/eglut egl/opengl
DRIVER_DIRS = dri
GALLIUM_WINSYS_DIRS = egl_drm

View file

@ -7,7 +7,7 @@ CONFIG_NAME = linux-opengl-es
# Directories to build
LIB_DIR = lib
SRC_DIRS = egl glsl mesa/es gallium gallium/winsys gallium/targets
PROGRAM_DIRS = egl/opengles1 egl/opengles2
PROGRAM_DIRS = egl/eglut egl/opengles1 egl/opengles2
# egl st needs this
DEFINES += -DGLX_DIRECT_RENDERING

View file

@ -9,7 +9,7 @@ CONFIG_NAME = linux-osmesa
# Compiler and flags
CC = gcc
CXX = g++
CFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE -DPTHREADS
CFLAGS = -g -ansi -pedantic -fPIC -ffast-math -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -DPTHREADS
CXXFLAGS = -O3 -ansi -pedantic -fPIC -ffast-math -D_POSIX_SOURCE -D_POSIX_C_SOURCE=199309L -D_SVID_SOURCE -D_BSD_SOURCE
# Work around aliasing bugs - developers should comment this out
@ -17,12 +17,12 @@ CFLAGS += -fno-strict-aliasing
CXXFLAGS += -fno-strict-aliasing
# Directories
SRC_DIRS = gallium mesa glu
SRC_DIRS = glsl mesa glu
DRIVER_DIRS = osmesa
PROGRAM_DIRS = osdemos
# Dependencies
OSMESA_LIB_DEPS = -lm -lpthread
OSMESA_LIB_DEPS = -lm -lpthread -ldl
GLU_LIB_DEPS = -L$(TOP)/$(LIB_DIR) -l$(OSMESA_LIB)
APP_LIB_DEPS = -lm -lpthread

View file

@ -20,7 +20,7 @@ OSMESA_LIB_NAME = libOSMesa16.so
# Directories
SRC_DIRS = gallium mesa glu
SRC_DIRS = glsl mesa glu
DRIVER_DIRS = osmesa
PROGRAM_DIRS =

View file

@ -20,7 +20,7 @@ OSMESA_LIB_NAME = libOSMesa32.so
# Directories
SRC_DIRS = gallium mesa glu
SRC_DIRS = glsl mesa glu
DRIVER_DIRS = osmesa
PROGRAM_DIRS =

View file

@ -955,7 +955,7 @@ if test "x$enable_egl" = xyes; then
fi
if test "$with_demos" = yes; then
PROGRAM_DIRS="$PROGRAM_DIRS egl/opengl"
PROGRAM_DIRS="$PROGRAM_DIRS egl/eglut egl/opengl"
fi
fi
AC_SUBST([EGL_LIB_DEPS])
@ -1499,6 +1499,15 @@ fi
fi
echo " Use XCB: $enable_xcb"
echo ""
if test "x$MESA_LLVM" == x1; then
echo " llvm: yes"
echo " llvm-config: $LLVM_CONFIG"
echo " llvm-version: $LLVM_VERSION"
else
echo " llvm: no"
fi
echo ""
if echo "$SRC_DIRS" | grep 'gallium' >/dev/null 2>&1; then
echo " Gallium: yes"

View file

@ -34,7 +34,7 @@ glGetStringi command DONE, except for dispatch
glTexParameterI, glGetTexParameterI commands DONE, except for dispatch
glVertexAttribI commands not started
glBindFragDataLocation, glGetFragDataLocation cmds not started
glBindBufferRange, glBindBufferBase commands not started
glBindBufferRange, glBindBufferBase commands DONE
GL 3.1:
@ -47,7 +47,7 @@ Primitive restart (GL_NV_primitive_restart) not started
Texture buffer objs (GL_ARB_textur_buffer_object) not started
Rectangular textures (GL_ARB_texture_rectangle) DONE
Uniform buffer objs (GL_ARB_uniform_buffer_object) not started
Signed normalized texture formats not started
Signed normalized texture formats ~50% done
GL 3.2:

View file

@ -40,6 +40,15 @@ versions are sent to this list. Very low traffic.
Follow the links above for list archives.
</p>
<p>
The old Mesa lists hosted at SourceForge are no longer in use.
The archives are still available, however:
<a href="http://sourceforge.net/mailarchive/forum.php?forum_name=mesa3d-announce" target="_parent">mesa3d-announce</a>,
<a href="http://sourceforge.net/mailarchive/forum.php?forum_name=mesa3d-users" target="_parent">mesa3d-users</a>,
<a href="http://sourceforge.net/mailarchive/forum.php?forum_name=mesa3d-dev" target="_parent">mesa3d-dev</a>.
</p>
<p>For mailing lists about Direct Rendering Modules (drm) in Linux/BSD
kernels, see the
<a href="http://dri.freedesktop.org/wiki/MailingLists" target="_parent">

View file

@ -34,6 +34,12 @@ tbd
<p>None.</p>
<h2>Changes</h2>
<ul>
<li>Upgraded glext.h to version 61, and upgraded glxext.h
</ul>
<h2>Bug fixes</h2>
<ul>
<li>Fixed Gallium glDrawPixels(GL_DEPTH_COMPONENT).

File diff suppressed because it is too large Load diff

View file

@ -124,6 +124,10 @@ extern "C" {
#define GLX_SAMPLES_ARB 100001
#endif
#ifndef GLX_ARB_vertex_buffer_object
#define GLX_CONTEXT_ALLOW_BUFFER_BYTE_ORDER_MISMATCH_ARB 0x2095
#endif
#ifndef GLX_ARB_fbconfig_float
#define GLX_RGBA_FLOAT_TYPE_ARB 0x20B9
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004

View file

@ -6,11 +6,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "readtex.h"
#define TEST_CLAMP 0
#define TEST_MIPMAPS 0
#define TEST_GEN_COMPRESSED_MIPMAPS 0
#define MAX_TEXTURES 8
@ -304,6 +306,69 @@ LoadTextures(GLuint n, const char *files[])
GL_RGBA, GL_UNSIGNED_BYTE, image);
}
}
#elif TEST_GEN_COMPRESSED_MIPMAPS
{
GLenum intFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
int f;
GLenum format;
GLubyte *img = LoadRGBImage(files[i], &w, &h, &format);
GLboolean write_compressed = GL_FALSE;
GLboolean read_compressed = GL_FALSE;
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, intFormat, w, h, 0,
format, GL_UNSIGNED_BYTE, img);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
free(img);
glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
GL_TEXTURE_INTERNAL_FORMAT, &f);
printf("actual internal format 0x%x\n", f);
if (write_compressed) {
GLint i, sz, w, h;
int num_levels = 8;
for (i = 0; i < num_levels; i++) {
char name[20], *buf;
FILE *f;
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sz);
printf("Writing level %d: %d x %d bytes: %d\n", i, w, h, sz);
buf = malloc(sz);
glGetCompressedTexImageARB(GL_TEXTURE_2D, i, buf);
sprintf(name, "comp%d", i);
f = fopen(name, "w");
fwrite(buf, 1, sz, f);
fclose(f);
free(buf);
}
}
if (read_compressed) {
GLint i, sz, w, h;
int num_levels = 8;
for (i = 01; i < num_levels; i++) {
char name[20], *buf;
FILE *f;
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
glGetTexLevelParameteriv(GL_TEXTURE_2D, i,
GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &sz);
buf = malloc(sz);
sprintf(name, "comp%d", i);
printf("Reading level %d: %d x %d bytes: %d from %s\n",
i, w, h, sz, name);
f = fopen(name, "r");
fread(buf, 1, sz, f);
fclose(f);
glCompressedTexImage2DARB(GL_TEXTURE_2D, i, intFormat,
w, h, 0, sz, buf);
free(buf);
}
}
}
#else
if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) {
printf("Error: couldn't load %s\n", files[i]);
@ -360,6 +425,7 @@ main(int argc, char *argv[])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
Win = glutCreateWindow(argv[0]);
glewInit();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);

View file

@ -7,7 +7,10 @@ INCLUDES = \
-I$(TOP)/include \
$(X11_CFLAGS)
SOURCES = $(wildcard *.c)
SOURCES = \
eglut.c \
eglut_screen.c \
eglut_x11.c
EGLUT_X11_OBJECTS = eglut.o eglut_x11.o
EGLUT_SCREEN_OBJECTS = eglut.o eglut_screen.o

View file

@ -62,9 +62,6 @@ xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP)
xeglthreads: xeglthreads.o $(HEADERS) $(LIB_DEP)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lpthread -lm $(X11_LIBS)
$(EGLUT_DIR)/libeglut-x11.a $(EGLUT_DIR)/libeglut-screen.a:
@$(MAKE) -C $(EGLUT_DIR)
# define the rules for EGLUT demos
define eglut-demo-rule
$(1)_x11 $(1)_screen: $(1)_%: $(1).o $(EGLUT_DIR)/libeglut-%.a $(LIB_DEP)
@ -80,4 +77,3 @@ $(EGLUT_SCREEN_DEMOS):
clean:
-rm -f *.o *~
-rm -f $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS)
@$(MAKE) -C $(EGLUT_DIR) clean

View file

@ -81,9 +81,6 @@ two_win: two_win.o $(ES1_LIB_DEPS)
$(CC) $(CFLAGS) two_win.o $(ES1_LIBS) -o $@
$(EGLUT_DIR)/libeglut-x11.a $(EGLUT_DIR)/libeglut-screen.a:
@$(MAKE) -C $(EGLUT_DIR)
# define the rules for EGLUT demos
define eglut-demo-rule
$(1)_x11 $(1)_screen: $(1)_%: $(1).o $(EGLUT_DIR)/libeglut-%.a $(ES1_LIB_DEPS)
@ -100,4 +97,3 @@ $(EGLUT_SCREEN_DEMOS):
clean:
-rm -f *.o *~
-rm -f $(PROGRAMS) $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS)
@$(MAKE) -C $(EGLUT_DIR) clean

View file

@ -34,9 +34,6 @@ lion_screen: lion.o lion-render.o $(EGLUT_DIR)/libeglut-screen.a
-L$(EGLUT_DIR) -leglut-screen $(VG_LIBS)
$(EGLUT_DIR)/libeglut-x11.a $(EGLUT_DIR)/libeglut-screen.a:
@$(MAKE) -C $(EGLUT_DIR)
# define the rules for EGLUT demos
define eglut-demo-rule
$(1)_x11 $(1)_screen: $(1)_%: $(1).o $(EGLUT_DIR)/libeglut-%.a
@ -52,4 +49,3 @@ $(EGLUT_SCREEN_DEMOS):
clean:
rm -f *.o *~
rm -f $(EGLUT_X11_DEMOS) $(EGLUT_SCREEN_DEMOS)
@$(MAKE) -C $(EGLUT_DIR) clean

View file

@ -5,7 +5,7 @@ include $(TOP)/configs/current
INCDIR = $(TOP)/include
OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -l$(OSMESA_LIB) $(APP_LIB_DEPS)
OSMESA_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(OSMESA_LIB) $(APP_LIB_DEPS)
OSMESA16_LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -lOSMesa16 -l$(GLU_LIB) \
-l$(GL_LIB) $(APP_LIB_DEPS)

View file

@ -399,7 +399,11 @@ test(GLenum type, GLint bits, const char *filename)
/* sanity checks */
glGetIntegerv(GL_RED_BITS, &cBits);
assert(cBits == bits);
if (cBits != bits) {
fprintf(stderr, "Unable to create %d-bit/channel renderbuffer.\n", bits);
fprintf(stderr, "May need to recompile Mesa with CHAN_BITS=16 or 32.\n");
return 0;
}
glGetIntegerv(GL_GREEN_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_BLUE_BITS, &cBits);

View file

@ -249,7 +249,7 @@ static void require_extension(const char *ext)
static void Init(void)
{
const char *const ver_string = (const char *const) glGetString(GL_VERSION);
const char *const ver_string = (const char *) glGetString(GL_VERSION);
unsigned i;
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));

View file

@ -708,7 +708,8 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR);
if (dri2_dpy->fd == -1) {
_eglLog(_EGL_FATAL,
"DRI2: could not open %s (%s)", path, strerror(errno));
"DRI2: could not open %s (%s)", dri2_dpy->device_name,
strerror(errno));
goto cleanup_driver;
}

View file

@ -101,6 +101,7 @@ C_SOURCES = \
util/u_blit.c \
util/u_blitter.c \
util/u_cache.c \
util/u_caps.c \
util/u_cpu_detect.c \
util/u_dl.c \
util/u_draw_quad.c \

View file

@ -144,6 +144,7 @@ source = [
'util/u_blit.c',
'util/u_blitter.c',
'util/u_cache.c',
'util/u_caps.c',
'util/u_cpu_detect.c',
'util/u_debug.c',
'util/u_debug_memory.c',

View file

@ -314,10 +314,13 @@ void cso_release_all( struct cso_context *ctx )
}
/**
* Free the CSO context. NOTE: the state tracker should have previously called
* cso_release_all().
*/
void cso_destroy_context( struct cso_context *ctx )
{
if (ctx) {
/*cso_release_all( ctx );*/
FREE( ctx );
}
}

View file

@ -24,6 +24,8 @@
/* generates the draw jit function */
static void
draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *var);
static void
draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *var);
static void
init_globals(struct draw_llvm *llvm)
@ -218,6 +220,7 @@ draw_llvm_prepare(struct draw_llvm *llvm, int num_inputs)
llvm->vertex_header_ptr_type = create_vertex_header(llvm, num_inputs);
draw_llvm_generate(llvm, variant);
draw_llvm_generate_elts(llvm, variant);
return variant;
}
@ -696,6 +699,158 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
lp_disassemble(variant->jit_func);
}
static void
draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
{
LLVMTypeRef arg_types[7];
LLVMTypeRef func_type;
LLVMValueRef context_ptr;
LLVMBasicBlockRef block;
LLVMBuilderRef builder;
LLVMValueRef fetch_elts, fetch_count, stride, step, io_itr;
LLVMValueRef io_ptr, vbuffers_ptr, vb_ptr;
struct draw_context *draw = llvm->draw;
unsigned i, j;
struct lp_build_context bld;
struct lp_build_context bld_int;
struct lp_build_loop_state lp_loop;
struct lp_type vs_type = lp_type_float_vec(32);
const int max_vertices = 4;
LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
LLVMValueRef fetch_max;
arg_types[0] = llvm->context_ptr_type; /* context */
arg_types[1] = llvm->vertex_header_ptr_type; /* vertex_header */
arg_types[2] = llvm->buffer_ptr_type; /* vbuffers */
arg_types[3] = LLVMPointerType(LLVMInt32Type(), 0); /* fetch_elts * */
arg_types[4] = LLVMInt32Type(); /* fetch_count */
arg_types[5] = LLVMInt32Type(); /* stride */
arg_types[6] = llvm->vb_ptr_type; /* pipe_vertex_buffer's */
func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
variant->function_elts = LLVMAddFunction(llvm->module, "draw_llvm_shader_elts", func_type);
LLVMSetFunctionCallConv(variant->function_elts, LLVMCCallConv);
for(i = 0; i < Elements(arg_types); ++i)
if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
LLVMAddAttribute(LLVMGetParam(variant->function_elts, i), LLVMNoAliasAttribute);
context_ptr = LLVMGetParam(variant->function_elts, 0);
io_ptr = LLVMGetParam(variant->function_elts, 1);
vbuffers_ptr = LLVMGetParam(variant->function_elts, 2);
fetch_elts = LLVMGetParam(variant->function_elts, 3);
fetch_count = LLVMGetParam(variant->function_elts, 4);
stride = LLVMGetParam(variant->function_elts, 5);
vb_ptr = LLVMGetParam(variant->function_elts, 6);
lp_build_name(context_ptr, "context");
lp_build_name(io_ptr, "io");
lp_build_name(vbuffers_ptr, "vbuffers");
lp_build_name(fetch_elts, "fetch_elts");
lp_build_name(fetch_count, "fetch_count");
lp_build_name(stride, "stride");
lp_build_name(vb_ptr, "vb");
/*
* Function body
*/
block = LLVMAppendBasicBlock(variant->function_elts, "entry");
builder = LLVMCreateBuilder();
LLVMPositionBuilderAtEnd(builder, block);
lp_build_context_init(&bld, builder, vs_type);
lp_build_context_init(&bld_int, builder, lp_type_int(32));
step = LLVMConstInt(LLVMInt32Type(), max_vertices, 0);
fetch_max = LLVMBuildSub(builder, fetch_count,
LLVMConstInt(LLVMInt32Type(), 1, 0),
"fetch_max");
lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 0, 0), &lp_loop);
{
LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
LLVMValueRef aos_attribs[PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS] = { { 0 } };
LLVMValueRef io;
const LLVMValueRef (*ptr_aos)[NUM_CHANNELS];
io_itr = lp_loop.counter;
io = LLVMBuildGEP(builder, io_ptr, &io_itr, 1, "");
#if DEBUG_STORE
lp_build_printf(builder, " --- io %d = %p, loop counter %d\n",
io_itr, io, lp_loop.counter);
#endif
for (i = 0; i < NUM_CHANNELS; ++i) {
LLVMValueRef true_index = LLVMBuildAdd(
builder,
lp_loop.counter,
LLVMConstInt(LLVMInt32Type(), i, 0), "");
LLVMValueRef fetch_ptr;
/* make sure we're not out of bounds which can happen
* if fetch_count % 4 != 0, because on the last iteration
* a few of the 4 vertex fetches will be out of bounds */
true_index = lp_build_min(&bld_int, true_index, fetch_max);
fetch_ptr = LLVMBuildGEP(builder, fetch_elts,
&true_index, 1, "");
true_index = LLVMBuildLoad(builder, fetch_ptr, "fetch_elt");
for (j = 0; j < draw->pt.nr_vertex_elements; ++j) {
struct pipe_vertex_element *velem = &draw->pt.vertex_element[j];
LLVMValueRef vb_index = LLVMConstInt(LLVMInt32Type(),
velem->vertex_buffer_index,
0);
LLVMValueRef vb = LLVMBuildGEP(builder, vb_ptr,
&vb_index, 1, "");
generate_fetch(builder, vbuffers_ptr,
&aos_attribs[j][i], velem, vb, true_index);
}
}
convert_to_soa(builder, aos_attribs, inputs,
draw->pt.nr_vertex_elements);
ptr_aos = (const LLVMValueRef (*)[NUM_CHANNELS]) inputs;
generate_vs(llvm,
builder,
outputs,
ptr_aos,
context_ptr);
convert_to_aos(builder, io, outputs,
draw->vs.vertex_shader->info.num_outputs,
max_vertices);
}
lp_build_loop_end_cond(builder, fetch_count, step, LLVMIntUGE, &lp_loop);
LLVMBuildRetVoid(builder);
LLVMDisposeBuilder(builder);
/*
* Translate the LLVM IR into machine code.
*/
#ifdef DEBUG
if(LLVMVerifyFunction(variant->function_elts, LLVMPrintMessageAction)) {
LLVMDumpValue(variant->function_elts);
assert(0);
}
#endif
LLVMRunFunctionPassManager(llvm->pass, variant->function_elts);
if (0) {
LLVMDumpValue(variant->function_elts);
debug_printf("\n");
}
variant->jit_func_elts = (draw_jit_vert_func_elts)LLVMGetPointerToGlobal(
llvm->draw->engine, variant->function_elts);
if (0)
lp_disassemble(variant->jit_func_elts);
}
void
draw_llvm_make_variant_key(struct draw_llvm *llvm,
struct draw_llvm_variant_key *key)

View file

@ -94,6 +94,16 @@ typedef void
unsigned stride,
struct pipe_vertex_buffer *vertex_buffers);
typedef void
(*draw_jit_vert_func_elts)(struct draw_jit_context *context,
struct vertex_header *io,
const char *vbuffers[PIPE_MAX_ATTRIBS],
const unsigned *fetch_elts,
unsigned fetch_count,
unsigned stride,
struct pipe_vertex_buffer *vertex_buffers);
struct draw_llvm {
struct draw_context *draw;
@ -122,7 +132,9 @@ struct draw_llvm_variant
{
struct draw_llvm_variant_key key;
LLVMValueRef function;
LLVMValueRef function_elts;
draw_jit_vert_func jit_func;
draw_jit_vert_func_elts jit_func_elts;
struct draw_llvm_variant *next;
};

View file

@ -38,10 +38,10 @@
#include "util/u_prim.h"
DEBUG_GET_ONCE_BOOL_OPTION(draw_fse, "DRAW_FSE", FALSE);
DEBUG_GET_ONCE_BOOL_OPTION(draw_no_fse, "DRAW_NO_FSE", FALSE);
DEBUG_GET_ONCE_BOOL_OPTION(draw_fse, "DRAW_FSE", FALSE)
DEBUG_GET_ONCE_BOOL_OPTION(draw_no_fse, "DRAW_NO_FSE", FALSE)
#ifdef HAVE_LLVM
DEBUG_GET_ONCE_BOOL_OPTION(draw_use_llvm, "DRAW_USE_LLVM", TRUE);
DEBUG_GET_ONCE_BOOL_OPTION(draw_use_llvm, "DRAW_USE_LLVM", TRUE)
#endif
static unsigned trim( unsigned count, unsigned first, unsigned incr )

View file

@ -167,8 +167,6 @@ static void llvm_middle_end_run( struct draw_pt_middle_end *middle,
{
struct llvm_middle_end *fpme = (struct llvm_middle_end *)middle;
struct draw_context *draw = fpme->draw;
struct draw_vertex_shader *vshader = draw->vs.vertex_shader;
struct draw_geometry_shader *gshader = draw->gs.geometry_shader;
unsigned opt = fpme->opt;
unsigned alloc_count = align( fetch_count, 4 );
@ -182,35 +180,13 @@ static void llvm_middle_end_run( struct draw_pt_middle_end *middle,
return;
}
/* Fetch into our vertex buffer
*/
draw_pt_fetch_run( fpme->fetch,
fetch_elts,
fetch_count,
(char *)pipeline_verts );
/* Run the shader, note that this overwrites the data[] parts of
* the pipeline verts. If there is no shader, eg if
* bypass_vs_clip_and_viewport, then the inputs == outputs, and are
* already in the correct place.*/
if (opt & PT_SHADE)
{
vshader->run_linear(vshader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
draw->pt.user.vs_constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
if (gshader)
draw_geometry_shader_run(gshader,
(const float (*)[4])pipeline_verts->data,
( float (*)[4])pipeline_verts->data,
draw->pt.user.gs_constants,
fetch_count,
fpme->vertex_size,
fpme->vertex_size);
}
fpme->current_variant->jit_func_elts( &fpme->llvm->jit_context,
pipeline_verts,
(const char **)draw->pt.user.vbuffer,
fetch_elts,
fetch_count,
fpme->vertex_size,
draw->pt.vertex_buffer );
if (draw_pt_post_vs_run( fpme->post_vs,
pipeline_verts,

View file

@ -46,7 +46,7 @@
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_exec.h"
DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE);
DEBUG_GET_ONCE_BOOL_OPTION(gallium_dump_vs, "GALLIUM_DUMP_VS", FALSE)
void
draw_vs_set_constants(struct draw_context *draw,

View file

@ -169,8 +169,9 @@ draw_create_vs_ppc(struct draw_context *draw,
struct draw_vs_varient_key;
struct draw_vertex_shader;
struct draw_vs_varient *draw_vs_varient_aos_sse( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key );
struct draw_vs_varient *
draw_vs_create_varient_aos_sse( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key );
@ -188,8 +189,9 @@ struct translate *draw_vs_get_fetch( struct draw_context *draw,
struct translate *draw_vs_get_emit( struct draw_context *draw,
struct translate_key *key );
struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key );
struct draw_vs_varient *
draw_vs_create_varient_generic( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key );

View file

@ -2089,13 +2089,21 @@ static boolean build_vertex_program( struct draw_vs_varient_aos_sse *varient,
}
/** cast wrapper */
static INLINE struct draw_vs_varient_aos_sse *
draw_vs_varient_aos_sse(struct draw_vs_varient *varient)
{
return (struct draw_vs_varient_aos_sse *) varient;
}
static void vaos_set_buffer( struct draw_vs_varient *varient,
unsigned buf,
const void *ptr,
unsigned stride )
unsigned stride,
unsigned max_stride)
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct draw_vs_varient_aos_sse *vaos = draw_vs_varient_aos_sse(varient);
if (buf < vaos->nr_vb) {
vaos->buffer[buf].base_ptr = (char *)ptr;
@ -2112,7 +2120,7 @@ static void PIPE_CDECL vaos_run_elts( struct draw_vs_varient *varient,
unsigned count,
void *output_buffer )
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct draw_vs_varient_aos_sse *vaos = draw_vs_varient_aos_sse(varient);
struct aos_machine *machine = vaos->draw->vs.aos_machine;
unsigned i;
@ -2136,7 +2144,7 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient,
unsigned count,
void *output_buffer )
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct draw_vs_varient_aos_sse *vaos = draw_vs_varient_aos_sse(varient);
struct aos_machine *machine = vaos->draw->vs.aos_machine;
unsigned i;
@ -2165,7 +2173,7 @@ static void PIPE_CDECL vaos_run_linear( struct draw_vs_varient *varient,
static void vaos_destroy( struct draw_vs_varient *varient )
{
struct draw_vs_varient_aos_sse *vaos = (struct draw_vs_varient_aos_sse *)varient;
struct draw_vs_varient_aos_sse *vaos = draw_vs_varient_aos_sse(varient);
FREE( vaos->buffer );
@ -2241,13 +2249,14 @@ static struct draw_vs_varient *varient_aos_sse( struct draw_vertex_shader *vs,
}
struct draw_vs_varient *draw_vs_varient_aos_sse( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key )
struct draw_vs_varient *
draw_vs_create_varient_aos_sse( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key )
{
struct draw_vs_varient *varient = varient_aos_sse( vs, key );
if (varient == NULL) {
varient = draw_vs_varient_generic( vs, key );
varient = draw_vs_create_varient_generic( vs, key );
}
return varient;

View file

@ -203,7 +203,7 @@ draw_create_vs_exec(struct draw_context *draw,
vs->base.prepare = vs_exec_prepare;
vs->base.run_linear = vs_exec_run_linear;
vs->base.delete = vs_exec_delete;
vs->base.create_varient = draw_vs_varient_generic;
vs->base.create_varient = draw_vs_create_varient_generic;
vs->machine = draw->vs.machine;
return &vs->base;

View file

@ -125,7 +125,7 @@ vs_ppc_run_linear( struct draw_vertex_shader *base,
*/
shader->func(inputs_soa, outputs_soa, temps_soa,
(float (*)[4]) shader->base.immediates,
(const float (*)[4])constants[0],
(float (*)[4])constants[0],
ppc_builtin_constants);
/* convert (up to) four output verts from SoA back to AoS format */
@ -190,7 +190,7 @@ draw_create_vs_ppc(struct draw_context *draw,
vs->base.create_varient = draw_vs_varient_aos_ppc;
else
#endif
vs->base.create_varient = draw_vs_varient_generic;
vs->base.create_varient = draw_vs_create_varient_generic;
vs->base.prepare = vs_ppc_prepare;
vs->base.run_linear = vs_ppc_run_linear;
vs->base.delete = vs_ppc_delete;

View file

@ -165,9 +165,9 @@ draw_create_vs_sse(struct draw_context *draw,
vs->base.draw = draw;
if (1)
vs->base.create_varient = draw_vs_varient_aos_sse;
vs->base.create_varient = draw_vs_create_varient_aos_sse;
else
vs->base.create_varient = draw_vs_varient_generic;
vs->base.create_varient = draw_vs_create_varient_generic;
vs->base.prepare = vs_sse_prepare;
vs->base.run_linear = vs_sse_run_linear;
vs->base.delete = vs_sse_delete;

View file

@ -263,8 +263,9 @@ static void vsvg_destroy( struct draw_vs_varient *varient )
}
struct draw_vs_varient *draw_vs_varient_generic( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key )
struct draw_vs_varient *
draw_vs_create_varient_generic( struct draw_vertex_shader *vs,
const struct draw_vs_varient_key *key )
{
unsigned i;
struct translate_key fetch, emit;

View file

@ -1210,6 +1210,14 @@ LLVMValueRef
lp_build_cos(struct lp_build_context *bld,
LLVMValueRef a)
{
#ifdef PIPE_OS_WINDOWS
/*
* FIXME: X86 backend translates llvm.cos.v4f32 to 4 calls to CRT's cosf()
* which is neither efficient nor does the CRT linkage work on Windows
* causing segmentation fault. So simply disable the code for now.
*/
return bld->one;
#else
const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
char intrinsic[32];
@ -1220,6 +1228,7 @@ lp_build_cos(struct lp_build_context *bld,
util_snprintf(intrinsic, sizeof intrinsic, "llvm.cos.v%uf%u", type.length, type.width);
return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a);
#endif
}
@ -1230,6 +1239,14 @@ LLVMValueRef
lp_build_sin(struct lp_build_context *bld,
LLVMValueRef a)
{
#ifdef PIPE_OS_WINDOWS
/*
* FIXME: X86 backend translates llvm.sin.v4f32 to 4 calls to CRT's sinf()
* which is neither efficient nor does the CRT linkage work on Windows
* causing segmentation fault. So simply disable the code for now.
*/
return bld->zero;
#else
const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
char intrinsic[32];
@ -1240,6 +1257,7 @@ lp_build_sin(struct lp_build_context *bld,
util_snprintf(intrinsic, sizeof intrinsic, "llvm.sin.v%uf%u", type.length, type.width);
return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a);
#endif
}

View file

@ -792,3 +792,78 @@ lp_build_endif(struct lp_build_if_state *ctx)
/* Resume building code at end of the ifthen->merge_block */
LLVMPositionBuilderAtEnd(ctx->builder, ifthen->merge_block);
}
/**
* Allocate a scalar (or vector) variable.
*
* Although not strictly part of control flow, control flow has deep impact in
* how variables should be allocated.
*
* The mem2reg optimization pass is the recommended way to dealing with mutable
* variables, and SSA. It looks for allocas and if it can handle them, it
* promotes them, but only looks for alloca instructions in the entry block of
* the function. Being in the entry block guarantees that the alloca is only
* executed once, which makes analysis simpler.
*
* See also:
* - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
*/
LLVMValueRef
lp_build_alloca(LLVMBuilderRef builder,
LLVMTypeRef type,
const char *name)
{
LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
LLVMBuilderRef first_builder = LLVMCreateBuilder();
LLVMValueRef res;
LLVMPositionBuilderAtEnd(first_builder, first_block);
LLVMPositionBuilderBefore(first_builder, first_instr);
res = LLVMBuildAlloca(first_builder, type, name);
LLVMDisposeBuilder(first_builder);
return res;
}
/**
* Allocate an array of scalars/vectors.
*
* mem2reg pass is not capable of promoting structs or arrays to registers, but
* we still put it in the first block anyway as failure to put allocas in the
* first block may prevent the X86 backend from successfully align the stack as
* required.
*
* Also the scalarrepl pass is supossedly more powerful and can promote
* arrays in many cases.
*
* See also:
* - http://www.llvm.org/docs/tutorial/OCamlLangImpl7.html#memory
*/
LLVMValueRef
lp_build_array_alloca(LLVMBuilderRef builder,
LLVMTypeRef type,
LLVMValueRef count,
const char *name)
{
LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
LLVMBasicBlockRef first_block = LLVMGetEntryBasicBlock(function);
LLVMValueRef first_instr = LLVMGetFirstInstruction(first_block);
LLVMBuilderRef first_builder = LLVMCreateBuilder();
LLVMValueRef res;
LLVMPositionBuilderBefore(first_builder, first_instr);
res = LLVMBuildArrayAlloca(first_builder, type, count, name);
LLVMDisposeBuilder(first_builder);
return res;
}

View file

@ -156,5 +156,15 @@ lp_build_endif(struct lp_build_if_state *ctx);
LLVMBasicBlockRef
lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);
LLVMValueRef
lp_build_alloca(LLVMBuilderRef builder,
LLVMTypeRef type,
const char *name);
LLVMValueRef
lp_build_array_alloca(LLVMBuilderRef builder,
LLVMTypeRef type,
LLVMValueRef count,
const char *name);
#endif /* !LP_BLD_FLOW_H */

View file

@ -40,6 +40,7 @@
#include "lp_bld_init.h"
#include "lp_bld_type.h"
#include "lp_bld_flow.h"
#include "lp_bld_format.h"
@ -370,11 +371,7 @@ lp_build_fetch_rgba_aos(LLVMBuilderRef builder,
LLVMAddGlobalMapping(lp_build_engine, function, format_desc->fetch_rgba_float);
}
/*
* XXX: this should better go to the first block in the function
*/
tmp = LLVMBuildAlloca(builder, LLVMVectorType(LLVMFloatType(), 4), "");
tmp = lp_build_alloca(builder, LLVMVectorType(LLVMFloatType(), 4), "");
/*
* Invoke format_desc->fetch_rgba_float() for each pixel and insert the result

View file

@ -472,18 +472,6 @@ lp_build_select_aos(struct lp_build_context *bld,
}
}
LLVMValueRef
lp_build_alloca(struct lp_build_context *bld)
{
const struct lp_type type = bld->type;
if (type.length > 1) { /*vector*/
return LLVMBuildAlloca(bld->builder, lp_build_vec_type(type), "");
} else { /*scalar*/
return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), "");
}
}
/** Return (a & ~b) */
LLVMValueRef

View file

@ -76,9 +76,6 @@ lp_build_select_aos(struct lp_build_context *bld,
LLVMValueRef b,
const boolean cond[4]);
LLVMValueRef
lp_build_alloca(struct lp_build_context *bld);
LLVMValueRef
lp_build_andc(struct lp_build_context *bld, LLVMValueRef a, LLVMValueRef b);

View file

@ -1830,6 +1830,11 @@ lp_build_sample_2d_linear_aos(struct lp_build_sample_context *bld,
LLVMValueRef unswizzled[4];
LLVMValueRef stride;
assert(bld->static_state->target == PIPE_TEXTURE_2D);
assert(bld->static_state->min_img_filter == PIPE_TEX_FILTER_LINEAR);
assert(bld->static_state->mag_img_filter == PIPE_TEX_FILTER_LINEAR);
assert(bld->static_state->min_mip_filter == PIPE_TEX_MIPFILTER_NONE);
lp_build_context_init(&i32, builder, lp_type_int_vec(32));
lp_build_context_init(&h16, builder, lp_type_ufixed(16));
lp_build_context_init(&u8n, builder, lp_type_unorm(8));

View file

@ -744,22 +744,11 @@ emit_declaration(
struct lp_build_tgsi_soa_context *bld,
const struct tgsi_full_declaration *decl)
{
LLVMTypeRef vec_type = lp_build_vec_type(bld->base.type);
unsigned first = decl->Range.First;
unsigned last = decl->Range.Last;
unsigned idx, i;
LLVMBasicBlockRef current_block =
LLVMGetInsertBlock(bld->base.builder);
LLVMBasicBlockRef first_block =
LLVMGetEntryBasicBlock(
LLVMGetBasicBlockParent(current_block));
LLVMValueRef first_inst =
LLVMGetFirstInstruction(first_block);
/* we want alloca's to be the first instruction
* in the function so we need to rewind the builder
* to the very beginning */
LLVMPositionBuilderBefore(bld->base.builder,
first_inst);
for (idx = first; idx <= last; ++idx) {
switch (decl->Declaration.File) {
@ -767,23 +756,25 @@ emit_declaration(
if (bld->has_indirect_addressing) {
LLVMValueRef val = LLVMConstInt(LLVMInt32Type(),
last*4 + 4, 0);
bld->temps_array = LLVMBuildArrayAlloca(bld->base.builder,
lp_build_vec_type(bld->base.type),
val, "");
bld->temps_array = lp_build_array_alloca(bld->base.builder,
vec_type, val, "");
} else {
for (i = 0; i < NUM_CHANNELS; i++)
bld->temps[idx][i] = lp_build_alloca(&bld->base);
bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
vec_type, "");
}
break;
case TGSI_FILE_OUTPUT:
for (i = 0; i < NUM_CHANNELS; i++)
bld->outputs[idx][i] = lp_build_alloca(&bld->base);
bld->outputs[idx][i] = lp_build_alloca(bld->base.builder,
vec_type, "");
break;
case TGSI_FILE_ADDRESS:
for (i = 0; i < NUM_CHANNELS; i++)
bld->addr[idx][i] = lp_build_alloca(&bld->base);
bld->addr[idx][i] = lp_build_alloca(bld->base.builder,
vec_type, "");
break;
default:
@ -792,8 +783,6 @@ emit_declaration(
}
}
LLVMPositionBuilderAtEnd(bld->base.builder,
current_block);
return TRUE;
}
@ -1600,18 +1589,10 @@ emit_instruction(
lp_exec_mask_cond_push(&bld->exec_mask, tmp0);
break;
case TGSI_OPCODE_BGNFOR:
/* fall through */
case TGSI_OPCODE_BGNLOOP:
lp_exec_bgnloop(&bld->exec_mask);
break;
case TGSI_OPCODE_REP:
/* deprecated */
assert(0);
return FALSE;
break;
case TGSI_OPCODE_ELSE:
lp_exec_mask_cond_invert(&bld->exec_mask);
break;
@ -1620,18 +1601,10 @@ emit_instruction(
lp_exec_mask_cond_pop(&bld->exec_mask);
break;
case TGSI_OPCODE_ENDFOR:
/* fall-through */
case TGSI_OPCODE_ENDLOOP:
lp_exec_endloop(&bld->exec_mask);
break;
case TGSI_OPCODE_ENDREP:
/* deprecated */
assert(0);
return FALSE;
break;
case TGSI_OPCODE_PUSHA:
/* deprecated? */
assert(0);

View file

@ -661,25 +661,6 @@ TGSI Instruction Specification
TBD
1.9.8 BGNFOR - Begin a For-Loop
dst.x = floor(src.x)
dst.y = floor(src.y)
dst.z = floor(src.z)
if (dst.y <= 0)
pc = [matching ENDFOR] + 1
endif
Note: The destination must be a loop register.
The source must be a constant register.
1.9.9 REP - Repeat
TBD
1.9.10 ELSE - Else
TBD
@ -690,23 +671,6 @@ TGSI Instruction Specification
TBD
1.9.12 ENDFOR - End a For-Loop
dst.x = dst.x + dst.z
dst.y = dst.y - 1.0
if (dst.y > 0)
pc = [matching BGNFOR instruction] + 1
endif
Note: The destination must be a loop register.
1.9.13 ENDREP - End Repeat
TBD
1.10 GL_NV_vertex_program3
---------------------------

View file

@ -586,7 +586,6 @@ iter_instruction(
/* update indentation */
if (inst->Instruction.Opcode == TGSI_OPCODE_IF ||
inst->Instruction.Opcode == TGSI_OPCODE_ELSE ||
inst->Instruction.Opcode == TGSI_OPCODE_BGNFOR ||
inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) {
ctx->indentation += indent_spaces;
}

View file

@ -3186,14 +3186,6 @@ exec_instruction(
*pc = -1;
break;
case TGSI_OPCODE_REP:
assert (0);
break;
case TGSI_OPCODE_ENDREP:
assert (0);
break;
case TGSI_OPCODE_PUSHA:
assert (0);
break;
@ -3258,29 +3250,6 @@ exec_instruction(
emit_primitive(mach);
break;
case TGSI_OPCODE_BGNFOR:
assert(mach->LoopCounterStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
for (chan_index = 0; chan_index < 3; chan_index++) {
FETCH( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[chan_index], 0, chan_index );
}
++mach->LoopCounterStackTop;
STORE(&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X], 0, CHAN_X);
/* update LoopMask */
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[0] <= 0.0f) {
mach->LoopMask &= ~0x1;
}
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[1] <= 0.0f) {
mach->LoopMask &= ~0x2;
}
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[2] <= 0.0f) {
mach->LoopMask &= ~0x4;
}
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[3] <= 0.0f) {
mach->LoopMask &= ~0x8;
}
/* TODO: if mach->LoopMask == 0, jump to end of loop */
UPDATE_EXEC_MASK(mach);
/* fall-through (for now) */
case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
@ -3295,56 +3264,6 @@ exec_instruction(
mach->BreakType = TGSI_EXEC_BREAK_INSIDE_LOOP;
break;
case TGSI_OPCODE_ENDFOR:
assert(mach->LoopCounterStackTop > 0);
micro_sub(&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
&mach->Temps[TEMP_1_I].xyzw[TEMP_1_C]);
/* update LoopMask */
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[0] <= 0.0f) {
mach->LoopMask &= ~0x1;
}
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[1] <= 0.0f) {
mach->LoopMask &= ~0x2;
}
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[2] <= 0.0f) {
mach->LoopMask &= ~0x4;
}
if (mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y].f[3] <= 0.0f) {
mach->LoopMask &= ~0x8;
}
micro_add(&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
&mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Z]);
assert(mach->LoopLabelStackTop > 0);
inst = mach->Instructions + mach->LoopLabelStack[mach->LoopLabelStackTop - 1];
STORE(&mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_X], 0, CHAN_X);
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
UPDATE_EXEC_MASK(mach);
if (mach->ExecMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
assert(mach->LoopLabelStackTop > 0);
*pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
}
else {
/* exit loop: pop LoopMask */
assert(mach->LoopStackTop > 0);
mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
/* pop ContMask */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop];
assert(mach->LoopLabelStackTop > 0);
--mach->LoopLabelStackTop;
assert(mach->LoopCounterStackTop > 0);
--mach->LoopCounterStackTop;
mach->BreakType = mach->BreakStack[--mach->BreakStackTop];
}
UPDATE_EXEC_MASK(mach);
break;
case TGSI_OPCODE_ENDLOOP:
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);

View file

@ -106,12 +106,12 @@ static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{ 1, 2, 1, 0, 0, 0, "TXL", TGSI_OPCODE_TXL },
{ 0, 0, 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
{ 0, 1, 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
{ 1, 1, 0, 0, 0, 1, "BGNFOR", TGSI_OPCODE_BGNFOR },
{ 0, 1, 0, 0, 0, 1, "REP", TGSI_OPCODE_REP },
{ 1, 1, 0, 0, 0, 1, "", 75 }, /* removed */
{ 0, 1, 0, 0, 0, 1, "", 76 }, /* removed */
{ 0, 0, 0, 1, 1, 1, "ELSE", TGSI_OPCODE_ELSE },
{ 0, 0, 0, 0, 1, 0, "ENDIF", TGSI_OPCODE_ENDIF },
{ 1, 0, 0, 0, 1, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
{ 0, 0, 0, 0, 1, 0, "ENDREP", TGSI_OPCODE_ENDREP },
{ 1, 0, 0, 0, 1, 0, "", 79 }, /* removed */
{ 0, 0, 0, 0, 1, 0, "", 80 }, /* removed */
{ 0, 1, 0, 0, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
{ 1, 0, 0, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
{ 1, 1, 0, 0, 0, 0, "CEIL", TGSI_OPCODE_CEIL },

View file

@ -111,12 +111,8 @@ OP12(DP2)
OP12_TEX(TXL)
OP00(BRK)
OP01_LBL(IF)
OP11(BGNFOR)
OP01(REP)
OP00_LBL(ELSE)
OP00(ENDIF)
OP10(ENDFOR)
OP00(ENDREP)
OP01(PUSHA)
OP10(POPA)
OP11(CEIL)

View file

@ -346,25 +346,6 @@ iter_instruction(
}
}
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_BGNFOR:
case TGSI_OPCODE_ENDFOR:
if (inst->Dst[0].Register.File != TGSI_FILE_LOOP ||
inst->Dst[0].Register.Index != 0) {
report_error(ctx, "Destination register must be LOOP[0]");
}
break;
}
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_BGNFOR:
if (inst->Src[0].Register.File != TGSI_FILE_CONSTANT &&
inst->Src[0].Register.File != TGSI_FILE_IMMEDIATE) {
report_error(ctx, "Source register file must be either CONST or IMM");
}
break;
}
ctx->num_instructions++;
return TRUE;

View file

@ -2533,14 +2533,6 @@ emit_instruction(
return 0;
break;
case TGSI_OPCODE_BGNFOR:
return 0;
break;
case TGSI_OPCODE_REP:
return 0;
break;
case TGSI_OPCODE_ELSE:
return 0;
break;
@ -2549,14 +2541,6 @@ emit_instruction(
return 0;
break;
case TGSI_OPCODE_ENDFOR:
return 0;
break;
case TGSI_OPCODE_ENDREP:
return 0;
break;
case TGSI_OPCODE_PUSHA:
return 0;
break;

View file

@ -0,0 +1,244 @@
/**************************************************************************
*
* Copyright 2010 Vmware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include "pipe/p_screen.h"
#include "util/u_format.h"
#include "util/u_debug.h"
#include "u_caps.h"
/**
* Iterates over a list of caps checks as defined in u_caps.h. Should
* all checks pass returns TRUE and out is set to the last element of
* the list (TERMINATE). Should any check fail returns FALSE and set
* out to the index of the start of the first failing check.
*/
boolean
util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out)
{
int i, tmpi;
float tmpf;
for (i = 0; list[i];) {
switch(list[i++]) {
case UTIL_CAPS_CHECK_CAP:
if (!screen->get_param(screen, list[i++])) {
*out = i - 2;
return FALSE;
}
break;
case UTIL_CAPS_CHECK_INT:
tmpi = screen->get_param(screen, list[i++]);
if (tmpi < (int)list[i++]) {
*out = i - 3;
return FALSE;
}
break;
case UTIL_CAPS_CHECK_FLOAT:
tmpf = screen->get_paramf(screen, list[i++]);
if (tmpf < (float)list[i++]) {
*out = i - 3;
return FALSE;
}
break;
case UTIL_CAPS_CHECK_FORMAT:
if (!screen->is_format_supported(screen,
list[i++],
PIPE_TEXTURE_2D,
PIPE_BIND_SAMPLER_VIEW,
0)) {
*out = i - 2;
return FALSE;
}
case UTIL_CAPS_CHECK_UNIMPLEMENTED:
*out = i - 1;
return FALSE;
default:
assert(!"Unsupported check");
return FALSE;
}
}
*out = i;
return TRUE;
}
/**
* Iterates over a list of caps checks as defined in u_caps.h.
* Returns TRUE if all caps checks pass returns FALSE otherwise.
*/
boolean
util_check_caps(struct pipe_screen *screen, const unsigned *list)
{
int out;
return util_check_caps_out(screen, list, &out);
}
/*
* Below follows some demo lists.
*
* None of these lists are exhausting lists of what is
* actually needed to support said API and more here for
* as example on how to uses the above functions. Especially
* for DX10 and DX11 where Gallium is missing features.
*/
/* DX 9_1 */
static unsigned caps_dx_9_1[] = {
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1),
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 2),
UTIL_CHECK_TERMINATE
};
/* DX 9_2 */
static unsigned caps_dx_9_2[] = {
UTIL_CHECK_CAP(OCCLUSION_QUERY),
UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE),
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1),
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16),
UTIL_CHECK_TERMINATE
};
/* DX 9_3 */
static unsigned caps_dx_9_3[] = {
UTIL_CHECK_CAP(SM3),
//UTIL_CHECK_CAP(INSTANCING),
UTIL_CHECK_CAP(OCCLUSION_QUERY),
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4),
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), /* 4096 */
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16),
UTIL_CHECK_TERMINATE
};
/* DX 10 */
static unsigned caps_dx_10[] = {
UTIL_CHECK_CAP(SM3),
//UTIL_CHECK_CAP(INSTANCING),
UTIL_CHECK_CAP(OCCLUSION_QUERY),
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8),
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 8192 */
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 8192 */
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16),
UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */
UTIL_CHECK_TERMINATE
};
/* DX11 */
static unsigned caps_dx_11[] = {
UTIL_CHECK_CAP(SM3),
//UTIL_CHECK_CAP(INSTANCING),
UTIL_CHECK_CAP(OCCLUSION_QUERY),
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8),
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 16384 */
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 16384 */
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16),
UTIL_CHECK_FORMAT(B8G8R8A8_UNORM),
UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */
UTIL_CHECK_TERMINATE
};
/* OpenGL 2.1 */
static unsigned caps_opengl_2_1[] = {
UTIL_CHECK_CAP(GLSL),
UTIL_CHECK_CAP(OCCLUSION_QUERY),
UTIL_CHECK_CAP(TWO_SIDED_STENCIL),
UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE),
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 2),
UTIL_CHECK_TERMINATE
};
/* OpenGL 3.0 */
/* UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), */
/**
* Demo function which checks against theoretical caps needed for different APIs.
*/
void util_caps_demo_print(struct pipe_screen *screen)
{
struct {
char* name;
unsigned *list;
} list[] = {
{"DX 9.1", caps_dx_9_1},
{"DX 9.2", caps_dx_9_2},
{"DX 9.3", caps_dx_9_3},
{"DX 10", caps_dx_10},
{"DX 11", caps_dx_11},
{"OpenGL 2.1", caps_opengl_2_1},
/* {"OpenGL 3.0", caps_opengl_3_0},*/
{NULL, NULL}
};
int i, out = 0;
for (i = 0; list[i].name; i++) {
if (util_check_caps_out(screen, list[i].list, &out)) {
debug_printf("%s: %s yes\n", __FUNCTION__, list[i].name);
continue;
}
switch (list[i].list[out]) {
case UTIL_CAPS_CHECK_CAP:
debug_printf("%s: %s no (cap %u not supported)\n", __FUNCTION__,
list[i].name,
list[i].list[out + 1]);
break;
case UTIL_CAPS_CHECK_INT:
debug_printf("%s: %s no (cap %u less then %u)\n", __FUNCTION__,
list[i].name,
list[i].list[out + 1],
list[i].list[out + 2]);
break;
case UTIL_CAPS_CHECK_FLOAT:
debug_printf("%s: %s no (cap %u less then %f)\n", __FUNCTION__,
list[i].name,
list[i].list[out + 1],
(double)(int)list[i].list[out + 2]);
break;
case UTIL_CAPS_CHECK_FORMAT:
debug_printf("%s: %s no (format %s not supported)\n", __FUNCTION__,
list[i].name,
util_format_name(list[i].list[out + 1]) + 12);
break;
case UTIL_CAPS_CHECK_UNIMPLEMENTED:
debug_printf("%s: %s no (not implemented in gallium or state tracker)\n",
__FUNCTION__, list[i].name);
break;
default:
assert(!"Unsupported check");
}
}
}

View file

@ -0,0 +1,67 @@
/**************************************************************************
*
* Copyright 2010 Vmware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef U_CAPS_H
#define U_CAPS_H
#include "pipe/p_compiler.h"
struct pipe_screen;
enum u_caps_check_enum {
UTIL_CAPS_CHECK_TERMINATE = 0,
UTIL_CAPS_CHECK_CAP,
UTIL_CAPS_CHECK_INT,
UTIL_CAPS_CHECK_FLOAT,
UTIL_CAPS_CHECK_FORMAT,
UTIL_CAPS_CHECK_UNIMPLEMENTED,
};
#define UTIL_CHECK_CAP(cap) \
UTIL_CAPS_CHECK_CAP, PIPE_CAP_##cap
#define UTIL_CHECK_INT(cap, higher) \
UTIL_CAPS_CHECK_INT, PIPE_CAP_##cap, (unsigned)(higher)
/* Floats currently lose precision */
#define UTIL_CHECK_FLOAT(cap, higher) \
UTIL_CAPS_CHECK_FLOAT, PIPE_CAP_##cap, (unsigned)(int)(higher)
#define UTIL_CHECK_FORMAT(format) \
UTIL_CAPS_CHECK_FORMAT, PIPE_FORMAT_##format
#define UTIL_CHECK_UNIMPLEMENTED \
UTIL_CAPS_CHECK_UNIMPLEMENTED
#define UTIL_CHECK_TERMINATE \
UTIL_CAPS_CHECK_TERMINATE
boolean util_check_caps(struct pipe_screen *screen, const unsigned *list);
boolean util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out);
void util_caps_demo_print(struct pipe_screen *screen);
#endif

View file

@ -656,12 +656,12 @@ util_dump_transfer(struct os_stream *stream, const struct pipe_transfer *state)
util_dump_struct_begin(stream, "pipe_transfer");
util_dump_member(stream, ptr, state, resource);
// util_dump_member(stream, uint, state, box);
/*util_dump_member(stream, uint, state, box);*/
util_dump_member(stream, uint, state, stride);
util_dump_member(stream, uint, state, slice_stride);
// util_dump_member(stream, ptr, state, data);
/*util_dump_member(stream, ptr, state, data);*/
util_dump_struct_end(stream);
}

View file

@ -332,7 +332,7 @@ util_format_name(enum pipe_format format)
assert(desc);
if (!desc) {
return "???";
return "PIPE_FORMAT_???";
}
return desc->name;

View file

@ -240,13 +240,14 @@ util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
util_format_dxtn_fetch_t fetch,
unsigned block_size)
{
const unsigned bw = 4, bh = 4, comps = 4;
unsigned x, y, i, j;
for(y = 0; y < height; y += 4) {
for(y = 0; y < height; y += bh) {
const uint8_t *src = src_row;
for(x = 0; x < width; x += 4) {
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4;
for(x = 0; x < width; x += bw) {
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps;
fetch(0, src, i, j, dst);
}
}
@ -379,212 +380,197 @@ util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride,
void
util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
const uint8_t *src_row, unsigned src_stride,
const uint8_t *src, unsigned src_stride,
unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, bytes_per_block = 8;
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const uint8_t *src = src_row;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][3];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(x = 0; x < width; x += bw) {
uint8_t tmp[4][4][3]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
for(k = 0; k < 3; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*4 + k];
}
}
}
util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, dst_stride);
src += 4*4;
dst += 8;
util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, 0);
dst += bytes_per_block;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
const uint8_t *src_row, unsigned src_stride,
const uint8_t *src, unsigned src_stride,
unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 8;
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const uint8_t *src = src_row;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][4];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 4; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
for(x = 0; x < width; x += bw) {
uint8_t tmp[4][4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
for(k = 0; k < comps; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k];
}
}
}
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, dst_stride);
src += 4*4;
dst += 8;
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, 0);
dst += bytes_per_block;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
const uint8_t *src_row, unsigned src_stride,
const uint8_t *src, unsigned src_stride,
unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 16;
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const uint8_t *src = src_row;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][4];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 4; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
for(x = 0; x < width; x += bw) {
uint8_t tmp[4][4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
for(k = 0; k < comps; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k];
}
}
}
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, dst_stride);
src += 4*4;
dst += 16;
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, 0);
dst += bytes_per_block;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
const uint8_t *src_row, unsigned src_stride,
const uint8_t *src, unsigned src_stride,
unsigned width, unsigned height)
{
const unsigned bw = 4, bh = 4, comps = 4, bytes_per_block = 16;
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const uint8_t *src = src_row;
for(y = 0; y < height; y += bh) {
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][4];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 4; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + i*4 + k];
for(x = 0; x < width; x += bw) {
uint8_t tmp[4][4][4]; /* [bh][bw][comps] */
for(j = 0; j < bh; ++j) {
for(i = 0; i < bw; ++i) {
for(k = 0; k < comps; ++k) {
tmp[j][i][k] = src[(y + j)*src_stride/sizeof(*src) + (x + i)*comps + k];
}
}
}
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, dst_stride);
src += 4*4;
dst += 16;
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0);
dst += bytes_per_block;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
dst_row += dst_stride / sizeof(*dst_row);
}
}
void
util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
const float *src_row, unsigned src_stride,
const float *src, unsigned src_stride,
unsigned width, unsigned height)
{
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const float *src = src_row;
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][3];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 3; ++k) {
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
}
}
}
util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, dst_stride);
src += 4*4;
util_format_dxtn_pack(3, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGB, dst, 0);
dst += 8;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
}
}
void
util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
const float *src_row, unsigned src_stride,
const float *src, unsigned src_stride,
unsigned width, unsigned height)
{
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const float *src = src_row;
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][4];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 4; ++k) {
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
}
}
}
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, dst_stride);
src += 4*4;
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT1_RGBA, dst, 0);
dst += 8;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
}
}
void
util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
const float *src, unsigned src_stride,
unsigned width, unsigned height)
{
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const float *src = src_row;
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][4];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 4; ++k) {
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
}
}
}
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, dst_stride);
src += 4*4;
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT3_RGBA, dst, 0);
dst += 16;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
}
}
void
util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height)
util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
const float *src, unsigned src_stride,
unsigned width, unsigned height)
{
unsigned x, y, i, j, k;
for(y = 0; y < height; y += 4) {
const float *src = src_row;
uint8_t *dst = dst_row;
for(x = 0; x < width; x += 4) {
uint8_t tmp[4][4][4];
for(j = 0; j < 4; ++j) {
for(i = 0; i < 4; ++i) {
for(k = 0; k < 4; ++k) {
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + i*4 + k]);
tmp[j][i][k] = float_to_ubyte(src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]);
}
}
}
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, dst_stride);
src += 4*4;
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], UTIL_FORMAT_DXT5_RGBA, dst, 0);
dst += 16;
}
src_row += src_stride;
dst_row += 4*dst_stride/sizeof(*dst_row);
}
}

View file

@ -544,7 +544,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);
//assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
/*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z, preserve stencil */
@ -571,7 +571,7 @@ pipe_put_tile_z(struct pipe_context *pipe,
case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);
//assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);
/*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
/* convert 32-bit Z to 24-bit Z, preserve stencil */

View file

@ -786,33 +786,6 @@ This instruction replicates its result.
TBD
.. opcode:: BGNFOR - Begin a For-Loop
dst.x = floor(src.x)
dst.y = floor(src.y)
dst.z = floor(src.z)
if (dst.y <= 0)
pc = [matching ENDFOR] + 1
endif
Note: The destination must be a loop register.
The source must be a constant register.
.. note::
Considered for cleanup.
.. note::
Considered for removal.
.. opcode:: REP - Repeat
TBD
.. opcode:: ELSE - Else
TBD
@ -823,30 +796,6 @@ This instruction replicates its result.
TBD
.. opcode:: ENDFOR - End a For-Loop
dst.x = dst.x + dst.z
dst.y = dst.y - 1.0
if (dst.y > 0)
pc = [matching BGNFOR instruction] + 1
endif
Note: The destination must be a loop register.
.. note::
Considered for cleanup.
.. note::
Considered for removal.
.. opcode:: ENDREP - End Repeat
TBD
.. opcode:: PUSHA - Push Address Register On Stack
push(src.x)

View file

@ -1622,14 +1622,6 @@ exec_instruction(
*pc = -1;
break;
case TGSI_OPCODE_REP:
ASSERT (0);
break;
case TGSI_OPCODE_ENDREP:
ASSERT (0);
break;
case TGSI_OPCODE_PUSHA:
ASSERT (0);
break;
@ -1743,8 +1735,6 @@ exec_instruction(
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
break;
case TGSI_OPCODE_BGNFOR:
/* fall-through (for now) */
case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
ASSERT(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
@ -1753,8 +1743,6 @@ exec_instruction(
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
break;
case TGSI_OPCODE_ENDFOR:
/* fall-through (for now at least) */
case TGSI_OPCODE_ENDLOOP:
/* Restore ContMask, but don't pop */
ASSERT(mach->ContStackTop > 0);

View file

@ -97,63 +97,24 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
llvmpipe->pipe.winsys = screen->winsys;
llvmpipe->pipe.screen = screen;
llvmpipe->pipe.priv = priv;
/* Init the pipe context methods */
llvmpipe->pipe.destroy = llvmpipe_destroy;
/* state setters */
llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state;
llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state;
llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states;
llvmpipe->pipe.bind_vertex_sampler_states = llvmpipe_bind_vertex_sampler_states;
llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state;
llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state;
llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state;
llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state;
llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state;
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
llvmpipe->pipe.clear = llvmpipe_clear;
llvmpipe->pipe.flush = llvmpipe_flush;
llvmpipe_init_blend_funcs(llvmpipe);
llvmpipe_init_clip_funcs(llvmpipe);
llvmpipe_init_draw_funcs(llvmpipe);
llvmpipe_init_sampler_funcs(llvmpipe);
llvmpipe_init_query_funcs( llvmpipe );
llvmpipe_init_vertex_funcs(llvmpipe);
llvmpipe_init_fs_funcs(llvmpipe);
llvmpipe_init_vs_funcs(llvmpipe);
llvmpipe_init_rasterizer_funcs(llvmpipe);
llvmpipe_init_context_resource_funcs( &llvmpipe->pipe );
llvmpipe_init_surface_functions(llvmpipe);
/*
* Create drawing context and plug our rendering stage into it.
@ -186,8 +147,6 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv )
draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe);
#endif
lp_init_surface_functions(llvmpipe);
lp_reset_counters();
return &llvmpipe->pipe;

View file

@ -94,9 +94,6 @@ struct llvmpipe_context {
/** Vertex format */
struct vertex_info vertex_info;
/** Which vertex shader output slot contains point size */
int psize_slot;
/** The tiling engine */
struct lp_setup_context *setup;

View file

@ -42,20 +42,12 @@
void
llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count)
{
llvmpipe_draw_elements(pipe, NULL, 0, 0, mode, start, count);
}
/**
* Draw vertex arrays, with optional indexing.
* Basically, map the vertex buffers (and drawing surfaces), then hand off
* the drawing to the 'draw' module.
*/
void
static void
llvmpipe_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
@ -115,7 +107,7 @@ llvmpipe_draw_range_elements(struct pipe_context *pipe,
}
void
static void
llvmpipe_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize,
@ -128,3 +120,19 @@ llvmpipe_draw_elements(struct pipe_context *pipe,
mode, start, count );
}
static void
llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count)
{
llvmpipe_draw_elements(pipe, NULL, 0, 0, mode, start, count);
}
void
llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
}

View file

@ -61,4 +61,10 @@
#define LP_MAX_THREADS 8
/**
* Max bytes per scene. This may be replaced by a runtime parameter.
*/
#define LP_MAX_SCENE_SIZE (512 * 1024 * 1024)
#endif /* LP_LIMITS_H */

View file

@ -882,9 +882,9 @@ create_rast_threads(struct lp_rasterizer *rast)
/**
* Create new lp_rasterizer.
* \param empty the queue to put empty scenes on after we've finished
* processing them.
* Create new lp_rasterizer. If num_threads is zero, don't create any
* new threads, do rendering synchronously.
* \param num_threads number of rasterizer threads to create
*/
struct lp_rasterizer *
lp_rast_create( unsigned num_threads )
@ -944,6 +944,8 @@ void lp_rast_destroy( struct lp_rasterizer *rast )
/* for synchronizing rasterization threads */
pipe_barrier_destroy( &rast->barrier );
lp_scene_queue_destroy(rast->full_scenes);
FREE(rast);
}

View file

@ -105,7 +105,7 @@ struct lp_rasterizer
* (potentially) shared, these empty scenes should be returned to
* the context which created them rather than retained here.
*/
struct lp_scene_queue *empty_scenes;
/* struct lp_scene_queue *empty_scenes; */
/** The scene currently being rasterized by the threads */
struct lp_scene *curr_scene;

View file

@ -32,7 +32,6 @@
#include "util/u_surface.h"
#include "lp_scene.h"
#include "lp_scene_queue.h"
#include "lp_debug.h"
/** List of texture references */
@ -43,6 +42,10 @@ struct texture_ref {
/**
* Create a new scene object.
* \param queue the queue to put newly rendered/emptied scenes into
*/
struct lp_scene *
lp_scene_create( struct pipe_context *pipe,
struct lp_scene_queue *queue )
@ -195,6 +198,8 @@ lp_scene_reset(struct lp_scene *scene )
make_empty_list(ref_list);
}
scene->scene_size = 0;
scene->has_color_clear = FALSE;
scene->has_depth_clear = FALSE;
}
@ -226,7 +231,10 @@ lp_bin_new_data_block( struct data_block_list *list )
}
/** Return number of bytes used for all bin data within a scene */
/**
* Return number of bytes used for all bin data within a scene.
* This does not include resources (textures) referenced by the scene.
*/
unsigned
lp_scene_data_size( const struct lp_scene *scene )
{
@ -267,6 +275,8 @@ lp_scene_add_resource_reference(struct lp_scene *scene,
pipe_resource_reference(&ref->resource, resource);
insert_at_tail(ref_list, ref);
}
scene->scene_size += llvmpipe_resource_size(resource);
}
@ -401,61 +411,6 @@ end:
}
/**
* Prepare this scene for the rasterizer.
* Map the framebuffer surfaces. Initialize the 'rast' state.
*/
static boolean
lp_scene_map_buffers( struct lp_scene *scene )
{
LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
/* XXX framebuffer surfaces are no longer mapped here */
/* XXX move all map/unmap stuff into rast module... */
return TRUE;
}
/**
* Called after rasterizer as finished rasterizing a scene.
*
* We want to call this from the pipe_context's current thread to
* avoid having to have mutexes on the transfer functions.
*/
static void
lp_scene_unmap_buffers( struct lp_scene *scene )
{
#if 0
unsigned i;
for (i = 0; i < scene->fb.nr_cbufs; i++) {
if (scene->cbuf_map[i]) {
struct pipe_surface *cbuf = scene->fb.cbufs[i];
llvmpipe_resource_unmap(cbuf->texture,
cbuf->face,
cbuf->level,
cbuf->zslice);
scene->cbuf_map[i] = NULL;
}
}
if (scene->zsbuf_map) {
struct pipe_surface *zsbuf = scene->fb.zsbuf;
llvmpipe_resource_unmap(zsbuf->texture,
zsbuf->face,
zsbuf->level,
zsbuf->zslice);
scene->zsbuf_map = NULL;
}
#endif
util_unreference_framebuffer_state( &scene->fb );
}
void lp_scene_begin_binning( struct lp_scene *scene,
struct pipe_framebuffer_state *fb )
{
@ -472,8 +427,7 @@ void lp_scene_begin_binning( struct lp_scene *scene,
void lp_scene_rasterize( struct lp_scene *scene,
struct lp_rasterizer *rast,
boolean write_depth )
struct lp_rasterizer *rast )
{
if (0) {
unsigned x, y;
@ -487,11 +441,6 @@ void lp_scene_rasterize( struct lp_scene *scene,
}
}
scene->write_depth = (scene->fb.zsbuf != NULL &&
write_depth);
lp_scene_map_buffers( scene );
/* Enqueue the scene for rasterization, then immediately wait for
* it to finish.
*/
@ -502,6 +451,9 @@ void lp_scene_rasterize( struct lp_scene *scene,
* transfers become per-context:
*/
lp_rast_finish( rast );
lp_scene_unmap_buffers( scene );
util_unreference_framebuffer_state( &scene->fb );
/* put scene into the empty list */
lp_scene_enqueue( scene->empty_queue, scene );
}

View file

@ -119,7 +119,11 @@ struct lp_scene {
/** list of resources referenced by the scene commands */
struct resource_ref resources;
boolean write_depth;
/** Approx memory used by the scene (in bytes). This includes the
* shared and per-tile bins plus any referenced resources/textures.
*/
unsigned scene_size;
boolean has_color_clear;
boolean has_depth_clear;
@ -182,6 +186,8 @@ lp_scene_alloc( struct lp_scene *scene, unsigned size)
lp_bin_new_data_block( list );
}
scene->scene_size += size;
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
@ -204,6 +210,8 @@ lp_scene_alloc_aligned( struct lp_scene *scene, unsigned size,
lp_bin_new_data_block( list );
}
scene->scene_size += size;
{
struct data_block *tail = list->tail;
ubyte *data = tail->data + tail->used;
@ -220,6 +228,7 @@ static INLINE void
lp_scene_putback_data( struct lp_scene *scene, unsigned size)
{
struct data_block_list *list = &scene->data;
scene->scene_size -= size;
assert(list->tail->used >= size);
list->tail->used -= size;
}
@ -302,11 +311,18 @@ lp_scene_bin_iter_next( struct lp_scene *scene, int *bin_x, int *bin_y );
void
lp_scene_rasterize( struct lp_scene *scene,
struct lp_rasterizer *rast,
boolean write_depth );
struct lp_rasterizer *rast );
void
lp_scene_begin_binning( struct lp_scene *scene,
struct pipe_framebuffer_state *fb );
static INLINE unsigned
lp_scene_get_size(const struct lp_scene *scene)
{
return scene->scene_size;
}
#endif /* LP_BIN_H */

View file

@ -97,6 +97,8 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 1;
case PIPE_CAP_SM3:
return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:

View file

@ -74,6 +74,26 @@ lp_setup_get_current_scene(struct lp_setup_context *setup)
}
/**
* Check if the size of the current scene has exceeded the limit.
* If so, flush/render it.
*/
static void
setup_check_scene_size_and_flush(struct lp_setup_context *setup)
{
if (setup->scene) {
struct lp_scene *scene = lp_setup_get_current_scene(setup);
unsigned size = lp_scene_get_size(scene);
if (size > LP_MAX_SCENE_SIZE) {
/*printf("LLVMPIPE: scene size = %u, flushing.\n", size);*/
set_scene_state( setup, SETUP_FLUSHED );
/*assert(lp_scene_get_size(scene) == 0);*/
}
}
}
static void
first_triangle( struct lp_setup_context *setup,
const float (*v0)[4],
@ -132,14 +152,11 @@ static void reset_context( struct lp_setup_context *setup )
/** Rasterize all scene's bins */
static void
lp_setup_rasterize_scene( struct lp_setup_context *setup,
boolean write_depth )
lp_setup_rasterize_scene( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
lp_scene_rasterize(scene,
setup->rast,
write_depth);
lp_scene_rasterize(scene, setup->rast);
reset_context( setup );
@ -190,7 +207,7 @@ execute_clears( struct lp_setup_context *setup )
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
begin_binning( setup );
lp_setup_rasterize_scene( setup, TRUE );
lp_setup_rasterize_scene( setup );
}
@ -221,7 +238,7 @@ set_scene_state( struct lp_setup_context *setup,
if (old_state == SETUP_CLEARED)
execute_clears( setup );
else
lp_setup_rasterize_scene( setup, TRUE );
lp_setup_rasterize_scene( setup );
break;
default:
@ -596,10 +613,14 @@ lp_setup_is_resource_referenced( const struct lp_setup_context *setup,
void
lp_setup_update_state( struct lp_setup_context *setup )
{
struct lp_scene *scene = lp_setup_get_current_scene(setup);
struct lp_scene *scene;
LP_DBG(DEBUG_SETUP, "%s\n", __FUNCTION__);
setup_check_scene_size_and_flush(setup);
scene = lp_setup_get_current_scene(setup);
assert(setup->fs.current.jit_function);
/* Some of the 'draw' pipeline stages may have changed some driver state.
@ -741,6 +762,8 @@ lp_setup_destroy( struct lp_setup_context *setup )
reset_context( setup );
util_unreference_framebuffer_state(&setup->fb);
for (i = 0; i < Elements(setup->fs.current_tex); i++) {
pipe_resource_reference(&setup->fs.current_tex[i], NULL);
}
@ -755,6 +778,8 @@ lp_setup_destroy( struct lp_setup_context *setup )
lp_scene_destroy(scene);
}
lp_scene_queue_destroy(setup->empty_scenes);
lp_rast_destroy( setup->rast );
FREE( setup );

View file

@ -440,7 +440,12 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
static void
lp_setup_vbuf_destroy(struct vbuf_render *vbr)
{
lp_setup_destroy(lp_setup_context(vbr));
struct lp_setup_context *setup = lp_setup_context(vbr);
if (setup->vertex_buffer) {
align_free(setup->vertex_buffer);
setup->vertex_buffer = NULL;
}
lp_setup_destroy(setup);
}

View file

@ -31,11 +31,10 @@
#ifndef LP_STATE_H
#define LP_STATE_H
#include "gallivm/lp_bld.h"
#include "pipe/p_state.h"
#include "tgsi/tgsi_scan.h"
#include "lp_jit.h"
#include "gallivm/lp_bld.h"
#include "gallivm/lp_bld_sample.h" /* for struct lp_sampler_static_state */
@ -85,8 +84,6 @@ struct lp_fragment_shader_variant_key
struct lp_fragment_shader_variant
{
struct lp_fragment_shader *shader;
struct lp_fragment_shader_variant_key key;
LLVMValueRef function[2];
@ -97,11 +94,7 @@ struct lp_fragment_shader_variant
};
/**
* Subclass of pipe_shader_state (though it doesn't really need to be).
*
* This is starting to look an awful lot like a quad pipeline stage...
*/
/** Subclass of pipe_shader_state */
struct lp_fragment_shader
{
struct pipe_shader_state base;
@ -109,140 +102,58 @@ struct lp_fragment_shader
struct tgsi_shader_info info;
struct lp_fragment_shader_variant *variants;
struct lp_fragment_shader_variant *current;
};
/** Subclass of pipe_shader_state */
struct lp_vertex_shader {
struct lp_vertex_shader
{
struct pipe_shader_state shader;
struct draw_vertex_shader *draw_data;
};
struct lp_velems_state {
/** Vertex element state */
struct lp_velems_state
{
unsigned count;
struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
};
void *
llvmpipe_create_blend_state(struct pipe_context *,
const struct pipe_blend_state *);
void llvmpipe_bind_blend_state(struct pipe_context *,
void *);
void llvmpipe_delete_blend_state(struct pipe_context *,
void *);
void *
llvmpipe_create_sampler_state(struct pipe_context *,
const struct pipe_sampler_state *);
void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
void
llvmpipe_bind_vertex_sampler_states(struct pipe_context *,
unsigned num_samplers,
void **samplers);
void llvmpipe_delete_sampler_state(struct pipe_context *, void *);
void *
llvmpipe_create_depth_stencil_state(struct pipe_context *,
const struct pipe_depth_stencil_alpha_state *);
void llvmpipe_bind_depth_stencil_state(struct pipe_context *, void *);
void llvmpipe_delete_depth_stencil_state(struct pipe_context *, void *);
void *
llvmpipe_create_rasterizer_state(struct pipe_context *,
const struct pipe_rasterizer_state *);
void llvmpipe_bind_rasterizer_state(struct pipe_context *, void *);
void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *);
void llvmpipe_set_framebuffer_state( struct pipe_context *,
const struct pipe_framebuffer_state * );
void llvmpipe_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color );
void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
const struct pipe_stencil_ref *stencil_ref );
void llvmpipe_set_clip_state( struct pipe_context *,
const struct pipe_clip_state * );
void llvmpipe_set_constant_buffer(struct pipe_context *,
uint shader, uint index,
struct pipe_resource *buf);
void *llvmpipe_create_fs_state(struct pipe_context *,
const struct pipe_shader_state *);
void llvmpipe_bind_fs_state(struct pipe_context *, void *);
void llvmpipe_delete_fs_state(struct pipe_context *, void *);
void *llvmpipe_create_vs_state(struct pipe_context *,
const struct pipe_shader_state *);
void llvmpipe_bind_vs_state(struct pipe_context *, void *);
void llvmpipe_delete_vs_state(struct pipe_context *, void *);
void *llvmpipe_create_vertex_elements_state(struct pipe_context *,
unsigned count,
const struct pipe_vertex_element *);
void llvmpipe_bind_vertex_elements_state(struct pipe_context *, void *);
void llvmpipe_delete_vertex_elements_state(struct pipe_context *, void *);
void llvmpipe_set_polygon_stipple( struct pipe_context *,
const struct pipe_poly_stipple * );
void llvmpipe_set_scissor_state( struct pipe_context *,
const struct pipe_scissor_state * );
void llvmpipe_set_fragment_sampler_views(struct pipe_context *,
unsigned num,
struct pipe_sampler_view **);
llvmpipe_set_framebuffer_state(struct pipe_context *,
const struct pipe_framebuffer_state *);
void
llvmpipe_set_vertex_sampler_views(struct pipe_context *,
unsigned num,
struct pipe_sampler_view **);
struct pipe_sampler_view *
llvmpipe_create_sampler_view(struct pipe_context *pipe,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ);
llvmpipe_update_fs(struct llvmpipe_context *lp);
void
llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view);
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );
void llvmpipe_set_vertex_buffers(struct pipe_context *,
unsigned count,
const struct pipe_vertex_buffer *);
void llvmpipe_update_fs(struct llvmpipe_context *lp);
void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe );
void llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
unsigned start, unsigned count);
void llvmpipe_draw_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize, int indexBias,
unsigned mode, unsigned start, unsigned count);
void
llvmpipe_draw_range_elements(struct pipe_context *pipe,
struct pipe_resource *indexBuffer,
unsigned indexSize, int indexBias,
unsigned min_index,
unsigned max_index,
unsigned mode, unsigned start, unsigned count);
llvmpipe_update_derived(struct llvmpipe_context *llvmpipe);
void
llvmpipe_map_texture_surfaces(struct llvmpipe_context *lp);
llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp);
llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_init_draw_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_init_clip_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_init_vs_funcs(struct llvmpipe_context *llvmpipe);
void
llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe);
#endif

View file

@ -40,15 +40,16 @@
#include "lp_state.h"
void *
static void *
llvmpipe_create_blend_state(struct pipe_context *pipe,
const struct pipe_blend_state *blend)
{
return mem_dup(blend, sizeof(*blend));
}
void llvmpipe_bind_blend_state( struct pipe_context *pipe,
void *blend )
static void
llvmpipe_bind_blend_state(struct pipe_context *pipe, void *blend)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -62,15 +63,17 @@ void llvmpipe_bind_blend_state( struct pipe_context *pipe,
llvmpipe->dirty |= LP_NEW_BLEND;
}
void llvmpipe_delete_blend_state(struct pipe_context *pipe,
void *blend)
static void
llvmpipe_delete_blend_state(struct pipe_context *pipe, void *blend)
{
FREE( blend );
}
void llvmpipe_set_blend_color( struct pipe_context *pipe,
const struct pipe_blend_color *blend_color )
static void
llvmpipe_set_blend_color(struct pipe_context *pipe,
const struct pipe_blend_color *blend_color)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -93,14 +96,15 @@ void llvmpipe_set_blend_color( struct pipe_context *pipe,
*/
void *
static void *
llvmpipe_create_depth_stencil_state(struct pipe_context *pipe,
const struct pipe_depth_stencil_alpha_state *depth_stencil)
{
return mem_dup(depth_stencil, sizeof(*depth_stencil));
}
void
static void
llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
void *depth_stencil)
{
@ -116,14 +120,17 @@ llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA;
}
void
static void
llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
{
FREE( depth );
}
void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
const struct pipe_stencil_ref *stencil_ref )
static void
llvmpipe_set_stencil_ref(struct pipe_context *pipe,
const struct pipe_stencil_ref *stencil_ref)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -142,3 +149,18 @@ void llvmpipe_set_stencil_ref( struct pipe_context *pipe,
}
void
llvmpipe_init_blend_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state;
llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state;
llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state;
llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state;
llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref;
}

View file

@ -32,8 +32,9 @@
#include "draw/draw_context.h"
void llvmpipe_set_clip_state( struct pipe_context *pipe,
const struct pipe_clip_state *clip )
static void
llvmpipe_set_clip_state(struct pipe_context *pipe,
const struct pipe_clip_state *clip)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -42,8 +43,9 @@ void llvmpipe_set_clip_state( struct pipe_context *pipe,
}
void llvmpipe_set_viewport_state( struct pipe_context *pipe,
const struct pipe_viewport_state *viewport )
static void
llvmpipe_set_viewport_state(struct pipe_context *pipe,
const struct pipe_viewport_state *viewport)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -55,8 +57,9 @@ void llvmpipe_set_viewport_state( struct pipe_context *pipe,
}
void llvmpipe_set_scissor_state( struct pipe_context *pipe,
const struct pipe_scissor_state *scissor )
static void
llvmpipe_set_scissor_state(struct pipe_context *pipe,
const struct pipe_scissor_state *scissor)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -67,8 +70,9 @@ void llvmpipe_set_scissor_state( struct pipe_context *pipe,
}
void llvmpipe_set_polygon_stipple( struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple )
static void
llvmpipe_set_polygon_stipple(struct pipe_context *pipe,
const struct pipe_poly_stipple *stipple)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -77,3 +81,14 @@ void llvmpipe_set_polygon_stipple( struct pipe_context *pipe,
llvmpipe->poly_stipple = *stipple; /* struct copy */
llvmpipe->dirty |= LP_NEW_STIPPLE;
}
void
llvmpipe_init_clip_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
}

View file

@ -621,7 +621,6 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMTypeRef fs_vec_type;
LLVMTypeRef fs_int_vec_type;
LLVMTypeRef blend_vec_type;
LLVMTypeRef blend_int_vec_type;
LLVMTypeRef arg_types[15];
LLVMTypeRef func_type;
LLVMTypeRef int32_vec4_type = lp_build_int32_vec4_type();
@ -680,7 +679,6 @@ generate_fragment(struct llvmpipe_context *lp,
fs_int_vec_type = lp_build_int_vec_type(fs_type);
blend_vec_type = lp_build_vec_type(blend_type);
blend_int_vec_type = lp_build_int_vec_type(blend_type);
arg_types[0] = screen->context_ptr_type; /* context */
arg_types[1] = LLVMInt32Type(); /* x */
@ -939,7 +937,6 @@ generate_variant(struct llvmpipe_context *lp,
if(!variant)
return NULL;
variant->shader = shader;
memcpy(&variant->key, key, sizeof *key);
generate_fragment(lp, shader, variant, 0);
@ -953,7 +950,7 @@ generate_variant(struct llvmpipe_context *lp,
}
void *
static void *
llvmpipe_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@ -969,11 +966,16 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
/* we need to keep a local copy of the tokens */
shader->base.tokens = tgsi_dup_tokens(templ->tokens);
if (LP_DEBUG & DEBUG_TGSI) {
debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader);
tgsi_dump(templ->tokens, 0);
}
return shader;
}
void
static void
llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -989,7 +991,7 @@ llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
}
void
static void
llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -1032,7 +1034,7 @@ llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
void
static void
llvmpipe_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
struct pipe_resource *constants)
@ -1163,8 +1165,6 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
LP_COUNT_ADD(nr_llvm_compiles, 2); /* emit vs. omit in/out test */
}
shader->current = variant;
/* TODO: put this in the variant */
/* TODO: most of these can be relaxed, in particular the colormask */
opaque = !key.blend.logicop_enable &&
@ -1178,7 +1178,19 @@ llvmpipe_update_fs(struct llvmpipe_context *lp)
? TRUE : FALSE;
lp_setup_set_fs_functions(lp->setup,
shader->current->jit_function[RAST_WHOLE],
shader->current->jit_function[RAST_EDGE_TEST],
variant->jit_function[RAST_WHOLE],
variant->jit_function[RAST_EDGE_TEST],
opaque);
}
void
llvmpipe_init_fs_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state;
llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
}

View file

@ -34,7 +34,7 @@
void *
static void *
llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
const struct pipe_rasterizer_state *rast)
{
@ -46,7 +46,7 @@ llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
void
static void
llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -79,10 +79,19 @@ llvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
}
void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
void *rasterizer)
static void
llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
void *rasterizer)
{
FREE( rasterizer );
}
void
llvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state;
llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
}

View file

@ -41,7 +41,7 @@
void *
static void *
llvmpipe_create_sampler_state(struct pipe_context *pipe,
const struct pipe_sampler_state *sampler)
{
@ -49,7 +49,7 @@ llvmpipe_create_sampler_state(struct pipe_context *pipe,
}
void
static void
llvmpipe_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **sampler)
{
@ -76,7 +76,7 @@ llvmpipe_bind_sampler_states(struct pipe_context *pipe,
}
void
static void
llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
unsigned num_samplers,
void **samplers)
@ -104,7 +104,7 @@ llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
}
void
static void
llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@ -133,7 +133,7 @@ llvmpipe_set_fragment_sampler_views(struct pipe_context *pipe,
}
void
static void
llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
unsigned num,
struct pipe_sampler_view **views)
@ -163,7 +163,7 @@ llvmpipe_set_vertex_sampler_views(struct pipe_context *pipe,
}
struct pipe_sampler_view *
static struct pipe_sampler_view *
llvmpipe_create_sampler_view(struct pipe_context *pipe,
struct pipe_resource *texture,
const struct pipe_sampler_view *templ)
@ -182,7 +182,7 @@ llvmpipe_create_sampler_view(struct pipe_context *pipe,
}
void
static void
llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
struct pipe_sampler_view *view)
{
@ -191,7 +191,7 @@ llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
}
void
static void
llvmpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
@ -199,4 +199,16 @@ llvmpipe_delete_sampler_state(struct pipe_context *pipe,
}
void
llvmpipe_init_sampler_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
llvmpipe->pipe.bind_fragment_sampler_states = llvmpipe_bind_sampler_states;
llvmpipe->pipe.bind_vertex_sampler_states = llvmpipe_bind_vertex_sampler_states;
llvmpipe->pipe.set_fragment_sampler_views = llvmpipe_set_fragment_sampler_views;
llvmpipe->pipe.set_vertex_sampler_views = llvmpipe_set_vertex_sampler_views;
llvmpipe->pipe.create_sampler_view = llvmpipe_create_sampler_view;
llvmpipe->pipe.sampler_view_destroy = llvmpipe_sampler_view_destroy;
llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
}

View file

@ -35,7 +35,7 @@
#include "draw/draw_context.h"
void *
static void *
llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_element *attribs)
@ -50,7 +50,7 @@ llvmpipe_create_vertex_elements_state(struct pipe_context *pipe,
return velems;
}
void
static void
llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
void *velems)
{
@ -65,13 +65,13 @@ llvmpipe_bind_vertex_elements_state(struct pipe_context *pipe,
draw_set_vertex_elements(llvmpipe->draw, lp_velems->count, lp_velems->velem);
}
void
static void
llvmpipe_delete_vertex_elements_state(struct pipe_context *pipe, void *velems)
{
FREE( velems );
}
void
static void
llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
unsigned count,
const struct pipe_vertex_buffer *buffers)
@ -87,3 +87,15 @@ llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
draw_set_vertex_buffers(llvmpipe->draw, count, buffers);
}
void
llvmpipe_init_vertex_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.create_vertex_elements_state = llvmpipe_create_vertex_elements_state;
llvmpipe->pipe.bind_vertex_elements_state = llvmpipe_bind_vertex_elements_state;
llvmpipe->pipe.delete_vertex_elements_state = llvmpipe_delete_vertex_elements_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
}

View file

@ -28,15 +28,17 @@
#include "pipe/p_defines.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_parse.h"
#include "util/u_memory.h"
#include "draw/draw_context.h"
#include "lp_context.h"
#include "lp_debug.h"
#include "lp_state.h"
void *
static void *
llvmpipe_create_vs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
@ -57,6 +59,11 @@ llvmpipe_create_vs_state(struct pipe_context *pipe,
if (state->draw_data == NULL)
goto fail;
if (LP_DEBUG & DEBUG_TGSI) {
debug_printf("llvmpipe: Create vertex shader %p:\n", (void *) state);
tgsi_dump(templ->tokens, 0);
}
return state;
fail:
@ -69,7 +76,7 @@ fail:
}
void
static void
llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -87,7 +94,7 @@ llvmpipe_bind_vs_state(struct pipe_context *pipe, void *_vs)
}
void
static void
llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
@ -99,3 +106,13 @@ llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
FREE( (void *)state->shader.tokens );
FREE( state );
}
void
llvmpipe_init_vs_funcs(struct llvmpipe_context *llvmpipe)
{
llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state;
llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
}

View file

@ -146,7 +146,7 @@ lp_surface_copy(struct pipe_context *pipe,
void
lp_init_surface_functions(struct llvmpipe_context *lp)
llvmpipe_init_surface_functions(struct llvmpipe_context *lp)
{
lp->pipe.surface_copy = lp_surface_copy;
lp->pipe.surface_fill = util_surface_fill;

View file

@ -36,7 +36,7 @@ struct llvmpipe_context;
extern void
lp_init_surface_functions(struct llvmpipe_context *lp);
llvmpipe_init_surface_functions(struct llvmpipe_context *lp);
#endif /* LP_SURFACE_H */

View file

@ -241,6 +241,13 @@ llvmpipe_resource_destroy(struct pipe_screen *pscreen,
/* display target */
struct sw_winsys *winsys = screen->winsys;
winsys->displaytarget_destroy(winsys, lpr->dt);
if (lpr->tiled[0].data) {
align_free(lpr->tiled[0].data);
lpr->tiled[0].data = NULL;
}
FREE(lpr->layout[0]);
}
else if (resource_is_texture(pt)) {
/* regular texture */
@ -1160,6 +1167,27 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
}
/**
* Return size of resource in bytes
*/
unsigned
llvmpipe_resource_size(const struct pipe_resource *resource)
{
const struct llvmpipe_resource *lpr = llvmpipe_resource_const(resource);
unsigned lvl, size = 0;
for (lvl = 0; lvl <= lpr->base.last_level; lvl++) {
if (lpr->linear[lvl].data)
size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR);
if (lpr->tiled[lvl].data)
size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED);
}
return size;
}
void
llvmpipe_init_screen_resource_funcs(struct pipe_screen *screen)
{

View file

@ -184,6 +184,10 @@ void *
llvmpipe_resource_data(struct pipe_resource *resource);
unsigned
llvmpipe_resource_size(const struct pipe_resource *resource);
ubyte *
llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
unsigned face_slice, unsigned level,

View file

@ -2,7 +2,7 @@ Import('*')
env = env.Clone()
env.Append(CPPPATH = [
env.PrependUnique(delete_existing=1, CPPPATH = [
'#/src/gallium/drivers',
])

View file

@ -11,6 +11,7 @@ C_SOURCES = \
r300_emit.c \
r300_flush.c \
r300_fs.c \
r300_hyperz.c \
r300_query.c \
r300_render.c \
r300_resource.c \

View file

@ -21,6 +21,7 @@ r300 = env.ConvenienceLibrary(
'r300_emit.c',
'r300_flush.c',
'r300_fs.c',
'r300_hyperz.c',
'r300_query.c',
'r300_render.c',
'r300_resource.c',

View file

@ -37,6 +37,8 @@
#include "r300_state_invariant.h"
#include "r300_winsys.h"
#include <inttypes.h>
static void r300_destroy_context(struct pipe_context* context)
{
struct r300_context* r300 = r300_context(context);
@ -49,9 +51,9 @@ static void r300_destroy_context(struct pipe_context* context)
/* Print stats, if enabled. */
if (SCREEN_DBG_ON(r300->screen, DBG_STATS)) {
fprintf(stderr, "r300: Stats for context %p:\n", r300);
fprintf(stderr, " : Flushes: %llu\n", r300->flush_counter);
fprintf(stderr, " : Flushes: %" PRIu64 "\n", r300->flush_counter);
foreach(atom, &r300->atom_list) {
fprintf(stderr, " : %s: %llu emits\n",
fprintf(stderr, " : %s: %" PRIu64 " emits\n",
atom->name, atom->counter);
}
}

View file

@ -257,6 +257,10 @@ struct r300_texture {
/* A pitch for each mip-level */
unsigned pitch[R300_MAX_TEXTURE_LEVELS];
/* A pitch multiplied by blockwidth as hardware wants
* the number of pixels instead of the number of blocks. */
unsigned hwpitch[R300_MAX_TEXTURE_LEVELS];
/* Size of one zslice or face based on the texture target */
unsigned layer_size[R300_MAX_TEXTURE_LEVELS];

View file

@ -38,6 +38,7 @@ static struct debug_option debug_options[] = {
{ "draw", DBG_DRAW, "Draw and emit (for debugging)" },
{ "tex", DBG_TEX, "Textures (for debugging)" },
{ "fall", DBG_FALL, "Fallbacks (for debugging)" },
{ "rs", DBG_RS, "Rasterizer (for debugging)" },
{ "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" },
{ "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" },
{ "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" },

View file

@ -83,7 +83,6 @@ void r300_emit_clip_state(struct r300_context* r300,
unsigned size, void* state)
{
struct pipe_clip_state* clip = (struct pipe_clip_state*)state;
int i;
CS_LOCALS(r300);
if (r300->screen->caps.has_tcl) {
@ -92,9 +91,7 @@ void r300_emit_clip_state(struct r300_context* r300,
(r300->screen->caps.is_r500 ?
R500_PVS_UCP_START : R300_PVS_UCP_START));
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4);
for (i = 0; i < 6; i++) {
OUT_CS_TABLE(clip->ucp[i], 4);
}
OUT_CS_TABLE(clip->ucp, 6 * 4);
OUT_CS_REG(R300_VAP_CLIP_CNTL, ((1 << clip->nr) - 1) |
R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
END_CS;
@ -103,7 +100,6 @@ void r300_emit_clip_state(struct r300_context* r300,
OUT_CS_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE);
END_CS;
}
}
void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
@ -416,12 +412,9 @@ void r500_emit_fs_constants(struct r300_context* r300, unsigned size, void *stat
OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, count * 4);
for(i = 0; i < count; ++i) {
const float *data;
assert(constants->Constants[i].Type == RC_CONSTANT_EXTERNAL);
data = buf->constants[i];
OUT_CS_TABLE(data, 4);
}
OUT_CS_TABLE(buf->constants, count * 4);
END_CS;
}
@ -999,7 +992,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state)
void r300_emit_vs_constants(struct r300_context* r300,
unsigned size, void *state)
{
unsigned i;
unsigned count =
((struct r300_vertex_shader*)r300->vs_state.state)->externals_count;
struct r300_constant_buffer *buf = (struct r300_constant_buffer*)state;
@ -1013,10 +1005,7 @@ void r300_emit_vs_constants(struct r300_context* r300,
(r300->screen->caps.is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, count * 4);
for (i = 0; i < count; i++) {
const float *data = buf->constants[i];
OUT_CS_TABLE(data, 4);
}
OUT_CS_TABLE(buf->constants, count * 4);
END_CS;
}
@ -1175,6 +1164,11 @@ unsigned r300_get_num_dirty_dwords(struct r300_context *r300)
}
}
/* emit_query_end is not atomized. */
dwords += 26;
/* let's reserve some more, just in case */
dwords += 32;
return dwords;
}

View file

@ -0,0 +1,108 @@
/*
* Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
* Copyright 2009 Marek Olšák <maraeo@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_hyperz.h"
#include "r300_context.h"
#include "r300_reg.h"
#include "r300_fs.h"
/*****************************************************************************/
/* The ZTOP state */
/*****************************************************************************/
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
{
/* We are interested only in the cases when a new depth or stencil value
* can be written and changed. */
/* We might optionally check for [Z func: never] and inspect the stencil
* state in a similar fashion, but it's not terribly important. */
return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) ||
(dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) ||
((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) &&
(dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK));
}
static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa)
{
/* We are interested only in the cases when alpha testing can kill
* a fragment. */
uint32_t af = dsa->alpha_function;
return (af & R300_FG_ALPHA_FUNC_ENABLE) &&
(af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS;
}
static void r300_update_ztop(struct r300_context* r300)
{
struct r300_ztop_state* ztop_state =
(struct r300_ztop_state*)r300->ztop_state.state;
/* This is important enough that I felt it warranted a comment.
*
* According to the docs, these are the conditions where ZTOP must be
* disabled:
* 1) Alpha testing enabled
* 2) Texture kill instructions in fragment shader
* 3) Chroma key culling enabled
* 4) W-buffering enabled
*
* The docs claim that for the first three cases, if no ZS writes happen,
* then ZTOP can be used.
*
* (3) will never apply since we do not support chroma-keyed operations.
* (4) will need to be re-examined (and this comment updated) if/when
* Hyper-Z becomes supported.
*
* Additionally, the following conditions require disabled ZTOP:
* 5) Depth writes in fragment shader
* 6) Outstanding occlusion queries
*
* This register causes stalls all the way from SC to CB when changed,
* but it is buffered on-chip so it does not hurt to write it if it has
* not changed.
*
* ~C.
*/
/* ZS writes */
if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) &&
(r300_dsa_alpha_test_enabled(r300->dsa_state.state) || /* (1) */
r300_fs(r300)->shader->info.uses_kill)) { /* (2) */
ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
} else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */
ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
} else if (r300->query_current) { /* (6) */
ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
} else {
ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
}
r300->ztop_state.dirty = TRUE;
}
void r300_update_hyperz_state(struct r300_context* r300)
{
r300_update_ztop(r300);
}

View file

@ -0,0 +1,30 @@
/*
* Copyright 2010 Marek Olšák <maraeo@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_HYPERZ_H
#define R300_HYPERZ_H
struct r300_context;
void r300_update_hyperz_state(struct r300_context* r300);
#endif

View file

@ -235,7 +235,7 @@ void r500_emit_draw_arrays_immediate(struct r300_context *r300,
dwords = 9 + count * vertex_size;
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + dwords);
r300_reserve_cs_space(r300, r300_get_num_dirty_dwords(r300) + 2 + dwords);
r300_emit_buffer_validate(r300, FALSE, NULL);
r300_emit_dirty_state(r300);
@ -600,8 +600,9 @@ void r300_draw_range_elements(struct pipe_context* pipe,
start += short_count;
count -= short_count;
/* 16 spare dwords are enough for emit_draw_elements. */
if (count && r300_reserve_cs_space(r300, 16)) {
/* 16 spare dwords are enough for emit_draw_elements.
* Also reserve some space for emit_query_end. */
if (count && r300_reserve_cs_space(r300, 74)) {
r300_emit_buffer_validate(r300, TRUE, indexBuffer);
r300_emit_dirty_state(r300);
r300_emit_aos(r300, 0, TRUE);
@ -668,8 +669,9 @@ void r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
count -= short_count;
/* Again, we emit both AOS and draw_arrays so there should be
* at least 128 spare dwords. */
if (count && r300_reserve_cs_space(r300, 128)) {
* at least 128 spare dwords.
* Also reserve some space for emit_query_end. */
if (count && r300_reserve_cs_space(r300, 186)) {
r300_emit_buffer_validate(r300, TRUE, NULL);
r300_emit_dirty_state(r300);
}

View file

@ -22,6 +22,7 @@
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "util/u_format.h"
#include "util/u_format_s3tc.h"
#include "util/u_memory.h"
#include "r300_context.h"
@ -319,6 +320,8 @@ struct pipe_screen* r300_create_screen(struct r300_winsys_screen *rws)
r300_init_screen_resource_functions(r300screen);
util_format_s3tc_init();
return &r300screen->screen;
}

View file

@ -72,6 +72,7 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
#define DBG_NO_TILING 0x0000100
#define DBG_NO_IMMD 0x0000200
#define DBG_STATS 0x0000400
#define DBG_RS 0x0000800
/*@}*/
static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)

View file

@ -853,8 +853,11 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
/* XXX Disable point sprites until we know what's wrong with them. */
rs->rs.sprite_coord_enable = 0;
/* Point sprites */
if (state->sprite_coord_enable) {
if (rs->rs.sprite_coord_enable) {
rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE;
for (i = 0; i < 8; i++) {
if (state->sprite_coord_enable & (1 << i))
@ -1072,11 +1075,9 @@ r300_create_sampler_view(struct pipe_context *pipe,
swizzle[2] = templ->swizzle_b;
swizzle[3] = templ->swizzle_a;
/* XXX Enable swizzles when they become supported. Now we get RGBA
* everywhere. And do testing! */
view->format = tex->tx_format;
view->format.format1 |= r300_translate_texformat(templ->format,
0); /*swizzle);*/
swizzle);
if (r300_screen(pipe->screen)->caps.is_r500) {
view->format.format2 |= r500_tx_format_msb_bit(templ->format);
}
@ -1280,26 +1281,57 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
if (r300_screen(pipe->screen)->caps.has_tcl) {
/* Check if the format is aligned to the size of DWORD. */
r300_vertex_psc(velems);
/* Check if the format is aligned to the size of DWORD.
* We only care about the blocksizes of the formats since
* swizzles are already set up. */
for (i = 0; i < count; i++) {
format = &velems->velem[i].src_format;
/* Replace some formats with their aligned counterparts,
* this is OK because we check for aligned strides too. */
/* XXX We need X instead of A in the format names. */
switch (*format) {
/* Align to RGBA8. */
case PIPE_FORMAT_R8_UNORM:
case PIPE_FORMAT_R8G8_UNORM:
case PIPE_FORMAT_R8G8B8_UNORM:
*format = PIPE_FORMAT_R8G8B8X8_UNORM;
*format = PIPE_FORMAT_R8G8B8A8_UNORM;
continue;
case PIPE_FORMAT_R8_SNORM:
case PIPE_FORMAT_R8G8_SNORM:
case PIPE_FORMAT_R8G8B8_SNORM:
*format = PIPE_FORMAT_R8G8B8A8_SNORM;
continue;
case PIPE_FORMAT_R8_USCALED:
case PIPE_FORMAT_R8G8_USCALED:
case PIPE_FORMAT_R8G8B8_USCALED:
*format = PIPE_FORMAT_R8G8B8A8_USCALED;
continue;
case PIPE_FORMAT_R8_SSCALED:
case PIPE_FORMAT_R8G8_SSCALED:
case PIPE_FORMAT_R8G8B8_SSCALED:
*format = PIPE_FORMAT_R8G8B8A8_SSCALED;
continue;
/* Align to RG16. */
case PIPE_FORMAT_R16_UNORM:
*format = PIPE_FORMAT_R16G16_UNORM;
continue;
case PIPE_FORMAT_R16_SNORM:
*format = PIPE_FORMAT_R16G16_SNORM;
continue;
case PIPE_FORMAT_R16_USCALED:
*format = PIPE_FORMAT_R16G16_USCALED;
continue;
case PIPE_FORMAT_R16_SSCALED:
*format = PIPE_FORMAT_R16G16_SSCALED;
continue;
case PIPE_FORMAT_R16_FLOAT:
*format = PIPE_FORMAT_R16G16_FLOAT;
continue;
/* Align to RGBA16. */
case PIPE_FORMAT_R16G16B16_UNORM:
*format = PIPE_FORMAT_R16G16B16A16_UNORM;
continue;
@ -1312,6 +1344,10 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
case PIPE_FORMAT_R16G16B16_SSCALED:
*format = PIPE_FORMAT_R16G16B16A16_SSCALED;
continue;
case PIPE_FORMAT_R16G16B16_FLOAT:
*format = PIPE_FORMAT_R16G16B16A16_FLOAT;
continue;
default:;
}
@ -1327,7 +1363,6 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
}
}
r300_vertex_psc(velems);
}
}
return velems;

View file

@ -28,6 +28,7 @@
#include "r300_context.h"
#include "r300_fs.h"
#include "r300_hyperz.h"
#include "r300_screen.h"
#include "r300_shader_semantics.h"
#include "r300_state.h"
@ -42,6 +43,7 @@ enum r300_rs_swizzle {
SWIZ_XYZW = 0,
SWIZ_X001,
SWIZ_XY01,
SWIZ_0001,
};
static void r300_draw_emit_attrib(struct r300_context* r300,
@ -169,10 +171,10 @@ static void r300_swtcl_vertex_psc(struct r300_context *r300)
}
static void r300_rs_col(struct r300_rs_block* rs, int id, int ptr,
boolean swizzle_0001)
enum r300_rs_swizzle swiz)
{
rs->ip[id] |= R300_RS_COL_PTR(ptr);
if (swizzle_0001) {
if (swiz == SWIZ_0001) {
rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_0001);
} else {
rs->ip[id] |= R300_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
@ -218,10 +220,10 @@ static void r300_rs_tex_write(struct r300_rs_block* rs, int id, int fp_offset)
}
static void r500_rs_col(struct r300_rs_block* rs, int id, int ptr,
boolean swizzle_0001)
enum r300_rs_swizzle swiz)
{
rs->ip[id] |= R500_RS_COL_PTR(ptr);
if (swizzle_0001) {
if (swiz == SWIZ_0001) {
rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_0001);
} else {
rs->ip[id] |= R500_RS_COL_FMT(R300_RS_COL_FMT_RGBA);
@ -276,7 +278,7 @@ static void r300_update_rs_block(struct r300_context* r300,
{
struct r300_rs_block rs = { { 0 } };
int i, col_count = 0, tex_count = 0, fp_offset = 0, count;
void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean);
void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
void (*rX00_rs_col_write)(struct r300_rs_block*, int, int);
void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int);
@ -301,12 +303,17 @@ static void r300_update_rs_block(struct r300_context* r300,
vs_outputs->color[1] != ATTR_UNUSED) {
/* Always rasterize if it's written by the VS,
* otherwise it locks up. */
rX00_rs_col(&rs, col_count, i, FALSE);
rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
/* Write it to the FS input register if it's used by the FS. */
if (fs_inputs->color[i] != ATTR_UNUSED) {
rX00_rs_col_write(&rs, col_count, fp_offset);
fp_offset++;
DBG(r300, DBG_RS,
"r300: Rasterized color %i written to FS.\n", i);
} else {
DBG(r300, DBG_RS, "r300: Rasterized color %i unused.\n", i);
}
col_count++;
} else {
@ -314,6 +321,9 @@ static void r300_update_rs_block(struct r300_context* r300,
/* If we try to set it to (0,0,0,1), it will lock up. */
if (fs_inputs->color[i] != ATTR_UNUSED) {
fp_offset++;
DBG(r300, DBG_RS, "r300: FS input color %i unassigned%s.\n",
i);
}
}
}
@ -331,9 +341,15 @@ static void r300_update_rs_block(struct r300_context* r300,
/* Write it to the FS input register if it's used by the FS. */
if (fs_inputs->generic[i] != ATTR_UNUSED) {
rX00_rs_tex_write(&rs, tex_count, fp_offset);
if (sprite_coord)
debug_printf("r300: SpriteCoord (generic index %i) is being written to reg %i\n", i, fp_offset);
fp_offset++;
DBG(r300, DBG_RS,
"r300: Rasterized generic %i written to FS%s.\n",
i, sprite_coord ? " (sprite coord)" : "");
} else {
DBG(r300, DBG_RS,
"r300: Rasterized generic %i unused%s.\n",
i, sprite_coord ? " (sprite coord)" : "");
}
tex_count++;
} else {
@ -341,6 +357,9 @@ static void r300_update_rs_block(struct r300_context* r300,
/* If we try to set it to (0,0,0,1), it will lock up. */
if (fs_inputs->generic[i] != ATTR_UNUSED) {
fp_offset++;
DBG(r300, DBG_RS, "r300: FS input generic %i unassigned%s.\n",
i, sprite_coord ? " (sprite coord)" : "");
}
}
}
@ -355,6 +374,10 @@ static void r300_update_rs_block(struct r300_context* r300,
if (fs_inputs->fog != ATTR_UNUSED) {
rX00_rs_tex_write(&rs, tex_count, fp_offset);
fp_offset++;
DBG(r300, DBG_RS, "r300: Rasterized fog written to FS.\n");
} else {
DBG(r300, DBG_RS, "r300: Rasterized fog unused.\n");
}
tex_count++;
} else {
@ -362,6 +385,8 @@ static void r300_update_rs_block(struct r300_context* r300,
/* If we try to set it to (0,0,0,1), it will lock up. */
if (fs_inputs->fog != ATTR_UNUSED) {
fp_offset++;
DBG(r300, DBG_RS, "r300: FS input fog unassigned.\n");
}
}
@ -371,16 +396,23 @@ static void r300_update_rs_block(struct r300_context* r300,
rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW);
rX00_rs_tex_write(&rs, tex_count, fp_offset);
DBG(r300, DBG_RS, "r300: Rasterized WPOS written to FS.\n");
fp_offset++;
tex_count++;
}
/* Rasterize at least one color, or bad things happen. */
if (col_count == 0 && tex_count == 0) {
rX00_rs_col(&rs, 0, 0, TRUE);
rX00_rs_col(&rs, 0, 0, SWIZ_0001);
col_count++;
DBG(r300, DBG_RS, "r300: Rasterized color 0 to prevent lockups.\n");
}
DBG(r300, DBG_RS, "r300: --- Rasterizer status ---: colors: %i, "
"generics: %i.\n", col_count, tex_count);
rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) |
R300_HIRES_EN;
@ -402,77 +434,6 @@ static void r300_update_derived_shader_state(struct r300_context* r300)
r300_update_rs_block(r300, &vs->outputs, &r300_fs(r300)->shader->inputs);
}
static boolean r300_dsa_writes_depth_stencil(struct r300_dsa_state* dsa)
{
/* We are interested only in the cases when a new depth or stencil value
* can be written and changed. */
/* We might optionally check for [Z func: never] and inspect the stencil
* state in a similar fashion, but it's not terribly important. */
return (dsa->z_buffer_control & R300_Z_WRITE_ENABLE) ||
(dsa->stencil_ref_mask & R300_STENCILWRITEMASK_MASK) ||
((dsa->z_buffer_control & R500_STENCIL_REFMASK_FRONT_BACK) &&
(dsa->stencil_ref_bf & R300_STENCILWRITEMASK_MASK));
}
static boolean r300_dsa_alpha_test_enabled(struct r300_dsa_state* dsa)
{
/* We are interested only in the cases when alpha testing can kill
* a fragment. */
uint32_t af = dsa->alpha_function;
return (af & R300_FG_ALPHA_FUNC_ENABLE) &&
(af & R300_FG_ALPHA_FUNC_ALWAYS) != R300_FG_ALPHA_FUNC_ALWAYS;
}
static void r300_update_ztop(struct r300_context* r300)
{
struct r300_ztop_state* ztop_state =
(struct r300_ztop_state*)r300->ztop_state.state;
/* This is important enough that I felt it warranted a comment.
*
* According to the docs, these are the conditions where ZTOP must be
* disabled:
* 1) Alpha testing enabled
* 2) Texture kill instructions in fragment shader
* 3) Chroma key culling enabled
* 4) W-buffering enabled
*
* The docs claim that for the first three cases, if no ZS writes happen,
* then ZTOP can be used.
*
* (3) will never apply since we do not support chroma-keyed operations.
* (4) will need to be re-examined (and this comment updated) if/when
* Hyper-Z becomes supported.
*
* Additionally, the following conditions require disabled ZTOP:
* 5) Depth writes in fragment shader
* 6) Outstanding occlusion queries
*
* This register causes stalls all the way from SC to CB when changed,
* but it is buffered on-chip so it does not hurt to write it if it has
* not changed.
*
* ~C.
*/
/* ZS writes */
if (r300_dsa_writes_depth_stencil(r300->dsa_state.state) &&
(r300_dsa_alpha_test_enabled(r300->dsa_state.state) || /* (1) */
r300_fs(r300)->shader->info.uses_kill)) { /* (2) */
ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
} else if (r300_fragment_shader_writes_depth(r300_fs(r300))) { /* (5) */
ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
} else if (r300->query_current) { /* (6) */
ztop_state->z_buffer_top = R300_ZTOP_DISABLE;
} else {
ztop_state->z_buffer_top = R300_ZTOP_ENABLE;
}
r300->ztop_state.dirty = TRUE;
}
static void r300_merge_textures_and_samplers(struct r300_context* r300)
{
struct r300_textures_state *state =
@ -578,5 +539,5 @@ void r300_update_derived_state(struct r300_context* r300)
r300_swtcl_vertex_psc(r300);
}
r300_update_ztop(r300);
r300_update_hyperz_state(r300);
}

View file

@ -453,10 +453,17 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) {
return 0;
}
for (i = 0; i < 4; i++) {
for (i = 0; i < desc->nr_channels; i++) {
swizzle |=
MIN2(desc->swizzle[i], R300_SWIZZLE_SELECT_FP_ONE) << (3*i);
}
/* Set (0,0,0,1) in unused components. */
for (; i < 3; i++) {
swizzle |= R300_SWIZZLE_SELECT_FP_ZERO << (3*i);
}
for (; i < 4; i++) {
swizzle |= R300_SWIZZLE_SELECT_FP_ONE << (3*i);
}
return swizzle | (0xf << R300_WRITE_ENA_SHIFT);
}

View file

@ -34,9 +34,6 @@
#include "r300_screen.h"
#include "r300_winsys.h"
/* XXX Enable float textures here. */
/*#define ENABLE_FLOAT_TEXTURES*/
#define TILE_WIDTH 0
#define TILE_HEIGHT 1
@ -74,7 +71,7 @@ static boolean r300_format_is_plain(enum pipe_format format)
* The FORMAT specifies how the texture sampler will treat the texture, and
* makes available X, Y, Z, W, ZERO, and ONE for swizzling. */
uint32_t r300_translate_texformat(enum pipe_format format,
const unsigned char *swizzle)
const unsigned char *swizzle_view)
{
uint32_t result = 0;
const struct util_format_description *desc;
@ -98,6 +95,7 @@ uint32_t r300_translate_texformat(enum pipe_format format,
R300_TX_FORMAT_SIGNED_Z,
R300_TX_FORMAT_SIGNED_W,
};
unsigned char swizzle[4];
desc = util_format_description(format);
@ -144,25 +142,18 @@ uint32_t r300_translate_texformat(enum pipe_format format,
}
}
/* Add swizzle. */
if (!swizzle) {
swizzle = desc->swizzle;
} /*else {
if (swizzle[0] != desc->swizzle[0] ||
swizzle[1] != desc->swizzle[1] ||
swizzle[2] != desc->swizzle[2] ||
swizzle[3] != desc->swizzle[3])
{
const char n[6] = "RGBA01";
fprintf(stderr, "Got different swizzling! Format: %c%c%c%c, "
"View: %c%c%c%c\n",
n[desc->swizzle[0]], n[desc->swizzle[1]],
n[desc->swizzle[2]], n[desc->swizzle[3]],
n[swizzle[0]], n[swizzle[1]], n[swizzle[2]],
n[swizzle[3]]);
/* Get swizzle. */
if (swizzle_view) {
/* Compose two sets of swizzles. */
for (i = 0; i < 4; i++) {
swizzle[i] = swizzle_view[i] <= UTIL_FORMAT_SWIZZLE_W ?
desc->swizzle[swizzle_view[i]] : swizzle_view[i];
}
}*/
} else {
memcpy(swizzle, desc->swizzle, sizeof(swizzle));
}
/* Add swizzle. */
for (i = 0; i < 4; i++) {
switch (swizzle[i]) {
case UTIL_FORMAT_SWIZZLE_X:
@ -316,7 +307,6 @@ uint32_t r300_translate_texformat(enum pipe_format format,
}
return ~0;
#if defined(ENABLE_FLOAT_TEXTURES)
case UTIL_FORMAT_TYPE_FLOAT:
switch (desc->channel[0].size) {
case 16:
@ -340,7 +330,6 @@ uint32_t r300_translate_texformat(enum pipe_format format,
return R300_TX_FORMAT_32F_32F_32F_32F | result;
}
}
#endif
}
return ~0; /* Unsupported/unknown. */
@ -405,16 +394,12 @@ static uint32_t r300_translate_colorformat(enum pipe_format format)
/* 64-bit buffers. */
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
#if defined(ENABLE_FLOAT_TEXTURES)
case PIPE_FORMAT_R16G16B16A16_FLOAT:
#endif
return R300_COLOR_FORMAT_ARGB16161616;
/* 128-bit buffers. */
#if defined(ENABLE_FLOAT_TEXTURES)
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return R300_COLOR_FORMAT_ARGB32323232;
#endif
/* YUV buffers. */
case PIPE_FORMAT_UYVY:
@ -532,7 +517,7 @@ static uint32_t r300_translate_out_fmt(enum pipe_format format)
case PIPE_FORMAT_R10SG10SB10SA2U_NORM:
case PIPE_FORMAT_R16G16B16A16_UNORM:
case PIPE_FORMAT_R16G16B16A16_SNORM:
//case PIPE_FORMAT_R16G16B16A16_FLOAT: /* not in pipe_format */
case PIPE_FORMAT_R16G16B16A16_FLOAT:
case PIPE_FORMAT_R32G32B32A32_FLOAT:
return modifier |
R300_C0_SEL_R | R300_C1_SEL_G |
@ -573,7 +558,7 @@ static void r300_texture_setup_immutable_state(struct r300_screen* screen,
if (tex->uses_pitch) {
/* rectangles love this */
f->format0 |= R300_TX_PITCH_EN;
f->format2 = (tex->pitch[0] - 1) & 0x1fff;
f->format2 = (tex->hwpitch[0] - 1) & 0x1fff;
} else {
/* power of two textures (3D, mipmaps, and no pitch) */
f->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
@ -614,7 +599,7 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen,
if (util_format_is_depth_or_stencil(tex->b.b.format)) {
for (i = 0; i <= tex->b.b.last_level; i++) {
tex->fb_state.depthpitch[i] =
tex->pitch[i] |
tex->hwpitch[i] |
R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
R300_DEPTHMICROTILE(tex->microtile);
}
@ -622,7 +607,7 @@ static void r300_texture_setup_fb_state(struct r300_screen* screen,
} else {
for (i = 0; i <= tex->b.b.last_level; i++) {
tex->fb_state.colorpitch[i] =
tex->pitch[i] |
tex->hwpitch[i] |
r300_translate_colorformat(tex->b.b.format) |
R300_COLOR_TILE(tex->mip_macrotile[i]) |
R300_COLOR_MICROTILE(tex->microtile);
@ -767,7 +752,7 @@ static void r300_texture_3d_fix_mipmapping(struct r300_screen *screen,
unsigned i, size;
if (screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
if (!screen->rws->get_value(screen->rws, R300_VID_DRM_2_3_0) &&
tex->b.b.target == PIPE_TEXTURE_3D &&
tex->b.b.last_level > 0) {
size = 0;
@ -813,6 +798,8 @@ static void r300_setup_miptree(struct r300_screen* screen,
tex->size = tex->offset[i] + size;
tex->layer_size[i] = layer_size;
tex->pitch[i] = stride / util_format_get_blocksize(base->format);
tex->hwpitch[i] =
tex->pitch[i] * util_format_get_blockwidth(base->format);
SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
"(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",

View file

@ -28,7 +28,7 @@
struct r300_texture;
uint32_t r300_translate_texformat(enum pipe_format format,
const unsigned char *swizzle);
const unsigned char *swizzle_view);
uint32_t r500_tx_format_msb_bit(enum pipe_format format);

View file

@ -108,11 +108,9 @@ static unsigned translate_opcode(unsigned opcode)
/* case TGSI_OPCODE_BRK: return RC_OPCODE_BRK; */
case TGSI_OPCODE_IF: return RC_OPCODE_IF;
/* case TGSI_OPCODE_LOOP: return RC_OPCODE_LOOP; */
/* case TGSI_OPCODE_REP: return RC_OPCODE_REP; */
case TGSI_OPCODE_ELSE: return RC_OPCODE_ELSE;
case TGSI_OPCODE_ENDIF: return RC_OPCODE_ENDIF;
/* case TGSI_OPCODE_ENDLOOP: return RC_OPCODE_ENDLOOP; */
/* case TGSI_OPCODE_ENDREP: return RC_OPCODE_ENDREP; */
/* case TGSI_OPCODE_PUSHA: return RC_OPCODE_PUSHA; */
/* case TGSI_OPCODE_POPA: return RC_OPCODE_POPA; */
case TGSI_OPCODE_CEIL: return RC_OPCODE_CEIL;

Some files were not shown because too many files have changed in this diff Show more