mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-14 13:20:28 +01:00
Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
This commit is contained in:
commit
62767cf2dd
55 changed files with 4319 additions and 592 deletions
|
|
@ -51,6 +51,7 @@ SOURCES = \
|
|||
manytex.c \
|
||||
minmag.c \
|
||||
mipmap_limits.c \
|
||||
mipmap_view.c \
|
||||
multipal.c \
|
||||
no_s3tc.c \
|
||||
packedpixels.c \
|
||||
|
|
@ -158,6 +159,14 @@ invert: invert.o readtex.o
|
|||
invert.o: invert.c readtex.h
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
|
||||
|
||||
mipmap_view: mipmap_view.o readtex.o
|
||||
$(CC) $(CFLAGS) mipmap_view.o readtex.o $(LIBS) -o $@
|
||||
|
||||
mipmap_view.o: mipmap_view.c readtex.h
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
|
||||
|
||||
|
||||
|
||||
readtex.o: readtex.c
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
|
||||
|
||||
|
|
|
|||
241
progs/tests/mipmap_view.c
Normal file
241
progs/tests/mipmap_view.c
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Test mipmap generation and lod bias.
|
||||
*
|
||||
* Brian Paul
|
||||
* 17 March 2008
|
||||
*/
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <GL/glut.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#include "readtex.h"
|
||||
|
||||
#define TEXTURE_FILE "../images/arch.rgb"
|
||||
|
||||
static int TexWidth = 256, TexHeight = 256;
|
||||
static int WinWidth = 1044, WinHeight = 900;
|
||||
static GLfloat Bias = 0.0;
|
||||
static GLboolean ScaleQuads = GL_FALSE;
|
||||
|
||||
|
||||
static void
|
||||
PrintString(const char *s)
|
||||
{
|
||||
while (*s) {
|
||||
glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Display(void)
|
||||
{
|
||||
int x, y, bias;
|
||||
char str[100];
|
||||
int texWidth = TexWidth, texHeight = TexHeight;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0, WinWidth, 0, WinHeight, -1, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
glColor3f(1,1,1);
|
||||
|
||||
y = WinHeight - 300;
|
||||
x = 4;
|
||||
|
||||
for (bias = -1; bias < 11; bias++) {
|
||||
|
||||
glRasterPos2f(x, y + TexHeight + 5);
|
||||
sprintf(str, "Texture LOD Bias = %d", bias);
|
||||
PrintString(str);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(x, y, 0);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
if (ScaleQuads) {
|
||||
if (bias > 0) {
|
||||
texWidth = TexWidth >> bias;
|
||||
texHeight = TexHeight >> bias;
|
||||
if (texWidth < 1)
|
||||
texWidth = 1;
|
||||
if (texHeight < 1)
|
||||
texHeight = 1;
|
||||
}
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0.0);
|
||||
}
|
||||
else {
|
||||
glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, bias);
|
||||
}
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
glTexCoord2f(0, 0); glVertex2f(0, 0);
|
||||
glTexCoord2f(1, 0); glVertex2f(texWidth, 0);
|
||||
glTexCoord2f(1, 1); glVertex2f(texWidth, texHeight);
|
||||
glTexCoord2f(0, 1); glVertex2f(0, texHeight);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
x += TexWidth + 4;
|
||||
if (x >= WinWidth) {
|
||||
x = 4;
|
||||
y -= 300;
|
||||
}
|
||||
}
|
||||
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Reshape(int width, int height)
|
||||
{
|
||||
WinWidth = width;
|
||||
WinHeight = height;
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Key(unsigned char key, int x, int y)
|
||||
{
|
||||
(void) x;
|
||||
(void) y;
|
||||
switch (key) {
|
||||
case 'b':
|
||||
Bias -= 10;
|
||||
break;
|
||||
case 'B':
|
||||
Bias += 10;
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
Bias = 100.0 * (key - '0');
|
||||
break;
|
||||
case 's':
|
||||
ScaleQuads = !ScaleQuads;
|
||||
break;
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Init(void)
|
||||
{
|
||||
GLfloat maxBias;
|
||||
|
||||
if (!glutExtensionSupported("GL_EXT_texture_lod_bias")) {
|
||||
printf("Sorry, GL_EXT_texture_lod_bias not supported by this renderer.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!glutExtensionSupported("GL_SGIS_generate_mipmap")) {
|
||||
printf("Sorry, GL_SGIS_generate_mipmap not supported by this renderer.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (1) {
|
||||
/* test auto mipmap generation */
|
||||
GLint width, height, i;
|
||||
GLenum format;
|
||||
GLubyte *image = LoadRGBImage(TEXTURE_FILE, &width, &height, &format);
|
||||
if (!image) {
|
||||
printf("Error: could not load texture image %s\n", TEXTURE_FILE);
|
||||
exit(1);
|
||||
}
|
||||
/* resize to TexWidth x TexHeight */
|
||||
if (width != TexWidth || height != TexHeight) {
|
||||
GLubyte *newImage = malloc(TexWidth * TexHeight * 4);
|
||||
gluScaleImage(format, width, height, GL_UNSIGNED_BYTE, image,
|
||||
TexWidth, TexHeight, GL_UNSIGNED_BYTE, newImage);
|
||||
free(image);
|
||||
image = newImage;
|
||||
}
|
||||
printf("Using GL_SGIS_generate_mipmap\n");
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, TexWidth, TexHeight, 0,
|
||||
format, GL_UNSIGNED_BYTE, image);
|
||||
free(image);
|
||||
|
||||
/* make sure mipmap was really generated correctly */
|
||||
width = TexWidth;
|
||||
height = TexHeight;
|
||||
for (i = 0; i < 9; i++) {
|
||||
GLint w, h;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_WIDTH, &w);
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, i, GL_TEXTURE_HEIGHT, &h);
|
||||
printf("Level %d size: %d x %d\n", i, w, h);
|
||||
assert(w == width);
|
||||
assert(h == height);
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
|
||||
printf("Using gluBuildMipmaps()\n");
|
||||
}
|
||||
else {
|
||||
printf("Error: could not load texture image %s\n", TEXTURE_FILE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* mipmapping required for this extension */
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
glGetFloatv(GL_MAX_TEXTURE_LOD_BIAS_EXT, &maxBias);
|
||||
|
||||
printf("GL_RENDERER: %s\n", (char*) glGetString(GL_RENDERER));
|
||||
printf("LOD bias range: [%g, %g]\n", -maxBias, maxBias);
|
||||
|
||||
printf("Press 's' to toggle quad scaling\n");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
glutInit(&argc, argv);
|
||||
glutInitWindowPosition(0, 0);
|
||||
glutInitWindowSize(WinWidth, WinHeight);
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
|
||||
glutCreateWindow(argv[0]);
|
||||
glutReshapeFunc(Reshape);
|
||||
glutKeyboardFunc(Key);
|
||||
glutDisplayFunc(Display);
|
||||
Init();
|
||||
glutMainLoop();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -149,6 +149,12 @@ void cso_set_blend(struct cso_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
void cso_unset_blend(struct cso_context *ctx)
|
||||
{
|
||||
ctx->blend = NULL;
|
||||
}
|
||||
|
||||
|
||||
void cso_single_sampler(struct cso_context *ctx,
|
||||
unsigned idx,
|
||||
const struct pipe_sampler_state *templ)
|
||||
|
|
@ -220,6 +226,15 @@ void cso_set_samplers( struct cso_context *ctx,
|
|||
cso_single_sampler_done( ctx );
|
||||
}
|
||||
|
||||
void cso_unset_samplers( struct cso_context *ctx )
|
||||
{
|
||||
uint i;
|
||||
for (i = 0; i < ctx->nr_samplers; i++)
|
||||
ctx->samplers[i] = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void cso_set_depth_stencil_alpha(struct cso_context *ctx,
|
||||
const struct pipe_depth_stencil_alpha_state *templ)
|
||||
{
|
||||
|
|
@ -252,6 +267,11 @@ void cso_set_depth_stencil_alpha(struct cso_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
void cso_unset_depth_stencil_alpha(struct cso_context *ctx)
|
||||
{
|
||||
ctx->depth_stencil = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void cso_set_rasterizer(struct cso_context *ctx,
|
||||
|
|
@ -285,7 +305,10 @@ void cso_set_rasterizer(struct cso_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void cso_unset_rasterizer(struct cso_context *ctx)
|
||||
{
|
||||
ctx->rasterizer = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -320,6 +343,12 @@ void cso_set_fragment_shader(struct cso_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
void cso_unset_fragment_shader(struct cso_context *ctx)
|
||||
{
|
||||
ctx->fragment_shader = NULL;
|
||||
}
|
||||
|
||||
|
||||
void cso_set_vertex_shader(struct cso_context *ctx,
|
||||
const struct pipe_shader_state *templ)
|
||||
{
|
||||
|
|
@ -350,3 +379,8 @@ void cso_set_vertex_shader(struct cso_context *ctx,
|
|||
ctx->pipe->bind_vs_state(ctx->pipe, handle);
|
||||
}
|
||||
}
|
||||
|
||||
void cso_unset_vertex_shader(struct cso_context *ctx)
|
||||
{
|
||||
ctx->vertex_shader = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,16 +44,25 @@ struct cso_context *cso_create_context( struct pipe_context *pipe );
|
|||
void cso_set_blend( struct cso_context *cso,
|
||||
const struct pipe_blend_state *blend );
|
||||
|
||||
void cso_unset_blend(struct cso_context *cso);
|
||||
|
||||
void cso_set_depth_stencil_alpha( struct cso_context *cso,
|
||||
const struct pipe_depth_stencil_alpha_state *dsa );
|
||||
|
||||
void cso_unset_depth_stencil_alpha( struct cso_context *cso );
|
||||
|
||||
void cso_set_rasterizer( struct cso_context *cso,
|
||||
const struct pipe_rasterizer_state *rasterizer );
|
||||
|
||||
void cso_unset_rasterizer( struct cso_context *cso );
|
||||
|
||||
void cso_set_samplers( struct cso_context *cso,
|
||||
unsigned count,
|
||||
const struct pipe_sampler_state **states );
|
||||
|
||||
void cso_unset_samplers( struct cso_context *cso );
|
||||
|
||||
|
||||
/* Alternate interface to support state trackers that like to modify
|
||||
* samplers one at a time:
|
||||
*/
|
||||
|
|
@ -72,9 +81,13 @@ void cso_single_sampler_done( struct cso_context *cso );
|
|||
void cso_set_fragment_shader( struct cso_context *cso,
|
||||
const struct pipe_shader_state *shader );
|
||||
|
||||
void cso_unset_fragment_shader( struct cso_context *cso );
|
||||
|
||||
void cso_set_vertex_shader( struct cso_context *cso,
|
||||
const struct pipe_shader_state *shader );
|
||||
|
||||
void cso_unset_vertex_shader( struct cso_context *cso );
|
||||
|
||||
void cso_destroy_context( struct cso_context *cso );
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -85,14 +85,52 @@ fetch_store_general( struct draw_context *draw,
|
|||
const unsigned *pitch = draw->vertex_fetch.pitch;
|
||||
const ubyte **src = draw->vertex_fetch.src_ptr;
|
||||
|
||||
for (i = start; i < count; i++) {
|
||||
for (i = start; i < start + count; i++) {
|
||||
for (j = 0; j < nr_attrs; j++) {
|
||||
/* vinfo->src_index is the output of the vertex shader
|
||||
* matching this hw-vertex component.
|
||||
*
|
||||
* In passthrough, we require a 1:1 mapping between vertex
|
||||
* shader outputs and inputs, which in turn correspond to
|
||||
* vertex elements in the state. So, this is the vertex
|
||||
* element we're interested in...
|
||||
*/
|
||||
const uint jj = vinfo->src_index[j];
|
||||
const enum pipe_format srcFormat = draw->vertex_element[jj].src_format;
|
||||
const ubyte *from = src[jj] + i * pitch[jj];
|
||||
float attrib[4];
|
||||
|
||||
/* Except... When we're not. Two cases EMIT_HEADER &
|
||||
* EMIT_1F_PSIZE don't consume an input. Should have some
|
||||
* method for indicating this, or change the logic here
|
||||
* somewhat so it doesn't matter.
|
||||
*
|
||||
* Just hack this up now, do something better about it later.
|
||||
*/
|
||||
if (vinfo->emit[j] == EMIT_HEADER) {
|
||||
memset(out, 0, sizeof(struct vertex_header));
|
||||
out += sizeof(struct vertex_header) / 4;
|
||||
continue;
|
||||
}
|
||||
else if (vinfo->emit[j] == EMIT_1F_PSIZE) {
|
||||
out[0] = 1.0; /* xxx */
|
||||
out += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* The normal fetch/emit code:
|
||||
*/
|
||||
switch (srcFormat) {
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
{
|
||||
ubyte *ub = (ubyte *) from;
|
||||
attrib[0] = UBYTE_TO_FLOAT(ub[0]);
|
||||
attrib[1] = UBYTE_TO_FLOAT(ub[1]);
|
||||
attrib[2] = UBYTE_TO_FLOAT(ub[2]);
|
||||
attrib[3] = UBYTE_TO_FLOAT(ub[3]);
|
||||
}
|
||||
break;
|
||||
case PIPE_FORMAT_R32G32B32A32_FLOAT:
|
||||
{
|
||||
float *f = (float *) from;
|
||||
|
|
@ -130,14 +168,21 @@ fetch_store_general( struct draw_context *draw,
|
|||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
assert(0);
|
||||
}
|
||||
|
||||
/* XXX this will probably only work for softpipe */
|
||||
debug_printf("attrib %d: %f %f %f %f\n", j,
|
||||
attrib[0], attrib[1], attrib[2], attrib[3]);
|
||||
|
||||
switch (vinfo->emit[j]) {
|
||||
case EMIT_HEADER:
|
||||
memset(out, 0, sizeof(struct vertex_header));
|
||||
out += sizeof(struct vertex_header) / 4;
|
||||
case EMIT_1F:
|
||||
out[0] = attrib[0];
|
||||
out += 1;
|
||||
break;
|
||||
case EMIT_2F:
|
||||
out[0] = attrib[0];
|
||||
out[1] = attrib[1];
|
||||
out += 2;
|
||||
break;
|
||||
case EMIT_4F:
|
||||
out[0] = attrib[0];
|
||||
|
|
@ -147,64 +192,15 @@ fetch_store_general( struct draw_context *draw,
|
|||
out += 4;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
assert(0);
|
||||
}
|
||||
|
||||
}
|
||||
debug_printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Example of a fetch/emit passthrough shader which could be
|
||||
* generated when bypass_clipping is enabled on a passthrough vertex
|
||||
* shader.
|
||||
*/
|
||||
static void fetch_xyz_rgb_st( struct draw_context *draw,
|
||||
float *out,
|
||||
unsigned start,
|
||||
unsigned count )
|
||||
{
|
||||
const unsigned *pitch = draw->vertex_fetch.pitch;
|
||||
const ubyte **src = draw->vertex_fetch.src_ptr;
|
||||
unsigned i;
|
||||
|
||||
const ubyte *xyzw = src[0] + start * pitch[0];
|
||||
const ubyte *rgba = src[1] + start * pitch[1];
|
||||
const ubyte *st = src[2] + start * pitch[2];
|
||||
|
||||
/* loop over vertex attributes (vertex shader inputs)
|
||||
*/
|
||||
for (i = 0; i < count; i++) {
|
||||
{
|
||||
const float *in = (const float *)xyzw; xyzw += pitch[0];
|
||||
/* decode input, encode output. Assume both are float[4] */
|
||||
out[0] = in[0];
|
||||
out[1] = in[1];
|
||||
out[2] = in[2];
|
||||
out[3] = in[3];
|
||||
}
|
||||
|
||||
{
|
||||
const float *in = (const float *)rgba; rgba += pitch[1];
|
||||
/* decode input, encode output. Assume both are float[4] */
|
||||
out[4] = in[0];
|
||||
out[5] = in[1];
|
||||
out[6] = in[2];
|
||||
out[7] = in[3];
|
||||
}
|
||||
|
||||
{
|
||||
const float *in = (const float *)st; st += pitch[2];
|
||||
/* decode input, encode output. Assume both are float[2] */
|
||||
out[8] = in[0];
|
||||
out[9] = in[1];
|
||||
}
|
||||
|
||||
out += 10;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean update_shader( struct draw_context *draw )
|
||||
{
|
||||
const struct vertex_info *vinfo = draw->render->get_vertex_info(draw->render);
|
||||
|
|
@ -229,70 +225,166 @@ static boolean update_shader( struct draw_context *draw )
|
|||
|
||||
draw->pt.hw_vertex_size = vinfo->size * 4;
|
||||
|
||||
/* Just trying to figure out how this would work:
|
||||
*/
|
||||
if (draw->rasterizer->bypass_vs ||
|
||||
(nr_attrs == 3 && 0 /* some other tests */))
|
||||
{
|
||||
#if 0
|
||||
draw->vertex_fetch.pt_fetch = fetch_xyz_rgb_st;
|
||||
#else
|
||||
draw->vertex_fetch.pt_fetch = fetch_store_general;
|
||||
#endif
|
||||
/*assert(vinfo->size == 10);*/
|
||||
draw->vertex_fetch.pt_fetch = fetch_store_general;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static boolean split_prim_inplace(unsigned prim, unsigned *first, unsigned *incr)
|
||||
{
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
*first = 1;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINES:
|
||||
*first = 2;
|
||||
*incr = 2;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
*first = 2;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
*first = 3;
|
||||
*incr = 3;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
*first = 3;
|
||||
*incr = 1;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_QUADS:
|
||||
*first = 4;
|
||||
*incr = 4;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
*first = 4;
|
||||
*incr = 2;
|
||||
return TRUE;
|
||||
default:
|
||||
*first = 0;
|
||||
*incr = 1; /* set to one so that count % incr works */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static boolean set_prim( struct draw_context *draw,
|
||||
unsigned prim )
|
||||
unsigned prim,
|
||||
unsigned count )
|
||||
{
|
||||
assert(!draw->user.elts);
|
||||
|
||||
draw->pt.prim = prim;
|
||||
|
||||
switch (prim) {
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
if (count > 1024)
|
||||
return FALSE;
|
||||
return draw->render->set_primitive( draw->render, PIPE_PRIM_LINE_STRIP );
|
||||
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
case PIPE_PRIM_POLYGON:
|
||||
if (count > 1024)
|
||||
return FALSE;
|
||||
return draw->render->set_primitive( draw->render, prim );
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
return FALSE;
|
||||
return draw->render->set_primitive( draw->render, PIPE_PRIM_TRIANGLES );
|
||||
|
||||
default:
|
||||
draw->render->set_primitive( draw->render, prim );
|
||||
return TRUE;
|
||||
return draw->render->set_primitive( draw->render, prim );
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
draw_passthrough_arrays(struct draw_context *draw,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count)
|
||||
|
||||
#define INDEX(i) (start + (i))
|
||||
static void pt_draw_arrays( struct draw_context *draw,
|
||||
unsigned start,
|
||||
unsigned length )
|
||||
{
|
||||
float *hw_verts;
|
||||
ushort *tmp = NULL;
|
||||
unsigned i, j;
|
||||
|
||||
if (draw_need_pipeline(draw))
|
||||
return FALSE;
|
||||
switch (draw->pt.prim) {
|
||||
case PIPE_PRIM_LINE_LOOP:
|
||||
tmp = MALLOC( sizeof(ushort) * (length + 1) );
|
||||
|
||||
if (!set_prim(draw, prim))
|
||||
return FALSE;
|
||||
for (i = 0; i < length; i++)
|
||||
tmp[i] = INDEX(i);
|
||||
tmp[length] = 0;
|
||||
|
||||
if (!update_shader(draw))
|
||||
return FALSE;
|
||||
draw->render->draw( draw->render,
|
||||
tmp,
|
||||
length+1 );
|
||||
break;
|
||||
|
||||
hw_verts = draw->render->allocate_vertices( draw->render,
|
||||
draw->pt.hw_vertex_size,
|
||||
count );
|
||||
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
tmp = MALLOC( sizeof(ushort) * (length / 2 * 6) );
|
||||
|
||||
for (j = i = 0; i + 3 < length; i += 2, j += 6) {
|
||||
tmp[j+0] = INDEX(i+0);
|
||||
tmp[j+1] = INDEX(i+1);
|
||||
tmp[j+2] = INDEX(i+3);
|
||||
|
||||
tmp[j+3] = INDEX(i+2);
|
||||
tmp[j+4] = INDEX(i+0);
|
||||
tmp[j+5] = INDEX(i+3);
|
||||
}
|
||||
|
||||
if (j)
|
||||
draw->render->draw( draw->render, tmp, j );
|
||||
break;
|
||||
|
||||
case PIPE_PRIM_QUADS:
|
||||
tmp = MALLOC( sizeof(int) * (length / 4 * 6) );
|
||||
|
||||
for (j = i = 0; i + 3 < length; i += 4, j += 6) {
|
||||
tmp[j+0] = INDEX(i+0);
|
||||
tmp[j+1] = INDEX(i+1);
|
||||
tmp[j+2] = INDEX(i+3);
|
||||
|
||||
tmp[j+3] = INDEX(i+1);
|
||||
tmp[j+4] = INDEX(i+2);
|
||||
tmp[j+5] = INDEX(i+3);
|
||||
}
|
||||
|
||||
if (j)
|
||||
draw->render->draw( draw->render, tmp, j );
|
||||
break;
|
||||
|
||||
default:
|
||||
draw->render->draw_arrays( draw->render,
|
||||
start,
|
||||
length );
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp)
|
||||
FREE(tmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static boolean do_draw( struct draw_context *draw,
|
||||
unsigned start, unsigned count )
|
||||
{
|
||||
float *hw_verts =
|
||||
draw->render->allocate_vertices( draw->render,
|
||||
(ushort)draw->pt.hw_vertex_size,
|
||||
(ushort)count );
|
||||
|
||||
if (!hw_verts)
|
||||
return FALSE;
|
||||
|
||||
/* Single routine to fetch vertices, run shader and emit HW verts.
|
||||
* Clipping and viewport transformation are done on hardware.
|
||||
/* Single routine to fetch vertices and emit HW verts.
|
||||
*/
|
||||
draw->vertex_fetch.pt_fetch( draw,
|
||||
hw_verts,
|
||||
|
|
@ -301,9 +393,9 @@ draw_passthrough_arrays(struct draw_context *draw,
|
|||
/* Draw arrays path to avoid re-emitting index list again and
|
||||
* again.
|
||||
*/
|
||||
draw->render->draw_arrays( draw->render,
|
||||
start,
|
||||
count );
|
||||
pt_draw_arrays( draw,
|
||||
0,
|
||||
count );
|
||||
|
||||
|
||||
draw->render->release_vertices( draw->render,
|
||||
|
|
@ -314,3 +406,68 @@ draw_passthrough_arrays(struct draw_context *draw,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
draw_passthrough_arrays(struct draw_context *draw,
|
||||
unsigned prim,
|
||||
unsigned start,
|
||||
unsigned count)
|
||||
{
|
||||
unsigned i = 0;
|
||||
unsigned first, incr;
|
||||
|
||||
//debug_printf("%s prim %d start %d count %d\n", __FUNCTION__, prim, start, count);
|
||||
|
||||
split_prim_inplace(prim, &first, &incr);
|
||||
|
||||
count -= (count - first) % incr;
|
||||
|
||||
debug_printf("%s %d %d %d\n", __FUNCTION__, prim, start, count);
|
||||
|
||||
if (draw_need_pipeline(draw))
|
||||
return FALSE;
|
||||
|
||||
debug_printf("%s AAA\n", __FUNCTION__);
|
||||
|
||||
if (!set_prim(draw, prim, count))
|
||||
return FALSE;
|
||||
|
||||
/* XXX: need a single value that reflects the most recent call to
|
||||
* driver->set_primitive:
|
||||
*/
|
||||
draw->pt.prim = prim;
|
||||
|
||||
debug_printf("%s BBB\n", __FUNCTION__);
|
||||
|
||||
if (!update_shader(draw))
|
||||
return FALSE;
|
||||
|
||||
debug_printf("%s CCC\n", __FUNCTION__);
|
||||
|
||||
/* Chop this up into bite-sized pieces that a driver should be able
|
||||
* to devour -- problem is we don't have a quick way to query the
|
||||
* driver on the maximum size for this chunk in the current state.
|
||||
*/
|
||||
while (i + first <= count) {
|
||||
int nr = MIN2( count - i, 1024 );
|
||||
|
||||
/* snap to prim boundary
|
||||
*/
|
||||
nr -= (nr - first) % incr;
|
||||
|
||||
if (!do_draw( draw, start + i, nr )) {
|
||||
assert(0);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* increment allowing for repeated vertices
|
||||
*/
|
||||
i += nr - (first - incr);
|
||||
}
|
||||
|
||||
|
||||
debug_printf("%s DONE\n", __FUNCTION__);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -169,11 +169,12 @@ void draw_do_flush( struct draw_context *draw, unsigned flags )
|
|||
flushing = TRUE;
|
||||
|
||||
if (flags >= DRAW_FLUSH_SHADER_QUEUE) {
|
||||
if (draw->vs.queue_nr)
|
||||
if (draw->vs.queue_nr) {
|
||||
if (draw->rasterizer->bypass_vs)
|
||||
fetch_and_store(draw);
|
||||
else
|
||||
(*draw->shader_queue_flush)(draw);
|
||||
}
|
||||
|
||||
if (flags >= DRAW_FLUSH_PRIM_QUEUE) {
|
||||
if (draw->pq.queue_nr)
|
||||
|
|
|
|||
|
|
@ -74,9 +74,11 @@ struct vbuf_render {
|
|||
|
||||
/**
|
||||
* Notify the renderer of the current primitive when it changes.
|
||||
* Prim is restricted to TRIANGLES, LINES and POINTS.
|
||||
* Must succeed for TRIANGLES, LINES and POINTS. Other prims at
|
||||
* the discretion of the driver, for the benefit of the passthrough
|
||||
* path.
|
||||
*/
|
||||
void (*set_primitive)( struct vbuf_render *, unsigned prim );
|
||||
boolean (*set_primitive)( struct vbuf_render *, unsigned prim );
|
||||
|
||||
/**
|
||||
* DrawElements, note indices are ushort:
|
||||
|
|
|
|||
|
|
@ -316,7 +316,9 @@ void spe_init_func(struct spe_function *p, unsigned code_size)
|
|||
|
||||
void spe_release_func(struct spe_function *p)
|
||||
{
|
||||
align_free(p->store);
|
||||
if (p->store != NULL) {
|
||||
align_free(p->store);
|
||||
}
|
||||
p->store = NULL;
|
||||
p->csr = NULL;
|
||||
}
|
||||
|
|
@ -326,8 +328,8 @@ int spe_allocate_available_register(struct spe_function *p)
|
|||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 128; i++) {
|
||||
const uint64_t mask = (1ULL << (i % 128));
|
||||
const unsigned idx = i / 128;
|
||||
const uint64_t mask = (1ULL << (i % 64));
|
||||
const unsigned idx = i / 64;
|
||||
|
||||
if ((p->regs[idx] & mask) != 0) {
|
||||
p->regs[idx] &= ~mask;
|
||||
|
|
@ -341,8 +343,8 @@ int spe_allocate_available_register(struct spe_function *p)
|
|||
|
||||
int spe_allocate_register(struct spe_function *p, int reg)
|
||||
{
|
||||
const unsigned idx = reg / 128;
|
||||
const unsigned bit = reg % 128;
|
||||
const unsigned idx = reg / 64;
|
||||
const unsigned bit = reg % 64;
|
||||
|
||||
assert((p->regs[idx] & (1ULL << bit)) != 0);
|
||||
|
||||
|
|
@ -353,8 +355,8 @@ int spe_allocate_register(struct spe_function *p, int reg)
|
|||
|
||||
void spe_release_register(struct spe_function *p, int reg)
|
||||
{
|
||||
const unsigned idx = reg / 128;
|
||||
const unsigned bit = reg % 128;
|
||||
const unsigned idx = reg / 64;
|
||||
const unsigned bit = reg % 64;
|
||||
|
||||
assert((p->regs[idx] & (1ULL << bit)) == 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,13 @@ C_SOURCES = \
|
|||
p_debug.c \
|
||||
p_tile.c \
|
||||
p_util.c \
|
||||
u_blit.c \
|
||||
u_draw_quad.c \
|
||||
u_gen_mipmap.c \
|
||||
u_handle_table.c \
|
||||
u_hash_table.c \
|
||||
u_mm.c \
|
||||
u_simple_shaders.c \
|
||||
u_snprintf.c
|
||||
|
||||
include ../../Makefile.template
|
||||
|
|
|
|||
|
|
@ -6,9 +6,13 @@ util = env.ConvenienceLibrary(
|
|||
'p_debug.c',
|
||||
'p_tile.c',
|
||||
'p_util.c',
|
||||
'u_blit.c',
|
||||
'u_draw_quad.c',
|
||||
'u_gen_mipmap.c',
|
||||
'u_handle_table.c',
|
||||
'u_hash_table.c',
|
||||
'u_mm.c',
|
||||
'u_simple_shaders.c',
|
||||
'u_snprintf.c',
|
||||
])
|
||||
|
||||
|
|
|
|||
276
src/gallium/auxiliary/util/u_blit.c
Normal file
276
src/gallium/auxiliary/util/u_blit.c
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Copy/blit pixel rect between surfaces
|
||||
*
|
||||
* @author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "util/u_draw_quad.h"
|
||||
#include "util/u_blit.h"
|
||||
#include "util/u_simple_shaders.h"
|
||||
|
||||
|
||||
struct blit_state
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
|
||||
void *blend;
|
||||
void *depthstencil;
|
||||
void *rasterizer;
|
||||
void *samplers[2]; /* one for linear, one for nearest sampling */
|
||||
|
||||
/*struct pipe_viewport_state viewport;*/
|
||||
struct pipe_sampler_state *vs;
|
||||
struct pipe_sampler_state *fs;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create state object for blit.
|
||||
* Intended to be created once and re-used for many blit() calls.
|
||||
*/
|
||||
struct blit_state *
|
||||
util_create_blit(struct pipe_context *pipe)
|
||||
{
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
struct blit_state *ctx;
|
||||
struct pipe_sampler_state sampler;
|
||||
|
||||
ctx = CALLOC_STRUCT(blit_state);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
ctx->pipe = pipe;
|
||||
|
||||
/* we don't use blending, but need to set valid values */
|
||||
memset(&blend, 0, sizeof(blend));
|
||||
blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
|
||||
blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
|
||||
blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
|
||||
blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
|
||||
blend.colormask = PIPE_MASK_RGBA;
|
||||
ctx->blend = pipe->create_blend_state(pipe, &blend);
|
||||
|
||||
/* depth/stencil/alpha */
|
||||
memset(&depthstencil, 0, sizeof(depthstencil));
|
||||
ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
|
||||
|
||||
/* rasterizer */
|
||||
memset(&rasterizer, 0, sizeof(rasterizer));
|
||||
rasterizer.front_winding = PIPE_WINDING_CW;
|
||||
rasterizer.cull_mode = PIPE_WINDING_NONE;
|
||||
rasterizer.bypass_clipping = 1; /* bypasses viewport too */
|
||||
/*rasterizer.bypass_vs = 1;*/
|
||||
ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer);
|
||||
|
||||
/* samplers */
|
||||
memset(&sampler, 0, sizeof(sampler));
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
sampler.normalized_coords = 1;
|
||||
ctx->samplers[0] = pipe->create_sampler_state(pipe, &sampler);
|
||||
|
||||
sampler.min_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
|
||||
sampler.mag_img_filter = PIPE_TEX_MIPFILTER_LINEAR;
|
||||
ctx->samplers[1] = pipe->create_sampler_state(pipe, &sampler);
|
||||
|
||||
|
||||
#if 0
|
||||
/* viewport */
|
||||
ctx->viewport.scale[0] = 1.0;
|
||||
ctx->viewport.scale[1] = 1.0;
|
||||
ctx->viewport.scale[2] = 1.0;
|
||||
ctx->viewport.scale[3] = 1.0;
|
||||
ctx->viewport.translate[0] = 0.0;
|
||||
ctx->viewport.translate[1] = 0.0;
|
||||
ctx->viewport.translate[2] = 0.0;
|
||||
ctx->viewport.translate[3] = 0.0;
|
||||
#endif
|
||||
|
||||
/* vertex shader */
|
||||
{
|
||||
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
|
||||
TGSI_SEMANTIC_GENERIC };
|
||||
const uint semantic_indexes[] = { 0, 0 };
|
||||
ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
|
||||
semantic_indexes);
|
||||
}
|
||||
|
||||
/* fragment shader */
|
||||
ctx->fs = util_make_fragment_tex_shader(pipe);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy a blit context
|
||||
*/
|
||||
void
|
||||
util_destroy_blit(struct blit_state *ctx)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
|
||||
pipe->delete_blend_state(pipe, ctx->blend);
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil);
|
||||
pipe->delete_rasterizer_state(pipe, ctx->rasterizer);
|
||||
pipe->delete_sampler_state(pipe, ctx->samplers[0]);
|
||||
pipe->delete_sampler_state(pipe, ctx->samplers[1]);
|
||||
|
||||
pipe->delete_vs_state(pipe, ctx->vs);
|
||||
pipe->delete_fs_state(pipe, ctx->fs);
|
||||
|
||||
FREE(ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy pixel block from src surface to dst surface.
|
||||
* Overlapping regions are acceptable.
|
||||
* XXX need some control over blitting Z and/or stencil.
|
||||
*/
|
||||
void
|
||||
util_blit_pixels(struct blit_state *ctx,
|
||||
struct pipe_surface *src,
|
||||
int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
struct pipe_surface *dst,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1,
|
||||
float z, uint filter)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_texture texTemp, *tex;
|
||||
struct pipe_surface *texSurf;
|
||||
struct pipe_framebuffer_state fb;
|
||||
const int srcW = abs(srcX1 - srcX0);
|
||||
const int srcH = abs(srcY1 - srcY0);
|
||||
const int srcLeft = MIN2(srcX0, srcX1);
|
||||
const int srcTop = MIN2(srcY0, srcY1);
|
||||
|
||||
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
|
||||
filter == PIPE_TEX_MIPFILTER_LINEAR);
|
||||
|
||||
if (srcLeft != srcX0) {
|
||||
/* left-right flip */
|
||||
int tmp = dstX0;
|
||||
dstX0 = dstX1;
|
||||
dstX1 = tmp;
|
||||
}
|
||||
|
||||
if (srcTop != srcY0) {
|
||||
/* up-down flip */
|
||||
int tmp = dstY0;
|
||||
dstY0 = dstY1;
|
||||
dstY1 = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX for now we're always creating a temporary texture.
|
||||
* Strictly speaking that's not always needed.
|
||||
*/
|
||||
|
||||
/* create temp texture */
|
||||
memset(&texTemp, 0, sizeof(texTemp));
|
||||
texTemp.target = PIPE_TEXTURE_2D;
|
||||
texTemp.format = src->format;
|
||||
texTemp.last_level = 0;
|
||||
texTemp.width[0] = srcW;
|
||||
texTemp.height[0] = srcH;
|
||||
texTemp.depth[0] = 1;
|
||||
texTemp.compressed = 0;
|
||||
texTemp.cpp = pf_get_bits(src->format) / 8;
|
||||
|
||||
tex = screen->texture_create(screen, &texTemp);
|
||||
if (!tex)
|
||||
return;
|
||||
|
||||
texSurf = screen->get_tex_surface(screen, tex, 0, 0, 0);
|
||||
|
||||
/* load temp texture */
|
||||
pipe->surface_copy(pipe, FALSE,
|
||||
texSurf, 0, 0, /* dest */
|
||||
src, srcLeft, srcTop, /* src */
|
||||
srcW, srcH); /* size */
|
||||
|
||||
/* drawing dest */
|
||||
memset(&fb, 0, sizeof(fb));
|
||||
fb.num_cbufs = 1;
|
||||
fb.cbufs[0] = dst;
|
||||
pipe->set_framebuffer_state(pipe, &fb);
|
||||
|
||||
/* sampler */
|
||||
if (filter == PIPE_TEX_MIPFILTER_NEAREST)
|
||||
pipe->bind_sampler_states(pipe, 1, &ctx->samplers[0]);
|
||||
else
|
||||
pipe->bind_sampler_states(pipe, 1, &ctx->samplers[1]);
|
||||
|
||||
/* texture */
|
||||
pipe->set_sampler_textures(pipe, 1, &tex);
|
||||
|
||||
/* shaders */
|
||||
pipe->bind_fs_state(pipe, ctx->fs);
|
||||
pipe->bind_vs_state(pipe, ctx->vs);
|
||||
|
||||
/* misc state */
|
||||
pipe->bind_blend_state(pipe, ctx->blend);
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil);
|
||||
pipe->bind_rasterizer_state(pipe, ctx->rasterizer);
|
||||
|
||||
/* draw quad */
|
||||
util_draw_texquad(pipe, dstX0, dstY0, dstX1, dstY1, z);
|
||||
|
||||
/* unbind */
|
||||
pipe->set_sampler_textures(pipe, 0, NULL);
|
||||
pipe->bind_sampler_states(pipe, 0, NULL);
|
||||
|
||||
/* free stuff */
|
||||
pipe_surface_reference(&texSurf, NULL);
|
||||
screen->texture_release(screen, &tex);
|
||||
|
||||
/* Note: caller must restore pipe/gallium state at this time */
|
||||
}
|
||||
|
||||
60
src/gallium/auxiliary/util/u_blit.h
Normal file
60
src/gallium/auxiliary/util/u_blit.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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 U_BLIT_H
|
||||
#define U_BLIT_H
|
||||
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_surface;
|
||||
|
||||
|
||||
struct blit_state;
|
||||
|
||||
|
||||
extern struct blit_state *
|
||||
util_create_blit(struct pipe_context *pipe);
|
||||
|
||||
|
||||
extern void
|
||||
util_destroy_blit(struct blit_state *ctx);
|
||||
|
||||
|
||||
|
||||
extern void
|
||||
util_blit_pixels(struct blit_state *ctx,
|
||||
struct pipe_surface *src,
|
||||
int srcX0, int srcY0,
|
||||
int srcX1, int srcY1,
|
||||
struct pipe_surface *dst,
|
||||
int dstX0, int dstY0,
|
||||
int dstX1, int dstY1,
|
||||
float z, uint filter);
|
||||
|
||||
|
||||
#endif
|
||||
112
src/gallium/auxiliary/util/u_draw_quad.c
Normal file
112
src/gallium/auxiliary/util/u_draw_quad.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "util/u_draw_quad.h"
|
||||
|
||||
|
||||
/**
|
||||
* Draw screen-aligned textured quad.
|
||||
*/
|
||||
void
|
||||
util_draw_texquad(struct pipe_context *pipe,
|
||||
float x0, float y0, float x1, float y1, float z)
|
||||
{
|
||||
struct pipe_buffer *vbuf;
|
||||
struct pipe_vertex_buffer vbuffer;
|
||||
struct pipe_vertex_element velement;
|
||||
uint numAttribs = 2, vertexBytes, i, j;
|
||||
float *v;
|
||||
|
||||
vertexBytes = 4 * (4 * numAttribs * sizeof(float));
|
||||
|
||||
/* XXX create one-time */
|
||||
vbuf = pipe->winsys->buffer_create(pipe->winsys, 32,
|
||||
PIPE_BUFFER_USAGE_VERTEX, vertexBytes);
|
||||
assert(vbuf);
|
||||
|
||||
v = (float *) pipe->winsys->buffer_map(pipe->winsys, vbuf,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE);
|
||||
|
||||
/*
|
||||
* Load vertex buffer
|
||||
*/
|
||||
for (i = j = 0; i < 4; i++) {
|
||||
v[j + 2] = z; /* z */
|
||||
v[j + 3] = 1.0; /* w */
|
||||
v[j + 6] = 0.0; /* r */
|
||||
v[j + 7] = 1.0; /* q */
|
||||
j += 8;
|
||||
}
|
||||
|
||||
v[0] = x0;
|
||||
v[1] = y0;
|
||||
v[4] = 0.0; /*s*/
|
||||
v[5] = 0.0; /*t*/
|
||||
|
||||
v[8] = x1;
|
||||
v[9] = y0;
|
||||
v[12] = 1.0;
|
||||
v[13] = 0.0;
|
||||
|
||||
v[16] = x1;
|
||||
v[17] = y1;
|
||||
v[20] = 1.0;
|
||||
v[21] = 1.0;
|
||||
|
||||
v[24] = x0;
|
||||
v[25] = y1;
|
||||
v[28] = 0.0;
|
||||
v[29] = 1.0;
|
||||
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, vbuf);
|
||||
|
||||
/* tell pipe about the vertex buffer */
|
||||
vbuffer.buffer = vbuf;
|
||||
vbuffer.pitch = numAttribs * 4 * sizeof(float); /* vertex size */
|
||||
vbuffer.buffer_offset = 0;
|
||||
pipe->set_vertex_buffer(pipe, 0, &vbuffer);
|
||||
|
||||
/* tell pipe about the vertex attributes */
|
||||
for (i = 0; i < numAttribs; i++) {
|
||||
velement.src_offset = i * 4 * sizeof(float);
|
||||
velement.vertex_buffer_index = 0;
|
||||
velement.src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
|
||||
velement.nr_components = 4;
|
||||
pipe->set_vertex_element(pipe, i, &velement);
|
||||
}
|
||||
|
||||
/* draw */
|
||||
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
/* XXX: do one-time */
|
||||
pipe_buffer_reference(pipe->winsys, &vbuf, NULL);
|
||||
}
|
||||
37
src/gallium/auxiliary/util/u_draw_quad.h
Normal file
37
src/gallium/auxiliary/util/u_draw_quad.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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 U_DRAWQUAD_H
|
||||
#define U_DRAWQUAD_H
|
||||
|
||||
|
||||
extern void
|
||||
util_draw_texquad(struct pipe_context *pipe,
|
||||
float x0, float y0, float x1, float y1, float z);
|
||||
|
||||
|
||||
#endif
|
||||
877
src/gallium/auxiliary/util/u_gen_mipmap.c
Normal file
877
src/gallium/auxiliary/util/u_gen_mipmap.c
Normal file
|
|
@ -0,0 +1,877 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Mipmap generation utility
|
||||
*
|
||||
* @author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "util/u_draw_quad.h"
|
||||
#include "util/u_gen_mipmap.h"
|
||||
#include "util/u_simple_shaders.h"
|
||||
|
||||
#include "tgsi/util/tgsi_build.h"
|
||||
#include "tgsi/util/tgsi_dump.h"
|
||||
#include "tgsi/util/tgsi_parse.h"
|
||||
|
||||
|
||||
struct gen_mipmap_state
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
|
||||
void *blend;
|
||||
void *depthstencil;
|
||||
void *rasterizer;
|
||||
/*struct pipe_viewport_state viewport;*/
|
||||
struct pipe_sampler_state *vs;
|
||||
struct pipe_sampler_state *fs;
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum dtype
|
||||
{
|
||||
UBYTE,
|
||||
UBYTE_3_3_2,
|
||||
USHORT,
|
||||
USHORT_4_4_4_4,
|
||||
USHORT_5_6_5,
|
||||
USHORT_1_5_5_5_REV,
|
||||
UINT,
|
||||
FLOAT,
|
||||
HALF_FLOAT
|
||||
};
|
||||
|
||||
|
||||
typedef ushort half_float;
|
||||
|
||||
|
||||
#if 0
|
||||
extern half_float
|
||||
float_to_half(float f);
|
||||
|
||||
extern float
|
||||
half_to_float(half_float h);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Average together two rows of a source image to produce a single new
|
||||
* row in the dest image. It's legal for the two source rows to point
|
||||
* to the same data. The source width must be equal to either the
|
||||
* dest width or two times the dest width.
|
||||
* \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc.
|
||||
* \param comps number of components per pixel (1..4)
|
||||
*/
|
||||
static void
|
||||
do_row(enum dtype datatype, uint comps, int srcWidth,
|
||||
const void *srcRowA, const void *srcRowB,
|
||||
int dstWidth, void *dstRow)
|
||||
{
|
||||
const uint k0 = (srcWidth == dstWidth) ? 0 : 1;
|
||||
const uint colStride = (srcWidth == dstWidth) ? 1 : 2;
|
||||
|
||||
assert(comps >= 1);
|
||||
assert(comps <= 4);
|
||||
|
||||
/* This assertion is no longer valid with non-power-of-2 textures
|
||||
assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
|
||||
*/
|
||||
|
||||
if (datatype == UBYTE && comps == 4) {
|
||||
uint i, j, k;
|
||||
const ubyte(*rowA)[4] = (const ubyte(*)[4]) srcRowA;
|
||||
const ubyte(*rowB)[4] = (const ubyte(*)[4]) srcRowB;
|
||||
ubyte(*dst)[4] = (ubyte(*)[4]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
|
||||
dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
|
||||
}
|
||||
}
|
||||
else if (datatype == UBYTE && comps == 3) {
|
||||
uint i, j, k;
|
||||
const ubyte(*rowA)[3] = (const ubyte(*)[3]) srcRowA;
|
||||
const ubyte(*rowB)[3] = (const ubyte(*)[3]) srcRowB;
|
||||
ubyte(*dst)[3] = (ubyte(*)[3]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
|
||||
}
|
||||
}
|
||||
else if (datatype == UBYTE && comps == 2) {
|
||||
uint i, j, k;
|
||||
const ubyte(*rowA)[2] = (const ubyte(*)[2]) srcRowA;
|
||||
const ubyte(*rowB)[2] = (const ubyte(*)[2]) srcRowB;
|
||||
ubyte(*dst)[2] = (ubyte(*)[2]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
|
||||
}
|
||||
}
|
||||
else if (datatype == UBYTE && comps == 1) {
|
||||
uint i, j, k;
|
||||
const ubyte *rowA = (const ubyte *) srcRowA;
|
||||
const ubyte *rowB = (const ubyte *) srcRowB;
|
||||
ubyte *dst = (ubyte *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
else if (datatype == USHORT && comps == 4) {
|
||||
uint i, j, k;
|
||||
const ushort(*rowA)[4] = (const ushort(*)[4]) srcRowA;
|
||||
const ushort(*rowB)[4] = (const ushort(*)[4]) srcRowB;
|
||||
ushort(*dst)[4] = (ushort(*)[4]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
|
||||
dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
|
||||
}
|
||||
}
|
||||
else if (datatype == USHORT && comps == 3) {
|
||||
uint i, j, k;
|
||||
const ushort(*rowA)[3] = (const ushort(*)[3]) srcRowA;
|
||||
const ushort(*rowB)[3] = (const ushort(*)[3]) srcRowB;
|
||||
ushort(*dst)[3] = (ushort(*)[3]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
|
||||
}
|
||||
}
|
||||
else if (datatype == USHORT && comps == 2) {
|
||||
uint i, j, k;
|
||||
const ushort(*rowA)[2] = (const ushort(*)[2]) srcRowA;
|
||||
const ushort(*rowB)[2] = (const ushort(*)[2]) srcRowB;
|
||||
ushort(*dst)[2] = (ushort(*)[2]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
|
||||
}
|
||||
}
|
||||
else if (datatype == USHORT && comps == 1) {
|
||||
uint i, j, k;
|
||||
const ushort *rowA = (const ushort *) srcRowA;
|
||||
const ushort *rowB = (const ushort *) srcRowB;
|
||||
ushort *dst = (ushort *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
|
||||
}
|
||||
}
|
||||
|
||||
else if (datatype == FLOAT && comps == 4) {
|
||||
uint i, j, k;
|
||||
const float(*rowA)[4] = (const float(*)[4]) srcRowA;
|
||||
const float(*rowB)[4] = (const float(*)[4]) srcRowB;
|
||||
float(*dst)[4] = (float(*)[4]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] +
|
||||
rowB[j][0] + rowB[k][0]) * 0.25F;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] +
|
||||
rowB[j][1] + rowB[k][1]) * 0.25F;
|
||||
dst[i][2] = (rowA[j][2] + rowA[k][2] +
|
||||
rowB[j][2] + rowB[k][2]) * 0.25F;
|
||||
dst[i][3] = (rowA[j][3] + rowA[k][3] +
|
||||
rowB[j][3] + rowB[k][3]) * 0.25F;
|
||||
}
|
||||
}
|
||||
else if (datatype == FLOAT && comps == 3) {
|
||||
uint i, j, k;
|
||||
const float(*rowA)[3] = (const float(*)[3]) srcRowA;
|
||||
const float(*rowB)[3] = (const float(*)[3]) srcRowB;
|
||||
float(*dst)[3] = (float(*)[3]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] +
|
||||
rowB[j][0] + rowB[k][0]) * 0.25F;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] +
|
||||
rowB[j][1] + rowB[k][1]) * 0.25F;
|
||||
dst[i][2] = (rowA[j][2] + rowA[k][2] +
|
||||
rowB[j][2] + rowB[k][2]) * 0.25F;
|
||||
}
|
||||
}
|
||||
else if (datatype == FLOAT && comps == 2) {
|
||||
uint i, j, k;
|
||||
const float(*rowA)[2] = (const float(*)[2]) srcRowA;
|
||||
const float(*rowB)[2] = (const float(*)[2]) srcRowB;
|
||||
float(*dst)[2] = (float(*)[2]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i][0] = (rowA[j][0] + rowA[k][0] +
|
||||
rowB[j][0] + rowB[k][0]) * 0.25F;
|
||||
dst[i][1] = (rowA[j][1] + rowA[k][1] +
|
||||
rowB[j][1] + rowB[k][1]) * 0.25F;
|
||||
}
|
||||
}
|
||||
else if (datatype == FLOAT && comps == 1) {
|
||||
uint i, j, k;
|
||||
const float *rowA = (const float *) srcRowA;
|
||||
const float *rowB = (const float *) srcRowB;
|
||||
float *dst = (float *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
else if (datatype == HALF_FLOAT && comps == 4) {
|
||||
uint i, j, k, comp;
|
||||
const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA;
|
||||
const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB;
|
||||
half_float(*dst)[4] = (half_float(*)[4]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
for (comp = 0; comp < 4; comp++) {
|
||||
float aj, ak, bj, bk;
|
||||
aj = half_to_float(rowA[j][comp]);
|
||||
ak = half_to_float(rowA[k][comp]);
|
||||
bj = half_to_float(rowB[j][comp]);
|
||||
bk = half_to_float(rowB[k][comp]);
|
||||
dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (datatype == HALF_FLOAT && comps == 3) {
|
||||
uint i, j, k, comp;
|
||||
const half_float(*rowA)[3] = (const half_float(*)[3]) srcRowA;
|
||||
const half_float(*rowB)[3] = (const half_float(*)[3]) srcRowB;
|
||||
half_float(*dst)[3] = (half_float(*)[3]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
for (comp = 0; comp < 3; comp++) {
|
||||
float aj, ak, bj, bk;
|
||||
aj = half_to_float(rowA[j][comp]);
|
||||
ak = half_to_float(rowA[k][comp]);
|
||||
bj = half_to_float(rowB[j][comp]);
|
||||
bk = half_to_float(rowB[k][comp]);
|
||||
dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (datatype == HALF_FLOAT && comps == 2) {
|
||||
uint i, j, k, comp;
|
||||
const half_float(*rowA)[2] = (const half_float(*)[2]) srcRowA;
|
||||
const half_float(*rowB)[2] = (const half_float(*)[2]) srcRowB;
|
||||
half_float(*dst)[2] = (half_float(*)[2]) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
for (comp = 0; comp < 2; comp++) {
|
||||
float aj, ak, bj, bk;
|
||||
aj = half_to_float(rowA[j][comp]);
|
||||
ak = half_to_float(rowA[k][comp]);
|
||||
bj = half_to_float(rowB[j][comp]);
|
||||
bk = half_to_float(rowB[k][comp]);
|
||||
dst[i][comp] = float_to_half((aj + ak + bj + bk) * 0.25F);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (datatype == HALF_FLOAT && comps == 1) {
|
||||
uint i, j, k;
|
||||
const half_float *rowA = (const half_float *) srcRowA;
|
||||
const half_float *rowB = (const half_float *) srcRowB;
|
||||
half_float *dst = (half_float *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
float aj, ak, bj, bk;
|
||||
aj = half_to_float(rowA[j]);
|
||||
ak = half_to_float(rowA[k]);
|
||||
bj = half_to_float(rowB[j]);
|
||||
bk = half_to_float(rowB[k]);
|
||||
dst[i] = float_to_half((aj + ak + bj + bk) * 0.25F);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (datatype == UINT && comps == 1) {
|
||||
uint i, j, k;
|
||||
const uint *rowA = (const uint *) srcRowA;
|
||||
const uint *rowB = (const uint *) srcRowB;
|
||||
uint *dst = (uint *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
|
||||
}
|
||||
}
|
||||
|
||||
else if (datatype == USHORT_5_6_5 && comps == 3) {
|
||||
uint i, j, k;
|
||||
const ushort *rowA = (const ushort *) srcRowA;
|
||||
const ushort *rowB = (const ushort *) srcRowB;
|
||||
ushort *dst = (ushort *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
const int rowAr0 = rowA[j] & 0x1f;
|
||||
const int rowAr1 = rowA[k] & 0x1f;
|
||||
const int rowBr0 = rowB[j] & 0x1f;
|
||||
const int rowBr1 = rowB[k] & 0x1f;
|
||||
const int rowAg0 = (rowA[j] >> 5) & 0x3f;
|
||||
const int rowAg1 = (rowA[k] >> 5) & 0x3f;
|
||||
const int rowBg0 = (rowB[j] >> 5) & 0x3f;
|
||||
const int rowBg1 = (rowB[k] >> 5) & 0x3f;
|
||||
const int rowAb0 = (rowA[j] >> 11) & 0x1f;
|
||||
const int rowAb1 = (rowA[k] >> 11) & 0x1f;
|
||||
const int rowBb0 = (rowB[j] >> 11) & 0x1f;
|
||||
const int rowBb1 = (rowB[k] >> 11) & 0x1f;
|
||||
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
|
||||
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
|
||||
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
|
||||
dst[i] = (blue << 11) | (green << 5) | red;
|
||||
}
|
||||
}
|
||||
else if (datatype == USHORT_4_4_4_4 && comps == 4) {
|
||||
uint i, j, k;
|
||||
const ushort *rowA = (const ushort *) srcRowA;
|
||||
const ushort *rowB = (const ushort *) srcRowB;
|
||||
ushort *dst = (ushort *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
const int rowAr0 = rowA[j] & 0xf;
|
||||
const int rowAr1 = rowA[k] & 0xf;
|
||||
const int rowBr0 = rowB[j] & 0xf;
|
||||
const int rowBr1 = rowB[k] & 0xf;
|
||||
const int rowAg0 = (rowA[j] >> 4) & 0xf;
|
||||
const int rowAg1 = (rowA[k] >> 4) & 0xf;
|
||||
const int rowBg0 = (rowB[j] >> 4) & 0xf;
|
||||
const int rowBg1 = (rowB[k] >> 4) & 0xf;
|
||||
const int rowAb0 = (rowA[j] >> 8) & 0xf;
|
||||
const int rowAb1 = (rowA[k] >> 8) & 0xf;
|
||||
const int rowBb0 = (rowB[j] >> 8) & 0xf;
|
||||
const int rowBb1 = (rowB[k] >> 8) & 0xf;
|
||||
const int rowAa0 = (rowA[j] >> 12) & 0xf;
|
||||
const int rowAa1 = (rowA[k] >> 12) & 0xf;
|
||||
const int rowBa0 = (rowB[j] >> 12) & 0xf;
|
||||
const int rowBa1 = (rowB[k] >> 12) & 0xf;
|
||||
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
|
||||
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
|
||||
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
|
||||
const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
|
||||
dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
|
||||
}
|
||||
}
|
||||
else if (datatype == USHORT_1_5_5_5_REV && comps == 4) {
|
||||
uint i, j, k;
|
||||
const ushort *rowA = (const ushort *) srcRowA;
|
||||
const ushort *rowB = (const ushort *) srcRowB;
|
||||
ushort *dst = (ushort *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
const int rowAr0 = rowA[j] & 0x1f;
|
||||
const int rowAr1 = rowA[k] & 0x1f;
|
||||
const int rowBr0 = rowB[j] & 0x1f;
|
||||
const int rowBr1 = rowB[k] & 0xf;
|
||||
const int rowAg0 = (rowA[j] >> 5) & 0x1f;
|
||||
const int rowAg1 = (rowA[k] >> 5) & 0x1f;
|
||||
const int rowBg0 = (rowB[j] >> 5) & 0x1f;
|
||||
const int rowBg1 = (rowB[k] >> 5) & 0x1f;
|
||||
const int rowAb0 = (rowA[j] >> 10) & 0x1f;
|
||||
const int rowAb1 = (rowA[k] >> 10) & 0x1f;
|
||||
const int rowBb0 = (rowB[j] >> 10) & 0x1f;
|
||||
const int rowBb1 = (rowB[k] >> 10) & 0x1f;
|
||||
const int rowAa0 = (rowA[j] >> 15) & 0x1;
|
||||
const int rowAa1 = (rowA[k] >> 15) & 0x1;
|
||||
const int rowBa0 = (rowB[j] >> 15) & 0x1;
|
||||
const int rowBa1 = (rowB[k] >> 15) & 0x1;
|
||||
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
|
||||
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
|
||||
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
|
||||
const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
|
||||
dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
|
||||
}
|
||||
}
|
||||
else if (datatype == UBYTE_3_3_2 && comps == 3) {
|
||||
uint i, j, k;
|
||||
const ubyte *rowA = (const ubyte *) srcRowA;
|
||||
const ubyte *rowB = (const ubyte *) srcRowB;
|
||||
ubyte *dst = (ubyte *) dstRow;
|
||||
for (i = j = 0, k = k0; i < (uint) dstWidth;
|
||||
i++, j += colStride, k += colStride) {
|
||||
const int rowAr0 = rowA[j] & 0x3;
|
||||
const int rowAr1 = rowA[k] & 0x3;
|
||||
const int rowBr0 = rowB[j] & 0x3;
|
||||
const int rowBr1 = rowB[k] & 0x3;
|
||||
const int rowAg0 = (rowA[j] >> 2) & 0x7;
|
||||
const int rowAg1 = (rowA[k] >> 2) & 0x7;
|
||||
const int rowBg0 = (rowB[j] >> 2) & 0x7;
|
||||
const int rowBg1 = (rowB[k] >> 2) & 0x7;
|
||||
const int rowAb0 = (rowA[j] >> 5) & 0x7;
|
||||
const int rowAb1 = (rowA[k] >> 5) & 0x7;
|
||||
const int rowBb0 = (rowB[j] >> 5) & 0x7;
|
||||
const int rowBb1 = (rowB[k] >> 5) & 0x7;
|
||||
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
|
||||
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
|
||||
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
|
||||
dst[i] = (blue << 5) | (green << 2) | red;
|
||||
}
|
||||
}
|
||||
else {
|
||||
debug_printf("bad format in do_row()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
format_to_type_comps(enum pipe_format pformat,
|
||||
enum dtype *datatype, uint *comps)
|
||||
{
|
||||
switch (pformat) {
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
*datatype = UBYTE;
|
||||
*comps = 4;
|
||||
return;
|
||||
case PIPE_FORMAT_A1R5G5B5_UNORM:
|
||||
*datatype = USHORT_1_5_5_5_REV;
|
||||
*comps = 4;
|
||||
return;
|
||||
case PIPE_FORMAT_A4R4G4B4_UNORM:
|
||||
*datatype = USHORT_4_4_4_4;
|
||||
*comps = 4;
|
||||
return;
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
*datatype = USHORT_5_6_5;
|
||||
*comps = 3;
|
||||
return;
|
||||
case PIPE_FORMAT_U_L8:
|
||||
case PIPE_FORMAT_U_A8:
|
||||
case PIPE_FORMAT_U_I8:
|
||||
*datatype = UBYTE;
|
||||
*comps = 1;
|
||||
return;
|
||||
case PIPE_FORMAT_U_A8_L8:
|
||||
*datatype = UBYTE;
|
||||
*comps = 2;
|
||||
return;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
reduce_1d(enum pipe_format pformat,
|
||||
int srcWidth, const ubyte *srcPtr,
|
||||
int dstWidth, ubyte *dstPtr)
|
||||
{
|
||||
enum dtype datatype;
|
||||
uint comps;
|
||||
|
||||
format_to_type_comps(pformat, &datatype, &comps);
|
||||
|
||||
/* we just duplicate the input row, kind of hack, saves code */
|
||||
do_row(datatype, comps,
|
||||
srcWidth, srcPtr, srcPtr,
|
||||
dstWidth, dstPtr);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strides are in bytes. If zero, it'll be computed as width * bpp.
|
||||
*/
|
||||
static void
|
||||
reduce_2d(enum pipe_format pformat,
|
||||
int srcWidth, int srcHeight,
|
||||
int srcRowStride, const ubyte *srcPtr,
|
||||
int dstWidth, int dstHeight,
|
||||
int dstRowStride, ubyte *dstPtr)
|
||||
{
|
||||
enum dtype datatype;
|
||||
uint comps;
|
||||
const int bpt = pf_get_size(pformat);
|
||||
const ubyte *srcA, *srcB;
|
||||
ubyte *dst;
|
||||
int row;
|
||||
|
||||
format_to_type_comps(pformat, &datatype, &comps);
|
||||
|
||||
if (!srcRowStride)
|
||||
srcRowStride = bpt * srcWidth;
|
||||
|
||||
if (!dstRowStride)
|
||||
dstRowStride = bpt * dstWidth;
|
||||
|
||||
/* Compute src and dst pointers */
|
||||
srcA = srcPtr;
|
||||
if (srcHeight > 1)
|
||||
srcB = srcA + srcRowStride;
|
||||
else
|
||||
srcB = srcA;
|
||||
dst = dstPtr;
|
||||
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
do_row(datatype, comps,
|
||||
srcWidth, srcA, srcB,
|
||||
dstWidth, dst);
|
||||
srcA += 2 * srcRowStride;
|
||||
srcB += 2 * srcRowStride;
|
||||
dst += dstRowStride;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
make_1d_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_winsys *winsys = pipe->winsys;
|
||||
const uint zslice = 0;
|
||||
uint dstLevel;
|
||||
|
||||
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
|
||||
const uint srcLevel = dstLevel - 1;
|
||||
struct pipe_surface *srcSurf, *dstSurf;
|
||||
void *srcMap, *dstMap;
|
||||
|
||||
srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
|
||||
dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
|
||||
|
||||
srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ)
|
||||
+ srcSurf->offset);
|
||||
dstMap = ((ubyte *) winsys->buffer_map(winsys, dstSurf->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE)
|
||||
+ dstSurf->offset);
|
||||
|
||||
reduce_1d(pt->format,
|
||||
srcSurf->width, srcMap,
|
||||
dstSurf->width, dstMap);
|
||||
|
||||
winsys->buffer_unmap(winsys, srcSurf->buffer);
|
||||
winsys->buffer_unmap(winsys, dstSurf->buffer);
|
||||
|
||||
pipe_surface_reference(&srcSurf, NULL);
|
||||
pipe_surface_reference(&dstSurf, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
make_2d_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_winsys *winsys = pipe->winsys;
|
||||
const uint zslice = 0;
|
||||
uint dstLevel;
|
||||
const int bpt = pf_get_size(pt->format);
|
||||
|
||||
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
|
||||
const uint srcLevel = dstLevel - 1;
|
||||
struct pipe_surface *srcSurf, *dstSurf;
|
||||
ubyte *srcMap, *dstMap;
|
||||
|
||||
srcSurf = screen->get_tex_surface(screen, pt, face, srcLevel, zslice);
|
||||
dstSurf = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
|
||||
|
||||
srcMap = ((ubyte *) winsys->buffer_map(winsys, srcSurf->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_READ)
|
||||
+ srcSurf->offset);
|
||||
dstMap = ((ubyte *) winsys->buffer_map(winsys, dstSurf->buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE)
|
||||
+ dstSurf->offset);
|
||||
|
||||
reduce_2d(pt->format,
|
||||
srcSurf->width, srcSurf->height,
|
||||
srcSurf->pitch * bpt, srcMap,
|
||||
dstSurf->width, dstSurf->height,
|
||||
dstSurf->pitch * bpt, dstMap);
|
||||
|
||||
winsys->buffer_unmap(winsys, srcSurf->buffer);
|
||||
winsys->buffer_unmap(winsys, dstSurf->buffer);
|
||||
|
||||
pipe_surface_reference(&srcSurf, NULL);
|
||||
pipe_surface_reference(&dstSurf, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
make_3d_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fallback_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel)
|
||||
{
|
||||
switch (pt->target) {
|
||||
case PIPE_TEXTURE_1D:
|
||||
make_1d_mipmap(ctx, pt, face, baseLevel, lastLevel);
|
||||
break;
|
||||
case PIPE_TEXTURE_2D:
|
||||
case PIPE_TEXTURE_CUBE:
|
||||
make_2d_mipmap(ctx, pt, face, baseLevel, lastLevel);
|
||||
break;
|
||||
case PIPE_TEXTURE_3D:
|
||||
make_3d_mipmap(ctx, pt, face, baseLevel, lastLevel);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a mipmap generation context.
|
||||
* The idea is to create one of these and re-use it each time we need to
|
||||
* generate a mipmap.
|
||||
*/
|
||||
struct gen_mipmap_state *
|
||||
util_create_gen_mipmap(struct pipe_context *pipe)
|
||||
{
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
struct gen_mipmap_state *ctx;
|
||||
|
||||
ctx = CALLOC_STRUCT(gen_mipmap_state);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
ctx->pipe = pipe;
|
||||
|
||||
/* we don't use blending, but need to set valid values */
|
||||
memset(&blend, 0, sizeof(blend));
|
||||
blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
|
||||
blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
|
||||
blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
|
||||
blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
|
||||
blend.colormask = PIPE_MASK_RGBA;
|
||||
ctx->blend = pipe->create_blend_state(pipe, &blend);
|
||||
|
||||
/* depth/stencil/alpha */
|
||||
memset(&depthstencil, 0, sizeof(depthstencil));
|
||||
ctx->depthstencil = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
|
||||
|
||||
/* rasterizer */
|
||||
memset(&rasterizer, 0, sizeof(rasterizer));
|
||||
rasterizer.front_winding = PIPE_WINDING_CW;
|
||||
rasterizer.cull_mode = PIPE_WINDING_NONE;
|
||||
rasterizer.bypass_clipping = 1; /* bypasses viewport too */
|
||||
//rasterizer.bypass_vs = 1;
|
||||
ctx->rasterizer = pipe->create_rasterizer_state(pipe, &rasterizer);
|
||||
|
||||
#if 0
|
||||
/* viewport */
|
||||
ctx->viewport.scale[0] = 1.0;
|
||||
ctx->viewport.scale[1] = 1.0;
|
||||
ctx->viewport.scale[2] = 1.0;
|
||||
ctx->viewport.scale[3] = 1.0;
|
||||
ctx->viewport.translate[0] = 0.0;
|
||||
ctx->viewport.translate[1] = 0.0;
|
||||
ctx->viewport.translate[2] = 0.0;
|
||||
ctx->viewport.translate[3] = 0.0;
|
||||
#endif
|
||||
|
||||
/* vertex shader */
|
||||
{
|
||||
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
|
||||
TGSI_SEMANTIC_GENERIC };
|
||||
const uint semantic_indexes[] = { 0, 0 };
|
||||
ctx->vs = util_make_vertex_passthrough_shader(pipe, 2, semantic_names,
|
||||
semantic_indexes);
|
||||
}
|
||||
|
||||
/* fragment shader */
|
||||
ctx->fs = util_make_fragment_tex_shader(pipe);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy a mipmap generation context
|
||||
*/
|
||||
void
|
||||
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
|
||||
pipe->delete_blend_state(pipe, ctx->blend);
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, ctx->depthstencil);
|
||||
pipe->delete_rasterizer_state(pipe, ctx->rasterizer);
|
||||
pipe->delete_vs_state(pipe, ctx->vs);
|
||||
pipe->delete_fs_state(pipe, ctx->fs);
|
||||
|
||||
FREE(ctx);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
simple_viewport(struct pipe_context *pipe, uint width, uint height)
|
||||
{
|
||||
struct pipe_viewport_state vp;
|
||||
|
||||
vp.scale[0] = 0.5 * width;
|
||||
vp.scale[1] = -0.5 * height;
|
||||
vp.scale[2] = 1.0;
|
||||
vp.scale[3] = 1.0;
|
||||
vp.translate[0] = 0.5 * width;
|
||||
vp.translate[1] = 0.5 * height;
|
||||
vp.translate[2] = 0.0;
|
||||
vp.translate[3] = 0.0;
|
||||
|
||||
pipe->set_viewport_state(pipe, &vp);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Generate mipmap images. It's assumed all needed texture memory is
|
||||
* already allocated.
|
||||
*
|
||||
* \param pt the texture to generate mipmap levels for
|
||||
* \param face which cube face to generate mipmaps for (0 for non-cube maps)
|
||||
* \param baseLevel the first mipmap level to use as a src
|
||||
* \param lastLevel the last mipmap level to generate
|
||||
*/
|
||||
void
|
||||
util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel)
|
||||
{
|
||||
struct pipe_context *pipe = ctx->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_framebuffer_state fb;
|
||||
struct pipe_sampler_state sampler;
|
||||
void *sampler_cso;
|
||||
uint dstLevel;
|
||||
uint zslice = 0;
|
||||
|
||||
/* check if we can render in the texture's format */
|
||||
if (!screen->is_format_supported(screen, pt->format, PIPE_SURFACE)) {
|
||||
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
/* init framebuffer state */
|
||||
memset(&fb, 0, sizeof(fb));
|
||||
fb.num_cbufs = 1;
|
||||
|
||||
/* sampler state */
|
||||
memset(&sampler, 0, sizeof(sampler));
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
|
||||
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.normalized_coords = 1;
|
||||
|
||||
/* bind our state */
|
||||
pipe->bind_blend_state(pipe, ctx->blend);
|
||||
pipe->bind_depth_stencil_alpha_state(pipe, ctx->depthstencil);
|
||||
pipe->bind_rasterizer_state(pipe, ctx->rasterizer);
|
||||
pipe->bind_vs_state(pipe, ctx->vs);
|
||||
pipe->bind_fs_state(pipe, ctx->fs);
|
||||
#if 0
|
||||
pipe->set_viewport_state(pipe, &ctx->viewport);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* XXX for small mipmap levels, it may be faster to use the software
|
||||
* fallback path...
|
||||
*/
|
||||
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
|
||||
const uint srcLevel = dstLevel - 1;
|
||||
|
||||
/*
|
||||
* Setup framebuffer / dest surface
|
||||
*/
|
||||
fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
|
||||
pipe->set_framebuffer_state(pipe, &fb);
|
||||
|
||||
/*
|
||||
* Setup sampler state
|
||||
* Note: we should only have to set the min/max LOD clamps to ensure
|
||||
* we grab texels from the right mipmap level. But some hardware
|
||||
* has trouble with min clamping so we also set the lod_bias to
|
||||
* try to work around that.
|
||||
*/
|
||||
sampler.min_lod = sampler.max_lod = (float) srcLevel;
|
||||
sampler.lod_bias = (float) srcLevel;
|
||||
sampler_cso = pipe->create_sampler_state(pipe, &sampler);
|
||||
pipe->bind_sampler_states(pipe, 1, &sampler_cso);
|
||||
|
||||
#if 0
|
||||
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
|
||||
#endif
|
||||
|
||||
pipe->set_sampler_textures(pipe, 1, &pt);
|
||||
|
||||
/* quad coords in window coords (bypassing clipping, viewport mapping) */
|
||||
util_draw_texquad(pipe,
|
||||
0.0F, 0.0F, /* x0, y0 */
|
||||
(float) pt->width[dstLevel], /* x1 */
|
||||
(float) pt->height[dstLevel], /* y1 */
|
||||
0.0F); /* z */
|
||||
|
||||
|
||||
pipe->flush(pipe, PIPE_FLUSH_WAIT);
|
||||
|
||||
/*pipe->texture_update(pipe, pt); not really needed */
|
||||
|
||||
pipe->delete_sampler_state(pipe, sampler_cso);
|
||||
}
|
||||
|
||||
/* Note: caller must restore pipe/gallium state at this time */
|
||||
}
|
||||
52
src/gallium/auxiliary/util/u_gen_mipmap.h
Normal file
52
src/gallium/auxiliary/util/u_gen_mipmap.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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 U_GENMIPMAP_H
|
||||
#define U_GENMIPMAP_H
|
||||
|
||||
#include "pipe/p_state.h"
|
||||
|
||||
|
||||
struct gen_mipmap_state;
|
||||
|
||||
|
||||
extern struct gen_mipmap_state *
|
||||
util_create_gen_mipmap(struct pipe_context *pipe);
|
||||
|
||||
|
||||
extern void
|
||||
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx);
|
||||
|
||||
|
||||
|
||||
extern void
|
||||
util_gen_mipmap(struct gen_mipmap_state *ctx,
|
||||
struct pipe_texture *pt,
|
||||
uint face, uint baseLevel, uint lastLevel);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -226,9 +226,13 @@ handle_table_remove(struct handle_table *ht,
|
|||
|
||||
index = handle - 1;
|
||||
object = ht->objects[index];
|
||||
assert(object);
|
||||
if(!object) {
|
||||
/* XXX: this warning may be noisy for legitimate use -- remove later */
|
||||
debug_warning("removing empty handle");
|
||||
return;
|
||||
}
|
||||
|
||||
if(object && ht->destroy)
|
||||
if(ht->destroy)
|
||||
ht->destroy(object);
|
||||
|
||||
ht->objects[index] = NULL;
|
||||
|
|
@ -237,6 +241,28 @@ handle_table_remove(struct handle_table *ht,
|
|||
}
|
||||
|
||||
|
||||
unsigned
|
||||
handle_table_get_next_handle(struct handle_table *ht,
|
||||
unsigned handle)
|
||||
{
|
||||
unsigned index;
|
||||
|
||||
for(index = handle; index < ht->size; ++index) {
|
||||
if(!ht->objects[index])
|
||||
return index + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned
|
||||
handle_table_get_first_handle(struct handle_table *ht)
|
||||
{
|
||||
return handle_table_get_next_handle(ht, 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
handle_table_destroy(struct handle_table *ht)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -100,6 +100,15 @@ void
|
|||
handle_table_destroy(struct handle_table *ht);
|
||||
|
||||
|
||||
unsigned
|
||||
handle_table_get_first_handle(struct handle_table *ht);
|
||||
|
||||
|
||||
unsigned
|
||||
handle_table_get_next_handle(struct handle_table *ht,
|
||||
unsigned handle);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -187,6 +187,28 @@ hash_table_remove(struct hash_table *ht,
|
|||
}
|
||||
|
||||
|
||||
enum pipe_error
|
||||
hash_table_foreach(struct hash_table *ht,
|
||||
enum pipe_error (*callback)(void *key, void *value, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct cso_hash_iter iter;
|
||||
struct hash_table_item *item;
|
||||
enum pipe_error result;
|
||||
|
||||
iter = cso_hash_first_node(ht->cso);
|
||||
while (!cso_hash_iter_is_null(iter)) {
|
||||
item = (struct hash_table_item *)cso_hash_iter_data(iter);
|
||||
result = callback(item->key, item->value, data);
|
||||
if(result != PIPE_OK)
|
||||
return result;
|
||||
iter = cso_hash_iter_next(iter);
|
||||
}
|
||||
|
||||
return PIPE_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
hash_table_destroy(struct hash_table *ht)
|
||||
{
|
||||
|
|
@ -196,4 +218,3 @@ hash_table_destroy(struct hash_table *ht)
|
|||
|
||||
FREE(ht);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,11 @@ hash_table_remove(struct hash_table *ht,
|
|||
void *key);
|
||||
|
||||
|
||||
enum pipe_error
|
||||
hash_table_foreach(struct hash_table *ht,
|
||||
enum pipe_error (*callback)(void *key, void *value, void *data),
|
||||
void *data);
|
||||
|
||||
void
|
||||
hash_table_destroy(struct hash_table *ht);
|
||||
|
||||
|
|
|
|||
133
src/gallium/auxiliary/util/u_pack_color.h
Normal file
133
src/gallium/auxiliary/util/u_pack_color.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Functions to produce packed colors/Z from floats.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef U_PACK_COLOR_H
|
||||
#define U_PACK_COLOR_H
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_format.h"
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
ubyte r, g, b, a;
|
||||
|
||||
if (pf_size_x(format) <= 8) {
|
||||
/* format uses 8-bit components or less */
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(r, rgba[0]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(g, rgba[1]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(b, rgba[2]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(a, rgba[3]);
|
||||
}
|
||||
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
{
|
||||
uint *d = (uint *) dest;
|
||||
*d = (r << 24) | (g << 16) | (b << 8) | a;
|
||||
}
|
||||
return;
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
{
|
||||
uint *d = (uint *) dest;
|
||||
*d = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
return;
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
{
|
||||
uint *d = (uint *) dest;
|
||||
*d = (b << 24) | (g << 16) | (r << 8) | a;
|
||||
}
|
||||
return;
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
{
|
||||
ushort *d = (ushort *) dest;
|
||||
*d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
|
||||
}
|
||||
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];
|
||||
}
|
||||
return;
|
||||
case PIPE_FORMAT_R32G32B32_FLOAT:
|
||||
{
|
||||
float *d = (float *) dest;
|
||||
d[0] = rgba[0];
|
||||
d[1] = rgba[1];
|
||||
d[2] = rgba[2];
|
||||
}
|
||||
return;
|
||||
/* XXX lots more cases to add */
|
||||
default:
|
||||
debug_printf("gallium: unhandled format in util_pack_color()");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Note: it's assumed that z is in [0,1]
|
||||
*/
|
||||
static INLINE uint
|
||||
util_pack_z(enum pipe_format format, double z)
|
||||
{
|
||||
switch (format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return (uint) (z * 0xffff);
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
/* special-case to avoid overflow */
|
||||
if (z == 1.0)
|
||||
return 0xffffffff;
|
||||
else
|
||||
return (uint) (z * 0xffffffff);
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
return (uint) (z * 0xffffff);
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
return ((uint) (z * 0xffffff)) << 8;
|
||||
default:
|
||||
debug_printf("gallium: unhandled fomrat in util_pack_z()");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* U_PACK_COLOR_H */
|
||||
263
src/gallium/auxiliary/util/u_simple_shaders.c
Normal file
263
src/gallium/auxiliary/util/u_simple_shaders.c
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Simple vertex/fragment shader generators.
|
||||
*
|
||||
* @author Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_debug.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_shader_tokens.h"
|
||||
|
||||
#include "util/u_simple_shaders.h"
|
||||
|
||||
#include "tgsi/util/tgsi_build.h"
|
||||
#include "tgsi/util/tgsi_dump.h"
|
||||
#include "tgsi/util/tgsi_parse.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Make simple vertex pass-through shader.
|
||||
*/
|
||||
void *
|
||||
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
|
||||
uint num_attribs,
|
||||
const uint *semantic_names,
|
||||
const uint *semantic_indexes)
|
||||
{
|
||||
uint maxTokens = 100;
|
||||
struct tgsi_token *tokens;
|
||||
struct tgsi_header *header;
|
||||
struct tgsi_processor *processor;
|
||||
struct tgsi_full_declaration decl;
|
||||
struct tgsi_full_instruction inst;
|
||||
const uint procType = TGSI_PROCESSOR_VERTEX;
|
||||
uint ti, i;
|
||||
struct pipe_shader_state shader;
|
||||
|
||||
tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0]));
|
||||
|
||||
/* shader header
|
||||
*/
|
||||
*(struct tgsi_version *) &tokens[0] = tgsi_build_version();
|
||||
|
||||
header = (struct tgsi_header *) &tokens[1];
|
||||
*header = tgsi_build_header();
|
||||
|
||||
processor = (struct tgsi_processor *) &tokens[2];
|
||||
*processor = tgsi_build_processor( procType, header );
|
||||
|
||||
ti = 3;
|
||||
|
||||
/* declare inputs */
|
||||
for (i = 0; i < num_attribs; i++) {
|
||||
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_INPUT;
|
||||
/*
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
|
||||
decl.Semantic.SemanticIndex = 0;
|
||||
*/
|
||||
decl.u.DeclarationRange.First =
|
||||
decl.u.DeclarationRange.Last = 0;
|
||||
ti += tgsi_build_full_declaration(&decl,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti);
|
||||
}
|
||||
|
||||
/* declare outputs */
|
||||
for (i = 0; i < num_attribs; i++) {
|
||||
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_OUTPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = semantic_names[i];
|
||||
decl.Semantic.SemanticIndex = semantic_indexes[i];
|
||||
decl.u.DeclarationRange.First =
|
||||
decl.u.DeclarationRange.Last = 0;
|
||||
ti += tgsi_build_full_declaration(&decl,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti);
|
||||
|
||||
}
|
||||
|
||||
/* emit MOV instructions */
|
||||
for (i = 0; i < num_attribs; i++) {
|
||||
/* MOVE out[i], in[i]; */
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_MOV;
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
|
||||
inst.FullDstRegisters[0].DstRegister.Index = i;
|
||||
inst.Instruction.NumSrcRegs = 1;
|
||||
inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
|
||||
inst.FullSrcRegisters[0].SrcRegister.Index = i;
|
||||
ti += tgsi_build_full_instruction(&inst,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti );
|
||||
}
|
||||
|
||||
/* END instruction */
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_END;
|
||||
inst.Instruction.NumDstRegs = 0;
|
||||
inst.Instruction.NumSrcRegs = 0;
|
||||
ti += tgsi_build_full_instruction(&inst,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti );
|
||||
|
||||
#if 0 /*debug*/
|
||||
tgsi_dump(tokens, 0);
|
||||
#endif
|
||||
|
||||
shader.tokens = tokens;
|
||||
return pipe->create_vs_state(pipe, &shader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Make simple fragment texture shader:
|
||||
* TEX OUT[0], IN[0], SAMP[0], 2D;
|
||||
* END;
|
||||
*/
|
||||
void *
|
||||
util_make_fragment_tex_shader(struct pipe_context *pipe)
|
||||
{
|
||||
uint maxTokens = 100;
|
||||
struct tgsi_token *tokens;
|
||||
struct tgsi_header *header;
|
||||
struct tgsi_processor *processor;
|
||||
struct tgsi_full_declaration decl;
|
||||
struct tgsi_full_instruction inst;
|
||||
const uint procType = TGSI_PROCESSOR_FRAGMENT;
|
||||
uint ti;
|
||||
struct pipe_shader_state shader;
|
||||
|
||||
tokens = (struct tgsi_token *) malloc(maxTokens * sizeof(tokens[0]));
|
||||
|
||||
/* shader header
|
||||
*/
|
||||
*(struct tgsi_version *) &tokens[0] = tgsi_build_version();
|
||||
|
||||
header = (struct tgsi_header *) &tokens[1];
|
||||
*header = tgsi_build_header();
|
||||
|
||||
processor = (struct tgsi_processor *) &tokens[2];
|
||||
*processor = tgsi_build_processor( procType, header );
|
||||
|
||||
ti = 3;
|
||||
|
||||
/* declare TEX[0] input */
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_INPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
|
||||
decl.Semantic.SemanticIndex = 0;
|
||||
/* XXX this could be linear... */
|
||||
decl.Declaration.Interpolate = 1;
|
||||
decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
|
||||
decl.u.DeclarationRange.First =
|
||||
decl.u.DeclarationRange.Last = 0;
|
||||
ti += tgsi_build_full_declaration(&decl,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti);
|
||||
|
||||
/* declare color[0] output */
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_OUTPUT;
|
||||
decl.Declaration.Semantic = 1;
|
||||
decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
|
||||
decl.Semantic.SemanticIndex = 0;
|
||||
decl.u.DeclarationRange.First =
|
||||
decl.u.DeclarationRange.Last = 0;
|
||||
ti += tgsi_build_full_declaration(&decl,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti);
|
||||
|
||||
/* declare sampler */
|
||||
decl = tgsi_default_full_declaration();
|
||||
decl.Declaration.File = TGSI_FILE_SAMPLER;
|
||||
decl.u.DeclarationRange.First =
|
||||
decl.u.DeclarationRange.Last = 0;
|
||||
ti += tgsi_build_full_declaration(&decl,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti);
|
||||
|
||||
/* TEX instruction */
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_TEX;
|
||||
inst.Instruction.NumDstRegs = 1;
|
||||
inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
|
||||
inst.FullDstRegisters[0].DstRegister.Index = 0;
|
||||
inst.Instruction.NumSrcRegs = 2;
|
||||
inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
|
||||
inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
|
||||
inst.FullSrcRegisters[0].SrcRegister.Index = 0;
|
||||
inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
|
||||
inst.FullSrcRegisters[1].SrcRegister.Index = 0;
|
||||
ti += tgsi_build_full_instruction(&inst,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti );
|
||||
|
||||
/* END instruction */
|
||||
inst = tgsi_default_full_instruction();
|
||||
inst.Instruction.Opcode = TGSI_OPCODE_END;
|
||||
inst.Instruction.NumDstRegs = 0;
|
||||
inst.Instruction.NumSrcRegs = 0;
|
||||
ti += tgsi_build_full_instruction(&inst,
|
||||
&tokens[ti],
|
||||
header,
|
||||
maxTokens - ti );
|
||||
|
||||
#if 0 /*debug*/
|
||||
tgsi_dump(tokens, 0);
|
||||
#endif
|
||||
|
||||
shader.tokens = tokens;
|
||||
return pipe->create_fs_state(pipe, &shader);
|
||||
}
|
||||
|
||||
52
src/gallium/auxiliary/util/u_simple_shaders.h
Normal file
52
src/gallium/auxiliary/util/u_simple_shaders.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 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 U_SIMPLE_SHADERS_H
|
||||
#define U_SIMPLE_SHADERS_H
|
||||
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
|
||||
|
||||
struct pipe_context;
|
||||
|
||||
|
||||
extern void *
|
||||
util_make_vertex_passthrough_shader(struct pipe_context *pipe,
|
||||
uint num_attribs,
|
||||
const uint *semantic_names,
|
||||
const uint *semantic_indexes);
|
||||
|
||||
|
||||
extern void *
|
||||
util_make_fragment_tex_shader(struct pipe_context *pipe);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -104,6 +104,16 @@
|
|||
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
struct cell_command_depth_stencil_alpha_test {
|
||||
uint64_t base; /**< Effective address of code start. */
|
||||
unsigned size; /**< Size in bytes of test code. */
|
||||
unsigned read_depth; /**< Flag: should depth be read? */
|
||||
unsigned read_stencil; /**< Flag: should stencil be read? */
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tell SPUs about the framebuffer size, location
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ SOURCES = \
|
|||
cell_flush.c \
|
||||
cell_state_derived.c \
|
||||
cell_state_emit.c \
|
||||
cell_state_per_fragment.c \
|
||||
cell_state_shader.c \
|
||||
cell_pipe_state.c \
|
||||
cell_screen.c \
|
||||
|
|
|
|||
|
|
@ -57,16 +57,37 @@ struct cell_fragment_shader_state
|
|||
};
|
||||
|
||||
|
||||
struct cell_blend_state {
|
||||
struct pipe_blend_state base;
|
||||
|
||||
/**
|
||||
* Generated code to perform alpha blending
|
||||
*/
|
||||
struct spe_function code;
|
||||
};
|
||||
|
||||
|
||||
struct cell_depth_stencil_alpha_state {
|
||||
struct pipe_depth_stencil_alpha_state base;
|
||||
|
||||
/**
|
||||
* Generated code to perform alpha, stencil, and depth testing on the SPE
|
||||
*/
|
||||
struct spe_function code;
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct cell_context
|
||||
{
|
||||
struct pipe_context pipe;
|
||||
|
||||
struct cell_winsys *winsys;
|
||||
|
||||
const struct pipe_blend_state *blend;
|
||||
const struct cell_blend_state *blend;
|
||||
const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
|
||||
uint num_samplers;
|
||||
const struct pipe_depth_stencil_alpha_state *depth_stencil;
|
||||
const struct cell_depth_stencil_alpha_state *depth_stencil;
|
||||
const struct pipe_rasterizer_state *rasterizer;
|
||||
const struct cell_vertex_shader_state *vs;
|
||||
const struct cell_fragment_shader_state *fs;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "cell_context.h"
|
||||
#include "cell_state.h"
|
||||
#include "cell_texture.h"
|
||||
#include "cell_state_per_fragment.h"
|
||||
|
||||
|
||||
|
||||
|
|
@ -43,7 +44,12 @@ static void *
|
|||
cell_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *blend)
|
||||
{
|
||||
return mem_dup(blend, sizeof(*blend));
|
||||
struct cell_blend_state *cb = MALLOC(sizeof(struct cell_blend_state));
|
||||
|
||||
(void) memcpy(cb, blend, sizeof(*blend));
|
||||
cb->code.store = NULL;
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -54,7 +60,7 @@ cell_bind_blend_state(struct pipe_context *pipe, void *blend)
|
|||
|
||||
draw_flush(cell->draw);
|
||||
|
||||
cell->blend = (const struct pipe_blend_state *)blend;
|
||||
cell->blend = (const struct cell_blend_state *)blend;
|
||||
|
||||
cell->dirty |= CELL_NEW_BLEND;
|
||||
}
|
||||
|
|
@ -63,7 +69,10 @@ cell_bind_blend_state(struct pipe_context *pipe, void *blend)
|
|||
static void
|
||||
cell_delete_blend_state(struct pipe_context *pipe, void *blend)
|
||||
{
|
||||
FREE(blend);
|
||||
struct cell_blend_state *cb = (struct cell_blend_state *) blend;
|
||||
|
||||
spe_release_func(& cb->code);
|
||||
FREE(cb);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -87,7 +96,13 @@ static void *
|
|||
cell_create_depth_stencil_alpha_state(struct pipe_context *pipe,
|
||||
const struct pipe_depth_stencil_alpha_state *depth_stencil)
|
||||
{
|
||||
return mem_dup(depth_stencil, sizeof(*depth_stencil));
|
||||
struct cell_depth_stencil_alpha_state *cdsa =
|
||||
MALLOC(sizeof(struct cell_depth_stencil_alpha_state));
|
||||
|
||||
(void) memcpy(cdsa, depth_stencil, sizeof(*depth_stencil));
|
||||
cdsa->code.store = NULL;
|
||||
|
||||
return cdsa;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -96,12 +111,16 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
|
|||
void *depth_stencil)
|
||||
{
|
||||
struct cell_context *cell = cell_context(pipe);
|
||||
struct cell_depth_stencil_alpha_state *cdsa =
|
||||
(struct cell_depth_stencil_alpha_state *) depth_stencil;
|
||||
|
||||
draw_flush(cell->draw);
|
||||
|
||||
cell->depth_stencil
|
||||
= (const struct pipe_depth_stencil_alpha_state *) depth_stencil;
|
||||
if ((cdsa != NULL) && (cdsa->code.store == NULL)) {
|
||||
cell_generate_depth_stencil_test(cdsa);
|
||||
}
|
||||
|
||||
cell->depth_stencil = cdsa;
|
||||
cell->dirty |= CELL_NEW_DEPTH_STENCIL;
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +128,11 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
|
|||
static void
|
||||
cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *depth)
|
||||
{
|
||||
FREE(depth);
|
||||
struct cell_depth_stencil_alpha_state *cdsa =
|
||||
(struct cell_depth_stencil_alpha_state *) depth;
|
||||
|
||||
spe_release_func(& cdsa->code);
|
||||
FREE(cdsa);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -71,9 +71,24 @@ cell_emit_state(struct cell_context *cell)
|
|||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_DEPTH_STENCIL) {
|
||||
emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL,
|
||||
cell->depth_stencil,
|
||||
sizeof(struct pipe_depth_stencil_alpha_state));
|
||||
struct cell_command_depth_stencil_alpha_test dsat;
|
||||
|
||||
|
||||
if (cell->depth_stencil != NULL) {
|
||||
dsat.base = (intptr_t) cell->depth_stencil->code.store;
|
||||
dsat.size = (char *) cell->depth_stencil->code.csr
|
||||
- (char *) cell->depth_stencil->code.store;
|
||||
dsat.read_depth = TRUE;
|
||||
dsat.read_stencil = FALSE;
|
||||
} else {
|
||||
dsat.base = 0;
|
||||
dsat.size = 0;
|
||||
dsat.read_depth = FALSE;
|
||||
dsat.read_stencil = FALSE;
|
||||
}
|
||||
|
||||
emit_state_cmd(cell, CELL_CMD_STATE_DEPTH_STENCIL, &dsat,
|
||||
sizeof(dsat));
|
||||
}
|
||||
|
||||
if (cell->dirty & CELL_NEW_SAMPLER) {
|
||||
|
|
|
|||
1075
src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
Normal file
1075
src/gallium/drivers/cell/ppu/cell_state_per_fragment.c
Normal file
File diff suppressed because it is too large
Load diff
35
src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
Normal file
35
src/gallium/drivers/cell/ppu/cell_state_per_fragment.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corporation 2008
|
||||
* 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
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CELL_STATE_PER_FRAGMENT_H
|
||||
#define CELL_STATE_PER_FRAGMENT_H
|
||||
|
||||
extern void
|
||||
cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa);
|
||||
|
||||
extern void
|
||||
cell_generate_alpha_blend(struct cell_blend_state *cb,
|
||||
const struct pipe_blend_color *blend_color);
|
||||
|
||||
#endif /* CELL_STATE_PER_FRAGMENT_H */
|
||||
|
|
@ -19,6 +19,7 @@ SOURCES = \
|
|||
spu_main.c \
|
||||
spu_blend.c \
|
||||
spu_dcache.c \
|
||||
spu_per_fragment_op.c \
|
||||
spu_render.c \
|
||||
spu_texture.c \
|
||||
spu_tile.c \
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ struct spu_vs_context draw;
|
|||
static unsigned char attribute_fetch_code_buffer[136 * PIPE_ATTRIB_MAX]
|
||||
ALIGN16_ATTRIB;
|
||||
|
||||
static unsigned char depth_stencil_code_buffer[4 * 64]
|
||||
ALIGN16_ATTRIB;
|
||||
|
||||
/**
|
||||
* Tell the PPU that this SPU has finished copying a buffer to
|
||||
* local store and that it may be reused by the PPU.
|
||||
|
|
@ -215,12 +218,19 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
|
|||
spu.fb.width_tiles = (spu.fb.width + TILE_SIZE - 1) / TILE_SIZE;
|
||||
spu.fb.height_tiles = (spu.fb.height + TILE_SIZE - 1) / TILE_SIZE;
|
||||
|
||||
if (spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM)
|
||||
switch (spu.fb.depth_format) {
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
spu.fb.zsize = 4;
|
||||
else if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM)
|
||||
break;
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
spu.fb.zsize = 2;
|
||||
else
|
||||
break;
|
||||
default:
|
||||
spu.fb.zsize = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (spu.fb.color_format == PIPE_FORMAT_A8R8G8B8_UNORM)
|
||||
spu.color_shuffle = ((vector unsigned char) {
|
||||
|
|
@ -248,14 +258,35 @@ cmd_state_blend(const struct pipe_blend_state *state)
|
|||
|
||||
|
||||
static void
|
||||
cmd_state_depth_stencil(const struct pipe_depth_stencil_alpha_state *state)
|
||||
cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *state)
|
||||
{
|
||||
if (Debug)
|
||||
printf("SPU %u: DEPTH_STENCIL: ztest %d\n",
|
||||
spu.init.id,
|
||||
state->depth.enabled);
|
||||
state->read_depth);
|
||||
|
||||
memcpy(&spu.depth_stencil, state, sizeof(*state));
|
||||
ASSERT_ALIGN16(state->base);
|
||||
|
||||
if (state->size != 0) {
|
||||
mfc_get(depth_stencil_code_buffer,
|
||||
(unsigned int) state->base, /* src */
|
||||
ROUNDUP16(state->size),
|
||||
TAG_BATCH_BUFFER,
|
||||
0, /* tid */
|
||||
0 /* rid */);
|
||||
wait_on_mask(1 << TAG_BATCH_BUFFER);
|
||||
} else {
|
||||
/* If there is no code, emit a return instruction.
|
||||
*/
|
||||
depth_stencil_code_buffer[0] = 0x35;
|
||||
depth_stencil_code_buffer[1] = 0x00;
|
||||
depth_stencil_code_buffer[2] = 0x00;
|
||||
depth_stencil_code_buffer[3] = 0x00;
|
||||
}
|
||||
|
||||
spu.frag_test = (frag_test_func) depth_stencil_code_buffer;
|
||||
spu.read_depth = state->read_depth;
|
||||
spu.read_stencil = state->read_stencil;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -415,9 +446,9 @@ cmd_batch(uint opcode)
|
|||
pos += (1 + ROUNDUP8(sizeof(struct pipe_blend_state)) / 8);
|
||||
break;
|
||||
case CELL_CMD_STATE_DEPTH_STENCIL:
|
||||
cmd_state_depth_stencil((struct pipe_depth_stencil_alpha_state *)
|
||||
cmd_state_depth_stencil((struct cell_command_depth_stencil_alpha_test *)
|
||||
&buffer[pos+1]);
|
||||
pos += (1 + ROUNDUP8(sizeof(struct pipe_depth_stencil_alpha_state)) / 8);
|
||||
pos += (1 + ROUNDUP8(sizeof(struct cell_command_depth_stencil_alpha_test)) / 8);
|
||||
break;
|
||||
case CELL_CMD_STATE_SAMPLER:
|
||||
cmd_state_sampler((struct pipe_sampler_state *) &buffer[pos+1]);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,17 @@ typedef union {
|
|||
#define TILE_STATUS_GETTING 5 /**< mfc_get() called but not yet arrived */
|
||||
|
||||
|
||||
struct spu_frag_test_results {
|
||||
qword mask;
|
||||
qword depth;
|
||||
qword stencil;
|
||||
};
|
||||
|
||||
typedef struct spu_frag_test_results (*frag_test_func)(qword frag_mask,
|
||||
qword pixel_depth, qword pixel_stencil, qword frag_depth,
|
||||
qword frag_alpha, qword facing);
|
||||
|
||||
|
||||
struct spu_framebuffer {
|
||||
void *color_start; /**< addr of color surface in main memory */
|
||||
void *depth_start; /**< addr of depth surface in main memory */
|
||||
|
|
@ -79,8 +90,9 @@ struct spu_global
|
|||
struct cell_init_info init;
|
||||
|
||||
struct spu_framebuffer fb;
|
||||
struct pipe_blend_state blend_stencil;
|
||||
struct pipe_depth_stencil_alpha_state depth_stencil;
|
||||
boolean read_depth;
|
||||
boolean read_stencil;
|
||||
frag_test_func frag_test;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
|
||||
struct cell_command_texture texture;
|
||||
|
|
|
|||
211
src/gallium/drivers/cell/spu/spu_per_fragment_op.c
Normal file
211
src/gallium/drivers/cell/spu/spu_per_fragment_op.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corporation 2008
|
||||
* 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
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file spu_per_fragment_op.c
|
||||
* SPU implementation various per-fragment operations.
|
||||
*
|
||||
* \author Ian Romanick <idr@us.ibm.com>
|
||||
*/
|
||||
|
||||
#include "pipe/p_format.h"
|
||||
#include "spu_main.h"
|
||||
#include "spu_per_fragment_op.h"
|
||||
|
||||
#define ZERO 0x80
|
||||
|
||||
static void
|
||||
read_ds_quad(tile_t *buffer, unsigned x, unsigned y,
|
||||
enum pipe_format depth_format, qword *depth,
|
||||
qword *stencil)
|
||||
{
|
||||
const int ix = x / 2;
|
||||
const int iy = y / 2;
|
||||
|
||||
switch (depth_format) {
|
||||
case PIPE_FORMAT_Z16_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->us8[iy][ix / 2];
|
||||
|
||||
const qword shuf_vec = (qword) {
|
||||
ZERO, ZERO, 0, 1, ZERO, ZERO, 2, 3,
|
||||
ZERO, ZERO, 4, 5, ZERO, ZERO, 6, 7
|
||||
};
|
||||
|
||||
|
||||
/* At even X values we want the first 4 shorts, and at odd X values we
|
||||
* want the second 4 shorts.
|
||||
*/
|
||||
qword bias = (qword) spu_splats((unsigned char) ((ix & 0x01) << 3));
|
||||
qword bias_mask = si_fsmbi(0x3333);
|
||||
qword sv = si_a(shuf_vec, si_and(bias_mask, bias));
|
||||
|
||||
*depth = si_shufb(*ptr, *ptr, sv);
|
||||
*stencil = si_il(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PIPE_FORMAT_Z32_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->ui4[iy][ix];
|
||||
|
||||
*depth = *ptr;
|
||||
*stencil = si_il(0);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PIPE_FORMAT_Z24S8_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->ui4[iy][ix];
|
||||
qword mask = si_fsmbi(0xEEEE);
|
||||
|
||||
*depth = si_rotmai(si_and(*ptr, mask), -8);
|
||||
*stencil = si_andc(*ptr, mask);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PIPE_FORMAT_S8Z24_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->ui4[iy][ix];
|
||||
|
||||
*depth = si_and(*ptr, si_fsmbi(0x7777));
|
||||
*stencil = si_andi(si_roti(*ptr, 8), 0x0ff);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_ds_quad(tile_t *buffer, unsigned x, unsigned y,
|
||||
enum pipe_format depth_format,
|
||||
qword depth, qword stencil)
|
||||
{
|
||||
const int ix = x / 2;
|
||||
const int iy = y / 2;
|
||||
|
||||
(void) stencil;
|
||||
|
||||
switch (depth_format) {
|
||||
case PIPE_FORMAT_Z16_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->us8[iy][ix / 2];
|
||||
|
||||
qword sv = ((ix & 0x01) == 0)
|
||||
? (qword) { 2, 3, 6, 7, 10, 11, 14, 15,
|
||||
24, 25, 26, 27, 28, 29, 30, 31 }
|
||||
: (qword) { 16, 17, 18, 19, 20 , 21, 22, 23,
|
||||
2, 3, 6, 7, 10, 11, 14, 15 };
|
||||
*ptr = si_shufb(depth, *ptr, sv);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PIPE_FORMAT_Z32_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->ui4[iy][ix];
|
||||
*ptr = depth;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PIPE_FORMAT_Z24S8_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->ui4[iy][ix];
|
||||
qword mask = si_fsmbi(0xEEEE);
|
||||
|
||||
depth = si_shli(depth, 8);
|
||||
*ptr = si_selb(stencil, depth, mask);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case PIPE_FORMAT_S8Z24_UNORM: {
|
||||
qword *ptr = (qword *) &buffer->ui4[iy][ix];
|
||||
qword mask = si_fsmbi(0x7777);
|
||||
|
||||
stencil = si_shli(stencil, 24);
|
||||
*ptr = si_selb(stencil, depth, mask);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qword
|
||||
spu_do_depth_stencil(int x, int y,
|
||||
qword frag_mask, qword frag_depth, qword frag_alpha,
|
||||
qword facing)
|
||||
{
|
||||
struct spu_frag_test_results result;
|
||||
qword pixel_depth;
|
||||
qword pixel_stencil;
|
||||
|
||||
/* All of this preable code (everthing before the call to frag_test) should
|
||||
* be generated on the PPU and upload to the SPU.
|
||||
*/
|
||||
if (spu.read_depth || spu.read_stencil) {
|
||||
read_ds_quad(&spu.ztile, x, y, spu.fb.depth_format,
|
||||
&pixel_depth, &pixel_stencil);
|
||||
}
|
||||
|
||||
switch (spu.fb.depth_format) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0x0000ffffu)));
|
||||
frag_depth = si_cfltu(frag_depth, 0);
|
||||
break;
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0xffffffffu)));
|
||||
frag_depth = si_cfltu(frag_depth, 0);
|
||||
break;
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
frag_depth = si_fm(frag_depth, (qword)spu_splats((float)(0x00ffffffu)));
|
||||
frag_depth = si_cfltu(frag_depth, 0);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
result = (*spu.frag_test)(frag_mask, pixel_depth, pixel_stencil,
|
||||
frag_depth, frag_alpha, facing);
|
||||
|
||||
|
||||
/* This code (everthing after the call to frag_test) should
|
||||
* be generated on the PPU and upload to the SPU.
|
||||
*/
|
||||
if (spu.read_depth || spu.read_stencil) {
|
||||
write_ds_quad(&spu.ztile, x, y, spu.fb.depth_format,
|
||||
result.depth, result.stencil);
|
||||
}
|
||||
|
||||
return result.mask;
|
||||
}
|
||||
32
src/gallium/drivers/cell/spu/spu_per_fragment_op.h
Normal file
32
src/gallium/drivers/cell/spu/spu_per_fragment_op.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* (C) Copyright IBM Corporation 2008
|
||||
* 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
|
||||
* on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
* license, and/or sell copies of the Software, and to permit persons to whom
|
||||
* the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
* AUTHORS, COPYRIGHT HOLDERS, AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
||||
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
* USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SPU_PER_FRAGMENT_OP
|
||||
#define SPU_PER_FRAGMENT_OP
|
||||
|
||||
extern qword
|
||||
spu_do_depth_stencil(int x, int y, qword frag_mask, qword frag_depth,
|
||||
qword frag_alpha, qword facing);
|
||||
|
||||
#endif /* SPU_PER_FRAGMENT_OP */
|
||||
|
|
@ -98,7 +98,7 @@ my_tile(uint tx, uint ty)
|
|||
static INLINE void
|
||||
get_cz_tiles(uint tx, uint ty)
|
||||
{
|
||||
if (spu.depth_stencil.depth.enabled) {
|
||||
if (spu.read_depth) {
|
||||
if (spu.cur_ztile_status != TILE_STATUS_CLEAR) {
|
||||
//printf("SPU %u: getting Z tile %u, %u\n", spu.init.id, tx, ty);
|
||||
get_tile(tx, ty, &spu.ztile, TAG_READ_TILE_Z, 1);
|
||||
|
|
@ -153,7 +153,7 @@ static INLINE void
|
|||
wait_put_cz_tiles(void)
|
||||
{
|
||||
wait_on_mask(1 << TAG_WRITE_TILE_COLOR);
|
||||
if (spu.depth_stencil.depth.enabled) {
|
||||
if (spu.read_depth) {
|
||||
wait_on_mask(1 << TAG_WRITE_TILE_Z);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,13 +56,13 @@ clear_c_tile(tile_t *ctile)
|
|||
static INLINE void
|
||||
clear_z_tile(tile_t *ztile)
|
||||
{
|
||||
if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
|
||||
if (spu.fb.zsize == 2) {
|
||||
memset16((ushort*) ztile->us,
|
||||
spu.fb.depth_clear_value,
|
||||
TILE_SIZE * TILE_SIZE);
|
||||
}
|
||||
else {
|
||||
ASSERT(spu.fb.depth_format == PIPE_FORMAT_Z32_UNORM);
|
||||
ASSERT(spu.fb.zsize != 0);
|
||||
memset32((uint*) ztile->ui,
|
||||
spu.fb.depth_clear_value,
|
||||
TILE_SIZE * TILE_SIZE);
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@
|
|||
#include "spu_texture.h"
|
||||
#include "spu_tile.h"
|
||||
#include "spu_tri.h"
|
||||
|
||||
#include "spu_ztest.h"
|
||||
#include "spu_per_fragment_op.h"
|
||||
|
||||
|
||||
/** Masks are uint[4] vectors with each element being 0 or 0xffffffff */
|
||||
|
|
@ -264,16 +263,12 @@ do_depth_test(int x, int y, mask_t quadmask)
|
|||
|
||||
zvals.v = eval_z((float) x, (float) y);
|
||||
|
||||
if (spu.fb.depth_format == PIPE_FORMAT_Z16_UNORM) {
|
||||
int ix = (x - setup.cliprect_minx) / 4;
|
||||
int iy = (y - setup.cliprect_miny) / 2;
|
||||
mask = spu_z16_test_less(zvals.v, &spu.ztile.us8[iy][ix], x>>1, quadmask);
|
||||
}
|
||||
else {
|
||||
int ix = (x - setup.cliprect_minx) / 2;
|
||||
int iy = (y - setup.cliprect_miny) / 2;
|
||||
mask = spu_z32_test_less(zvals.v, &spu.ztile.ui4[iy][ix], quadmask);
|
||||
}
|
||||
mask = (mask_t) spu_do_depth_stencil(x - setup.cliprect_minx,
|
||||
y - setup.cliprect_miny,
|
||||
(qword) quadmask,
|
||||
(qword) zvals.v,
|
||||
(qword) spu_splats((unsigned char) 0x0ffu),
|
||||
(qword) spu_splats((unsigned int) 0x01u));
|
||||
|
||||
if (spu_extract(spu_orx(mask), 0))
|
||||
spu.cur_ztile_status = TILE_STATUS_DIRTY;
|
||||
|
|
@ -299,7 +294,7 @@ emit_quad( int x, int y, mask_t mask )
|
|||
sp->quad.first->run(sp->quad.first, &setup.quad);
|
||||
#else
|
||||
|
||||
if (spu.depth_stencil.depth.enabled) {
|
||||
if (spu.read_depth) {
|
||||
mask = do_depth_test(x, y, mask);
|
||||
}
|
||||
|
||||
|
|
@ -434,7 +429,7 @@ static void flush_spans( void )
|
|||
}
|
||||
ASSERT(spu.cur_ctile_status != TILE_STATUS_DEFINED);
|
||||
|
||||
if (spu.depth_stencil.depth.enabled) {
|
||||
if (spu.read_depth) {
|
||||
if (spu.cur_ztile_status == TILE_STATUS_GETTING) {
|
||||
/* wait for mfc_get() to complete */
|
||||
//printf("SPU: %u: waiting for ztile\n", spu.init.id);
|
||||
|
|
|
|||
|
|
@ -1,135 +0,0 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Zbuffer/depth test code.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SPU_ZTEST_H
|
||||
#define SPU_ZTEST_H
|
||||
|
||||
|
||||
#ifdef __SPU__
|
||||
#include <spu_intrinsics.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Perform Z testing for a 16-bit/value Z buffer.
|
||||
*
|
||||
* \param zvals vector of four fragment zvalues as floats
|
||||
* \param zbuf ptr to vector of ushort[8] zbuffer values. Note that this
|
||||
* contains the Z values for 2 quads, 8 pixels.
|
||||
* \param x x coordinate of quad (only lsbit is significant)
|
||||
* \param inMask indicates which fragments in the quad are alive
|
||||
* \return new mask indicating which fragments are alive after ztest
|
||||
*/
|
||||
static INLINE vector unsigned int
|
||||
spu_z16_test_less(vector float zvals, vector unsigned short *zbuf,
|
||||
uint x, vector unsigned int inMask)
|
||||
{
|
||||
#define ZERO 0x80
|
||||
vector unsigned int zvals_ui4, zbuf_ui4, mask;
|
||||
|
||||
/* convert floats to uints in [0, 65535] */
|
||||
zvals_ui4 = spu_convtu(zvals, 32); /* convert to [0, 2^32] */
|
||||
zvals_ui4 = spu_rlmask(zvals_ui4, -16); /* right shift 16 */
|
||||
|
||||
/* XXX this conditional could be removed with a bit of work */
|
||||
if (x & 1) {
|
||||
/* convert zbuffer values from ushorts to uints */
|
||||
/* gather lower four ushorts */
|
||||
zbuf_ui4 = spu_shuffle((vector unsigned int) *zbuf,
|
||||
(vector unsigned int) *zbuf,
|
||||
((vector unsigned char) {
|
||||
ZERO, ZERO, 8, 9, ZERO, ZERO, 10, 11,
|
||||
ZERO, ZERO, 12, 13, ZERO, ZERO, 14, 15}));
|
||||
/* mask = (zbuf_ui4 < zvals_ui4) ? ~0 : 0 */
|
||||
mask = spu_cmpgt(zbuf_ui4, zvals_ui4);
|
||||
/* mask &= inMask */
|
||||
mask = spu_and(mask, inMask);
|
||||
/* zbuf = mask ? zval : zbuf */
|
||||
zbuf_ui4 = spu_sel(zbuf_ui4, zvals_ui4, mask);
|
||||
/* convert zbuffer values from uints back to ushorts, preserve lower 4 */
|
||||
*zbuf = (vector unsigned short)
|
||||
spu_shuffle(zbuf_ui4, (vector unsigned int) *zbuf,
|
||||
((vector unsigned char) {
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
2, 3, 6, 7, 10, 11, 14, 15}));
|
||||
}
|
||||
else {
|
||||
/* convert zbuffer values from ushorts to uints */
|
||||
/* gather upper four ushorts */
|
||||
zbuf_ui4 = spu_shuffle((vector unsigned int) *zbuf,
|
||||
(vector unsigned int) *zbuf,
|
||||
((vector unsigned char) {
|
||||
ZERO, ZERO, 0, 1, ZERO, ZERO, 2, 3,
|
||||
ZERO, ZERO, 4, 5, ZERO, ZERO, 6, 7}));
|
||||
/* mask = (zbuf_ui4 < zvals_ui4) ? ~0 : 0 */
|
||||
mask = spu_cmpgt(zbuf_ui4, zvals_ui4);
|
||||
/* mask &= inMask */
|
||||
mask = spu_and(mask, inMask);
|
||||
/* zbuf = mask ? zval : zbuf */
|
||||
zbuf_ui4 = spu_sel(zbuf_ui4, zvals_ui4, mask);
|
||||
/* convert zbuffer values from uints back to ushorts, preserve upper 4 */
|
||||
*zbuf = (vector unsigned short)
|
||||
spu_shuffle(zbuf_ui4, (vector unsigned int) *zbuf,
|
||||
((vector unsigned char) {
|
||||
2, 3, 6, 7, 10, 11, 14, 15,
|
||||
24, 25, 26, 27, 28, 29, 30, 31}));
|
||||
}
|
||||
return mask;
|
||||
#undef ZERO
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* As above, but Zbuffer values as 32-bit uints
|
||||
*/
|
||||
static INLINE vector unsigned int
|
||||
spu_z32_test_less(vector float zvals, vector unsigned int *zbuf_ptr,
|
||||
vector unsigned int inMask)
|
||||
{
|
||||
vector unsigned int zvals_ui4, mask, zbuf = *zbuf_ptr;
|
||||
|
||||
/* convert floats to uints in [0, 0xffffffff] */
|
||||
zvals_ui4 = spu_convtu(zvals, 32);
|
||||
/* mask = (zbuf < zvals_ui4) ? ~0 : 0 */
|
||||
mask = spu_cmpgt(zbuf, zvals_ui4);
|
||||
/* mask &= inMask */
|
||||
mask = spu_and(mask, inMask);
|
||||
/* zbuf = mask ? zval : zbuf */
|
||||
*zbuf_ptr = spu_sel(zbuf, zvals_ui4, mask);
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
|
||||
#endif /* SPU_ZTEST_H */
|
||||
|
|
@ -116,7 +116,7 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
static boolean
|
||||
i915_vbuf_render_set_primitive( struct vbuf_render *render,
|
||||
unsigned prim )
|
||||
{
|
||||
|
|
@ -125,15 +125,17 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
|
|||
switch(prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
i915_render->hwprim = PRIM3D_POINTLIST;
|
||||
break;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_LINES:
|
||||
i915_render->hwprim = PRIM3D_LINELIST;
|
||||
break;
|
||||
return TRUE;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
i915_render->hwprim = PRIM3D_TRILIST;
|
||||
break;
|
||||
return TRUE;
|
||||
default:
|
||||
assert(0);
|
||||
/* Actually, can handle a lot more just fine... Fixme.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,11 +101,20 @@ sp_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
static boolean
|
||||
sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
|
||||
{
|
||||
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
|
||||
cvbr->prim = prim;
|
||||
if (prim == PIPE_PRIM_TRIANGLES ||
|
||||
prim == PIPE_PRIM_LINES ||
|
||||
prim == PIPE_PRIM_POINTS) {
|
||||
cvbr->prim = prim;
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -207,6 +216,27 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
(struct vertex_header *) ((char *) vertex_buffer + (I) * vertex_size)
|
||||
|
||||
switch (cvbr->prim) {
|
||||
case PIPE_PRIM_POINTS:
|
||||
for (i = 0; i < nr; i++) {
|
||||
prim.v[0] = VERTEX(i);
|
||||
setup->point( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_LINES:
|
||||
assert(nr % 2 == 0);
|
||||
for (i = 0; i < nr; i += 2) {
|
||||
prim.v[0] = VERTEX(i);
|
||||
prim.v[1] = VERTEX(i + 1);
|
||||
setup->line( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_LINE_STRIP:
|
||||
for (i = 1; i < nr; i++) {
|
||||
prim.v[0] = VERTEX(i - 1);
|
||||
prim.v[1] = VERTEX(i);
|
||||
setup->line( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLES:
|
||||
assert(nr % 3 == 0);
|
||||
for (i = 0; i < nr; i += 3) {
|
||||
|
|
@ -217,6 +247,58 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
|
|||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLE_STRIP:
|
||||
assert(nr >= 3);
|
||||
for (i = 2; i < nr; i++) {
|
||||
prim.v[0] = VERTEX(i - 2);
|
||||
prim.v[1] = VERTEX(i - 1);
|
||||
prim.v[2] = VERTEX(i);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_TRIANGLE_FAN:
|
||||
assert(nr >= 3);
|
||||
for (i = 2; i < nr; i++) {
|
||||
prim.v[0] = VERTEX(0);
|
||||
prim.v[1] = VERTEX(i - 1);
|
||||
prim.v[2] = VERTEX(i);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_QUADS:
|
||||
assert(nr % 4 == 0);
|
||||
for (i = 0; i < nr; i += 4) {
|
||||
prim.v[0] = VERTEX(i + 0);
|
||||
prim.v[1] = VERTEX(i + 1);
|
||||
prim.v[2] = VERTEX(i + 2);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
|
||||
prim.v[0] = VERTEX(i + 0);
|
||||
prim.v[1] = VERTEX(i + 2);
|
||||
prim.v[2] = VERTEX(i + 3);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_QUAD_STRIP:
|
||||
assert(nr >= 4);
|
||||
for (i = 2; i < nr; i += 2) {
|
||||
prim.v[0] = VERTEX(i - 2);
|
||||
prim.v[1] = VERTEX(i);
|
||||
prim.v[2] = VERTEX(i + 1);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
|
||||
prim.v[0] = VERTEX(i - 2);
|
||||
prim.v[1] = VERTEX(i + 1);
|
||||
prim.v[2] = VERTEX(i - 1);
|
||||
calc_det(&prim);
|
||||
setup->tri( setup, &prim );
|
||||
}
|
||||
break;
|
||||
case PIPE_PRIM_POLYGON:
|
||||
/* draw as tri fan */
|
||||
for (i = 2; i < nr; i++) {
|
||||
|
|
|
|||
|
|
@ -158,6 +158,16 @@ void debug_mask_vprintf(uint32_t uuid,
|
|||
const char *format,
|
||||
va_list ap);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debug_warning(__msg) \
|
||||
debug_printf("%s:%i:warning: %s\n", __FILE__, __LINE__, (__msg))
|
||||
#else
|
||||
#define debug_warning(__msg) \
|
||||
((void)0)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -88,14 +88,16 @@ FREE( void *ptr )
|
|||
static INLINE void *
|
||||
REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
|
||||
{
|
||||
void *new_ptr;
|
||||
if( new_size <= old_size ) {
|
||||
return old_ptr;
|
||||
}
|
||||
new_ptr = MALLOC( new_size );
|
||||
if( new_ptr ) {
|
||||
memcpy( new_ptr, old_ptr, old_size );
|
||||
void *new_ptr = NULL;
|
||||
|
||||
if (new_size != 0) {
|
||||
new_ptr = MALLOC( new_size );
|
||||
|
||||
if( new_ptr && old_ptr ) {
|
||||
memcpy( new_ptr, old_ptr, old_size );
|
||||
}
|
||||
}
|
||||
|
||||
FREE( old_ptr );
|
||||
return new_ptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1576,9 +1576,6 @@ parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst,
|
|||
if (err) {
|
||||
program_error(ctx, Program->Position, "Bad attribute binding");
|
||||
}
|
||||
else {
|
||||
Program->Base.InputsRead |= (1 << *inputReg);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -2557,6 +2554,11 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Add attributes to InputsRead only if they are used the program.
|
||||
* This avoids the handling of unused ATTRIB declarations in the drivers. */
|
||||
if (*File == PROGRAM_INPUT)
|
||||
Program->Base.InputsRead |= (1 << *Index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ STATETRACKER_SOURCES = \
|
|||
state_tracker/st_atom_texture.c \
|
||||
state_tracker/st_atom_viewport.c \
|
||||
state_tracker/st_cb_accum.c \
|
||||
state_tracker/st_cb_blit.c \
|
||||
state_tracker/st_cb_bufferobjects.c \
|
||||
state_tracker/st_cb_clear.c \
|
||||
state_tracker/st_cb_flush.c \
|
||||
|
|
|
|||
125
src/mesa/state_tracker/st_cb_blit.c
Normal file
125
src/mesa/state_tracker/st_cb_blit.c
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/*
|
||||
* Authors:
|
||||
* Brian Paul
|
||||
*/
|
||||
|
||||
#include "main/imports.h"
|
||||
#include "main/image.h"
|
||||
#include "main/macros.h"
|
||||
#include "main/texformat.h"
|
||||
#include "shader/program.h"
|
||||
#include "shader/prog_parameter.h"
|
||||
#include "shader/prog_print.h"
|
||||
|
||||
#include "st_context.h"
|
||||
#include "st_program.h"
|
||||
#include "st_cb_drawpixels.h"
|
||||
#include "st_cb_blit.h"
|
||||
#include "st_cb_fbo.h"
|
||||
|
||||
#include "util/u_blit.h"
|
||||
|
||||
#include "cso_cache/cso_context.h"
|
||||
|
||||
|
||||
void
|
||||
st_init_blit(struct st_context *st)
|
||||
{
|
||||
st->blit = util_create_blit(st->pipe);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
st_destroy_blit(struct st_context *st)
|
||||
{
|
||||
util_destroy_blit(st->blit);
|
||||
st->blit = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
st_BlitFramebuffer(GLcontext *ctx,
|
||||
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter)
|
||||
{
|
||||
struct st_context *st = ctx->st;
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
|
||||
const uint pFilter = ((filter == GL_NEAREST)
|
||||
? PIPE_TEX_MIPFILTER_NEAREST
|
||||
: PIPE_TEX_MIPFILTER_LINEAR);
|
||||
|
||||
if (mask & GL_COLOR_BUFFER_BIT) {
|
||||
struct st_renderbuffer *srcRb =
|
||||
st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
|
||||
struct st_renderbuffer *dstRb =
|
||||
st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0][0]);
|
||||
struct pipe_surface *srcSurf = srcRb->surface;
|
||||
struct pipe_surface *dstSurf = dstRb->surface;
|
||||
|
||||
srcY0 = srcRb->Base.Height - srcY0;
|
||||
srcY1 = srcRb->Base.Height - srcY1;
|
||||
|
||||
dstY0 = dstRb->Base.Height - dstY0;
|
||||
dstY1 = dstRb->Base.Height - dstY1;
|
||||
|
||||
util_blit_pixels(st->blit,
|
||||
srcSurf, srcX0, srcY0, srcX1, srcY1,
|
||||
dstSurf, dstX0, dstY0, dstX1, dstY1,
|
||||
0.0, pFilter);
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* XXX is this sufficient? */
|
||||
st_invalidate_state(ctx, _NEW_COLOR | _NEW_TEXTURE);
|
||||
#else
|
||||
/* need to "unset" cso state because we went behind the back of the cso
|
||||
* tracker. Without unset, the _set_ calls would be no-ops.
|
||||
*/
|
||||
cso_unset_blend(st->cso_context);
|
||||
cso_unset_depth_stencil_alpha(st->cso_context);
|
||||
cso_unset_rasterizer(st->cso_context);
|
||||
cso_set_blend(st->cso_context, &st->state.blend);
|
||||
cso_set_depth_stencil_alpha(st->cso_context, &st->state.depth_stencil);
|
||||
cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
|
||||
pipe->bind_fs_state(pipe, st->fp->driver_shader);
|
||||
pipe->bind_vs_state(pipe, st->vp->driver_shader);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
st_init_blit_functions(struct dd_function_table *functions)
|
||||
{
|
||||
functions->BlitFramebuffer = st_BlitFramebuffer;
|
||||
}
|
||||
46
src/mesa/state_tracker/st_cb_blit.h
Normal file
46
src/mesa/state_tracker/st_cb_blit.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* 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 ST_CB_BLIT_H
|
||||
#define ST_CB_BLIT_H
|
||||
|
||||
|
||||
#include "st_context.h"
|
||||
|
||||
|
||||
|
||||
extern void
|
||||
st_init_blit(struct st_context *st);
|
||||
|
||||
extern void
|
||||
st_destroy_blit(struct st_context *st);
|
||||
|
||||
extern void
|
||||
st_init_blit_functions(struct dd_function_table *functions);
|
||||
|
||||
|
||||
#endif /* ST_CB_BLIT_H */
|
||||
|
|
@ -48,6 +48,7 @@
|
|||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "util/u_pack_color.h"
|
||||
|
||||
#include "cso_cache/cso_context.h"
|
||||
|
||||
|
|
@ -56,55 +57,6 @@
|
|||
#define TEST_DRAW_PASSTHROUGH 0
|
||||
|
||||
|
||||
static GLuint
|
||||
color_value(enum pipe_format pipeFormat, const GLfloat color[4])
|
||||
{
|
||||
GLubyte r, g, b, a;
|
||||
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(r, color[0]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(g, color[1]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(b, color[2]);
|
||||
UNCLAMPED_FLOAT_TO_UBYTE(a, color[3]);
|
||||
|
||||
switch (pipeFormat) {
|
||||
case PIPE_FORMAT_R8G8B8A8_UNORM:
|
||||
return (r << 24) | (g << 16) | (b << 8) | a;
|
||||
case PIPE_FORMAT_A8R8G8B8_UNORM:
|
||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||
case PIPE_FORMAT_B8G8R8A8_UNORM:
|
||||
return (b << 24) | (g << 16) | (r << 8) | a;
|
||||
case PIPE_FORMAT_R5G6B5_UNORM:
|
||||
return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint
|
||||
depth_value(enum pipe_format pipeFormat, GLfloat value)
|
||||
{
|
||||
switch (pipeFormat) {
|
||||
case PIPE_FORMAT_Z16_UNORM:
|
||||
return (uint) (value * 0xffff);
|
||||
case PIPE_FORMAT_Z32_UNORM:
|
||||
/* special-case to avoid overflow */
|
||||
if (value == 1.0)
|
||||
return 0xffffffff;
|
||||
else
|
||||
return (uint) (value * 0xffffffff);
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
return (uint) (value * 0xffffff);
|
||||
case PIPE_FORMAT_Z24S8_UNORM:
|
||||
return ((uint) (value * 0xffffff)) << 8;
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GLboolean
|
||||
is_depth_stencil_format(enum pipe_format pipeFormat)
|
||||
{
|
||||
|
|
@ -405,6 +357,8 @@ clear_with_quad(GLcontext *ctx,
|
|||
st_invalidate_state(ctx, _NEW_COLOR | _NEW_DEPTH | _NEW_STENCIL);
|
||||
#else
|
||||
/* Restore pipe state */
|
||||
cso_set_blend(st->cso_context, &st->state.blend);
|
||||
cso_set_depth_stencil_alpha(st->cso_context, &st->state.depth_stencil);
|
||||
cso_set_rasterizer(st->cso_context, &st->state.rasterizer);
|
||||
pipe->bind_fs_state(pipe, st->fp->driver_shader);
|
||||
pipe->bind_vs_state(pipe, st->vp->driver_shader);
|
||||
|
|
@ -518,7 +472,6 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
|
|||
|
||||
|
||||
|
||||
|
||||
static void
|
||||
clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
||||
{
|
||||
|
|
@ -527,10 +480,10 @@ clear_color_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
|||
clear_with_quad(ctx, GL_TRUE, GL_FALSE, GL_FALSE);
|
||||
}
|
||||
else {
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
/* clear whole buffer w/out masking */
|
||||
uint clearValue = color_value(strb->surface->format, ctx->Color.ClearColor);
|
||||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
uint clearValue;
|
||||
util_pack_color(ctx->Color.ClearColor, strb->surface->format, &clearValue);
|
||||
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -547,7 +500,7 @@ clear_depth_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
|||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
/* simple clear of whole buffer */
|
||||
uint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear);
|
||||
uint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear);
|
||||
ctx->st->pipe->clear(ctx->st->pipe, strb->surface, clearValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -591,7 +544,7 @@ clear_depth_stencil_buffer(GLcontext *ctx, struct gl_renderbuffer *rb)
|
|||
struct st_renderbuffer *strb = st_renderbuffer(rb);
|
||||
|
||||
/* clear whole buffer w/out masking */
|
||||
GLuint clearValue = depth_value(strb->surface->format, ctx->Depth.Clear);
|
||||
GLuint clearValue = util_pack_z(strb->surface->format, ctx->Depth.Clear);
|
||||
|
||||
switch (strb->surface->format) {
|
||||
case PIPE_FORMAT_S8Z24_UNORM:
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "st_context.h"
|
||||
#include "st_cb_accum.h"
|
||||
#include "st_cb_bufferobjects.h"
|
||||
#include "st_cb_blit.h"
|
||||
#include "st_cb_clear.h"
|
||||
#include "st_cb_drawpixels.h"
|
||||
#include "st_cb_fbo.h"
|
||||
|
|
@ -100,6 +101,7 @@ st_create_context_priv( GLcontext *ctx, struct pipe_context *pipe )
|
|||
st_init_atoms( st );
|
||||
st_init_draw( st );
|
||||
st_init_generate_mipmap(st);
|
||||
st_init_blit(st);
|
||||
|
||||
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
|
||||
st->state.sampler_list[i] = &st->state.samplers[i];
|
||||
|
|
@ -151,6 +153,8 @@ static void st_destroy_context_priv( struct st_context *st )
|
|||
draw_destroy(st->draw);
|
||||
st_destroy_atoms( st );
|
||||
st_destroy_draw( st );
|
||||
st_destroy_generate_mipmap(st);
|
||||
st_destroy_blit(st);
|
||||
|
||||
_vbo_DestroyContext(st->ctx);
|
||||
|
||||
|
|
@ -217,6 +221,7 @@ void st_init_driver_functions(struct dd_function_table *functions)
|
|||
|
||||
st_init_accum_functions(functions);
|
||||
st_init_bufferobject_functions(functions);
|
||||
st_init_blit_functions(functions);
|
||||
st_init_clear_functions(functions);
|
||||
st_init_drawpixels_functions(functions);
|
||||
st_init_fbo_functions(functions);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ struct draw_context;
|
|||
struct draw_stage;
|
||||
struct cso_cache;
|
||||
struct cso_blend;
|
||||
struct gen_mipmap_state;
|
||||
struct blit_state;
|
||||
|
||||
|
||||
#define ST_NEW_MESA 0x1 /* Mesa state has changed */
|
||||
#define ST_NEW_FRAGMENT_PROGRAM 0x2
|
||||
|
|
@ -146,18 +149,8 @@ struct st_context
|
|||
struct st_fragment_program *combined_prog;
|
||||
} bitmap;
|
||||
|
||||
/** For gen/render mipmap feature */
|
||||
struct {
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
|
||||
void *blend_cso;
|
||||
void *depthstencil_cso;
|
||||
void *rasterizer_cso;
|
||||
struct st_fragment_program *stfp;
|
||||
struct st_vertex_program *stvp;
|
||||
} gen_mipmap;
|
||||
struct gen_mipmap_state *gen_mipmap;
|
||||
struct blit_state *blit;
|
||||
|
||||
struct cso_context *cso_context;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ void st_init_extensions(struct st_context *st)
|
|||
ctx->Extensions.EXT_blend_logic_op = GL_TRUE;
|
||||
ctx->Extensions.EXT_blend_minmax = GL_TRUE;
|
||||
ctx->Extensions.EXT_blend_subtract = GL_TRUE;
|
||||
ctx->Extensions.EXT_framebuffer_blit = GL_TRUE;
|
||||
ctx->Extensions.EXT_framebuffer_object = GL_TRUE;
|
||||
ctx->Extensions.EXT_fog_coord = GL_TRUE;
|
||||
ctx->Extensions.EXT_multi_draw_arrays = GL_TRUE;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "pipe/p_defines.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "util/u_gen_mipmap.h"
|
||||
|
||||
#include "cso_cache/cso_cache.h"
|
||||
#include "cso_cache/cso_context.h"
|
||||
|
||||
|
|
@ -49,55 +51,6 @@
|
|||
#include "st_cb_texture.h"
|
||||
|
||||
|
||||
|
||||
static struct st_fragment_program *
|
||||
make_tex_fragment_program(GLcontext *ctx)
|
||||
{
|
||||
struct st_fragment_program *stfp;
|
||||
struct gl_program *p;
|
||||
GLuint ic = 0;
|
||||
|
||||
p = ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->NumInstructions = 2;
|
||||
|
||||
p->Instructions = _mesa_alloc_instructions(p->NumInstructions);
|
||||
if (!p->Instructions) {
|
||||
ctx->Driver.DeleteProgram(ctx, p);
|
||||
return NULL;
|
||||
}
|
||||
_mesa_init_instructions(p->Instructions, p->NumInstructions);
|
||||
|
||||
/* TEX result.color, fragment.texcoord[0], texture[0], 2D; */
|
||||
p->Instructions[ic].Opcode = OPCODE_TEX;
|
||||
p->Instructions[ic].DstReg.File = PROGRAM_OUTPUT;
|
||||
p->Instructions[ic].DstReg.Index = FRAG_RESULT_COLR;
|
||||
p->Instructions[ic].SrcReg[0].File = PROGRAM_INPUT;
|
||||
p->Instructions[ic].SrcReg[0].Index = FRAG_ATTRIB_TEX0;
|
||||
p->Instructions[ic].TexSrcUnit = 0;
|
||||
p->Instructions[ic].TexSrcTarget = TEXTURE_2D_INDEX;
|
||||
ic++;
|
||||
|
||||
/* END; */
|
||||
p->Instructions[ic++].Opcode = OPCODE_END;
|
||||
|
||||
assert(ic == p->NumInstructions);
|
||||
|
||||
p->InputsRead = FRAG_BIT_TEX0;
|
||||
p->OutputsWritten = (1 << FRAG_RESULT_COLR);
|
||||
|
||||
stfp = (struct st_fragment_program *) p;
|
||||
|
||||
st_translate_fragment_program(ctx->st, stfp, NULL);
|
||||
|
||||
return stfp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* one-time init for generate mipmap
|
||||
* XXX Note: there may be other times we need no-op/simple state like this.
|
||||
|
|
@ -106,117 +59,18 @@ make_tex_fragment_program(GLcontext *ctx)
|
|||
void
|
||||
st_init_generate_mipmap(struct st_context *st)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_blend_state blend;
|
||||
struct pipe_rasterizer_state rasterizer;
|
||||
struct pipe_depth_stencil_alpha_state depthstencil;
|
||||
|
||||
/* we don't use blending, but need to set valid values */
|
||||
memset(&blend, 0, sizeof(blend));
|
||||
blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
|
||||
blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
|
||||
blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
|
||||
blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
|
||||
blend.colormask = PIPE_MASK_RGBA;
|
||||
st->gen_mipmap.blend = blend;
|
||||
st->gen_mipmap.blend_cso = pipe->create_blend_state(pipe, &blend);
|
||||
|
||||
memset(&depthstencil, 0, sizeof(depthstencil));
|
||||
st->gen_mipmap.depthstencil_cso = pipe->create_depth_stencil_alpha_state(pipe, &depthstencil);
|
||||
|
||||
/* Note: we're assuming zero is valid for all non-specified fields */
|
||||
memset(&rasterizer, 0, sizeof(rasterizer));
|
||||
rasterizer.front_winding = PIPE_WINDING_CW;
|
||||
rasterizer.cull_mode = PIPE_WINDING_NONE;
|
||||
st->gen_mipmap.rasterizer_cso = pipe->create_rasterizer_state(pipe, &rasterizer);
|
||||
|
||||
st->gen_mipmap.stfp = make_tex_fragment_program(st->ctx);
|
||||
st->gen_mipmap.stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
|
||||
st->gen_mipmap = util_create_gen_mipmap(st->pipe);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
st_destroy_generate_mipmpap(struct st_context *st)
|
||||
st_destroy_generate_mipmap(struct st_context *st)
|
||||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
|
||||
pipe->delete_blend_state(pipe, st->gen_mipmap.blend_cso);
|
||||
pipe->delete_depth_stencil_alpha_state(pipe, st->gen_mipmap.depthstencil_cso);
|
||||
pipe->delete_rasterizer_state(pipe, st->gen_mipmap.rasterizer_cso);
|
||||
|
||||
/* XXX free stfp, stvp */
|
||||
util_destroy_gen_mipmap(st->gen_mipmap);
|
||||
st->gen_mipmap = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
simple_viewport(struct pipe_context *pipe, uint width, uint height)
|
||||
{
|
||||
struct pipe_viewport_state vp;
|
||||
|
||||
vp.scale[0] = 0.5 * width;
|
||||
vp.scale[1] = -0.5 * height;
|
||||
vp.scale[2] = 1.0;
|
||||
vp.scale[3] = 1.0;
|
||||
vp.translate[0] = 0.5 * width;
|
||||
vp.translate[1] = 0.5 * height;
|
||||
vp.translate[2] = 0.0;
|
||||
vp.translate[3] = 0.0;
|
||||
|
||||
pipe->set_viewport_state(pipe, &vp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Draw simple [-1,1]x[-1,1] quad
|
||||
*/
|
||||
static void
|
||||
draw_quad(GLcontext *ctx)
|
||||
{
|
||||
GLfloat verts[4][2][4]; /* four verts, two attribs, XYZW */
|
||||
GLuint i;
|
||||
GLfloat sLeft = 0.0, sRight = 1.0;
|
||||
GLfloat tTop = 1.0, tBot = 0.0;
|
||||
GLfloat x0 = -1.0, x1 = 1.0;
|
||||
GLfloat y0 = -1.0, y1 = 1.0;
|
||||
|
||||
/* upper-left */
|
||||
verts[0][0][0] = x0; /* attr[0].x */
|
||||
verts[0][0][1] = y0; /* attr[0].y */
|
||||
verts[0][1][0] = sLeft; /* attr[1].s */
|
||||
verts[0][1][1] = tTop; /* attr[1].t */
|
||||
|
||||
/* upper-right */
|
||||
verts[1][0][0] = x1;
|
||||
verts[1][0][1] = y0;
|
||||
verts[1][1][0] = sRight;
|
||||
verts[1][1][1] = tTop;
|
||||
|
||||
/* lower-right */
|
||||
verts[2][0][0] = x1;
|
||||
verts[2][0][1] = y1;
|
||||
verts[2][1][0] = sRight;
|
||||
verts[2][1][1] = tBot;
|
||||
|
||||
/* lower-left */
|
||||
verts[3][0][0] = x0;
|
||||
verts[3][0][1] = y1;
|
||||
verts[3][1][0] = sLeft;
|
||||
verts[3][1][1] = tBot;
|
||||
|
||||
/* same for all verts: */
|
||||
for (i = 0; i < 4; i++) {
|
||||
verts[i][0][2] = 0.0; /*Z*/
|
||||
verts[i][0][3] = 1.0; /*W*/
|
||||
verts[i][1][2] = 0.0; /*R*/
|
||||
verts[i][1][3] = 1.0; /*Q*/
|
||||
}
|
||||
|
||||
st_draw_vertices(ctx, PIPE_PRIM_QUADS, 4, (float *) verts, 2, GL_TRUE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Generate mipmap levels using hardware rendering.
|
||||
* \return TRUE if successful, FALSE if not possible
|
||||
|
|
@ -229,12 +83,7 @@ st_render_mipmap(struct st_context *st,
|
|||
{
|
||||
struct pipe_context *pipe = st->pipe;
|
||||
struct pipe_screen *screen = pipe->screen;
|
||||
struct pipe_framebuffer_state fb;
|
||||
struct pipe_sampler_state sampler;
|
||||
void *sampler_cso;
|
||||
const uint face = _mesa_tex_target_to_face(target), zslice = 0;
|
||||
/*const uint first_level_save = pt->first_level;*/
|
||||
uint dstLevel;
|
||||
const uint face = _mesa_tex_target_to_face(target);
|
||||
|
||||
assert(target != GL_TEXTURE_3D); /* not done yet */
|
||||
|
||||
|
|
@ -243,66 +92,7 @@ st_render_mipmap(struct st_context *st,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* init framebuffer state */
|
||||
memset(&fb, 0, sizeof(fb));
|
||||
fb.num_cbufs = 1;
|
||||
|
||||
/* sampler state */
|
||||
memset(&sampler, 0, sizeof(sampler));
|
||||
sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
|
||||
sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
|
||||
sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
|
||||
sampler.normalized_coords = 1;
|
||||
|
||||
|
||||
/* bind state */
|
||||
cso_set_blend(st->cso_context, &st->gen_mipmap.blend);
|
||||
cso_set_depth_stencil_alpha(st->cso_context, &st->gen_mipmap.depthstencil);
|
||||
cso_set_rasterizer(st->cso_context, &st->gen_mipmap.rasterizer);
|
||||
|
||||
/* bind shaders */
|
||||
pipe->bind_fs_state(pipe, st->gen_mipmap.stfp->driver_shader);
|
||||
pipe->bind_vs_state(pipe, st->gen_mipmap.stvp->driver_shader);
|
||||
|
||||
/*
|
||||
* XXX for small mipmap levels, it may be faster to use the software
|
||||
* fallback path...
|
||||
*/
|
||||
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
|
||||
const uint srcLevel = dstLevel - 1;
|
||||
|
||||
/*
|
||||
* Setup framebuffer / dest surface
|
||||
*/
|
||||
fb.cbufs[0] = screen->get_tex_surface(screen, pt, face, dstLevel, zslice);
|
||||
pipe->set_framebuffer_state(pipe, &fb);
|
||||
|
||||
/*
|
||||
* Setup sampler state
|
||||
*/
|
||||
sampler.min_lod = sampler.max_lod = srcLevel;
|
||||
sampler_cso = pipe->create_sampler_state(pipe, &sampler);
|
||||
pipe->bind_sampler_states(pipe, 1, &sampler_cso);
|
||||
|
||||
simple_viewport(pipe, pt->width[dstLevel], pt->height[dstLevel]);
|
||||
|
||||
/*
|
||||
* Setup src texture, override pt->first_level so we sample from
|
||||
* the right mipmap level.
|
||||
*/
|
||||
/*pt->first_level = srcLevel;*/
|
||||
pipe->set_sampler_textures(pipe, 1, &pt);
|
||||
|
||||
draw_quad(st->ctx);
|
||||
|
||||
pipe->delete_sampler_state(pipe, sampler_cso);
|
||||
}
|
||||
|
||||
/* restore first_level */
|
||||
/*pt->first_level = first_level_save;*/
|
||||
util_gen_mipmap(st->gen_mipmap, pt, face, baseLevel, lastLevel);
|
||||
|
||||
/* restore pipe state */
|
||||
#if 0
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ st_init_generate_mipmap(struct st_context *st);
|
|||
|
||||
|
||||
extern void
|
||||
st_destroy_generate_mipmpap(struct st_context *st);
|
||||
st_destroy_generate_mipmap(struct st_context *st);
|
||||
|
||||
|
||||
extern void
|
||||
|
|
|
|||
|
|
@ -348,8 +348,6 @@ static GLboolean build_vertex_emit( struct x86_program *p )
|
|||
struct x86_reg vp1 = x86_make_reg(file_XMM, 2);
|
||||
GLubyte *fixup, *label;
|
||||
|
||||
x86_init_func(&p->func);
|
||||
|
||||
/* Push a few regs?
|
||||
*/
|
||||
x86_push(&p->func, countEBP);
|
||||
|
|
@ -641,7 +639,7 @@ void _tnl_generate_sse_emit( GLcontext *ctx )
|
|||
|
||||
p.ctx = ctx;
|
||||
p.inputs_safe = 0; /* for now */
|
||||
p.outputs_safe = 1; /* for now */
|
||||
p.outputs_safe = 0; /* for now */
|
||||
p.have_sse2 = cpu_has_xmm2;
|
||||
p.identity = x86_make_reg(file_XMM, 6);
|
||||
p.chan0 = x86_make_reg(file_XMM, 7);
|
||||
|
|
|
|||
|
|
@ -633,7 +633,7 @@ void vf_generate_sse_emit( struct vertex_fetch *vf )
|
|||
|
||||
p.vf = vf;
|
||||
p.inputs_safe = 0; /* for now */
|
||||
p.outputs_safe = 1; /* for now */
|
||||
p.outputs_safe = 0; /* for now */
|
||||
p.have_sse2 = cpu_has_xmm2;
|
||||
p.identity = x86_make_reg(file_XMM, 6);
|
||||
p.chan0 = x86_make_reg(file_XMM, 7);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue