Merge branch 'master' into pipe-format-simplify

Conflicts:
	src/gallium/auxiliary/draw/draw_pipe_aaline.c
	src/gallium/auxiliary/draw/draw_pipe_pstipple.c
	src/gallium/auxiliary/util/u_blit.c
	src/gallium/auxiliary/util/u_gen_mipmap.c
	src/gallium/auxiliary/util/u_surface.c
	src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
	src/gallium/drivers/cell/ppu/cell_texture.c
	src/gallium/drivers/llvmpipe/lp_texture.c
	src/gallium/drivers/r300/r300_emit.c
	src/gallium/drivers/r300/r300_texture.c
	src/gallium/drivers/softpipe/sp_texture.c
	src/gallium/drivers/softpipe/sp_tile_cache.c
	src/gallium/drivers/svga/svga_state_vs.c
	src/gallium/include/pipe/p_format.h
	src/gallium/state_trackers/dri/dri_drawable.c
	src/gallium/state_trackers/egl/egl_surface.c
	src/gallium/state_trackers/python/p_device.i
	src/gallium/state_trackers/python/st_softpipe_winsys.c
	src/gallium/state_trackers/vega/api_filters.c
	src/gallium/state_trackers/vega/image.c
	src/gallium/state_trackers/vega/mask.c
	src/gallium/state_trackers/vega/paint.c
	src/gallium/state_trackers/vega/renderer.c
	src/gallium/state_trackers/vega/vg_tracker.c
	src/gallium/state_trackers/xorg/xorg_crtc.c
	src/gallium/state_trackers/xorg/xorg_dri2.c
	src/gallium/state_trackers/xorg/xorg_exa.c
	src/gallium/state_trackers/xorg/xorg_renderer.c
	src/gallium/state_trackers/xorg/xorg_xv.c
	src/gallium/state_trackers/xorg/xvmc/surface.c
	src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
	src/gallium/winsys/drm/radeon/core/radeon_buffer.c
	src/gallium/winsys/egl_xlib/sw_winsys.c
	src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
	src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
	src/gallium/winsys/gdi/gdi_softpipe_winsys.c
	src/gallium/winsys/xlib/xlib_cell.c
	src/gallium/winsys/xlib/xlib_llvmpipe.c
	src/gallium/winsys/xlib/xlib_softpipe.c
	src/mesa/state_tracker/st_cb_fbo.c
	src/mesa/state_tracker/st_cb_texture.c
	src/mesa/state_tracker/st_texture.c
This commit is contained in:
Michal Krol 2009-12-17 22:37:15 +01:00
commit 16c6dce013
418 changed files with 19179 additions and 18124 deletions

View File

@ -182,7 +182,7 @@ ultrix-gcc:
# Rules for making release tarballs
VERSION=7.7-devel
VERSION=7.7-rc2
DIRECTORY = Mesa-$(VERSION)
LIB_NAME = MesaLib-$(VERSION)
DEMO_NAME = MesaDemos-$(VERSION)
@ -225,6 +225,10 @@ MAIN_FILES = \
$(DIRECTORY)/include/GL/vms_x_fix.h \
$(DIRECTORY)/include/GL/wglext.h \
$(DIRECTORY)/include/GL/wmesa.h \
$(DIRECTORY)/src/glsl/Makefile \
$(DIRECTORY)/src/glsl/*/Makefile \
$(DIRECTORY)/src/glsl/*/SConscript \
$(DIRECTORY)/src/glsl/*/*.[ch] \
$(DIRECTORY)/src/Makefile \
$(DIRECTORY)/src/mesa/Makefile* \
$(DIRECTORY)/src/mesa/sources.mak \
@ -240,7 +244,6 @@ MAIN_FILES = \
$(DIRECTORY)/src/mesa/shader/*.[chly] \
$(DIRECTORY)/src/mesa/shader/Makefile \
$(DIRECTORY)/src/mesa/shader/descrip.mms \
$(DIRECTORY)/src/mesa/shader/grammar/*.[ch] \
$(DIRECTORY)/src/mesa/shader/slang/*.[ch] \
$(DIRECTORY)/src/mesa/shader/slang/descrip.mms \
$(DIRECTORY)/src/mesa/shader/slang/library/*.[ch] \

View File

@ -160,6 +160,25 @@ Export('env')
# TODO: Build several variants at the same time?
# http://www.scons.org/wiki/SimultaneousVariantBuilds
if env['platform'] != common.default_platform:
# GLSL code has to be built twice -- one for the host OS, another for the target OS...
host_env = Environment(
# options are ignored
# default tool is used
toolpath = ['#scons'],
ENV = os.environ,
)
host_env['platform'] = common.default_platform
SConscript(
'src/glsl/SConscript',
variant_dir = env['build'] + '/host',
duplicate = 0, # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html
exports={'env':host_env},
)
SConscript(
'src/SConscript',
variant_dir = env['build'],

View File

@ -83,7 +83,7 @@ MOTIF_CFLAGS = -I/usr/include/Motif1.2
# Directories to build
LIB_DIR = lib
SRC_DIRS = mesa gallium egl gallium/winsys glu glut/glx glew glw
SRC_DIRS = glsl mesa gallium egl gallium/winsys glu glut/glx glew glw
GLU_DIRS = sgi
DRIVER_DIRS = x11 osmesa
# Which subdirs under $(TOP)/progs/ to enter:

View File

@ -413,7 +413,7 @@ esac
dnl
dnl Driver specific build directories
dnl
SRC_DIRS="mesa glew"
SRC_DIRS="glsl mesa glew"
GLU_DIRS="sgi"
WINDOW_SYSTEM=""
GALLIUM_DIRS="auxiliary drivers state_trackers"
@ -1143,7 +1143,14 @@ yes)
GALLIUM_STATE_TRACKERS_DIRS=glx
;;
dri)
test "x$enable_egl" = xyes && GALLIUM_STATE_TRACKERS_DIRS=egl
GALLIUM_STATE_TRACKERS_DIRS="dri"
if test "x$enable_egl" = xyes; then
GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS egl"
fi
# Have only tested st/xorg on 1.6.0 servers
PKG_CHECK_MODULES(XORG, [xorg-server >= 1.6.0],
HAVE_XORG="yes"; GALLIUM_STATE_TRACKERS_DIRS="$GALLIUM_STATE_TRACKERS_DIRS xorg",
HAVE_XORG="no")
;;
esac
;;
@ -1206,13 +1213,15 @@ dnl
dnl Gallium Intel configuration
dnl
AC_ARG_ENABLE([gallium-intel],
[AS_HELP_STRING([--disable-gallium-intel],
[build gallium intel @<:@default=enabled@:>@])],
[AS_HELP_STRING([--enable-gallium-intel],
[build gallium intel @<:@default=disabled@:>@])],
[enable_gallium_intel="$enableval"],
[enable_gallium_intel=yes])
[enable_gallium_intel=auto])
if test "x$enable_gallium_intel" = xyes; then
GALLIUM_WINSYS_DRM_DIRS="$GALLIUM_WINSYS_DRM_DIRS intel"
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
elif test "x$enable_gallium_intel" = xauto; then
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS i915"
fi
dnl

View File

@ -56,6 +56,9 @@ tbd
<li>Fixed clipping / provoking vertex bugs in i965 driver.
<li>Assorted build fixes for AIX.
<li>Endianness fixes for the DRI swrast driver (bug 22767).</li>
<li>Point sprite fixes for i915/945 driver.
<li>Fixed assorted memory leaks (usually on error paths)
<li>Fixed some GLSL compiler bugs (ex: 25579)
</ul>
<h2>Changes</h2>

View File

@ -4,7 +4,7 @@ TOP = ..
include $(TOP)/configs/current
SUBDIRS = "$(strip "$(PROGRAM_DIRS)")"
SUBDIRS = $(PROGRAM_DIRS)
default: message subdirs
@ -15,22 +15,18 @@ message:
subdirs:
@if test -n "$(SUBDIRS)" ; then \
for dir in $(SUBDIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE)) || exit 1 ; \
fi \
done \
fi
@list='$(SUBDIRS)'; for dir in $$list ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE)) || exit 1 ; \
fi \
done
# Dummy install target
install:
clean:
-@if test -n "$(SUBDIRS)" ; then \
for dir in $(SUBDIRS) tests ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE) clean) ; \
fi \
done \
fi
@list='$(SUBDIRS)'; for dir in $$list tests ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE) clean) ; \
fi \
done

View File

@ -15,8 +15,6 @@
#define DEPTH 5.0f
static PFNGLFOGCOORDPOINTEREXTPROC glFogCoordPointer_ext;
static GLfloat camz;
static GLint fogMode;

View File

@ -248,6 +248,7 @@ loadImageTextures(void)
free(texData3);
free(texData4);
free(image);
}
}

View File

@ -17,6 +17,7 @@ SOURCES = \
tri-depth2.c \
tri-depthwrite.c \
tri-depthwrite2.c \
tri-inv.c \
tri-param.c \
fp-tri.c

View File

@ -56,7 +56,7 @@ static void Key(unsigned char key, int x, int y)
case 27:
exit(1);
default:
return;
break;
}
glutPostRedisplay();

View File

@ -0,0 +1,47 @@
//
// Fragment shader for procedural bumps
//
// Authors: John Kessenich, Randi Rost
//
// Copyright (c) 2002-2006 3Dlabs Inc. Ltd.
//
// See 3Dlabs-License.txt for license information
//
// Texture mapping/modulation added by Brian Paul
//
varying vec3 LightDir;
varying vec3 EyeDir;
uniform float BumpDensity; // = 16.0
uniform float BumpSize; // = 0.15
uniform float SpecularFactor; // = 0.5
sampler2D Tex;
void main()
{
vec3 ambient = vec3(0.25);
vec3 litColor;
vec2 c = BumpDensity * gl_TexCoord[0].st;
vec2 p = fract(c) - vec2(0.5);
float d, f;
d = p.x * p.x + p.y * p.y;
f = inversesqrt(d + 1.0);
if (d >= BumpSize)
{ p = vec2(0.0); f = 1.0; }
vec3 SurfaceColor = texture2D(Tex, gl_TexCoord[0].st).xyz;
vec3 normDelta = vec3(p.x, p.y, 1.0) * f;
litColor = SurfaceColor * (ambient + max(dot(normDelta, LightDir), 0.0));
vec3 reflectDir = reflect(LightDir, normDelta);
float spec = max(dot(EyeDir, reflectDir), 0.0);
spec *= SpecularFactor;
litColor = min(litColor + spec, vec3(1.0));
gl_FragColor = vec4(litColor, 1.0);
}

View File

@ -12,15 +12,20 @@
#include <GL/glew.h>
#include <GL/glut.h>
#include "shaderutil.h"
#include "readtex.h"
static char *FragProgFile = "CH11-bumpmap.frag";
static char *FragTexProgFile = "CH11-bumpmaptex.frag";
static char *VertProgFile = "CH11-bumpmap.vert";
static char *TextureFile = "../images/tile.rgb";
/* program/shader objects */
static GLuint fragShader;
static GLuint fragTexShader;
static GLuint vertShader;
static GLuint program;
static GLuint texProgram;
static struct uniform_info Uniforms[] = {
@ -32,13 +37,26 @@ static struct uniform_info Uniforms[] = {
END_OF_UNIFORMS
};
static struct uniform_info TexUniforms[] = {
{ "LightPosition", 1, GL_FLOAT_VEC3, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
{ "Tex", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
{ "BumpDensity", 1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 },
{ "BumpSize", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
{ "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
END_OF_UNIFORMS
};
static GLint win = 0;
static GLfloat xRot = 20.0f, yRot = 0.0f, zRot = 0.0f;
static GLint tangentAttrib;
static GLint tangentAttribTex;
static GLuint Texture;
static GLboolean Anim = GL_FALSE;
static GLboolean Textured = GL_FALSE;
static void
@ -135,6 +153,11 @@ Redisplay(void)
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glRotatef(zRot, 0.0f, 0.0f, 1.0f);
if (Textured)
glUseProgram(texProgram);
else
glUseProgram(program);
Cube(1.5);
glPopMatrix();
@ -163,8 +186,10 @@ static void
CleanUp(void)
{
glDeleteShader(fragShader);
glDeleteShader(fragTexShader);
glDeleteShader(vertShader);
glDeleteProgram(program);
glDeleteProgram(texProgram);
glutDestroyWindow(win);
}
@ -181,6 +206,9 @@ Key(unsigned char key, int x, int y)
Anim = !Anim;
glutIdleFunc(Anim ? Idle : NULL);
break;
case 't':
Textured = !Textured;
break;
case 'z':
zRot += step;
break;
@ -254,6 +282,26 @@ Init(void)
CheckError(__LINE__);
/*
* As above, but fragment shader also uses a texture map.
*/
fragTexShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragTexProgFile);
texProgram = LinkShaders(vertShader, fragTexShader);
glUseProgram(texProgram);
assert(glIsProgram(texProgram));
assert(glIsShader(fragTexShader));
SetUniformValues(texProgram, TexUniforms);
PrintUniforms(TexUniforms);
/*
* Load tex image.
*/
glGenTextures(1, &Texture);
glBindTexture(GL_TEXTURE_2D, Texture);
LoadRGBMipmaps(TextureFile, GL_RGB);
glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
glEnable(GL_DEPTH_TEST);
@ -268,10 +316,13 @@ ParseOptions(int argc, char *argv[])
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-fs") == 0) {
FragProgFile = argv[i+1];
FragProgFile = argv[++i];
}
else if (strcmp(argv[i], "-vs") == 0) {
VertProgFile = argv[i+1];
VertProgFile = argv[++i];
}
else if (strcmp(argv[i], "-t") == 0) {
TextureFile = argv[++i];
}
}
}

View File

@ -27,11 +27,15 @@ static GLuint SphereList, RectList, CurList;
static GLint win = 0;
static GLboolean anim = GL_TRUE;
static GLfloat xRot = 0.0f, yRot = 0.0f;
static GLint WinSize[2];
static GLint WinSizeUniform = -1;
static void
Redisplay(void)
{
glUniform2iv(WinSizeUniform, 1, WinSize);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
@ -55,6 +59,8 @@ Idle(void)
static void
Reshape(int width, int height)
{
WinSize[0] = width;
WinSize[1] = height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -163,8 +169,10 @@ static void
Init(void)
{
static const char *fragShaderText =
"uniform ivec2 WinSize; \n"
"void main() {\n"
" gl_FragColor = abs(dFdy(gl_TexCoord[0])) * 50.0;\n"
" vec2 d = dFdy(gl_TexCoord[0].xy) * vec2(WinSize); \n"
" gl_FragColor = vec4(d.x, d.y, 0.0, 1.0);\n"
" // gl_FragColor = gl_TexCoord[0];\n"
"}\n";
static const char *vertShaderText =
@ -181,6 +189,7 @@ Init(void)
program = LinkShaders(vertShader, fragShader);
glUseProgram(program);
WinSizeUniform = glGetUniformLocation(program, "WinSize");
/*assert(glGetError() == 0);*/
@ -220,8 +229,10 @@ ParseOptions(int argc, char *argv[])
int
main(int argc, char *argv[])
{
WinSize[0] = WinSize[1] = 200;
glutInit(&argc, argv);
glutInitWindowSize(200, 200);
glutInitWindowSize(WinSize[0], WinSize[1]);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glewInit();

View File

@ -10,7 +10,7 @@ LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(T
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
PROGS = accum bitmap1 bitmap2 blendeq blendxor copy cursor depth eval fog \
font line logo nurb olympic overlay point prim quad select \
font line logo nurb olympic overlay point prim rgbtoppm quad select \
shape sphere star stencil stretch texture tri wave

View File

@ -86,13 +86,19 @@ static ImageRec *ImageOpen(char *fileName)
exit(1);
}
if ((image->file = fopen(fileName, "rb")) == NULL) {
return NULL;
free(image);
return NULL;
}
fread(image, 1, 12, image->file);
if (swapFlag) {
ConvertShort(&image->imagic, 6);
ConvertShort(&image->imagic, 1);
ConvertShort(&image->type, 1);
ConvertShort(&image->dim, 1);
ConvertShort(&image->xsize, 1);
ConvertShort(&image->ysize, 1);
ConvertShort(&image->zsize, 1);
}
image->tmp = (unsigned char *)malloc(image->xsize*256);
@ -224,6 +230,7 @@ read_rgb_texture(char *name, int *width, int *height)
if (gbuf) free(gbuf);
if (bbuf) free(bbuf);
if (abuf) free(abuf);
ImageClose(image);
return NULL;
}
ptr = base;

View File

@ -98,6 +98,7 @@ SOURCES = \
texdown \
texfilt.c \
texgenmix.c \
texleak.c \
texline.c \
texobj.c \
texobjshare.c \

View File

@ -192,6 +192,7 @@ static void Init( void )
GLfloat * params;
GLint max_program_env_parameters;
GLint max_program_local_parameters;
int i;
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
@ -238,6 +239,10 @@ static void Init( void )
params = malloc(max_program_env_parameters * 4 * sizeof(GLfloat));
for (i = 0; i < max_program_env_parameters * 4; i++) {
params[i] = 0.0F;
}
pass &= set_parameter_batch(max_program_env_parameters, params, "Env",
program_env_parameter4fv,
program_env_parameters4fv,

View File

@ -162,7 +162,7 @@ MeasureDownloadRate(void)
const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN);
const int bytes = image_bytes * NR_TEXOBJ;
GLubyte *orig_texImage, *orig_getImage;
GLubyte *texImage, *getImage;
GLubyte *texImage;
GLdouble t0, t1, time;
int count;
int i;
@ -184,7 +184,6 @@ MeasureDownloadRate(void)
printf("alloc %p %p\n", orig_texImage, orig_getImage);
texImage = (GLubyte *)align((unsigned long)orig_texImage, ALIGN);
getImage = (GLubyte *)align((unsigned long)orig_getImage, ALIGN);
for (i = 1; !(((unsigned long)texImage) & i); i<<=1)
;

140
progs/tests/texleak.c Normal file
View File

@ -0,0 +1,140 @@
/*
* 'Texture leak' test
*
* Allocates and uses an additional texture of the maximum supported size for
* each frame. This tests the system's ability to cope with using increasing
* amounts of texture memory.
*
* Michel Dänzer July 2009 This program is in the public domain.
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <GL/glew.h>
#include <GL/glut.h>
GLint size;
GLvoid *image;
static GLuint numTexObj;
static GLuint *texObj;
static void Idle( void )
{
glutPostRedisplay();
}
static void DrawObject(void)
{
static const GLfloat tex_coords[] = { 0.0, 0.0, 1.0, 1.0, 0.0 };
static const GLfloat vtx_coords[] = { -1.0, -1.0, 1.0, 1.0, -1.0 };
GLint i, j;
glEnable(GL_TEXTURE_2D);
for (i = 0; i < numTexObj; i++) {
glBindTexture(GL_TEXTURE_2D, texObj[i]);
glBegin(GL_QUADS);
for (j = 0; j < 4; j++ ) {
glTexCoord2f(tex_coords[j], tex_coords[j+1]);
glVertex2f( vtx_coords[j], vtx_coords[j+1] );
}
glEnd();
}
}
static void Display( void )
{
struct timeval start, end;
texObj = realloc(texObj, ++numTexObj * sizeof(*texObj));
/* allocate a texture object */
glGenTextures(1, texObj + (numTexObj - 1));
glBindTexture(GL_TEXTURE_2D, texObj[numTexObj - 1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
memset(image, (16 * numTexObj) & 0xff, 4 * size * size);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
gettimeofday(&start, NULL);
glClear( GL_COLOR_BUFFER_BIT );
glPushMatrix();
glScalef(5.0, 5.0, 5.0);
DrawObject();
glPopMatrix();
glutSwapBuffers();
glFinish();
gettimeofday(&end, NULL);
printf("Rendering frame took %lu ms using %u MB of textures\n",
end.tv_sec * 1000 + end.tv_usec / 1000 - start.tv_sec * 1000 -
start.tv_usec / 1000, numTexObj * 4 * size / 1024 * size / 1024);
sleep(1);
}
static void Reshape( int width, int height )
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -6.0, 6.0, -6.0, 6.0, 10.0, 100.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0, 0.0, -70.0 );
}
static void Init( int argc, char *argv[] )
{
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
printf("%d x %d max texture size\n", size, size);
image = malloc(4 * size * size);
if (!image) {
fprintf(stderr, "Failed to allocate %u bytes of memory\n", 4 * size * size);
exit(1);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glShadeModel(GL_FLAT);
glClearColor(0.3, 0.3, 0.4, 1.0);
Idle();
}
int main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitWindowSize( 300, 300 );
glutInitWindowPosition( 0, 0 );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
glutCreateWindow(argv[0] );
glewInit();
Init( argc, argv );
glutReshapeFunc( Reshape );
glutDisplayFunc( Display );
glutIdleFunc(Idle);
glutMainLoop();
return 0;
}

View File

@ -117,7 +117,12 @@ static rawImageRec *RawImageOpen(const char *fileName)
fread(raw, 1, 12, raw->file);
if (swapFlag) {
ConvertShort(&raw->imagic, 6);
ConvertShort(&raw->imagic, 1);
ConvertShort(&raw->type, 1);
ConvertShort(&raw->dim, 1);
ConvertShort(&raw->sizeX, 1);
ConvertShort(&raw->sizeY, 1);
ConvertShort(&raw->sizeZ, 1);
}
raw->tmp = (unsigned char *)malloc(raw->sizeX*256);

View File

@ -84,9 +84,9 @@ static void check_link(GLuint prog)
static void setup_uniforms()
{
{
GLuint loc1f = glGetUniformLocationARB(program, "Offset1f");
GLuint loc2f = glGetUniformLocationARB(program, "Offset2f");
GLuint loc4f = glGetUniformLocationARB(program, "Offset4f");
GLint loc1f = glGetUniformLocationARB(program, "Offset1f");
GLint loc2f = glGetUniformLocationARB(program, "Offset2f");
GLint loc4f = glGetUniformLocationARB(program, "Offset4f");
GLfloat vecKer[] =
{ 1.0, 0.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
@ -105,9 +105,9 @@ static void setup_uniforms()
}
{
GLuint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
GLuint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
GLuint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
GLint loc1f = glGetUniformLocationARB(program, "KernelValue1f");
GLint loc2f = glGetUniformLocationARB(program, "KernelValue2f");
GLint loc4f = glGetUniformLocationARB(program, "KernelValue4f");
GLfloat vecKer[] =
{ 1.0, 0.0, 0.0, 0.25,
0.0, 1.0, 0.0, 0.25,

View File

@ -401,6 +401,10 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
root = RootWindow(dpy, scrnum);
/*
* Find a basic GLX visual. We'll then create a rendering context and
* query various info strings.
*/
visinfo = glXChooseVisual(dpy, scrnum, attribSingle);
if (!visinfo)
visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
@ -409,24 +413,29 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect, GLboolean limits)
ctx = glXCreateContext( dpy, visinfo, NULL, allowDirect );
#ifdef GLX_VERSION_1_3
{
/* Try glXChooseFBConfig() if glXChooseVisual didn't work.
* XXX when would that happen?
*/
if (!visinfo) {
int fbAttribSingle[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER, GL_TRUE,
GLX_DOUBLEBUFFER, GL_FALSE,
None };
int fbAttribDouble[] = {
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
GLX_DOUBLEBUFFER, GL_TRUE,
None };
GLXFBConfig *configs = NULL;
int nConfigs;
if (!visinfo)
configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs);
if (!configs)
configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs);
if (configs) {

View File

@ -390,15 +390,15 @@ def generate(env):
else:
ccflags += [
'/O2', # optimize for speed
#'/fp:fast', # fast floating point
'/GL', # enable whole program optimization
]
ccflags += [
'/fp:fast', # fast floating point
'/W3', # warning level
#'/Wp64', # enable 64 bit porting warnings
]
if env['machine'] == 'x86':
ccflags += [
#'/QIfist', # Suppress _ftol
#'/arch:SSE2', # use the SSE2 instructions
]
if platform == 'windows':
@ -476,6 +476,11 @@ def generate(env):
]
# Handle circular dependencies in the libraries
env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
if msvc:
if not env['debug']:
# enable Link-time Code Generation
linkflags += ['/LTCG']
env.Append(ARFLAGS = ['/LTCG'])
if platform == 'windows' and msvc:
# See also:
# - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx

View File

@ -1,5 +1,6 @@
Import('*')
SConscript('glsl/SConscript')
SConscript('gallium/SConscript')
if 'mesa' in env['statetrackers']:

View File

@ -404,7 +404,6 @@ aaline_create_texture(struct aaline_stage *aaline)
texTemp.width0 = 1 << MAX_TEXTURE_LEVEL;
texTemp.height0 = 1 << MAX_TEXTURE_LEVEL;
texTemp.depth0 = 1;
util_format_get_block(texTemp.format, &texTemp.block);
aaline->texture = screen->texture_create(screen, &texTemp);
if (!aaline->texture)

View File

@ -432,7 +432,6 @@ pstip_create_texture(struct pstip_stage *pstip)
texTemp.width0 = 32;
texTemp.height0 = 32;
texTemp.depth0 = 1;
util_format_get_block(texTemp.format, &texTemp.block);
pstip->texture = screen->texture_create(screen, &texTemp);
if (pstip->texture == NULL)

View File

@ -237,8 +237,9 @@ pb_reference(struct pb_buffer **dst,
{
struct pb_buffer *old = *dst;
if (pipe_reference((struct pipe_reference**)dst, &src->base.reference))
if (pipe_reference(&(*dst)->base.reference, &src->base.reference))
pb_destroy( old );
*dst = src;
}

View File

@ -243,6 +243,7 @@ fenced_buffer_list_check_free_locked(struct fenced_buffer_list *fenced_list,
struct pb_fence_ops *ops = fenced_list->ops;
struct list_head *curr, *next;
struct fenced_buffer *fenced_buf;
struct pb_buffer *pb_buf;
struct pipe_fence_handle *prev_fence = NULL;
curr = fenced_list->delayed.next;
@ -271,7 +272,9 @@ fenced_buffer_list_check_free_locked(struct fenced_buffer_list *fenced_list,
fenced_buffer_remove_locked(fenced_list, fenced_buf);
pipe_mutex_unlock(fenced_buf->mutex);
pb_reference((struct pb_buffer **)&fenced_buf, NULL);
pb_buf = &fenced_buf->base;
pb_reference(&pb_buf, NULL);
curr = next;
next = curr->next;

View File

@ -294,7 +294,7 @@ pb_cache_manager_create_buffer(struct pb_manager *_mgr,
LIST_DEL(&buf->head);
pipe_mutex_unlock(mgr->mutex);
/* Increase refcount */
pb_reference((struct pb_buffer**)&buf, &buf->base);
pipe_reference(NULL, &buf->base.base.reference);
return &buf->base;
}

View File

@ -87,6 +87,7 @@ rbug_get_message(struct rbug_connection *c, uint32_t *serial)
if (!data) {
return NULL;
}
data->opcode = 0;
do {
uint8_t *ptr = ((uint8_t*)data) + read;

View File

@ -399,7 +399,7 @@ tgsi_default_instruction( void )
struct tgsi_instruction instruction;
instruction.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
instruction.NrTokens = 1;
instruction.NrTokens = 0;
instruction.Opcode = TGSI_OPCODE_MOV;
instruction.Saturate = TGSI_SAT_NONE;
instruction.Predicate = 0;
@ -942,3 +942,107 @@ tgsi_default_full_dst_register( void )
return full_dst_register;
}
struct tgsi_property
tgsi_default_property( void )
{
struct tgsi_property property;
property.Type = TGSI_TOKEN_TYPE_PROPERTY;
property.NrTokens = 1;
property.PropertyName = TGSI_PROPERTY_GS_INPUT_PRIM;
property.Padding = 0;
return property;
}
struct tgsi_property
tgsi_build_property(unsigned property_name,
struct tgsi_header *header)
{
struct tgsi_property property;
property = tgsi_default_property();
property.PropertyName = property_name;
header_bodysize_grow( header );
return property;
}
struct tgsi_full_property
tgsi_default_full_property( void )
{
struct tgsi_full_property full_property;
full_property.Property = tgsi_default_property();
memset(full_property.u, 0,
sizeof(struct tgsi_property_data) * 8);
return full_property;
}
static void
property_grow(
struct tgsi_property *property,
struct tgsi_header *header )
{
assert( property->NrTokens < 0xFF );
property->NrTokens++;
header_bodysize_grow( header );
}
struct tgsi_property_data
tgsi_build_property_data(
unsigned value,
struct tgsi_property *property,
struct tgsi_header *header )
{
struct tgsi_property_data property_data;
property_data.Data = value;
property_grow( property, header );
return property_data;
}
unsigned
tgsi_build_full_property(
const struct tgsi_full_property *full_prop,
struct tgsi_token *tokens,
struct tgsi_header *header,
unsigned maxsize )
{
unsigned size = 0, i;
struct tgsi_property *property;
if( maxsize <= size )
return 0;
property = (struct tgsi_property *) &tokens[size];
size++;
*property = tgsi_build_property(
TGSI_PROPERTY_GS_INPUT_PRIM,
header );
assert( full_prop->Property.NrTokens <= 8 + 1 );
for( i = 0; i < full_prop->Property.NrTokens - 1; i++ ) {
struct tgsi_property_data *data;
if( maxsize <= size )
return 0;
data = (struct tgsi_property_data *) &tokens[size];
size++;
*data = tgsi_build_property_data(
full_prop->u[i].Data,
property,
header );
}
return size;
}

View File

@ -126,6 +126,34 @@ tgsi_build_full_immediate(
struct tgsi_header *header,
unsigned maxsize );
/*
* properties
*/
struct tgsi_property
tgsi_default_property( void );
struct tgsi_property
tgsi_build_property(
unsigned property_name,
struct tgsi_header *header );
struct tgsi_full_property
tgsi_default_full_property( void );
struct tgsi_property_data
tgsi_build_property_data(
unsigned value,
struct tgsi_property *property,
struct tgsi_header *header );
unsigned
tgsi_build_full_property(
const struct tgsi_full_property *full_prop,
struct tgsi_token *tokens,
struct tgsi_header *header,
unsigned maxsize );
/*
* instruction
*/

View File

@ -101,7 +101,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"ADDR",
"IMM",
"LOOP",
"PRED"
"PRED",
"SV"
};
static const char *interpolate_names[] =
@ -149,6 +150,27 @@ static const char *texture_names[] =
"SHADOWRECT"
};
static const char *property_names[] =
{
"GS_INPUT_PRIMITIVE",
"GS_OUTPUT_PRIMITIVE",
"GS_MAX_OUTPUT_VERTICES"
};
static const char *primitive_names[] =
{
"POINTS",
"LINES",
"LINE_LOOP",
"LINE_STRIP",
"TRIANGLES",
"TRIANGLE_STRIP",
"TRIANGLE_FAN",
"QUADS",
"QUAD_STRIP",
"POLYGON"
};
static void
_dump_register(
@ -272,6 +294,50 @@ tgsi_dump_declaration(
iter_declaration( &ctx.iter, (struct tgsi_full_declaration *)decl );
}
static boolean
iter_property(
struct tgsi_iterate_context *iter,
struct tgsi_full_property *prop )
{
int i;
struct dump_ctx *ctx = (struct dump_ctx *)iter;
assert(Elements(property_names) == TGSI_PROPERTY_COUNT);
TXT( "PROPERTY " );
ENM(prop->Property.PropertyName, property_names);
if (prop->Property.NrTokens > 1)
TXT(" ");
for (i = 0; i < prop->Property.NrTokens - 1; ++i) {
switch (prop->Property.PropertyName) {
case TGSI_PROPERTY_GS_INPUT_PRIM:
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
ENM(prop->u[i].Data, primitive_names);
break;
default:
SID( prop->u[i].Data );
break;
}
if (i < prop->Property.NrTokens - 2)
TXT( ", " );
}
EOL();
return TRUE;
}
void tgsi_dump_property(
const struct tgsi_full_property *prop )
{
struct dump_ctx ctx;
ctx.printf = dump_ctx_printf;
iter_property( &ctx.iter, (struct tgsi_full_property *)prop );
}
static boolean
iter_immediate(
struct tgsi_iterate_context *iter,
@ -492,6 +558,7 @@ tgsi_dump(
ctx.iter.iterate_instruction = iter_instruction;
ctx.iter.iterate_declaration = iter_declaration;
ctx.iter.iterate_immediate = iter_immediate;
ctx.iter.iterate_property = iter_property;
ctx.iter.epilog = NULL;
ctx.instno = 0;
@ -546,6 +613,7 @@ tgsi_dump_str(
ctx.base.iter.iterate_instruction = iter_instruction;
ctx.base.iter.iterate_declaration = iter_declaration;
ctx.base.iter.iterate_immediate = iter_immediate;
ctx.base.iter.iterate_property = iter_property;
ctx.base.iter.epilog = NULL;
ctx.base.instno = 0;

View File

@ -49,6 +49,7 @@ tgsi_dump(
struct tgsi_full_immediate;
struct tgsi_full_instruction;
struct tgsi_full_declaration;
struct tgsi_full_property;
void
tgsi_dump_immediate(
@ -63,6 +64,10 @@ void
tgsi_dump_declaration(
const struct tgsi_full_declaration *decl );
void
tgsi_dump_property(
const struct tgsi_full_property *prop );
#if defined __cplusplus
}
#endif

View File

@ -336,6 +336,9 @@ tgsi_exec_machine_bind_shader(
numInstructions++;
break;
case TGSI_TOKEN_TYPE_PROPERTY:
break;
default:
assert( 0 );
}
@ -1158,6 +1161,7 @@ fetch_src_file_channel(
break;
case TGSI_FILE_INPUT:
case TGSI_FILE_SYSTEM_VALUE:
chan->u[0] = mach->Inputs[index->i[0]].xyzw[swizzle].u[0];
chan->u[1] = mach->Inputs[index->i[1]].xyzw[swizzle].u[1];
chan->u[2] = mach->Inputs[index->i[2]].xyzw[swizzle].u[2];
@ -1302,6 +1306,7 @@ fetch_source(
*/
switch (reg->Register.File) {
case TGSI_FILE_INPUT:
case TGSI_FILE_SYSTEM_VALUE:
index.i[0] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
index.i[1] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
index.i[2] *= TGSI_EXEC_MAX_INPUT_ATTRIBS;
@ -1892,7 +1897,8 @@ exec_declaration(struct tgsi_exec_machine *mach,
const struct tgsi_full_declaration *decl)
{
if (mach->Processor == TGSI_PROCESSOR_FRAGMENT) {
if (decl->Declaration.File == TGSI_FILE_INPUT) {
if (decl->Declaration.File == TGSI_FILE_INPUT ||
decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE) {
uint first, last, mask;
first = decl->Range.First;

View File

@ -66,6 +66,12 @@ tgsi_iterate_shader(
goto fail;
break;
case TGSI_TOKEN_TYPE_PROPERTY:
if (ctx->iterate_property)
if (!ctx->iterate_property( ctx, &parse.FullToken.FullProperty ))
goto fail;
break;
default:
assert( 0 );
}

View File

@ -56,6 +56,11 @@ struct tgsi_iterate_context
struct tgsi_iterate_context *ctx,
struct tgsi_full_immediate *imm );
boolean
(* iterate_property)(
struct tgsi_iterate_context *ctx,
struct tgsi_full_property *prop );
boolean
(* epilog)(
struct tgsi_iterate_context *ctx );

View File

@ -60,7 +60,7 @@ tgsi_parse_end_of_tokens(
struct tgsi_parse_context *ctx )
{
return ctx->Position >=
1 + ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
ctx->FullHeader.Header.HeaderSize + ctx->FullHeader.Header.BodySize;
}
@ -220,6 +220,22 @@ tgsi_parse_token(
break;
}
case TGSI_TOKEN_TYPE_PROPERTY:
{
struct tgsi_full_property *prop = &ctx->FullToken.FullProperty;
uint prop_count;
memset(prop, 0, sizeof *prop);
copy_token(&prop->Property, &token);
prop_count = prop->Property.NrTokens - 1;
for (i = 0; i < prop_count; i++) {
next_token(ctx, &prop->u[i]);
}
break;
}
default:
assert( 0 );
}
@ -232,8 +248,7 @@ tgsi_num_tokens(const struct tgsi_token *tokens)
struct tgsi_parse_context ctx;
if (tgsi_parse_init(&ctx, tokens) == TGSI_PARSE_OK) {
unsigned len = (ctx.FullHeader.Header.HeaderSize +
ctx.FullHeader.Header.BodySize +
1);
ctx.FullHeader.Header.BodySize);
return len;
}
return 0;

View File

@ -67,6 +67,12 @@ struct tgsi_full_immediate
union tgsi_immediate_data u[4];
};
struct tgsi_full_property
{
struct tgsi_property Property;
struct tgsi_property_data u[8];
};
#define TGSI_FULL_MAX_DST_REGISTERS 2
#define TGSI_FULL_MAX_SRC_REGISTERS 4 /* TXD has 4 */
@ -86,6 +92,7 @@ union tgsi_full_token
struct tgsi_full_declaration FullDeclaration;
struct tgsi_full_immediate FullImmediate;
struct tgsi_full_instruction FullInstruction;
struct tgsi_full_property FullProperty;
};
struct tgsi_parse_context

View File

@ -293,6 +293,7 @@ emit_fetch(struct gen_context *gen,
case TGSI_SWIZZLE_W:
switch (reg->Register.File) {
case TGSI_FILE_INPUT:
case TGSI_FILE_SYSTEM_VALUE:
{
int offset = (reg->Register.Index * 4 + swizzle) * 16;
int offset_reg = emit_li_offset(gen, offset);
@ -1173,7 +1174,8 @@ emit_declaration(
struct ppc_function *func,
struct tgsi_full_declaration *decl )
{
if( decl->Declaration.File == TGSI_FILE_INPUT ) {
if( decl->Declaration.File == TGSI_FILE_INPUT ||
decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
#if 0
unsigned first, last, mask;
unsigned i, j;
@ -1339,6 +1341,9 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
}
break;
case TGSI_TOKEN_TYPE_PROPERTY:
break;
default:
ok = 0;
assert( 0 );

View File

@ -324,6 +324,17 @@ iter_immediate(
return TRUE;
}
static boolean
iter_property(
struct tgsi_iterate_context *iter,
struct tgsi_full_property *prop )
{
/*struct sanity_check_ctx *ctx = (struct sanity_check_ctx *) iter;*/
return TRUE;
}
static boolean
epilog(
struct tgsi_iterate_context *iter )
@ -367,6 +378,7 @@ tgsi_sanity_check(
ctx.iter.iterate_instruction = iter_instruction;
ctx.iter.iterate_declaration = iter_declaration;
ctx.iter.iterate_immediate = iter_immediate;
ctx.iter.iterate_property = iter_property;
ctx.iter.epilog = epilog;
memset( ctx.regs_decl, 0, sizeof( ctx.regs_decl ) );

View File

@ -97,7 +97,8 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *src =
&fullinst->Src[i];
if (src->Register.File == TGSI_FILE_INPUT) {
if (src->Register.File == TGSI_FILE_INPUT ||
src->Register.File == TGSI_FILE_SYSTEM_VALUE) {
const int ind = src->Register.Index;
if (info->input_semantic_name[ind] == TGSI_SEMANTIC_FOG) {
if (src->Register.SwizzleX == TGSI_SWIZZLE_X) {
@ -128,7 +129,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->file_count[file]++;
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
if (file == TGSI_FILE_INPUT) {
if (file == TGSI_FILE_INPUT || file == TGSI_FILE_SYSTEM_VALUE) {
info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.Name;
info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.Index;
info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
@ -160,6 +161,19 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
info->file_max[file] = MAX2(info->file_max[file], (int)reg);
}
break;
case TGSI_TOKEN_TYPE_PROPERTY:
{
const struct tgsi_full_property *fullprop
= &parse.FullToken.FullProperty;
info->properties[info->num_properties].name =
fullprop->Property.PropertyName;
memcpy(info->properties[info->num_properties].data,
fullprop->u, 8 * sizeof(unsigned));;
++info->num_properties;
}
break;
default:
assert( 0 );
@ -212,6 +226,7 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
/* Do a whole bunch of checks for a simple move */
if (fullinst->Instruction.Opcode != TGSI_OPCODE_MOV ||
src->Register.File != TGSI_FILE_INPUT ||
src->Register.File != TGSI_FILE_SYSTEM_VALUE ||
dst->Register.File != TGSI_FILE_OUTPUT ||
src->Register.Index != dst->Register.Index ||
@ -235,6 +250,8 @@ tgsi_is_passthrough_shader(const struct tgsi_token *tokens)
/* fall-through */
case TGSI_TOKEN_TYPE_IMMEDIATE:
/* fall-through */
case TGSI_TOKEN_TYPE_PROPERTY:
/* fall-through */
default:
; /* no-op */
}

View File

@ -33,7 +33,6 @@
#include "pipe/p_state.h"
#include "pipe/p_shader_tokens.h"
/**
* Shader summary info
*/
@ -61,8 +60,13 @@ struct tgsi_shader_info
boolean uses_kill; /**< KIL or KILP instruction used? */
boolean uses_fogcoord; /**< fragment shader uses fog coord? */
boolean uses_frontfacing; /**< fragment shader uses front/back-face flag? */
};
struct {
unsigned name;
unsigned data[8];
} properties[TGSI_PROPERTY_COUNT];
uint num_properties;
};
extern void
tgsi_scan_shader(const struct tgsi_token *tokens,

View File

@ -1288,6 +1288,7 @@ emit_fetch(
break;
case TGSI_FILE_INPUT:
case TGSI_FILE_SYSTEM_VALUE:
emit_inputf(
func,
xmm,
@ -2633,7 +2634,8 @@ emit_declaration(
struct x86_function *func,
struct tgsi_full_declaration *decl )
{
if( decl->Declaration.File == TGSI_FILE_INPUT ) {
if( decl->Declaration.File == TGSI_FILE_INPUT ||
decl->Declaration.File == TGSI_FILE_SYSTEM_VALUE ) {
unsigned first, last, mask;
unsigned i, j;
@ -2952,6 +2954,9 @@ tgsi_emit_sse2(
num_immediates++;
}
break;
case TGSI_TOKEN_TYPE_PROPERTY:
/* we just ignore them for now */
break;
default:
ok = 0;

View File

@ -27,6 +27,7 @@
#include "util/u_debug.h"
#include "util/u_memory.h"
#include "pipe/p_defines.h"
#include "tgsi_text.h"
#include "tgsi_build.h"
#include "tgsi_info.h"
@ -59,6 +60,21 @@ static boolean uprcase( char c )
return c;
}
/*
* Ignore case of str1 and assume str2 is already uppercase.
* Return TRUE iff str1 and str2 are equal.
*/
static int
streq_nocase_uprcase(const char *str1,
const char *str2)
{
while (*str1 && uprcase(*str1) == *str2) {
str1++;
str2++;
}
return *str1 == *str2;
}
static boolean str_match_no_case( const char **pcur, const char *str )
{
const char *cur = *pcur;
@ -110,6 +126,20 @@ static boolean parse_uint( const char **pcur, uint *val )
return FALSE;
}
static boolean parse_identifier( const char **pcur, char *ret )
{
const char *cur = *pcur;
int i = 0;
if (is_alpha_underscore( cur )) {
ret[i++] = *cur++;
while (is_alpha_underscore( cur ))
ret[i++] = *cur++;
*pcur = cur;
return TRUE;
}
return FALSE;
}
/* Parse floating point.
*/
static boolean parse_float( const char **pcur, float *val )
@ -229,7 +259,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"ADDR",
"IMM",
"LOOP",
"PRED"
"PRED",
"SV"
};
static boolean
@ -939,6 +970,106 @@ static boolean parse_immediate( struct translate_ctx *ctx )
return TRUE;
}
static const char *property_names[] =
{
"GS_INPUT_PRIMITIVE",
"GS_OUTPUT_PRIMITIVE",
"GS_MAX_OUTPUT_VERTICES"
};
static const char *primitive_names[] =
{
"POINTS",
"LINES",
"LINE_LOOP",
"LINE_STRIP",
"TRIANGLES",
"TRIANGLE_STRIP",
"TRIANGLE_FAN",
"QUADS",
"QUAD_STRIP",
"POLYGON"
};
static boolean
parse_primitive( const char **pcur, uint *primitive )
{
uint i;
for (i = 0; i < PIPE_PRIM_MAX; i++) {
const char *cur = *pcur;
if (str_match_no_case( &cur, primitive_names[i])) {
*primitive = i;
*pcur = cur;
return TRUE;
}
}
return FALSE;
}
static boolean parse_property( struct translate_ctx *ctx )
{
struct tgsi_full_property prop;
uint property_name;
uint values[8];
uint advance;
char id[64];
if (!eat_white( &ctx->cur )) {
report_error( ctx, "Syntax error" );
return FALSE;
}
if (!parse_identifier( &ctx->cur, id )) {
report_error( ctx, "Syntax error" );
return FALSE;
}
for (property_name = 0; property_name < TGSI_PROPERTY_COUNT;
++property_name) {
if (streq_nocase_uprcase(id, property_names[property_name])) {
break;
}
}
if (property_name >= TGSI_PROPERTY_COUNT) {
debug_printf( "\nError: Unknown property : '%s'", id );
return FALSE;
}
eat_opt_white( &ctx->cur );
switch(property_name) {
case TGSI_PROPERTY_GS_INPUT_PRIM:
case TGSI_PROPERTY_GS_OUTPUT_PRIM:
if (!parse_primitive(&ctx->cur, &values[0] )) {
report_error( ctx, "Unknown primitive name as property!" );
return FALSE;
}
break;
default:
if (!parse_uint(&ctx->cur, &values[0] )) {
report_error( ctx, "Expected unsigned integer as property!" );
return FALSE;
}
}
prop = tgsi_default_full_property();
prop.Property.PropertyName = property_name;
prop.Property.NrTokens += 1;
prop.u[0].Data = values[0];
advance = tgsi_build_full_property(
&prop,
ctx->tokens_cur,
ctx->header,
(uint) (ctx->tokens_end - ctx->tokens_cur) );
if (advance == 0)
return FALSE;
ctx->tokens_cur += advance;
return TRUE;
}
static boolean translate( struct translate_ctx *ctx )
{
eat_opt_white( &ctx->cur );
@ -947,7 +1078,6 @@ static boolean translate( struct translate_ctx *ctx )
while (*ctx->cur != '\0') {
uint label_val = 0;
if (!eat_white( &ctx->cur )) {
report_error( ctx, "Syntax error" );
return FALSE;
@ -955,7 +1085,6 @@ static boolean translate( struct translate_ctx *ctx )
if (*ctx->cur == '\0')
break;
if (parse_label( ctx, &label_val )) {
if (!parse_instruction( ctx, TRUE ))
return FALSE;
@ -968,6 +1097,10 @@ static boolean translate( struct translate_ctx *ctx )
if (!parse_immediate( ctx ))
return FALSE;
}
else if (str_match_no_case( &ctx->cur, "PROPERTY" )) {
if (!parse_property( ctx ))
return FALSE;
}
else if (!parse_instruction( ctx, FALSE )) {
return FALSE;
}

View File

@ -79,6 +79,19 @@ emit_immediate(struct tgsi_transform_context *ctx,
}
static void
emit_property(struct tgsi_transform_context *ctx,
const struct tgsi_full_property *prop)
{
uint ti = ctx->ti;
ti += tgsi_build_full_property(prop,
ctx->tokens_out + ti,
ctx->header,
ctx->max_tokens_out - ti);
ctx->ti = ti;
}
/**
* Apply user-defined transformations to the input shader to produce
@ -110,6 +123,7 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
ctx->emit_instruction = emit_instruction;
ctx->emit_declaration = emit_declaration;
ctx->emit_immediate = emit_immediate;
ctx->emit_property = emit_property;
ctx->tokens_out = tokens_out;
ctx->max_tokens_out = max_tokens_out;
@ -182,6 +196,17 @@ tgsi_transform_shader(const struct tgsi_token *tokens_in,
ctx->emit_immediate(ctx, fullimm);
}
break;
case TGSI_TOKEN_TYPE_PROPERTY:
{
struct tgsi_full_property *fullprop
= &parse.FullToken.FullProperty;
if (ctx->transform_property)
ctx->transform_property(ctx, fullprop);
else
ctx->emit_property(ctx, fullprop);
}
break;
default:
assert( 0 );

View File

@ -53,6 +53,8 @@ struct tgsi_transform_context
void (*transform_immediate)(struct tgsi_transform_context *ctx,
struct tgsi_full_immediate *imm);
void (*transform_property)(struct tgsi_transform_context *ctx,
struct tgsi_full_property *prop);
/**
* Called at end of input program to allow caller to append extra
@ -73,6 +75,8 @@ struct tgsi_transform_context
const struct tgsi_full_declaration *decl);
void (*emit_immediate)(struct tgsi_transform_context *ctx,
const struct tgsi_full_immediate *imm);
void (*emit_property)(struct tgsi_transform_context *ctx,
const struct tgsi_full_property *prop);
struct tgsi_header *header;
uint max_tokens_out;

View File

@ -89,6 +89,11 @@ struct ureg_program
unsigned vs_inputs[UREG_MAX_INPUT/32];
struct {
unsigned index;
} gs_input[UREG_MAX_INPUT];
unsigned nr_gs_inputs;
struct {
unsigned semantic_name;
unsigned semantic_index;
@ -278,6 +283,22 @@ ureg_DECL_vs_input( struct ureg_program *ureg,
}
struct ureg_src
ureg_DECL_gs_input(struct ureg_program *ureg,
unsigned index)
{
if (ureg->nr_gs_inputs < UREG_MAX_INPUT) {
ureg->gs_input[ureg->nr_gs_inputs].index = index;
ureg->nr_gs_inputs++;
} else {
set_bad(ureg);
}
/* XXX: Add suport for true 2D input registers. */
return ureg_src_register(TGSI_FILE_INPUT, index);
}
struct ureg_dst
ureg_DECL_output( struct ureg_program *ureg,
unsigned name,
@ -964,8 +985,7 @@ static void emit_decls( struct ureg_program *ureg )
emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
}
}
}
else {
} else if (ureg->processor == TGSI_PROCESSOR_FRAGMENT) {
for (i = 0; i < ureg->nr_fs_inputs; i++) {
emit_decl( ureg,
TGSI_FILE_INPUT,
@ -974,6 +994,13 @@ static void emit_decls( struct ureg_program *ureg )
ureg->fs_input[i].semantic_index,
ureg->fs_input[i].interp );
}
} else {
for (i = 0; i < ureg->nr_gs_inputs; i++) {
emit_decl_range(ureg,
TGSI_FILE_INPUT,
ureg->gs_input[i].index,
1);
}
}
for (i = 0; i < ureg->nr_outputs; i++) {
@ -1053,7 +1080,7 @@ fixup_header_size(struct ureg_program *ureg)
{
union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 0 );
out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 3;
out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 2;
}

View File

@ -133,6 +133,10 @@ struct ureg_src
ureg_DECL_vs_input( struct ureg_program *,
unsigned index );
struct ureg_src
ureg_DECL_gs_input(struct ureg_program *,
unsigned index);
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
unsigned semantic_name,

View File

@ -9,8 +9,10 @@ C_SOURCES = \
u_debug_symbol.c \
u_debug_stack.c \
u_blit.c \
u_blitter.c \
u_cache.c \
u_cpu_detect.c \
u_dl.c \
u_draw_quad.c \
u_format.c \
u_format_access.c \
@ -30,6 +32,7 @@ C_SOURCES = \
u_stream_stdc.c \
u_stream_wd.c \
u_surface.c \
u_texture.c \
u_tile.c \
u_time.c \
u_timed_winsys.c \

View File

@ -23,6 +23,7 @@ util = env.ConvenienceLibrary(
source = [
'u_bitmask.c',
'u_blit.c',
'u_blitter.c',
'u_cache.c',
'u_cpu_detect.c',
'u_debug.c',
@ -30,6 +31,7 @@ util = env.ConvenienceLibrary(
'u_debug_memory.c',
'u_debug_stack.c',
'u_debug_symbol.c',
'u_dl.c',
'u_draw_quad.c',
'u_format.c',
'u_format_access.c',
@ -48,6 +50,7 @@ util = env.ConvenienceLibrary(
'u_stream_stdc.c',
'u_stream_wd.c',
'u_surface.c',
'u_texture.c',
'u_tile.c',
'u_time.c',
'u_timed_winsys.c',

View File

@ -127,7 +127,8 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
}
/* fragment shader */
ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
ctx->fs[TGSI_WRITEMASK_XYZW] =
util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@ -358,7 +359,6 @@ util_blit_pixels_writemask(struct blit_state *ctx,
texTemp.width0 = srcW;
texTemp.height0 = srcH;
texTemp.depth0 = 1;
util_format_get_block(src->format, &texTemp.block);
tex = screen->texture_create(screen, &texTemp);
if (!tex)
@ -422,7 +422,9 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_set_sampler_textures(ctx->cso, 1, &tex);
if (ctx->fs[writemask] == NULL)
ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
ctx->fs[writemask] =
util_make_fragment_tex_shader_writemask(pipe, TGSI_TEXTURE_2D,
writemask);
/* shaders */
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);

View File

@ -0,0 +1,718 @@
/**************************************************************************
*
* 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 the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/**
* @file
* Blitter utility to facilitate acceleration of the clear, surface_copy,
* and surface_fill functions.
*
* @author Marek Olšák
*/
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "pipe/p_state.h"
#include "util/u_memory.h"
#include "util/u_math.h"
#include "util/u_blitter.h"
#include "util/u_draw_quad.h"
#include "util/u_pack_color.h"
#include "util/u_rect.h"
#include "util/u_simple_shaders.h"
#include "util/u_texture.h"
struct blitter_context_priv
{
struct blitter_context blitter;
struct pipe_context *pipe; /**< pipe context */
struct pipe_buffer *vbuf; /**< quad */
float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */
/* Templates for various state objects. */
struct pipe_depth_stencil_alpha_state template_dsa;
struct pipe_sampler_state template_sampler_state;
/* Constant state objects. */
/* Vertex shaders. */
void *vs_col; /**< Vertex shader which passes {pos, color} to the output */
void *vs_tex; /**<Vertex shader which passes {pos, texcoord} to the output.*/
/* Fragment shaders. */
/* FS which outputs a color to multiple color buffers. */
void *fs_col[PIPE_MAX_COLOR_BUFS];
/* FS which outputs a color from a texture,
where the index is PIPE_TEXTURE_* to be sampled. */
void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES];
/* FS which outputs a depth from a texture,
where the index is PIPE_TEXTURE_* to be sampled. */
void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES];
/* Blend state. */
void *blend_write_color; /**< blend state with writemask of RGBA */
void *blend_keep_color; /**< blend state with writemask of 0 */
/* Depth stencil alpha state. */
void *dsa_write_depth_stencil[0xff]; /**< indices are stencil clear values */
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
/* Sampler state for clamping to a miplevel. */
void *sampler_state[PIPE_MAX_TEXTURE_LEVELS];
/* Rasterizer state. */
void *rs_state;
};
struct blitter_context *util_blitter_create(struct pipe_context *pipe)
{
struct blitter_context_priv *ctx;
struct pipe_blend_state blend;
struct pipe_depth_stencil_alpha_state *dsa;
struct pipe_rasterizer_state rs_state;
struct pipe_sampler_state *sampler_state;
unsigned i;
ctx = CALLOC_STRUCT(blitter_context_priv);
if (!ctx)
return NULL;
ctx->pipe = pipe;
/* init state objects for them to be considered invalid */
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
ctx->blitter.saved_num_textures = ~0;
ctx->blitter.saved_num_sampler_states = ~0;
/* blend state objects */
memset(&blend, 0, sizeof(blend));
ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend);
blend.colormask = PIPE_MASK_RGBA;
ctx->blend_write_color = pipe->create_blend_state(pipe, &blend);
/* depth stencil alpha state objects */
dsa = &ctx->template_dsa;
ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, dsa);
dsa->depth.enabled = 1;
dsa->depth.writemask = 1;
dsa->depth.func = PIPE_FUNC_ALWAYS;
ctx->dsa_write_depth_keep_stencil =
pipe->create_depth_stencil_alpha_state(pipe, dsa);
dsa->stencil[0].enabled = 1;
dsa->stencil[0].func = PIPE_FUNC_ALWAYS;
dsa->stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE;
dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE;
dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE;
dsa->stencil[0].valuemask = 0xff;
dsa->stencil[0].writemask = 0xff;
/* The DSA state objects which write depth and stencil are created
* on-demand. */
/* sampler state */
sampler_state = &ctx->template_sampler_state;
sampler_state->wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler_state->wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
sampler_state->wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
/* The sampler state objects which sample from a specified mipmap level
* are created on-demand. */
/* rasterizer state */
memset(&rs_state, 0, sizeof(rs_state));
rs_state.front_winding = PIPE_WINDING_CW;
rs_state.cull_mode = PIPE_WINDING_NONE;
rs_state.bypass_vs_clip_and_viewport = 1;
rs_state.gl_rasterization_rules = 1;
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state);
/* fragment shaders are created on-demand */
/* vertex shaders */
{
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_COLOR };
const uint semantic_indices[] = { 0, 0 };
ctx->vs_col =
util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
semantic_indices);
}
{
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
TGSI_SEMANTIC_GENERIC };
const uint semantic_indices[] = { 0, 0 };
ctx->vs_tex =
util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
semantic_indices);
}
/* set invariant vertex coordinates */
for (i = 0; i < 4; i++)
ctx->vertices[i][0][3] = 1; /*v.w*/
/* create the vertex buffer */
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
32,
PIPE_BUFFER_USAGE_VERTEX,
sizeof(ctx->vertices));
return &ctx->blitter;
}
void util_blitter_destroy(struct blitter_context *blitter)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
int i;
pipe->delete_blend_state(pipe, ctx->blend_write_color);
pipe->delete_blend_state(pipe, ctx->blend_keep_color);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->delete_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
for (i = 0; i < 0xff; i++)
if (ctx->dsa_write_depth_stencil[i])
pipe->delete_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_stencil[i]);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs_col);
pipe->delete_vs_state(pipe, ctx->vs_tex);
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) {
if (ctx->fs_texfetch_col[i])
pipe->delete_fs_state(pipe, ctx->fs_texfetch_col[i]);
if (ctx->fs_texfetch_depth[i])
pipe->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]);
}
for (i = 0; i < PIPE_MAX_COLOR_BUFS && ctx->fs_col[i]; i++)
if (ctx->fs_col[i])
pipe->delete_fs_state(pipe, ctx->fs_col[i]);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (ctx->sampler_state[i])
pipe->delete_sampler_state(pipe, ctx->sampler_state[i]);
pipe_buffer_reference(&ctx->vbuf, NULL);
FREE(ctx);
}
static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
{
/* make sure these CSOs have been saved */
assert(ctx->blitter.saved_blend_state &&
ctx->blitter.saved_dsa_state &&
ctx->blitter.saved_rs_state &&
ctx->blitter.saved_fs &&
ctx->blitter.saved_vs);
}
static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
{
struct pipe_context *pipe = ctx->pipe;
/* restore the state objects which are always required to be saved */
pipe->bind_blend_state(pipe, ctx->blitter.saved_blend_state);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->blitter.saved_dsa_state);
pipe->bind_rasterizer_state(pipe, ctx->blitter.saved_rs_state);
pipe->bind_fs_state(pipe, ctx->blitter.saved_fs);
pipe->bind_vs_state(pipe, ctx->blitter.saved_vs);
ctx->blitter.saved_blend_state = 0;
ctx->blitter.saved_dsa_state = 0;
ctx->blitter.saved_rs_state = 0;
ctx->blitter.saved_fs = 0;
ctx->blitter.saved_vs = 0;
/* restore the state objects which are required to be saved before copy/fill
*/
if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) {
pipe->set_framebuffer_state(pipe, &ctx->blitter.saved_fb_state);
ctx->blitter.saved_fb_state.nr_cbufs = ~0;
}
if (ctx->blitter.saved_num_sampler_states != ~0) {
pipe->bind_fragment_sampler_states(pipe,
ctx->blitter.saved_num_sampler_states,
ctx->blitter.saved_sampler_states);
ctx->blitter.saved_num_sampler_states = ~0;
}
if (ctx->blitter.saved_num_textures != ~0) {
pipe->set_fragment_sampler_textures(pipe,
ctx->blitter.saved_num_textures,
ctx->blitter.saved_textures);
ctx->blitter.saved_num_textures = ~0;
}
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2,
float depth)
{
int i;
/* set vertex positions */
ctx->vertices[0][0][0] = x1; /*v0.x*/
ctx->vertices[0][0][1] = y1; /*v0.y*/
ctx->vertices[1][0][0] = x2; /*v1.x*/
ctx->vertices[1][0][1] = y1; /*v1.y*/
ctx->vertices[2][0][0] = x2; /*v2.x*/
ctx->vertices[2][0][1] = y2; /*v2.y*/
ctx->vertices[3][0][0] = x1; /*v3.x*/
ctx->vertices[3][0][1] = y2; /*v3.y*/
for (i = 0; i < 4; i++)
ctx->vertices[i][0][2] = depth; /*z*/
}
static void blitter_set_clear_color(struct blitter_context_priv *ctx,
const float *rgba)
{
int i;
for (i = 0; i < 4; i++) {
ctx->vertices[i][1][0] = rgba[0];
ctx->vertices[i][1][1] = rgba[1];
ctx->vertices[i][1][2] = rgba[2];
ctx->vertices[i][1][3] = rgba[3];
}
}
static void blitter_set_texcoords_2d(struct blitter_context_priv *ctx,
struct pipe_surface *surf,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
{
int i;
float s1 = x1 / (float)surf->width;
float t1 = y1 / (float)surf->height;
float s2 = x2 / (float)surf->width;
float t2 = y2 / (float)surf->height;
ctx->vertices[0][1][0] = s1; /*t0.s*/
ctx->vertices[0][1][1] = t1; /*t0.t*/
ctx->vertices[1][1][0] = s2; /*t1.s*/
ctx->vertices[1][1][1] = t1; /*t1.t*/
ctx->vertices[2][1][0] = s2; /*t2.s*/
ctx->vertices[2][1][1] = t2; /*t2.t*/
ctx->vertices[3][1][0] = s1; /*t3.s*/
ctx->vertices[3][1][1] = t2; /*t3.t*/
for (i = 0; i < 4; i++) {
ctx->vertices[i][1][2] = 0; /*r*/
ctx->vertices[i][1][3] = 1; /*q*/
}
}
static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
struct pipe_surface *surf,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
{
int i;
float depth = u_minify(surf->texture->depth0, surf->level);
float r = surf->zslice / depth;
blitter_set_texcoords_2d(ctx, surf, x1, y1, x2, y2);
for (i = 0; i < 4; i++)
ctx->vertices[i][1][2] = r; /*r*/
}
static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
struct pipe_surface *surf,
unsigned x1, unsigned y1,
unsigned x2, unsigned y2)
{
int i;
float s1 = x1 / (float)surf->width;
float t1 = y1 / (float)surf->height;
float s2 = x2 / (float)surf->width;
float t2 = y2 / (float)surf->height;
const float st[4][2] = {
{s1, t1}, {s2, t1}, {s2, t2}, {s1, t2}
};
util_map_texcoords2d_onto_cubemap(surf->face,
/* pointer, stride in floats */
&st[0][0], 2,
&ctx->vertices[0][1][0], 8);
for (i = 0; i < 4; i++)
ctx->vertices[i][1][3] = 1; /*q*/
}
static void blitter_draw_quad(struct blitter_context_priv *ctx)
{
struct pipe_context *pipe = ctx->pipe;
/* write vertices and draw them */
pipe_buffer_write(pipe->screen, ctx->vbuf,
0, sizeof(ctx->vertices), ctx->vertices);
util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
}
static INLINE
void *blitter_get_state_write_depth_stencil(
struct blitter_context_priv *ctx,
unsigned stencil)
{
struct pipe_context *pipe = ctx->pipe;
stencil &= 0xff;
/* Create the DSA state on-demand. */
if (!ctx->dsa_write_depth_stencil[stencil]) {
ctx->template_dsa.stencil[0].ref_value = stencil;
ctx->dsa_write_depth_stencil[stencil] =
pipe->create_depth_stencil_alpha_state(pipe, &ctx->template_dsa);
}
return ctx->dsa_write_depth_stencil[stencil];
}
static INLINE
void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
int miplevel)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_sampler_state *sampler_state = &ctx->template_sampler_state;
assert(miplevel < PIPE_MAX_TEXTURE_LEVELS);
/* Create the sampler state on-demand. */
if (!ctx->sampler_state[miplevel]) {
sampler_state->lod_bias = miplevel;
sampler_state->min_lod = miplevel;
sampler_state->max_lod = miplevel;
ctx->sampler_state[miplevel] = pipe->create_sampler_state(pipe,
sampler_state);
}
/* Return void** so that it can be passed to bind_fragment_sampler_states
* directly. */
return &ctx->sampler_state[miplevel];
}
static INLINE
void *blitter_get_fs_col(struct blitter_context_priv *ctx, unsigned num_cbufs)
{
struct pipe_context *pipe = ctx->pipe;
unsigned index = num_cbufs ? num_cbufs - 1 : 0;
assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
if (!ctx->fs_col[index])
ctx->fs_col[index] =
util_make_fragment_clonecolor_shader(pipe, num_cbufs);
return ctx->fs_col[index];
}
static INLINE
void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx,
unsigned tex_target)
{
struct pipe_context *pipe = ctx->pipe;
assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
/* Create the fragment shader on-demand. */
if (!ctx->fs_texfetch_col[tex_target]) {
switch (tex_target) {
case PIPE_TEXTURE_1D:
ctx->fs_texfetch_col[PIPE_TEXTURE_1D] =
util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_1D);
break;
case PIPE_TEXTURE_2D:
ctx->fs_texfetch_col[PIPE_TEXTURE_2D] =
util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
break;
case PIPE_TEXTURE_3D:
ctx->fs_texfetch_col[PIPE_TEXTURE_3D] =
util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_3D);
break;
case PIPE_TEXTURE_CUBE:
ctx->fs_texfetch_col[PIPE_TEXTURE_CUBE] =
util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_CUBE);
break;
default:;
}
}
return ctx->fs_texfetch_col[tex_target];
}
static INLINE
void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx,
unsigned tex_target)
{
struct pipe_context *pipe = ctx->pipe;
assert(tex_target < PIPE_MAX_TEXTURE_TYPES);
/* Create the fragment shader on-demand. */
if (!ctx->fs_texfetch_depth[tex_target]) {
switch (tex_target) {
case PIPE_TEXTURE_1D:
ctx->fs_texfetch_depth[PIPE_TEXTURE_1D] =
util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_1D);
break;
case PIPE_TEXTURE_2D:
ctx->fs_texfetch_depth[PIPE_TEXTURE_2D] =
util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_2D);
break;
case PIPE_TEXTURE_3D:
ctx->fs_texfetch_depth[PIPE_TEXTURE_3D] =
util_make_fragment_tex_shader_writedepth(pipe, TGSI_TEXTURE_3D);
break;
case PIPE_TEXTURE_CUBE:
ctx->fs_texfetch_depth[PIPE_TEXTURE_CUBE] =
util_make_fragment_tex_shader_writedepth(pipe,TGSI_TEXTURE_CUBE);
break;
default:;
}
}
return ctx->fs_texfetch_depth[tex_target];
}
void util_blitter_clear(struct blitter_context *blitter,
unsigned width, unsigned height,
unsigned num_cbufs,
unsigned clear_buffers,
const float *rgba,
double depth, unsigned stencil)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
assert(num_cbufs <= PIPE_MAX_COLOR_BUFS);
blitter_check_saved_CSOs(ctx);
/* bind CSOs */
if (clear_buffers & PIPE_CLEAR_COLOR)
pipe->bind_blend_state(pipe, ctx->blend_write_color);
else
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL)
pipe->bind_depth_stencil_alpha_state(pipe,
blitter_get_state_write_depth_stencil(ctx, stencil));
else
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, num_cbufs));
pipe->bind_vs_state(pipe, ctx->vs_col);
blitter_set_clear_color(ctx, rgba);
blitter_set_rectangle(ctx, 0, 0, width, height, depth);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}
void util_blitter_copy(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
struct pipe_surface *src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height,
boolean ignore_stencil)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb_state;
boolean is_stencil, is_depth;
unsigned dst_tex_usage;
/* give up if textures are not set */
assert(dst->texture && src->texture);
if (!dst->texture || !src->texture)
return;
is_depth = pf_get_component_bits(src->format, PIPE_FORMAT_COMP_Z) != 0;
is_stencil = pf_get_component_bits(src->format, PIPE_FORMAT_COMP_S) != 0;
dst_tex_usage = is_depth || is_stencil ? PIPE_TEXTURE_USAGE_DEPTH_STENCIL :
PIPE_TEXTURE_USAGE_RENDER_TARGET;
/* check if we can sample from and render to the surfaces */
/* (assuming copying a stencil buffer is not possible) */
if ((!ignore_stencil && is_stencil) ||
!screen->is_format_supported(screen, dst->format, dst->texture->target,
dst_tex_usage, 0) ||
!screen->is_format_supported(screen, src->format, src->texture->target,
PIPE_TEXTURE_USAGE_SAMPLER, 0)) {
util_surface_copy(pipe, FALSE, dst, dstx, dsty, src, srcx, srcy,
width, height);
return;
}
/* check whether the states are properly saved */
blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
assert(blitter->saved_num_textures != ~0);
assert(blitter->saved_num_sampler_states != ~0);
assert(src->texture->target < PIPE_MAX_TEXTURE_TYPES);
/* bind CSOs */
fb_state.width = dst->width;
fb_state.height = dst->height;
if (is_depth) {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
pipe->bind_depth_stencil_alpha_state(pipe,
ctx->dsa_write_depth_keep_stencil);
pipe->bind_fs_state(pipe,
blitter_get_fs_texfetch_depth(ctx, src->texture->target));
fb_state.nr_cbufs = 0;
fb_state.zsbuf = dst;
} else {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_fs_state(pipe,
blitter_get_fs_texfetch_col(ctx, src->texture->target));
fb_state.nr_cbufs = 1;
fb_state.cbufs[0] = dst;
fb_state.zsbuf = 0;
}
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vs_state(pipe, ctx->vs_tex);
pipe->bind_fragment_sampler_states(pipe, 1,
blitter_get_sampler_state(ctx, src->level));
pipe->set_fragment_sampler_textures(pipe, 1, &src->texture);
pipe->set_framebuffer_state(pipe, &fb_state);
/* set texture coordinates */
switch (src->texture->target) {
case PIPE_TEXTURE_1D:
case PIPE_TEXTURE_2D:
blitter_set_texcoords_2d(ctx, src, srcx, srcy,
srcx+width, srcy+height);
break;
case PIPE_TEXTURE_3D:
blitter_set_texcoords_3d(ctx, src, srcx, srcy,
srcx+width, srcy+height);
break;
case PIPE_TEXTURE_CUBE:
blitter_set_texcoords_cube(ctx, src, srcx, srcy,
srcx+width, srcy+height);
break;
default:
assert(0);
}
blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}
void util_blitter_fill(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height,
unsigned value)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
struct pipe_framebuffer_state fb_state;
float rgba[4];
ubyte ub_rgba[4] = {0};
union util_color color;
int i;
assert(dst->texture);
if (!dst->texture)
return;
/* check if we can render to the surface */
if (pf_is_depth_or_stencil(dst->format) || /* unlikely, but you never know */
!screen->is_format_supported(screen, dst->format, dst->texture->target,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
util_surface_fill(pipe, dst, dstx, dsty, width, height, value);
return;
}
/* unpack the color */
color.ui = value;
util_unpack_color_ub(dst->format, &color,
ub_rgba, ub_rgba+1, ub_rgba+2, ub_rgba+3);
for (i = 0; i < 4; i++)
rgba[i] = ubyte_to_float(ub_rgba[i]);
/* check the saved state */
blitter_check_saved_CSOs(ctx);
assert(blitter->saved_fb_state.nr_cbufs != ~0);
/* bind CSOs */
pipe->bind_blend_state(pipe, ctx->blend_write_color);
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_fs_state(pipe, blitter_get_fs_col(ctx, 1));
pipe->bind_vs_state(pipe, ctx->vs_col);
/* set a framebuffer state */
fb_state.width = dst->width;
fb_state.height = dst->height;
fb_state.nr_cbufs = 1;
fb_state.cbufs[0] = dst;
fb_state.zsbuf = 0;
pipe->set_framebuffer_state(pipe, &fb_state);
blitter_set_clear_color(ctx, rgba);
blitter_set_rectangle(ctx, 0, 0, width, height, 0);
blitter_draw_quad(ctx);
blitter_restore_CSOs(ctx);
}

View File

@ -0,0 +1,230 @@
/**************************************************************************
*
* 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 the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef U_BLITTER_H
#define U_BLITTER_H
#include "util/u_memory.h"
#include "pipe/p_state.h"
#ifdef __cplusplus
extern "C" {
#endif
struct pipe_context;
struct blitter_context
{
/* Private members, really. */
void *saved_blend_state; /**< blend state */
void *saved_dsa_state; /**< depth stencil alpha state */
void *saved_rs_state; /**< rasterizer state */
void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */
struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */
int saved_num_sampler_states;
void *saved_sampler_states[32];
int saved_num_textures;
struct pipe_texture *saved_textures[32]; /* is 32 enough? */
};
/**
* Create a blitter context.
*/
struct blitter_context *util_blitter_create(struct pipe_context *pipe);
/**
* Destroy a blitter context.
*/
void util_blitter_destroy(struct blitter_context *blitter);
/*
* These CSOs must be saved before any of the following functions is called:
* - blend state
* - depth stencil alpha state
* - rasterizer state
* - vertex shader
* - fragment shader
*/
/**
* Clear a specified set of currently bound buffers to specified values.
*/
void util_blitter_clear(struct blitter_context *blitter,
unsigned width, unsigned height,
unsigned num_cbufs,
unsigned clear_buffers,
const float *rgba,
double depth, unsigned stencil);
/**
* Copy a block of pixels from one surface to another.
*
* You can copy from any color format to any other color format provided
* the former can be sampled and the latter can be rendered to. Otherwise,
* a software fallback path is taken and both surfaces must be of the same
* format.
*
* The same holds for depth-stencil formats with the exception that stencil
* cannot be copied unless you set ignore_stencil to FALSE. In that case,
* a software fallback path is taken and both surfaces must be of the same
* format.
*
* Use pipe_screen->is_format_supported to know your options.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
* - framebuffer state
* - fragment sampler states
* - fragment sampler textures
*/
void util_blitter_copy(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
struct pipe_surface *src,
unsigned srcx, unsigned srcy,
unsigned width, unsigned height,
boolean ignore_stencil);
/**
* Fill a region of a surface with a constant value.
*
* If the surface cannot be rendered to or it's a depth-stencil format,
* a software fallback path is taken.
*
* These states must be saved in the blitter in addition to the state objects
* already required to be saved:
* - framebuffer state
*/
void util_blitter_fill(struct blitter_context *blitter,
struct pipe_surface *dst,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height,
unsigned value);
/**
* Copy all pixels from one surface to another.
*
* The rules are the same as in util_blitter_copy with the addition that
* surfaces must have the same size.
*/
static INLINE
void util_blitter_copy_surface(struct blitter_context *blitter,
struct pipe_surface *dst,
struct pipe_surface *src,
boolean ignore_stencil)
{
assert(dst->width == src->width && dst->height == src->height);
util_blitter_copy(blitter, dst, 0, 0, src, 0, 0, src->width, src->height,
ignore_stencil);
}
/* The functions below should be used to save currently bound constant state
* objects inside a driver. The objects are automatically restored at the end
* of the util_blitter_{clear, fill, copy, copy_surface} functions and then
* forgotten.
*
* CSOs not listed here are not affected by util_blitter. */
static INLINE
void util_blitter_save_blend(struct blitter_context *blitter,
void *state)
{
blitter->saved_blend_state = state;
}
static INLINE
void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter,
void *state)
{
blitter->saved_dsa_state = state;
}
static INLINE
void util_blitter_save_rasterizer(struct blitter_context *blitter,
void *state)
{
blitter->saved_rs_state = state;
}
static INLINE
void util_blitter_save_fragment_shader(struct blitter_context *blitter,
void *fs)
{
blitter->saved_fs = fs;
}
static INLINE
void util_blitter_save_vertex_shader(struct blitter_context *blitter,
void *vs)
{
blitter->saved_vs = vs;
}
static INLINE
void util_blitter_save_framebuffer(struct blitter_context *blitter,
struct pipe_framebuffer_state *state)
{
blitter->saved_fb_state = *state;
}
static INLINE
void util_blitter_save_fragment_sampler_states(
struct blitter_context *blitter,
int num_sampler_states,
void **sampler_states)
{
assert(num_sampler_states <= Elements(blitter->saved_sampler_states));
blitter->saved_num_sampler_states = num_sampler_states;
memcpy(blitter->saved_sampler_states, sampler_states,
num_sampler_states * sizeof(void *));
}
static INLINE
void util_blitter_save_fragment_sampler_textures(
struct blitter_context *blitter,
int num_textures,
struct pipe_texture **textures)
{
assert(num_textures <= Elements(blitter->saved_textures));
blitter->saved_num_textures = num_textures;
memcpy(blitter->saved_textures, textures,
num_textures * sizeof(struct pipe_texture *));
}
#ifdef __cplusplus
}
#endif
#endif

View File

@ -46,13 +46,13 @@ util_clear(struct pipe_context *pipe,
{
if (buffers & PIPE_CLEAR_COLOR) {
struct pipe_surface *ps = framebuffer->cbufs[0];
unsigned color;
union util_color uc;
util_pack_color(rgba, ps->format, &color);
util_pack_color(rgba, ps->format, &uc);
if (pipe->surface_fill) {
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color);
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
} else {
util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, color);
util_surface_fill(pipe, ps, 0, 0, ps->width, ps->height, uc.ui);
}
}

View File

@ -669,10 +669,10 @@ void debug_dump_surface(const char *prefix,
goto error;
debug_dump_image(prefix,
transfer->format,
transfer->block.size,
transfer->nblocksx,
transfer->nblocksy,
texture->format,
pf_get_blocksize(texture->format),
pf_get_nblocksx(texture->format, transfer->width),
pf_get_nblocksy(texture->format, transfer->height),
transfer->stride,
data);

View File

@ -0,0 +1,79 @@
/**************************************************************************
*
* Copyright 2009 VMware, Inc.
* Copyright 1999-2008 Brian Paul
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
**************************************************************************/
#include "pipe/p_config.h"
#if defined(PIPE_OS_UNIX)
#include <dlfcn.h>
#endif
#if defined(PIPE_OS_WINDOWS)
#include <windows.h>
#endif
#include "u_dl.h"
struct util_dl_library *
util_dl_open(const char *filename)
{
#if defined(PIPE_OS_UNIX)
return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
#elif defined(PIPE_OS_WINDOWS)
return (struct util_dl_library *)LoadLibraryA(filename);
#else
return NULL;
#endif
}
util_dl_proc
util_dl_get_proc_address(struct util_dl_library *library,
const char *procname)
{
#if defined(PIPE_OS_UNIX)
return (util_dl_proc)dlsym((void *)library, procname);
#elif defined(PIPE_OS_WINDOWS)
return (util_dl_proc)GetProcAddress((HMODULE)library, procname);
#else
return (util_dl_proc)NULL;
#endif
}
void
util_dl_close(struct util_dl_library *library)
{
#if defined(PIPE_OS_UNIX)
dlclose((void *)library);
#elif defined(PIPE_OS_WINDOWS)
FreeLibrary((HMODULE)library);
#else
(void)library;
#endif
}

View File

@ -1,8 +1,8 @@
/**************************************************************************
*
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA
*
* Copyright 2009 VMware, Inc.
* All Rights Reserved.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@ -10,32 +10,52 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
*
*
**************************************************************************/
/*
* Authors: Keith Whitwell <keithw-at-tungstengraphics-dot-com>
#ifndef U_DL_H_
#define U_DL_H_
struct util_dl_library;
typedef void (*util_dl_proc)(void);
/**
* Open a library dynamically.
*/
struct util_dl_library *
util_dl_open(const char *filename);
#include "radeon_winsys_softpipe.h"
struct pipe_context *radeon_create_softpipe(struct pipe_winsys* winsys)
{
struct pipe_screen *pipe_screen;
/**
* Lookup a function in a library.
*/
util_dl_proc
util_dl_get_proc_address(struct util_dl_library *library,
const char *procname);
pipe_screen = softpipe_create_screen(winsys);
return softpipe_create(pipe_screen);
}
/**
* Close a library.
*/
void
util_dl_close(struct util_dl_library *library);
#endif /* U_DL_H_ */

View File

@ -33,10 +33,46 @@
#include "pipe/p_format.h"
/**
* Describe how to best pack/unpack pixels into/from the prescribed format.
*
* These are used for automatic code generation of pixel packing and unpacking
* routines (in compile time, e.g., u_format_access.py, or in runtime, like
* llvmpipe does).
*
* Thumb rule is: if you're not code generating pixel packing/unpacking then
* these are irrelevant for you.
*
* Note that this can be deduced from other values in util_format_description
* structure. This is by design, to make code generation of pixel
* packing/unpacking/sampling routines simple and efficient.
*
* XXX: This should be renamed to something like util_format_pack.
*/
enum util_format_layout {
/**
* Single scalar component.
*/
UTIL_FORMAT_LAYOUT_SCALAR = 0,
/**
* One or more components of mixed integer formats, arithmetically encoded
* in a word up to 32bits.
*/
UTIL_FORMAT_LAYOUT_ARITH = 1,
/**
* One or more components, no mixed formats, each with equal power of two
* number of bytes.
*/
UTIL_FORMAT_LAYOUT_ARRAY = 2,
/**
* XXX: Not used yet. These might go away and be replaced by a single entry,
* for formats where multiple pixels have to be
* read in order to determine a single pixel value (i.e., block.width > 1
* || block.height > 1)
*/
UTIL_FORMAT_LAYOUT_YUV = 3,
UTIL_FORMAT_LAYOUT_DXT = 4
};

View File

@ -325,14 +325,14 @@ def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
elif swizzle == SWIZZLE_0:
value = '0'
elif swizzle == SWIZZLE_1:
value = '1'
value = get_one(dst_type)
else:
assert False
elif format.colorspace == 'zs':
if i < 3:
value = 'z'
else:
value = '1'
value = get_one(dst_type)
else:
assert False
print ' *dst_pixel++ = %s; /* %s */' % (value, 'rgba'[i])

View File

@ -44,11 +44,10 @@ def colorspace_map(colorspace):
colorspace_channels_map = {
'rgb': 'rgba',
'rgba': 'rgba',
'zs': 'zs',
'yuv': ['y1', 'y2', 'u', 'v'],
'dxt': []
'rgb': ['r', 'g', 'b', 'a'],
'srgb': ['sr', 'sg', 'sb', 'a'],
'zs': ['z', 's'],
'yuv': ['y', 'u', 'v'],
}
@ -103,7 +102,7 @@ def write_format_table(formats):
print " {"
print " %s," % (format.name,)
print " \"%s\"," % (format.name,)
print " {%u, %u, %u}, /* block */" % (format.block_width, format.block_height, format.block_size())
print " {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size())
print " %s," % (layout_map(format.layout),)
print " {"
for i in range(4):
@ -112,7 +111,7 @@ def write_format_table(formats):
sep = ","
else:
sep = ""
print " {%s, %s, %u}%s /* %s */" % (kind_map[type.kind], bool_map(type.norm), type.size, sep, "xyzw"[i])
print " {%s, %s, %u}%s\t/* %s */" % (kind_map[type.kind], bool_map(type.norm), type.size, sep, "xyzw"[i])
print " },"
print " {"
for i in range(4):
@ -122,10 +121,10 @@ def write_format_table(formats):
else:
sep = ""
try:
comment = layout_channels_map[format.layout][i]
except:
comment = colorspace_channels_map[format.colorspace][i]
except (KeyError, IndexError):
comment = 'ignored'
print " %s%s /* %s */" % (swizzle_map[swizzle], sep, comment)
print " %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment)
print " },"
print " %s," % (colorspace_map(format.colorspace),)
print " },"

View File

@ -47,6 +47,7 @@
#include "util/u_gen_mipmap.h"
#include "util/u_simple_shaders.h"
#include "util/u_math.h"
#include "util/u_texture.h"
#include "cso_cache/cso_context.h"
@ -1160,8 +1161,8 @@ make_2d_mipmap(struct gen_mipmap_state *ctx,
const uint zslice = 0;
uint dstLevel;
assert(pt->block.width == 1);
assert(pt->block.height == 1);
assert(pf_get_blockwidth(pt->format) == 1);
assert(pf_get_blockheight(pt->format) == 1);
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
@ -1205,8 +1206,8 @@ make_3d_mipmap(struct gen_mipmap_state *ctx,
struct pipe_screen *screen = pipe->screen;
uint dstLevel, zslice = 0;
assert(pt->block.width == 1);
assert(pt->block.height == 1);
assert(pf_get_blockwidth(pt->format) == 1);
assert(pf_get_blockheight(pt->format) == 1);
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
const uint srcLevel = dstLevel - 1;
@ -1318,7 +1319,7 @@ util_create_gen_mipmap(struct pipe_context *pipe,
}
/* fragment shader */
ctx->fs = util_make_fragment_tex_shader(pipe);
ctx->fs = util_make_fragment_tex_shader(pipe, TGSI_TEXTURE_2D);
/* vertex data that doesn't change */
for (i = 0; i < 4; i++) {
@ -1384,59 +1385,9 @@ set_vertex_data(struct gen_mipmap_state *ctx,
static const float st[4][2] = {
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
};
float rx, ry, rz;
uint i;
/* loop over quad verts */
for (i = 0; i < 4; i++) {
/* Compute sc = +/-scale and tc = +/-scale.
* Not +/-1 to avoid cube face selection ambiguity near the edges,
* though that can still sometimes happen with this scale factor...
*/
const float scale = 0.9999f;
const float sc = (2.0f * st[i][0] - 1.0f) * scale;
const float tc = (2.0f * st[i][1] - 1.0f) * scale;
switch (face) {
case PIPE_TEX_FACE_POS_X:
rx = 1.0f;
ry = -tc;
rz = -sc;
break;
case PIPE_TEX_FACE_NEG_X:
rx = -1.0f;
ry = -tc;
rz = sc;
break;
case PIPE_TEX_FACE_POS_Y:
rx = sc;
ry = 1.0f;
rz = tc;
break;
case PIPE_TEX_FACE_NEG_Y:
rx = sc;
ry = -1.0f;
rz = -tc;
break;
case PIPE_TEX_FACE_POS_Z:
rx = sc;
ry = -tc;
rz = 1.0f;
break;
case PIPE_TEX_FACE_NEG_Z:
rx = -sc;
ry = -tc;
rz = -1.0f;
break;
default:
rx = ry = rz = 0.0f;
assert(0);
}
ctx->vertices[i][1][0] = rx; /*s*/
ctx->vertices[i][1][1] = ry; /*t*/
ctx->vertices[i][1][2] = rz; /*r*/
}
util_map_texcoords2d_onto_cubemap(face, &st[0][0], 2,
&ctx->vertices[0][1][0], 8);
}
else {
/* 1D/2D */

View File

@ -82,7 +82,7 @@ void pipe_linear_from_tile(struct pipe_tile_info *t, const void *src_ptr,
void
pipe_linear_fill_info(struct pipe_tile_info *t,
const struct pipe_format_block *block,
const struct u_linear_format_block *block,
unsigned tile_width, unsigned tile_height,
unsigned tiles_x, unsigned tiles_y)
{

View File

@ -35,6 +35,19 @@
#include "pipe/p_format.h"
struct u_linear_format_block
{
/** Block size in bytes */
unsigned size;
/** Block width in pixels */
unsigned width;
/** Block height in pixels */
unsigned height;
};
struct pipe_tile_info
{
unsigned size;
@ -49,10 +62,10 @@ struct pipe_tile_info
unsigned rows;
/* Describe the tile in pixels */
struct pipe_format_block tile;
struct u_linear_format_block tile;
/* Describe each block within the tile */
struct pipe_format_block block;
struct u_linear_format_block block;
};
void pipe_linear_to_tile(size_t src_stride, const void *src_ptr,
@ -71,7 +84,7 @@ void pipe_linear_from_tile(struct pipe_tile_info *t, const void *src_ptr,
* @tiles_y number of tiles in y axis
*/
void pipe_linear_fill_info(struct pipe_tile_info *t,
const struct pipe_format_block *block,
const struct u_linear_format_block *block,
unsigned tile_width, unsigned tile_height,
unsigned tiles_x, unsigned tiles_y);

View File

@ -41,101 +41,97 @@
#include "util/u_math.h"
union util_color {
ubyte ub;
ushort us;
uint ui;
float f[4];
};
/**
* Pack ubyte R,G,B,A into dest pixel.
*/
static INLINE void
util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
enum pipe_format format, void *dest)
enum pipe_format format, union util_color *uc)
{
switch (format) {
case PIPE_FORMAT_R8G8B8A8_UNORM:
{
uint *d = (uint *) dest;
*d = (r << 24) | (g << 16) | (b << 8) | a;
uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
}
return;
case PIPE_FORMAT_R8G8B8X8_UNORM:
{
uint *d = (uint *) dest;
*d = (r << 24) | (g << 16) | (b << 8) | 0xff;
uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
}
return;
case PIPE_FORMAT_A8R8G8B8_UNORM:
{
uint *d = (uint *) dest;
*d = (a << 24) | (r << 16) | (g << 8) | b;
uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_X8R8G8B8_UNORM:
{
uint *d = (uint *) dest;
*d = (0xff << 24) | (r << 16) | (g << 8) | b;
uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_B8G8R8A8_UNORM:
{
uint *d = (uint *) dest;
*d = (b << 24) | (g << 16) | (r << 8) | a;
uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
}
return;
case PIPE_FORMAT_B8G8R8X8_UNORM:
{
uint *d = (uint *) dest;
*d = (b << 24) | (g << 16) | (r << 8) | 0xff;
uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
}
return;
case PIPE_FORMAT_R5G6B5_UNORM:
{
ushort *d = (ushort *) dest;
*d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
case PIPE_FORMAT_A1R5G5B5_UNORM:
{
ushort *d = (ushort *) dest;
*d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
}
return;
case PIPE_FORMAT_A4R4G4B4_UNORM:
{
ushort *d = (ushort *) dest;
*d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
}
return;
case PIPE_FORMAT_A8_UNORM:
{
ubyte *d = (ubyte *) dest;
*d = a;
uc->ub = a;
}
return;
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_I8_UNORM:
{
ubyte *d = (ubyte *) dest;
*d = r;
uc->ub = a;
}
return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
float *d = (float *) dest;
d[0] = (float)r / 255.0f;
d[1] = (float)g / 255.0f;
d[2] = (float)b / 255.0f;
d[3] = (float)a / 255.0f;
uc->f[0] = (float)r / 255.0f;
uc->f[1] = (float)g / 255.0f;
uc->f[2] = (float)b / 255.0f;
uc->f[3] = (float)a / 255.0f;
}
return;
case PIPE_FORMAT_R32G32B32_FLOAT:
{
float *d = (float *) dest;
d[0] = (float)r / 255.0f;
d[1] = (float)g / 255.0f;
d[2] = (float)b / 255.0f;
uc->f[0] = (float)r / 255.0f;
uc->f[1] = (float)g / 255.0f;
uc->f[2] = (float)b / 255.0f;
}
return;
/* XXX lots more cases to add */
default:
uc->ui = 0; /* keep compiler happy */
debug_print_format("gallium: unhandled format in util_pack_color_ub()", format);
assert(0);
}
@ -146,13 +142,13 @@ util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
* Unpack RGBA from a packed pixel, returning values as ubytes in [0,255].
*/
static INLINE void
util_unpack_color_ub(enum pipe_format format, const void *src,
util_unpack_color_ub(enum pipe_format format, union util_color *uc,
ubyte *r, ubyte *g, ubyte *b, ubyte *a)
{
switch (format) {
case PIPE_FORMAT_R8G8B8A8_UNORM:
{
uint p = ((const uint *) src)[0];
uint p = uc->ui;
*r = (ubyte) ((p >> 24) & 0xff);
*g = (ubyte) ((p >> 16) & 0xff);
*b = (ubyte) ((p >> 8) & 0xff);
@ -161,7 +157,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_R8G8B8X8_UNORM:
{
uint p = ((const uint *) src)[0];
uint p = uc->ui;
*r = (ubyte) ((p >> 24) & 0xff);
*g = (ubyte) ((p >> 16) & 0xff);
*b = (ubyte) ((p >> 8) & 0xff);
@ -170,7 +166,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_A8R8G8B8_UNORM:
{
uint p = ((const uint *) src)[0];
uint p = uc->ui;
*r = (ubyte) ((p >> 16) & 0xff);
*g = (ubyte) ((p >> 8) & 0xff);
*b = (ubyte) ((p >> 0) & 0xff);
@ -179,7 +175,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_X8R8G8B8_UNORM:
{
uint p = ((const uint *) src)[0];
uint p = uc->ui;
*r = (ubyte) ((p >> 16) & 0xff);
*g = (ubyte) ((p >> 8) & 0xff);
*b = (ubyte) ((p >> 0) & 0xff);
@ -188,7 +184,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_B8G8R8A8_UNORM:
{
uint p = ((const uint *) src)[0];
uint p = uc->ui;
*r = (ubyte) ((p >> 8) & 0xff);
*g = (ubyte) ((p >> 16) & 0xff);
*b = (ubyte) ((p >> 24) & 0xff);
@ -197,7 +193,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_B8G8R8X8_UNORM:
{
uint p = ((const uint *) src)[0];
uint p = uc->ui;
*r = (ubyte) ((p >> 8) & 0xff);
*g = (ubyte) ((p >> 16) & 0xff);
*b = (ubyte) ((p >> 24) & 0xff);
@ -206,7 +202,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_R5G6B5_UNORM:
{
ushort p = ((const ushort *) src)[0];
ushort p = uc->us;
*r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7));
*g = (ubyte) (((p >> 3) & 0xfc) | ((p >> 9) & 0x3));
*b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7));
@ -215,7 +211,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_A1R5G5B5_UNORM:
{
ushort p = ((const ushort *) src)[0];
ushort p = uc->us;
*r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7));
*g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7));
*b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7));
@ -224,7 +220,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_A4R4G4B4_UNORM:
{
ushort p = ((const ushort *) src)[0];
ushort p = uc->us;
*r = (ubyte) (((p >> 4) & 0xf0) | ((p >> 8) & 0xf));
*g = (ubyte) (((p >> 0) & 0xf0) | ((p >> 4) & 0xf));
*b = (ubyte) (((p << 4) & 0xf0) | ((p >> 0) & 0xf));
@ -233,27 +229,27 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_A8_UNORM:
{
ubyte p = ((const ubyte *) src)[0];
ubyte p = uc->ub;
*r = *g = *b = (ubyte) 0xff;
*a = p;
}
return;
case PIPE_FORMAT_L8_UNORM:
{
ubyte p = ((const ubyte *) src)[0];
ubyte p = uc->ub;
*r = *g = *b = p;
*a = (ubyte) 0xff;
}
return;
case PIPE_FORMAT_I8_UNORM:
{
ubyte p = ((const ubyte *) src)[0];
ubyte p = uc->ub;
*r = *g = *b = *a = p;
}
return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
const float *p = (const float *) src;
const float *p = &uc->f[0];
*r = float_to_ubyte(p[0]);
*g = float_to_ubyte(p[1]);
*b = float_to_ubyte(p[2]);
@ -262,7 +258,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
return;
case PIPE_FORMAT_R32G32B32_FLOAT:
{
const float *p = (const float *) src;
const float *p = &uc->f[0];
*r = float_to_ubyte(p[0]);
*g = float_to_ubyte(p[1]);
*b = float_to_ubyte(p[2]);
@ -272,7 +268,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
case PIPE_FORMAT_R32G32_FLOAT:
{
const float *p = (const float *) src;
const float *p = &uc->f[0];
*r = float_to_ubyte(p[0]);
*g = float_to_ubyte(p[1]);
*b = *a = (ubyte) 0xff;
@ -281,7 +277,7 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
case PIPE_FORMAT_R32_FLOAT:
{
const float *p = (const float *) src;
const float *p = &uc->f[0];
*r = float_to_ubyte(p[0]);
*g = *b = *a = (ubyte) 0xff;
}
@ -294,14 +290,13 @@ util_unpack_color_ub(enum pipe_format format, const void *src,
assert(0);
}
}
/**
* Note rgba outside [0,1] will be clamped for int pixel formats.
*/
static INLINE void
util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc)
{
ubyte r = 0;
ubyte g = 0;
@ -319,90 +314,78 @@ util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
switch (format) {
case PIPE_FORMAT_R8G8B8A8_UNORM:
{
uint *d = (uint *) dest;
*d = (r << 24) | (g << 16) | (b << 8) | a;
uc->ui = (r << 24) | (g << 16) | (b << 8) | a;
}
return;
case PIPE_FORMAT_R8G8B8X8_UNORM:
{
uint *d = (uint *) dest;
*d = (r << 24) | (g << 16) | (b << 8) | 0xff;
uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff;
}
return;
case PIPE_FORMAT_A8R8G8B8_UNORM:
{
uint *d = (uint *) dest;
*d = (a << 24) | (r << 16) | (g << 8) | b;
uc->ui = (a << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_X8R8G8B8_UNORM:
{
uint *d = (uint *) dest;
*d = (0xff << 24) | (r << 16) | (g << 8) | b;
uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b;
}
return;
case PIPE_FORMAT_B8G8R8A8_UNORM:
{
uint *d = (uint *) dest;
*d = (b << 24) | (g << 16) | (r << 8) | a;
uc->ui = (b << 24) | (g << 16) | (r << 8) | a;
}
return;
case PIPE_FORMAT_B8G8R8X8_UNORM:
{
uint *d = (uint *) dest;
*d = (b << 24) | (g << 16) | (r << 8) | 0xff;
uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff;
}
return;
case PIPE_FORMAT_R5G6B5_UNORM:
{
ushort *d = (ushort *) dest;
*d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
}
return;
case PIPE_FORMAT_A1R5G5B5_UNORM:
{
ushort *d = (ushort *) dest;
*d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
}
return;
case PIPE_FORMAT_A4R4G4B4_UNORM:
{
ushort *d = (ushort *) dest;
*d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
uc->ub = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
}
return;
case PIPE_FORMAT_A8_UNORM:
{
ubyte *d = (ubyte *) dest;
*d = a;
uc->ub = a;
}
return;
case PIPE_FORMAT_L8_UNORM:
case PIPE_FORMAT_I8_UNORM:
{
ubyte *d = (ubyte *) dest;
*d = r;
uc->ub = r;
}
return;
case PIPE_FORMAT_R32G32B32A32_FLOAT:
{
float *d = (float *) dest;
d[0] = rgba[0];
d[1] = rgba[1];
d[2] = rgba[2];
d[3] = rgba[3];
uc->f[0] = rgba[0];
uc->f[1] = rgba[1];
uc->f[2] = rgba[2];
uc->f[3] = rgba[3];
}
return;
case PIPE_FORMAT_R32G32B32_FLOAT:
{
float *d = (float *) dest;
d[0] = rgba[0];
d[1] = rgba[1];
d[2] = rgba[2];
uc->f[0] = rgba[0];
uc->f[1] = rgba[1];
uc->f[2] = rgba[2];
}
return;
/* XXX lots more cases to add */
default:
uc->ui = 0; /* keep compiler happy */
debug_print_format("gallium: unhandled format in util_pack_color()", format);
assert(0);
}

View File

@ -44,7 +44,7 @@
*/
void
util_copy_rect(ubyte * dst,
const struct pipe_format_block *block,
enum pipe_format format,
unsigned dst_stride,
unsigned dst_x,
unsigned dst_y,
@ -57,27 +57,30 @@ util_copy_rect(ubyte * dst,
{
unsigned i;
int src_stride_pos = src_stride < 0 ? -src_stride : src_stride;
int blocksize = pf_get_blocksize(format);
int blockwidth = pf_get_blockwidth(format);
int blockheight = pf_get_blockheight(format);
assert(block->size > 0);
assert(block->width > 0);
assert(block->height > 0);
assert(blocksize > 0);
assert(blockwidth > 0);
assert(blockheight > 0);
assert(src_x >= 0);
assert(src_y >= 0);
assert(dst_x >= 0);
assert(dst_y >= 0);
dst_x /= block->width;
dst_y /= block->height;
width = (width + block->width - 1)/block->width;
height = (height + block->height - 1)/block->height;
src_x /= block->width;
src_y /= block->height;
dst_x /= blockwidth;
dst_y /= blockheight;
width = (width + blockwidth - 1)/blockwidth;
height = (height + blockheight - 1)/blockheight;
src_x /= blockwidth;
src_y /= blockheight;
dst += dst_x * block->size;
src += src_x * block->size;
dst += dst_x * blocksize;
src += src_x * blocksize;
dst += dst_y * dst_stride;
src += src_y * src_stride_pos;
width *= block->size;
width *= blocksize;
if (width == dst_stride && width == src_stride)
memcpy(dst, src, height * width);
@ -92,7 +95,7 @@ util_copy_rect(ubyte * dst,
void
util_fill_rect(ubyte * dst,
const struct pipe_format_block *block,
enum pipe_format format,
unsigned dst_stride,
unsigned dst_x,
unsigned dst_y,
@ -102,23 +105,26 @@ util_fill_rect(ubyte * dst,
{
unsigned i, j;
unsigned width_size;
int blocksize = pf_get_blocksize(format);
int blockwidth = pf_get_blockwidth(format);
int blockheight = pf_get_blockheight(format);
assert(block->size > 0);
assert(block->width > 0);
assert(block->height > 0);
assert(blocksize > 0);
assert(blockwidth > 0);
assert(blockheight > 0);
assert(dst_x >= 0);
assert(dst_y >= 0);
dst_x /= block->width;
dst_y /= block->height;
width = (width + block->width - 1)/block->width;
height = (height + block->height - 1)/block->height;
dst_x /= blockwidth;
dst_y /= blockheight;
width = (width + blockwidth - 1)/blockwidth;
height = (height + blockheight - 1)/blockheight;
dst += dst_x * block->size;
dst += dst_x * blocksize;
dst += dst_y * dst_stride;
width_size = width * block->size;
width_size = width * blocksize;
switch (block->size) {
switch (blocksize) {
case 1:
if(dst_stride == width_size)
memset(dst, (ubyte) value, height * width_size);
@ -172,10 +178,15 @@ util_surface_copy(struct pipe_context *pipe,
struct pipe_transfer *src_trans, *dst_trans;
void *dst_map;
const void *src_map;
enum pipe_format src_format, dst_format;
assert(src->texture && dst->texture);
if (!src->texture || !dst->texture)
return;
src_format = src->texture->format;
dst_format = dst->texture->format;
src_trans = screen->get_tex_transfer(screen,
src->texture,
src->face,
@ -192,9 +203,9 @@ util_surface_copy(struct pipe_context *pipe,
PIPE_TRANSFER_WRITE,
dst_x, dst_y, w, h);
assert(dst_trans->block.size == src_trans->block.size);
assert(dst_trans->block.width == src_trans->block.width);
assert(dst_trans->block.height == src_trans->block.height);
assert(pf_get_blocksize(dst_format) == pf_get_blocksize(src_format));
assert(pf_get_blockwidth(dst_format) == pf_get_blockwidth(src_format));
assert(pf_get_blockheight(dst_format) == pf_get_blockheight(src_format));
src_map = pipe->screen->transfer_map(screen, src_trans);
dst_map = pipe->screen->transfer_map(screen, dst_trans);
@ -205,7 +216,7 @@ util_surface_copy(struct pipe_context *pipe,
if (src_map && dst_map) {
/* If do_flip, invert src_y position and pass negative src stride */
util_copy_rect(dst_map,
&dst_trans->block,
dst_format,
dst_trans->stride,
0, 0,
w, h,
@ -259,11 +270,11 @@ util_surface_fill(struct pipe_context *pipe,
if (dst_map) {
assert(dst_trans->stride > 0);
switch (dst_trans->block.size) {
switch (pf_get_blocksize(dst_trans->texture->format)) {
case 1:
case 2:
case 4:
util_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
util_fill_rect(dst_map, dst_trans->texture->format, dst_trans->stride,
0, 0, width, height, value);
break;
case 8:

View File

@ -42,13 +42,13 @@ struct pipe_surface;
extern void
util_copy_rect(ubyte * dst, const struct pipe_format_block *block,
util_copy_rect(ubyte * dst, enum pipe_format format,
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
unsigned width, unsigned height, const ubyte * src,
int src_stride, unsigned src_x, int src_y);
extern void
util_fill_rect(ubyte * dst, const struct pipe_format_block *block,
util_fill_rect(ubyte * dst, enum pipe_format format,
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
unsigned width, unsigned height, uint32_t value);

View File

@ -2,6 +2,7 @@
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
* 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
@ -30,6 +31,7 @@
* Simple vertex/fragment shader generators.
*
* @author Brian Paul
Marek Olšák
*/
@ -87,6 +89,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
*/
void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned tex_target,
unsigned writemask )
{
struct ureg_program *ureg;
@ -116,30 +119,82 @@ util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
ureg_TEX( ureg,
ureg_writemask(out, writemask),
TGSI_TEXTURE_2D, tex, sampler );
tex_target, tex, sampler );
ureg_END( ureg );
return ureg_create_shader_and_destroy( ureg, pipe );
}
void *
util_make_fragment_tex_shader(struct pipe_context *pipe )
util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target )
{
return util_make_fragment_tex_shader_writemask( pipe,
tex_target,
TGSI_WRITEMASK_XYZW );
}
/**
* Make a simple fragment texture shader which reads an X component from
* a texture and writes it as depth.
*/
void *
util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
unsigned tex_target)
{
struct ureg_program *ureg;
struct ureg_src sampler;
struct ureg_src tex;
struct ureg_dst out, depth;
struct ureg_src imm;
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
if (ureg == NULL)
return NULL;
sampler = ureg_DECL_sampler( ureg, 0 );
tex = ureg_DECL_fs_input( ureg,
TGSI_SEMANTIC_GENERIC, 0,
TGSI_INTERPOLATE_PERSPECTIVE );
out = ureg_DECL_output( ureg,
TGSI_SEMANTIC_COLOR,
0 );
depth = ureg_DECL_output( ureg,
TGSI_SEMANTIC_POSITION,
0 );
imm = ureg_imm4f( ureg, 0, 0, 0, 1 );
ureg_MOV( ureg, out, imm );
ureg_TEX( ureg,
ureg_writemask(depth, TGSI_WRITEMASK_Z),
tex_target, tex, sampler );
ureg_END( ureg );
return ureg_create_shader_and_destroy( ureg, pipe );
}
/**
* Make simple fragment color pass-through shader.
*/
void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe)
{
return util_make_fragment_clonecolor_shader(pipe, 1);
}
void *
util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs)
{
struct ureg_program *ureg;
struct ureg_src src;
struct ureg_dst dst;
struct ureg_dst dst[8];
int i;
assert(num_cbufs <= 8);
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
if (ureg == NULL)
@ -148,12 +203,13 @@ util_make_fragment_passthrough_shader(struct pipe_context *pipe)
src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0,
TGSI_INTERPOLATE_PERSPECTIVE );
dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 );
for (i = 0; i < num_cbufs; i++)
dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i );
for (i = 0; i < num_cbufs; i++)
ureg_MOV( ureg, dst[i], src );
ureg_MOV( ureg, dst, src );
ureg_END( ureg );
return ureg_create_shader_and_destroy( ureg, pipe );
}

View File

@ -51,16 +51,25 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
extern void *
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
unsigned writemask );
unsigned tex_target,
unsigned writemask);
extern void *
util_make_fragment_tex_shader(struct pipe_context *pipe);
util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target);
extern void *
util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe,
unsigned tex_target);
extern void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe);
extern void *
util_make_fragment_clonecolor_shader(struct pipe_context *pipe, int num_cbufs);
#ifdef __cplusplus
}
#endif

View File

@ -83,7 +83,6 @@ util_create_rgba_surface(struct pipe_screen *screen,
templ.width0 = width;
templ.height0 = height;
templ.depth0 = 1;
util_format_get_block(format, &templ.block);
templ.tex_usage = usage;
*textureOut = screen->texture_create(screen, &templ);

View File

@ -0,0 +1,102 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
* Copyright 2008 VMware, Inc. All rights reserved.
* 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 the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/**
* @file
* Texture mapping utility functions.
*
* @author Brian Paul
* Marek Olšák
*/
#include "pipe/p_defines.h"
#include "util/u_texture.h"
void util_map_texcoords2d_onto_cubemap(unsigned face,
const float *in_st, unsigned in_stride,
float *out_str, unsigned out_stride)
{
int i;
float rx, ry, rz;
/* loop over quad verts */
for (i = 0; i < 4; i++) {
/* Compute sc = +/-scale and tc = +/-scale.
* Not +/-1 to avoid cube face selection ambiguity near the edges,
* though that can still sometimes happen with this scale factor...
*/
const float scale = 0.9999f;
const float sc = (2 * in_st[0] - 1) * scale;
const float tc = (2 * in_st[1] - 1) * scale;
switch (face) {
case PIPE_TEX_FACE_POS_X:
rx = 1;
ry = -tc;
rz = -sc;
break;
case PIPE_TEX_FACE_NEG_X:
rx = -1;
ry = -tc;
rz = sc;
break;
case PIPE_TEX_FACE_POS_Y:
rx = sc;
ry = 1;
rz = tc;
break;
case PIPE_TEX_FACE_NEG_Y:
rx = sc;
ry = -1;
rz = -tc;
break;
case PIPE_TEX_FACE_POS_Z:
rx = sc;
ry = -tc;
rz = 1;
break;
case PIPE_TEX_FACE_NEG_Z:
rx = -sc;
ry = -tc;
rz = -1;
break;
default:
rx = ry = rz = 0;
assert(0);
}
out_str[0] = rx; /*s*/
out_str[1] = ry; /*t*/
out_str[2] = rz; /*r*/
in_st += in_stride;
out_str += out_stride;
}
}

View File

@ -0,0 +1,54 @@
/**************************************************************************
*
* 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 the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef U_TEXTURE_H
#define U_TEXTURE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Convert 2D texture coordinates of 4 vertices into cubemap coordinates
* in the given face.
* Coordinates must be in the range [0,1].
*
* \param face Cubemap face.
* \param in_st 4 pairs of 2D texture coordinates to convert.
* \param in_stride Stride of in_st in floats.
* \param out_str STR cubemap texture coordinates to compute.
* \param out_stride Stride of out_str in floats.
*/
void util_map_texcoords2d_onto_cubemap(unsigned face,
const float *in_st, unsigned in_stride,
float *out_str, unsigned out_stride);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -52,7 +52,7 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
const void *src;
if (dst_stride == 0)
dst_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
dst_stride = pf_get_stride(pt->texture->format, w);
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
@ -62,7 +62,7 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
if(!src)
return;
util_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
util_copy_rect(dst, pt->texture->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
screen->transfer_unmap(screen, pt);
}
@ -78,9 +78,10 @@ pipe_put_tile_raw(struct pipe_transfer *pt,
{
struct pipe_screen *screen = pt->texture->screen;
void *dst;
enum pipe_format format = pt->texture->format;
if (src_stride == 0)
src_stride = pf_get_nblocksx(&pt->block, w) * pt->block.size;
src_stride = pf_get_stride(format, w);
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
@ -90,7 +91,7 @@ pipe_put_tile_raw(struct pipe_transfer *pt,
if(!dst)
return;
util_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0);
screen->transfer_unmap(screen, pt);
}
@ -246,6 +247,53 @@ b8g8r8a8_put_tile_rgba(unsigned *dst,
}
/*** PIPE_FORMAT_R8G8B8A8_UNORM ***/
static void
r8g8b8a8_get_tile_rgba(const unsigned *src,
unsigned w, unsigned h,
float *p,
unsigned dst_stride)
{
unsigned i, j;
for (i = 0; i < h; i++) {
float *pRow = p;
for (j = 0; j < w; j++, pRow += 4) {
const unsigned pixel = *src++;
pRow[0] = ubyte_to_float((pixel >> 24) & 0xff);
pRow[1] = ubyte_to_float((pixel >> 16) & 0xff);
pRow[2] = ubyte_to_float((pixel >> 8) & 0xff);
pRow[3] = ubyte_to_float((pixel >> 0) & 0xff);
}
p += dst_stride;
}
}
static void
r8g8b8a8_put_tile_rgba(unsigned *dst,
unsigned w, unsigned h,
const float *p,
unsigned src_stride)
{
unsigned i, j;
for (i = 0; i < h; i++) {
const float *pRow = p;
for (j = 0; j < w; j++, pRow += 4) {
unsigned r, g, b, a;
r = float_to_ubyte(pRow[0]);
g = float_to_ubyte(pRow[1]);
b = float_to_ubyte(pRow[2]);
a = float_to_ubyte(pRow[3]);
*dst++ = (r << 24) | (g << 16) | (b << 8) | a;
}
p += src_stride;
}
}
/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
static void
@ -1143,6 +1191,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_B8G8R8A8_UNORM:
b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
r8g8b8a8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
break;
case PIPE_FORMAT_A1R5G5B5_UNORM:
a1r5g5b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
@ -1219,21 +1270,22 @@ pipe_get_tile_rgba(struct pipe_transfer *pt,
{
unsigned dst_stride = w * 4;
void *packed;
enum pipe_format format = pt->texture->format;
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
packed = MALLOC(pf_get_nblocks(format, w, h) * pf_get_blocksize(format));
if (!packed)
return;
if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
if(format == PIPE_FORMAT_YCBCR || format == PIPE_FORMAT_YCBCR_REV)
assert((x & 1) == 0);
pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
pipe_tile_raw_to_rgba(pt->format, packed, w, h, p, dst_stride);
pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
FREE(packed);
}
@ -1246,16 +1298,17 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
{
unsigned src_stride = w * 4;
void *packed;
enum pipe_format format = pt->texture->format;
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
packed = MALLOC(pf_get_nblocks(format, w, h) * pf_get_blocksize(format));
if (!packed)
return;
switch (pt->format) {
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
break;
@ -1265,6 +1318,9 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
case PIPE_FORMAT_B8G8R8A8_UNORM:
b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
r8g8b8a8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_A1R5G5B5_UNORM:
a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
@ -1274,9 +1330,6 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
case PIPE_FORMAT_R8G8B8_UNORM:
r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
assert(0);
break;
case PIPE_FORMAT_A4R4G4B4_UNORM:
a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
@ -1322,7 +1375,7 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
/*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/
break;
default:
debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format));
debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
}
pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
@ -1344,6 +1397,7 @@ pipe_get_tile_z(struct pipe_transfer *pt,
ubyte *map;
uint *pDest = z;
uint i, j;
enum pipe_format format = pt->texture->format;
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
@ -1354,7 +1408,7 @@ pipe_get_tile_z(struct pipe_transfer *pt,
return;
}
switch (pt->format) {
switch (format) {
case PIPE_FORMAT_Z32_UNORM:
{
const uint *ptrc
@ -1428,6 +1482,7 @@ pipe_put_tile_z(struct pipe_transfer *pt,
const uint *ptrc = zSrc;
ubyte *map;
uint i, j;
enum pipe_format format = pt->texture->format;
if (pipe_clip_tile(x, y, &w, &h, pt))
return;
@ -1438,7 +1493,7 @@ pipe_put_tile_z(struct pipe_transfer *pt,
return;
}
switch (pt->format) {
switch (format) {
case PIPE_FORMAT_Z32_UNORM:
{
uint *pDest = (uint *) (map + y * pt->stride + x*4);

View File

@ -835,7 +835,6 @@ init_buffers(struct vl_mpeg12_mc_renderer *r)
template.height0 = r->pot_buffers ?
util_next_power_of_two(r->picture_height) : r->picture_height;
template.depth0 = 1;
util_format_get_block(template.format, &template.block);
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | PIPE_TEXTURE_USAGE_DYNAMIC;
r->textures.individual.y = r->pipe->screen->texture_create(r->pipe->screen, &template);
@ -1445,7 +1444,7 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby,
assert(r);
assert(blocks);
tex_pitch = r->tex_transfer[0]->stride / r->tex_transfer[0]->block.size;
tex_pitch = r->tex_transfer[0]->stride / pf_get_blocksize(r->tex_transfer[0]->texture->format);
texels = r->texels[0] + mbpy * tex_pitch + mbpx;
for (y = 0; y < 2; ++y) {
@ -1484,7 +1483,7 @@ grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby,
mbpy /= 2;
for (tb = 0; tb < 2; ++tb) {
tex_pitch = r->tex_transfer[tb + 1]->stride / r->tex_transfer[tb + 1]->block.size;
tex_pitch = r->tex_transfer[tb + 1]->stride / pf_get_blocksize(r->tex_transfer[tb + 1]->texture->format);
texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx;
if ((cbp >> (1 - tb)) & 1) {

View File

@ -59,9 +59,9 @@ cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
if (buffers & PIPE_CLEAR_COLOR) {
uint surfIndex = 0;
uint clearValue;
union util_color uc;
util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &clearValue);
util_pack_color(rgba, cell->framebuffer.cbufs[0]->format, &uc);
/* Build a CLEAR command and place it in the current batch buffer */
STATIC_ASSERT(sizeof(struct cell_command_clear_surface) % 16 == 0);
@ -70,7 +70,7 @@ cell_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
cell_batch_alloc16(cell, sizeof(*clr));
clr->opcode[0] = CELL_CMD_CLEAR_SURFACE;
clr->surface = surfIndex;
clr->value = clearValue;
clr->value = uc.ui;
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {

View File

@ -995,7 +995,7 @@ static boolean
emit_inequality(struct codegen *gen, const struct tgsi_full_instruction *inst)
{
int ch, s1_reg[4], s2_reg[4], d_reg[4], one_reg;
bool complement = FALSE;
boolean complement = FALSE;
one_reg = get_const_one_reg(gen);

View File

@ -67,14 +67,11 @@ cell_texture_layout(struct cell_texture *ct)
w_tile = align(width, TILE_SIZE);
h_tile = align(height, TILE_SIZE);
pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w_tile);
pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h_tile);
ct->stride[level] = pt->nblocksx[level] * pt->block.size;
ct->stride[level] = pf_get_stride(pt->format, w_tile);
ct->level_offset[level] = ct->buffer_size;
size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
size = ct->stride[level] * pf_get_nblocksy(pt->format, h_tile);
if (pt->target == PIPE_TEXTURE_CUBE)
size *= 6;
else
@ -285,10 +282,12 @@ cell_get_tex_surface(struct pipe_screen *screen,
ps->zslice = zslice;
if (pt->target == PIPE_TEXTURE_CUBE) {
ps->offset += face * pt->nblocksy[level] * ct->stride[level];
unsigned h_tile = align(ps->height, TILE_SIZE);
ps->offset += face * pf_get_nblocksy(ps->format, h_tile) * ct->stride[level];
}
else if (pt->target == PIPE_TEXTURE_3D) {
ps->offset += zslice * pt->nblocksy[level] * ct->stride[level];
unsigned h_tile = align(ps->height, TILE_SIZE);
ps->offset += zslice * pf_get_nblocksy(ps->format, h_tile) * ct->stride[level];
}
else {
assert(face == 0);
@ -329,14 +328,10 @@ cell_get_tex_transfer(struct pipe_screen *screen,
if (ctrans) {
struct pipe_transfer *pt = &ctrans->base;
pipe_texture_reference(&pt->texture, texture);
pt->format = texture->format;
pt->block = texture->block;
pt->x = x;
pt->y = y;
pt->width = w;
pt->height = h;
pt->nblocksx = texture->nblocksx[level];
pt->nblocksy = texture->nblocksy[level];
pt->stride = ct->stride[level];
pt->usage = usage;
pt->face = face;
@ -346,10 +341,12 @@ cell_get_tex_transfer(struct pipe_screen *screen,
ctrans->offset = ct->level_offset[level];
if (texture->target == PIPE_TEXTURE_CUBE) {
ctrans->offset += face * pt->nblocksy * pt->stride;
unsigned h_tile = align(u_minify(texture->height0, level), TILE_SIZE);
ctrans->offset += face * pf_get_nblocksy(texture->format, h_tile) * pt->stride;
}
else if (texture->target == PIPE_TEXTURE_3D) {
ctrans->offset += zslice * pt->nblocksy * pt->stride;
unsigned h_tile = align(u_minify(texture->height0, level), TILE_SIZE);
ctrans->offset += zslice * pf_get_nblocksy(texture->format, h_tile) * pt->stride;
}
else {
assert(face == 0);
@ -402,7 +399,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
* Create a buffer of ordinary memory for the linear texture.
* This is the memory that the user will read/write.
*/
size = pt->nblocksx[level] * pt->nblocksy[level] * pt->block.size;
size = pf_get_stride(pt->format, align(texWidth, TILE_SIZE)) *
pf_get_nblocksy(pt->format, align(texHeight, TILE_SIZE));
ctrans->map = align_malloc(size, 16);
if (!ctrans->map)

View File

@ -48,17 +48,19 @@ i915_surface_copy(struct pipe_context *pipe,
{
struct i915_texture *dst_tex = (struct i915_texture *)dst->texture;
struct i915_texture *src_tex = (struct i915_texture *)src->texture;
struct pipe_texture *dpt = &dst_tex->base;
struct pipe_texture *spt = &src_tex->base;
assert( dst != src );
assert( dst_tex->base.block.size == src_tex->base.block.size );
assert( dst_tex->base.block.width == src_tex->base.block.height );
assert( dst_tex->base.block.height == src_tex->base.block.height );
assert( dst_tex->base.block.width == 1 );
assert( dst_tex->base.block.height == 1 );
assert( pf_get_blocksize(dpt->format) == pf_get_blocksize(spt->format) );
assert( pf_get_blockwidth(dpt->format) == pf_get_blockwidth(spt->format) );
assert( pf_get_blockheight(dpt->format) == pf_get_blockheight(spt->format) );
assert( pf_get_blockwidth(dpt->format) == 1 );
assert( pf_get_blockheight(dpt->format) == 1 );
i915_copy_blit( i915_context(pipe),
FALSE,
dst_tex->base.block.size,
pf_get_blocksize(dpt->format),
(unsigned short) src_tex->stride, src_tex->buffer, src->offset,
(unsigned short) dst_tex->stride, dst_tex->buffer, dst->offset,
(short) srcx, (short) srcy, (short) dstx, (short) dsty, (short) width, (short) height );
@ -72,12 +74,13 @@ i915_surface_fill(struct pipe_context *pipe,
unsigned width, unsigned height, unsigned value)
{
struct i915_texture *tex = (struct i915_texture *)dst->texture;
struct pipe_texture *pt = &tex->base;
assert(tex->base.block.width == 1);
assert(tex->base.block.height == 1);
assert(pf_get_blockwidth(pt->format) == 1);
assert(pf_get_blockheight(pt->format) == 1);
i915_fill_blit( i915_context(pipe),
tex->base.block.size,
pf_get_blocksize(pt->format),
(unsigned short) tex->stride,
tex->buffer, dst->offset,
(short) dstx, (short) dsty,

View File

@ -74,6 +74,9 @@ static const int step_offsets[6][2] = {
{-1, 1}
};
/* XXX really need twice the size if x is already pot?
Otherwise just use util_next_power_of_two?
*/
static unsigned
power_of_two(unsigned x)
{
@ -83,13 +86,6 @@ power_of_two(unsigned x)
return value;
}
static unsigned
round_up(unsigned n, unsigned multiple)
{
return (n + multiple - 1) & ~(multiple - 1);
}
/*
* More advanced helper funcs
*/
@ -101,13 +97,8 @@ i915_miptree_set_level_info(struct i915_texture *tex,
unsigned nr_images,
unsigned w, unsigned h, unsigned d)
{
struct pipe_texture *pt = &tex->base;
assert(level < PIPE_MAX_TEXTURE_LEVELS);
pt->nblocksx[level] = pf_get_nblocksx(&pt->block, w);
pt->nblocksy[level] = pf_get_nblocksy(&pt->block, h);
tex->nr_images[level] = nr_images;
/*
@ -138,7 +129,7 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
assert(img < tex->nr_images[level]);
tex->image_offset[level][img] = y * tex->stride + x * tex->base.block.size;
tex->image_offset[level][img] = y * tex->stride + x * pf_get_blocksize(tex->base.format);
/*
printf("%s level %d img %d pos %d,%d image_offset %x\n",
@ -160,28 +151,28 @@ i915_scanout_layout(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
if (pt->last_level > 0 || pt->block.size != 4)
if (pt->last_level > 0 || pf_get_blocksize(pt->format) != 4)
return FALSE;
i915_miptree_set_level_info(tex, 0, 1,
tex->base.width0,
tex->base.height0,
pt->width0,
pt->height0,
1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
if (tex->base.width0 >= 240) {
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
if (pt->width0 >= 240) {
tex->stride = power_of_two(pf_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(pf_get_nblocksy(pt->format, pt->height0), 8);
tex->hw_tiled = INTEL_TILE_X;
} else if (tex->base.width0 == 64 && tex->base.height0 == 64) {
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
} else if (pt->width0 == 64 && pt->height0 == 64) {
tex->stride = power_of_two(pf_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(pf_get_nblocksy(pt->format, pt->height0), 8);
} else {
return FALSE;
}
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
tex->base.width0, tex->base.height0, pt->block.size,
pt->width0, pt->height0, pf_get_blocksize(pt->format),
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
return TRUE;
@ -195,25 +186,25 @@ i915_display_target_layout(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
if (pt->last_level > 0 || pt->block.size != 4)
if (pt->last_level > 0 || pf_get_blocksize(pt->format) != 4)
return FALSE;
/* fallback to normal textures for small textures */
if (tex->base.width0 < 240)
if (pt->width0 < 240)
return FALSE;
i915_miptree_set_level_info(tex, 0, 1,
tex->base.width0,
tex->base.height0,
pt->width0,
pt->height0,
1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
tex->stride = power_of_two(pf_get_stride(pt->format, pt->width0));
tex->total_nblocksy = align(pf_get_nblocksy(pt->format, pt->height0), 8);
tex->hw_tiled = INTEL_TILE_X;
debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
tex->base.width0, tex->base.height0, pt->block.size,
pt->width0, pt->height0, pf_get_blocksize(pt->format),
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
return TRUE;
@ -226,34 +217,32 @@ i915_miptree_layout_2d(struct i915_texture *tex)
unsigned level;
unsigned width = pt->width0;
unsigned height = pt->height0;
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned nblocksy = pf_get_nblocksy(pt->format, pt->width0);
/* used for scanouts that need special layouts */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if (pt->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
if (i915_scanout_layout(tex))
return;
/* for shared buffers we use some very like scanout */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
if (pt->tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
if (i915_display_target_layout(tex))
return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->stride = align(pf_get_stride(pt->format, pt->width0), 4);
tex->total_nblocksy = 0;
for (level = 0; level <= pt->last_level; level++) {
i915_miptree_set_level_info(tex, level, 1, width, height, 1);
i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);
nblocksy = round_up(MAX2(2, nblocksy), 2);
nblocksy = align(MAX2(2, nblocksy), 2);
tex->total_nblocksy += nblocksy;
width = u_minify(width, 1);
height = u_minify(height, 1);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
nblocksy = pf_get_nblocksy(pt->format, height);
}
}
@ -266,13 +255,12 @@ i915_miptree_layout_3d(struct i915_texture *tex)
unsigned width = pt->width0;
unsigned height = pt->height0;
unsigned depth = pt->depth0;
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned nblocksy = pf_get_nblocksy(pt->format, pt->height0);
unsigned stack_nblocksy = 0;
/* Calculate the size of a single slice.
*/
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->stride = align(pf_get_stride(pt->format, pt->width0), 4);
/* XXX: hardware expects/requires 9 levels at minimum.
*/
@ -283,8 +271,7 @@ i915_miptree_layout_3d(struct i915_texture *tex)
width = u_minify(width, 1);
height = u_minify(height, 1);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
nblocksy = pf_get_nblocksy(pt->format, height);
}
/* Fixup depth image_offsets:
@ -309,14 +296,14 @@ i915_miptree_layout_cube(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
unsigned width = pt->width0, height = pt->height0;
const unsigned nblocks = pt->nblocksx[0];
const unsigned nblocks = pf_get_nblocksx(pt->format, pt->width0);
unsigned level;
unsigned face;
assert(width == height); /* cubemap images are square */
/* double pitch for cube layouts */
tex->stride = round_up(nblocks * pt->block.size * 2, 4);
tex->stride = align(nblocks * pf_get_blocksize(pt->format) * 2, 4);
tex->total_nblocksy = nblocks * 4;
for (level = 0; level <= pt->last_level; level++) {
@ -379,8 +366,8 @@ i945_miptree_layout_2d(struct i915_texture *tex)
unsigned y = 0;
unsigned width = pt->width0;
unsigned height = pt->height0;
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned nblocksx = pf_get_nblocksx(pt->format, pt->width0);
unsigned nblocksy = pf_get_nblocksy(pt->format, pt->height0);
/* used for scanouts that need special layouts */
if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
@ -392,7 +379,7 @@ i945_miptree_layout_2d(struct i915_texture *tex)
if (i915_display_target_layout(tex))
return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->stride = align(pf_get_stride(pt->format, pt->width0), 4);
/* May need to adjust pitch to accomodate the placement of
* the 2nd mipmap level. This occurs when the alignment
@ -401,11 +388,11 @@ i945_miptree_layout_2d(struct i915_texture *tex)
*/
if (pt->last_level > 0) {
unsigned mip1_nblocksx
= align(pf_get_nblocksx(&pt->block, u_minify(width, 1)), align_x)
+ pf_get_nblocksx(&pt->block, u_minify(width, 2));
= align(pf_get_nblocksx(pt->format, u_minify(width, 1)), align_x)
+ pf_get_nblocksx(pt->format, u_minify(width, 2));
if (mip1_nblocksx > nblocksx)
tex->stride = mip1_nblocksx * pt->block.size;
tex->stride = mip1_nblocksx * pf_get_blocksize(pt->format);
}
/* Pitch must be a whole number of dwords
@ -435,8 +422,8 @@ i945_miptree_layout_2d(struct i915_texture *tex)
width = u_minify(width, 1);
height = u_minify(height, 1);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
nblocksx = pf_get_nblocksx(pt->format, width);
nblocksy = pf_get_nblocksy(pt->format, height);
}
}
@ -447,17 +434,16 @@ i945_miptree_layout_3d(struct i915_texture *tex)
unsigned width = pt->width0;
unsigned height = pt->height0;
unsigned depth = pt->depth0;
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
unsigned nblocksy = pf_get_nblocksy(pt->format, pt->width0);
unsigned pack_x_pitch, pack_x_nr;
unsigned pack_y_pitch;
unsigned level;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
tex->stride = align(pf_get_stride(pt->format, pt->width0), 4);
tex->total_nblocksy = 0;
pack_y_pitch = MAX2(pt->nblocksy[0], 2);
pack_x_pitch = tex->stride / pt->block.size;
pack_y_pitch = MAX2(nblocksy, 2);
pack_x_pitch = tex->stride / pf_get_blocksize(pt->format);
pack_x_nr = 1;
for (level = 0; level <= pt->last_level; level++) {
@ -482,7 +468,7 @@ i945_miptree_layout_3d(struct i915_texture *tex)
if (pack_x_pitch > 4) {
pack_x_pitch >>= 1;
pack_x_nr <<= 1;
assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
assert(pack_x_pitch * pack_x_nr * pf_get_blocksize(pt->format) <= tex->stride);
}
if (pack_y_pitch > 2) {
@ -492,8 +478,7 @@ i945_miptree_layout_3d(struct i915_texture *tex)
width = u_minify(width, 1);
height = u_minify(height, 1);
depth = u_minify(depth, 1);
nblocksx = pf_get_nblocksx(&pt->block, width);
nblocksy = pf_get_nblocksy(&pt->block, height);
nblocksy = pf_get_nblocksy(pt->format, height);
}
}
@ -503,7 +488,7 @@ i945_miptree_layout_cube(struct i915_texture *tex)
struct pipe_texture *pt = &tex->base;
unsigned level;
const unsigned nblocks = pt->nblocksx[0];
const unsigned nblocks = pf_get_nblocksx(pt->format, pt->width0);
unsigned face;
unsigned width = pt->width0;
unsigned height = pt->height0;
@ -523,9 +508,9 @@ i945_miptree_layout_cube(struct i915_texture *tex)
* or the final row of 4x4, 2x2 and 1x1 faces below this.
*/
if (nblocks > 32)
tex->stride = round_up(nblocks * pt->block.size * 2, 4);
tex->stride = align(nblocks * pf_get_blocksize(pt->format) * 2, 4);
else
tex->stride = 14 * 8 * pt->block.size;
tex->stride = 14 * 8 * pf_get_blocksize(pt->format);
tex->total_nblocksy = nblocks * 4;
@ -645,9 +630,6 @@ i915_texture_create(struct pipe_screen *screen,
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width0);
tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height0);
if (is->is_i945) {
if (!i945_miptree_layout(tex))
goto fail;
@ -829,14 +811,10 @@ i915_get_tex_transfer(struct pipe_screen *screen,
trans = CALLOC_STRUCT(i915_transfer);
if (trans) {
pipe_texture_reference(&trans->base.texture, texture);
trans->base.format = trans->base.format;
trans->base.x = x;
trans->base.y = y;
trans->base.width = w;
trans->base.height = h;
trans->base.block = texture->block;
trans->base.nblocksx = texture->nblocksx[level];
trans->base.nblocksy = texture->nblocksy[level];
trans->base.stride = tex->stride;
trans->offset = offset;
trans->base.usage = usage;
@ -852,6 +830,7 @@ i915_transfer_map(struct pipe_screen *screen,
struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
char *map;
boolean write = FALSE;
enum pipe_format format = tex->base.format;
if (transfer->usage & PIPE_TRANSFER_WRITE)
write = TRUE;
@ -861,8 +840,8 @@ i915_transfer_map(struct pipe_screen *screen,
return NULL;
return map + i915_transfer(transfer)->offset +
transfer->y / transfer->block.height * transfer->stride +
transfer->x / transfer->block.width * transfer->block.size;
transfer->y / pf_get_blockheight(format) * transfer->stride +
transfer->x / pf_get_blockwidth(format) * pf_get_blocksize(format);
}
static void

View File

@ -742,7 +742,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
id_pipe->base.set_polygon_stipple = identity_set_polygon_stipple;
id_pipe->base.set_scissor_state = identity_set_scissor_state;
id_pipe->base.set_viewport_state = identity_set_viewport_state;
id_pipe->base.set_fragment_sampler_textures = identity_set_vertex_sampler_textures;
id_pipe->base.set_fragment_sampler_textures = identity_set_fragment_sampler_textures;
id_pipe->base.set_vertex_sampler_textures = identity_set_vertex_sampler_textures;
id_pipe->base.set_vertex_buffers = identity_set_vertex_buffers;
id_pipe->base.set_vertex_elements = identity_set_vertex_elements;

View File

@ -629,7 +629,8 @@ lp_build_abs(struct lp_build_context *bld,
if(type.floating) {
/* Mask out the sign bit */
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long)1 << type.width) - 1);
unsigned long absMask = ~(1 << (type.width - 1));
LLVMValueRef mask = lp_build_int_const_scalar(type, ((unsigned long long) absMask));
a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
a = LLVMBuildAnd(bld->builder, a, mask, "");
a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
@ -1083,7 +1084,7 @@ lp_build_log(struct lp_build_context *bld,
LLVMValueRef x)
{
/* log(2) */
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
LLVMValueRef log2 = lp_build_const_scalar(bld->type, 0.69314718055994529);
return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
}
@ -1095,7 +1096,7 @@ lp_build_log(struct lp_build_context *bld,
/**
* Generate polynomial.
* Ex: x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
* Ex: coeffs[0] + x * coeffs[1] + x^2 * coeffs[2].
*/
static LLVMValueRef
lp_build_polynomial(struct lp_build_context *bld,
@ -1285,13 +1286,13 @@ lp_build_log2_approx(struct lp_build_context *bld,
/* mant = (float) mantissa(x) */
mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
mant = LLVMBuildOr(bld->builder, mant, one, "");
mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
mant = LLVMBuildBitCast(bld->builder, mant, vec_type, "");
logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
Elements(lp_build_log2_polynomial));
/* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildSub(bld->builder, mant, bld->one, ""), "");
res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
}

View File

@ -77,10 +77,10 @@ lp_disassemble(const void* func)
while (ud_disassemble(&ud_obj)) {
#ifdef PIPE_ARCH_X86
debug_printf("%08lx: ", (unsigned long)ud_insn_off(&ud_obj));
debug_printf("0x%08lx:\t", (unsigned long)ud_insn_off(&ud_obj));
#endif
#ifdef PIPE_ARCH_X86_64
debug_printf("%016llx: ", (unsigned long long)ud_insn_off(&ud_obj));
debug_printf("0x%016llx:\t", (unsigned long long)ud_insn_off(&ud_obj));
#endif
#if 0
@ -115,9 +115,16 @@ lp_disassemble(const void* func)
}
}
if (ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret)
if ((ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret) ||
ud_obj.mnemonic == UD_Iinvalid)
break;
}
#if 0
/* Print GDB command, useful to verify udis86 output */
debug_printf("disassemble %p %p\n", func, (void*)(uintptr_t)ud_obj.pc);
#endif
debug_printf("\n");
#else
(void)func;

View File

@ -560,9 +560,9 @@ emit_instruction(
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
LLVMValueRef *p_floor_log2;
LLVMValueRef *p_exp;
LLVMValueRef *p_log2;
LLVMValueRef *p_floor_log2 = NULL;
LLVMValueRef *p_exp = NULL;
LLVMValueRef *p_log2 = NULL;
src0 = emit_fetch( bld, inst, 0, CHAN_X );
src0 = lp_build_abs( &bld->base, src0 );
@ -763,7 +763,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
tmp0 = lp_build_floor(&bld->base, src0);
tmp0 = lp_build_sub(&bld->base, tmp0, src0);
tmp0 = lp_build_sub(&bld->base, src0, tmp0);
dst0[chan_index] = tmp0;
}
break;

View File

@ -50,6 +50,7 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
double depth, unsigned stencil)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
union util_color uc;
unsigned cv;
uint i;
@ -64,8 +65,8 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i];
util_pack_color(rgba, ps->format, &cv);
lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv);
util_pack_color(rgba, ps->format, &uc);
lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, uc.ui);
}
llvmpipe->dirty_render_cache = TRUE;
}

View File

@ -118,6 +118,11 @@ static void llvmpipe_destroy( struct pipe_context *pipe )
pipe_texture_reference(&llvmpipe->texture[i], NULL);
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
lp_destroy_tex_tile_cache(llvmpipe->vertex_tex_cache[i]);
pipe_texture_reference(&llvmpipe->vertex_textures[i], NULL);
}
for (i = 0; i < Elements(llvmpipe->constants); i++) {
if (llvmpipe->constants[i].buffer) {
pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL);
@ -145,6 +150,11 @@ llvmpipe_is_texture_referenced( struct pipe_context *pipe,
llvmpipe->framebuffer.zsbuf->texture == texture)
return PIPE_REFERENCED_FOR_WRITE;
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
if (llvmpipe->vertex_tex_cache[i] &&
llvmpipe->vertex_tex_cache[i]->texture == texture)
return PIPE_REFERENCED_FOR_READ;
}
return PIPE_UNREFERENCED;
}
@ -181,6 +191,7 @@ llvmpipe_create( struct pipe_screen *screen )
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;
@ -206,6 +217,7 @@ llvmpipe_create( struct pipe_screen *screen )
llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
llvmpipe->pipe.set_fragment_sampler_textures = llvmpipe_set_sampler_textures;
llvmpipe->pipe.set_vertex_sampler_textures = llvmpipe_set_vertex_sampler_textures;
llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
@ -234,13 +246,15 @@ llvmpipe_create( struct pipe_screen *screen )
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
llvmpipe->tex_cache[i] = lp_create_tex_tile_cache( screen );
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++)
llvmpipe->vertex_tex_cache[i] = lp_create_tex_tile_cache(screen);
/* vertex shader samplers */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples;
llvmpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX;
llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->tex_cache[i];
llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->vertex_tex_cache[i];
llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i];
}
@ -260,7 +274,7 @@ llvmpipe_create( struct pipe_screen *screen )
goto fail;
draw_texture_samplers(llvmpipe->draw,
PIPE_MAX_SAMPLERS,
PIPE_MAX_VERTEX_SAMPLERS,
(struct tgsi_sampler **)
llvmpipe->tgsi.vert_samplers_list);

View File

@ -55,6 +55,7 @@ struct llvmpipe_context {
/** Constant state objects */
const struct pipe_blend_state *blend;
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
struct pipe_sampler_state *vertex_samplers[PIPE_MAX_VERTEX_SAMPLERS];
const struct pipe_depth_stencil_alpha_state *depth_stencil;
const struct pipe_rasterizer_state *rasterizer;
struct lp_fragment_shader *fs;
@ -68,12 +69,15 @@ struct llvmpipe_context {
struct pipe_poly_stipple poly_stipple;
struct pipe_scissor_state scissor;
struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
struct pipe_texture *vertex_textures[PIPE_MAX_VERTEX_SAMPLERS];
struct pipe_viewport_state viewport;
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
unsigned num_samplers;
unsigned num_textures;
unsigned num_vertex_samplers;
unsigned num_vertex_textures;
unsigned num_vertex_elements;
unsigned num_vertex_buffers;
@ -136,6 +140,7 @@ struct llvmpipe_context {
unsigned tex_timestamp;
struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
struct llvmpipe_tex_tile_cache *vertex_tex_cache[PIPE_MAX_VERTEX_SAMPLERS];
unsigned no_rast : 1;

View File

@ -0,0 +1,71 @@
/**************************************************************************
*
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef LP_DEBUG_H
#define LP_DEBUG_H
#include "pipe/p_compiler.h"
#include "util/u_debug.h"
extern void
st_print_current(void);
#define DEBUG_PIPE 0x1
#define DEBUG_TGSI 0x2
#define DEBUG_TEX 0x4
#define DEBUG_ASM 0x8
#define DEBUG_SETUP 0x10
#define DEBUG_RAST 0x20
#define DEBUG_QUERY 0x40
#define DEBUG_SCREEN 0x80
#define DEBUG_JIT 0x100
#ifdef DEBUG
extern int LP_DEBUG;
#else
#define LP_DEBUG 0
#endif
void st_debug_init( void );
static INLINE void
LP_DBG( unsigned flag, const char *fmt, ... )
{
if (LP_DEBUG & flag)
{
va_list args;
va_start( args, fmt );
debug_vprintf( fmt, args );
va_end( args );
}
}
#endif /* LP_DEBUG_H */

View File

@ -36,6 +36,24 @@
#include "lp_winsys.h"
#include "lp_jit.h"
#include "lp_screen.h"
#include "lp_debug.h"
#ifdef DEBUG
int LP_DEBUG = 0;
static const struct debug_named_value lp_debug_flags[] = {
{ "pipe", DEBUG_PIPE },
{ "tgsi", DEBUG_TGSI },
{ "tex", DEBUG_TEX },
{ "asm", DEBUG_ASM },
{ "setup", DEBUG_SETUP },
{ "rast", DEBUG_RAST },
{ "query", DEBUG_QUERY },
{ "screen", DEBUG_SCREEN },
{ "jit", DEBUG_JIT },
{NULL, 0}
};
#endif
static const char *
@ -59,7 +77,9 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
return PIPE_MAX_SAMPLERS;
case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
return 0;
return PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_MAX_COMBINED_SAMPLERS:
return PIPE_MAX_SAMPLERS + PIPE_MAX_VERTEX_SAMPLERS;
case PIPE_CAP_NPOT_TEXTURES:
return 1;
case PIPE_CAP_TWO_SIDED_STENCIL:
@ -257,6 +277,10 @@ llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
{
struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
#ifdef DEBUG
LP_DEBUG = debug_get_flags_option("LP_DEBUG", lp_debug_flags, 0 );
#endif
if (!screen)
return NULL;

View File

@ -166,7 +166,7 @@ shade_quads(struct llvmpipe_context *llvmpipe,
assert((y % 2) == 0);
depth = llvmpipe->zsbuf_map +
y*llvmpipe->zsbuf_transfer->stride +
2*x*llvmpipe->zsbuf_transfer->block.size;
2*x*pf_get_blocksize(llvmpipe->zsbuf_transfer->texture->format);
}
else
depth = NULL;

View File

@ -126,6 +126,10 @@ 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 *
@ -172,6 +176,11 @@ void llvmpipe_set_sampler_textures( struct pipe_context *,
unsigned num,
struct pipe_texture ** );
void
llvmpipe_set_vertex_sampler_textures(struct pipe_context *,
unsigned num_textures,
struct pipe_texture **);
void llvmpipe_set_viewport_state( struct pipe_context *,
const struct pipe_viewport_state * );

View File

@ -198,10 +198,14 @@ update_tgsi_samplers( struct llvmpipe_context *llvmpipe )
unsigned i;
/* vertex shader samplers */
for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->sampler[i];
llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->texture[i];
llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->vertex_samplers[i];
llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->vertex_textures[i];
llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples;
}
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
lp_tex_tile_cache_validate_texture( llvmpipe->vertex_tex_cache[i] );
}
/* fragment shader samplers */

View File

@ -87,6 +87,7 @@
#include "lp_state.h"
#include "lp_quad.h"
#include "lp_tex_sample.h"
#include "lp_debug.h"
static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
@ -408,59 +409,58 @@ generate_fragment(struct llvmpipe_context *lp,
unsigned i;
unsigned chan;
#ifdef DEBUG
tgsi_dump(shader->base.tokens, 0);
if(key->depth.enabled) {
debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
debug_printf("depth.writemask = %u\n", key->depth.writemask);
}
if(key->alpha.enabled) {
debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
}
if(key->blend.logicop_enable) {
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
}
else if(key->blend.blend_enable) {
debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
}
debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
if(key->sampler[i].format) {
debug_printf("sampler[%u] = \n", i);
debug_printf(" .format = %s\n",
pf_name(key->sampler[i].format));
debug_printf(" .target = %s\n",
debug_dump_tex_target(key->sampler[i].target, TRUE));
debug_printf(" .pot = %u %u %u\n",
key->sampler[i].pot_width,
key->sampler[i].pot_height,
key->sampler[i].pot_depth);
debug_printf(" .wrap = %s %s %s\n",
debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
debug_printf(" .min_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
debug_printf(" .min_mip_filter = %s\n",
debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
debug_printf(" .mag_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
if(key->sampler[i].compare_mode)
debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
if (LP_DEBUG & DEBUG_JIT) {
tgsi_dump(shader->base.tokens, 0);
if(key->depth.enabled) {
debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format));
debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
debug_printf("depth.writemask = %u\n", key->depth.writemask);
}
if(key->alpha.enabled) {
debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
}
if(key->blend.logicop_enable) {
debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
}
else if(key->blend.blend_enable) {
debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
}
debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) {
if(key->sampler[i].format) {
debug_printf("sampler[%u] = \n", i);
debug_printf(" .format = %s\n",
pf_name(key->sampler[i].format));
debug_printf(" .target = %s\n",
debug_dump_tex_target(key->sampler[i].target, TRUE));
debug_printf(" .pot = %u %u %u\n",
key->sampler[i].pot_width,
key->sampler[i].pot_height,
key->sampler[i].pot_depth);
debug_printf(" .wrap = %s %s %s\n",
debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE),
debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE));
debug_printf(" .min_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
debug_printf(" .min_mip_filter = %s\n",
debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
debug_printf(" .mag_img_filter = %s\n",
debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE));
if(key->sampler[i].compare_mode)
debug_printf(" .compare_mode = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE));
debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords);
debug_printf(" .prefilter = %u\n", key->sampler[i].prefilter);
}
}
}
#endif
variant = CALLOC_STRUCT(lp_fragment_shader_variant);
if(!variant)
return NULL;
@ -599,8 +599,8 @@ generate_fragment(struct llvmpipe_context *lp,
}
lp_build_conv_mask(builder, fs_type, blend_type,
fs_mask, num_fs,
&blend_mask, 1);
fs_mask, num_fs,
&blend_mask, 1);
/*
* Blending.
@ -631,16 +631,15 @@ generate_fragment(struct llvmpipe_context *lp,
LLVMRunFunctionPassManager(screen->pass, variant->function);
#ifdef DEBUG
LLVMDumpValue(variant->function);
debug_printf("\n");
#endif
if (LP_DEBUG & DEBUG_JIT) {
LLVMDumpValue(variant->function);
debug_printf("\n");
}
variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
#ifdef DEBUG
lp_disassemble(variant->jit_function);
#endif
if (LP_DEBUG & DEBUG_ASM)
lp_disassemble(variant->jit_function);
variant->next = shader->variants;
shader->variants = variant;

View File

@ -77,6 +77,34 @@ llvmpipe_bind_sampler_states(struct pipe_context *pipe,
}
void
llvmpipe_bind_vertex_sampler_states(struct pipe_context *pipe,
unsigned num_samplers,
void **samplers)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
unsigned i;
assert(num_samplers <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
if (num_samplers == llvmpipe->num_vertex_samplers &&
!memcmp(llvmpipe->vertex_samplers, samplers, num_samplers * sizeof(void *)))
return;
draw_flush(llvmpipe->draw);
for (i = 0; i < num_samplers; ++i)
llvmpipe->vertex_samplers[i] = samplers[i];
for (i = num_samplers; i < PIPE_MAX_VERTEX_SAMPLERS; ++i)
llvmpipe->vertex_samplers[i] = NULL;
llvmpipe->num_vertex_samplers = num_samplers;
llvmpipe->dirty |= LP_NEW_SAMPLER;
}
void
llvmpipe_set_sampler_textures(struct pipe_context *pipe,
unsigned num, struct pipe_texture **texture)
@ -116,6 +144,37 @@ llvmpipe_set_sampler_textures(struct pipe_context *pipe,
}
void
llvmpipe_set_vertex_sampler_textures(struct pipe_context *pipe,
unsigned num_textures,
struct pipe_texture **textures)
{
struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
uint i;
assert(num_textures <= PIPE_MAX_VERTEX_SAMPLERS);
/* Check for no-op */
if (num_textures == llvmpipe->num_vertex_textures &&
!memcmp(llvmpipe->vertex_textures, textures, num_textures * sizeof(struct pipe_texture *))) {
return;
}
draw_flush(llvmpipe->draw);
for (i = 0; i < PIPE_MAX_VERTEX_SAMPLERS; i++) {
struct pipe_texture *tex = i < num_textures ? textures[i] : NULL;
pipe_texture_reference(&llvmpipe->vertex_textures[i], tex);
lp_tex_tile_cache_set_texture(llvmpipe->vertex_tex_cache[i], tex);
}
llvmpipe->num_vertex_textures = num_textures;
llvmpipe->dirty |= LP_NEW_TEXTURE;
}
void
llvmpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)

View File

@ -155,7 +155,6 @@ lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc)
if (lpt->timestamp != tc->timestamp) {
/* texture was modified, invalidate all cached tiles */
uint i;
debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
for (i = 0; i < NUM_ENTRIES; i++) {
tc->entries[i].addr.bits.invalid = 1;
}
@ -291,7 +290,7 @@ lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc,
assert(0);
}
util_format_read_4ub(tc->tex_trans->format,
util_format_read_4ub(tc->tex_trans->texture->format,
(uint8_t *)tile->color, sizeof tile->color[0],
tc->tex_trans_map, tc->tex_trans->stride,
x, y, w, h);

View File

@ -50,7 +50,6 @@
/* Simple, maximally packed layout.
*/
/* Conventional allocation path for non-display textures:
*/
static boolean
@ -65,20 +64,15 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
unsigned buffer_size = 0;
util_format_get_block(lpt->base.format, &lpt->base.block);
for (level = 0; level <= pt->last_level; level++) {
unsigned nblocksx, nblocksy;
pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
/* Allocate storage for whole quads. This is particularly important
* for depth surfaces, which are currently stored in a swizzled format. */
nblocksx = pf_get_nblocksx(&pt->block, align(width, 2));
nblocksy = pf_get_nblocksy(&pt->block, align(height, 2));
nblocksx = pf_get_nblocksx(pt->format, align(width, 2));
nblocksy = pf_get_nblocksy(pt->format, align(height, 2));
lpt->stride[level] = align(nblocksx*pt->block.size, 16);
lpt->stride[level] = align(nblocksx * pf_get_blocksize(pt->format), 16);
lpt->level_offset[level] = buffer_size;
@ -102,10 +96,6 @@ llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
{
struct llvmpipe_winsys *winsys = screen->winsys;
util_format_get_block(lpt->base.format, &lpt->base.block);
lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width0);
lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height0);
lpt->dt = winsys->displaytarget_create(winsys,
lpt->base.format,
lpt->base.width0,
@ -182,8 +172,6 @@ llvmpipe_texture_blanket(struct pipe_screen * screen,
lpt->base = *base;
pipe_reference_init(&lpt->base.reference, 1);
lpt->base.screen = screen;
lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width0);
lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height0);
lpt->stride[0] = stride[0];
pipe_buffer_reference(&lpt->buffer, buffer);
@ -257,11 +245,17 @@ llvmpipe_get_tex_surface(struct pipe_screen *screen,
ps->level = level;
ps->zslice = zslice;
/* XXX shouldn't that rather be
tex_height = align(ps->height, 2);
to account for alignment done in llvmpipe_texture_layout ?
*/
if (pt->target == PIPE_TEXTURE_CUBE) {
ps->offset += face * pt->nblocksy[level] * lpt->stride[level];
unsigned tex_height = ps->height;
ps->offset += face * pf_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
}
else if (pt->target == PIPE_TEXTURE_3D) {
ps->offset += zslice * pt->nblocksy[level] * lpt->stride[level];
unsigned tex_height = ps->height;
ps->offset += zslice * pf_get_nblocksy(pt->format, tex_height) * lpt->stride[level];
}
else {
assert(face == 0);
@ -302,14 +296,10 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
if (lpt) {
struct pipe_transfer *pt = &lpt->base;
pipe_texture_reference(&pt->texture, texture);
pt->format = texture->format;
pt->block = texture->block;
pt->x = x;
pt->y = y;
pt->width = w;
pt->height = h;
pt->nblocksx = texture->nblocksx[level];
pt->nblocksy = texture->nblocksy[level];
pt->stride = lptex->stride[level];
pt->usage = usage;
pt->face = face;
@ -318,11 +308,17 @@ llvmpipe_get_tex_transfer(struct pipe_screen *screen,
lpt->offset = lptex->level_offset[level];
/* XXX shouldn't that rather be
tex_height = align(u_minify(texture->height0, level), 2)
to account for alignment done in llvmpipe_texture_layout ?
*/
if (texture->target == PIPE_TEXTURE_CUBE) {
lpt->offset += face * pt->nblocksy * pt->stride;
unsigned tex_height = u_minify(texture->height0, level);
lpt->offset += face * pf_get_nblocksy(texture->format, tex_height) * pt->stride;
}
else if (texture->target == PIPE_TEXTURE_3D) {
lpt->offset += zslice * pt->nblocksy * pt->stride;
unsigned tex_height = u_minify(texture->height0, level);
lpt->offset += zslice * pf_get_nblocksy(texture->format, tex_height) * pt->stride;
}
else {
assert(face == 0);
@ -354,9 +350,11 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
ubyte *map, *xfer_map;
struct llvmpipe_texture *lpt;
enum pipe_format format;
assert(transfer->texture);
lpt = llvmpipe_texture(transfer->texture);
format = lpt->base.format;
if(lpt->dt) {
struct llvmpipe_winsys *winsys = screen->winsys;
@ -381,8 +379,8 @@ llvmpipe_transfer_map( struct pipe_screen *_screen,
}
xfer_map = map + llvmpipe_transfer(transfer)->offset +
transfer->y / transfer->block.height * transfer->stride +
transfer->x / transfer->block.width * transfer->block.size;
transfer->y / pf_get_blockheight(format) * transfer->stride +
transfer->x / pf_get_blockwidth(format) * pf_get_blocksize(format);
/*printf("map = %p xfer map = %p\n", map, xfer_map);*/
return xfer_map;
}

View File

@ -252,13 +252,13 @@ lp_flush_tile_cache(struct llvmpipe_tile_cache *tc)
case LP_TILE_STATUS_CLEAR:
/* Actually clear the tiles which were flagged as being in a
* clear state. */
util_fill_rect(tc->transfer_map, &pt->block, pt->stride,
util_fill_rect(tc->transfer_map, pt->texture->format, pt->stride,
x, y, w, h,
tc->clear_val);
break;
case LP_TILE_STATUS_DEFINED:
lp_tile_write_4ub(pt->format,
lp_tile_write_4ub(pt->texture->format,
tile->color,
tc->transfer_map, pt->stride,
x, y, w, h);
@ -291,6 +291,11 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
assert(tc->surface);
assert(tc->transfer);
if(!tc->transfer_map)
lp_tile_cache_map_transfers(tc);
assert(tc->transfer_map);
switch(tile->status) {
case LP_TILE_STATUS_CLEAR:
/* don't get tile from framebuffer, just clear it */
@ -306,7 +311,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
y &= ~(TILE_SIZE - 1);
if (!pipe_clip_tile(x, y, &w, &h, tc->transfer))
lp_tile_read_4ub(pt->format,
lp_tile_read_4ub(pt->texture->format,
tile->color,
tc->transfer_map, tc->transfer->stride,
x, y, w, h);

View File

@ -48,13 +48,14 @@ so_ref(struct nouveau_stateobj *ref, struct nouveau_stateobj **pso)
struct nouveau_stateobj *so = *pso;
int i;
if (pipe_reference((struct pipe_reference**)pso, &ref->reference)) {
if (pipe_reference(&(*pso)->reference, &ref->reference)) {
free(so->push);
for (i = 0; i < so->cur_reloc; i++)
nouveau_bo_ref(NULL, &so->reloc[i].bo);
free(so->reloc);
free(so);
}
*pso = ref;
}
static INLINE void
@ -111,20 +112,30 @@ so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so)
{
struct nouveau_pushbuf *pb = chan->pushbuf;
unsigned nr, i;
int ret = 0;
nr = so->cur - so->push;
if (pb->remaining < nr)
nouveau_pushbuf_flush(chan, nr);
/* This will flush if we need space.
* We don't actually need the marker.
*/
if ((ret = nouveau_pushbuf_marker_emit(chan, nr, so->cur_reloc))) {
debug_printf("so_emit failed marker emit with error %d\n", ret);
return;
}
pb->remaining -= nr;
memcpy(pb->cur, so->push, nr * 4);
for (i = 0; i < so->cur_reloc; i++) {
struct nouveau_stateobj_reloc *r = &so->reloc[i];
nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset,
if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur + r->offset,
r->bo, r->data, 0, r->flags,
r->vor, r->tor);
r->vor, r->tor))) {
debug_printf("so_emit failed reloc with error %d\n", ret);
goto out;
}
}
out:
pb->cur += nr;
}
@ -133,26 +144,45 @@ so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so)
{
struct nouveau_pushbuf *pb = chan->pushbuf;
unsigned i;
int ret = 0;
if (!so)
return;
i = so->cur_reloc << 1;
if (pb->remaining < i)
nouveau_pushbuf_flush(chan, i);
/* This will flush if we need space.
* We don't actually need the marker.
*/
if ((ret = nouveau_pushbuf_marker_emit(chan, i, i))) {
debug_printf("so_emit_reloc_markers failed marker emit with" \
"error %d\n", ret);
return;
}
pb->remaining -= i;
for (i = 0; i < so->cur_reloc; i++) {
struct nouveau_stateobj_reloc *r = &so->reloc[i];
nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->packet, 0,
if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo,
r->packet, 0,
(r->flags & (NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART |
NOUVEAU_BO_RDWR)) |
NOUVEAU_BO_DUMMY, 0, 0);
nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo, r->data, 0,
NOUVEAU_BO_DUMMY, 0, 0))) {
debug_printf("so_emit_reloc_markers failed reloc" \
"with error %d\n", ret);
pb->remaining += ((so->cur_reloc - i) << 1);
return;
}
if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur++, r->bo,
r->data, 0,
r->flags | NOUVEAU_BO_DUMMY,
r->vor, r->tor);
r->vor, r->tor))) {
debug_printf("so_emit_reloc_markers failed reloc" \
"with error %d\n", ret);
pb->remaining += ((so->cur_reloc - i) << 1) - 1;
return;
}
}
}

View File

@ -10,28 +10,21 @@ static void
nv04_miptree_layout(struct nv04_miptree *nv04mt)
{
struct pipe_texture *pt = &nv04mt->base;
uint width = pt->width0, height = pt->height0;
uint offset = 0;
int nr_faces, l;
nr_faces = 1;
for (l = 0; l <= pt->last_level; l++) {
pt->nblocksx[l] = pf_get_nblocksx(&pt->block, width);
pt->nblocksy[l] = pf_get_nblocksy(&pt->block, height);
nv04mt->level[l].pitch = pt->width0;
nv04mt->level[l].pitch = (nv04mt->level[l].pitch + 63) & ~63;
width = u_minify(width, 1);
height = u_minify(height, 1);
}
for (l = 0; l <= pt->last_level; l++) {
nv04mt->level[l].image_offset =
CALLOC(nr_faces, sizeof(unsigned));
/* XXX guess was obviously missing */
nv04mt->level[l].image_offset[0] = offset;
offset += nv04mt->level[l].pitch * u_minify(pt->height0, l);
}
@ -62,7 +55,7 @@ nv04_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *pt)
FREE(mt);
return NULL;
}
mt->bo = nouveau_bo(mt->buffer);
return &mt->base;
}
@ -88,6 +81,7 @@ nv04_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
pipe_buffer_reference(&mt->buffer, pb);
mt->bo = nouveau_bo(mt->buffer);
return &mt->base;
}
@ -128,7 +122,7 @@ nv04_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
ns->base.zslice = zslice;
ns->pitch = nv04mt->level[level].pitch;
ns->base.offset = nv04mt->level[level].image_offset;
ns->base.offset = nv04mt->level[level].image_offset[0];
return &ns->base;
}

View File

@ -31,6 +31,7 @@ struct nv04_rasterizer_state {
struct nv04_miptree {
struct pipe_texture base;
struct nouveau_bo *bo;
struct pipe_buffer *buffer;
uint total_size;

View File

@ -133,6 +133,9 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
assert(sub_w == w || util_is_pot(sub_w));
assert(sub_h == h || util_is_pot(sub_h));
MARK_RING (chan, 8 + ((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*17, 2 +
((w+sub_w)/sub_w)*((h+sub_h)/sub_h)*2);
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
OUT_RELOCo(chan, dst_bo,
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@ -155,10 +158,10 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
sub_w = MIN2(sub_w, w - x);
/* Must be 64-byte aligned */
assert(!((dst->offset + nv04_swizzle_bits(dx+x, dy+y) * dst->texture->block.size) & 63));
assert(!((dst->offset + nv04_swizzle_bits(dx+x, dy+y) * pf_get_blocksize(dst->texture->format)) & 63));
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(dx+x, dy+y) * dst->texture->block.size,
OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(dx+x, dy+y) * pf_get_blocksize(dst->texture->format),
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 9);
@ -177,7 +180,7 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
OUT_RING (chan, src_pitch |
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
OUT_RELOCl(chan, src_bo, src->offset + (sy+y) * src_pitch + (sx+x) * src->texture->block.size,
OUT_RELOCl(chan, src_bo, src->offset + (sy+y) * src_pitch + (sx+x) * pf_get_blocksize(src->texture->format),
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
OUT_RING (chan, 0);
}
@ -198,11 +201,11 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
unsigned dst_offset = dst->offset + dy * dst_pitch +
dx * dst->texture->block.size;
dx * pf_get_blocksize(dst->texture->format);
unsigned src_offset = src->offset + sy * src_pitch +
sx * src->texture->block.size;
sx * pf_get_blocksize(src->texture->format);
WAIT_RING (chan, 3 + ((h / 2047) + 1) * 9);
MARK_RING (chan, 3 + ((h / 2047) + 1) * 9, 2 + ((h / 2047) + 1) * 2);
BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
OUT_RELOCo(chan, src_bo,
NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
@ -219,7 +222,7 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
OUT_RING (chan, src_pitch);
OUT_RING (chan, dst_pitch);
OUT_RING (chan, w * src->texture->block.size);
OUT_RING (chan, w * pf_get_blocksize(src->texture->format));
OUT_RING (chan, count);
OUT_RING (chan, 0x0101);
OUT_RING (chan, 0);
@ -250,7 +253,7 @@ nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
if (format < 0)
return 1;
WAIT_RING (chan, 12);
MARK_RING (chan, 12, 4);
BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
OUT_RELOCo(chan, src_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@ -315,7 +318,7 @@ nv04_surface_fill(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
gdirect_format = nv04_rect_format(dst->format);
assert(gdirect_format >= 0);
WAIT_RING (chan, 16);
MARK_RING (chan, 16, 4);
BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RELOCo(chan, dst_bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);

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