Compare commits
53 Commits
mesa-17.1.
...
texman_0_1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3b325e560 | ||
|
|
382ce985ac | ||
|
|
54b7eca7a0 | ||
|
|
f74e06bf11 | ||
|
|
9c02649d18 | ||
|
|
2c34704e41 | ||
|
|
85d0041ff0 | ||
|
|
67ff8b354e | ||
|
|
08e7957571 | ||
|
|
9c1f7089d8 | ||
|
|
5381ac5f11 | ||
|
|
a6f78d4eee | ||
|
|
ae695e3566 | ||
|
|
c82c3335e1 | ||
|
|
f8246f504b | ||
|
|
499458bcdb | ||
|
|
37a53fd6a0 | ||
|
|
5ec38fb2ea | ||
|
|
11c0215bf8 | ||
|
|
6a13b6c346 | ||
|
|
a103097ee5 | ||
|
|
7efad0d84c | ||
|
|
42c88cd072 | ||
|
|
2541c54e79 | ||
|
|
33529e3d8e | ||
|
|
84c1b82081 | ||
|
|
a97a1439ae | ||
|
|
2fd2910010 | ||
|
|
fbbda155e0 | ||
|
|
a49c3c0fae | ||
|
|
baf5998d59 | ||
|
|
4c5acef241 | ||
|
|
9839e272cf | ||
|
|
b57e79ff14 | ||
|
|
43824acb4e | ||
|
|
d8f509e749 | ||
|
|
eb91c93c2e | ||
|
|
79de983b6f | ||
|
|
fdb3acf016 | ||
|
|
2807d1f58a | ||
|
|
93f913926e | ||
|
|
33ca04f379 | ||
|
|
398cb30c72 | ||
|
|
f67bb30314 | ||
|
|
4578d7b9f0 | ||
|
|
dcdfc154c3 | ||
|
|
696ba32779 | ||
|
|
dcfe55539f | ||
|
|
ff84b1f1b2 | ||
|
|
3bca9c47f4 | ||
|
|
d4d7fdb43b | ||
|
|
d65dab5777 | ||
|
|
638ca019ef |
@@ -9,7 +9,7 @@ CONFIG_NAME = linux-dri
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CXX = g++
|
CXX = g++
|
||||||
|
|
||||||
MKDEP = /usr/X11R6/bin/makedepend
|
#MKDEP = /usr/X11R6/bin/makedepend
|
||||||
#MKDEP = gcc -M
|
#MKDEP = gcc -M
|
||||||
#MKDEP_OPTIONS = -MF depend
|
#MKDEP_OPTIONS = -MF depend
|
||||||
|
|
||||||
@@ -63,5 +63,7 @@ WINDOW_SYSTEM=dri
|
|||||||
|
|
||||||
# gamma are missing because they have not been converted to use the new
|
# gamma are missing because they have not been converted to use the new
|
||||||
# interface.
|
# interface.
|
||||||
DRI_DIRS = i810 i830 i915 mach64 mga r128 r200 r300 radeon s3v \
|
DRI_DIRS = i810 i915 mach64 mga r128 r200 r300 radeon s3v \
|
||||||
savage sis tdfx trident unichrome ffb
|
savage sis tdfx trident unichrome ffb
|
||||||
|
|
||||||
|
DRI_DIRS = i915
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ PROGS = \
|
|||||||
fplight \
|
fplight \
|
||||||
gamma \
|
gamma \
|
||||||
gears \
|
gears \
|
||||||
|
gearbox \
|
||||||
geartrain \
|
geartrain \
|
||||||
glinfo \
|
glinfo \
|
||||||
gloss \
|
gloss \
|
||||||
@@ -51,7 +52,7 @@ PROGS = \
|
|||||||
terrain \
|
terrain \
|
||||||
tessdemo \
|
tessdemo \
|
||||||
texcyl \
|
texcyl \
|
||||||
texdown \
|
texdown-pool \
|
||||||
texenv \
|
texenv \
|
||||||
texobj \
|
texobj \
|
||||||
trispd \
|
trispd \
|
||||||
@@ -73,9 +74,8 @@ PROGS = \
|
|||||||
|
|
||||||
##### TARGETS #####
|
##### TARGETS #####
|
||||||
|
|
||||||
default: $(PROGS)
|
default: readtex.o $(PROGS)
|
||||||
|
|
||||||
$(PROGS): readtex.o
|
|
||||||
|
|
||||||
readtex.c: $(TOP)/progs/util/readtex.c
|
readtex.c: $(TOP)/progs/util/readtex.c
|
||||||
cp $< .
|
cp $< .
|
||||||
|
|||||||
486
progs/demos/gearbox.c
Normal file
486
progs/demos/gearbox.c
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
/*
|
||||||
|
* Use glCopyTexSubImage2D to draw animated gears on the sides of a box.
|
||||||
|
*
|
||||||
|
* Brian Paul
|
||||||
|
* 27 January 2006
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <GL/glut.h>
|
||||||
|
|
||||||
|
#ifndef M_PI
|
||||||
|
#define M_PI 3.14159265
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static GLint WinWidth = 800, WinHeight = 500;
|
||||||
|
static GLint TexWidth, TexHeight;
|
||||||
|
static GLuint TexObj = 1;
|
||||||
|
static GLenum IntFormat = GL_RGBA;
|
||||||
|
|
||||||
|
static GLboolean WireFrame = GL_FALSE;
|
||||||
|
|
||||||
|
static GLint T0 = 0;
|
||||||
|
static GLint Frames = 0;
|
||||||
|
static GLint Win = 0;
|
||||||
|
|
||||||
|
static GLfloat ViewRotX = 20.0, ViewRotY = 30.0, ViewRotZ = 0.0;
|
||||||
|
static GLint Gear1, Gear2, Gear3;
|
||||||
|
static GLfloat GearRot = 0.0;
|
||||||
|
static GLfloat CubeRot = 0.0;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Draw a gear wheel. You'll probably want to call this function when
|
||||||
|
building a display list since we do a lot of trig here.
|
||||||
|
|
||||||
|
Input: inner_radius - radius of hole at center
|
||||||
|
outer_radius - radius at center of teeth
|
||||||
|
width - width of gear
|
||||||
|
teeth - number of teeth
|
||||||
|
tooth_depth - depth of tooth
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
||||||
|
GLint teeth, GLfloat tooth_depth)
|
||||||
|
{
|
||||||
|
GLint i;
|
||||||
|
GLfloat r0, r1, r2;
|
||||||
|
GLfloat angle, da;
|
||||||
|
GLfloat u, v, len;
|
||||||
|
|
||||||
|
r0 = inner_radius;
|
||||||
|
r1 = outer_radius - tooth_depth / 2.0;
|
||||||
|
r2 = outer_radius + tooth_depth / 2.0;
|
||||||
|
|
||||||
|
da = 2.0 * M_PI / teeth / 4.0;
|
||||||
|
|
||||||
|
glShadeModel(GL_FLAT);
|
||||||
|
|
||||||
|
glNormal3f(0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
/* draw front face */
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i <= teeth; i++) {
|
||||||
|
angle = i * 2.0 * M_PI / teeth;
|
||||||
|
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||||
|
if (i < teeth) {
|
||||||
|
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
/* draw front sides of teeth */
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
da = 2.0 * M_PI / teeth / 4.0;
|
||||||
|
for (i = 0; i < teeth; i++) {
|
||||||
|
angle = i * 2.0 * M_PI / teeth;
|
||||||
|
|
||||||
|
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||||
|
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||||
|
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glNormal3f(0.0, 0.0, -1.0);
|
||||||
|
|
||||||
|
/* draw back face */
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i <= teeth; i++) {
|
||||||
|
angle = i * 2.0 * M_PI / teeth;
|
||||||
|
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||||
|
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||||
|
if (i < teeth) {
|
||||||
|
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
|
||||||
|
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
/* draw back sides of teeth */
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
da = 2.0 * M_PI / teeth / 4.0;
|
||||||
|
for (i = 0; i < teeth; i++) {
|
||||||
|
angle = i * 2.0 * M_PI / teeth;
|
||||||
|
|
||||||
|
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
|
||||||
|
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
|
||||||
|
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
/* draw outward faces of teeth */
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i < teeth; i++) {
|
||||||
|
angle = i * 2.0 * M_PI / teeth;
|
||||||
|
|
||||||
|
glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
|
||||||
|
u = r2 * cos(angle + da) - r1 * cos(angle);
|
||||||
|
v = r2 * sin(angle + da) - r1 * sin(angle);
|
||||||
|
len = sqrt(u * u + v * v);
|
||||||
|
u /= len;
|
||||||
|
v /= len;
|
||||||
|
glNormal3f(v, -u, 0.0);
|
||||||
|
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
|
||||||
|
glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
|
||||||
|
glNormal3f(cos(angle), sin(angle), 0.0);
|
||||||
|
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5);
|
||||||
|
glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5);
|
||||||
|
u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
|
||||||
|
v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
|
||||||
|
glNormal3f(v, -u, 0.0);
|
||||||
|
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5);
|
||||||
|
glNormal3f(cos(angle), sin(angle), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
|
||||||
|
glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
glShadeModel(GL_SMOOTH);
|
||||||
|
|
||||||
|
/* draw inside radius cylinder */
|
||||||
|
glBegin(GL_QUAD_STRIP);
|
||||||
|
for (i = 0; i <= teeth; i++) {
|
||||||
|
angle = i * 2.0 * M_PI / teeth;
|
||||||
|
glNormal3f(-cos(angle), -sin(angle), 0.0);
|
||||||
|
glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
|
||||||
|
glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cleanup(void)
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &TexObj);
|
||||||
|
glDeleteLists(Gear1, 1);
|
||||||
|
glDeleteLists(Gear2, 1);
|
||||||
|
glDeleteLists(Gear3, 1);
|
||||||
|
glutDestroyWindow(Win);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DrawGears(void)
|
||||||
|
{
|
||||||
|
if (WireFrame) {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(20/*ViewRotX*/, 1.0, 0.0, 0.0);
|
||||||
|
glRotatef(ViewRotY, 0.0, 1.0, 0.0);
|
||||||
|
glRotatef(ViewRotZ, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(-3.0, -2.0, 0.0);
|
||||||
|
glRotatef(GearRot, 0.0, 0.0, 1.0);
|
||||||
|
glCallList(Gear1);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(3.1, -2.0, 0.0);
|
||||||
|
glRotatef(-2.0 * GearRot - 9.0, 0.0, 0.0, 1.0);
|
||||||
|
glCallList(Gear2);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(-3.1, 4.2, 0.0);
|
||||||
|
glRotatef(-2.0 * GearRot - 25.0, 0.0, 0.0, 1.0);
|
||||||
|
glCallList(Gear3);
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
DrawCube(void)
|
||||||
|
{
|
||||||
|
static const GLfloat texcoords[4][2] = {
|
||||||
|
{ 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 }
|
||||||
|
};
|
||||||
|
static const GLfloat vertices[4][2] = {
|
||||||
|
{ -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 }
|
||||||
|
};
|
||||||
|
static const GLfloat xforms[6][4] = {
|
||||||
|
{ 0, 0, 1, 0 },
|
||||||
|
{ 90, 0, 1, 0 },
|
||||||
|
{ 180, 0, 1, 0 },
|
||||||
|
{ 270, 0, 1, 0 },
|
||||||
|
{ 90, 1, 0, 0 },
|
||||||
|
{ -90, 1, 0, 0 }
|
||||||
|
};
|
||||||
|
static const GLfloat mat[4] = { 1.0, 1.0, 0.5, 1.0 };
|
||||||
|
GLint i, j;
|
||||||
|
|
||||||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(ViewRotX, 1.0, 0.0, 0.0);
|
||||||
|
glRotatef(15, 1, 0, 0);
|
||||||
|
glRotatef(CubeRot, 0, 1, 0);
|
||||||
|
glScalef(4, 4, 4);
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]);
|
||||||
|
glTranslatef(0, 0, 1.1);
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glNormal3f(0, 0, 1);
|
||||||
|
for (j = 0; j < 4; j++) {
|
||||||
|
glTexCoord2fv(texcoords[j]);
|
||||||
|
glVertex2fv(vertices[j]);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
draw(void)
|
||||||
|
{
|
||||||
|
float ar;
|
||||||
|
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslatef(0.0, 0.0, -40.0);
|
||||||
|
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
/* draw gears */
|
||||||
|
glViewport(0, 0, TexWidth, TexHeight);
|
||||||
|
glScissor(0, 0, TexWidth, TexHeight);
|
||||||
|
glClearColor(0.5, 0.5, 0.8, 0.0);
|
||||||
|
glClearColor(1, 1, 1, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 60.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
DrawGears();
|
||||||
|
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight);
|
||||||
|
|
||||||
|
/* draw textured cube */
|
||||||
|
glViewport(TexWidth, 0, WinWidth - TexWidth, WinHeight);
|
||||||
|
glScissor(TexWidth, 0, WinWidth - TexWidth, WinHeight);
|
||||||
|
glClearColor(0.5, 0.5, 0.8, 0.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
ar = (float) (WinWidth - TexWidth) / WinHeight;
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glFrustum(-ar, ar, -1.0, 1.0, 5.0, 60.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
DrawCube();
|
||||||
|
|
||||||
|
/* finish up */
|
||||||
|
glutSwapBuffers();
|
||||||
|
|
||||||
|
Frames++;
|
||||||
|
{
|
||||||
|
GLint t = glutGet(GLUT_ELAPSED_TIME);
|
||||||
|
if (t - T0 >= 5000) {
|
||||||
|
GLfloat seconds = (t - T0) / 1000.0;
|
||||||
|
GLfloat fps = Frames / seconds;
|
||||||
|
printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
|
||||||
|
T0 = t;
|
||||||
|
Frames = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
idle(void)
|
||||||
|
{
|
||||||
|
static double t0 = -1.;
|
||||||
|
double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
|
||||||
|
if (t0 < 0.0)
|
||||||
|
t0 = t;
|
||||||
|
dt = t - t0;
|
||||||
|
t0 = t;
|
||||||
|
|
||||||
|
GearRot += 70.0 * dt; /* 70 degrees per second */
|
||||||
|
GearRot = fmod(GearRot, 360.0); /* prevents eventual overflow */
|
||||||
|
|
||||||
|
CubeRot += 15.0 * dt;
|
||||||
|
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* change view angle, exit upon ESC */
|
||||||
|
static void
|
||||||
|
key(unsigned char k, int x, int y)
|
||||||
|
{
|
||||||
|
(void) x;
|
||||||
|
(void) y;
|
||||||
|
switch (k) {
|
||||||
|
case 'w':
|
||||||
|
WireFrame = !WireFrame;
|
||||||
|
break;
|
||||||
|
case 'z':
|
||||||
|
ViewRotZ += 5.0;
|
||||||
|
break;
|
||||||
|
case 'Z':
|
||||||
|
ViewRotZ -= 5.0;
|
||||||
|
break;
|
||||||
|
case 27: /* Escape */
|
||||||
|
cleanup();
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* change view angle */
|
||||||
|
static void
|
||||||
|
special(int k, int x, int y)
|
||||||
|
{
|
||||||
|
(void) x;
|
||||||
|
(void) y;
|
||||||
|
switch (k) {
|
||||||
|
case GLUT_KEY_UP:
|
||||||
|
ViewRotX += 5.0;
|
||||||
|
break;
|
||||||
|
case GLUT_KEY_DOWN:
|
||||||
|
ViewRotX -= 5.0;
|
||||||
|
break;
|
||||||
|
case GLUT_KEY_LEFT:
|
||||||
|
ViewRotY += 5.0;
|
||||||
|
break;
|
||||||
|
case GLUT_KEY_RIGHT:
|
||||||
|
ViewRotY -= 5.0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* new window size or exposure */
|
||||||
|
static void
|
||||||
|
reshape(int width, int height)
|
||||||
|
{
|
||||||
|
WinWidth = width;
|
||||||
|
WinHeight = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
init(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
static GLfloat pos[4] = {5.0, 5.0, 10.0, 0.0};
|
||||||
|
static GLfloat red[4] = {0.8, 0.1, 0.0, 1.0};
|
||||||
|
static GLfloat green[4] = {0.0, 0.8, 0.2, 1.0};
|
||||||
|
static GLfloat blue[4] = {0.2, 0.2, 1.0, 1.0};
|
||||||
|
GLint i;
|
||||||
|
|
||||||
|
glLightfv(GL_LIGHT0, GL_POSITION, pos);
|
||||||
|
#if 0
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
#endif
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
/* make the gears */
|
||||||
|
Gear1 = glGenLists(1);
|
||||||
|
glNewList(Gear1, GL_COMPILE);
|
||||||
|
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
|
||||||
|
gear(1.0, 4.0, 1.0, 20, 0.7);
|
||||||
|
glEndList();
|
||||||
|
|
||||||
|
Gear2 = glGenLists(1);
|
||||||
|
glNewList(Gear2, GL_COMPILE);
|
||||||
|
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
|
||||||
|
gear(0.5, 2.0, 2.0, 10, 0.7);
|
||||||
|
glEndList();
|
||||||
|
|
||||||
|
Gear3 = glGenLists(1);
|
||||||
|
glNewList(Gear3, GL_COMPILE);
|
||||||
|
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
|
||||||
|
gear(1.3, 2.0, 0.5, 10, 0.7);
|
||||||
|
glEndList();
|
||||||
|
|
||||||
|
glEnable(GL_NORMALIZE);
|
||||||
|
|
||||||
|
/* xxx make size dynamic */
|
||||||
|
TexWidth = 256;
|
||||||
|
TexHeight = 256;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, TexObj);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, IntFormat, TexWidth, TexHeight, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
for ( i=1; i<argc; i++ ) {
|
||||||
|
if (strcmp(argv[i], "-info")==0) {
|
||||||
|
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
|
||||||
|
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
|
||||||
|
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
|
||||||
|
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
visible(int vis)
|
||||||
|
{
|
||||||
|
if (vis == GLUT_VISIBLE)
|
||||||
|
glutIdleFunc(idle);
|
||||||
|
else
|
||||||
|
glutIdleFunc(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
glutInit(&argc, argv);
|
||||||
|
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
|
||||||
|
|
||||||
|
glutInitWindowSize(WinWidth, WinHeight);
|
||||||
|
Win = glutCreateWindow("gearbox");
|
||||||
|
init(argc, argv);
|
||||||
|
|
||||||
|
glutDisplayFunc(draw);
|
||||||
|
glutReshapeFunc(reshape);
|
||||||
|
glutKeyboardFunc(key);
|
||||||
|
glutSpecialFunc(special);
|
||||||
|
glutVisibilityFunc(visible);
|
||||||
|
|
||||||
|
glutMainLoop();
|
||||||
|
return 0; /* ANSI C requires main to return int. */
|
||||||
|
}
|
||||||
@@ -38,8 +38,8 @@
|
|||||||
#include <GL/glut.h>
|
#include <GL/glut.h>
|
||||||
|
|
||||||
|
|
||||||
static GLsizei MaxSize = 1024;
|
static GLsizei MaxSize = 2048;
|
||||||
static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0;
|
static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0;
|
||||||
static GLboolean ScaleAndBias = GL_FALSE;
|
static GLboolean ScaleAndBias = GL_FALSE;
|
||||||
static GLboolean SubImage = GL_FALSE;
|
static GLboolean SubImage = GL_FALSE;
|
||||||
static GLdouble DownloadRate = 0.0; /* texels/sec */
|
static GLdouble DownloadRate = 0.0; /* texels/sec */
|
||||||
@@ -47,6 +47,32 @@ static GLdouble DownloadRate = 0.0; /* texels/sec */
|
|||||||
static GLuint Mode = 0;
|
static GLuint Mode = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Try and avoid L2 cache effects by cycling through a small number of
|
||||||
|
* textures.
|
||||||
|
*
|
||||||
|
* At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will
|
||||||
|
* keep us out of most caches at 32mb total.
|
||||||
|
*
|
||||||
|
* This turns into a fairly interesting question of what exactly you
|
||||||
|
* expect to be in cache in normal usage, and what you think should be
|
||||||
|
* outside. There's no rules for this, no reason to favour one usage
|
||||||
|
* over another except what the application you care about happens to
|
||||||
|
* resemble most closely.
|
||||||
|
*
|
||||||
|
* - Should the client texture image be in L2 cache? Has it just been
|
||||||
|
* generated or read from disk?
|
||||||
|
* - Does the application really use >1 texture, or is it constantly
|
||||||
|
* updating one image in-place?
|
||||||
|
*
|
||||||
|
* Different answers will favour different texture upload mechanisms.
|
||||||
|
* To upload an image that is purely outside of cache, a DMA-based
|
||||||
|
* upload will probably win, whereas for small, in-cache textures,
|
||||||
|
* copying looks good.
|
||||||
|
*/
|
||||||
|
#define NR_TEXOBJ 4
|
||||||
|
static GLuint TexObj[NR_TEXOBJ];
|
||||||
|
|
||||||
|
|
||||||
struct FormatRec {
|
struct FormatRec {
|
||||||
GLenum Format;
|
GLenum Format;
|
||||||
GLenum Type;
|
GLenum Type;
|
||||||
@@ -116,25 +142,57 @@ TypeStr(GLenum type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* On x86, there is a performance cliff for memcpy to texture memory
|
||||||
|
* for sources below 64 byte alignment. We do our best with this in
|
||||||
|
* the driver, but it is better if the images are correctly aligned to
|
||||||
|
* start with:
|
||||||
|
*/
|
||||||
|
#define ALIGN (1<<12)
|
||||||
|
|
||||||
|
static unsigned align(unsigned value, unsigned a)
|
||||||
|
{
|
||||||
|
return (value + a - 1) & ~(a-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int MIN2(int a, int b)
|
||||||
|
{
|
||||||
|
return a < b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
MeasureDownloadRate(void)
|
MeasureDownloadRate(void)
|
||||||
{
|
{
|
||||||
const int w = TexWidth + 2 * TexBorder;
|
const int w = TexWidth + 2 * TexBorder;
|
||||||
const int h = TexHeight + 2 * TexBorder;
|
const int h = TexHeight + 2 * TexBorder;
|
||||||
const int bytes = w * h * BytesPerTexel(Format);
|
const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN);
|
||||||
|
const int bytes = image_bytes * NR_TEXOBJ;
|
||||||
|
GLubyte *orig_texImage, *orig_getImage;
|
||||||
GLubyte *texImage, *getImage;
|
GLubyte *texImage, *getImage;
|
||||||
GLdouble t0, t1, time;
|
GLdouble t0, t1, time;
|
||||||
int count;
|
int count;
|
||||||
int i;
|
int i;
|
||||||
|
int offset = 0;
|
||||||
|
GLdouble total = 0; /* ints will tend to overflow */
|
||||||
|
|
||||||
texImage = (GLubyte *) malloc(bytes);
|
printf("allocating %d bytes for %d %dx%d images\n",
|
||||||
getImage = (GLubyte *) malloc(bytes);
|
bytes, NR_TEXOBJ, w, h);
|
||||||
if (!texImage || !getImage) {
|
|
||||||
|
orig_texImage = (GLubyte *) malloc(bytes + ALIGN);
|
||||||
|
orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN);
|
||||||
|
if (!orig_texImage || !orig_getImage) {
|
||||||
DownloadRate = 0.0;
|
DownloadRate = 0.0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("alloc %p %p\n", orig_texImage, orig_getImage);
|
||||||
|
|
||||||
|
texImage = (GLubyte *)align((unsigned)orig_texImage, ALIGN);
|
||||||
|
getImage = (GLubyte *)align((unsigned)orig_getImage, ALIGN);
|
||||||
|
|
||||||
|
for (i = 1; !(((unsigned)texImage) & i); i<<=1)
|
||||||
|
;
|
||||||
|
printf("texture image alignment: %d bytes (%p)\n", i, texImage);
|
||||||
|
|
||||||
for (i = 0; i < bytes; i++) {
|
for (i = 0; i < bytes; i++) {
|
||||||
texImage[i] = i & 0xff;
|
texImage[i] = i & 0xff;
|
||||||
}
|
}
|
||||||
@@ -166,51 +224,80 @@ MeasureDownloadRate(void)
|
|||||||
count = 0;
|
count = 0;
|
||||||
t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
|
t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
|
||||||
do {
|
do {
|
||||||
|
int img = count%NR_TEXOBJ;
|
||||||
|
GLubyte *img_ptr = texImage + img * image_bytes;
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, TexObj[img]);
|
||||||
|
|
||||||
if (SubImage && count > 0) {
|
if (SubImage && count > 0) {
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h,
|
/* Only update a portion of the image each iteration. This
|
||||||
|
* is presumably why you'd want to use texsubimage, otherwise
|
||||||
|
* you may as well just call teximage again.
|
||||||
|
*
|
||||||
|
* A bigger question is whether to use a pointer that moves
|
||||||
|
* with each call, ie does the incoming data come from L2
|
||||||
|
* cache under normal circumstances, or is it pulled from
|
||||||
|
* uncached memory?
|
||||||
|
*
|
||||||
|
* There's a good argument to say L2 cache, ie you'd expect
|
||||||
|
* the data to have been recently generated. It's possible
|
||||||
|
* that it could have come from a file read, which may or may
|
||||||
|
* not have gone through the cpu.
|
||||||
|
*/
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||||
|
-TexBorder,
|
||||||
|
-TexBorder + offset * h/8,
|
||||||
|
w,
|
||||||
|
h/8,
|
||||||
FormatTable[Format].Format,
|
FormatTable[Format].Format,
|
||||||
FormatTable[Format].Type, texImage);
|
FormatTable[Format].Type,
|
||||||
|
#if 1
|
||||||
|
texImage /* likely in L2$ */
|
||||||
|
#else
|
||||||
|
img_ptr + offset * bytes/8 /* unlikely in L2$ */
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
offset += 1;
|
||||||
|
offset %= 8;
|
||||||
|
total += w * h / 8;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||||
FormatTable[Format].IntFormat, w, h, TexBorder,
|
FormatTable[Format].IntFormat, w, h, TexBorder,
|
||||||
FormatTable[Format].Format,
|
FormatTable[Format].Format,
|
||||||
FormatTable[Format].Type, texImage);
|
FormatTable[Format].Type,
|
||||||
|
img_ptr);
|
||||||
|
total += w*h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
/* Render a texture, but not necessarily the one just uploaded.
|
||||||
|
*/
|
||||||
|
/* glBindTexture(GL_TEXTURE_2D, TexObj[(img + NR_TEXOBJ/2)%NR_TEXOBJ]); */
|
||||||
|
|
||||||
/* draw a tiny polygon to force texture into texram */
|
/* draw a tiny polygon to force texture into texram */
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
glTexCoord2f(0, 0); glVertex2f(1, 1);
|
glTexCoord2f(0, 0); glVertex2f(1, 1);
|
||||||
glTexCoord2f(1, 0); glVertex2f(3, 1);
|
glTexCoord2f(1, 0); glVertex2f(3, 1);
|
||||||
glTexCoord2f(0.5, 1); glVertex2f(2, 3);
|
glTexCoord2f(0.5, 1); glVertex2f(2, 3);
|
||||||
glEnd();
|
glEnd();
|
||||||
|
/* glFinish(); */
|
||||||
|
#endif
|
||||||
|
|
||||||
t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
|
t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
|
||||||
time = t1 - t0;
|
time = t1 - t0;
|
||||||
count++;
|
count++;
|
||||||
|
/* printf("total %f count %d\n", total, count); */
|
||||||
} while (time < 3.0);
|
} while (time < 3.0);
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
printf("w*h=%d count=%d time=%f\n", w*h, count, time);
|
printf("total texels=%f time=%f\n", total, time);
|
||||||
DownloadRate = w * h * count / time;
|
DownloadRate = total / time;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (!ScaleAndBias) {
|
|
||||||
/* verify texture readback */
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0,
|
|
||||||
FormatTable[Format].Format,
|
|
||||||
FormatTable[Format].Type, getImage);
|
|
||||||
for (i = 0; i < w * h; i++) {
|
|
||||||
if (texImage[i] != getImage[i]) {
|
|
||||||
printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free(texImage);
|
free(orig_texImage);
|
||||||
free(getImage);
|
free(orig_getImage);
|
||||||
|
|
||||||
{
|
{
|
||||||
GLint err = glGetError();
|
GLint err = glGetError();
|
||||||
@@ -92,7 +92,7 @@ static void idle( void )
|
|||||||
dt = t - t0;
|
dt = t - t0;
|
||||||
t0 = t;
|
t0 = t;
|
||||||
Angle += 120.0*dt;
|
Angle += 120.0*dt;
|
||||||
glutPostRedisplay();
|
/* glutPostRedisplay(); */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ SOURCES = antialias.c \
|
|||||||
sharedtex.c \
|
sharedtex.c \
|
||||||
stencilwrap.c \
|
stencilwrap.c \
|
||||||
stencil_wrap.c \
|
stencil_wrap.c \
|
||||||
|
subtexrate.c \
|
||||||
tex1d.c \
|
tex1d.c \
|
||||||
texfilt.c \
|
texfilt.c \
|
||||||
texline.c \
|
texline.c \
|
||||||
|
|||||||
378
progs/tests/subtexrate.c
Normal file
378
progs/tests/subtexrate.c
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
/*
|
||||||
|
* Measure glTexSubImage and glCopyTexSubImage speed
|
||||||
|
*
|
||||||
|
* Brian Paul
|
||||||
|
* 26 Jan 2006
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <GL/glut.h>
|
||||||
|
|
||||||
|
static GLint WinWidth = 1024, WinHeight = 512;
|
||||||
|
static GLint TexWidth = 512, TexHeight = 512;
|
||||||
|
|
||||||
|
static GLuint TexObj = 1;
|
||||||
|
|
||||||
|
static GLenum IntFormat = GL_RGBA;
|
||||||
|
static GLenum ReadFormat = GL_BGRA; /* for glReadPixels */
|
||||||
|
|
||||||
|
static GLboolean DrawQuad = GL_TRUE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* draw teapot image, size TexWidth by TexHeight
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DrawTestImage(void)
|
||||||
|
{
|
||||||
|
GLfloat ar;
|
||||||
|
|
||||||
|
glViewport(0, 0, TexWidth, TexHeight);
|
||||||
|
glScissor(0, 0, TexWidth, TexHeight);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glClearColor(0.5, 0.5, 0.5, 0.0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
ar = (float) TexWidth / TexHeight;
|
||||||
|
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_LIGHT0);
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glFrontFace(GL_CW);
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(45, 1, 0, 0);
|
||||||
|
glRotatef(45, 0, 1, 0);
|
||||||
|
glutSolidTeapot(2.3);
|
||||||
|
glPopMatrix();
|
||||||
|
glFrontFace(GL_CCW);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glViewport(0, 0, WinWidth, WinHeight);
|
||||||
|
glFinish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do glCopyTexSubImage2D call (update texture with framebuffer data)
|
||||||
|
* If doSubRect is true, do the copy in four pieces instead of all at once.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
DoCopyTex(GLboolean doSubRect)
|
||||||
|
{
|
||||||
|
if (doSubRect) {
|
||||||
|
/* copy in four parts */
|
||||||
|
int w = TexWidth / 2, h = TexHeight / 2;
|
||||||
|
int x0 = 0, y0 = 0;
|
||||||
|
int x1 = w, y1 = h;
|
||||||
|
#if 0
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x0, y0, w, h);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x1, y0, w, h);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, x0, y1, w, h);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, x1, y1, w, h);
|
||||||
|
#else
|
||||||
|
/* scramble */
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, x1, y1, w, h);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, x0, y1, w, h);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, x1, y0, w, h);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, x0, y0, w, h);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, TexWidth, TexHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do glTexSubImage2D (update texture w/ user data)
|
||||||
|
* If doSubRect, do update in four pieces, else all at once.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
SubTex(GLboolean doSubRect, const GLubyte *image)
|
||||||
|
{
|
||||||
|
if (doSubRect) {
|
||||||
|
/* four pieces */
|
||||||
|
int w = TexWidth / 2, h = TexHeight / 2;
|
||||||
|
int x0 = 0, y0 = 0;
|
||||||
|
int x1 = w, y1 = h;
|
||||||
|
glPixelStorei(GL_UNPACK_ROW_LENGTH, TexWidth);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glPixelStorei( GL_PACK_INVERT_MESA, GL_TRUE );
|
||||||
|
|
||||||
|
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
|
||||||
|
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y0); */
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0); */
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, w, h,
|
||||||
|
ReadFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y0); */
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1); */
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y0, w, h,
|
||||||
|
ReadFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y1); */
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x0); */
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y1, w, h,
|
||||||
|
ReadFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_ROWS, y1); */
|
||||||
|
/* glPixelStorei(GL_UNPACK_SKIP_PIXELS, x1); */
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, x1, y1, w, h,
|
||||||
|
ReadFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
glPixelStorei( GL_PACK_INVERT_MESA, GL_FALSE );
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* all at once */
|
||||||
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TexWidth, TexHeight,
|
||||||
|
ReadFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Measure gl[Copy]TexSubImage rate.
|
||||||
|
* This actually also includes time to render a quad and SwapBuffers.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
RunTest(GLboolean copyTex, GLboolean doSubRect)
|
||||||
|
{
|
||||||
|
double t0, t1;
|
||||||
|
int iters = 0;
|
||||||
|
float copyRate, mbRate;
|
||||||
|
float rot = 0.0;
|
||||||
|
int bpp, r, g, b, a;
|
||||||
|
int w, h;
|
||||||
|
GLubyte *image = NULL;
|
||||||
|
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
|
||||||
|
bpp = (r + g + b + a) / 8;
|
||||||
|
|
||||||
|
if (!copyTex) {
|
||||||
|
/* read image from frame buffer */
|
||||||
|
image = (GLubyte *) malloc(TexWidth * TexHeight * bpp);
|
||||||
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||||
|
glReadPixels(0, 0, TexWidth, TexHeight,
|
||||||
|
ReadFormat, GL_UNSIGNED_BYTE, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glViewport(WinWidth / 2, 0, WinWidth / 2, WinHeight);
|
||||||
|
|
||||||
|
t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
|
||||||
|
|
||||||
|
if (!DrawQuad)
|
||||||
|
glDrawBuffer(GL_FRONT);
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (copyTex)
|
||||||
|
/* Framebuffer -> Texture */
|
||||||
|
DoCopyTex(doSubRect);
|
||||||
|
else {
|
||||||
|
/* Main Mem -> Texture */
|
||||||
|
SubTex(doSubRect, image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* draw textured quad */
|
||||||
|
if (DrawQuad) {
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(rot, 0, 0, 1);
|
||||||
|
glTranslatef(1, 0, 0);
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glTexCoord2f(0, 0); glVertex2f(-1, -1);
|
||||||
|
glTexCoord2f(1, 0); glVertex2f( 1, -1);
|
||||||
|
glTexCoord2f(1, 1); glVertex2f( 1, 1);
|
||||||
|
glTexCoord2f(0, 1); glVertex2f(-1, 1);
|
||||||
|
glEnd();
|
||||||
|
glPopMatrix();
|
||||||
|
glutSwapBuffers();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Draw something tiny to ensure that the texture is really
|
||||||
|
* uploaded:
|
||||||
|
*/
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(rot, 0, 0, 1);
|
||||||
|
glTranslatef(1, 0, 0);
|
||||||
|
glBegin(GL_POLYGON);
|
||||||
|
glTexCoord2f(0, 0); glVertex2f(-.01, -.01);
|
||||||
|
glTexCoord2f(.01, 0); glVertex2f( .01, -.01);
|
||||||
|
glTexCoord2f(.01, .01); glVertex2f( .01, .01);
|
||||||
|
glTexCoord2f(0, .01); glVertex2f(-.01, .01);
|
||||||
|
glEnd();
|
||||||
|
glPopMatrix();
|
||||||
|
glFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
iters++;
|
||||||
|
rot += 2.0;
|
||||||
|
|
||||||
|
t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
|
||||||
|
} while (t1 - t0 < 2.0);
|
||||||
|
|
||||||
|
/* Make sure everything is done before taking the final timing:
|
||||||
|
*/
|
||||||
|
glFinish();
|
||||||
|
t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
|
||||||
|
|
||||||
|
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
if (image)
|
||||||
|
free(image);
|
||||||
|
|
||||||
|
if (doSubRect) {
|
||||||
|
w = TexWidth / 2;
|
||||||
|
h = TexHeight / 2;
|
||||||
|
iters *= 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
w = TexWidth;
|
||||||
|
h = TexHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyRate = iters / (t1 - t0);
|
||||||
|
mbRate = w * h * bpp * copyRate / (1024 * 1024);
|
||||||
|
|
||||||
|
if (copyTex)
|
||||||
|
printf("glCopyTexSubImage: %d x %d, %d Bpp:\n", w, h, bpp);
|
||||||
|
else
|
||||||
|
printf("glTexSubImage: %d x %d, %d Bpp:\n", w, h, bpp);
|
||||||
|
printf(" %d calls in %.2f = %.2f calls/sec, %.2f MB/s\n",
|
||||||
|
iters, t1-t0, copyRate, mbRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
Draw(void)
|
||||||
|
{
|
||||||
|
glClearColor(0.2, 0.2, 0.8, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
DrawTestImage();
|
||||||
|
if (!DrawQuad) {
|
||||||
|
glutSwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
RunTest(GL_FALSE, GL_FALSE);
|
||||||
|
RunTest(GL_FALSE, GL_TRUE);
|
||||||
|
RunTest(GL_TRUE, GL_FALSE);
|
||||||
|
RunTest(GL_TRUE, GL_TRUE);
|
||||||
|
|
||||||
|
glutSwapBuffers();
|
||||||
|
|
||||||
|
/* printf("exiting\n"); */
|
||||||
|
/* exit(0); */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
Reshape(int width, int height)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
glTranslatef(0.0, 0.0, -15.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
Key(unsigned char key, int x, int y)
|
||||||
|
{
|
||||||
|
(void) x;
|
||||||
|
(void) y;
|
||||||
|
switch (key) {
|
||||||
|
case 27:
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
SpecialKey(int key, int x, int y)
|
||||||
|
{
|
||||||
|
(void) x;
|
||||||
|
(void) y;
|
||||||
|
switch (key) {
|
||||||
|
case GLUT_KEY_UP:
|
||||||
|
break;
|
||||||
|
case GLUT_KEY_DOWN:
|
||||||
|
break;
|
||||||
|
case GLUT_KEY_LEFT:
|
||||||
|
break;
|
||||||
|
case GLUT_KEY_RIGHT:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
glutPostRedisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
Init(void)
|
||||||
|
{
|
||||||
|
/* create initial, empty teximage */
|
||||||
|
glBindTexture(GL_TEXTURE_2D, TexObj);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, IntFormat, TexWidth, TexHeight, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ParseArgs(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "-nodraw") == 0)
|
||||||
|
DrawQuad = GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
GLint mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH;
|
||||||
|
glutInit(&argc, argv);
|
||||||
|
|
||||||
|
ParseArgs(argc, argv);
|
||||||
|
|
||||||
|
glutInitWindowPosition(0, 0);
|
||||||
|
glutInitWindowSize(WinWidth, WinHeight);
|
||||||
|
glutInitDisplayMode(mode);
|
||||||
|
glutCreateWindow(argv[0]);
|
||||||
|
glutReshapeFunc(Reshape);
|
||||||
|
glutKeyboardFunc(Key);
|
||||||
|
glutSpecialFunc(SpecialKey);
|
||||||
|
glutDisplayFunc(Draw);
|
||||||
|
|
||||||
|
printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
|
||||||
|
Init();
|
||||||
|
|
||||||
|
glutMainLoop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -89,7 +89,7 @@ $(LIB_DIR)/$(LIBNAME): $(LIBNAME)
|
|||||||
depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
|
depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
|
||||||
touch depend
|
touch depend
|
||||||
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) $(ASM_SOURCES) \
|
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) $(ASM_SOURCES) \
|
||||||
> /dev/null
|
>& /dev/null
|
||||||
|
|
||||||
|
|
||||||
# Emacs tags
|
# Emacs tags
|
||||||
|
|||||||
@@ -5,33 +5,50 @@ include $(TOP)/configs/current
|
|||||||
LIBNAME = i915_dri.so
|
LIBNAME = i915_dri.so
|
||||||
|
|
||||||
DRIVER_SOURCES = \
|
DRIVER_SOURCES = \
|
||||||
|
bufmgr_fake.c \
|
||||||
|
intel_regions.c \
|
||||||
|
intel_batchbuffer.c \
|
||||||
|
intel_mipmap_tree.c \
|
||||||
|
i915_tex_layout.c \
|
||||||
|
intel_tex_image.c \
|
||||||
|
intel_tex_subimage.c \
|
||||||
|
intel_tex_copy.c \
|
||||||
|
intel_tex_validate.c \
|
||||||
|
intel_tex_format.c \
|
||||||
|
intel_tex.c \
|
||||||
|
intel_pixel.c \
|
||||||
|
intel_pixel_copy.c \
|
||||||
|
intel_pixel_read.c \
|
||||||
|
intel_pixel_draw.c \
|
||||||
|
intel_buffers.c \
|
||||||
|
intel_blit.c \
|
||||||
|
i915_tex.c \
|
||||||
|
i915_texstate.c \
|
||||||
i915_context.c \
|
i915_context.c \
|
||||||
i915_debug.c \
|
i915_debug.c \
|
||||||
i915_fragprog.c \
|
i915_fragprog.c \
|
||||||
i915_metaops.c \
|
i915_metaops.c \
|
||||||
i915_program.c \
|
i915_program.c \
|
||||||
i915_state.c \
|
i915_state.c \
|
||||||
i915_tex.c \
|
|
||||||
i915_texprog.c \
|
i915_texprog.c \
|
||||||
i915_texstate.c \
|
|
||||||
i915_vtbl.c \
|
i915_vtbl.c \
|
||||||
|
intel_context.c \
|
||||||
|
intel_ioctl.c \
|
||||||
|
intel_screen.c \
|
||||||
|
intel_span.c \
|
||||||
|
intel_state.c \
|
||||||
|
intel_tris.c
|
||||||
|
|
||||||
|
|
||||||
|
DISABLED = \
|
||||||
|
intel_render.c \
|
||||||
i830_context.c \
|
i830_context.c \
|
||||||
i830_metaops.c \
|
i830_metaops.c \
|
||||||
i830_state.c \
|
i830_state.c \
|
||||||
i830_texblend.c \
|
i830_texblend.c \
|
||||||
i830_tex.c \
|
i830_tex.c \
|
||||||
i830_texstate.c \
|
i830_texstate.c \
|
||||||
i830_vtbl.c \
|
i830_vtbl.c
|
||||||
intel_batchbuffer.c \
|
|
||||||
intel_context.c \
|
|
||||||
intel_ioctl.c \
|
|
||||||
intel_pixel.c \
|
|
||||||
intel_render.c \
|
|
||||||
intel_screen.c \
|
|
||||||
intel_span.c \
|
|
||||||
intel_state.c \
|
|
||||||
intel_tex.c \
|
|
||||||
intel_tris.c
|
|
||||||
|
|
||||||
C_SOURCES = \
|
C_SOURCES = \
|
||||||
$(COMMON_SOURCES) \
|
$(COMMON_SOURCES) \
|
||||||
|
|||||||
181
src/mesa/drivers/dri/i915/bufmgr.h
Normal file
181
src/mesa/drivers/dri/i915/bufmgr.h
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
#ifndef BUFMGR_H
|
||||||
|
#define BUFMGR_H
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
|
||||||
|
/* Note that this is destined to be external to Mesa, so don't use GL
|
||||||
|
* types like GLuint, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* The buffer manager context. Opaque.
|
||||||
|
*/
|
||||||
|
struct bufmgr;
|
||||||
|
|
||||||
|
#define BM_LIST_MAX 32
|
||||||
|
|
||||||
|
/* List of buffers to validate. Probably better managed by the client:
|
||||||
|
*/
|
||||||
|
struct bm_buffer_list {
|
||||||
|
struct {
|
||||||
|
unsigned buffer;
|
||||||
|
unsigned *offset_return;
|
||||||
|
unsigned *memtype_return;
|
||||||
|
} elem[BM_LIST_MAX];
|
||||||
|
|
||||||
|
unsigned nr;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel );
|
||||||
|
|
||||||
|
/* struct bufmgr *bmCreate( ... ); */
|
||||||
|
/* struct bufmgr *bmAttach( ... ); */
|
||||||
|
|
||||||
|
/* Define an address space. Doesn't really do anything, but the
|
||||||
|
* information could be used to validate the bmInitPool() requests.
|
||||||
|
*/
|
||||||
|
void bmInitMemType( struct bufmgr *,
|
||||||
|
unsigned mem_type,
|
||||||
|
unsigned long size );
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a pool of a given memory type, from a certain offset and a
|
||||||
|
* certain size.
|
||||||
|
*
|
||||||
|
* Also passed in is a virtual pointer to the start of the pool. This
|
||||||
|
* is useful in the faked-out version in i915 so that MapBuffer can
|
||||||
|
* return a pointer to a buffer residing in AGP space.
|
||||||
|
*
|
||||||
|
* Flags passed into a pool are inherited by all buffers allocated in
|
||||||
|
* that pool. So pools representing the static front,back,depth
|
||||||
|
* buffer allocations should have MEM_AGP|NO_UPLOAD|NO_EVICT|NO_MOVE to match
|
||||||
|
* the behaviour of the legacy allocations.
|
||||||
|
*
|
||||||
|
* Returns -1 for failure, pool number for success.
|
||||||
|
*/
|
||||||
|
int bmInitPool( struct bufmgr *,
|
||||||
|
unsigned long low_offset,
|
||||||
|
void *low_virtual,
|
||||||
|
unsigned long size,
|
||||||
|
unsigned flags);
|
||||||
|
|
||||||
|
|
||||||
|
/* Flags for validate and other calls. If both NO_UPLOAD and NO_EVICT
|
||||||
|
* are specified, ValidateBuffers is essentially a query.
|
||||||
|
*/
|
||||||
|
#define BM_MEM_LOCAL 0x1
|
||||||
|
#define BM_MEM_AGP 0x2
|
||||||
|
#define BM_MEM_VRAM 0x4 /* not yet used */
|
||||||
|
#define BM_WRITE 0x8 /* not yet used */
|
||||||
|
#define BM_READ 0x10 /* not yet used */
|
||||||
|
#define BM_NO_UPLOAD 0x20
|
||||||
|
#define BM_NO_EVICT 0x40
|
||||||
|
#define BM_NO_MOVE 0x80 /* not yet used */
|
||||||
|
#define BM_NO_ALLOC 0x100 /* legacy "fixed" buffers only */
|
||||||
|
#define BM_CLIENT 0x200 /* for map - pointer will be accessed
|
||||||
|
* without dri lock */
|
||||||
|
|
||||||
|
#define BM_MEM_MASK (BM_MEM_LOCAL|BM_MEM_AGP|BM_MEM_VRAM)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Stick closely to ARB_vbo semantics - they're well defined and
|
||||||
|
* understood, and drivers can just pass the calls through without too
|
||||||
|
* much thunking.
|
||||||
|
*/
|
||||||
|
void bmGenBuffers(struct bufmgr *, unsigned n, unsigned *buffers);
|
||||||
|
void bmDeleteBuffers(struct bufmgr *, unsigned n, unsigned *buffers);
|
||||||
|
|
||||||
|
|
||||||
|
/* Hook to inform faked buffer manager about fixed-position
|
||||||
|
* front,depth,back buffers. These may move to a fully memory-managed
|
||||||
|
* scheme, or they may continue to be managed as is.
|
||||||
|
*/
|
||||||
|
unsigned bmBufferStatic(struct bufmgr *,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned size,
|
||||||
|
unsigned pool);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The driver has more intimate knowledge of the hardare than a GL
|
||||||
|
* client would, so flags here is more proscriptive than the usage
|
||||||
|
* values in the ARB_vbo interface:
|
||||||
|
*/
|
||||||
|
void bmBufferData(struct bufmgr *,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned size,
|
||||||
|
const void *data,
|
||||||
|
unsigned flags );
|
||||||
|
|
||||||
|
void bmBufferSubData(struct bufmgr *,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned offset,
|
||||||
|
unsigned size,
|
||||||
|
const void *data );
|
||||||
|
|
||||||
|
void *bmMapBuffer( struct bufmgr *,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned access );
|
||||||
|
|
||||||
|
void bmUnmapBuffer( struct bufmgr *,
|
||||||
|
unsigned buffer );
|
||||||
|
|
||||||
|
/* To be called prior to emitting commands to hardware which reference
|
||||||
|
* these buffers.
|
||||||
|
*
|
||||||
|
* NewBufferList() and AddBuffer() build up a list of buffers to be
|
||||||
|
* validated. The buffer list provides information on where the
|
||||||
|
* buffers should be placed and whether their contents need to be
|
||||||
|
* preserved on copying. The offset data elements are return values
|
||||||
|
* from this function telling the driver exactly where the buffers are
|
||||||
|
* currently located.
|
||||||
|
*
|
||||||
|
* ValidateBufferList() performs the actual validation and returns the
|
||||||
|
* buffer pools and offsets within the pools.
|
||||||
|
*
|
||||||
|
* FenceBufferList() must be called to set fences and other
|
||||||
|
* housekeeping before unlocking after a successful call to
|
||||||
|
* ValidateBufferList(). The buffer manager knows how to emit and test
|
||||||
|
* fences directly through the drm and without callbacks to the
|
||||||
|
* driver.
|
||||||
|
*/
|
||||||
|
struct bm_buffer_list *bmNewBufferList( void );
|
||||||
|
|
||||||
|
void bmAddBuffer( struct bm_buffer_list *list,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned flags,
|
||||||
|
unsigned *pool_return,
|
||||||
|
unsigned *offset_return );
|
||||||
|
|
||||||
|
int bmValidateBufferList( struct bufmgr *,
|
||||||
|
struct bm_buffer_list *,
|
||||||
|
unsigned flags );
|
||||||
|
|
||||||
|
unsigned bmFenceBufferList( struct bufmgr *,
|
||||||
|
struct bm_buffer_list * );
|
||||||
|
|
||||||
|
void bmFreeBufferList( struct bm_buffer_list * );
|
||||||
|
|
||||||
|
|
||||||
|
/* This functionality is used by the buffer manager, not really sure
|
||||||
|
* if we need to be exposing it in this way, probably libdrm will
|
||||||
|
* offer equivalent calls.
|
||||||
|
*
|
||||||
|
* For now they can stay, but will likely change/move before final:
|
||||||
|
*/
|
||||||
|
unsigned bmSetFence( struct bufmgr * );
|
||||||
|
int bmTestFence( struct bufmgr *, unsigned fence );
|
||||||
|
void bmFinishFence( struct bufmgr *, unsigned fence );
|
||||||
|
|
||||||
|
void bmFlushReadCaches( struct bufmgr *bm );
|
||||||
|
void bmFlushDrawCache( struct bufmgr *bm );
|
||||||
|
|
||||||
|
void bm_fake_NotifyContendedLockTake( struct bufmgr * );
|
||||||
|
|
||||||
|
extern int INTEL_DEBUG;
|
||||||
|
#define DEBUG_BUFMGR 0x2000
|
||||||
|
|
||||||
|
#define DBG(...) do { if (INTEL_DEBUG & DEBUG_BUFMGR) _mesa_printf(__VA_ARGS__); } while(0)
|
||||||
|
|
||||||
|
#endif
|
||||||
858
src/mesa/drivers/dri/i915/bufmgr_fake.c
Normal file
858
src/mesa/drivers/dri/i915/bufmgr_fake.c
Normal file
@@ -0,0 +1,858 @@
|
|||||||
|
/* Fake version of the buffer manager so that we can prototype the
|
||||||
|
* changes in a driver fairly quickly. Basically wraps the old style
|
||||||
|
* memory management in the new programming interface.
|
||||||
|
*
|
||||||
|
* This version imports code from the via memory manager to closer
|
||||||
|
* approximate the behaviour of a true memory manager. In particular,
|
||||||
|
* in this version we do not expect to lose texture memory contents on
|
||||||
|
* context switches.
|
||||||
|
*/
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_ioctl.h"
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
#include "simple_list.h"
|
||||||
|
#include "mm.h"
|
||||||
|
#include "imports.h"
|
||||||
|
|
||||||
|
struct _mesa_HashTable;
|
||||||
|
|
||||||
|
static int delayed_free( struct bufmgr *bm );
|
||||||
|
|
||||||
|
#define BM_POOL_MAX 8
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrapper around mm.c's mem_block, which understands that you must
|
||||||
|
* wait for fences to expire before memory can be freed. This is
|
||||||
|
* specific to our use of memcpy for uploads - an upload that was
|
||||||
|
* processed through the command queue wouldn't need to care about
|
||||||
|
* fences.
|
||||||
|
*/
|
||||||
|
struct block {
|
||||||
|
struct block *next, *prev;
|
||||||
|
int mem_type;
|
||||||
|
struct pool *pool; /* BM_MEM_AGP */
|
||||||
|
struct mem_block *mem; /* BM_MEM_AGP */
|
||||||
|
unsigned fence; /* BM_MEM_AGP, Split to read_fence, write_fence */
|
||||||
|
void *virtual;
|
||||||
|
struct buffer *buf;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct buffer {
|
||||||
|
unsigned id; /* debug only */
|
||||||
|
unsigned size;
|
||||||
|
unsigned alignment;
|
||||||
|
unsigned mapped;
|
||||||
|
unsigned flags;
|
||||||
|
struct block *block;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pool {
|
||||||
|
unsigned flags;
|
||||||
|
struct mem_block *heap;
|
||||||
|
void *virtual;
|
||||||
|
struct block lru;
|
||||||
|
struct block freed;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bufmgr {
|
||||||
|
struct intel_context *intel;
|
||||||
|
struct pool pool[BM_POOL_MAX];
|
||||||
|
unsigned nr_pools;
|
||||||
|
|
||||||
|
struct _mesa_HashTable *hash;
|
||||||
|
|
||||||
|
unsigned buf_nr; /* for generating ids */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static struct block *alloc_from_pool( struct bufmgr *bm,
|
||||||
|
unsigned pool_nr,
|
||||||
|
unsigned size,
|
||||||
|
unsigned align )
|
||||||
|
{
|
||||||
|
struct pool *pool = &bm->pool[pool_nr];
|
||||||
|
struct block *block = (struct block *)calloc(sizeof *block, 1);
|
||||||
|
if (!block)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
DBG("alloc_from_pool %d sz 0x%x\n", pool_nr, size);
|
||||||
|
assert(align >= 7);
|
||||||
|
|
||||||
|
block->mem = mmAllocMem(pool->heap, size, align, 0);
|
||||||
|
if (!block->mem) {
|
||||||
|
DBG("\t- failed\n");
|
||||||
|
free(block);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
make_empty_list(block);
|
||||||
|
block->pool = pool;
|
||||||
|
block->mem_type = pool->flags & BM_MEM_MASK;
|
||||||
|
block->virtual = pool->virtual + block->mem->ofs;
|
||||||
|
|
||||||
|
DBG("\t- offset 0x%x\n", block->mem->ofs);
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct block *alloc_local( unsigned size )
|
||||||
|
{
|
||||||
|
struct block *block = (struct block *)calloc(sizeof *block, 1);
|
||||||
|
if (!block)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
DBG("alloc_local 0x%x\n", size);
|
||||||
|
|
||||||
|
block->mem_type = BM_MEM_LOCAL;
|
||||||
|
block->virtual = ALIGN_MALLOC(size, 1<<7);
|
||||||
|
if (!block->virtual) {
|
||||||
|
free(block);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static struct block *alloc_block( struct bufmgr *bm,
|
||||||
|
unsigned size,
|
||||||
|
unsigned align,
|
||||||
|
int flags )
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
if (!(flags & BM_CLIENT)) {
|
||||||
|
for (i = 0; i < bm->nr_pools; i++) {
|
||||||
|
struct block *block;
|
||||||
|
|
||||||
|
if (bm->pool[i].flags & BM_NO_ALLOC)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((bm->pool[i].flags & flags & BM_MEM_MASK) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
block = alloc_from_pool(bm, i, size, align);
|
||||||
|
if (block)
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & BM_MEM_LOCAL)
|
||||||
|
return alloc_local(size);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bmAllocMem( struct bufmgr *bm,
|
||||||
|
struct buffer *buf,
|
||||||
|
GLuint flags )
|
||||||
|
{
|
||||||
|
delayed_free(bm);
|
||||||
|
|
||||||
|
buf->block = alloc_block(bm,
|
||||||
|
buf->size,
|
||||||
|
buf->alignment,
|
||||||
|
buf->flags | flags);
|
||||||
|
|
||||||
|
if (buf->block)
|
||||||
|
buf->block->buf = buf;
|
||||||
|
else
|
||||||
|
_mesa_printf("bmAllocMem failed memflags %x\n", buf->flags & BM_MEM_MASK);
|
||||||
|
|
||||||
|
/* Sleep here or fail???
|
||||||
|
*/
|
||||||
|
/* assert(buf->block); */
|
||||||
|
return buf->block != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Release the card storage associated with buf:
|
||||||
|
*/
|
||||||
|
static void free_block( struct bufmgr *bm, struct block *block )
|
||||||
|
{
|
||||||
|
DBG("free block %p\n", block);
|
||||||
|
|
||||||
|
if (!block)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DBG("free block (mem: %d, sz %d) from buf %d\n",
|
||||||
|
block->mem_type,
|
||||||
|
block->buf->size,
|
||||||
|
block->buf->id);
|
||||||
|
|
||||||
|
switch (block->mem_type) {
|
||||||
|
case BM_MEM_AGP:
|
||||||
|
case BM_MEM_VRAM:
|
||||||
|
remove_from_list(block);
|
||||||
|
|
||||||
|
DBG(" - offset %x\n", block->mem->ofs);
|
||||||
|
|
||||||
|
if (bmTestFence(bm, block->fence)) {
|
||||||
|
DBG(" - free immediately\n");
|
||||||
|
mmFreeMem(block->mem);
|
||||||
|
free(block);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DBG(" - place on delayed_free list\n");
|
||||||
|
block->buf = NULL;
|
||||||
|
insert_at_tail(&block->pool->freed, block);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BM_MEM_LOCAL:
|
||||||
|
DBG(" - free local memory\n");
|
||||||
|
ALIGN_FREE(block->virtual);
|
||||||
|
free(block);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DBG(" - unknown memory type\n");
|
||||||
|
free(block);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int delayed_free( struct bufmgr *bm )
|
||||||
|
{
|
||||||
|
struct block *block, *tmp;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < bm->nr_pools; i++) {
|
||||||
|
foreach_s(block, tmp, &bm->pool[i].freed ) {
|
||||||
|
if (bmTestFence(bm, block->fence)) {
|
||||||
|
ret += block->mem->size;
|
||||||
|
remove_from_list(block);
|
||||||
|
mmFreeMem(block->mem);
|
||||||
|
free(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("%s: %d\n", __FUNCTION__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int move_buffers( struct bufmgr *bm,
|
||||||
|
struct buffer *buffers[],
|
||||||
|
int nr,
|
||||||
|
int flags )
|
||||||
|
{
|
||||||
|
struct block *newMem[BM_LIST_MAX];
|
||||||
|
GLint i;
|
||||||
|
GLuint nr_uploads = 0;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
memset(newMem, 0, sizeof(newMem));
|
||||||
|
|
||||||
|
/* First do all the allocations (or fail):
|
||||||
|
*/
|
||||||
|
for (i = 0; i < nr; i++) {
|
||||||
|
if (!buffers[i]->block) {
|
||||||
|
if (flags & BM_NO_ALLOC)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
newMem[i] = alloc_block(bm,
|
||||||
|
buffers[i]->size,
|
||||||
|
buffers[i]->alignment,
|
||||||
|
flags & BM_MEM_MASK);
|
||||||
|
|
||||||
|
if (!newMem[i])
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!(buffers[i]->block->mem_type & flags)) {
|
||||||
|
if (flags & BM_NO_UPLOAD)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
/* Known issue: this assert will get hit on texture swapping.
|
||||||
|
* There's not much to do about that at this stage - it's a
|
||||||
|
* todo item.
|
||||||
|
*/
|
||||||
|
assert(!buffers[i]->mapped);
|
||||||
|
|
||||||
|
DBG("try to move buffer %d size 0x%x to pools 0x%x\n",
|
||||||
|
buffers[i]->id, buffers[i]->size, flags & BM_MEM_MASK);
|
||||||
|
|
||||||
|
newMem[i] = alloc_block(bm,
|
||||||
|
buffers[i]->size,
|
||||||
|
buffers[i]->alignment,
|
||||||
|
flags & BM_MEM_MASK);
|
||||||
|
|
||||||
|
if (!newMem[i])
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Now copy all the image data and free the old texture memory.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < nr; i++) {
|
||||||
|
if (newMem[i]) {
|
||||||
|
if (buffers[i]->block) {
|
||||||
|
/* XXX: To be replaced with DMA, GTT bind, and other
|
||||||
|
* mechanisms in final version. Memcpy (or sse_memcpy) is
|
||||||
|
* probably pretty good for local->agp uploads.
|
||||||
|
*/
|
||||||
|
DBG("memcpy %d bytes\n", buffers[i]->size);
|
||||||
|
memcpy(newMem[i]->virtual,
|
||||||
|
buffers[i]->block->virtual,
|
||||||
|
buffers[i]->size);
|
||||||
|
|
||||||
|
free_block(bm, buffers[i]->block);
|
||||||
|
nr_uploads++;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers[i]->block = newMem[i];
|
||||||
|
buffers[i]->block->buf = buffers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell hardware that its texture and other caches may be invalid:
|
||||||
|
*/
|
||||||
|
if (nr_uploads && (flags & (BM_MEM_AGP|BM_MEM_VRAM)))
|
||||||
|
bmFlushReadCaches(bm);
|
||||||
|
|
||||||
|
DBG("%s - success\n", __FUNCTION__);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
/* Release any allocations made prior to failure:
|
||||||
|
*/
|
||||||
|
for (i = 0; i < nr; i++) {
|
||||||
|
if (newMem[i])
|
||||||
|
free_block(bm, newMem[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mesa_printf("%s - fail\n", __FUNCTION__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned evict_lru( struct bufmgr *bm,
|
||||||
|
unsigned flags)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (flags & BM_NO_EVICT)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* XXX: this is broken with >1 active pool - all the first pool
|
||||||
|
* will be evicted before starting on the second. Actually, maybe
|
||||||
|
* you want that in some situations...
|
||||||
|
*/
|
||||||
|
for (i = 0; i < bm->nr_pools; i++) {
|
||||||
|
if ((bm->pool[i].flags & flags & BM_MEM_MASK) &&
|
||||||
|
!(bm->pool[i].flags & BM_NO_EVICT)) {
|
||||||
|
struct block *block = bm->pool[i].lru.next;
|
||||||
|
unsigned size = block->buf->size;
|
||||||
|
|
||||||
|
if (block == &bm->pool[i].lru ||
|
||||||
|
!bmTestFence(bm, block->fence))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
move_buffers(bm, &block->buf, 1, BM_MEM_LOCAL);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Speculatively move texture images which haven't been used in a
|
||||||
|
* while back to local memory.
|
||||||
|
*/
|
||||||
|
static void viaSwapOutWork( struct bufmgr *bm )
|
||||||
|
{
|
||||||
|
unsigned total = 0;
|
||||||
|
unsigned target;
|
||||||
|
|
||||||
|
if (bm->thrashing) {
|
||||||
|
target = 1*1024*1024;
|
||||||
|
}
|
||||||
|
else if (bmIsTexMemLow(bm)) {
|
||||||
|
target = 64*1024;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
unsigned size = evict_lru(bm);
|
||||||
|
if (!size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
total += size;
|
||||||
|
if (total >= target)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* Public functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* The initialization functions are skewed in the fake implementation.
|
||||||
|
* This call would be to attach to an existing manager, rather than to
|
||||||
|
* create a local one.
|
||||||
|
*/
|
||||||
|
struct bufmgr *bm_fake_intel_Attach( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
struct bufmgr *bm = (struct bufmgr *)calloc(sizeof(*bm), 1);
|
||||||
|
|
||||||
|
bm->intel = intel;
|
||||||
|
bm->hash = _mesa_NewHashTable();
|
||||||
|
|
||||||
|
return bm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bmInitMemType( struct bufmgr *bm,
|
||||||
|
unsigned mem_type,
|
||||||
|
unsigned long size )
|
||||||
|
{
|
||||||
|
/* Nothing really to do. Could store and use to validate
|
||||||
|
* bmInitPool requests.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* The virtual pointer would go away in a true implementation.
|
||||||
|
*/
|
||||||
|
int bmInitPool( struct bufmgr *bm,
|
||||||
|
unsigned long low_offset,
|
||||||
|
void *low_virtual,
|
||||||
|
unsigned long size,
|
||||||
|
unsigned flags)
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
if (bm->nr_pools >= BM_POOL_MAX)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
i = bm->nr_pools++;
|
||||||
|
|
||||||
|
DBG("bmInitPool %d low_offset %x sz %x\n",
|
||||||
|
i, low_offset, size);
|
||||||
|
|
||||||
|
bm->pool[i].heap = mmInit( low_offset, size );
|
||||||
|
bm->pool[i].virtual = low_virtual - low_offset;
|
||||||
|
bm->pool[i].flags = flags;
|
||||||
|
|
||||||
|
make_empty_list(&bm->pool[i].lru);
|
||||||
|
make_empty_list(&bm->pool[i].freed);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void bmGenBuffers(struct bufmgr *bm, unsigned n, unsigned *buffers)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
struct buffer *buf = calloc(sizeof(*buf), 1);
|
||||||
|
buf->id = ++bm->buf_nr;
|
||||||
|
buf->alignment = 12; /* page-alignment to fit in with AGP swapping */
|
||||||
|
buf->flags = BM_MEM_AGP|BM_MEM_VRAM|BM_MEM_LOCAL;
|
||||||
|
buffers[i] = buf->id;
|
||||||
|
_mesa_HashInsert(bm->hash, buffers[i], buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bmDeleteBuffers(struct bufmgr *bm, unsigned n, unsigned *buffers)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
struct buffer *buf = _mesa_HashLookup(bm->hash, buffers[i]);
|
||||||
|
if (buf) {
|
||||||
|
free_block(bm, buf->block);
|
||||||
|
free(buf);
|
||||||
|
_mesa_HashRemove(bm->hash, buffers[i]);
|
||||||
|
}
|
||||||
|
assert(_mesa_HashLookup(bm->hash, buffers[i]) == NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Hook to inform faked buffer manager about fixed-position
|
||||||
|
* front,depth,back buffers. These may move to a fully memory-managed
|
||||||
|
* scheme, or they may continue to be managed as is. It will probably
|
||||||
|
* be useful to pass a fixed offset here one day.
|
||||||
|
*/
|
||||||
|
unsigned bmBufferStatic(struct bufmgr *bm,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned size,
|
||||||
|
unsigned pool )
|
||||||
|
{
|
||||||
|
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||||
|
|
||||||
|
assert(!buf->block);
|
||||||
|
assert(bm->pool[pool].flags & BM_NO_EVICT);
|
||||||
|
assert(bm->pool[pool].flags & BM_NO_MOVE);
|
||||||
|
|
||||||
|
buf->size = size;
|
||||||
|
buf->flags = bm->pool[pool].flags;
|
||||||
|
buf->alignment = 12;
|
||||||
|
buf->block = alloc_from_pool(bm, pool, buf->size, buf->alignment);
|
||||||
|
if (!buf->block)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buf->block->buf = buf;
|
||||||
|
return buf->block->mem->ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* If buffer size changes, free and reallocate. Otherwise update in
|
||||||
|
* place.
|
||||||
|
*/
|
||||||
|
void bmBufferData(struct bufmgr *bm,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned size,
|
||||||
|
const void *data,
|
||||||
|
unsigned flags )
|
||||||
|
{
|
||||||
|
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||||
|
|
||||||
|
DBG("bmBufferData %d sz 0x%x data: %p\n", buffer, size, data);
|
||||||
|
|
||||||
|
assert(!buf->mapped);
|
||||||
|
|
||||||
|
if (buf->block) {
|
||||||
|
if ((buf->block->mem_type != BM_MEM_LOCAL && !bmTestFence(bm, buf->block->fence)) ||
|
||||||
|
(buf->size && buf->size != size) ||
|
||||||
|
(data == NULL)) {
|
||||||
|
free_block(bm, buf->block);
|
||||||
|
buf->block = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->size = size;
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
bmAllocMem(bm, buf, buf->flags | flags);
|
||||||
|
memcpy(buf->block->virtual, data, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update the buffer in place, in whatever space it is currently resident:
|
||||||
|
*/
|
||||||
|
void bmBufferSubData(struct bufmgr *bm,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned offset,
|
||||||
|
unsigned size,
|
||||||
|
const void *data )
|
||||||
|
{
|
||||||
|
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||||
|
|
||||||
|
DBG("bmBufferSubdata %d offset 0x%x sz 0x%x\n", buffer, offset, size);
|
||||||
|
|
||||||
|
if (buf->block == 0)
|
||||||
|
bmAllocMem(bm, buf, buf->flags);
|
||||||
|
|
||||||
|
if (buf->block->mem_type != BM_MEM_LOCAL)
|
||||||
|
bmFinishFence(bm, buf->block->fence);
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
memcpy(buf->block->virtual + offset, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return a pointer to whatever space the buffer is currently resident in:
|
||||||
|
*/
|
||||||
|
void *bmMapBuffer( struct bufmgr *bm,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned flags )
|
||||||
|
{
|
||||||
|
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||||
|
|
||||||
|
DBG("bmMapBuffer %d\n", buffer);
|
||||||
|
|
||||||
|
if (buf->mapped)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (buf->block == 0)
|
||||||
|
bmAllocMem(bm, buf, flags);
|
||||||
|
|
||||||
|
if (buf->block == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
buf->mapped = 1;
|
||||||
|
|
||||||
|
/* Finish any outstanding operations to/from this memory:
|
||||||
|
*/
|
||||||
|
if (buf->block->mem_type != BM_MEM_LOCAL)
|
||||||
|
bmFinishFence(bm, buf->block->fence);
|
||||||
|
|
||||||
|
return buf->block->virtual;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmUnmapBuffer( struct bufmgr *bm, unsigned buffer )
|
||||||
|
{
|
||||||
|
struct buffer *buf = (struct buffer *)_mesa_HashLookup( bm->hash, buffer );
|
||||||
|
|
||||||
|
DBG("bmUnmapBuffer %d\n", buffer);
|
||||||
|
buf->mapped = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add a mechanism to tell the manager about some fixed buffers such
|
||||||
|
* as the (fixed) front, back and depth buffers. Something like this
|
||||||
|
* may be needed even in a finalized version if we keep the static
|
||||||
|
* management of these buffers.
|
||||||
|
*
|
||||||
|
* These are excluded from the buffer memory management in this file,
|
||||||
|
* but are presented to the driver by the same interface. In the
|
||||||
|
* future they may become managed.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
void bm_fake_SetFixedBufferParams( struct bufmgr *bm
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned offset,
|
||||||
|
unsigned size )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Build the list of buffers to validate:
|
||||||
|
*/
|
||||||
|
struct bm_buffer_list *bmNewBufferList( void )
|
||||||
|
{
|
||||||
|
struct bm_buffer_list *list = calloc(sizeof(*list), 1);
|
||||||
|
DBG("bmNewBufferList\n");
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmAddBuffer( struct bm_buffer_list *list,
|
||||||
|
unsigned buffer,
|
||||||
|
unsigned flags,
|
||||||
|
unsigned *memtype_return,
|
||||||
|
unsigned *offset_return )
|
||||||
|
{
|
||||||
|
assert(list->nr < BM_LIST_MAX);
|
||||||
|
|
||||||
|
|
||||||
|
list->elem[list->nr].buffer = buffer;
|
||||||
|
list->elem[list->nr].memtype_return = memtype_return;
|
||||||
|
list->elem[list->nr].offset_return = offset_return;
|
||||||
|
|
||||||
|
DBG("bmAddBuffer nr %d buf %d\n",
|
||||||
|
list->nr, buffer);
|
||||||
|
|
||||||
|
list->nr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmFreeBufferList( struct bm_buffer_list *list )
|
||||||
|
{
|
||||||
|
free(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* To be called prior to emitting commands to hardware which reference
|
||||||
|
* these buffers. The buffer_usage list provides information on where
|
||||||
|
* the buffers should be placed and whether their contents need to be
|
||||||
|
* preserved on copying. The offset and pool data elements are return
|
||||||
|
* values from this function telling the driver exactly where the
|
||||||
|
* buffers are currently located.
|
||||||
|
*/
|
||||||
|
int bmValidateBufferList( struct bufmgr *bm,
|
||||||
|
struct bm_buffer_list *list,
|
||||||
|
unsigned flags )
|
||||||
|
{
|
||||||
|
struct buffer *bufs[BM_LIST_MAX];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (list->nr > BM_LIST_MAX)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < list->nr; i++)
|
||||||
|
bufs[i] = _mesa_HashLookup(bm->hash, list->elem[i].buffer);
|
||||||
|
|
||||||
|
|
||||||
|
/* The old story: evict one texture after another until allocation
|
||||||
|
* succeeds. This is a pretty poor strategy but really hard to do
|
||||||
|
* better without more infrastucture... Which is coming - hooray!
|
||||||
|
*/
|
||||||
|
while (!move_buffers(bm, bufs, list->nr, flags)) {
|
||||||
|
if (!delayed_free(bm) &&
|
||||||
|
!evict_lru(bm, flags))
|
||||||
|
return 0;
|
||||||
|
_mesa_printf("couldn't allocate sufficient texture memory\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < list->nr; i++) {
|
||||||
|
DBG("%d: buf %d ofs 0x%x\n",
|
||||||
|
i, bufs[i]->id, bufs[i]->block->mem->ofs);
|
||||||
|
|
||||||
|
assert(!bufs[i]->mapped);
|
||||||
|
|
||||||
|
if (list->elem[i].offset_return)
|
||||||
|
list->elem[i].offset_return[0] = bufs[i]->block->mem->ofs;
|
||||||
|
|
||||||
|
if (list->elem[i].memtype_return)
|
||||||
|
list->elem[i].memtype_return[0] = bufs[i]->block->mem_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* After commands are emitted but before unlocking, this must be
|
||||||
|
* called so that the buffer manager can correctly age the buffers.
|
||||||
|
* The buffer manager keeps track of the list of validated buffers, so
|
||||||
|
* already knows what to apply the fence to.
|
||||||
|
*
|
||||||
|
* The buffer manager knows how to emit and test fences directly
|
||||||
|
* through the drm and without callbacks or whatever into the driver.
|
||||||
|
*/
|
||||||
|
unsigned bmFenceBufferList( struct bufmgr *bm, struct bm_buffer_list *list )
|
||||||
|
{
|
||||||
|
|
||||||
|
DBG("%s (%d bufs)\n", __FUNCTION__, list->nr);
|
||||||
|
|
||||||
|
if (list->nr) {
|
||||||
|
unsigned i;
|
||||||
|
unsigned fence = bmSetFence( bm );
|
||||||
|
|
||||||
|
/* Move all buffers to head of resident list and set their fences
|
||||||
|
*/
|
||||||
|
for (i = 0; i < list->nr; i++) {
|
||||||
|
struct buffer *buf = _mesa_HashLookup(bm->hash, list->elem[i].buffer);
|
||||||
|
|
||||||
|
move_to_head(&buf->block->pool->lru, buf->block);
|
||||||
|
buf->block->fence = fence;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fence;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This functionality is used by the buffer manager, not really sure
|
||||||
|
* if we need to be exposing it in this way, probably libdrm will
|
||||||
|
* offer equivalent calls.
|
||||||
|
*
|
||||||
|
* For now they can stay, but will likely change/move before final:
|
||||||
|
*/
|
||||||
|
unsigned bmSetFence( struct bufmgr *bm )
|
||||||
|
{
|
||||||
|
assert(bm->intel->locked);
|
||||||
|
|
||||||
|
return intelEmitIrqLocked( bm->intel );
|
||||||
|
}
|
||||||
|
|
||||||
|
int bmTestFence( struct bufmgr *bm, unsigned fence )
|
||||||
|
{
|
||||||
|
/* if (fence % 1024 == 0) */
|
||||||
|
/* _mesa_printf("%d %d\n", fence, bm->intel->sarea->last_dispatch); */
|
||||||
|
|
||||||
|
return fence <= bm->intel->sarea->last_dispatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bmFinishFence( struct bufmgr *bm, unsigned fence )
|
||||||
|
{
|
||||||
|
if (!bmTestFence(bm, fence))
|
||||||
|
intelWaitIrq( bm->intel, fence );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* There is a need to tell the hardware to flush various caches
|
||||||
|
* before we can start reading and writing video memory.
|
||||||
|
*
|
||||||
|
* TODO: Need a flag value to tell hardware which caches have changed?
|
||||||
|
* Who would we rely on to populate the flag?
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* If new data is uploaded/mapped to video or agp memory, need to
|
||||||
|
* flush the texture and other read caches to ensure the new version
|
||||||
|
* is picked up. Can be done immediately after the upload (ie. within
|
||||||
|
* ValidateBuffers).
|
||||||
|
*/
|
||||||
|
void bmFlushReadCaches( struct bufmgr *bm )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If a buffer which has been written to is going to be evicted, read
|
||||||
|
* by bmGetBufferData or mappped with bmMapBuffer, need to flush the
|
||||||
|
* write cache first. Probably want to make sure this happens
|
||||||
|
* immediately after the last write and before the fence (how to
|
||||||
|
* tell?). If we wait until just prior the evict/read/map, would then
|
||||||
|
* have to emit another fence and wait for the hw queue to drain to be
|
||||||
|
* sure the caches had flushed.
|
||||||
|
*
|
||||||
|
* A possible strategy:
|
||||||
|
* - every once in a while, when there is no last_draw_flush_fence outstanding,
|
||||||
|
* emit a draw-cache flush just prior to the fence.
|
||||||
|
* - note the fence (last_draw_flush_fence)
|
||||||
|
* - note the most recently retired value of last_draw_flush_fence in
|
||||||
|
* last_retired_draw_flush_fence
|
||||||
|
* - keep track of which fence each buffer is last written to in
|
||||||
|
* buffer.last_write_fence
|
||||||
|
* - on evict/read/map, check:
|
||||||
|
* - if buffer.last_write_fence > last_draw_flush_fence {
|
||||||
|
* emit_flush
|
||||||
|
* last_draw_flush_fence = emit fence
|
||||||
|
* }
|
||||||
|
* if last_write_fence > last_retired_draw_flush_fence {
|
||||||
|
* finish_fence(last_draw_flush_fence)
|
||||||
|
* last_retired_draw_flush_fence = last_draw_fence
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void bmFlushDrawCache( struct bufmgr *bm )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Specifically ignore texture memory sharing.
|
||||||
|
*/
|
||||||
|
void bm_fake_NotifyContendedLockTake( struct bufmgr *bm )
|
||||||
|
{
|
||||||
|
fprintf(stderr, "did we just lose texture memory? oh well, never mind\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ GLboolean i830CreateContext( const __GLcontextModes *mesaVis,
|
|||||||
{
|
{
|
||||||
struct dd_function_table functions;
|
struct dd_function_table functions;
|
||||||
i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context);
|
i830ContextPtr i830 = (i830ContextPtr) CALLOC_STRUCT(i830_context);
|
||||||
intelContextPtr intel = &i830->intel;
|
struct intel_context *intel = &i830->intel;
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
if (!i830) return GL_FALSE;
|
if (!i830) return GL_FALSE;
|
||||||
|
|
||||||
|
|||||||
@@ -48,10 +48,8 @@
|
|||||||
*/
|
*/
|
||||||
#define I830_DESTREG_CBUFADDR0 0
|
#define I830_DESTREG_CBUFADDR0 0
|
||||||
#define I830_DESTREG_CBUFADDR1 1
|
#define I830_DESTREG_CBUFADDR1 1
|
||||||
#define I830_DESTREG_CBUFADDR2 2
|
|
||||||
#define I830_DESTREG_DBUFADDR0 3
|
#define I830_DESTREG_DBUFADDR0 3
|
||||||
#define I830_DESTREG_DBUFADDR1 4
|
#define I830_DESTREG_DBUFADDR1 4
|
||||||
#define I830_DESTREG_DBUFADDR2 5
|
|
||||||
#define I830_DESTREG_DV0 6
|
#define I830_DESTREG_DV0 6
|
||||||
#define I830_DESTREG_DV1 7
|
#define I830_DESTREG_DV1 7
|
||||||
#define I830_DESTREG_SENABLE 8
|
#define I830_DESTREG_SENABLE 8
|
||||||
@@ -160,7 +158,7 @@ i830CreateContext( const __GLcontextModes *mesaVis,
|
|||||||
/* i830_tex.c, i830_texstate.c
|
/* i830_tex.c, i830_texstate.c
|
||||||
*/
|
*/
|
||||||
extern void
|
extern void
|
||||||
i830UpdateTextureState( intelContextPtr intel );
|
i830UpdateTextureState( struct intel_context *intel );
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
i830InitTextureFuncs( struct dd_function_table *functions );
|
i830InitTextureFuncs( struct dd_function_table *functions );
|
||||||
@@ -206,7 +204,7 @@ i830TryTextureDrawPixels( GLcontext *ctx,
|
|||||||
const GLvoid *pixels );
|
const GLvoid *pixels );
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
i830ClearWithTris( intelContextPtr intel, GLbitfield mask,
|
i830ClearWithTris( struct intel_context *intel, GLbitfield mask,
|
||||||
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
|
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ do { \
|
|||||||
* current GL state and used for other purposes than simply rendering
|
* current GL state and used for other purposes than simply rendering
|
||||||
* incoming triangles.
|
* incoming triangles.
|
||||||
*/
|
*/
|
||||||
static void set_initial_state( i830ContextPtr i830 )
|
static void set_initial_state( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) );
|
memcpy(&i830->meta, &i830->initial, sizeof(i830->meta) );
|
||||||
i830->meta.active = ACTIVE;
|
i830->meta.active = ACTIVE;
|
||||||
@@ -66,7 +66,7 @@ static void set_initial_state( i830ContextPtr i830 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_no_depth_stencil_write( i830ContextPtr i830 )
|
static void set_no_depth_stencil_write( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
|
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
|
||||||
*/
|
*/
|
||||||
@@ -88,7 +88,7 @@ static void set_no_depth_stencil_write( i830ContextPtr i830 )
|
|||||||
|
|
||||||
/* Set stencil unit to replace always with the reference value.
|
/* Set stencil unit to replace always with the reference value.
|
||||||
*/
|
*/
|
||||||
static void set_stencil_replace( i830ContextPtr i830,
|
static void set_stencil_replace( struct intel_context *intel,
|
||||||
GLuint s_mask,
|
GLuint s_mask,
|
||||||
GLuint s_clear)
|
GLuint s_clear)
|
||||||
{
|
{
|
||||||
@@ -140,7 +140,7 @@ static void set_stencil_replace( i830ContextPtr i830,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_color_mask( i830ContextPtr i830, GLboolean state )
|
static void set_color_mask( struct intel_context *intel, GLboolean state )
|
||||||
{
|
{
|
||||||
const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) |
|
const GLuint mask = ((1 << WRITEMASK_RED_SHIFT) |
|
||||||
(1 << WRITEMASK_GREEN_SHIFT) |
|
(1 << WRITEMASK_GREEN_SHIFT) |
|
||||||
@@ -161,7 +161,7 @@ static void set_color_mask( i830ContextPtr i830, GLboolean state )
|
|||||||
/* Installs a one-stage passthrough texture blend pipeline. Is there
|
/* Installs a one-stage passthrough texture blend pipeline. Is there
|
||||||
* more that can be done to turn off texturing?
|
* more that can be done to turn off texturing?
|
||||||
*/
|
*/
|
||||||
static void set_no_texture( i830ContextPtr i830 )
|
static void set_no_texture( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
static const struct gl_tex_env_combine_state comb = {
|
static const struct gl_tex_env_combine_state comb = {
|
||||||
GL_NONE, GL_NONE,
|
GL_NONE, GL_NONE,
|
||||||
@@ -181,7 +181,7 @@ static void set_no_texture( i830ContextPtr i830 )
|
|||||||
/* Set up a single element blend stage for 'replace' texturing with no
|
/* Set up a single element blend stage for 'replace' texturing with no
|
||||||
* funny ops.
|
* funny ops.
|
||||||
*/
|
*/
|
||||||
static void enable_texture_blend_replace( i830ContextPtr i830,
|
static void enable_texture_blend_replace( struct intel_context *intel,
|
||||||
GLenum format )
|
GLenum format )
|
||||||
{
|
{
|
||||||
static const struct gl_tex_env_combine_state comb = {
|
static const struct gl_tex_env_combine_state comb = {
|
||||||
@@ -207,7 +207,7 @@ static void enable_texture_blend_replace( i830ContextPtr i830,
|
|||||||
/* Set up an arbitary piece of memory as a rectangular texture
|
/* Set up an arbitary piece of memory as a rectangular texture
|
||||||
* (including the front or back buffer).
|
* (including the front or back buffer).
|
||||||
*/
|
*/
|
||||||
static void set_tex_rect_source( i830ContextPtr i830,
|
static void set_tex_rect_source( struct intel_context *intel,
|
||||||
GLuint offset,
|
GLuint offset,
|
||||||
GLuint width,
|
GLuint width,
|
||||||
GLuint height,
|
GLuint height,
|
||||||
@@ -249,17 +249,17 @@ static void set_tex_rect_source( i830ContextPtr i830,
|
|||||||
|
|
||||||
/* Select between front and back draw buffers.
|
/* Select between front and back draw buffers.
|
||||||
*/
|
*/
|
||||||
static void set_draw_offset( i830ContextPtr i830,
|
static void set_draw_offset( struct intel_context *intel,
|
||||||
GLuint offset )
|
GLuint offset )
|
||||||
{
|
{
|
||||||
i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset;
|
/* i830->meta.Buffer[I830_DESTREG_CBUFADDR2] = offset; */
|
||||||
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
|
i830->meta.emitted &= ~I830_UPLOAD_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup an arbitary draw format, useful for targeting
|
/* Setup an arbitary draw format, useful for targeting
|
||||||
* texture or agp memory.
|
* texture or agp memory.
|
||||||
*/
|
*/
|
||||||
static void set_draw_format( i830ContextPtr i830,
|
static void set_draw_format( struct intel_context *intel,
|
||||||
GLuint format,
|
GLuint format,
|
||||||
GLuint depth_format)
|
GLuint depth_format)
|
||||||
{
|
{
|
||||||
@@ -271,7 +271,7 @@ static void set_draw_format( i830ContextPtr i830,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_vertex_format( i830ContextPtr i830 )
|
static void set_vertex_format( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD |
|
i830->meta.Ctx[I830_CTXREG_VF] = (_3DSTATE_VFT0_CMD |
|
||||||
VFT0_TEX_COUNT(1) |
|
VFT0_TEX_COUNT(1) |
|
||||||
@@ -287,446 +287,6 @@ static void set_vertex_format( i830ContextPtr i830 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void draw_quad(i830ContextPtr i830,
|
|
||||||
GLfloat x0, GLfloat x1,
|
|
||||||
GLfloat y0, GLfloat y1,
|
|
||||||
GLubyte red, GLubyte green,
|
|
||||||
GLubyte blue, GLubyte alpha,
|
|
||||||
GLfloat s0, GLfloat s1,
|
|
||||||
GLfloat t0, GLfloat t1 )
|
|
||||||
{
|
|
||||||
GLuint vertex_size = 8;
|
|
||||||
GLuint *vb = intelEmitInlinePrimitiveLocked( &i830->intel,
|
|
||||||
PRIM3D_TRIFAN,
|
|
||||||
4*vertex_size,
|
|
||||||
vertex_size );
|
|
||||||
intelVertex tmp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
|
|
||||||
/* fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n", */
|
|
||||||
/* __FUNCTION__, */
|
|
||||||
/* x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1); */
|
|
||||||
|
|
||||||
|
|
||||||
/* initial vertex, left bottom */
|
|
||||||
tmp.v.x = x0;
|
|
||||||
tmp.v.y = y0;
|
|
||||||
tmp.v.z = 1.0;
|
|
||||||
tmp.v.w = 1.0;
|
|
||||||
tmp.v.color.red = red;
|
|
||||||
tmp.v.color.green = green;
|
|
||||||
tmp.v.color.blue = blue;
|
|
||||||
tmp.v.color.alpha = alpha;
|
|
||||||
tmp.v.specular.red = 0;
|
|
||||||
tmp.v.specular.green = 0;
|
|
||||||
tmp.v.specular.blue = 0;
|
|
||||||
tmp.v.specular.alpha = 0;
|
|
||||||
tmp.v.u0 = s0;
|
|
||||||
tmp.v.v0 = t0;
|
|
||||||
for (i = 0 ; i < 8 ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* right bottom */
|
|
||||||
vb += 8;
|
|
||||||
tmp.v.x = x1;
|
|
||||||
tmp.v.u0 = s1;
|
|
||||||
for (i = 0 ; i < 8 ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* right top */
|
|
||||||
vb += 8;
|
|
||||||
tmp.v.y = y1;
|
|
||||||
tmp.v.v0 = t1;
|
|
||||||
for (i = 0 ; i < 8 ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* left top */
|
|
||||||
vb += 8;
|
|
||||||
tmp.v.x = x0;
|
|
||||||
tmp.v.u0 = s0;
|
|
||||||
for (i = 0 ; i < 8 ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* fprintf(stderr, "%s: DV1: %x\n", */
|
|
||||||
/* __FUNCTION__, i830->meta.Buffer[I830_DESTREG_DV1]); */
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
i830ClearWithTris(intelContextPtr intel, GLbitfield mask,
|
|
||||||
GLboolean all,
|
|
||||||
GLint cx, GLint cy, GLint cw, GLint ch)
|
|
||||||
{
|
|
||||||
i830ContextPtr i830 = I830_CONTEXT( intel );
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
intelScreenPrivate *screen = intel->intelScreen;
|
|
||||||
int x0, y0, x1, y1;
|
|
||||||
|
|
||||||
|
|
||||||
SET_STATE( i830, meta );
|
|
||||||
set_initial_state( i830 );
|
|
||||||
set_no_texture( i830 );
|
|
||||||
set_vertex_format( i830 );
|
|
||||||
|
|
||||||
LOCK_HARDWARE(intel);
|
|
||||||
|
|
||||||
if(!all) {
|
|
||||||
x0 = cx;
|
|
||||||
y0 = cy;
|
|
||||||
x1 = x0 + cw;
|
|
||||||
y1 = y0 + ch;
|
|
||||||
} else {
|
|
||||||
x0 = 0;
|
|
||||||
y0 = 0;
|
|
||||||
x1 = x0 + dPriv->w;
|
|
||||||
y1 = y0 + dPriv->h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't do any clipping to screen - these are window coordinates.
|
|
||||||
* The active cliprects will be applied as for any other geometry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(mask & BUFFER_BIT_FRONT_LEFT) {
|
|
||||||
set_no_depth_stencil_write( i830 );
|
|
||||||
set_color_mask( i830, GL_TRUE );
|
|
||||||
set_draw_offset( i830, screen->front.offset );
|
|
||||||
draw_quad(i830, x0, x1, y0, y1,
|
|
||||||
intel->clear_red, intel->clear_green,
|
|
||||||
intel->clear_blue, intel->clear_alpha,
|
|
||||||
0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mask & BUFFER_BIT_BACK_LEFT) {
|
|
||||||
set_no_depth_stencil_write( i830 );
|
|
||||||
set_color_mask( i830, GL_TRUE );
|
|
||||||
set_draw_offset( i830, screen->back.offset );
|
|
||||||
|
|
||||||
draw_quad(i830, x0, x1, y0, y1,
|
|
||||||
intel->clear_red, intel->clear_green,
|
|
||||||
intel->clear_blue, intel->clear_alpha,
|
|
||||||
0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mask & BUFFER_BIT_STENCIL) {
|
|
||||||
set_stencil_replace( i830,
|
|
||||||
intel->ctx.Stencil.WriteMask[0],
|
|
||||||
intel->ctx.Stencil.Clear);
|
|
||||||
|
|
||||||
set_color_mask( i830, GL_FALSE );
|
|
||||||
set_draw_offset( i830, screen->front.offset );
|
|
||||||
draw_quad( i830, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
|
|
||||||
SET_STATE( i830, state );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLboolean
|
|
||||||
i830TryTextureReadPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *pack,
|
|
||||||
GLvoid *pixels )
|
|
||||||
{
|
|
||||||
i830ContextPtr i830 = I830_CONTEXT(ctx);
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
intelScreenPrivate *screen = i830->intel.intelScreen;
|
|
||||||
GLint pitch = pack->RowLength ? pack->RowLength : width;
|
|
||||||
__DRIdrawablePrivate *dPriv = i830->intel.driDrawable;
|
|
||||||
int textureFormat;
|
|
||||||
GLenum glTextureFormat;
|
|
||||||
int src_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
|
|
||||||
int destOffset = intelAgpOffsetFromVirtual( &i830->intel, pixels);
|
|
||||||
int destFormat, depthFormat, destPitch;
|
|
||||||
drm_clip_rect_t tmp;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
|
|
||||||
if ( ctx->_ImageTransferState ||
|
|
||||||
pack->SwapBytes ||
|
|
||||||
pack->LsbFirst ||
|
|
||||||
!pack->Invert) {
|
|
||||||
fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (screen->fbFormat) {
|
|
||||||
case DV_PF_565:
|
|
||||||
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
|
|
||||||
glTextureFormat = GL_RGB;
|
|
||||||
break;
|
|
||||||
case DV_PF_555:
|
|
||||||
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
|
|
||||||
glTextureFormat = GL_RGBA;
|
|
||||||
break;
|
|
||||||
case DV_PF_8888:
|
|
||||||
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
|
|
||||||
glTextureFormat = GL_RGBA;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "%s: textureFormat failed %x\n", __FUNCTION__,
|
|
||||||
screen->fbFormat);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case GL_UNSIGNED_SHORT_5_6_5:
|
|
||||||
if (format != GL_RGB) return GL_FALSE;
|
|
||||||
destFormat = COLR_BUF_RGB565;
|
|
||||||
depthFormat = DEPTH_FRMT_16_FIXED;
|
|
||||||
destPitch = pitch * 2;
|
|
||||||
break;
|
|
||||||
case GL_UNSIGNED_INT_8_8_8_8_REV:
|
|
||||||
if (format != GL_BGRA) return GL_FALSE;
|
|
||||||
destFormat = COLR_BUF_ARGB8888;
|
|
||||||
depthFormat = DEPTH_FRMT_24_FIXED_8_OTHER;
|
|
||||||
destPitch = pitch * 4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "%s: destFormat failed %s\n", __FUNCTION__,
|
|
||||||
_mesa_lookup_enum_by_nr(type));
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
destFormat |= (0x02<<24);
|
|
||||||
|
|
||||||
/* fprintf(stderr, "type: %s destFormat: %x\n", */
|
|
||||||
/* _mesa_lookup_enum_by_nr(type), */
|
|
||||||
/* destFormat); */
|
|
||||||
|
|
||||||
intelFlush( ctx );
|
|
||||||
|
|
||||||
SET_STATE( i830, meta );
|
|
||||||
set_initial_state( i830 );
|
|
||||||
set_no_depth_stencil_write( i830 );
|
|
||||||
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
{
|
|
||||||
intelWaitForIdle( intel ); /* required by GL */
|
|
||||||
|
|
||||||
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
SET_STATE(i830, state);
|
|
||||||
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* FIXME -- Just emit the correct state
|
|
||||||
*/
|
|
||||||
if (i830SetParam(i830->driFd, I830_SETPARAM_CBUFFER_PITCH,
|
|
||||||
destPitch) != 0) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
SET_STATE(i830, state);
|
|
||||||
fprintf(stderr, "%s: setparam failed\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
y = dPriv->h - y - height;
|
|
||||||
x += dPriv->x;
|
|
||||||
y += dPriv->y;
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the frontbuffer up as a large rectangular texture.
|
|
||||||
*/
|
|
||||||
set_tex_rect_source( i830,
|
|
||||||
src_offset,
|
|
||||||
screen->width,
|
|
||||||
screen->height,
|
|
||||||
screen->front.pitch,
|
|
||||||
textureFormat );
|
|
||||||
|
|
||||||
|
|
||||||
enable_texture_blend_replace( i830, glTextureFormat );
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the 3d engine to draw into the agp memory
|
|
||||||
*/
|
|
||||||
|
|
||||||
set_draw_offset( i830, destOffset );
|
|
||||||
set_draw_format( i830, destFormat, depthFormat );
|
|
||||||
|
|
||||||
|
|
||||||
/* Draw a single quad, no cliprects:
|
|
||||||
*/
|
|
||||||
i830->intel.numClipRects = 1;
|
|
||||||
i830->intel.pClipRects = &tmp;
|
|
||||||
i830->intel.pClipRects[0].x1 = 0;
|
|
||||||
i830->intel.pClipRects[0].y1 = 0;
|
|
||||||
i830->intel.pClipRects[0].x2 = width;
|
|
||||||
i830->intel.pClipRects[0].y2 = height;
|
|
||||||
|
|
||||||
draw_quad( i830,
|
|
||||||
0, width, 0, height,
|
|
||||||
0, 255, 0, 0,
|
|
||||||
x, x+width, y, y+height );
|
|
||||||
|
|
||||||
intelWindowMoved( intel );
|
|
||||||
}
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
intelFinish( ctx ); /* required by GL */
|
|
||||||
|
|
||||||
SET_STATE( i830, state );
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLboolean
|
|
||||||
i830TryTextureDrawPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *unpack,
|
|
||||||
const GLvoid *pixels )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
i830ContextPtr i830 = I830_CONTEXT(ctx);
|
|
||||||
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
int textureFormat;
|
|
||||||
GLenum glTextureFormat;
|
|
||||||
int dst_offset = i830->meta.Buffer[I830_DESTREG_CBUFADDR2];
|
|
||||||
int src_offset = intelAgpOffsetFromVirtual( intel, pixels );
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
/* Todo -- upload images that aren't in agp space, then texture
|
|
||||||
* from them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ( !intelIsAgpMemory( intel, pixels, pitch*height ) ) {
|
|
||||||
fprintf(stderr, "%s: intelIsAgpMemory failed\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Todo -- don't want to clobber all the drawing state like we do
|
|
||||||
* for readpixels -- most of this state can be handled just fine.
|
|
||||||
*/
|
|
||||||
if ( ctx->_ImageTransferState ||
|
|
||||||
unpack->SwapBytes ||
|
|
||||||
unpack->LsbFirst ||
|
|
||||||
ctx->Color.AlphaEnabled ||
|
|
||||||
ctx->Depth.Test ||
|
|
||||||
ctx->Fog.Enabled ||
|
|
||||||
ctx->Scissor.Enabled ||
|
|
||||||
ctx->Stencil.Enabled ||
|
|
||||||
!ctx->Color.ColorMask[0] ||
|
|
||||||
!ctx->Color.ColorMask[1] ||
|
|
||||||
!ctx->Color.ColorMask[2] ||
|
|
||||||
!ctx->Color.ColorMask[3] ||
|
|
||||||
ctx->Color.ColorLogicOpEnabled ||
|
|
||||||
ctx->Texture._EnabledUnits) {
|
|
||||||
fprintf(stderr, "%s: other tests failed\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Todo -- remove these restrictions:
|
|
||||||
*/
|
|
||||||
if (ctx->Pixel.ZoomX != 1.0F ||
|
|
||||||
ctx->Pixel.ZoomY != -1.0F)
|
|
||||||
return GL_FALSE;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
|
|
||||||
if (format != GL_BGRA) return GL_FALSE;
|
|
||||||
textureFormat = MAPSURF_16BIT | MT_16BIT_ARGB1555;
|
|
||||||
glTextureFormat = GL_RGBA;
|
|
||||||
break;
|
|
||||||
case GL_UNSIGNED_SHORT_5_6_5:
|
|
||||||
if (format != GL_RGB) return GL_FALSE;
|
|
||||||
textureFormat = MAPSURF_16BIT | MT_16BIT_RGB565;
|
|
||||||
glTextureFormat = GL_RGB;
|
|
||||||
break;
|
|
||||||
case GL_UNSIGNED_SHORT_8_8_MESA:
|
|
||||||
if (format != GL_YCBCR_MESA) return GL_FALSE;
|
|
||||||
textureFormat = (MAPSURF_422 | MT_422_YCRCB_SWAPY
|
|
||||||
/* | TM0S1_COLORSPACE_CONVERSION */
|
|
||||||
);
|
|
||||||
glTextureFormat = GL_YCBCR_MESA;
|
|
||||||
break;
|
|
||||||
case GL_UNSIGNED_SHORT_8_8_REV_MESA:
|
|
||||||
if (format != GL_YCBCR_MESA) return GL_FALSE;
|
|
||||||
textureFormat = (MAPSURF_422 | MT_422_YCRCB_NORMAL
|
|
||||||
/* | TM0S1_COLORSPACE_CONVERSION */
|
|
||||||
);
|
|
||||||
glTextureFormat = GL_YCBCR_MESA;
|
|
||||||
break;
|
|
||||||
case GL_UNSIGNED_INT_8_8_8_8_REV:
|
|
||||||
if (format != GL_BGRA) return GL_FALSE;
|
|
||||||
textureFormat = MAPSURF_32BIT | MT_32BIT_ARGB8888;
|
|
||||||
glTextureFormat = GL_RGBA;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "%s: destFormat failed\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
intelFlush( ctx );
|
|
||||||
|
|
||||||
SET_STATE( i830, meta );
|
|
||||||
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
{
|
|
||||||
intelWaitForIdle( intel ); /* required by GL */
|
|
||||||
|
|
||||||
y -= height; /* cope with pixel zoom */
|
|
||||||
|
|
||||||
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
SET_STATE(i830, state);
|
|
||||||
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
y = dPriv->h - y - height;
|
|
||||||
|
|
||||||
set_initial_state( i830 );
|
|
||||||
|
|
||||||
/* Set the pixel image up as a rectangular texture.
|
|
||||||
*/
|
|
||||||
set_tex_rect_source( i830,
|
|
||||||
src_offset,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
pitch, /* XXXX!!!! -- /2 sometimes */
|
|
||||||
textureFormat );
|
|
||||||
|
|
||||||
|
|
||||||
enable_texture_blend_replace( i830, glTextureFormat );
|
|
||||||
|
|
||||||
|
|
||||||
/* Draw to the current draw buffer:
|
|
||||||
*/
|
|
||||||
set_draw_offset( i830, dst_offset );
|
|
||||||
|
|
||||||
/* Draw a quad, use regular cliprects
|
|
||||||
*/
|
|
||||||
/* fprintf(stderr, "x: %d y: %d width %d height %d\n", x, y, width, height); */
|
|
||||||
|
|
||||||
draw_quad( i830,
|
|
||||||
x, x+width, y, y+height,
|
|
||||||
0, 255, 0, 0,
|
|
||||||
0, width, 0, height );
|
|
||||||
|
|
||||||
intelWindowMoved( intel );
|
|
||||||
}
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
intelFinish( ctx ); /* required by GL */
|
|
||||||
|
|
||||||
SET_STATE(i830, state);
|
|
||||||
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -407,10 +407,10 @@
|
|||||||
#define LOGICOP_SET 0xf
|
#define LOGICOP_SET 0xf
|
||||||
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
|
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
|
||||||
#define ENABLE_STENCIL_TEST_MASK (1<<17)
|
#define ENABLE_STENCIL_TEST_MASK (1<<17)
|
||||||
#define STENCIL_TEST_MASK(x) ((x)<<8)
|
#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8)
|
||||||
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
|
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
|
||||||
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
|
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
|
||||||
#define STENCIL_WRITE_MASK(x) (x)
|
#define STENCIL_WRITE_MASK(x) ((x)&0xff)
|
||||||
|
|
||||||
/* _3DSTATE_MODES_5, p196 */
|
/* _3DSTATE_MODES_5, p196 */
|
||||||
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
|
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
|
||||||
|
|||||||
@@ -1012,13 +1012,12 @@ static void i830_init_packets( i830ContextPtr i830 )
|
|||||||
(BUF_3D_ID_DEPTH |
|
(BUF_3D_ID_DEPTH |
|
||||||
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
|
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
|
||||||
BUF_3D_USE_FENCE);
|
BUF_3D_USE_FENCE);
|
||||||
i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset;
|
/* i830->state.Buffer[I830_DESTREG_DBUFADDR2] = screen->depth.offset; */
|
||||||
|
|
||||||
|
|
||||||
i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
|
i830->state.Buffer[I830_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
|
||||||
|
|
||||||
switch (screen->fbFormat) {
|
switch (screen->fbFormat) {
|
||||||
case DV_PF_555:
|
|
||||||
case DV_PF_565:
|
case DV_PF_565:
|
||||||
i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
|
i830->state.Buffer[I830_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
|
||||||
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ intelTextureObjectPtr i830AllocTexObj( struct gl_texture_object *texObj )
|
|||||||
|
|
||||||
texObj->DriverData = t;
|
texObj->DriverData = t;
|
||||||
t->intel.base.tObj = texObj;
|
t->intel.base.tObj = texObj;
|
||||||
t->intel.dirty = I830_UPLOAD_TEX_ALL;
|
t->intel.dirty = ~0;
|
||||||
make_empty_list( &t->intel.base );
|
make_empty_list( &t->intel.base );
|
||||||
|
|
||||||
t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */
|
t->Setup[I830_TEXREG_TM0LI] = 0; /* not used */
|
||||||
@@ -268,7 +268,7 @@ static void i830TexParameter( GLcontext *ctx, GLenum target,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
t->intel.dirty = I830_UPLOAD_TEX_ALL;
|
t->intel.dirty = ~0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ static GLuint emit_factor( GLuint blendUnit, GLuint *state, GLuint count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline__ GLuint GetTexelOp(GLint unit)
|
static inline GLuint GetTexelOp(GLint unit)
|
||||||
{
|
{
|
||||||
switch(unit) {
|
switch(unit) {
|
||||||
case 0: return TEXBLENDARG_TEXEL0;
|
case 0: return TEXBLENDARG_TEXEL0;
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ static GLboolean i830SetTexImages( i830ContextPtr i830,
|
|||||||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
|
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MAX_MIP_MASK;
|
||||||
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
|
t->Setup[I830_TEXREG_TM0S3] &= ~TM0S3_MIN_MIP_MASK;
|
||||||
t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
|
t->Setup[I830_TEXREG_TM0S3] |= ((numLevels - 1)*4) << TM0S3_MIN_MIP_SHIFT;
|
||||||
t->intel.dirty = I830_UPLOAD_TEX_ALL;
|
t->intel.dirty = ~0;
|
||||||
|
|
||||||
return intelUploadTexImages( &i830->intel, &t->intel, 0 );
|
return intelUploadTexImages( &i830->intel, &t->intel, 0 );
|
||||||
}
|
}
|
||||||
@@ -259,11 +259,7 @@ static void i830_import_tex_unit( i830ContextPtr i830,
|
|||||||
if(INTEL_DEBUG&DEBUG_TEXTURE)
|
if(INTEL_DEBUG&DEBUG_TEXTURE)
|
||||||
fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
|
fprintf(stderr, "%s unit(%d)\n", __FUNCTION__, unit);
|
||||||
|
|
||||||
if (i830->intel.CurrentTexObj[unit])
|
|
||||||
i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << unit);
|
|
||||||
|
|
||||||
i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
|
i830->intel.CurrentTexObj[unit] = (intelTextureObjectPtr)t;
|
||||||
t->intel.base.bound |= (1 << unit);
|
|
||||||
|
|
||||||
I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) );
|
I830_STATECHANGE( i830, I830_UPLOAD_TEX(unit) );
|
||||||
|
|
||||||
@@ -285,7 +281,7 @@ static void i830_import_tex_unit( i830ContextPtr i830,
|
|||||||
i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE];
|
i830->state.Tex[unit][I830_TEXREG_CUBE] = t->Setup[I830_TEXREG_CUBE];
|
||||||
i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit);
|
i830->state.Tex[unit][I830_TEXREG_MCS] |= MAP_UNIT(unit);
|
||||||
|
|
||||||
t->intel.dirty &= ~I830_UPLOAD_TEX(unit);
|
t->intel.dirty &= ~(1<<unit); /* This is broken! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -317,7 +313,7 @@ static GLboolean enable_tex_common( GLcontext *ctx, GLuint unit )
|
|||||||
* time.
|
* time.
|
||||||
*/
|
*/
|
||||||
if (i830->intel.CurrentTexObj[unit] != &t->intel ||
|
if (i830->intel.CurrentTexObj[unit] != &t->intel ||
|
||||||
(t->intel.dirty & I830_UPLOAD_TEX(unit))) {
|
(t->intel.dirty & (1<<unit))) {
|
||||||
i830_import_tex_unit( i830, t, unit);
|
i830_import_tex_unit( i830, t, unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -419,14 +415,10 @@ static GLboolean disable_tex( GLcontext *ctx, GLuint unit )
|
|||||||
* one if nothing is enabled.
|
* one if nothing is enabled.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( i830->intel.CurrentTexObj[unit] != NULL ) {
|
/* The old texture is no longer bound to this texture unit.
|
||||||
/* The old texture is no longer bound to this texture unit.
|
* Mark it as such.
|
||||||
* Mark it as such.
|
*/
|
||||||
*/
|
i830->intel.CurrentTexObj[unit] = NULL;
|
||||||
|
|
||||||
i830->intel.CurrentTexObj[unit]->base.bound &= ~(1U << 0);
|
|
||||||
i830->intel.CurrentTexObj[unit] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
@@ -436,7 +428,7 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
|
|||||||
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
|
||||||
|
|
||||||
if (texUnit->_ReallyEnabled &&
|
if (texUnit->_ReallyEnabled &&
|
||||||
INTEL_CONTEXT(ctx)->intelScreen->tex.size < 2048 * 1024)
|
intel_context(ctx)->intelScreen->tex.size < 2048 * 1024)
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
switch(texUnit->_ReallyEnabled) {
|
switch(texUnit->_ReallyEnabled) {
|
||||||
@@ -458,7 +450,7 @@ static GLboolean i830UpdateTexUnit( GLcontext *ctx, GLuint unit )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i830UpdateTextureState( intelContextPtr intel )
|
void i830UpdateTextureState( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
i830ContextPtr i830 = I830_CONTEXT(intel);
|
i830ContextPtr i830 = I830_CONTEXT(intel);
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
#include "tnl/t_context.h"
|
#include "tnl/t_context.h"
|
||||||
#include "tnl/t_vertex.h"
|
#include "tnl/t_vertex.h"
|
||||||
|
|
||||||
static GLboolean i830_check_vertex_size( intelContextPtr intel,
|
static GLboolean i830_check_vertex_size( struct intel_context *intel,
|
||||||
GLuint expected );
|
GLuint expected );
|
||||||
|
|
||||||
#define SZ_TO_HW(sz) ((sz-2)&0x3)
|
#define SZ_TO_HW(sz) ((sz-2)&0x3)
|
||||||
@@ -59,7 +59,7 @@ do { \
|
|||||||
#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2))
|
#define VRTX_TEX_SET_FMT(n, x) ((x)<<((n)*2))
|
||||||
#define TEXBIND_SET(n, x) ((x)<<((n)*4))
|
#define TEXBIND_SET(n, x) ((x)<<((n)*4))
|
||||||
|
|
||||||
static void i830_render_start( intelContextPtr intel )
|
static void i830_render_start( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
i830ContextPtr i830 = I830_CONTEXT(intel);
|
i830ContextPtr i830 = I830_CONTEXT(intel);
|
||||||
@@ -186,7 +186,7 @@ static void i830_render_start( intelContextPtr intel )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i830_reduced_primitive_state( intelContextPtr intel,
|
static void i830_reduced_primitive_state( struct intel_context *intel,
|
||||||
GLenum rprim )
|
GLenum rprim )
|
||||||
{
|
{
|
||||||
i830ContextPtr i830 = I830_CONTEXT(intel);
|
i830ContextPtr i830 = I830_CONTEXT(intel);
|
||||||
@@ -217,7 +217,7 @@ static void i830_reduced_primitive_state( intelContextPtr intel,
|
|||||||
/* Pull apart the vertex format registers and figure out how large a
|
/* Pull apart the vertex format registers and figure out how large a
|
||||||
* vertex is supposed to be.
|
* vertex is supposed to be.
|
||||||
*/
|
*/
|
||||||
static GLboolean i830_check_vertex_size( intelContextPtr intel,
|
static GLboolean i830_check_vertex_size( struct intel_context *intel,
|
||||||
GLuint expected )
|
GLuint expected )
|
||||||
{
|
{
|
||||||
i830ContextPtr i830 = I830_CONTEXT(intel);
|
i830ContextPtr i830 = I830_CONTEXT(intel);
|
||||||
@@ -257,11 +257,11 @@ static GLboolean i830_check_vertex_size( intelContextPtr intel,
|
|||||||
return sz == expected;
|
return sz == expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i830_emit_invarient_state( intelContextPtr intel )
|
static void i830_emit_invarient_state( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
BATCH_LOCALS;
|
BATCH_LOCALS;
|
||||||
|
|
||||||
BEGIN_BATCH( 200 );
|
BEGIN_BATCH(200, 0);
|
||||||
|
|
||||||
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
|
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(0));
|
||||||
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
|
OUT_BATCH(_3DSTATE_MAP_CUBE | MAP_UNIT(1));
|
||||||
@@ -355,7 +355,7 @@ static void i830_emit_invarient_state( intelContextPtr intel )
|
|||||||
#define emit( intel, state, size ) \
|
#define emit( intel, state, size ) \
|
||||||
do { \
|
do { \
|
||||||
int k; \
|
int k; \
|
||||||
BEGIN_BATCH( size / sizeof(GLuint)); \
|
BEGIN_BATCH(size / sizeof(GLuint), 0); \
|
||||||
for (k = 0 ; k < size / sizeof(GLuint) ; k++) \
|
for (k = 0 ; k < size / sizeof(GLuint) ; k++) \
|
||||||
OUT_BATCH(state[k]); \
|
OUT_BATCH(state[k]); \
|
||||||
ADVANCE_BATCH(); \
|
ADVANCE_BATCH(); \
|
||||||
@@ -364,7 +364,7 @@ do { \
|
|||||||
|
|
||||||
/* Push the state into the sarea and/or texture memory.
|
/* Push the state into the sarea and/or texture memory.
|
||||||
*/
|
*/
|
||||||
static void i830_emit_state( intelContextPtr intel )
|
static void i830_emit_state( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
i830ContextPtr i830 = I830_CONTEXT(intel);
|
i830ContextPtr i830 = I830_CONTEXT(intel);
|
||||||
struct i830_hw_state *state = i830->current;
|
struct i830_hw_state *state = i830->current;
|
||||||
@@ -405,32 +405,32 @@ static void i830_emit_state( intelContextPtr intel )
|
|||||||
state->emitted |= dirty;
|
state->emitted |= dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i830_destroy_context( intelContextPtr intel )
|
static void i830_destroy_context( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
_tnl_free_vertices(&intel->ctx);
|
_tnl_free_vertices(&intel->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i830_set_draw_offset( intelContextPtr intel, int offset )
|
static void i830_set_draw_offset( struct intel_context *intel, int offset )
|
||||||
{
|
{
|
||||||
i830ContextPtr i830 = I830_CONTEXT(intel);
|
i830ContextPtr i830 = I830_CONTEXT(intel);
|
||||||
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
|
I830_STATECHANGE( i830, I830_UPLOAD_BUFFERS );
|
||||||
i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset;
|
/* i830->state.Buffer[I830_DESTREG_CBUFADDR2] = offset; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This isn't really handled at the moment.
|
/* This isn't really handled at the moment.
|
||||||
*/
|
*/
|
||||||
static void i830_lost_hardware( intelContextPtr intel )
|
static void i830_lost_hardware( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
I830_CONTEXT(intel)->state.emitted = 0;
|
I830_CONTEXT(intel)->state.emitted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void i830_emit_flush( intelContextPtr intel )
|
static void i830_emit_flush( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
BATCH_LOCALS;
|
BATCH_LOCALS;
|
||||||
|
|
||||||
BEGIN_BATCH(2);
|
BEGIN_BATCH(2, 0);
|
||||||
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE );
|
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE );
|
||||||
OUT_BATCH( 0 );
|
OUT_BATCH( 0 );
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
@@ -441,7 +441,6 @@ static void i830_emit_flush( intelContextPtr intel )
|
|||||||
|
|
||||||
void i830InitVtbl( i830ContextPtr i830 )
|
void i830InitVtbl( i830ContextPtr i830 )
|
||||||
{
|
{
|
||||||
i830->intel.vtbl.alloc_tex_obj = i830AllocTexObj;
|
|
||||||
i830->intel.vtbl.check_vertex_size = i830_check_vertex_size;
|
i830->intel.vtbl.check_vertex_size = i830_check_vertex_size;
|
||||||
i830->intel.vtbl.clear_with_tris = i830ClearWithTris;
|
i830->intel.vtbl.clear_with_tris = i830ClearWithTris;
|
||||||
i830->intel.vtbl.destroy = i830_destroy_context;
|
i830->intel.vtbl.destroy = i830_destroy_context;
|
||||||
|
|||||||
@@ -41,6 +41,10 @@
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "i915_reg.h"
|
#include "i915_reg.h"
|
||||||
|
|
||||||
|
#include "bufmgr.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
|
||||||
/***************************************
|
/***************************************
|
||||||
* Mesa's Driver Functions
|
* Mesa's Driver Functions
|
||||||
***************************************/
|
***************************************/
|
||||||
@@ -65,7 +69,7 @@ static void i915InvalidateState( GLcontext *ctx, GLuint new_state )
|
|||||||
_ac_InvalidateState( ctx, new_state );
|
_ac_InvalidateState( ctx, new_state );
|
||||||
_tnl_InvalidateState( ctx, new_state );
|
_tnl_InvalidateState( ctx, new_state );
|
||||||
_tnl_invalidate_vertex_state( ctx, new_state );
|
_tnl_invalidate_vertex_state( ctx, new_state );
|
||||||
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
|
intel_context(ctx)->NewGLState |= new_state;
|
||||||
|
|
||||||
/* Todo: gather state values under which tracked parameters become
|
/* Todo: gather state values under which tracked parameters become
|
||||||
* invalidated, add callbacks for things like
|
* invalidated, add callbacks for things like
|
||||||
@@ -99,13 +103,16 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
|
|||||||
void *sharedContextPrivate)
|
void *sharedContextPrivate)
|
||||||
{
|
{
|
||||||
struct dd_function_table functions;
|
struct dd_function_table functions;
|
||||||
i915ContextPtr i915 = (i915ContextPtr) CALLOC_STRUCT(i915_context);
|
struct i915_context *i915 = (struct i915_context *) CALLOC_STRUCT(i915_context);
|
||||||
intelContextPtr intel = &i915->intel;
|
struct intel_context *intel = &i915->intel;
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
|
|
||||||
if (!i915) return GL_FALSE;
|
if (!i915) return GL_FALSE;
|
||||||
|
|
||||||
|
_mesa_printf( "\ntexmem branch (i915, drop2)\n\n");
|
||||||
|
|
||||||
i915InitVtbl( i915 );
|
i915InitVtbl( i915 );
|
||||||
|
i915InitMetaFuncs( i915 );
|
||||||
|
|
||||||
i915InitDriverFunctions( &functions );
|
i915InitDriverFunctions( &functions );
|
||||||
|
|
||||||
@@ -119,48 +126,28 @@ GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
|
|||||||
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
|
ctx->Const.MaxTextureImageUnits = I915_TEX_UNITS;
|
||||||
ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
|
ctx->Const.MaxTextureCoordUnits = I915_TEX_UNITS;
|
||||||
|
|
||||||
intel->nr_heaps = 1;
|
|
||||||
intel->texture_heaps[0] =
|
|
||||||
driCreateTextureHeap( 0, intel,
|
|
||||||
intel->intelScreen->tex.size,
|
|
||||||
12,
|
|
||||||
I830_NR_TEX_REGIONS,
|
|
||||||
intel->sarea->texList,
|
|
||||||
& intel->sarea->texAge,
|
|
||||||
& intel->swapped,
|
|
||||||
sizeof( struct i915_texture_object ),
|
|
||||||
(destroy_texture_object_t *)intelDestroyTexObj );
|
|
||||||
|
|
||||||
/* FIXME: driCalculateMaxTextureLevels assumes that mipmaps are
|
/* Advertise the full hardware capabilities. The new memory
|
||||||
* tightly packed, but they're not in Intel graphics
|
* manager should cope much better with overload situations:
|
||||||
* hardware.
|
|
||||||
*/
|
*/
|
||||||
ctx->Const.MaxTextureUnits = 1;
|
ctx->Const.MaxTextureLevels = 12;
|
||||||
driCalculateMaxTextureLevels( intel->texture_heaps,
|
ctx->Const.Max3DTextureLevels = 9;
|
||||||
intel->nr_heaps,
|
ctx->Const.MaxCubeTextureLevels = 12;
|
||||||
&intel->ctx.Const,
|
ctx->Const.MaxTextureRectSize = (1<<11);
|
||||||
4,
|
|
||||||
11, /* max 2D texture size is 2048x2048 */
|
|
||||||
8, /* 3D texture */
|
|
||||||
11, /* cube texture. */
|
|
||||||
11, /* rect texture */
|
|
||||||
12,
|
|
||||||
GL_FALSE );
|
|
||||||
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
|
ctx->Const.MaxTextureUnits = I915_TEX_UNITS;
|
||||||
|
|
||||||
/* GL_ARB_fragment_program limits - don't think Mesa actually
|
/* GL_ARB_fragment_program limits - don't think Mesa actually
|
||||||
* validates programs against these, and in any case one ARB
|
* validates programs against these, and in any case one ARB
|
||||||
* instruction can translate to more than one HW instruction, so
|
* instruction can translate to more than one HW instruction, so
|
||||||
* we'll still have to check and fallback each time.
|
* we'll still have to check and fallback each time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY;
|
ctx->Const.FragmentProgram.MaxNativeTemps = I915_MAX_TEMPORARY;
|
||||||
ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */
|
ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* 8 tex, 2 color, fog */
|
||||||
ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT;
|
ctx->Const.FragmentProgram.MaxNativeParameters = I915_MAX_CONSTANT;
|
||||||
ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN;
|
ctx->Const.FragmentProgram.MaxNativeAluInstructions = I915_MAX_ALU_INSN;
|
||||||
ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN;
|
ctx->Const.FragmentProgram.MaxNativeTexInstructions = I915_MAX_TEX_INSN;
|
||||||
ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN +
|
ctx->Const.FragmentProgram.MaxNativeInstructions = (I915_MAX_ALU_INSN +
|
||||||
I915_MAX_TEX_INSN);
|
I915_MAX_TEX_INSN);
|
||||||
ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT;
|
ctx->Const.FragmentProgram.MaxNativeTexIndirections = I915_MAX_TEX_INDIRECT;
|
||||||
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
|
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
#define I915_UPLOAD_PROGRAM 0x8
|
#define I915_UPLOAD_PROGRAM 0x8
|
||||||
#define I915_UPLOAD_CONSTANTS 0x10
|
#define I915_UPLOAD_CONSTANTS 0x10
|
||||||
#define I915_UPLOAD_FOG 0x20
|
#define I915_UPLOAD_FOG 0x20
|
||||||
|
#define I915_UPLOAD_INVARIENT 0x40
|
||||||
#define I915_UPLOAD_TEX(i) (0x00010000<<(i))
|
#define I915_UPLOAD_TEX(i) (0x00010000<<(i))
|
||||||
#define I915_UPLOAD_TEX_ALL (0x00ff0000)
|
#define I915_UPLOAD_TEX_ALL (0x00ff0000)
|
||||||
#define I915_UPLOAD_TEX_0_SHIFT 16
|
#define I915_UPLOAD_TEX_0_SHIFT 16
|
||||||
@@ -52,10 +53,8 @@
|
|||||||
*/
|
*/
|
||||||
#define I915_DESTREG_CBUFADDR0 0
|
#define I915_DESTREG_CBUFADDR0 0
|
||||||
#define I915_DESTREG_CBUFADDR1 1
|
#define I915_DESTREG_CBUFADDR1 1
|
||||||
#define I915_DESTREG_CBUFADDR2 2
|
|
||||||
#define I915_DESTREG_DBUFADDR0 3
|
#define I915_DESTREG_DBUFADDR0 3
|
||||||
#define I915_DESTREG_DBUFADDR1 4
|
#define I915_DESTREG_DBUFADDR1 4
|
||||||
#define I915_DESTREG_DBUFADDR2 5
|
|
||||||
#define I915_DESTREG_DV0 6
|
#define I915_DESTREG_DV0 6
|
||||||
#define I915_DESTREG_DV1 7
|
#define I915_DESTREG_DV1 7
|
||||||
#define I915_DESTREG_SENABLE 8
|
#define I915_DESTREG_SENABLE 8
|
||||||
@@ -86,7 +85,6 @@
|
|||||||
#define I915_STPREG_ST1 1
|
#define I915_STPREG_ST1 1
|
||||||
#define I915_STP_SETUP_SIZE 2
|
#define I915_STP_SETUP_SIZE 2
|
||||||
|
|
||||||
#define I915_TEXREG_MS2 0
|
|
||||||
#define I915_TEXREG_MS3 1
|
#define I915_TEXREG_MS3 1
|
||||||
#define I915_TEXREG_MS4 2
|
#define I915_TEXREG_MS4 2
|
||||||
#define I915_TEXREG_SS2 3
|
#define I915_TEXREG_SS2 3
|
||||||
@@ -163,8 +161,6 @@ struct i915_fragment_program {
|
|||||||
GLuint nr_params;
|
GLuint nr_params;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Helpers for i915_texprog.c:
|
/* Helpers for i915_texprog.c:
|
||||||
*/
|
*/
|
||||||
GLuint src_texture; /* Reg containing sampled texture color,
|
GLuint src_texture; /* Reg containing sampled texture color,
|
||||||
@@ -185,13 +181,6 @@ struct i915_fragment_program {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct i915_texture_object
|
|
||||||
{
|
|
||||||
struct intel_texture_object intel;
|
|
||||||
GLenum lastTarget;
|
|
||||||
GLboolean refs_border_color;
|
|
||||||
GLuint Setup[I915_TEX_SETUP_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define I915_TEX_UNITS 8
|
#define I915_TEX_UNITS 8
|
||||||
|
|
||||||
@@ -206,6 +195,15 @@ struct i915_hw_state {
|
|||||||
GLuint ConstantSize;
|
GLuint ConstantSize;
|
||||||
GLuint Program[I915_PROGRAM_SIZE];
|
GLuint Program[I915_PROGRAM_SIZE];
|
||||||
GLuint ProgramSize;
|
GLuint ProgramSize;
|
||||||
|
|
||||||
|
/* Region pointers for relocation:
|
||||||
|
*/
|
||||||
|
struct intel_region *draw_region;
|
||||||
|
struct intel_region *depth_region;
|
||||||
|
struct intel_region *tex_region[I915_TEX_UNITS];
|
||||||
|
GLuint tex_offset[I915_TEX_UNITS];
|
||||||
|
|
||||||
|
|
||||||
GLuint active; /* I915_UPLOAD_* */
|
GLuint active; /* I915_UPLOAD_* */
|
||||||
GLuint emitted; /* I915_UPLOAD_* */
|
GLuint emitted; /* I915_UPLOAD_* */
|
||||||
};
|
};
|
||||||
@@ -220,6 +218,8 @@ struct i915_context
|
|||||||
|
|
||||||
GLuint last_ReallyEnabled;
|
GLuint last_ReallyEnabled;
|
||||||
GLuint vertex_fog;
|
GLuint vertex_fog;
|
||||||
|
GLuint lodbias_ss2[MAX_TEXTURE_UNITS];
|
||||||
|
|
||||||
|
|
||||||
struct i915_fragment_program tex_program;
|
struct i915_fragment_program tex_program;
|
||||||
struct i915_fragment_program *current_program;
|
struct i915_fragment_program *current_program;
|
||||||
@@ -228,24 +228,14 @@ struct i915_context
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct i915_context *i915ContextPtr;
|
|
||||||
typedef struct i915_texture_object *i915TextureObjectPtr;
|
|
||||||
|
|
||||||
#define I915_CONTEXT(ctx) ((i915ContextPtr)(ctx))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define I915_STATECHANGE(i915, flag) \
|
#define I915_STATECHANGE(i915, flag) \
|
||||||
do { \
|
do { \
|
||||||
if (0) fprintf(stderr, "I915_STATECHANGE %x in %s\n", flag, __FUNCTION__); \
|
|
||||||
INTEL_FIREVERTICES( &(i915)->intel ); \
|
INTEL_FIREVERTICES( &(i915)->intel ); \
|
||||||
(i915)->state.emitted &= ~(flag); \
|
(i915)->state.emitted &= ~(flag); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define I915_ACTIVESTATE(i915, flag, mode) \
|
#define I915_ACTIVESTATE(i915, flag, mode) \
|
||||||
do { \
|
do { \
|
||||||
if (0) fprintf(stderr, "I915_ACTIVESTATE %x %d in %s\n", \
|
|
||||||
flag, mode, __FUNCTION__); \
|
|
||||||
INTEL_FIREVERTICES( &(i915)->intel ); \
|
INTEL_FIREVERTICES( &(i915)->intel ); \
|
||||||
if (mode) \
|
if (mode) \
|
||||||
(i915)->state.active |= (flag); \
|
(i915)->state.active |= (flag); \
|
||||||
@@ -257,7 +247,7 @@ do { \
|
|||||||
/*======================================================================
|
/*======================================================================
|
||||||
* i915_vtbl.c
|
* i915_vtbl.c
|
||||||
*/
|
*/
|
||||||
extern void i915InitVtbl( i915ContextPtr i915 );
|
extern void i915InitVtbl( struct i915_context *i915 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -294,7 +284,7 @@ extern GLboolean i915CreateContext( const __GLcontextModes *mesaVis,
|
|||||||
/*======================================================================
|
/*======================================================================
|
||||||
* i915_texprog.c
|
* i915_texprog.c
|
||||||
*/
|
*/
|
||||||
extern void i915ValidateTextureProgram( i915ContextPtr i915 );
|
extern void i915ValidateTextureProgram( struct i915_context *i915 );
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
@@ -308,44 +298,43 @@ extern void i915_print_ureg( const char *msg, GLuint ureg );
|
|||||||
* i915_state.c
|
* i915_state.c
|
||||||
*/
|
*/
|
||||||
extern void i915InitStateFunctions( struct dd_function_table *functions );
|
extern void i915InitStateFunctions( struct dd_function_table *functions );
|
||||||
extern void i915InitState( i915ContextPtr i915 );
|
extern void i915InitState( struct i915_context *i915 );
|
||||||
extern void i915_update_fog( GLcontext *ctx );
|
extern void i915_update_fog( GLcontext *ctx );
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
* i915_tex.c
|
* i915_tex.c
|
||||||
*/
|
*/
|
||||||
extern void i915UpdateTextureState( intelContextPtr intel );
|
extern void i915UpdateTextureState( struct intel_context *intel );
|
||||||
extern void i915InitTextureFuncs( struct dd_function_table *functions );
|
extern void i915InitTextureFuncs( struct dd_function_table *functions );
|
||||||
extern intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj );
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
* i915_metaops.c
|
* i915_metaops.c
|
||||||
*/
|
*/
|
||||||
extern GLboolean
|
void i915InitMetaFuncs( struct i915_context *i915 );
|
||||||
i915TryTextureReadPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *pack,
|
|
||||||
GLvoid *pixels );
|
|
||||||
|
|
||||||
extern GLboolean
|
|
||||||
i915TryTextureDrawPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *unpack,
|
|
||||||
const GLvoid *pixels );
|
|
||||||
|
|
||||||
extern void
|
|
||||||
i915ClearWithTris( intelContextPtr intel, GLbitfield mask,
|
|
||||||
GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch);
|
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================
|
/*======================================================================
|
||||||
* i915_fragprog.c
|
* i915_fragprog.c
|
||||||
*/
|
*/
|
||||||
extern void i915ValidateFragmentProgram( i915ContextPtr i915 );
|
extern void i915ValidateFragmentProgram( struct i915_context *i915 );
|
||||||
extern void i915InitFragProgFuncs( struct dd_function_table *functions );
|
extern void i915InitFragProgFuncs( struct dd_function_table *functions );
|
||||||
|
|
||||||
|
/*======================================================================
|
||||||
|
* Inline conversion functions. These are better-typed than the
|
||||||
|
* macros used previously:
|
||||||
|
*/
|
||||||
|
static inline struct i915_context *
|
||||||
|
i915_context( GLcontext *ctx )
|
||||||
|
{
|
||||||
|
return (struct i915_context *)ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define I915_CONTEXT(ctx) i915_context(ctx)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -806,7 +806,7 @@ static void check_wpos( struct i915_fragment_program *p )
|
|||||||
|
|
||||||
static void translate_program( struct i915_fragment_program *p )
|
static void translate_program( struct i915_fragment_program *p )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(p->ctx);
|
struct i915_context *i915 = I915_CONTEXT(p->ctx);
|
||||||
|
|
||||||
i915_init_program( i915, p );
|
i915_init_program( i915, p );
|
||||||
check_wpos( p );
|
check_wpos( p );
|
||||||
@@ -840,7 +840,7 @@ static void i915BindProgram( GLcontext *ctx,
|
|||||||
struct program *prog )
|
struct program *prog )
|
||||||
{
|
{
|
||||||
if (target == GL_FRAGMENT_PROGRAM_ARB) {
|
if (target == GL_FRAGMENT_PROGRAM_ARB) {
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
struct i915_fragment_program *p = (struct i915_fragment_program *)prog;
|
struct i915_fragment_program *p = (struct i915_fragment_program *)prog;
|
||||||
|
|
||||||
if (i915->current_program == p)
|
if (i915->current_program == p)
|
||||||
@@ -896,7 +896,7 @@ static void i915DeleteProgram( GLcontext *ctx,
|
|||||||
struct program *prog )
|
struct program *prog )
|
||||||
{
|
{
|
||||||
if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
|
if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
struct i915_fragment_program *p = (struct i915_fragment_program *)prog;
|
struct i915_fragment_program *p = (struct i915_fragment_program *)prog;
|
||||||
|
|
||||||
if (i915->current_program == p)
|
if (i915->current_program == p)
|
||||||
@@ -940,10 +940,10 @@ static void i915ProgramStringNotify( GLcontext *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i915ValidateFragmentProgram( i915ContextPtr i915 )
|
void i915ValidateFragmentProgram( struct i915_context *i915 )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &i915->intel.ctx;
|
GLcontext *ctx = &i915->intel.ctx;
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct vertex_buffer *VB = &tnl->vb;
|
struct vertex_buffer *VB = &tnl->vb;
|
||||||
|
|
||||||
|
|||||||
@@ -34,39 +34,32 @@
|
|||||||
#include "intel_screen.h"
|
#include "intel_screen.h"
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
#include "intel_ioctl.h"
|
#include "intel_ioctl.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
|
||||||
#include "i915_context.h"
|
#include "i915_context.h"
|
||||||
#include "i915_reg.h"
|
#include "i915_reg.h"
|
||||||
|
|
||||||
/* A large amount of state doesn't need to be uploaded.
|
/* A large amount of state doesn't need to be uploaded.
|
||||||
*/
|
*/
|
||||||
#define ACTIVE (I915_UPLOAD_PROGRAM | \
|
#define ACTIVE (I915_UPLOAD_INVARIENT | \
|
||||||
|
I915_UPLOAD_PROGRAM | \
|
||||||
I915_UPLOAD_STIPPLE | \
|
I915_UPLOAD_STIPPLE | \
|
||||||
I915_UPLOAD_CTX | \
|
I915_UPLOAD_CTX | \
|
||||||
I915_UPLOAD_BUFFERS | \
|
I915_UPLOAD_BUFFERS | \
|
||||||
I915_UPLOAD_TEX(0))
|
I915_UPLOAD_TEX(0))
|
||||||
|
|
||||||
#define SET_STATE( i915, STATE ) \
|
#define SET_STATE( i915, STATE ) \
|
||||||
do { \
|
do { \
|
||||||
i915->current->emitted &= ~ACTIVE; \
|
i915->current->emitted &= ~ACTIVE; \
|
||||||
i915->current = &i915->STATE; \
|
i915->current = &i915->STATE; \
|
||||||
i915->current->emitted &= ~ACTIVE; \
|
i915->current->emitted &= ~ACTIVE; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* Operations where the 3D engine is decoupled temporarily from the
|
|
||||||
* current GL state and used for other purposes than simply rendering
|
|
||||||
* incoming triangles.
|
|
||||||
*/
|
|
||||||
static void set_initial_state( i915ContextPtr i915 )
|
|
||||||
{
|
|
||||||
memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) );
|
|
||||||
i915->meta.active = ACTIVE;
|
|
||||||
i915->meta.emitted = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
static void meta_no_depth_stencil_write( struct intel_context *intel )
|
||||||
static void set_no_depth_stencil_write( i915ContextPtr i915 )
|
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
|
/* ctx->Driver.Enable( ctx, GL_STENCIL_TEST, GL_FALSE )
|
||||||
*/
|
*/
|
||||||
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
|
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_TEST_ENABLE |
|
||||||
@@ -82,10 +75,11 @@ static void set_no_depth_stencil_write( i915ContextPtr i915 )
|
|||||||
|
|
||||||
/* Set stencil unit to replace always with the reference value.
|
/* Set stencil unit to replace always with the reference value.
|
||||||
*/
|
*/
|
||||||
static void set_stencil_replace( i915ContextPtr i915,
|
static void meta_stencil_replace( struct intel_context *intel,
|
||||||
GLuint s_mask,
|
GLuint s_mask,
|
||||||
GLuint s_clear)
|
GLuint s_clear)
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
GLuint op = STENCILOP_REPLACE;
|
GLuint op = STENCILOP_REPLACE;
|
||||||
GLuint func = COMPAREFUNC_ALWAYS;
|
GLuint func = COMPAREFUNC_ALWAYS;
|
||||||
|
|
||||||
@@ -100,7 +94,6 @@ static void set_stencil_replace( i915ContextPtr i915,
|
|||||||
i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE |
|
i915->meta.Ctx[I915_CTXREG_LIS6] &= ~(S6_DEPTH_TEST_ENABLE |
|
||||||
S6_DEPTH_WRITE_ENABLE);
|
S6_DEPTH_WRITE_ENABLE);
|
||||||
|
|
||||||
|
|
||||||
/* ctx->Driver.StencilMask( ctx, s_mask )
|
/* ctx->Driver.StencilMask( ctx, s_mask )
|
||||||
*/
|
*/
|
||||||
i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
|
i915->meta.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
|
||||||
@@ -108,7 +101,6 @@ static void set_stencil_replace( i915ContextPtr i915,
|
|||||||
i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
|
i915->meta.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
|
||||||
STENCIL_WRITE_MASK(s_mask));
|
STENCIL_WRITE_MASK(s_mask));
|
||||||
|
|
||||||
|
|
||||||
/* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
|
/* ctx->Driver.StencilOp( ctx, GL_REPLACE, GL_REPLACE, GL_REPLACE )
|
||||||
*/
|
*/
|
||||||
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
|
i915->meta.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
|
||||||
@@ -137,8 +129,9 @@ static void set_stencil_replace( i915ContextPtr i915,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void set_color_mask( i915ContextPtr i915, GLboolean state )
|
static void meta_color_mask( struct intel_context *intel, GLboolean state )
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
const GLuint mask = (S5_WRITEDISABLE_RED |
|
const GLuint mask = (S5_WRITEDISABLE_RED |
|
||||||
S5_WRITEDISABLE_GREEN |
|
S5_WRITEDISABLE_GREEN |
|
||||||
S5_WRITEDISABLE_BLUE |
|
S5_WRITEDISABLE_BLUE |
|
||||||
@@ -210,8 +203,10 @@ static void set_color_mask( i915ContextPtr i915, GLboolean state )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void set_no_texture( i915ContextPtr i915 )
|
static void meta_no_texture( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
static const GLuint prog[] = {
|
static const GLuint prog[] = {
|
||||||
_3DSTATE_PIXEL_SHADER_PROGRAM,
|
_3DSTATE_PIXEL_SHADER_PROGRAM,
|
||||||
|
|
||||||
@@ -240,9 +235,10 @@ static void set_no_texture( i915ContextPtr i915 )
|
|||||||
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
|
i915->meta.emitted &= ~I915_UPLOAD_PROGRAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
static void meta_texture_blend_replace( struct intel_context *intel )
|
||||||
static void enable_texture_blend_replace( i915ContextPtr i915 )
|
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
static const GLuint prog[] = {
|
static const GLuint prog[] = {
|
||||||
_3DSTATE_PIXEL_SHADER_PROGRAM,
|
_3DSTATE_PIXEL_SHADER_PROGRAM,
|
||||||
|
|
||||||
@@ -285,78 +281,86 @@ static void enable_texture_blend_replace( i915ContextPtr i915 )
|
|||||||
/* Set up an arbitary piece of memory as a rectangular texture
|
/* Set up an arbitary piece of memory as a rectangular texture
|
||||||
* (including the front or back buffer).
|
* (including the front or back buffer).
|
||||||
*/
|
*/
|
||||||
static void set_tex_rect_source( i915ContextPtr i915,
|
static void meta_tex_rect_source( struct intel_context *intel,
|
||||||
GLuint offset,
|
struct intel_region *region,
|
||||||
GLuint width,
|
|
||||||
GLuint height,
|
|
||||||
GLuint pitch,
|
|
||||||
GLuint textureFormat )
|
GLuint textureFormat )
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
GLuint unit = 0;
|
GLuint unit = 0;
|
||||||
GLint numLevels = 1;
|
GLint numLevels = 1;
|
||||||
GLuint *state = i915->meta.Tex[0];
|
GLuint *state = i915->meta.Tex[0];
|
||||||
|
|
||||||
pitch *= i915->intel.intelScreen->cpp;
|
GLuint pitch = region->pitch * region->cpp;
|
||||||
|
|
||||||
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
|
/* fprintf(stderr, "%s: offset: %x w: %d h: %d pitch %d format %x\n", */
|
||||||
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
|
/* __FUNCTION__, offset, width, height, pitch, textureFormat ); */
|
||||||
|
|
||||||
state[I915_TEXREG_MS2] = offset;
|
intel_region_release(intel, &i915->meta.tex_region[0]);
|
||||||
state[I915_TEXREG_MS3] = (((height - 1) << MS3_HEIGHT_SHIFT) |
|
intel_region_reference(&i915->meta.tex_region[0], region);
|
||||||
((width - 1) << MS3_WIDTH_SHIFT) |
|
i915->meta.tex_offset[0] = 0;
|
||||||
textureFormat |
|
|
||||||
MS3_USE_FENCE_REGS);
|
state[I915_TEXREG_MS3] = (((region->height - 1) << MS3_HEIGHT_SHIFT) |
|
||||||
|
((region->pitch - 1) << MS3_WIDTH_SHIFT) |
|
||||||
|
textureFormat |
|
||||||
|
MS3_USE_FENCE_REGS);
|
||||||
|
|
||||||
state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
|
state[I915_TEXREG_MS4] = ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) |
|
||||||
MS4_CUBE_FACE_ENA_MASK |
|
MS4_CUBE_FACE_ENA_MASK |
|
||||||
((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT));
|
((((numLevels-1) * 4)) << MS4_MAX_LOD_SHIFT));
|
||||||
|
|
||||||
state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) |
|
state[I915_TEXREG_SS2] = ((FILTER_NEAREST << SS2_MIN_FILTER_SHIFT) |
|
||||||
(MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) |
|
(MIPFILTER_NONE << SS2_MIP_FILTER_SHIFT) |
|
||||||
(FILTER_NEAREST << SS2_MAG_FILTER_SHIFT));
|
(FILTER_NEAREST << SS2_MAG_FILTER_SHIFT));
|
||||||
|
|
||||||
state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) |
|
state[I915_TEXREG_SS3] = ((TEXCOORDMODE_WRAP << SS3_TCX_ADDR_MODE_SHIFT) |
|
||||||
(TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) |
|
(TEXCOORDMODE_WRAP << SS3_TCY_ADDR_MODE_SHIFT) |
|
||||||
(TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) |
|
(TEXCOORDMODE_WRAP << SS3_TCZ_ADDR_MODE_SHIFT) |
|
||||||
(unit<<SS3_TEXTUREMAP_INDEX_SHIFT));
|
(unit<<SS3_TEXTUREMAP_INDEX_SHIFT));
|
||||||
|
|
||||||
state[I915_TEXREG_SS4] = 0;
|
state[I915_TEXREG_SS4] = 0;
|
||||||
|
|
||||||
i915->meta.emitted &= ~I915_UPLOAD_TEX(0);
|
i915->meta.emitted &= ~I915_UPLOAD_TEX(0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Select between front and back draw buffers.
|
/* Select between front and back draw buffers.
|
||||||
*/
|
*/
|
||||||
static void set_draw_offset( i915ContextPtr i915,
|
static void meta_draw_region( struct intel_context *intel,
|
||||||
GLuint offset )
|
struct intel_region *draw_region,
|
||||||
|
struct intel_region *depth_region )
|
||||||
{
|
{
|
||||||
i915->meta.Buffer[I915_DESTREG_CBUFADDR2] = offset;
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
|
intel_region_release(intel, &i915->meta.draw_region);
|
||||||
|
intel_region_release(intel, &i915->meta.depth_region);
|
||||||
|
intel_region_reference(&i915->meta.draw_region, draw_region);
|
||||||
|
intel_region_reference(&i915->meta.depth_region, depth_region);
|
||||||
|
|
||||||
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
|
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Setup an arbitary draw format, useful for targeting texture or agp
|
/* Setup an arbitary draw format, useful for targeting texture or agp
|
||||||
* memory.
|
* memory.
|
||||||
*/
|
*/
|
||||||
static void set_draw_format( i915ContextPtr i915,
|
static void set_draw_format( struct intel_context *intel,
|
||||||
GLuint format,
|
GLuint format,
|
||||||
GLuint depth_format)
|
GLuint depth_format)
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
|
i915->meta.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
|
||||||
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
||||||
format |
|
format |
|
||||||
LOD_PRECLAMP_OGL |
|
LOD_PRECLAMP_OGL |
|
||||||
TEX_DEFAULT_COLOR_OGL |
|
TEX_DEFAULT_COLOR_OGL |
|
||||||
depth_format);
|
depth_format);
|
||||||
|
|
||||||
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
|
i915->meta.emitted &= ~I915_UPLOAD_BUFFERS;
|
||||||
/* fprintf(stderr, "%s: DV1: %x\n", */
|
|
||||||
/* __FUNCTION__, i915->meta.Buffer[I915_DESTREG_DV1]); */
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static void set_vertex_format( i915ContextPtr i915 )
|
static void set_vertex_format( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
i915->meta.Ctx[I915_CTXREG_LIS2] =
|
i915->meta.Ctx[I915_CTXREG_LIS2] =
|
||||||
(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
|
(S2_TEXCOORD_FMT(0, TEXCOORDFMT_2D) |
|
||||||
S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
|
S2_TEXCOORD_FMT(1, TEXCOORDFMT_NOT_PRESENT) |
|
||||||
@@ -371,146 +375,50 @@ static void set_vertex_format( i915ContextPtr i915 )
|
|||||||
|
|
||||||
i915->meta.Ctx[I915_CTXREG_LIS4] |=
|
i915->meta.Ctx[I915_CTXREG_LIS4] |=
|
||||||
(S4_VFMT_COLOR |
|
(S4_VFMT_COLOR |
|
||||||
S4_VFMT_SPEC_FOG |
|
S4_VFMT_XYZ);
|
||||||
S4_VFMT_XYZW);
|
|
||||||
|
|
||||||
i915->meta.emitted &= ~I915_UPLOAD_CTX;
|
i915->meta.emitted &= ~I915_UPLOAD_CTX;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void draw_quad(i915ContextPtr i915,
|
|
||||||
GLfloat x0, GLfloat x1,
|
/* Operations where the 3D engine is decoupled temporarily from the
|
||||||
GLfloat y0, GLfloat y1,
|
* current GL state and used for other purposes than simply rendering
|
||||||
GLubyte red, GLubyte green,
|
* incoming triangles.
|
||||||
GLubyte blue, GLubyte alpha,
|
*/
|
||||||
GLfloat s0, GLfloat s1,
|
static void install_meta_state( struct intel_context *intel )
|
||||||
GLfloat t0, GLfloat t1 )
|
|
||||||
{
|
{
|
||||||
GLuint vertex_size = 8;
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
GLuint *vb = intelEmitInlinePrimitiveLocked( &i915->intel,
|
memcpy(&i915->meta, &i915->initial, sizeof(i915->meta) );
|
||||||
PRIM3D_TRIFAN,
|
i915->meta.active = ACTIVE;
|
||||||
4 * vertex_size,
|
i915->meta.emitted = 0;
|
||||||
vertex_size );
|
|
||||||
intelVertex tmp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (0)
|
SET_STATE(i915, meta);
|
||||||
fprintf(stderr, "%s: %f,%f-%f,%f 0x%x%x%x%x %f,%f-%f,%f\n",
|
set_vertex_format(intel);
|
||||||
__FUNCTION__,
|
meta_no_texture(intel);
|
||||||
x0,y0,x1,y1,red,green,blue,alpha,s0,t0,s1,t1);
|
|
||||||
|
|
||||||
|
|
||||||
/* initial vertex, left bottom */
|
|
||||||
tmp.v.x = x0;
|
|
||||||
tmp.v.y = y0;
|
|
||||||
tmp.v.z = 1.0;
|
|
||||||
tmp.v.w = 1.0;
|
|
||||||
tmp.v.color.red = red;
|
|
||||||
tmp.v.color.green = green;
|
|
||||||
tmp.v.color.blue = blue;
|
|
||||||
tmp.v.color.alpha = alpha;
|
|
||||||
tmp.v.specular.red = 0;
|
|
||||||
tmp.v.specular.green = 0;
|
|
||||||
tmp.v.specular.blue = 0;
|
|
||||||
tmp.v.specular.alpha = 0;
|
|
||||||
tmp.v.u0 = s0;
|
|
||||||
tmp.v.v0 = t0;
|
|
||||||
|
|
||||||
for (i = 0 ; i < vertex_size ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* right bottom */
|
|
||||||
vb += vertex_size;
|
|
||||||
tmp.v.x = x1;
|
|
||||||
tmp.v.u0 = s1;
|
|
||||||
for (i = 0 ; i < vertex_size ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* right top */
|
|
||||||
vb += vertex_size;
|
|
||||||
tmp.v.y = y1;
|
|
||||||
tmp.v.v0 = t1;
|
|
||||||
for (i = 0 ; i < vertex_size ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
|
|
||||||
/* left top */
|
|
||||||
vb += vertex_size;
|
|
||||||
tmp.v.x = x0;
|
|
||||||
tmp.v.u0 = s0;
|
|
||||||
for (i = 0 ; i < vertex_size ; i++)
|
|
||||||
vb[i] = tmp.ui[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void leave_meta_state( struct intel_context *intel )
|
||||||
i915ClearWithTris(intelContextPtr intel, GLbitfield mask,
|
|
||||||
GLboolean all,
|
|
||||||
GLint cx, GLint cy, GLint cw, GLint ch)
|
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT( intel );
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
intel_region_release(intel, &i915->meta.draw_region);
|
||||||
intelScreenPrivate *screen = intel->intelScreen;
|
intel_region_release(intel, &i915->meta.depth_region);
|
||||||
int x0, y0, x1, y1;
|
intel_region_release(intel, &i915->meta.tex_region[0]);
|
||||||
|
SET_STATE(i915, state);
|
||||||
SET_STATE( i915, meta );
|
|
||||||
set_initial_state( i915 );
|
|
||||||
set_no_texture( i915 );
|
|
||||||
set_vertex_format( i915 );
|
|
||||||
|
|
||||||
LOCK_HARDWARE(intel);
|
|
||||||
|
|
||||||
if(!all) {
|
|
||||||
x0 = cx;
|
|
||||||
y0 = cy;
|
|
||||||
x1 = x0 + cw;
|
|
||||||
y1 = y0 + ch;
|
|
||||||
} else {
|
|
||||||
x0 = 0;
|
|
||||||
y0 = 0;
|
|
||||||
x1 = x0 + dPriv->w;
|
|
||||||
y1 = y0 + dPriv->h;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't do any clipping to screen - these are window coordinates.
|
|
||||||
* The active cliprects will be applied as for any other geometry.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_FRONT_LEFT) {
|
|
||||||
set_no_depth_stencil_write( i915 );
|
|
||||||
set_color_mask( i915, GL_TRUE );
|
|
||||||
set_draw_offset( i915, screen->front.offset );
|
|
||||||
|
|
||||||
draw_quad(i915, x0, x1, y0, y1,
|
|
||||||
intel->clear_red, intel->clear_green,
|
|
||||||
intel->clear_blue, intel->clear_alpha,
|
|
||||||
0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_BACK_LEFT) {
|
|
||||||
set_no_depth_stencil_write( i915 );
|
|
||||||
set_color_mask( i915, GL_TRUE );
|
|
||||||
set_draw_offset( i915, screen->back.offset );
|
|
||||||
|
|
||||||
draw_quad(i915, x0, x1, y0, y1,
|
|
||||||
intel->clear_red, intel->clear_green,
|
|
||||||
intel->clear_blue, intel->clear_alpha,
|
|
||||||
0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_STENCIL) {
|
|
||||||
set_stencil_replace( i915,
|
|
||||||
intel->ctx.Stencil.WriteMask[0],
|
|
||||||
intel->ctx.Stencil.Clear);
|
|
||||||
|
|
||||||
set_color_mask( i915, GL_FALSE );
|
|
||||||
set_draw_offset( i915, screen->front.offset ); /* could be either? */
|
|
||||||
|
|
||||||
draw_quad( i915, x0, x1, y0, y1, 0, 0, 0, 0, 0, 0, 0, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
|
|
||||||
SET_STATE( i915, state );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void i915InitMetaFuncs( struct i915_context *i915 )
|
||||||
|
{
|
||||||
|
i915->intel.vtbl.install_meta_state = install_meta_state;
|
||||||
|
i915->intel.vtbl.leave_meta_state = leave_meta_state;
|
||||||
|
i915->intel.vtbl.meta_no_depth_stencil_write = meta_no_depth_stencil_write;
|
||||||
|
i915->intel.vtbl.meta_stencil_replace = meta_stencil_replace;
|
||||||
|
i915->intel.vtbl.meta_color_mask = meta_color_mask;
|
||||||
|
i915->intel.vtbl.meta_no_texture = meta_no_texture;
|
||||||
|
i915->intel.vtbl.meta_texture_blend_replace = meta_texture_blend_replace;
|
||||||
|
i915->intel.vtbl.meta_tex_rect_source = meta_tex_rect_source;
|
||||||
|
i915->intel.vtbl.meta_draw_region = meta_draw_region;
|
||||||
|
i915->intel.vtbl.meta_draw_format = set_draw_format;
|
||||||
|
}
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ void i915_program_error( struct i915_fragment_program *p, const char *msg )
|
|||||||
p->error = 1;
|
p->error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i915_init_program( i915ContextPtr i915, struct i915_fragment_program *p )
|
void i915_init_program( struct i915_context *i915, struct i915_fragment_program *p )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &i915->intel.ctx;
|
GLcontext *ctx = &i915->intel.ctx;
|
||||||
TNLcontext *tnl = TNL_CONTEXT( ctx );
|
TNLcontext *tnl = TNL_CONTEXT( ctx );
|
||||||
@@ -431,7 +431,7 @@ void i915_fini_program( struct i915_fragment_program *p )
|
|||||||
p->declarations[0] |= program_size + decl_size - 2;
|
p->declarations[0] |= program_size + decl_size - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i915_upload_program( i915ContextPtr i915, struct i915_fragment_program *p )
|
void i915_upload_program( struct i915_context *i915, struct i915_fragment_program *p )
|
||||||
{
|
{
|
||||||
GLuint program_size = p->csr - p->program;
|
GLuint program_size = p->csr - p->program;
|
||||||
GLuint decl_size = p->decl - p->declarations;
|
GLuint decl_size = p->decl - p->declarations;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@
|
|||||||
|
|
||||||
/* One neat thing about the UREG representation:
|
/* One neat thing about the UREG representation:
|
||||||
*/
|
*/
|
||||||
static __inline int swizzle( int reg, int x, int y, int z, int w )
|
static inline int swizzle( int reg, int x, int y, int z, int w )
|
||||||
{
|
{
|
||||||
return ((reg & ~UREG_XYZW_CHANNEL_MASK) |
|
return ((reg & ~UREG_XYZW_CHANNEL_MASK) |
|
||||||
CHANNEL_SRC( GET_CHANNEL_SRC( reg, x ), 0 ) |
|
CHANNEL_SRC( GET_CHANNEL_SRC( reg, x ), 0 ) |
|
||||||
@@ -95,7 +95,7 @@ static __inline int swizzle( int reg, int x, int y, int z, int w )
|
|||||||
|
|
||||||
/* Another neat thing about the UREG representation:
|
/* Another neat thing about the UREG representation:
|
||||||
*/
|
*/
|
||||||
static __inline int negate( int reg, int x, int y, int z, int w )
|
static inline int negate( int reg, int x, int y, int z, int w )
|
||||||
{
|
{
|
||||||
return reg ^ (((x&1)<<UREG_CHANNEL_X_NEGATE_SHIFT)|
|
return reg ^ (((x&1)<<UREG_CHANNEL_X_NEGATE_SHIFT)|
|
||||||
((y&1)<<UREG_CHANNEL_Y_NEGATE_SHIFT)|
|
((y&1)<<UREG_CHANNEL_Y_NEGATE_SHIFT)|
|
||||||
@@ -149,10 +149,10 @@ extern GLuint i915_emit_param4fv( struct i915_fragment_program *p,
|
|||||||
extern void i915_program_error( struct i915_fragment_program *p,
|
extern void i915_program_error( struct i915_fragment_program *p,
|
||||||
const char *msg );
|
const char *msg );
|
||||||
|
|
||||||
extern void i915_init_program( i915ContextPtr i915,
|
extern void i915_init_program( struct i915_context *i915,
|
||||||
struct i915_fragment_program *p );
|
struct i915_fragment_program *p );
|
||||||
|
|
||||||
extern void i915_upload_program( i915ContextPtr i915,
|
extern void i915_upload_program( struct i915_context *i915,
|
||||||
struct i915_fragment_program *p );
|
struct i915_fragment_program *p );
|
||||||
|
|
||||||
extern void i915_fini_program( struct i915_fragment_program *p );
|
extern void i915_fini_program( struct i915_fragment_program *p );
|
||||||
|
|||||||
@@ -435,10 +435,10 @@
|
|||||||
#define LOGICOP_MASK (0xf<<18)
|
#define LOGICOP_MASK (0xf<<18)
|
||||||
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
|
#define MODE4_ENABLE_STENCIL_TEST_MASK ((1<<17)|(0xff00))
|
||||||
#define ENABLE_STENCIL_TEST_MASK (1<<17)
|
#define ENABLE_STENCIL_TEST_MASK (1<<17)
|
||||||
#define STENCIL_TEST_MASK(x) ((x)<<8)
|
#define STENCIL_TEST_MASK(x) (((x)&0xff)<<8)
|
||||||
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
|
#define MODE4_ENABLE_STENCIL_WRITE_MASK ((1<<16)|(0x00ff))
|
||||||
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
|
#define ENABLE_STENCIL_WRITE_MASK (1<<16)
|
||||||
#define STENCIL_WRITE_MASK(x) (x)
|
#define STENCIL_WRITE_MASK(x) ((x)&0xff)
|
||||||
|
|
||||||
/* _3DSTATE_MODES_5, p220 */
|
/* _3DSTATE_MODES_5, p220 */
|
||||||
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
|
#define _3DSTATE_MODES_5_CMD (CMD_3D|(0x0c<<24))
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ static void
|
|||||||
i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
|
i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
|
||||||
GLuint mask)
|
GLuint mask)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
int test = intel_translate_compare_func( func );
|
int test = intel_translate_compare_func( func );
|
||||||
|
|
||||||
mask = mask & 0xff;
|
mask = mask & 0xff;
|
||||||
@@ -73,7 +73,7 @@ i915StencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func, GLint ref,
|
|||||||
static void
|
static void
|
||||||
i915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
|
i915StencilMaskSeparate(GLcontext *ctx, GLenum face, GLuint mask)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
|
fprintf(stderr, "%s : mask 0x%x\n", __FUNCTION__, mask);
|
||||||
@@ -91,7 +91,7 @@ static void
|
|||||||
i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
|
i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
|
||||||
GLenum zpass)
|
GLenum zpass)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
int fop = intel_translate_stencil_op(fail);
|
int fop = intel_translate_stencil_op(fail);
|
||||||
int dfop = intel_translate_stencil_op(zfail);
|
int dfop = intel_translate_stencil_op(zfail);
|
||||||
int dpop = intel_translate_stencil_op(zpass);
|
int dpop = intel_translate_stencil_op(zpass);
|
||||||
@@ -116,7 +116,7 @@ i915StencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail, GLenum zfail,
|
|||||||
|
|
||||||
static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
|
static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
int test = intel_translate_compare_func( func );
|
int test = intel_translate_compare_func( func );
|
||||||
GLubyte refByte;
|
GLubyte refByte;
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ static void i915AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
|
|||||||
*/
|
*/
|
||||||
static void i915EvalLogicOpBlendState(GLcontext *ctx)
|
static void i915EvalLogicOpBlendState(GLcontext *ctx)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
|
|
||||||
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
|
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
|
||||||
|
|
||||||
@@ -157,7 +157,7 @@ static void i915EvalLogicOpBlendState(GLcontext *ctx)
|
|||||||
|
|
||||||
static void i915BlendColor(GLcontext *ctx, const GLfloat color[4])
|
static void i915BlendColor(GLcontext *ctx, const GLfloat color[4])
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
GLubyte r, g, b, a;
|
GLubyte r, g, b, a;
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
@@ -194,7 +194,7 @@ static GLuint translate_blend_equation( GLenum mode )
|
|||||||
|
|
||||||
static void i915UpdateBlendState( GLcontext *ctx )
|
static void i915UpdateBlendState( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &
|
GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &
|
||||||
~(IAB_SRC_FACTOR_MASK |
|
~(IAB_SRC_FACTOR_MASK |
|
||||||
IAB_DST_FACTOR_MASK |
|
IAB_DST_FACTOR_MASK |
|
||||||
@@ -261,7 +261,7 @@ static void i915BlendEquationSeparate(GLcontext *ctx, GLenum eqRGB,
|
|||||||
|
|
||||||
static void i915DepthFunc(GLcontext *ctx, GLenum func)
|
static void i915DepthFunc(GLcontext *ctx, GLenum func)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
int test = intel_translate_compare_func( func );
|
int test = intel_translate_compare_func( func );
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
@@ -274,7 +274,7 @@ static void i915DepthFunc(GLcontext *ctx, GLenum func)
|
|||||||
|
|
||||||
static void i915DepthMask(GLcontext *ctx, GLboolean flag)
|
static void i915DepthMask(GLcontext *ctx, GLboolean flag)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
|
fprintf(stderr, "%s flag (%d)\n", __FUNCTION__, flag);
|
||||||
@@ -295,7 +295,7 @@ static void i915DepthMask(GLcontext *ctx, GLboolean flag)
|
|||||||
*/
|
*/
|
||||||
static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask )
|
static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
const GLubyte *m = mask;
|
const GLubyte *m = mask;
|
||||||
GLubyte p[4];
|
GLubyte p[4];
|
||||||
int i,j,k;
|
int i,j,k;
|
||||||
@@ -348,7 +348,7 @@ static void i915PolygonStipple( GLcontext *ctx, const GLubyte *mask )
|
|||||||
static void i915Scissor(GLcontext *ctx, GLint x, GLint y,
|
static void i915Scissor(GLcontext *ctx, GLint x, GLint y,
|
||||||
GLsizei w, GLsizei h)
|
GLsizei w, GLsizei h)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
intelScreenPrivate *screen = i915->intel.intelScreen;
|
intelScreenPrivate *screen = i915->intel.intelScreen;
|
||||||
int x1, y1, x2, y2;
|
int x1, y1, x2, y2;
|
||||||
|
|
||||||
@@ -382,7 +382,7 @@ static void i915Scissor(GLcontext *ctx, GLint x, GLint y,
|
|||||||
|
|
||||||
static void i915LogicOp(GLcontext *ctx, GLenum opcode)
|
static void i915LogicOp(GLcontext *ctx, GLenum opcode)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
int tmp = intel_translate_logic_op(opcode);
|
int tmp = intel_translate_logic_op(opcode);
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
@@ -397,7 +397,7 @@ static void i915LogicOp(GLcontext *ctx, GLenum opcode)
|
|||||||
|
|
||||||
static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused)
|
static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
GLuint mode;
|
GLuint mode;
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
@@ -425,7 +425,7 @@ static void i915CullFaceFrontFace(GLcontext *ctx, GLenum unused)
|
|||||||
|
|
||||||
static void i915LineWidth( GLcontext *ctx, GLfloat widthf )
|
static void i915LineWidth( GLcontext *ctx, GLfloat widthf )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT( ctx );
|
struct i915_context *i915 = I915_CONTEXT( ctx );
|
||||||
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;
|
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
@@ -444,7 +444,7 @@ static void i915LineWidth( GLcontext *ctx, GLfloat widthf )
|
|||||||
|
|
||||||
static void i915PointSize(GLcontext *ctx, GLfloat size)
|
static void i915PointSize(GLcontext *ctx, GLfloat size)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
|
int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;
|
||||||
GLint point_size = (int)size;
|
GLint point_size = (int)size;
|
||||||
|
|
||||||
@@ -469,7 +469,7 @@ static void i915ColorMask(GLcontext *ctx,
|
|||||||
GLboolean r, GLboolean g,
|
GLboolean r, GLboolean g,
|
||||||
GLboolean b, GLboolean a)
|
GLboolean b, GLboolean a)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT( ctx );
|
struct i915_context *i915 = I915_CONTEXT( ctx );
|
||||||
GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK;
|
GLuint tmp = i915->state.Ctx[I915_CTXREG_LIS5] & ~S5_WRITEDISABLE_MASK;
|
||||||
|
|
||||||
if (INTEL_DEBUG&DEBUG_DRI)
|
if (INTEL_DEBUG&DEBUG_DRI)
|
||||||
@@ -490,7 +490,7 @@ static void update_specular( GLcontext *ctx )
|
|||||||
{
|
{
|
||||||
/* A hack to trigger the rebuild of the fragment program.
|
/* A hack to trigger the rebuild of the fragment program.
|
||||||
*/
|
*/
|
||||||
INTEL_CONTEXT(ctx)->NewGLState |= _NEW_TEXTURE;
|
intel_context(ctx)->NewGLState |= _NEW_TEXTURE;
|
||||||
I915_CONTEXT(ctx)->tex_program.translated = 0;
|
I915_CONTEXT(ctx)->tex_program.translated = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,7 +507,7 @@ static void i915LightModelfv(GLcontext *ctx, GLenum pname,
|
|||||||
|
|
||||||
static void i915ShadeModel(GLcontext *ctx, GLenum mode)
|
static void i915ShadeModel(GLcontext *ctx, GLenum mode)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
|
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
|
||||||
|
|
||||||
if (mode == GL_SMOOTH) {
|
if (mode == GL_SMOOTH) {
|
||||||
@@ -526,7 +526,7 @@ static void i915ShadeModel(GLcontext *ctx, GLenum mode)
|
|||||||
*/
|
*/
|
||||||
void i915_update_fog( GLcontext *ctx )
|
void i915_update_fog( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
GLenum mode;
|
GLenum mode;
|
||||||
GLboolean enabled;
|
GLboolean enabled;
|
||||||
GLboolean try_pixel_fog;
|
GLboolean try_pixel_fog;
|
||||||
@@ -619,7 +619,7 @@ void i915_update_fog( GLcontext *ctx )
|
|||||||
|
|
||||||
static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
|
static void i915Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_FOG_COORDINATE_SOURCE_EXT:
|
case GL_FOG_COORDINATE_SOURCE_EXT:
|
||||||
@@ -671,7 +671,7 @@ static void i915Hint(GLcontext *ctx, GLenum target, GLenum state)
|
|||||||
|
|
||||||
static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(ctx);
|
struct i915_context *i915 = I915_CONTEXT(ctx);
|
||||||
|
|
||||||
switch(cap) {
|
switch(cap) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
@@ -785,7 +785,7 @@ static void i915Enable(GLcontext *ctx, GLenum cap, GLboolean state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void i915_init_packets( i915ContextPtr i915 )
|
static void i915_init_packets( struct i915_context *i915 )
|
||||||
{
|
{
|
||||||
intelScreenPrivate *screen = i915->intel.intelScreen;
|
intelScreenPrivate *screen = i915->intel.intelScreen;
|
||||||
|
|
||||||
@@ -823,7 +823,6 @@ static void i915_init_packets( i915ContextPtr i915 )
|
|||||||
ENABLE_STENCIL_WRITE_MASK |
|
ENABLE_STENCIL_WRITE_MASK |
|
||||||
STENCIL_WRITE_MASK(0xff));
|
STENCIL_WRITE_MASK(0xff));
|
||||||
|
|
||||||
|
|
||||||
i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
|
i915->state.Ctx[I915_CTXREG_IAB] = (_3DSTATE_INDEPENDENT_ALPHA_BLEND_CMD |
|
||||||
IAB_MODIFY_ENABLE |
|
IAB_MODIFY_ENABLE |
|
||||||
IAB_MODIFY_FUNC |
|
IAB_MODIFY_FUNC |
|
||||||
@@ -862,19 +861,15 @@ static void i915_init_packets( i915ContextPtr i915 )
|
|||||||
BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
|
BUF_3D_PITCH(screen->front.pitch * screen->cpp) |
|
||||||
BUF_3D_USE_FENCE);
|
BUF_3D_USE_FENCE);
|
||||||
|
|
||||||
|
|
||||||
i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
|
i915->state.Buffer[I915_DESTREG_DBUFADDR0] = _3DSTATE_BUF_INFO_CMD;
|
||||||
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
|
i915->state.Buffer[I915_DESTREG_DBUFADDR1] =
|
||||||
(BUF_3D_ID_DEPTH |
|
(BUF_3D_ID_DEPTH |
|
||||||
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
|
BUF_3D_PITCH(screen->depth.pitch * screen->cpp) |
|
||||||
BUF_3D_USE_FENCE);
|
BUF_3D_USE_FENCE);
|
||||||
i915->state.Buffer[I915_DESTREG_DBUFADDR2] = screen->depth.offset;
|
|
||||||
|
|
||||||
|
|
||||||
i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
|
i915->state.Buffer[I915_DESTREG_DV0] = _3DSTATE_DST_BUF_VARS_CMD;
|
||||||
|
|
||||||
switch (screen->fbFormat) {
|
switch (screen->fbFormat) {
|
||||||
case DV_PF_555:
|
|
||||||
case DV_PF_565:
|
case DV_PF_565:
|
||||||
i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
|
i915->state.Buffer[I915_DESTREG_DV1] = (DSTORG_HORT_BIAS(0x8) | /* .5 */
|
||||||
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
DSTORG_VERT_BIAS(0x8) | /* .5 */
|
||||||
@@ -905,9 +900,10 @@ static void i915_init_packets( i915ContextPtr i915 )
|
|||||||
* we get hardware contexts working.
|
* we get hardware contexts working.
|
||||||
*/
|
*/
|
||||||
i915->state.active = (I915_UPLOAD_PROGRAM |
|
i915->state.active = (I915_UPLOAD_PROGRAM |
|
||||||
I915_UPLOAD_STIPPLE |
|
I915_UPLOAD_STIPPLE |
|
||||||
I915_UPLOAD_CTX |
|
I915_UPLOAD_CTX |
|
||||||
I915_UPLOAD_BUFFERS);
|
I915_UPLOAD_BUFFERS |
|
||||||
|
I915_UPLOAD_INVARIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void i915InitStateFunctions( struct dd_function_table *functions )
|
void i915InitStateFunctions( struct dd_function_table *functions )
|
||||||
@@ -937,7 +933,7 @@ void i915InitStateFunctions( struct dd_function_table *functions )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i915InitState( i915ContextPtr i915 )
|
void i915InitState( struct i915_context *i915 )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &i915->intel.ctx;
|
GLcontext *ctx = &i915->intel.ctx;
|
||||||
|
|
||||||
|
|||||||
@@ -45,76 +45,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate space for and load the mesa images into the texture memory block.
|
|
||||||
* This will happen before drawing with a new texture, or drawing with a
|
|
||||||
* texture after it was swapped out or teximaged again.
|
|
||||||
*/
|
|
||||||
|
|
||||||
intelTextureObjectPtr i915AllocTexObj( struct gl_texture_object *texObj )
|
|
||||||
{
|
|
||||||
i915TextureObjectPtr t = CALLOC_STRUCT( i915_texture_object );
|
|
||||||
if ( !t )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
texObj->DriverData = t;
|
|
||||||
t->intel.base.tObj = texObj;
|
|
||||||
t->intel.dirty = I915_UPLOAD_TEX_ALL;
|
|
||||||
make_empty_list( &t->intel.base );
|
|
||||||
return &t->intel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void i915TexParameter( GLcontext *ctx, GLenum target,
|
|
||||||
struct gl_texture_object *tObj,
|
|
||||||
GLenum pname, const GLfloat *params )
|
|
||||||
{
|
|
||||||
i915TextureObjectPtr t = (i915TextureObjectPtr) tObj->DriverData;
|
|
||||||
|
|
||||||
switch (pname) {
|
|
||||||
case GL_TEXTURE_MIN_FILTER:
|
|
||||||
case GL_TEXTURE_MAG_FILTER:
|
|
||||||
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
|
||||||
case GL_TEXTURE_WRAP_S:
|
|
||||||
case GL_TEXTURE_WRAP_T:
|
|
||||||
case GL_TEXTURE_WRAP_R:
|
|
||||||
case GL_TEXTURE_BORDER_COLOR:
|
|
||||||
t->intel.dirty = I915_UPLOAD_TEX_ALL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GL_TEXTURE_COMPARE_MODE:
|
|
||||||
t->intel.dirty = I915_UPLOAD_TEX_ALL;
|
|
||||||
break;
|
|
||||||
case GL_TEXTURE_COMPARE_FUNC:
|
|
||||||
t->intel.dirty = I915_UPLOAD_TEX_ALL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GL_TEXTURE_BASE_LEVEL:
|
|
||||||
case GL_TEXTURE_MAX_LEVEL:
|
|
||||||
case GL_TEXTURE_MIN_LOD:
|
|
||||||
case GL_TEXTURE_MAX_LOD:
|
|
||||||
/* The i915 and its successors can do a lot of this without
|
|
||||||
* reloading the textures. A project for someone?
|
|
||||||
*/
|
|
||||||
intelFlush( ctx );
|
|
||||||
driSwapOutTextureObject( (driTextureObject *) t );
|
|
||||||
t->intel.dirty = I915_UPLOAD_TEX_ALL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void i915TexEnv( GLcontext *ctx, GLenum target,
|
static void i915TexEnv( GLcontext *ctx, GLenum target,
|
||||||
GLenum pname, const GLfloat *param )
|
GLenum pname, const GLfloat *param )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT( ctx );
|
struct i915_context *i915 = I915_CONTEXT( ctx );
|
||||||
GLuint unit = ctx->Texture.CurrentUnit;
|
|
||||||
|
|
||||||
switch (pname) {
|
switch (pname) {
|
||||||
case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */
|
case GL_TEXTURE_ENV_COLOR: /* Should be a tracked param */
|
||||||
@@ -139,13 +73,12 @@ static void i915TexEnv( GLcontext *ctx, GLenum target,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_TEXTURE_LOD_BIAS: {
|
case GL_TEXTURE_LOD_BIAS: {
|
||||||
int b = (int) ((*param) * 16.0);
|
GLuint unit = ctx->Texture.CurrentUnit;
|
||||||
|
GLint b = (int) ((*param) * 16.0);
|
||||||
if (b > 255) b = 255;
|
if (b > 255) b = 255;
|
||||||
if (b < -256) b = -256;
|
if (b < -256) b = -256;
|
||||||
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
|
I915_STATECHANGE(i915, I915_UPLOAD_TEX(unit));
|
||||||
i915->state.Tex[unit][I915_TEXREG_SS2] &= ~SS2_LOD_BIAS_MASK;
|
i915->lodbias_ss2[unit] = ((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
|
||||||
i915->state.Tex[unit][I915_TEXREG_SS2] |=
|
|
||||||
((b << SS2_LOD_BIAS_SHIFT) & SS2_LOD_BIAS_MASK);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,15 +89,8 @@ static void i915TexEnv( GLcontext *ctx, GLenum target,
|
|||||||
|
|
||||||
|
|
||||||
static void i915BindTexture( GLcontext *ctx, GLenum target,
|
static void i915BindTexture( GLcontext *ctx, GLenum target,
|
||||||
struct gl_texture_object *texObj )
|
struct gl_texture_object *texobj )
|
||||||
{
|
{
|
||||||
i915TextureObjectPtr tex = (i915TextureObjectPtr)texObj->DriverData;
|
|
||||||
|
|
||||||
if (tex->lastTarget != texObj->Target) {
|
|
||||||
tex->intel.dirty = I915_UPLOAD_TEX_ALL;
|
|
||||||
tex->lastTarget = texObj->Target;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need this if image format changes between bound textures.
|
/* Need this if image format changes between bound textures.
|
||||||
* Could try and shortcircuit by checking for differences in
|
* Could try and shortcircuit by checking for differences in
|
||||||
* state between incoming and outgoing textures:
|
* state between incoming and outgoing textures:
|
||||||
@@ -178,5 +104,4 @@ void i915InitTextureFuncs( struct dd_function_table *functions )
|
|||||||
{
|
{
|
||||||
functions->BindTexture = i915BindTexture;
|
functions->BindTexture = i915BindTexture;
|
||||||
functions->TexEnv = i915TexEnv;
|
functions->TexEnv = i915TexEnv;
|
||||||
functions->TexParameter = i915TexParameter;
|
|
||||||
}
|
}
|
||||||
|
|||||||
333
src/mesa/drivers/dri/i915/i915_tex_layout.c
Normal file
333
src/mesa/drivers/dri/i915/i915_tex_layout.c
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/* Code to layout images in a mipmap tree for i915 and i945
|
||||||
|
* respectively.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
|
#include "macros.h"
|
||||||
|
|
||||||
|
static GLint initial_offsets[6][2] = { {0,0},
|
||||||
|
{0,2},
|
||||||
|
{1,0},
|
||||||
|
{1,2},
|
||||||
|
{1,1},
|
||||||
|
{1,3} };
|
||||||
|
|
||||||
|
|
||||||
|
static GLint step_offsets[6][2] = { {0,2},
|
||||||
|
{0,2},
|
||||||
|
{-1,2},
|
||||||
|
{-1,2},
|
||||||
|
{-1,1},
|
||||||
|
{-1,1} };
|
||||||
|
|
||||||
|
static GLuint minify( GLuint d )
|
||||||
|
{
|
||||||
|
return MAX2(1, d>>1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt )
|
||||||
|
{
|
||||||
|
GLint i;
|
||||||
|
|
||||||
|
switch (mt->target) {
|
||||||
|
case GL_TEXTURE_CUBE_MAP: {
|
||||||
|
const GLuint dim = mt->width0;
|
||||||
|
GLuint face;
|
||||||
|
|
||||||
|
/* double pitch for cube layouts */
|
||||||
|
mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
|
||||||
|
mt->total_height = dim * 4;
|
||||||
|
|
||||||
|
for ( face = 0 ; face < 6 ; face++) {
|
||||||
|
GLuint x = initial_offsets[face][0] * dim;
|
||||||
|
GLuint y = initial_offsets[face][1] * dim;
|
||||||
|
GLuint d = dim;
|
||||||
|
|
||||||
|
for (i = mt->first_level; i <= mt->last_level; i++) {
|
||||||
|
intel_miptree_set_image_offset(mt, face, i,
|
||||||
|
x, y,
|
||||||
|
d, d, 1);
|
||||||
|
|
||||||
|
if (d == 0)
|
||||||
|
_mesa_printf("cube mipmap %d/%d (%d..%d) is 0x0\n",
|
||||||
|
face, i, mt->first_level, mt->last_level);
|
||||||
|
|
||||||
|
d >>= 1;
|
||||||
|
x += step_offsets[face][0] * d;
|
||||||
|
y += step_offsets[face][1] * d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_TEXTURE_3D: {
|
||||||
|
GLuint width = mt->width0;
|
||||||
|
GLuint height = mt->height0;
|
||||||
|
GLuint depth = mt->depth0;
|
||||||
|
|
||||||
|
/* Calculate the size of a single slice.
|
||||||
|
*/
|
||||||
|
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||||
|
mt->total_height = 0;
|
||||||
|
|
||||||
|
/* XXX: hardware expects/requires 9 levels at minimum.
|
||||||
|
*/
|
||||||
|
for ( i = mt->first_level ; i <= MAX2(8, mt->last_level) ; i++ ) {
|
||||||
|
intel_miptree_set_image_offset(mt, 0, i,
|
||||||
|
0, mt->total_height,
|
||||||
|
width, height, depth);
|
||||||
|
|
||||||
|
mt->total_height += MAX2(2, height);
|
||||||
|
|
||||||
|
width = minify(width);
|
||||||
|
height = minify(height);
|
||||||
|
depth = minify(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fixup depth_image_stride:
|
||||||
|
*/
|
||||||
|
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||||
|
mt->offset[0][i].depth_image_stride = mt->total_height * mt->pitch * mt->cpp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Multiply slice size by texture depth for total size. It's
|
||||||
|
* remarkable how wasteful of memory the i915 texture layouts
|
||||||
|
* are. They are largely fixed in the i945.
|
||||||
|
*/
|
||||||
|
mt->total_height *= mt->depth0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
GLuint width = mt->width0;
|
||||||
|
GLuint height = mt->height0;
|
||||||
|
|
||||||
|
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||||
|
mt->total_height = 0;
|
||||||
|
|
||||||
|
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||||
|
intel_miptree_set_image_offset(mt, 0, i,
|
||||||
|
0, mt->total_height,
|
||||||
|
width, height, 1);
|
||||||
|
|
||||||
|
if (mt->compressed)
|
||||||
|
mt->total_height += MAX2(1, height/4);
|
||||||
|
else
|
||||||
|
mt->total_height += MAX2(2, height);
|
||||||
|
|
||||||
|
width = minify(width);
|
||||||
|
height = minify(height);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||||
|
mt->pitch,
|
||||||
|
mt->total_height,
|
||||||
|
mt->cpp,
|
||||||
|
mt->pitch * mt->total_height * mt->cpp );
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt )
|
||||||
|
{
|
||||||
|
GLint i;
|
||||||
|
|
||||||
|
switch (mt->target) {
|
||||||
|
case GL_TEXTURE_CUBE_MAP: {
|
||||||
|
const GLuint dim = mt->width0;
|
||||||
|
GLuint face;
|
||||||
|
|
||||||
|
/* Depending on the size of the largest images, pitch can be
|
||||||
|
* determined either by the old-style packing of cubemap faces,
|
||||||
|
* or the final row of 4x4, 2x2 and 1x1 faces below this.
|
||||||
|
*/
|
||||||
|
if (dim > 32)
|
||||||
|
mt->pitch = ((dim * mt->cpp * 2 + 3) & ~3) / mt->cpp;
|
||||||
|
else
|
||||||
|
mt->pitch = 14 * 8;
|
||||||
|
|
||||||
|
mt->total_height = dim * 4 + 4;
|
||||||
|
|
||||||
|
|
||||||
|
for ( face = 0 ; face < 6 ; face++) {
|
||||||
|
GLuint x = initial_offsets[face][0] * dim;
|
||||||
|
GLuint y = initial_offsets[face][1] * dim;
|
||||||
|
GLuint d = dim;
|
||||||
|
|
||||||
|
if (dim == 4 && face >= 4) {
|
||||||
|
y = mt->total_height - 4;
|
||||||
|
x = (face - 4) * 8;
|
||||||
|
}
|
||||||
|
else if (dim < 4) {
|
||||||
|
y = mt->total_height - 4;
|
||||||
|
x = face * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||||
|
intel_miptree_set_image_offset(mt, face, i,
|
||||||
|
x, y,
|
||||||
|
d, d, 1);
|
||||||
|
|
||||||
|
d >>= 1;
|
||||||
|
|
||||||
|
switch (d) {
|
||||||
|
case 4:
|
||||||
|
switch (face) {
|
||||||
|
case FACE_POS_X:
|
||||||
|
case FACE_NEG_X:
|
||||||
|
x += step_offsets[face][0] * d;
|
||||||
|
y += step_offsets[face][1] * d;
|
||||||
|
break;
|
||||||
|
case FACE_POS_Y:
|
||||||
|
case FACE_NEG_Y:
|
||||||
|
y += 12;
|
||||||
|
x -= 8;
|
||||||
|
break;
|
||||||
|
case FACE_POS_Z:
|
||||||
|
case FACE_NEG_Z:
|
||||||
|
y = mt->total_height - 4;
|
||||||
|
x = (face - 4) * 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
y = mt->total_height - 4;
|
||||||
|
x = 16 + face * 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
x += 48;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
x += step_offsets[face][0] * d;
|
||||||
|
y += step_offsets[face][1] * d;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GL_TEXTURE_3D: {
|
||||||
|
GLuint width = mt->width0;
|
||||||
|
GLuint height = mt->height0;
|
||||||
|
GLuint depth = mt->depth0;
|
||||||
|
GLuint depth_pack_pitch;
|
||||||
|
GLuint depth_packing = 0;
|
||||||
|
|
||||||
|
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||||
|
mt->total_height = 0;
|
||||||
|
|
||||||
|
depth_pack_pitch = mt->pitch * mt->cpp;
|
||||||
|
|
||||||
|
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||||
|
|
||||||
|
intel_miptree_set_image_offset(mt, 0, i,
|
||||||
|
0, mt->total_height,
|
||||||
|
width, height, depth);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mt->total_height += MAX2(2, height) * MAX2((depth >> depth_packing), 1);
|
||||||
|
|
||||||
|
/* When alignment dominates, can't increase depth packing?
|
||||||
|
* Or does pitch grow??? What are the alignment constraints,
|
||||||
|
* anyway?
|
||||||
|
*/
|
||||||
|
if (depth_pack_pitch > 4) {
|
||||||
|
depth_packing++;
|
||||||
|
depth_pack_pitch >>= 2; /* KW: is this right?? */
|
||||||
|
}
|
||||||
|
|
||||||
|
width = minify(width);
|
||||||
|
height = minify(height);
|
||||||
|
depth = minify(depth);
|
||||||
|
|
||||||
|
/* XXX: Not sure how 3d textures work on i945 - where did
|
||||||
|
* t->depth_pitch get set in the old code. Did it ever work?
|
||||||
|
* Fix up later.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default: {
|
||||||
|
GLuint x = 0;
|
||||||
|
GLuint y = 0;
|
||||||
|
GLuint width = mt->width0;
|
||||||
|
GLuint height = mt->height0;
|
||||||
|
|
||||||
|
mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
|
||||||
|
mt->total_height = 0;
|
||||||
|
|
||||||
|
for ( i = mt->first_level ; i <= mt->last_level ; i++ ) {
|
||||||
|
intel_miptree_set_image_offset(mt, 0, i,
|
||||||
|
x, y,
|
||||||
|
width, height, 1);
|
||||||
|
|
||||||
|
|
||||||
|
/* LPT change: step right after second mipmap.
|
||||||
|
*/
|
||||||
|
if (i == 1)
|
||||||
|
x += mt->pitch / 2;
|
||||||
|
else {
|
||||||
|
GLuint img_height;
|
||||||
|
|
||||||
|
if (mt->compressed)
|
||||||
|
img_height = MAX2(1, height/4);
|
||||||
|
else
|
||||||
|
img_height = MAX2(2, height);
|
||||||
|
|
||||||
|
y += img_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Because the images are packed better, the final offset
|
||||||
|
* might not be the maximal one:
|
||||||
|
*/
|
||||||
|
mt->total_height = MAX2(mt->total_height, y);
|
||||||
|
|
||||||
|
width = minify(width);
|
||||||
|
height = minify(height);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
|
||||||
|
mt->pitch,
|
||||||
|
mt->total_height,
|
||||||
|
mt->cpp,
|
||||||
|
mt->pitch * mt->total_height * mt->cpp );
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -536,7 +536,7 @@ static void emit_program_fini( struct i915_fragment_program *p )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void i915EmitTextureProgram( i915ContextPtr i915 )
|
static void i915EmitTextureProgram( struct i915_context *i915 )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &i915->intel.ctx;
|
GLcontext *ctx = &i915->intel.ctx;
|
||||||
struct i915_fragment_program *p = &i915->tex_program;
|
struct i915_fragment_program *p = &i915->tex_program;
|
||||||
@@ -570,9 +570,9 @@ static void i915EmitTextureProgram( i915ContextPtr i915 )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i915ValidateTextureProgram( i915ContextPtr i915 )
|
void i915ValidateTextureProgram( struct i915_context *i915 )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = &i915->intel;
|
struct intel_context *intel = &i915->intel;
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct vertex_buffer *VB = &tnl->vb;
|
struct vertex_buffer *VB = &tnl->vb;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -37,14 +37,16 @@
|
|||||||
#include "tnl/t_vertex.h"
|
#include "tnl/t_vertex.h"
|
||||||
|
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
|
||||||
#include "i915_reg.h"
|
#include "i915_reg.h"
|
||||||
#include "i915_context.h"
|
#include "i915_context.h"
|
||||||
|
|
||||||
static void i915_render_start( intelContextPtr intel )
|
static void i915_render_start( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
i915ContextPtr i915 = I915_CONTEXT(intel);
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
if (ctx->FragmentProgram._Active)
|
if (ctx->FragmentProgram._Active)
|
||||||
i915ValidateFragmentProgram( i915 );
|
i915ValidateFragmentProgram( i915 );
|
||||||
@@ -53,42 +55,42 @@ static void i915_render_start( intelContextPtr intel )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void i915_reduced_primitive_state( intelContextPtr intel,
|
static void i915_reduced_primitive_state( struct intel_context *intel,
|
||||||
GLenum rprim )
|
GLenum rprim )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(intel);
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
|
GLuint st1 = i915->state.Stipple[I915_STPREG_ST1];
|
||||||
|
|
||||||
st1 &= ~ST1_ENABLE;
|
st1 &= ~ST1_ENABLE;
|
||||||
|
|
||||||
switch (rprim) {
|
switch (rprim) {
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
if (intel->ctx.Polygon.StippleFlag &&
|
if (intel->ctx.Polygon.StippleFlag &&
|
||||||
intel->hw_stipple)
|
intel->hw_stipple)
|
||||||
st1 |= ST1_ENABLE;
|
st1 |= ST1_ENABLE;
|
||||||
break;
|
break;
|
||||||
case GL_LINES:
|
case GL_LINES:
|
||||||
case GL_POINTS:
|
case GL_POINTS:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
i915->intel.reduced_primitive = rprim;
|
i915->intel.reduced_primitive = rprim;
|
||||||
|
|
||||||
if (st1 != i915->state.Stipple[I915_STPREG_ST1]) {
|
if (st1 != i915->state.Stipple[I915_STPREG_ST1]) {
|
||||||
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
|
I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);
|
||||||
i915->state.Stipple[I915_STPREG_ST1] = st1;
|
i915->state.Stipple[I915_STPREG_ST1] = st1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Pull apart the vertex format registers and figure out how large a
|
/* Pull apart the vertex format registers and figure out how large a
|
||||||
* vertex is supposed to be.
|
* vertex is supposed to be.
|
||||||
*/
|
*/
|
||||||
static GLboolean i915_check_vertex_size( intelContextPtr intel,
|
static GLboolean i915_check_vertex_size( struct intel_context *intel,
|
||||||
GLuint expected )
|
GLuint expected )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(intel);
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
int lis2 = i915->current->Ctx[I915_CTXREG_LIS2];
|
int lis2 = i915->current->Ctx[I915_CTXREG_LIS2];
|
||||||
int lis4 = i915->current->Ctx[I915_CTXREG_LIS4];
|
int lis4 = i915->current->Ctx[I915_CTXREG_LIS4];
|
||||||
int i, sz = 0;
|
int i, sz = 0;
|
||||||
@@ -132,11 +134,11 @@ static GLboolean i915_check_vertex_size( intelContextPtr intel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void i915_emit_invarient_state( intelContextPtr intel )
|
static void i915_emit_invarient_state( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
BATCH_LOCALS;
|
BATCH_LOCALS;
|
||||||
|
|
||||||
BEGIN_BATCH( 200 );
|
BEGIN_BATCH( 200, 0 );
|
||||||
|
|
||||||
OUT_BATCH(_3DSTATE_AA_CMD |
|
OUT_BATCH(_3DSTATE_AA_CMD |
|
||||||
AA_LINE_ECAAR_WIDTH_ENABLE |
|
AA_LINE_ECAAR_WIDTH_ENABLE |
|
||||||
@@ -204,21 +206,15 @@ static void i915_emit_invarient_state( intelContextPtr intel )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define emit( intel, state, size ) \
|
#define emit(intel, state, size ) \
|
||||||
do { \
|
intel_batchbuffer_data(intel->batch, state, size, 0 )
|
||||||
int k; \
|
|
||||||
BEGIN_BATCH( (size) / sizeof(GLuint)); \
|
|
||||||
for (k = 0 ; k < (size) / sizeof(GLuint) ; k++) \
|
|
||||||
OUT_BATCH((state)[k]); \
|
|
||||||
ADVANCE_BATCH(); \
|
|
||||||
} while (0);
|
|
||||||
|
|
||||||
|
|
||||||
/* Push the state into the sarea and/or texture memory.
|
/* Push the state into the sarea and/or texture memory.
|
||||||
*/
|
*/
|
||||||
static void i915_emit_state( intelContextPtr intel )
|
static void i915_emit_state( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(intel);
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
struct i915_hw_state *state = i915->current;
|
struct i915_hw_state *state = i915->current;
|
||||||
int i;
|
int i;
|
||||||
GLuint dirty;
|
GLuint dirty;
|
||||||
@@ -233,27 +229,48 @@ static void i915_emit_state( intelContextPtr intel )
|
|||||||
dirty = state->active & ~state->emitted;
|
dirty = state->active & ~state->emitted;
|
||||||
|
|
||||||
|
|
||||||
if (VERBOSE)
|
if (INTEL_DEBUG & DEBUG_STATE)
|
||||||
fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
|
fprintf(stderr, "%s dirty: %x\n", __FUNCTION__, dirty);
|
||||||
|
|
||||||
|
if (dirty & I915_UPLOAD_INVARIENT) {
|
||||||
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_INVARIENT:\n");
|
||||||
|
i915_emit_invarient_state( intel );
|
||||||
|
}
|
||||||
|
|
||||||
if (dirty & I915_UPLOAD_CTX) {
|
if (dirty & I915_UPLOAD_CTX) {
|
||||||
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CTX:\n");
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CTX:\n");
|
||||||
emit( i915, state->Ctx, sizeof(state->Ctx) );
|
emit(intel, state->Ctx, sizeof(state->Ctx) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty & I915_UPLOAD_BUFFERS) {
|
if (dirty & I915_UPLOAD_BUFFERS) {
|
||||||
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_BUFFERS:\n");
|
||||||
emit( i915, state->Buffer, sizeof(state->Buffer) );
|
|
||||||
|
BEGIN_BATCH(I915_DEST_SETUP_SIZE, 0);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]);
|
||||||
|
OUT_RELOC(state->draw_region->buffer, BM_MEM_AGP|BM_WRITE, 0);
|
||||||
|
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]);
|
||||||
|
OUT_RELOC(state->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0);
|
||||||
|
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_DV0]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_DV1]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_SENABLE]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_SR0]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_SR1]);
|
||||||
|
OUT_BATCH(state->Buffer[I915_DESTREG_SR2]);
|
||||||
|
ADVANCE_BATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty & I915_UPLOAD_STIPPLE) {
|
if (dirty & I915_UPLOAD_STIPPLE) {
|
||||||
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n");
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_STIPPLE:\n");
|
||||||
emit( i915, state->Stipple, sizeof(state->Stipple) );
|
emit(intel, state->Stipple, sizeof(state->Stipple) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty & I915_UPLOAD_FOG) {
|
if (dirty & I915_UPLOAD_FOG) {
|
||||||
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_FOG:\n");
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_FOG:\n");
|
||||||
emit( i915, state->Fog, sizeof(state->Fog) );
|
emit(intel, state->Fog, sizeof(state->Fog) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Combine all the dirty texture state into a single command to
|
/* Combine all the dirty texture state into a single command to
|
||||||
@@ -266,18 +283,29 @@ static void i915_emit_state( intelContextPtr intel )
|
|||||||
if (dirty & I915_UPLOAD_TEX(i))
|
if (dirty & I915_UPLOAD_TEX(i))
|
||||||
nr++;
|
nr++;
|
||||||
|
|
||||||
BEGIN_BATCH(2+nr*3);
|
BEGIN_BATCH(2+nr*3, 0);
|
||||||
OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr));
|
OUT_BATCH(_3DSTATE_MAP_STATE | (3*nr));
|
||||||
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
|
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
|
||||||
for (i = 0 ; i < I915_TEX_UNITS ; i++)
|
for (i = 0 ; i < I915_TEX_UNITS ; i++)
|
||||||
if (dirty & I915_UPLOAD_TEX(i)) {
|
if (dirty & I915_UPLOAD_TEX(i)) {
|
||||||
OUT_BATCH(state->Tex[i][I915_TEXREG_MS2]);
|
|
||||||
|
if (state->tex_region[i]) {
|
||||||
|
OUT_RELOC(state->tex_region[i]->buffer,
|
||||||
|
BM_MEM_AGP|BM_READ,
|
||||||
|
state->tex_offset[i]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(i == 0);
|
||||||
|
assert(state == &i915->meta);
|
||||||
|
OUT_BATCH(0);
|
||||||
|
}
|
||||||
|
|
||||||
OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
|
OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]);
|
||||||
OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
|
OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]);
|
||||||
}
|
}
|
||||||
ADVANCE_BATCH();
|
ADVANCE_BATCH();
|
||||||
|
|
||||||
BEGIN_BATCH(2+nr*3);
|
BEGIN_BATCH(2+nr*3, 0);
|
||||||
OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr));
|
OUT_BATCH(_3DSTATE_SAMPLER_STATE | (3*nr));
|
||||||
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
|
OUT_BATCH((dirty & I915_UPLOAD_TEX_ALL) >> I915_UPLOAD_TEX_0_SHIFT);
|
||||||
for (i = 0 ; i < I915_TEX_UNITS ; i++)
|
for (i = 0 ; i < I915_TEX_UNITS ; i++)
|
||||||
@@ -290,64 +318,65 @@ static void i915_emit_state( intelContextPtr intel )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dirty & I915_UPLOAD_CONSTANTS) {
|
if (dirty & I915_UPLOAD_CONSTANTS) {
|
||||||
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_CONSTANTS:\n");
|
||||||
emit( i915, state->Constant, state->ConstantSize * sizeof(GLuint) );
|
emit(intel, state->Constant, state->ConstantSize * sizeof(GLuint) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty & I915_UPLOAD_PROGRAM) {
|
if (dirty & I915_UPLOAD_PROGRAM) {
|
||||||
if (VERBOSE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
|
if (INTEL_DEBUG & DEBUG_STATE) fprintf(stderr, "I915_UPLOAD_PROGRAM:\n");
|
||||||
|
|
||||||
assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize);
|
assert((state->Program[0] & 0x1ff)+2 == state->ProgramSize);
|
||||||
|
|
||||||
emit( i915, state->Program, state->ProgramSize * sizeof(GLuint) );
|
emit(intel, state->Program, state->ProgramSize * sizeof(GLuint) );
|
||||||
if (VERBOSE)
|
if (INTEL_DEBUG & DEBUG_STATE)
|
||||||
i915_disassemble_program( state->Program, state->ProgramSize );
|
i915_disassemble_program( state->Program, state->ProgramSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
state->emitted |= dirty;
|
state->emitted |= dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i915_destroy_context( intelContextPtr intel )
|
static void i915_destroy_context( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
_tnl_free_vertices(&intel->ctx);
|
_tnl_free_vertices(&intel->ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i915_set_draw_offset( intelContextPtr intel, int offset )
|
static void i915_set_draw_region( struct intel_context *intel,
|
||||||
|
struct intel_region *draw_region,
|
||||||
|
struct intel_region *depth_region)
|
||||||
{
|
{
|
||||||
i915ContextPtr i915 = I915_CONTEXT(intel);
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
|
||||||
|
intel_region_release(intel, &i915->state.draw_region);
|
||||||
|
intel_region_release(intel, &i915->state.depth_region);
|
||||||
|
intel_region_reference(&i915->state.draw_region, draw_region);
|
||||||
|
intel_region_reference(&i915->state.depth_region, depth_region);
|
||||||
|
|
||||||
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
|
I915_STATECHANGE( i915, I915_UPLOAD_BUFFERS );
|
||||||
i915->state.Buffer[I915_DESTREG_CBUFADDR2] = offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i915_lost_hardware( intelContextPtr intel )
|
static void i915_lost_hardware( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
I915_CONTEXT(intel)->state.emitted = 0;
|
struct i915_context *i915 = i915_context(&intel->ctx);
|
||||||
|
i915->state.emitted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void i915_emit_flush( intelContextPtr intel )
|
static GLuint i915_flush_cmd( void )
|
||||||
{
|
{
|
||||||
BATCH_LOCALS;
|
return MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE;
|
||||||
|
|
||||||
BEGIN_BATCH(2);
|
|
||||||
OUT_BATCH( MI_FLUSH | FLUSH_MAP_CACHE | FLUSH_RENDER_CACHE );
|
|
||||||
OUT_BATCH( 0 );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void i915InitVtbl( i915ContextPtr i915 )
|
void i915InitVtbl( struct i915_context *i915 )
|
||||||
{
|
{
|
||||||
i915->intel.vtbl.alloc_tex_obj = i915AllocTexObj;
|
|
||||||
i915->intel.vtbl.check_vertex_size = i915_check_vertex_size;
|
i915->intel.vtbl.check_vertex_size = i915_check_vertex_size;
|
||||||
i915->intel.vtbl.clear_with_tris = i915ClearWithTris;
|
|
||||||
i915->intel.vtbl.destroy = i915_destroy_context;
|
i915->intel.vtbl.destroy = i915_destroy_context;
|
||||||
i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state;
|
i915->intel.vtbl.emit_invarient_state = i915_emit_invarient_state;
|
||||||
i915->intel.vtbl.emit_state = i915_emit_state;
|
i915->intel.vtbl.emit_state = i915_emit_state;
|
||||||
i915->intel.vtbl.lost_hardware = i915_lost_hardware;
|
i915->intel.vtbl.lost_hardware = i915_lost_hardware;
|
||||||
i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state;
|
i915->intel.vtbl.reduced_primitive_state = i915_reduced_primitive_state;
|
||||||
i915->intel.vtbl.render_start = i915_render_start;
|
i915->intel.vtbl.render_start = i915_render_start;
|
||||||
i915->intel.vtbl.set_draw_offset = i915_set_draw_offset;
|
i915->intel.vtbl.set_draw_region = i915_set_draw_region;
|
||||||
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
|
i915->intel.vtbl.update_texture_state = i915UpdateTextureState;
|
||||||
i915->intel.vtbl.emit_flush = i915_emit_flush;
|
i915->intel.vtbl.flush_cmd = i915_flush_cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
* All Rights Reserved.
|
* All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
@@ -25,664 +25,266 @@
|
|||||||
*
|
*
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "mtypes.h"
|
|
||||||
#include "context.h"
|
|
||||||
#include "enums.h"
|
|
||||||
|
|
||||||
#include "intel_reg.h"
|
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
#include "intel_context.h"
|
#include "intel_ioctl.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
/* Relocations in kernel space:
|
||||||
|
* - pass dma buffer seperately
|
||||||
|
* - memory manager knows how to patch
|
||||||
/* ================================================================
|
* - pass list of dependent buffers
|
||||||
* Performance monitoring functions
|
* - pass relocation list
|
||||||
|
*
|
||||||
|
* Either:
|
||||||
|
* - get back an offset for buffer to fire
|
||||||
|
* - memory manager knows how to fire buffer
|
||||||
|
*
|
||||||
|
* Really want the buffer to be AGP and pinned.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void intel_fill_box( intelContextPtr intel,
|
/* Cliprect fence: The highest fence protecting a dma buffer
|
||||||
GLshort x, GLshort y,
|
* containing explicit cliprect information. Like the old drawable
|
||||||
GLshort w, GLshort h,
|
* lock but irq-driven. X server must wait for this fence to expire
|
||||||
GLubyte r, GLubyte g, GLubyte b )
|
* before changing cliprects [and then doing sw rendering?]. For
|
||||||
|
* other dma buffers, the scheduler will grab current cliprect info
|
||||||
|
* and mix into buffer. X server must hold the lock while changing
|
||||||
|
* cliprects??? Make per-drawable. Need cliprects in shared memory
|
||||||
|
* -- beats storing them with every cmd buffer in the queue.
|
||||||
|
*
|
||||||
|
* ==> X server must wait for this fence to expire before touching the
|
||||||
|
* framebuffer with new cliprects.
|
||||||
|
*
|
||||||
|
* ==> Cliprect-dependent buffers associated with a
|
||||||
|
* cliprect-timestamp. All of the buffers associated with a timestamp
|
||||||
|
* must go to hardware before any buffer with a newer timestamp.
|
||||||
|
*
|
||||||
|
* ==> Dma should be queued per-drawable for correct X/GL
|
||||||
|
* synchronization. Or can fences be used for this?
|
||||||
|
*
|
||||||
|
* Applies to: Blit operations, metaops, X server operations -- X
|
||||||
|
* server automatically waits on its own dma to complete before
|
||||||
|
* modifying cliprects ???
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void intel_dump_batchbuffer( unsigned offset,
|
||||||
|
int *ptr,
|
||||||
|
int count )
|
||||||
{
|
{
|
||||||
intelEmitFillBlitLocked( intel,
|
int i;
|
||||||
intel->intelScreen->cpp,
|
fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count/4);
|
||||||
intel->intelScreen->back.pitch,
|
for (i = 0; i < count/4; i += 4)
|
||||||
intel->intelScreen->front.offset,
|
fprintf(stderr, "0x%x:\t0x%08x 0x%08x 0x%08x 0x%08x\n",
|
||||||
x, y, w, h,
|
offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
|
||||||
INTEL_PACKCOLOR(intel->intelScreen->fbFormat,
|
fprintf(stderr, "END BATCH\n\n\n");
|
||||||
r,g,b,0xff));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intel_draw_performance_boxes( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
/* Purple box for page flipping
|
|
||||||
*/
|
|
||||||
if ( intel->perf_boxes & I830_BOX_FLIP )
|
|
||||||
intel_fill_box( intel, 4, 4, 8, 8, 255, 0, 255 );
|
|
||||||
|
|
||||||
/* Red box if we have to wait for idle at any point
|
|
||||||
*/
|
|
||||||
if ( intel->perf_boxes & I830_BOX_WAIT )
|
|
||||||
intel_fill_box( intel, 16, 4, 8, 8, 255, 0, 0 );
|
|
||||||
|
|
||||||
/* Blue box: lost context?
|
|
||||||
*/
|
|
||||||
if ( intel->perf_boxes & I830_BOX_LOST_CONTEXT )
|
|
||||||
intel_fill_box( intel, 28, 4, 8, 8, 0, 0, 255 );
|
|
||||||
|
|
||||||
/* Yellow box for texture swaps
|
|
||||||
*/
|
|
||||||
if ( intel->perf_boxes & I830_BOX_TEXTURE_LOAD )
|
|
||||||
intel_fill_box( intel, 40, 4, 8, 8, 255, 255, 0 );
|
|
||||||
|
|
||||||
/* Green box if hardware never idles (as far as we can tell)
|
|
||||||
*/
|
|
||||||
if ( !(intel->perf_boxes & I830_BOX_RING_EMPTY) )
|
|
||||||
intel_fill_box( intel, 64, 4, 8, 8, 0, 255, 0 );
|
|
||||||
|
|
||||||
|
|
||||||
/* Draw bars indicating number of buffers allocated
|
|
||||||
* (not a great measure, easily confused)
|
|
||||||
*/
|
|
||||||
#if 0
|
|
||||||
if (intel->dma_used) {
|
|
||||||
int bar = intel->dma_used / 10240;
|
|
||||||
if (bar > 100) bar = 100;
|
|
||||||
if (bar < 1) bar = 1;
|
|
||||||
intel_fill_box( intel, 4, 16, bar, 4, 196, 128, 128 );
|
|
||||||
intel->dma_used = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
intel->perf_boxes = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void intel_batchbuffer_reset( struct intel_batchbuffer *batch )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int bad_prim_vertex_nr( int primitive, int nr )
|
|
||||||
{
|
{
|
||||||
switch (primitive & PRIM3D_MASK) {
|
bmBufferData(batch->bm,
|
||||||
case PRIM3D_POINTLIST:
|
batch->buffer,
|
||||||
return nr < 1;
|
BATCH_SZ,
|
||||||
case PRIM3D_LINELIST:
|
NULL,
|
||||||
return (nr & 1) || nr == 0;
|
0);
|
||||||
case PRIM3D_LINESTRIP:
|
|
||||||
return nr < 2;
|
if (!batch->list)
|
||||||
case PRIM3D_TRILIST:
|
batch->list = bmNewBufferList();
|
||||||
case PRIM3D_RECTLIST:
|
|
||||||
return nr % 3 || nr == 0;
|
batch->list->nr = 0;
|
||||||
case PRIM3D_POLY:
|
batch->nr_relocs = 0;
|
||||||
case PRIM3D_TRIFAN:
|
batch->flags = 0;
|
||||||
case PRIM3D_TRISTRIP:
|
|
||||||
case PRIM3D_TRISTRIP_RVRSE:
|
bmAddBuffer( batch->list,
|
||||||
return nr < 3;
|
batch->buffer,
|
||||||
default:
|
0,
|
||||||
return 1;
|
NULL,
|
||||||
}
|
&batch->offset[batch->list->nr]);
|
||||||
|
|
||||||
|
batch->map = bmMapBuffer(batch->bm, batch->buffer,
|
||||||
|
BM_MEM_AGP|BM_MEM_LOCAL|BM_CLIENT|BM_WRITE);
|
||||||
|
batch->ptr = batch->map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intel_flush_inline_primitive( GLcontext *ctx )
|
/*======================================================================
|
||||||
|
* Public functions
|
||||||
|
*/
|
||||||
|
struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
struct intel_batchbuffer *batch = calloc(sizeof(*batch), 1);
|
||||||
GLuint used = intel->batch.ptr - intel->prim.start_ptr;
|
|
||||||
GLuint vertcount;
|
|
||||||
|
|
||||||
assert(intel->prim.primitive != ~0);
|
batch->intel = intel;
|
||||||
|
batch->bm = intel->bm;
|
||||||
|
|
||||||
if (1) {
|
bmGenBuffers(intel->bm, 1, &batch->buffer);
|
||||||
/* Check vertex size against the vertex we're specifying to
|
intel_batchbuffer_reset( batch );
|
||||||
* hardware. If it's wrong, ditch the primitive.
|
return batch;
|
||||||
*/
|
}
|
||||||
if (!intel->vtbl.check_vertex_size( intel, intel->vertex_size ))
|
|
||||||
goto do_discard;
|
|
||||||
|
|
||||||
vertcount = (used - 4)/ (intel->vertex_size * 4);
|
void intel_batchbuffer_free( struct intel_batchbuffer *batch )
|
||||||
|
{
|
||||||
if (!vertcount)
|
if (batch->map)
|
||||||
goto do_discard;
|
bmUnmapBuffer(batch->bm, batch->buffer);
|
||||||
|
|
||||||
if (vertcount * intel->vertex_size * 4 != used - 4) {
|
|
||||||
fprintf(stderr, "vertex size confusion %d %d\n", used,
|
|
||||||
intel->vertex_size * vertcount * 4);
|
|
||||||
goto do_discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bad_prim_vertex_nr( intel->prim.primitive, vertcount )) {
|
|
||||||
fprintf(stderr, "bad_prim_vertex_nr %x %d\n", intel->prim.primitive,
|
|
||||||
vertcount);
|
|
||||||
goto do_discard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (used < 8)
|
|
||||||
goto do_discard;
|
|
||||||
|
|
||||||
*(int *)intel->prim.start_ptr = (_3DPRIMITIVE |
|
|
||||||
intel->prim.primitive |
|
|
||||||
(used/4-2));
|
|
||||||
|
|
||||||
goto finished;
|
|
||||||
|
|
||||||
do_discard:
|
free(batch);
|
||||||
intel->batch.ptr -= used;
|
|
||||||
intel->batch.space += used;
|
|
||||||
assert(intel->batch.space >= 0);
|
|
||||||
|
|
||||||
finished:
|
|
||||||
intel->prim.primitive = ~0;
|
|
||||||
intel->prim.start_ptr = 0;
|
|
||||||
intel->prim.flush = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: Push this whole function into bufmgr.
|
||||||
/* Emit a primitive referencing vertices in a vertex buffer.
|
|
||||||
*/
|
*/
|
||||||
void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim )
|
static void do_flush_locked( struct intel_batchbuffer *batch,
|
||||||
|
GLuint used,
|
||||||
|
GLboolean ignore_cliprects)
|
||||||
{
|
{
|
||||||
BATCH_LOCALS;
|
GLuint *ptr;
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
if (0)
|
bmValidateBufferList( batch->bm,
|
||||||
fprintf(stderr, "%s %x\n", __FUNCTION__, prim);
|
batch->list,
|
||||||
|
BM_MEM_AGP );
|
||||||
|
|
||||||
|
/* Apply the relocations. This nasty map indicates to me that the
|
||||||
/* Finish any in-progress primitive:
|
* whole task should be done internally by the memory manager, and
|
||||||
|
* that dma buffers probably need to be pinned within agp space.
|
||||||
*/
|
*/
|
||||||
INTEL_FIREVERTICES( intel );
|
ptr = (GLuint *)bmMapBuffer(batch->bm, batch->buffer,
|
||||||
|
BM_NO_MOVE|BM_NO_UPLOAD|
|
||||||
|
BM_NO_EVICT|BM_MEM_AGP|
|
||||||
|
BM_WRITE);
|
||||||
|
|
||||||
|
for (i = 0; i < batch->nr_relocs; i++) {
|
||||||
|
struct buffer_reloc *r = &batch->reloc[i];
|
||||||
|
|
||||||
|
DBG("apply fixup at offset 0x%x, elem %d (buf %d, offset 0x%x), delta 0x%x\n",
|
||||||
|
r->offset, r->elem, batch->list->elem[r->elem].buffer,
|
||||||
|
batch->offset[r->elem], r->delta);
|
||||||
|
|
||||||
|
ptr[r->offset/4] = batch->offset[r->elem] + r->delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_DMA)
|
||||||
|
intel_dump_batchbuffer( 0, ptr, used );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bmUnmapBuffer(batch->bm, batch->buffer);
|
||||||
|
|
||||||
|
|
||||||
|
/* Fire the batch buffer, which was uploaded above:
|
||||||
|
*/
|
||||||
|
intel_batch_ioctl(batch->intel,
|
||||||
|
batch->offset[0],
|
||||||
|
used,
|
||||||
|
ignore_cliprects);
|
||||||
|
|
||||||
/* Emit outstanding state:
|
batch->last_fence = bmFenceBufferList(batch->bm, batch->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = batch->intel;
|
||||||
|
GLuint used = batch->ptr - batch->map;
|
||||||
|
|
||||||
|
if (used == 0)
|
||||||
|
return batch->last_fence;
|
||||||
|
|
||||||
|
/* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a
|
||||||
|
* performance drain that we would like to avoid.
|
||||||
*/
|
*/
|
||||||
intel->vtbl.emit_state( intel );
|
if (used & 4) {
|
||||||
|
((int *)batch->ptr)[0] = intel->vtbl.flush_cmd();
|
||||||
/* Make sure there is some space in this buffer:
|
((int *)batch->ptr)[1] = 0;
|
||||||
*/
|
((int *)batch->ptr)[2] = MI_BATCH_BUFFER_END;
|
||||||
if (intel->vertex_size * 10 * sizeof(GLuint) >= intel->batch.space)
|
used += 12;
|
||||||
intelFlushBatch(intel, GL_TRUE);
|
|
||||||
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
if (((int)intel->batch.ptr) & 0x4) {
|
|
||||||
BEGIN_BATCH(1);
|
|
||||||
OUT_BATCH(0);
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Emit a slot which will be filled with the inline primitive
|
|
||||||
* command later.
|
|
||||||
*/
|
|
||||||
BEGIN_BATCH(2);
|
|
||||||
OUT_BATCH( 0 );
|
|
||||||
|
|
||||||
intel->prim.start_ptr = batch_ptr;
|
|
||||||
intel->prim.primitive = prim;
|
|
||||||
intel->prim.flush = intel_flush_inline_primitive;
|
|
||||||
|
|
||||||
OUT_BATCH( 0 );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelRestartInlinePrimitive( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
GLuint prim = intel->prim.primitive;
|
|
||||||
|
|
||||||
intel_flush_inline_primitive( &intel->ctx );
|
|
||||||
if (1) intelFlushBatch(intel, GL_TRUE); /* GL_TRUE - is critical */
|
|
||||||
intelStartInlinePrimitive( intel, prim );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelWrapInlinePrimitive( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
GLuint prim = intel->prim.primitive;
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
intel_flush_inline_primitive( &intel->ctx );
|
|
||||||
intelFlushBatch(intel, GL_TRUE);
|
|
||||||
intelStartInlinePrimitive( intel, prim );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Emit a primitive with space for inline vertices.
|
|
||||||
*/
|
|
||||||
GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
|
|
||||||
int primitive,
|
|
||||||
int dwords,
|
|
||||||
int vertex_size )
|
|
||||||
{
|
|
||||||
GLuint *tmp = 0;
|
|
||||||
BATCH_LOCALS;
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s 0x%x %d\n", __FUNCTION__, primitive, dwords);
|
|
||||||
|
|
||||||
/* Emit outstanding state:
|
|
||||||
*/
|
|
||||||
intel->vtbl.emit_state( intel );
|
|
||||||
|
|
||||||
|
|
||||||
if (1) {
|
|
||||||
int used = dwords * 4;
|
|
||||||
int vertcount;
|
|
||||||
|
|
||||||
/* Check vertex size against the vertex we're specifying to
|
|
||||||
* hardware. If it's wrong, ditch the primitive.
|
|
||||||
*/
|
|
||||||
if (!intel->vtbl.check_vertex_size( intel, vertex_size ))
|
|
||||||
goto do_discard;
|
|
||||||
|
|
||||||
vertcount = dwords / vertex_size;
|
|
||||||
|
|
||||||
if (dwords % vertex_size) {
|
|
||||||
fprintf(stderr, "did not request a whole number of vertices\n");
|
|
||||||
goto do_discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bad_prim_vertex_nr( primitive, vertcount )) {
|
|
||||||
fprintf(stderr, "bad_prim_vertex_nr %x %d\n", primitive, vertcount);
|
|
||||||
goto do_discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (used < 8)
|
|
||||||
goto do_discard;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Emit 3D_PRIMITIVE commands:
|
|
||||||
*/
|
|
||||||
BEGIN_BATCH(1 + dwords);
|
|
||||||
OUT_BATCH( _3DPRIMITIVE |
|
|
||||||
primitive |
|
|
||||||
(dwords-1) );
|
|
||||||
|
|
||||||
tmp = (GLuint *)batch_ptr;
|
|
||||||
batch_ptr += dwords * 4;
|
|
||||||
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
|
|
||||||
do_discard:
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy the back buffer to the front buffer.
|
|
||||||
*/
|
|
||||||
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
|
|
||||||
{
|
|
||||||
intelContextPtr intel;
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
assert(dPriv);
|
|
||||||
assert(dPriv->driContextPriv);
|
|
||||||
assert(dPriv->driContextPriv->driverPrivate);
|
|
||||||
|
|
||||||
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
|
|
||||||
|
|
||||||
intelFlush( &intel->ctx );
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
{
|
|
||||||
intelScreenPrivate *intelScreen = intel->intelScreen;
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
int nbox = dPriv->numClipRects;
|
|
||||||
drm_clip_rect_t *pbox = dPriv->pClipRects;
|
|
||||||
int pitch = intelScreen->front.pitch;
|
|
||||||
int cpp = intelScreen->cpp;
|
|
||||||
int i;
|
|
||||||
GLuint CMD, BR13;
|
|
||||||
BATCH_LOCALS;
|
|
||||||
|
|
||||||
switch(cpp) {
|
|
||||||
case 2:
|
|
||||||
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
|
|
||||||
CMD = XY_SRC_COPY_BLT_CMD;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
|
|
||||||
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
|
|
||||||
XY_SRC_COPY_BLT_WRITE_RGB);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
|
|
||||||
CMD = XY_SRC_COPY_BLT_CMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
intel_draw_performance_boxes( intel );
|
|
||||||
|
|
||||||
for (i = 0 ; i < nbox; i++, pbox++)
|
|
||||||
{
|
|
||||||
if (pbox->x1 > pbox->x2 ||
|
|
||||||
pbox->y1 > pbox->y2 ||
|
|
||||||
pbox->x2 > intelScreen->width ||
|
|
||||||
pbox->y2 > intelScreen->height)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
BEGIN_BATCH( 8);
|
|
||||||
OUT_BATCH( CMD );
|
|
||||||
OUT_BATCH( BR13 );
|
|
||||||
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
|
|
||||||
OUT_BATCH( (pbox->y2 << 16) | pbox->x2 );
|
|
||||||
|
|
||||||
if (intel->sarea->pf_current_page == 0)
|
|
||||||
OUT_BATCH( intelScreen->front.offset );
|
|
||||||
else
|
|
||||||
OUT_BATCH( intelScreen->back.offset );
|
|
||||||
|
|
||||||
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
|
|
||||||
OUT_BATCH( BR13 & 0xffff );
|
|
||||||
|
|
||||||
if (intel->sarea->pf_current_page == 0)
|
|
||||||
OUT_BATCH( intelScreen->back.offset );
|
|
||||||
else
|
|
||||||
OUT_BATCH( intelScreen->front.offset );
|
|
||||||
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intelFlushBatchLocked( intel, GL_TRUE, GL_TRUE, GL_TRUE );
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelEmitFillBlitLocked( intelContextPtr intel,
|
|
||||||
GLuint cpp,
|
|
||||||
GLshort dst_pitch,
|
|
||||||
GLuint dst_offset,
|
|
||||||
GLshort x, GLshort y,
|
|
||||||
GLshort w, GLshort h,
|
|
||||||
GLuint color )
|
|
||||||
{
|
|
||||||
GLuint BR13, CMD;
|
|
||||||
BATCH_LOCALS;
|
|
||||||
|
|
||||||
dst_pitch *= cpp;
|
|
||||||
|
|
||||||
switch(cpp) {
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
BR13 = dst_pitch | (0xF0 << 16) | (1<<24);
|
|
||||||
CMD = XY_COLOR_BLT_CMD;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25);
|
|
||||||
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
|
|
||||||
XY_COLOR_BLT_WRITE_RGB);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_BATCH( 6);
|
|
||||||
OUT_BATCH( CMD );
|
|
||||||
OUT_BATCH( BR13 );
|
|
||||||
OUT_BATCH( (y << 16) | x );
|
|
||||||
OUT_BATCH( ((y+h) << 16) | (x+w) );
|
|
||||||
OUT_BATCH( dst_offset );
|
|
||||||
OUT_BATCH( color );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy BitBlt
|
|
||||||
*/
|
|
||||||
void intelEmitCopyBlitLocked( intelContextPtr intel,
|
|
||||||
GLuint cpp,
|
|
||||||
GLshort src_pitch,
|
|
||||||
GLuint src_offset,
|
|
||||||
GLshort dst_pitch,
|
|
||||||
GLuint dst_offset,
|
|
||||||
GLshort src_x, GLshort src_y,
|
|
||||||
GLshort dst_x, GLshort dst_y,
|
|
||||||
GLshort w, GLshort h )
|
|
||||||
{
|
|
||||||
GLuint CMD, BR13;
|
|
||||||
int dst_y2 = dst_y + h;
|
|
||||||
int dst_x2 = dst_x + w;
|
|
||||||
BATCH_LOCALS;
|
|
||||||
|
|
||||||
src_pitch *= cpp;
|
|
||||||
dst_pitch *= cpp;
|
|
||||||
|
|
||||||
switch(cpp) {
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
BR13 = dst_pitch | (0xCC << 16) | (1<<24);
|
|
||||||
CMD = XY_SRC_COPY_BLT_CMD;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25);
|
|
||||||
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
|
|
||||||
XY_SRC_COPY_BLT_WRITE_RGB);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dst_y2 < dst_y ||
|
|
||||||
dst_x2 < dst_x) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BEGIN_BATCH( 12);
|
|
||||||
OUT_BATCH( CMD );
|
|
||||||
OUT_BATCH( BR13 );
|
|
||||||
OUT_BATCH( (dst_y << 16) | dst_x );
|
|
||||||
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
|
|
||||||
OUT_BATCH( dst_offset );
|
|
||||||
OUT_BATCH( (src_y << 16) | src_x );
|
|
||||||
OUT_BATCH( src_pitch );
|
|
||||||
OUT_BATCH( src_offset );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
|
|
||||||
GLint cx1, GLint cy1, GLint cw, GLint ch)
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
|
||||||
intelScreenPrivate *intelScreen = intel->intelScreen;
|
|
||||||
GLuint clear_depth, clear_color;
|
|
||||||
GLint cx, cy;
|
|
||||||
GLint pitch = intelScreen->front.pitch;
|
|
||||||
GLint cpp = intelScreen->cpp;
|
|
||||||
GLint i;
|
|
||||||
GLuint BR13, CMD, D_CMD;
|
|
||||||
BATCH_LOCALS;
|
|
||||||
|
|
||||||
|
|
||||||
clear_color = intel->ClearColor;
|
|
||||||
clear_depth = 0;
|
|
||||||
|
|
||||||
if (flags & BUFFER_BIT_DEPTH) {
|
|
||||||
clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & BUFFER_BIT_STENCIL) {
|
|
||||||
clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(cpp) {
|
|
||||||
case 2:
|
|
||||||
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
|
|
||||||
D_CMD = CMD = XY_COLOR_BLT_CMD;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
|
|
||||||
CMD = (XY_COLOR_BLT_CMD |
|
|
||||||
XY_COLOR_BLT_WRITE_ALPHA |
|
|
||||||
XY_COLOR_BLT_WRITE_RGB);
|
|
||||||
D_CMD = XY_COLOR_BLT_CMD;
|
|
||||||
if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB;
|
|
||||||
if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
|
|
||||||
D_CMD = CMD = XY_COLOR_BLT_CMD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
intelFlush( &intel->ctx );
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
{
|
|
||||||
/* flip top to bottom */
|
|
||||||
cy = intel->driDrawable->h-cy1-ch;
|
|
||||||
cx = cx1 + intel->drawX;
|
|
||||||
cy += intel->drawY;
|
|
||||||
|
|
||||||
/* adjust for page flipping */
|
|
||||||
if ( intel->sarea->pf_current_page == 1 ) {
|
|
||||||
GLuint tmp = flags;
|
|
||||||
|
|
||||||
flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
|
|
||||||
if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT;
|
|
||||||
if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0 ; i < intel->numClipRects ; i++)
|
|
||||||
{
|
|
||||||
drm_clip_rect_t *box = &intel->pClipRects[i];
|
|
||||||
drm_clip_rect_t b;
|
|
||||||
|
|
||||||
if (!all) {
|
|
||||||
GLint x = box[i].x1;
|
|
||||||
GLint y = box[i].y1;
|
|
||||||
GLint w = box[i].x2 - x;
|
|
||||||
GLint h = box[i].y2 - y;
|
|
||||||
|
|
||||||
if (x < cx) w -= cx - x, x = cx;
|
|
||||||
if (y < cy) h -= cy - y, y = cy;
|
|
||||||
if (x + w > cx + cw) w = cx + cw - x;
|
|
||||||
if (y + h > cy + ch) h = cy + ch - y;
|
|
||||||
if (w <= 0) continue;
|
|
||||||
if (h <= 0) continue;
|
|
||||||
|
|
||||||
b.x1 = x;
|
|
||||||
b.y1 = y;
|
|
||||||
b.x2 = x + w;
|
|
||||||
b.y2 = y + h;
|
|
||||||
} else {
|
|
||||||
b = *box;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (b.x1 > b.x2 ||
|
|
||||||
b.y1 > b.y2 ||
|
|
||||||
b.x2 > intelScreen->width ||
|
|
||||||
b.y2 > intelScreen->height)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( flags & BUFFER_BIT_FRONT_LEFT ) {
|
|
||||||
BEGIN_BATCH( 6);
|
|
||||||
OUT_BATCH( CMD );
|
|
||||||
OUT_BATCH( BR13 );
|
|
||||||
OUT_BATCH( (b.y1 << 16) | b.x1 );
|
|
||||||
OUT_BATCH( (b.y2 << 16) | b.x2 );
|
|
||||||
OUT_BATCH( intelScreen->front.offset );
|
|
||||||
OUT_BATCH( clear_color );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( flags & BUFFER_BIT_BACK_LEFT ) {
|
|
||||||
BEGIN_BATCH( 6);
|
|
||||||
OUT_BATCH( CMD );
|
|
||||||
OUT_BATCH( BR13 );
|
|
||||||
OUT_BATCH( (b.y1 << 16) | b.x1 );
|
|
||||||
OUT_BATCH( (b.y2 << 16) | b.x2 );
|
|
||||||
OUT_BATCH( intelScreen->back.offset );
|
|
||||||
OUT_BATCH( clear_color );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
|
|
||||||
BEGIN_BATCH( 6);
|
|
||||||
OUT_BATCH( D_CMD );
|
|
||||||
OUT_BATCH( BR13 );
|
|
||||||
OUT_BATCH( (b.y1 << 16) | b.x1 );
|
|
||||||
OUT_BATCH( (b.y2 << 16) | b.x2 );
|
|
||||||
OUT_BATCH( intelScreen->depth.offset );
|
|
||||||
OUT_BATCH( clear_depth );
|
|
||||||
ADVANCE_BATCH();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelDestroyBatchBuffer( GLcontext *ctx )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
|
|
||||||
if (intel->alloc.ptr) {
|
|
||||||
intelFreeAGP( intel, intel->alloc.ptr );
|
|
||||||
intel->alloc.ptr = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelInitBatchBuffer( GLcontext *ctx )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
|
|
||||||
if (!intel->intelScreen->allow_batchbuffer || getenv("INTEL_NO_BATCH")) {
|
|
||||||
intel->alloc.size = 8 * 1024;
|
|
||||||
intel->alloc.ptr = malloc( intel->alloc.size );
|
|
||||||
intel->alloc.offset = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (intel->intelScreen->deviceID) {
|
((int *)batch->ptr)[0] = intel->vtbl.flush_cmd();
|
||||||
case PCI_CHIP_I865_G:
|
((int *)batch->ptr)[1] = MI_BATCH_BUFFER_END;
|
||||||
/* HW bug? Seems to crash if batchbuffer crosses 4k boundary.
|
used += 8;
|
||||||
*/
|
|
||||||
intel->alloc.size = 8 * 1024;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* This is the smallest amount of memory the kernel deals with.
|
|
||||||
* We'd ideally like to make this smaller.
|
|
||||||
*/
|
|
||||||
intel->alloc.size = 1 << intel->intelScreen->logTextureGranularity;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
intel->alloc.ptr = intelAllocateAGP( intel, intel->alloc.size );
|
|
||||||
if (intel->alloc.ptr)
|
|
||||||
intel->alloc.offset =
|
|
||||||
intelAgpOffsetFromVirtual( intel, intel->alloc.ptr );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!intel->alloc.ptr) {
|
bmUnmapBuffer(batch->bm, batch->buffer);
|
||||||
FALLBACK(intel, INTEL_FALLBACK_NO_BATCHBUFFER, 1);
|
batch->ptr = NULL;
|
||||||
|
batch->map = NULL;
|
||||||
|
|
||||||
|
/* TODO: Just pass the relocation list and dma buffer up to the
|
||||||
|
* kernel.
|
||||||
|
*/
|
||||||
|
if (!intel->locked)
|
||||||
|
{
|
||||||
|
assert(!(batch->flags & INTEL_BATCH_NO_CLIPRECTS));
|
||||||
|
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
do_flush_locked(batch, used, GL_FALSE);
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
intel->prim.flush = 0;
|
assert(!(batch->flags & INTEL_BATCH_CLIPRECTS));
|
||||||
intel->vtbl.emit_invarient_state( intel );
|
|
||||||
|
|
||||||
/* Make sure this gets to the hardware, even if we have no cliprects:
|
do_flush_locked(batch, used, GL_TRUE);
|
||||||
*/
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
intelFlushBatchLocked( intel, GL_TRUE, GL_FALSE, GL_TRUE );
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reset the buffer:
|
||||||
|
*/
|
||||||
|
intel_batchbuffer_reset( batch );
|
||||||
|
return batch->last_fence;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void intel_batchbuffer_finish( struct intel_batchbuffer *batch )
|
||||||
|
{
|
||||||
|
bmFinishFence(batch->bm,
|
||||||
|
intel_batchbuffer_flush(batch));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is the only way buffers get added to the validate list.
|
||||||
|
*/
|
||||||
|
GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch,
|
||||||
|
GLuint buffer,
|
||||||
|
GLuint flags,
|
||||||
|
GLuint delta )
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
assert(batch->nr_relocs <= MAX_RELOCS);
|
||||||
|
|
||||||
|
for (i = 0; i < batch->list->nr; i++)
|
||||||
|
if (buffer == batch->list->elem[i].buffer)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == batch->list->nr) {
|
||||||
|
if (i == BM_LIST_MAX)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
bmAddBuffer(batch->list,
|
||||||
|
buffer,
|
||||||
|
flags,
|
||||||
|
NULL,
|
||||||
|
&batch->offset[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct buffer_reloc *r = &batch->reloc[batch->nr_relocs++];
|
||||||
|
r->offset = batch->ptr - batch->map;
|
||||||
|
r->delta = delta;
|
||||||
|
r->elem = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
batch->ptr += 4;
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intel_batchbuffer_data(struct intel_batchbuffer *batch,
|
||||||
|
const void *data,
|
||||||
|
GLuint bytes,
|
||||||
|
GLuint flags)
|
||||||
|
{
|
||||||
|
assert((bytes & 3) == 0);
|
||||||
|
intel_batchbuffer_require_space(batch, bytes, flags);
|
||||||
|
__memcpy(batch->ptr, data, bytes);
|
||||||
|
batch->ptr += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,123 +1,113 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef INTEL_BATCHBUFFER_H
|
#ifndef INTEL_BATCHBUFFER_H
|
||||||
#define INTEL_BATCHBUFFER_H
|
#define INTEL_BATCHBUFFER_H
|
||||||
|
|
||||||
#include "intel_context.h"
|
#include "mtypes.h"
|
||||||
#include "intel_ioctl.h"
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
struct intel_context;
|
||||||
|
|
||||||
|
#define BATCH_SZ 4096
|
||||||
|
#define BATCH_RESERVED 16
|
||||||
|
|
||||||
|
#define MAX_RELOCS 100
|
||||||
|
|
||||||
|
#define INTEL_BATCH_NO_CLIPRECTS 0x1
|
||||||
|
#define INTEL_BATCH_CLIPRECTS 0x2
|
||||||
|
|
||||||
|
struct buffer_reloc {
|
||||||
|
GLuint offset;
|
||||||
|
GLuint elem; /* elem in buffer list, not buffer id */
|
||||||
|
GLuint delta; /* not needed? */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct intel_batchbuffer {
|
||||||
|
struct bufmgr *bm;
|
||||||
|
struct intel_context *intel;
|
||||||
|
|
||||||
|
GLuint buffer;
|
||||||
|
GLuint last_fence;
|
||||||
|
GLuint flags;
|
||||||
|
|
||||||
|
/* In progress:
|
||||||
|
*/
|
||||||
|
GLuint offset[BM_LIST_MAX];
|
||||||
|
struct bm_buffer_list *list;
|
||||||
|
GLubyte *map;
|
||||||
|
GLubyte *ptr;
|
||||||
|
|
||||||
|
struct buffer_reloc reloc[MAX_RELOCS];
|
||||||
|
GLuint nr_relocs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct intel_batchbuffer *intel_batchbuffer_alloc( struct intel_context *intel );
|
||||||
|
|
||||||
|
void intel_batchbuffer_free( struct intel_batchbuffer *batch );
|
||||||
|
|
||||||
|
|
||||||
#define BATCH_LOCALS GLubyte *batch_ptr;
|
void intel_batchbuffer_finish( struct intel_batchbuffer *batch );
|
||||||
|
|
||||||
/* #define VERBOSE 0 */
|
GLuint intel_batchbuffer_flush( struct intel_batchbuffer *batch );
|
||||||
#ifndef VERBOSE
|
|
||||||
extern int VERBOSE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define BEGIN_BATCH(n) \
|
/* Unlike bmBufferData, this currently requires the buffer be mapped.
|
||||||
do { \
|
* Consider it a convenience function wrapping multple
|
||||||
if (VERBOSE) fprintf(stderr, \
|
* intel_buffer_dword() calls.
|
||||||
"BEGIN_BATCH(%d) in %s, %d dwords free\n", \
|
*/
|
||||||
(n), __FUNCTION__, intel->batch.space/4); \
|
void intel_batchbuffer_data(struct intel_batchbuffer *batch,
|
||||||
if (intel->batch.space < (n)*4) \
|
const void *data,
|
||||||
intelFlushBatch(intel, GL_TRUE); \
|
GLuint bytes,
|
||||||
batch_ptr = intel->batch.ptr; \
|
GLuint flags);
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define OUT_BATCH(n) \
|
void intel_batchbuffer_release_space(struct intel_batchbuffer *batch,
|
||||||
do { \
|
GLuint bytes);
|
||||||
*(GLuint *)batch_ptr = (n); \
|
|
||||||
if (VERBOSE) fprintf(stderr, " -- %08x at %s/%d\n", (n), __FILE__, __LINE__); \
|
|
||||||
batch_ptr += 4; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ADVANCE_BATCH() \
|
GLboolean intel_batchbuffer_emit_reloc( struct intel_batchbuffer *batch,
|
||||||
do { \
|
GLuint buffer,
|
||||||
if (VERBOSE) fprintf(stderr, "ADVANCE_BATCH()\n"); \
|
GLuint flags,
|
||||||
intel->batch.space -= (batch_ptr - intel->batch.ptr); \
|
GLuint offset );
|
||||||
intel->batch.ptr = batch_ptr; \
|
|
||||||
assert(intel->batch.space >= 0); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
extern void intelInitBatchBuffer( GLcontext *ctx );
|
/* Inline functions - might actually be better off with these
|
||||||
extern void intelDestroyBatchBuffer( GLcontext *ctx );
|
* non-inlined. Certainly better off switching all command packets to
|
||||||
|
* be passed as structs rather than dwords, but that's a little bit of
|
||||||
extern void intelStartInlinePrimitive( intelContextPtr intel, GLuint prim );
|
* work...
|
||||||
extern void intelWrapInlinePrimitive( intelContextPtr intel );
|
*/
|
||||||
extern void intelRestartInlinePrimitive( intelContextPtr intel );
|
static inline GLuint
|
||||||
extern GLuint *intelEmitInlinePrimitiveLocked(intelContextPtr intel,
|
intel_batchbuffer_space( struct intel_batchbuffer *batch )
|
||||||
int primitive, int dwords,
|
|
||||||
int vertex_size);
|
|
||||||
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv );
|
|
||||||
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
|
|
||||||
GLint cx1, GLint cy1, GLint cw, GLint ch);
|
|
||||||
|
|
||||||
extern void intelEmitCopyBlitLocked( intelContextPtr intel,
|
|
||||||
GLuint cpp,
|
|
||||||
GLshort src_pitch,
|
|
||||||
GLuint src_offset,
|
|
||||||
GLshort dst_pitch,
|
|
||||||
GLuint dst_offset,
|
|
||||||
GLshort srcx, GLshort srcy,
|
|
||||||
GLshort dstx, GLshort dsty,
|
|
||||||
GLshort w, GLshort h );
|
|
||||||
|
|
||||||
extern void intelEmitFillBlitLocked( intelContextPtr intel,
|
|
||||||
GLuint cpp,
|
|
||||||
GLshort dst_pitch,
|
|
||||||
GLuint dst_offset,
|
|
||||||
GLshort x, GLshort y,
|
|
||||||
GLshort w, GLshort h,
|
|
||||||
GLuint color );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static __inline GLuint *intelExtendInlinePrimitive( intelContextPtr intel,
|
|
||||||
GLuint dwords )
|
|
||||||
{
|
{
|
||||||
GLuint sz = dwords * sizeof(GLuint);
|
return (BATCH_SZ - BATCH_RESERVED) - (batch->ptr - batch->map);
|
||||||
GLuint *ptr;
|
|
||||||
|
|
||||||
if (intel->batch.space < sz) {
|
|
||||||
intelWrapInlinePrimitive( intel );
|
|
||||||
/* assert(intel->batch.space >= sz); */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* assert(intel->prim.primitive != ~0); */
|
|
||||||
ptr = (GLuint *)intel->batch.ptr;
|
|
||||||
intel->batch.ptr += sz;
|
|
||||||
intel->batch.space -= sz;
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
intel_batchbuffer_emit_dword(struct intel_batchbuffer *batch,
|
||||||
|
GLuint dword)
|
||||||
|
{
|
||||||
|
assert(batch->map);
|
||||||
|
assert(intel_batchbuffer_space(batch) >= 4);
|
||||||
|
*(GLuint *)(batch->ptr) = dword;
|
||||||
|
batch->ptr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
|
||||||
|
GLuint sz,
|
||||||
|
GLuint flags)
|
||||||
|
{
|
||||||
|
assert(sz < BATCH_SZ - 8);
|
||||||
|
if (intel_batchbuffer_space(batch) < sz ||
|
||||||
|
(batch->flags != 0 && flags != 0 && batch->flags != flags))
|
||||||
|
intel_batchbuffer_flush(batch);
|
||||||
|
|
||||||
|
batch->flags |= flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here are the crusty old macros, to be removed:
|
||||||
|
*/
|
||||||
|
#define BATCH_LOCALS
|
||||||
|
#define BEGIN_BATCH(n, flags) intel_batchbuffer_require_space(intel->batch, n*4, flags)
|
||||||
|
#define OUT_BATCH(d) intel_batchbuffer_emit_dword(intel->batch, d)
|
||||||
|
#define OUT_RELOC(buf,flags,delta) intel_batchbuffer_emit_reloc(intel->batch, buf, flags, delta)
|
||||||
|
#define ADVANCE_BATCH() do { } while(0)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
384
src/mesa/drivers/dri/i915/intel_blit.c
Normal file
384
src/mesa/drivers/dri/i915/intel_blit.c
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "enums.h"
|
||||||
|
|
||||||
|
#include "intel_reg.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the back buffer to the front buffer.
|
||||||
|
*/
|
||||||
|
void intelCopyBuffer( const __DRIdrawablePrivate *dPriv )
|
||||||
|
{
|
||||||
|
struct intel_context *intel;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
assert(dPriv);
|
||||||
|
assert(dPriv->driContextPriv);
|
||||||
|
assert(dPriv->driContextPriv->driverPrivate);
|
||||||
|
|
||||||
|
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
|
||||||
|
intelFlush( &intel->ctx );
|
||||||
|
|
||||||
|
|
||||||
|
bmFinishFence(intel->bm, intel->last_swap_fence);
|
||||||
|
|
||||||
|
/* The LOCK_HARDWARE is required for the cliprects. Buffer offsets
|
||||||
|
* should work regardless.
|
||||||
|
*/
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
{
|
||||||
|
intelScreenPrivate *intelScreen = intel->intelScreen;
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
int nbox = dPriv->numClipRects;
|
||||||
|
drm_clip_rect_t *pbox = dPriv->pClipRects;
|
||||||
|
int pitch = intelScreen->front.pitch;
|
||||||
|
int cpp = intelScreen->cpp;
|
||||||
|
int BR13, CMD;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
|
||||||
|
if (cpp == 2) {
|
||||||
|
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
|
||||||
|
CMD = XY_SRC_COPY_BLT_CMD;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
|
||||||
|
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
|
||||||
|
XY_SRC_COPY_BLT_WRITE_RGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < nbox; i++, pbox++)
|
||||||
|
{
|
||||||
|
if (pbox->x1 > pbox->x2 ||
|
||||||
|
pbox->y1 > pbox->y2 ||
|
||||||
|
pbox->x2 > intelScreen->width ||
|
||||||
|
pbox->y2 > intelScreen->height)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
|
||||||
|
OUT_BATCH( (pbox->y2 << 16) | pbox->x2 );
|
||||||
|
|
||||||
|
if (intel->sarea->pf_current_page == 0)
|
||||||
|
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
|
||||||
|
else
|
||||||
|
OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
|
||||||
|
|
||||||
|
OUT_BATCH( (pbox->y1 << 16) | pbox->x1 );
|
||||||
|
OUT_BATCH( BR13 & 0xffff );
|
||||||
|
|
||||||
|
if (intel->sarea->pf_current_page == 0)
|
||||||
|
OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_READ, 0 );
|
||||||
|
else
|
||||||
|
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_READ, 0 );
|
||||||
|
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intel->last_swap_fence = intel_batchbuffer_flush( intel->batch );
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelEmitFillBlit( struct intel_context *intel,
|
||||||
|
GLuint cpp,
|
||||||
|
GLshort dst_pitch,
|
||||||
|
GLuint dst_buffer,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLshort x, GLshort y,
|
||||||
|
GLshort w, GLshort h,
|
||||||
|
GLuint color )
|
||||||
|
{
|
||||||
|
GLuint BR13, CMD;
|
||||||
|
BATCH_LOCALS;
|
||||||
|
|
||||||
|
dst_pitch *= cpp;
|
||||||
|
|
||||||
|
switch(cpp) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
BR13 = dst_pitch | (0xF0 << 16) | (1<<24);
|
||||||
|
CMD = XY_COLOR_BLT_CMD;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
BR13 = dst_pitch | (0xF0 << 16) | (1<<24) | (1<<25);
|
||||||
|
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
|
||||||
|
XY_COLOR_BLT_WRITE_RGB);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (y << 16) | x );
|
||||||
|
OUT_BATCH( ((y+h) << 16) | (x+w) );
|
||||||
|
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset );
|
||||||
|
OUT_BATCH( color );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy BitBlt
|
||||||
|
*/
|
||||||
|
void intelEmitCopyBlit( struct intel_context *intel,
|
||||||
|
GLuint cpp,
|
||||||
|
GLshort src_pitch,
|
||||||
|
GLuint src_buffer,
|
||||||
|
GLuint src_offset,
|
||||||
|
GLshort dst_pitch,
|
||||||
|
GLuint dst_buffer,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLshort src_x, GLshort src_y,
|
||||||
|
GLshort dst_x, GLshort dst_y,
|
||||||
|
GLshort w, GLshort h )
|
||||||
|
{
|
||||||
|
GLuint CMD, BR13;
|
||||||
|
int dst_y2 = dst_y + h;
|
||||||
|
int dst_x2 = dst_x + w;
|
||||||
|
BATCH_LOCALS;
|
||||||
|
|
||||||
|
|
||||||
|
DBG("%s src:buf(%d)/%d %d,%d dst:buf(%d)/%d %d,%d sz:%dx%d\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
src_buffer, src_pitch, src_x, src_y,
|
||||||
|
dst_buffer, dst_pitch, dst_x, dst_y,
|
||||||
|
w,h);
|
||||||
|
|
||||||
|
src_pitch *= cpp;
|
||||||
|
dst_pitch *= cpp;
|
||||||
|
|
||||||
|
switch(cpp) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
BR13 = dst_pitch | (0xCC << 16) | (1<<24);
|
||||||
|
CMD = XY_SRC_COPY_BLT_CMD;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
BR13 = dst_pitch | (0xCC << 16) | (1<<24) | (1<<25);
|
||||||
|
CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
|
||||||
|
XY_SRC_COPY_BLT_WRITE_RGB);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dst_y2 < dst_y ||
|
||||||
|
dst_x2 < dst_x) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initial y values don't seem to work with negative pitches. If
|
||||||
|
* we adjust the offsets manually (below), it seems to work fine.
|
||||||
|
*/
|
||||||
|
if (0) {
|
||||||
|
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (dst_y << 16) | dst_x );
|
||||||
|
OUT_BATCH( (dst_y2 << 16) | dst_x2 );
|
||||||
|
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset );
|
||||||
|
OUT_BATCH( (src_y << 16) | src_x );
|
||||||
|
OUT_BATCH( ((GLint)src_pitch&0xffff) );
|
||||||
|
OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BEGIN_BATCH(8, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (0 << 16) | dst_x );
|
||||||
|
OUT_BATCH( (h << 16) | dst_x2 );
|
||||||
|
OUT_RELOC( dst_buffer, BM_MEM_AGP|BM_WRITE, dst_offset + dst_y * dst_pitch );
|
||||||
|
OUT_BATCH( (0 << 16) | src_x );
|
||||||
|
OUT_BATCH( ((GLint)src_pitch&0xffff) );
|
||||||
|
OUT_RELOC( src_buffer, BM_MEM_AGP|BM_READ, src_offset + src_y * src_pitch );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelClearWithBlit(GLcontext *ctx, GLbitfield flags, GLboolean all,
|
||||||
|
GLint cx1, GLint cy1, GLint cw, GLint ch)
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
intelScreenPrivate *intelScreen = intel->intelScreen;
|
||||||
|
GLuint clear_depth, clear_color;
|
||||||
|
GLint cx, cy;
|
||||||
|
GLint pitch = intelScreen->front.pitch;
|
||||||
|
GLint cpp = intelScreen->cpp;
|
||||||
|
GLint i;
|
||||||
|
GLuint BR13, CMD, D_CMD;
|
||||||
|
BATCH_LOCALS;
|
||||||
|
|
||||||
|
|
||||||
|
clear_color = intel->ClearColor;
|
||||||
|
clear_depth = 0;
|
||||||
|
|
||||||
|
if (flags & BUFFER_BIT_DEPTH) {
|
||||||
|
clear_depth = (GLuint)(ctx->Depth.Clear * intel->ClearDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & BUFFER_BIT_STENCIL) {
|
||||||
|
clear_depth |= (ctx->Stencil.Clear & 0xff) << 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(cpp) {
|
||||||
|
case 2:
|
||||||
|
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
|
||||||
|
D_CMD = CMD = XY_COLOR_BLT_CMD;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
|
||||||
|
CMD = (XY_COLOR_BLT_CMD |
|
||||||
|
XY_COLOR_BLT_WRITE_ALPHA |
|
||||||
|
XY_COLOR_BLT_WRITE_RGB);
|
||||||
|
D_CMD = XY_COLOR_BLT_CMD;
|
||||||
|
if (flags & BUFFER_BIT_DEPTH) D_CMD |= XY_COLOR_BLT_WRITE_RGB;
|
||||||
|
if (flags & BUFFER_BIT_STENCIL) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
|
||||||
|
D_CMD = CMD = XY_COLOR_BLT_CMD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
intelFlush( &intel->ctx );
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
{
|
||||||
|
/* flip top to bottom */
|
||||||
|
cy = intel->driDrawable->h-cy1-ch;
|
||||||
|
cx = cx1 + intel->drawX;
|
||||||
|
cy += intel->drawY;
|
||||||
|
|
||||||
|
/* adjust for page flipping */
|
||||||
|
if ( intel->sarea->pf_current_page == 1 ) {
|
||||||
|
GLuint tmp = flags;
|
||||||
|
|
||||||
|
flags &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT);
|
||||||
|
if ( tmp & BUFFER_BIT_FRONT_LEFT ) flags |= BUFFER_BIT_BACK_LEFT;
|
||||||
|
if ( tmp & BUFFER_BIT_BACK_LEFT ) flags |= BUFFER_BIT_FRONT_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; i < intel->numClipRects ; i++)
|
||||||
|
{
|
||||||
|
drm_clip_rect_t *box = &intel->pClipRects[i];
|
||||||
|
drm_clip_rect_t b;
|
||||||
|
|
||||||
|
if (!all) {
|
||||||
|
GLint x = box[i].x1;
|
||||||
|
GLint y = box[i].y1;
|
||||||
|
GLint w = box[i].x2 - x;
|
||||||
|
GLint h = box[i].y2 - y;
|
||||||
|
|
||||||
|
if (x < cx) w -= cx - x, x = cx;
|
||||||
|
if (y < cy) h -= cy - y, y = cy;
|
||||||
|
if (x + w > cx + cw) w = cx + cw - x;
|
||||||
|
if (y + h > cy + ch) h = cy + ch - y;
|
||||||
|
if (w <= 0) continue;
|
||||||
|
if (h <= 0) continue;
|
||||||
|
|
||||||
|
b.x1 = x;
|
||||||
|
b.y1 = y;
|
||||||
|
b.x2 = x + w;
|
||||||
|
b.y2 = y + h;
|
||||||
|
} else {
|
||||||
|
b = *box;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (b.x1 > b.x2 ||
|
||||||
|
b.y1 > b.y2 ||
|
||||||
|
b.x2 > intelScreen->width ||
|
||||||
|
b.y2 > intelScreen->height)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( flags & BUFFER_BIT_FRONT_LEFT ) {
|
||||||
|
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (b.y1 << 16) | b.x1 );
|
||||||
|
OUT_BATCH( (b.y2 << 16) | b.x2 );
|
||||||
|
OUT_RELOC( intel->front_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
|
||||||
|
OUT_BATCH( clear_color );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flags & BUFFER_BIT_BACK_LEFT ) {
|
||||||
|
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (b.y1 << 16) | b.x1 );
|
||||||
|
OUT_BATCH( (b.y2 << 16) | b.x2 );
|
||||||
|
OUT_RELOC( intel->back_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
|
||||||
|
OUT_BATCH( clear_color );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( flags & (BUFFER_BIT_STENCIL | BUFFER_BIT_DEPTH) ) {
|
||||||
|
BEGIN_BATCH(6, INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
OUT_BATCH( D_CMD );
|
||||||
|
OUT_BATCH( BR13 );
|
||||||
|
OUT_BATCH( (b.y1 << 16) | b.x1 );
|
||||||
|
OUT_BATCH( (b.y2 << 16) | b.x2 );
|
||||||
|
OUT_RELOC( intel->depth_region->buffer, BM_MEM_AGP|BM_WRITE, 0 );
|
||||||
|
OUT_BATCH( clear_depth );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intel_batchbuffer_flush( intel->batch );
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
60
src/mesa/drivers/dri/i915/intel_blit.h
Normal file
60
src/mesa/drivers/dri/i915/intel_blit.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INTEL_BLIT_H
|
||||||
|
#define INTEL_BLIT_H
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_ioctl.h"
|
||||||
|
|
||||||
|
extern void intelCopyBuffer( const __DRIdrawablePrivate *dpriv );
|
||||||
|
extern void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all,
|
||||||
|
GLint cx1, GLint cy1, GLint cw, GLint ch);
|
||||||
|
|
||||||
|
extern void intelEmitCopyBlit( struct intel_context *intel,
|
||||||
|
GLuint cpp,
|
||||||
|
GLshort src_pitch,
|
||||||
|
GLuint src_buffer,
|
||||||
|
GLuint src_offset,
|
||||||
|
GLshort dst_pitch,
|
||||||
|
GLuint dst_buffer,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLshort srcx, GLshort srcy,
|
||||||
|
GLshort dstx, GLshort dsty,
|
||||||
|
GLshort w, GLshort h );
|
||||||
|
|
||||||
|
extern void intelEmitFillBlit( struct intel_context *intel,
|
||||||
|
GLuint cpp,
|
||||||
|
GLshort dst_pitch,
|
||||||
|
GLuint dst_buffer,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLshort x, GLshort y,
|
||||||
|
GLshort w, GLshort h,
|
||||||
|
GLuint color );
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
505
src/mesa/drivers/dri/i915/intel_buffers.c
Normal file
505
src/mesa/drivers/dri/i915/intel_buffers.c
Normal file
@@ -0,0 +1,505 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "intel_screen.h"
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_tris.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "framebuffer.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
|
||||||
|
const drm_clip_rect_t *a,
|
||||||
|
const drm_clip_rect_t *b )
|
||||||
|
{
|
||||||
|
GLint bx = b->x1;
|
||||||
|
GLint by = b->y1;
|
||||||
|
GLint bw = b->x2 - bx;
|
||||||
|
GLint bh = b->y2 - by;
|
||||||
|
|
||||||
|
if (bx < a->x1) bw -= a->x1 - bx, bx = a->x1;
|
||||||
|
if (by < a->y1) bh -= a->y1 - by, by = a->y1;
|
||||||
|
if (bx + bw > a->x2) bw = a->x2 - bx;
|
||||||
|
if (by + bh > a->y2) bh = a->y2 - by;
|
||||||
|
if (bw <= 0) return GL_FALSE;
|
||||||
|
if (bh <= 0) return GL_FALSE;
|
||||||
|
|
||||||
|
dst->x1 = bx;
|
||||||
|
dst->y1 = by;
|
||||||
|
dst->x2 = bx + bw;
|
||||||
|
dst->y2 = by + bh;
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct intel_region *intel_drawbuf_region( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
|
||||||
|
case BUFFER_BIT_FRONT_LEFT:
|
||||||
|
return intel->front_region;
|
||||||
|
case BUFFER_BIT_BACK_LEFT:
|
||||||
|
return intel->back_region;
|
||||||
|
default:
|
||||||
|
/* Not necessary to fallback - could handle either NONE or
|
||||||
|
* FRONT_AND_BACK cases below.
|
||||||
|
*/
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct intel_region *intel_readbuf_region( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
GLcontext *ctx = &intel->ctx;
|
||||||
|
|
||||||
|
/* This will have to change to support EXT_fbo's, but is correct
|
||||||
|
* for now:
|
||||||
|
*/
|
||||||
|
switch (ctx->ReadBuffer->_ColorReadBufferIndex) {
|
||||||
|
case BUFFER_FRONT_LEFT:
|
||||||
|
return intel->front_region;
|
||||||
|
case BUFFER_BACK_LEFT:
|
||||||
|
return intel->back_region;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void intelBufferSize(GLframebuffer *buffer,
|
||||||
|
GLuint *width,
|
||||||
|
GLuint *height)
|
||||||
|
{
|
||||||
|
GET_CURRENT_CONTEXT(ctx);
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
/* Need to lock to make sure the driDrawable is uptodate. This
|
||||||
|
* information is used to resize Mesa's software buffers, so it has
|
||||||
|
* to be correct.
|
||||||
|
*/
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
if (intel->driDrawable) {
|
||||||
|
*width = intel->driDrawable->w;
|
||||||
|
*height = intel->driDrawable->h;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*width = 0;
|
||||||
|
*height = 0;
|
||||||
|
}
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void intelSetFrontClipRects( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
|
||||||
|
if (!dPriv) return;
|
||||||
|
|
||||||
|
intel->numClipRects = dPriv->numClipRects;
|
||||||
|
intel->pClipRects = dPriv->pClipRects;
|
||||||
|
intel->drawX = dPriv->x;
|
||||||
|
intel->drawY = dPriv->y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void intelSetBackClipRects( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
|
||||||
|
if (!dPriv) return;
|
||||||
|
|
||||||
|
if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
|
||||||
|
intel->numClipRects = dPriv->numClipRects;
|
||||||
|
intel->pClipRects = dPriv->pClipRects;
|
||||||
|
intel->drawX = dPriv->x;
|
||||||
|
intel->drawY = dPriv->y;
|
||||||
|
} else {
|
||||||
|
intel->numClipRects = dPriv->numBackClipRects;
|
||||||
|
intel->pClipRects = dPriv->pBackClipRects;
|
||||||
|
intel->drawX = dPriv->backX;
|
||||||
|
intel->drawY = dPriv->backY;
|
||||||
|
|
||||||
|
if (dPriv->numBackClipRects == 1 &&
|
||||||
|
dPriv->x == dPriv->backX &&
|
||||||
|
dPriv->y == dPriv->backY) {
|
||||||
|
|
||||||
|
/* Repeat the calculation of the back cliprect dimensions here
|
||||||
|
* as early versions of dri.a in the Xserver are incorrect. Try
|
||||||
|
* very hard not to restrict future versions of dri.a which
|
||||||
|
* might eg. allocate truly private back buffers.
|
||||||
|
*/
|
||||||
|
int x1, y1;
|
||||||
|
int x2, y2;
|
||||||
|
|
||||||
|
x1 = dPriv->x;
|
||||||
|
y1 = dPriv->y;
|
||||||
|
x2 = dPriv->x + dPriv->w;
|
||||||
|
y2 = dPriv->y + dPriv->h;
|
||||||
|
|
||||||
|
if (x1 < 0) x1 = 0;
|
||||||
|
if (y1 < 0) y1 = 0;
|
||||||
|
if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
|
||||||
|
if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
|
||||||
|
|
||||||
|
if (x1 == dPriv->pBackClipRects[0].x1 &&
|
||||||
|
y1 == dPriv->pBackClipRects[0].y1) {
|
||||||
|
|
||||||
|
dPriv->pBackClipRects[0].x2 = x2;
|
||||||
|
dPriv->pBackClipRects[0].y2 = y2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelWindowMoved( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
if (!intel->ctx.DrawBuffer) {
|
||||||
|
intelSetFrontClipRects( intel );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
|
||||||
|
case BUFFER_BIT_FRONT_LEFT:
|
||||||
|
intelSetFrontClipRects( intel );
|
||||||
|
break;
|
||||||
|
case BUFFER_BIT_BACK_LEFT:
|
||||||
|
intelSetBackClipRects( intel );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
|
||||||
|
intelSetFrontClipRects( intel );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set state we know depends on drawable parameters:
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
GLcontext *ctx = &intel->ctx;
|
||||||
|
|
||||||
|
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||||
|
ctx->Scissor.Width, ctx->Scissor.Height );
|
||||||
|
|
||||||
|
ctx->Driver.DepthRange( ctx,
|
||||||
|
ctx->Viewport.Near,
|
||||||
|
ctx->Viewport.Far );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void emit_clip_rect_quads(struct intel_context *intel,
|
||||||
|
const drm_clip_rect_t *clear)
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
for (i = 0; i < intel->numClipRects; i++) {
|
||||||
|
drm_clip_rect_t rect;
|
||||||
|
|
||||||
|
if (intel_intersect_cliprects(&rect,
|
||||||
|
clear,
|
||||||
|
&intel->pClipRects[i]))
|
||||||
|
{
|
||||||
|
intel_meta_draw_quad(intel,
|
||||||
|
rect.x1, rect.x2,
|
||||||
|
rect.y1, rect.y2,
|
||||||
|
0,
|
||||||
|
intel->ClearColor,
|
||||||
|
0, 0, 0, 0,
|
||||||
|
INTEL_BATCH_NO_CLIPRECTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* A true meta version of this would be very simple and additionally
|
||||||
|
* machine independent. Maybe we'll get there one day.
|
||||||
|
*/
|
||||||
|
static void intelClearWithTris(struct intel_context *intel,
|
||||||
|
GLbitfield mask,
|
||||||
|
GLboolean all,
|
||||||
|
GLint cx, GLint cy,
|
||||||
|
GLint cw, GLint ch)
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
drm_clip_rect_t clear;
|
||||||
|
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
intel->vtbl.install_meta_state(intel);
|
||||||
|
|
||||||
|
if(!all) {
|
||||||
|
clear.x1 = cx;
|
||||||
|
clear.y1 = cy;
|
||||||
|
clear.x2 = cx + cw;
|
||||||
|
clear.y2 = cy + ch;
|
||||||
|
} else {
|
||||||
|
clear.x1 = 0;
|
||||||
|
clear.y1 = 0;
|
||||||
|
clear.x2 = dPriv->w;
|
||||||
|
clear.y2 = dPriv->h;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Back and stencil cliprects are the same. Try and do both
|
||||||
|
* buffers at once:
|
||||||
|
*/
|
||||||
|
if (mask & (BUFFER_BIT_BACK_LEFT|BUFFER_BIT_STENCIL)) {
|
||||||
|
intel->vtbl.meta_draw_region(intel,
|
||||||
|
intel->back_region,
|
||||||
|
intel->depth_region );
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_BACK_LEFT)
|
||||||
|
intel->vtbl.meta_color_mask(intel, GL_TRUE );
|
||||||
|
else
|
||||||
|
intel->vtbl.meta_color_mask(intel, GL_FALSE );
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_STENCIL)
|
||||||
|
intel->vtbl.meta_stencil_replace( intel,
|
||||||
|
intel->ctx.Stencil.WriteMask[0],
|
||||||
|
intel->ctx.Stencil.Clear);
|
||||||
|
else
|
||||||
|
intel->vtbl.meta_no_depth_stencil_write(intel);
|
||||||
|
|
||||||
|
/* Do cliprects explicitly:
|
||||||
|
*/
|
||||||
|
emit_clip_rect_quads(intel, &clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Front may have different cliprects:
|
||||||
|
*/
|
||||||
|
if (mask & BUFFER_BIT_FRONT_LEFT) {
|
||||||
|
intel->vtbl.meta_no_depth_stencil_write(intel);
|
||||||
|
intel->vtbl.meta_color_mask(intel, GL_TRUE );
|
||||||
|
intel->vtbl.meta_draw_region(intel,
|
||||||
|
intel->front_region,
|
||||||
|
intel->depth_region);
|
||||||
|
|
||||||
|
emit_clip_rect_quads(intel, &clear);
|
||||||
|
}
|
||||||
|
|
||||||
|
intel->vtbl.leave_meta_state( intel );
|
||||||
|
intel_batchbuffer_flush( intel->batch );
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void intelClear(GLcontext *ctx,
|
||||||
|
GLbitfield mask,
|
||||||
|
GLboolean all,
|
||||||
|
GLint cx, GLint cy,
|
||||||
|
GLint cw, GLint ch)
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
|
||||||
|
GLbitfield tri_mask = 0;
|
||||||
|
GLbitfield blit_mask = 0;
|
||||||
|
GLbitfield swrast_mask = 0;
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_FRONT_LEFT) {
|
||||||
|
if (colorMask == ~0) {
|
||||||
|
blit_mask |= BUFFER_BIT_FRONT_LEFT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tri_mask |= BUFFER_BIT_FRONT_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_BACK_LEFT) {
|
||||||
|
if (colorMask == ~0) {
|
||||||
|
blit_mask |= BUFFER_BIT_BACK_LEFT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tri_mask |= BUFFER_BIT_BACK_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_DEPTH) {
|
||||||
|
blit_mask |= BUFFER_BIT_DEPTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mask & BUFFER_BIT_STENCIL) {
|
||||||
|
if (!intel->hw_stencil) {
|
||||||
|
swrast_mask |= BUFFER_BIT_STENCIL;
|
||||||
|
}
|
||||||
|
else if (ctx->Stencil.WriteMask[0] != 0xff) {
|
||||||
|
tri_mask |= BUFFER_BIT_STENCIL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
blit_mask |= BUFFER_BIT_STENCIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
|
||||||
|
|
||||||
|
intelFlush( ctx );
|
||||||
|
|
||||||
|
if (blit_mask)
|
||||||
|
intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch );
|
||||||
|
|
||||||
|
if (tri_mask)
|
||||||
|
intelClearWithTris( intel, tri_mask, all, cx, cy, cw, ch);
|
||||||
|
|
||||||
|
if (swrast_mask)
|
||||||
|
_swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Flip the front & back buffers
|
||||||
|
*/
|
||||||
|
static void intelPageFlip( const __DRIdrawablePrivate *dPriv )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct intel_context *intel;
|
||||||
|
int tmp, ret;
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_IOCTL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
assert(dPriv);
|
||||||
|
assert(dPriv->driContextPriv);
|
||||||
|
assert(dPriv->driContextPriv->driverPrivate);
|
||||||
|
|
||||||
|
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
|
||||||
|
|
||||||
|
intelFlush( &intel->ctx );
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
|
||||||
|
if (dPriv->pClipRects) {
|
||||||
|
*(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
|
||||||
|
intel->sarea->nbox = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = intel->sarea->last_enqueue;
|
||||||
|
intelRefillBatchLocked( intel );
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
|
||||||
|
|
||||||
|
intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
|
||||||
|
{
|
||||||
|
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
||||||
|
struct intel_context *intel;
|
||||||
|
GLcontext *ctx;
|
||||||
|
intel = (struct intel_context *) dPriv->driContextPriv->driverPrivate;
|
||||||
|
ctx = &intel->ctx;
|
||||||
|
if (ctx->Visual.doubleBufferMode) {
|
||||||
|
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
|
||||||
|
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
|
||||||
|
intelPageFlip( dPriv );
|
||||||
|
} else {
|
||||||
|
intelCopyBuffer( dPriv );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* XXX this shouldn't be an error but we can't handle it for now */
|
||||||
|
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
int front = 0;
|
||||||
|
|
||||||
|
if (!ctx->DrawBuffer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
|
||||||
|
case BUFFER_BIT_FRONT_LEFT:
|
||||||
|
front = 1;
|
||||||
|
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
|
||||||
|
break;
|
||||||
|
case BUFFER_BIT_BACK_LEFT:
|
||||||
|
front = 0;
|
||||||
|
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( intel->sarea->pf_current_page == 1 )
|
||||||
|
front ^= 1;
|
||||||
|
|
||||||
|
intelSetFrontClipRects( intel );
|
||||||
|
|
||||||
|
|
||||||
|
if (front) {
|
||||||
|
if (intel->draw_region != intel->front_region) {
|
||||||
|
intel_region_release(intel, &intel->draw_region);
|
||||||
|
intel_region_reference(&intel->draw_region, intel->front_region);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (intel->draw_region != intel->back_region) {
|
||||||
|
intel_region_release(intel, &intel->draw_region);
|
||||||
|
intel_region_reference(&intel->draw_region, intel->back_region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intel->vtbl.set_draw_region( intel,
|
||||||
|
intel->draw_region,
|
||||||
|
intel->depth_region);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
|
||||||
|
{
|
||||||
|
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelInitBufferFuncs( struct dd_function_table *functions )
|
||||||
|
{
|
||||||
|
functions->Clear = intelClear;
|
||||||
|
functions->GetBufferSize = intelBufferSize;
|
||||||
|
functions->ResizeBuffers = _mesa_resize_framebuffer;
|
||||||
|
functions->DrawBuffer = intelDrawBuffer;
|
||||||
|
functions->ReadBuffer = intelReadBuffer;
|
||||||
|
}
|
||||||
@@ -54,6 +54,11 @@
|
|||||||
#include "intel_tris.h"
|
#include "intel_tris.h"
|
||||||
#include "intel_ioctl.h"
|
#include "intel_ioctl.h"
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_pixel.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#ifndef INTEL_DEBUG
|
#ifndef INTEL_DEBUG
|
||||||
@@ -77,9 +82,6 @@ int INTEL_DEBUG = (0);
|
|||||||
#define need_GL_NV_vertex_program
|
#define need_GL_NV_vertex_program
|
||||||
#include "extension_helper.h"
|
#include "extension_helper.h"
|
||||||
|
|
||||||
#ifndef VERBOSE
|
|
||||||
int VERBOSE = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DEBUG_LOCKING
|
#if DEBUG_LOCKING
|
||||||
char *prevLockFile;
|
char *prevLockFile;
|
||||||
@@ -90,9 +92,9 @@ int prevLockLine;
|
|||||||
* Mesa's Driver Functions
|
* Mesa's Driver Functions
|
||||||
***************************************/
|
***************************************/
|
||||||
|
|
||||||
#define DRIVER_DATE "20050225"
|
#define DRIVER_DATE "20060212"
|
||||||
|
|
||||||
const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
|
static const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
|
||||||
{
|
{
|
||||||
const char * chipset;
|
const char * chipset;
|
||||||
static char buffer[128];
|
static char buffer[128];
|
||||||
@@ -103,7 +105,7 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_RENDERER:
|
case GL_RENDERER:
|
||||||
switch (INTEL_CONTEXT(ctx)->intelScreen->deviceID) {
|
switch (intel_context(ctx)->intelScreen->deviceID) {
|
||||||
case PCI_CHIP_845_G:
|
case PCI_CHIP_845_G:
|
||||||
chipset = "Intel(R) 845G"; break;
|
chipset = "Intel(R) 845G"; break;
|
||||||
case PCI_CHIP_I830_M:
|
case PCI_CHIP_I830_M:
|
||||||
@@ -130,27 +132,6 @@ const GLubyte *intelGetString( GLcontext *ctx, GLenum name )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intelBufferSize(GLframebuffer *buffer,
|
|
||||||
GLuint *width, GLuint *height)
|
|
||||||
{
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
/* Need to lock to make sure the driDrawable is uptodate. This
|
|
||||||
* information is used to resize Mesa's software buffers, so it has
|
|
||||||
* to be correct.
|
|
||||||
*/
|
|
||||||
LOCK_HARDWARE(intel);
|
|
||||||
if (intel->driDrawable) {
|
|
||||||
*width = intel->driDrawable->w;
|
|
||||||
*height = intel->driDrawable->h;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*width = 0;
|
|
||||||
*height = 0;
|
|
||||||
}
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension strings exported by the intel driver.
|
* Extension strings exported by the intel driver.
|
||||||
@@ -197,7 +178,7 @@ const struct dri_extension card_extensions[] =
|
|||||||
{ "GL_NV_blend_square", NULL },
|
{ "GL_NV_blend_square", NULL },
|
||||||
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
|
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
|
||||||
{ "GL_NV_vertex_program1_1", NULL },
|
{ "GL_NV_vertex_program1_1", NULL },
|
||||||
{ "GL_SGIS_generate_mipmap", NULL },
|
/* { "GL_SGIS_generate_mipmap", NULL }, */
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -214,7 +195,7 @@ static const struct tnl_pipeline_stage *intel_pipeline[] = {
|
|||||||
&_tnl_point_attenuation_stage,
|
&_tnl_point_attenuation_stage,
|
||||||
&_tnl_arb_vertex_program_stage,
|
&_tnl_arb_vertex_program_stage,
|
||||||
&_tnl_vertex_program_stage,
|
&_tnl_vertex_program_stage,
|
||||||
#if 1
|
#if 0
|
||||||
&_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */
|
&_intel_render_stage, /* ADD: unclipped rastersetup-to-dma */
|
||||||
#endif
|
#endif
|
||||||
&_tnl_render_stage,
|
&_tnl_render_stage,
|
||||||
@@ -237,6 +218,7 @@ static const struct dri_debug_control debug_control[] =
|
|||||||
{ "sync", DEBUG_SYNC },
|
{ "sync", DEBUG_SYNC },
|
||||||
{ "sleep", DEBUG_SLEEP },
|
{ "sleep", DEBUG_SLEEP },
|
||||||
{ "pix", DEBUG_PIXEL },
|
{ "pix", DEBUG_PIXEL },
|
||||||
|
{ "buf", DEBUG_BUFMGR },
|
||||||
{ NULL, 0 }
|
{ NULL, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -248,7 +230,32 @@ static void intelInvalidateState( GLcontext *ctx, GLuint new_state )
|
|||||||
_ac_InvalidateState( ctx, new_state );
|
_ac_InvalidateState( ctx, new_state );
|
||||||
_tnl_InvalidateState( ctx, new_state );
|
_tnl_InvalidateState( ctx, new_state );
|
||||||
_tnl_invalidate_vertex_state( ctx, new_state );
|
_tnl_invalidate_vertex_state( ctx, new_state );
|
||||||
INTEL_CONTEXT(ctx)->NewGLState |= new_state;
|
intel_context(ctx)->NewGLState |= new_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelFlush( GLcontext *ctx )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
|
||||||
|
if (intel->Fallback)
|
||||||
|
_swrast_flush( ctx );
|
||||||
|
|
||||||
|
INTEL_FIREVERTICES( intel );
|
||||||
|
|
||||||
|
if (intel->batch->map != intel->batch->ptr)
|
||||||
|
intel_batchbuffer_flush( intel->batch );
|
||||||
|
|
||||||
|
/* XXX: Need to do an MI_FLUSH here. Actually, the bufmgr_fake.c
|
||||||
|
* code will have done one already.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void intelFinish( GLcontext *ctx )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
intelFlush( ctx );
|
||||||
|
bmFinishFence( intel->bm, intel->last_fence );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -257,10 +264,7 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
|
|||||||
_mesa_init_driver_functions( functions );
|
_mesa_init_driver_functions( functions );
|
||||||
|
|
||||||
functions->Flush = intelFlush;
|
functions->Flush = intelFlush;
|
||||||
functions->Clear = intelClear;
|
|
||||||
functions->Finish = intelFinish;
|
functions->Finish = intelFinish;
|
||||||
functions->GetBufferSize = intelBufferSize;
|
|
||||||
functions->ResizeBuffers = _mesa_resize_framebuffer;
|
|
||||||
functions->GetString = intelGetString;
|
functions->GetString = intelGetString;
|
||||||
functions->UpdateState = intelInvalidateState;
|
functions->UpdateState = intelInvalidateState;
|
||||||
functions->CopyColorTable = _swrast_CopyColorTable;
|
functions->CopyColorTable = _swrast_CopyColorTable;
|
||||||
@@ -271,11 +275,12 @@ void intelInitDriverFunctions( struct dd_function_table *functions )
|
|||||||
intelInitTextureFuncs( functions );
|
intelInitTextureFuncs( functions );
|
||||||
intelInitPixelFuncs( functions );
|
intelInitPixelFuncs( functions );
|
||||||
intelInitStateFuncs( functions );
|
intelInitStateFuncs( functions );
|
||||||
|
intelInitBufferFuncs( functions );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GLboolean intelInitContext( intelContextPtr intel,
|
GLboolean intelInitContext( struct intel_context *intel,
|
||||||
const __GLcontextModes *mesaVis,
|
const __GLcontextModes *mesaVis,
|
||||||
__DRIcontextPrivate *driContextPriv,
|
__DRIcontextPrivate *driContextPriv,
|
||||||
void *sharedContextPrivate,
|
void *sharedContextPrivate,
|
||||||
@@ -300,9 +305,6 @@ GLboolean intelInitContext( intelContextPtr intel,
|
|||||||
intel->sarea = saPriv;
|
intel->sarea = saPriv;
|
||||||
|
|
||||||
|
|
||||||
(void) memset( intel->texture_heaps, 0, sizeof( intel->texture_heaps ) );
|
|
||||||
make_empty_list( & intel->swapped );
|
|
||||||
|
|
||||||
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
|
ctx->Const.MaxTextureMaxAnisotropy = 2.0;
|
||||||
|
|
||||||
ctx->Const.MinLineWidth = 1.0;
|
ctx->Const.MinLineWidth = 1.0;
|
||||||
@@ -371,7 +373,57 @@ GLboolean intelInitContext( intelContextPtr intel,
|
|||||||
|
|
||||||
_math_matrix_ctr (&intel->ViewportMatrix);
|
_math_matrix_ctr (&intel->ViewportMatrix);
|
||||||
|
|
||||||
driInitExtensions( ctx, card_extensions, GL_TRUE );
|
/* Disable imaging extension until convolution is working in
|
||||||
|
* teximage paths:
|
||||||
|
*/
|
||||||
|
driInitExtensions( ctx, card_extensions,
|
||||||
|
/* GL_TRUE, */
|
||||||
|
GL_FALSE);
|
||||||
|
|
||||||
|
|
||||||
|
/* Buffer manager:
|
||||||
|
*/
|
||||||
|
intel->bm = bm_fake_intel_Attach( intel );
|
||||||
|
|
||||||
|
bmInitPool(intel->bm,
|
||||||
|
intel->intelScreen->tex.offset, /* low offset */
|
||||||
|
intel->intelScreen->tex.map, /* low virtual */
|
||||||
|
intel->intelScreen->tex.size,
|
||||||
|
BM_MEM_AGP);
|
||||||
|
|
||||||
|
/* These are still static, but create regions for them.
|
||||||
|
*/
|
||||||
|
intel->front_region =
|
||||||
|
intel_region_create_static(intel,
|
||||||
|
BM_MEM_AGP,
|
||||||
|
intelScreen->front.offset,
|
||||||
|
intelScreen->front.map,
|
||||||
|
intelScreen->cpp,
|
||||||
|
intelScreen->front.pitch,
|
||||||
|
intelScreen->height);
|
||||||
|
|
||||||
|
|
||||||
|
intel->back_region =
|
||||||
|
intel_region_create_static(intel,
|
||||||
|
BM_MEM_AGP,
|
||||||
|
intelScreen->back.offset,
|
||||||
|
intelScreen->back.map,
|
||||||
|
intelScreen->cpp,
|
||||||
|
intelScreen->back.pitch,
|
||||||
|
intelScreen->height);
|
||||||
|
|
||||||
|
/* Still assuming front.cpp == depth.cpp
|
||||||
|
*/
|
||||||
|
intel->depth_region =
|
||||||
|
intel_region_create_static(intel,
|
||||||
|
BM_MEM_AGP,
|
||||||
|
intelScreen->depth.offset,
|
||||||
|
intelScreen->depth.map,
|
||||||
|
intelScreen->cpp,
|
||||||
|
intelScreen->depth.pitch,
|
||||||
|
intelScreen->height);
|
||||||
|
|
||||||
|
intel->batch = intel_batchbuffer_alloc( intel );
|
||||||
|
|
||||||
if (intel->ctx.Mesa_DXTn) {
|
if (intel->ctx.Mesa_DXTn) {
|
||||||
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
|
_mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" );
|
||||||
@@ -387,24 +439,16 @@ GLboolean intelInitContext( intelContextPtr intel,
|
|||||||
/* DRI_TEXMGR_DO_TEXTURE_RECT ); */
|
/* DRI_TEXMGR_DO_TEXTURE_RECT ); */
|
||||||
|
|
||||||
|
|
||||||
intel->prim.flush = intelInitBatchBuffer;
|
|
||||||
intel->prim.primitive = ~0;
|
intel->prim.primitive = ~0;
|
||||||
|
|
||||||
|
|
||||||
#if DO_DEBUG
|
#if DO_DEBUG
|
||||||
INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
|
INTEL_DEBUG = driParseDebugString( getenv( "INTEL_DEBUG" ),
|
||||||
debug_control );
|
debug_control );
|
||||||
INTEL_DEBUG |= driParseDebugString( getenv( "INTEL_DEBUG" ),
|
|
||||||
debug_control );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef VERBOSE
|
|
||||||
if (getenv("INTEL_VERBOSE"))
|
|
||||||
VERBOSE=1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (getenv("INTEL_NO_RAST") ||
|
if (getenv("INTEL_NO_RAST")) {
|
||||||
getenv("INTEL_NO_RAST")) {
|
|
||||||
fprintf(stderr, "disabling 3D rasterization\n");
|
fprintf(stderr, "disabling 3D rasterization\n");
|
||||||
FALLBACK(intel, INTEL_FALLBACK_USER, 1);
|
FALLBACK(intel, INTEL_FALLBACK_USER, 1);
|
||||||
}
|
}
|
||||||
@@ -414,7 +458,7 @@ GLboolean intelInitContext( intelContextPtr intel,
|
|||||||
|
|
||||||
void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
|
void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
|
||||||
{
|
{
|
||||||
intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
|
struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
|
||||||
|
|
||||||
assert(intel); /* should never be null */
|
assert(intel); /* should never be null */
|
||||||
if (intel) {
|
if (intel) {
|
||||||
@@ -431,21 +475,14 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
|
|||||||
_swrast_DestroyContext (&intel->ctx);
|
_swrast_DestroyContext (&intel->ctx);
|
||||||
intel->Fallback = 0; /* don't call _swrast_Flush later */
|
intel->Fallback = 0; /* don't call _swrast_Flush later */
|
||||||
|
|
||||||
intelDestroyBatchBuffer(&intel->ctx);
|
intel_batchbuffer_free(intel->batch);
|
||||||
|
|
||||||
|
|
||||||
if ( release_texture_heaps ) {
|
if ( release_texture_heaps ) {
|
||||||
/* This share group is about to go away, free our private
|
/* This share group is about to go away, free our private
|
||||||
* texture object data.
|
* texture object data.
|
||||||
*/
|
*/
|
||||||
int i;
|
fprintf(stderr, "do somethign to free texture heaps\n");
|
||||||
|
|
||||||
for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
|
|
||||||
driDestroyTextureHeap( intel->texture_heaps[ i ] );
|
|
||||||
intel->texture_heaps[ i ] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( is_empty_list( & intel->swapped ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free the Mesa context */
|
/* free the Mesa context */
|
||||||
@@ -453,102 +490,6 @@ void intelDestroyContext(__DRIcontextPrivate *driContextPriv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void intelSetFrontClipRects( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
|
|
||||||
if (!dPriv) return;
|
|
||||||
|
|
||||||
intel->numClipRects = dPriv->numClipRects;
|
|
||||||
intel->pClipRects = dPriv->pClipRects;
|
|
||||||
intel->drawX = dPriv->x;
|
|
||||||
intel->drawY = dPriv->y;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelSetBackClipRects( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
|
|
||||||
if (!dPriv) return;
|
|
||||||
|
|
||||||
if (intel->sarea->pf_enabled == 0 && dPriv->numBackClipRects == 0) {
|
|
||||||
intel->numClipRects = dPriv->numClipRects;
|
|
||||||
intel->pClipRects = dPriv->pClipRects;
|
|
||||||
intel->drawX = dPriv->x;
|
|
||||||
intel->drawY = dPriv->y;
|
|
||||||
} else {
|
|
||||||
intel->numClipRects = dPriv->numBackClipRects;
|
|
||||||
intel->pClipRects = dPriv->pBackClipRects;
|
|
||||||
intel->drawX = dPriv->backX;
|
|
||||||
intel->drawY = dPriv->backY;
|
|
||||||
|
|
||||||
if (dPriv->numBackClipRects == 1 &&
|
|
||||||
dPriv->x == dPriv->backX &&
|
|
||||||
dPriv->y == dPriv->backY) {
|
|
||||||
|
|
||||||
/* Repeat the calculation of the back cliprect dimensions here
|
|
||||||
* as early versions of dri.a in the Xserver are incorrect. Try
|
|
||||||
* very hard not to restrict future versions of dri.a which
|
|
||||||
* might eg. allocate truly private back buffers.
|
|
||||||
*/
|
|
||||||
int x1, y1;
|
|
||||||
int x2, y2;
|
|
||||||
|
|
||||||
x1 = dPriv->x;
|
|
||||||
y1 = dPriv->y;
|
|
||||||
x2 = dPriv->x + dPriv->w;
|
|
||||||
y2 = dPriv->y + dPriv->h;
|
|
||||||
|
|
||||||
if (x1 < 0) x1 = 0;
|
|
||||||
if (y1 < 0) y1 = 0;
|
|
||||||
if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
|
|
||||||
if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
|
|
||||||
|
|
||||||
if (x1 == dPriv->pBackClipRects[0].x1 &&
|
|
||||||
y1 == dPriv->pBackClipRects[0].y1) {
|
|
||||||
|
|
||||||
dPriv->pBackClipRects[0].x2 = x2;
|
|
||||||
dPriv->pBackClipRects[0].y2 = y2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelWindowMoved( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
if (!intel->ctx.DrawBuffer) {
|
|
||||||
intelSetFrontClipRects( intel );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
switch (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0]) {
|
|
||||||
case BUFFER_BIT_FRONT_LEFT:
|
|
||||||
intelSetFrontClipRects( intel );
|
|
||||||
break;
|
|
||||||
case BUFFER_BIT_BACK_LEFT:
|
|
||||||
intelSetBackClipRects( intel );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* glDrawBuffer(GL_NONE or GL_FRONT_AND_BACK): software fallback */
|
|
||||||
intelSetFrontClipRects( intel );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set state we know depends on drawable parameters:
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
GLcontext *ctx = &intel->ctx;
|
|
||||||
|
|
||||||
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
|
||||||
ctx->Scissor.Width, ctx->Scissor.Height );
|
|
||||||
|
|
||||||
ctx->Driver.DepthRange( ctx,
|
|
||||||
ctx->Viewport.Near,
|
|
||||||
ctx->Viewport.Far );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
|
GLboolean intelUnbindContext(__DRIcontextPrivate *driContextPriv)
|
||||||
{
|
{
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
@@ -560,7 +501,7 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (driContextPriv) {
|
if (driContextPriv) {
|
||||||
intelContextPtr intel = (intelContextPtr) driContextPriv->driverPrivate;
|
struct intel_context *intel = (struct intel_context *) driContextPriv->driverPrivate;
|
||||||
|
|
||||||
if ( intel->driDrawable != driDrawPriv ) {
|
if ( intel->driDrawable != driDrawPriv ) {
|
||||||
/* Shouldn't the readbuffer be stored also? */
|
/* Shouldn't the readbuffer be stored also? */
|
||||||
@@ -580,13 +521,12 @@ GLboolean intelMakeCurrent(__DRIcontextPrivate *driContextPriv,
|
|||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void intelGetLock( intelContextPtr intel, GLuint flags )
|
void intelGetLock( struct intel_context *intel, GLuint flags )
|
||||||
{
|
{
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
__DRIscreenPrivate *sPriv = intel->driScreen;
|
__DRIscreenPrivate *sPriv = intel->driScreen;
|
||||||
drmI830Sarea * sarea = intel->sarea;
|
drmI830Sarea * sarea = intel->sarea;
|
||||||
int me = intel->hHWContext;
|
int me = intel->hHWContext;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
drmGetLock(intel->driFd, intel->hHWContext, flags);
|
drmGetLock(intel->driFd, intel->hHWContext, flags);
|
||||||
|
|
||||||
@@ -598,143 +538,19 @@ void intelGetLock( intelContextPtr intel, GLuint flags )
|
|||||||
if (dPriv)
|
if (dPriv)
|
||||||
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
|
DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
|
||||||
|
|
||||||
/* If we lost context, need to dump all registers to hardware.
|
/* Lost context?
|
||||||
* Note that we don't care about 2d contexts, even if they perform
|
|
||||||
* accelerated commands, so the DRI locking in the X server is even
|
|
||||||
* more broken than usual.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (sarea->ctxOwner != me) {
|
if (sarea->ctxOwner != me) {
|
||||||
intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
|
intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
|
||||||
sarea->ctxOwner = me;
|
sarea->ctxOwner = me;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shared texture managment - if another client has played with
|
/* Drawable changed?
|
||||||
* texture space, figure out which if any of our textures have been
|
|
||||||
* ejected, and update our global LRU.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for ( i = 0 ; i < intel->nr_heaps ; i++ ) {
|
|
||||||
DRI_AGE_TEXTURES( intel->texture_heaps[ i ] );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dPriv && intel->lastStamp != dPriv->lastStamp) {
|
if (dPriv && intel->lastStamp != dPriv->lastStamp) {
|
||||||
intelWindowMoved( intel );
|
intelWindowMoved( intel );
|
||||||
intel->lastStamp = dPriv->lastStamp;
|
intel->lastStamp = dPriv->lastStamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void intelSwapBuffers( __DRIdrawablePrivate *dPriv )
|
|
||||||
{
|
|
||||||
if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
|
||||||
intelContextPtr intel;
|
|
||||||
GLcontext *ctx;
|
|
||||||
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
|
|
||||||
ctx = &intel->ctx;
|
|
||||||
if (ctx->Visual.doubleBufferMode) {
|
|
||||||
_mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */
|
|
||||||
if ( 0 /*intel->doPageFlip*/ ) { /* doPageFlip is never set !!! */
|
|
||||||
intelPageFlip( dPriv );
|
|
||||||
} else {
|
|
||||||
intelCopyBuffer( dPriv );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* XXX this shouldn't be an error but we can't handle it for now */
|
|
||||||
fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelInitState( GLcontext *ctx )
|
|
||||||
{
|
|
||||||
/* Mesa should do this for us:
|
|
||||||
*/
|
|
||||||
ctx->Driver.AlphaFunc( ctx,
|
|
||||||
ctx->Color.AlphaFunc,
|
|
||||||
ctx->Color.AlphaRef);
|
|
||||||
|
|
||||||
ctx->Driver.BlendColor( ctx,
|
|
||||||
ctx->Color.BlendColor );
|
|
||||||
|
|
||||||
ctx->Driver.BlendEquationSeparate( ctx,
|
|
||||||
ctx->Color.BlendEquationRGB,
|
|
||||||
ctx->Color.BlendEquationA);
|
|
||||||
|
|
||||||
ctx->Driver.BlendFuncSeparate( ctx,
|
|
||||||
ctx->Color.BlendSrcRGB,
|
|
||||||
ctx->Color.BlendDstRGB,
|
|
||||||
ctx->Color.BlendSrcA,
|
|
||||||
ctx->Color.BlendDstA);
|
|
||||||
|
|
||||||
ctx->Driver.ColorMask( ctx,
|
|
||||||
ctx->Color.ColorMask[RCOMP],
|
|
||||||
ctx->Color.ColorMask[GCOMP],
|
|
||||||
ctx->Color.ColorMask[BCOMP],
|
|
||||||
ctx->Color.ColorMask[ACOMP]);
|
|
||||||
|
|
||||||
ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
|
|
||||||
ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
|
|
||||||
ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
|
|
||||||
|
|
||||||
ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
|
|
||||||
ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
|
|
||||||
ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
|
|
||||||
ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
|
|
||||||
ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
|
|
||||||
ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
|
|
||||||
ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
|
|
||||||
ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
|
|
||||||
ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
|
|
||||||
ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
|
|
||||||
ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
|
|
||||||
|
|
||||||
ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
|
|
||||||
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
|
|
||||||
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
|
|
||||||
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
|
|
||||||
ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
|
|
||||||
|
|
||||||
ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
|
|
||||||
|
|
||||||
{
|
|
||||||
GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
|
|
||||||
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->Driver.LineWidth( ctx, ctx->Line.Width );
|
|
||||||
ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
|
|
||||||
ctx->Driver.PointSize( ctx, ctx->Point.Size );
|
|
||||||
ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
|
|
||||||
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
|
||||||
ctx->Scissor.Width, ctx->Scissor.Height );
|
|
||||||
ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
|
|
||||||
ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
|
|
||||||
ctx->Stencil.Function[0],
|
|
||||||
ctx->Stencil.Ref[0],
|
|
||||||
ctx->Stencil.ValueMask[0] );
|
|
||||||
ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
|
|
||||||
ctx->Stencil.Function[1],
|
|
||||||
ctx->Stencil.Ref[1],
|
|
||||||
ctx->Stencil.ValueMask[1] );
|
|
||||||
ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
|
|
||||||
ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
|
|
||||||
ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
|
|
||||||
ctx->Stencil.FailFunc[0],
|
|
||||||
ctx->Stencil.ZFailFunc[0],
|
|
||||||
ctx->Stencil.ZPassFunc[0]);
|
|
||||||
ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
|
|
||||||
ctx->Stencil.FailFunc[1],
|
|
||||||
ctx->Stencil.ZFailFunc[1],
|
|
||||||
ctx->Stencil.ZPassFunc[1]);
|
|
||||||
|
|
||||||
|
|
||||||
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -47,82 +47,123 @@
|
|||||||
#define DV_PF_565 (2<<8)
|
#define DV_PF_565 (2<<8)
|
||||||
#define DV_PF_8888 (3<<8)
|
#define DV_PF_8888 (3<<8)
|
||||||
|
|
||||||
#define INTEL_CONTEXT(ctx) ((intelContextPtr)(ctx))
|
struct intel_region;
|
||||||
|
struct intel_context;
|
||||||
|
|
||||||
typedef struct intel_context intelContext;
|
typedef void (*intel_tri_func)(struct intel_context *, intelVertex *, intelVertex *,
|
||||||
typedef struct intel_context *intelContextPtr;
|
|
||||||
typedef struct intel_texture_object *intelTextureObjectPtr;
|
|
||||||
|
|
||||||
typedef void (*intel_tri_func)(intelContextPtr, intelVertex *, intelVertex *,
|
|
||||||
intelVertex *);
|
intelVertex *);
|
||||||
typedef void (*intel_line_func)(intelContextPtr, intelVertex *, intelVertex *);
|
typedef void (*intel_line_func)(struct intel_context *, intelVertex *, intelVertex *);
|
||||||
typedef void (*intel_point_func)(intelContextPtr, intelVertex *);
|
typedef void (*intel_point_func)(struct intel_context *, intelVertex *);
|
||||||
|
|
||||||
#define INTEL_FALLBACK_DRAW_BUFFER 0x1
|
#define INTEL_FALLBACK_DRAW_BUFFER 0x1
|
||||||
#define INTEL_FALLBACK_READ_BUFFER 0x2
|
#define INTEL_FALLBACK_READ_BUFFER 0x2
|
||||||
#define INTEL_FALLBACK_USER 0x4
|
#define INTEL_FALLBACK_USER 0x4
|
||||||
#define INTEL_FALLBACK_NO_BATCHBUFFER 0x8
|
#define INTEL_FALLBACK_RENDERMODE 0x8
|
||||||
#define INTEL_FALLBACK_NO_TEXMEM 0x10
|
|
||||||
#define INTEL_FALLBACK_RENDERMODE 0x20
|
|
||||||
|
|
||||||
extern void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode );
|
extern void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode );
|
||||||
#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode )
|
#define FALLBACK( intel, bit, mode ) intelFallback( intel, bit, mode )
|
||||||
|
|
||||||
|
|
||||||
#define INTEL_TEX_MAXLEVELS 10
|
|
||||||
|
|
||||||
|
|
||||||
struct intel_texture_object
|
struct intel_texture_object
|
||||||
{
|
{
|
||||||
driTextureObject base; /* the parent class */
|
struct gl_texture_object base; /* The "parent" object */
|
||||||
|
|
||||||
GLuint texelBytes;
|
/* The mipmap tree must include at least these levels once
|
||||||
GLuint age;
|
* validated:
|
||||||
GLuint Pitch;
|
*/
|
||||||
GLuint Height;
|
GLuint firstLevel;
|
||||||
GLuint TextureOffset;
|
GLuint lastLevel;
|
||||||
GLubyte *BufAddr;
|
|
||||||
|
|
||||||
GLuint min_level;
|
/* Offset for firstLevel image:
|
||||||
GLuint max_level;
|
*/
|
||||||
GLuint depth_pitch;
|
GLuint textureOffset;
|
||||||
|
|
||||||
struct {
|
/* On validation any active images held in main memory or in other
|
||||||
const struct gl_texture_image *image;
|
* regions will be copied to this region and the old storage freed.
|
||||||
GLuint offset; /* into BufAddr */
|
*/
|
||||||
GLuint height;
|
struct intel_mipmap_tree *mt;
|
||||||
GLuint internalFormat;
|
|
||||||
} image[6][INTEL_TEX_MAXLEVELS];
|
|
||||||
|
|
||||||
GLuint dirty;
|
|
||||||
GLuint firstLevel,lastLevel;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct intel_texture_image
|
||||||
|
{
|
||||||
|
struct gl_texture_image base;
|
||||||
|
|
||||||
|
/* These aren't stored in gl_texture_image
|
||||||
|
*/
|
||||||
|
GLuint level;
|
||||||
|
GLuint face;
|
||||||
|
|
||||||
|
/* If intelImage->mt != NULL, image data is stored here.
|
||||||
|
* Else if intelImage->base.Data != NULL, image is stored there.
|
||||||
|
* Else there is no image data.
|
||||||
|
*/
|
||||||
|
struct intel_mipmap_tree *mt;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define INTEL_MAX_FIXUP 64
|
||||||
|
|
||||||
struct intel_context
|
struct intel_context
|
||||||
{
|
{
|
||||||
GLcontext ctx; /* the parent class */
|
GLcontext ctx; /* the parent class */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
void (*destroy)( intelContextPtr intel );
|
void (*destroy)( struct intel_context *intel );
|
||||||
void (*emit_state)( intelContextPtr intel );
|
void (*emit_state)( struct intel_context *intel );
|
||||||
void (*emit_invarient_state)( intelContextPtr intel );
|
void (*emit_invarient_state)( struct intel_context *intel );
|
||||||
void (*lost_hardware)( intelContextPtr intel );
|
void (*lost_hardware)( struct intel_context *intel );
|
||||||
void (*update_texture_state)( intelContextPtr intel );
|
void (*update_texture_state)( struct intel_context *intel );
|
||||||
|
|
||||||
void (*render_start)( intelContextPtr intel );
|
void (*render_start)( struct intel_context *intel );
|
||||||
void (*set_draw_offset)( intelContextPtr intel, int offset );
|
void (*set_draw_region)( struct intel_context *intel,
|
||||||
void (*emit_flush)( intelContextPtr intel );
|
struct intel_region *draw_region,
|
||||||
|
struct intel_region *depth_region );
|
||||||
|
|
||||||
void (*reduced_primitive_state)( intelContextPtr intel, GLenum rprim );
|
GLuint (*flush_cmd)( void );
|
||||||
|
|
||||||
GLboolean (*check_vertex_size)( intelContextPtr intel, GLuint expected );
|
void (*reduced_primitive_state)( struct intel_context *intel, GLenum rprim );
|
||||||
|
|
||||||
void (*clear_with_tris)( intelContextPtr intel, GLbitfield mask,
|
GLboolean (*check_vertex_size)( struct intel_context *intel, GLuint expected );
|
||||||
|
|
||||||
|
void (*clear_with_tris)( struct intel_context *intel, GLbitfield mask,
|
||||||
GLboolean all,
|
GLboolean all,
|
||||||
GLint cx, GLint cy, GLint cw, GLint ch);
|
GLint cx, GLint cy, GLint cw, GLint ch);
|
||||||
|
|
||||||
intelTextureObjectPtr (*alloc_tex_obj)( struct gl_texture_object *tObj );
|
|
||||||
|
/* Metaops:
|
||||||
|
*/
|
||||||
|
void (*install_meta_state)( struct intel_context *intel );
|
||||||
|
void (*leave_meta_state)( struct intel_context *intel );
|
||||||
|
|
||||||
|
void (*meta_draw_region)( struct intel_context *intel,
|
||||||
|
struct intel_region *draw_region,
|
||||||
|
struct intel_region *depth_region );
|
||||||
|
|
||||||
|
void (*meta_color_mask)( struct intel_context *intel,
|
||||||
|
GLboolean );
|
||||||
|
|
||||||
|
void (*meta_stencil_replace)( struct intel_context *intel,
|
||||||
|
GLuint mask,
|
||||||
|
GLuint clear );
|
||||||
|
|
||||||
|
void (*meta_no_depth_stencil_write)( struct intel_context *intel );
|
||||||
|
|
||||||
|
void (*meta_no_texture)( struct intel_context *intel );
|
||||||
|
void (*meta_texture_blend_replace)( struct intel_context *intel );
|
||||||
|
|
||||||
|
void (*meta_tex_rect_source)( struct intel_context *intel,
|
||||||
|
struct intel_region *region,
|
||||||
|
GLuint textureFormat );
|
||||||
|
|
||||||
|
void (*meta_draw_format)( struct intel_context *intel,
|
||||||
|
GLuint format,
|
||||||
|
GLuint depth_format );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} vtbl;
|
} vtbl;
|
||||||
|
|
||||||
@@ -130,41 +171,27 @@ struct intel_context
|
|||||||
GLuint Fallback;
|
GLuint Fallback;
|
||||||
GLuint NewGLState;
|
GLuint NewGLState;
|
||||||
|
|
||||||
struct {
|
GLuint last_fence;
|
||||||
GLuint start_offset;
|
GLuint last_swap_fence;
|
||||||
GLint size;
|
|
||||||
GLint space;
|
struct intel_batchbuffer *batch;
|
||||||
GLubyte *ptr;
|
|
||||||
} batch;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
void *ptr;
|
|
||||||
GLint size;
|
|
||||||
GLuint offset;
|
|
||||||
GLuint active_buf;
|
|
||||||
GLuint irq_emitted;
|
|
||||||
} alloc;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
GLuint id;
|
||||||
GLuint primitive;
|
GLuint primitive;
|
||||||
GLubyte *start_ptr;
|
GLubyte *start_ptr;
|
||||||
void (*flush)( GLcontext * );
|
void (*flush)( struct intel_context * );
|
||||||
} prim;
|
} prim;
|
||||||
|
|
||||||
GLboolean locked;
|
GLboolean locked;
|
||||||
|
|
||||||
GLubyte clear_red;
|
|
||||||
GLubyte clear_green;
|
|
||||||
GLubyte clear_blue;
|
|
||||||
GLubyte clear_alpha;
|
|
||||||
GLuint ClearColor;
|
GLuint ClearColor;
|
||||||
GLuint ClearDepth;
|
GLuint ClearDepth;
|
||||||
|
|
||||||
|
/* Offsets of fields within the current vertex:
|
||||||
|
*/
|
||||||
GLuint coloroffset;
|
GLuint coloroffset;
|
||||||
GLuint specoffset;
|
GLuint specoffset;
|
||||||
|
|
||||||
/* Support for duplicating XYZW as WPOS parameter (crutch for I915).
|
|
||||||
*/
|
|
||||||
GLuint wpos_offset;
|
GLuint wpos_offset;
|
||||||
GLuint wpos_size;
|
GLuint wpos_size;
|
||||||
|
|
||||||
@@ -179,14 +206,10 @@ struct intel_context
|
|||||||
GLboolean hw_stencil;
|
GLboolean hw_stencil;
|
||||||
GLboolean hw_stipple;
|
GLboolean hw_stipple;
|
||||||
|
|
||||||
/* Texture object bookkeeping
|
/* AGP memory buffer manager:
|
||||||
*/
|
*/
|
||||||
GLuint nr_heaps;
|
struct bufmgr *bm;
|
||||||
driTexHeap * texture_heaps[1];
|
|
||||||
driTextureObject swapped;
|
|
||||||
GLuint lastStamp;
|
|
||||||
|
|
||||||
struct intel_texture_object *CurrentTexObj[MAX_TEXTURE_UNITS];
|
|
||||||
|
|
||||||
/* State for intelvb.c and inteltris.c.
|
/* State for intelvb.c and inteltris.c.
|
||||||
*/
|
*/
|
||||||
@@ -195,7 +218,13 @@ struct intel_context
|
|||||||
GLenum render_primitive;
|
GLenum render_primitive;
|
||||||
GLenum reduced_primitive;
|
GLenum reduced_primitive;
|
||||||
GLuint vertex_size;
|
GLuint vertex_size;
|
||||||
char *verts; /* points to tnl->clipspace.vertex_buf */
|
GLubyte *verts; /* points to tnl->clipspace.vertex_buf */
|
||||||
|
|
||||||
|
|
||||||
|
struct intel_region *front_region;
|
||||||
|
struct intel_region *back_region;
|
||||||
|
struct intel_region *draw_region;
|
||||||
|
struct intel_region *depth_region;
|
||||||
|
|
||||||
|
|
||||||
/* Fallback rasterization functions
|
/* Fallback rasterization functions
|
||||||
@@ -206,13 +235,11 @@ struct intel_context
|
|||||||
|
|
||||||
/* These refer to the current draw (front vs. back) buffer:
|
/* These refer to the current draw (front vs. back) buffer:
|
||||||
*/
|
*/
|
||||||
GLuint drawOffset; /* agp offset of drawbuffer */
|
|
||||||
int drawX; /* origin of drawable in draw buffer */
|
int drawX; /* origin of drawable in draw buffer */
|
||||||
int drawY;
|
int drawY;
|
||||||
GLuint numClipRects; /* cliprects for that buffer */
|
GLuint numClipRects; /* cliprects for that buffer */
|
||||||
drm_clip_rect_t *pClipRects;
|
drm_clip_rect_t *pClipRects;
|
||||||
|
|
||||||
int dirtyAge;
|
|
||||||
int perf_boxes;
|
int perf_boxes;
|
||||||
int do_irqs;
|
int do_irqs;
|
||||||
|
|
||||||
@@ -228,6 +255,8 @@ struct intel_context
|
|||||||
__DRIscreenPrivate *driScreen;
|
__DRIscreenPrivate *driScreen;
|
||||||
intelScreenPrivate *intelScreen;
|
intelScreenPrivate *intelScreen;
|
||||||
drmI830Sarea *sarea;
|
drmI830Sarea *sarea;
|
||||||
|
|
||||||
|
GLuint lastStamp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration cache
|
* Configuration cache
|
||||||
@@ -321,8 +350,7 @@ do { \
|
|||||||
|
|
||||||
#define INTEL_FIREVERTICES(intel) \
|
#define INTEL_FIREVERTICES(intel) \
|
||||||
do { \
|
do { \
|
||||||
if ((intel)->prim.flush) \
|
assert(!(intel)->prim.flush); \
|
||||||
(intel)->prim.flush(&(intel)->ctx); \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
@@ -356,7 +384,7 @@ do { \
|
|||||||
* than COPY_DWORDS would:
|
* than COPY_DWORDS would:
|
||||||
*/
|
*/
|
||||||
#if defined(i386) || defined(__i386__)
|
#if defined(i386) || defined(__i386__)
|
||||||
static __inline__ void * __memcpy(void * to, const void * from, size_t n)
|
static inline void * __memcpy(void * to, const void * from, size_t n)
|
||||||
{
|
{
|
||||||
int d0, d1, d2;
|
int d0, d1, d2;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -417,21 +445,19 @@ extern int INTEL_DEBUG;
|
|||||||
* intel_context.c:
|
* intel_context.c:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void intelInitDriverFunctions( struct dd_function_table *functions );
|
extern GLboolean intelInitContext( struct intel_context *intel,
|
||||||
|
|
||||||
extern GLboolean intelInitContext( intelContextPtr intel,
|
|
||||||
const __GLcontextModes *mesaVis,
|
const __GLcontextModes *mesaVis,
|
||||||
__DRIcontextPrivate *driContextPriv,
|
__DRIcontextPrivate *driContextPriv,
|
||||||
void *sharedContextPrivate,
|
void *sharedContextPrivate,
|
||||||
struct dd_function_table *functions );
|
struct dd_function_table *functions );
|
||||||
|
|
||||||
extern void intelGetLock(intelContextPtr intel, GLuint flags);
|
extern void intelGetLock(struct intel_context *intel, GLuint flags);
|
||||||
extern void intelSetBackClipRects(intelContextPtr intel);
|
|
||||||
extern void intelSetFrontClipRects(intelContextPtr intel);
|
|
||||||
extern void intelWindowMoved( intelContextPtr intel );
|
|
||||||
|
|
||||||
extern void intelInitState( GLcontext *ctx );
|
extern void intelInitState( GLcontext *ctx );
|
||||||
extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name );
|
extern void intelFinish( GLcontext *ctx );
|
||||||
|
extern void intelFlush( GLcontext *ctx );
|
||||||
|
|
||||||
|
extern void intelInitDriverFunctions( struct dd_function_table *functions );
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
@@ -491,6 +517,8 @@ extern void intelInitStateFuncs( struct dd_function_table *functions );
|
|||||||
#define BLENDFACT_INV_CONST_ALPHA 0x0f
|
#define BLENDFACT_INV_CONST_ALPHA 0x0f
|
||||||
#define BLENDFACT_MASK 0x0f
|
#define BLENDFACT_MASK 0x0f
|
||||||
|
|
||||||
|
#define MI_BATCH_BUFFER_END (0xA<<23)
|
||||||
|
|
||||||
|
|
||||||
extern int intel_translate_compare_func( GLenum func );
|
extern int intel_translate_compare_func( GLenum func );
|
||||||
extern int intel_translate_stencil_op( GLenum op );
|
extern int intel_translate_stencil_op( GLenum op );
|
||||||
@@ -499,18 +527,39 @@ extern int intel_translate_logic_op( GLenum opcode );
|
|||||||
|
|
||||||
|
|
||||||
/* ================================================================
|
/* ================================================================
|
||||||
* intel_ioctl.c:
|
* intel_buffers.c:
|
||||||
*/
|
*/
|
||||||
extern void intel_dump_batchbuffer( long offset,
|
void intelInitBufferFuncs( struct dd_function_table *functions );
|
||||||
int *ptr,
|
|
||||||
int count );
|
struct intel_region *intel_readbuf_region( struct intel_context *intel );
|
||||||
|
struct intel_region *intel_drawbuf_region( struct intel_context *intel );
|
||||||
|
|
||||||
|
extern void intelWindowMoved( struct intel_context *intel );
|
||||||
|
|
||||||
|
extern GLboolean intel_intersect_cliprects( drm_clip_rect_t *dest,
|
||||||
|
const drm_clip_rect_t *a,
|
||||||
|
const drm_clip_rect_t *b );
|
||||||
|
|
||||||
|
|
||||||
/* ================================================================
|
|
||||||
* intel_pixel.c:
|
|
||||||
*/
|
|
||||||
extern void intelInitPixelFuncs( struct dd_function_table *functions );
|
|
||||||
|
|
||||||
|
/*======================================================================
|
||||||
|
* Inline conversion functions.
|
||||||
|
* These are better-typed than the macros used previously:
|
||||||
|
*/
|
||||||
|
static inline struct intel_context *intel_context( GLcontext *ctx )
|
||||||
|
{
|
||||||
|
return (struct intel_context *)ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct intel_texture_object *intel_texture_object( struct gl_texture_object *obj )
|
||||||
|
{
|
||||||
|
return (struct intel_texture_object *)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct intel_texture_image *intel_texture_image( struct gl_texture_image *img )
|
||||||
|
{
|
||||||
|
return (struct intel_texture_image *)img;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -38,11 +38,13 @@
|
|||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
#include "intel_ioctl.h"
|
#include "intel_ioctl.h"
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
#include "drm.h"
|
#include "drm.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
int intelEmitIrqLocked( struct intel_context *intel )
|
||||||
static int intelEmitIrqLocked( intelContextPtr intel )
|
|
||||||
{
|
{
|
||||||
drmI830IrqEmit ie;
|
drmI830IrqEmit ie;
|
||||||
int ret, seq = 0;
|
int ret, seq = 0;
|
||||||
@@ -51,21 +53,21 @@ static int intelEmitIrqLocked( intelContextPtr intel )
|
|||||||
(DRM_LOCK_HELD|intel->hHWContext));
|
(DRM_LOCK_HELD|intel->hHWContext));
|
||||||
|
|
||||||
ie.irq_seq = &seq;
|
ie.irq_seq = &seq;
|
||||||
|
|
||||||
ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT,
|
ret = drmCommandWriteRead( intel->driFd, DRM_I830_IRQ_EMIT,
|
||||||
&ie, sizeof(ie) );
|
&ie, sizeof(ie) );
|
||||||
if ( ret ) {
|
if ( ret ) {
|
||||||
fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
|
fprintf( stderr, "%s: drmI830IrqEmit: %d\n", __FUNCTION__, ret );
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
fprintf(stderr, "%s --> %d\n", __FUNCTION__, seq );
|
fprintf(stderr, "%s --> %d\n", __FUNCTION__, seq );
|
||||||
|
|
||||||
return seq;
|
return seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intelWaitIrq( intelContextPtr intel, int seq )
|
void intelWaitIrq( struct intel_context *intel, int seq )
|
||||||
{
|
{
|
||||||
drmI830IrqWait iw;
|
drmI830IrqWait iw;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -81,527 +83,63 @@ static void intelWaitIrq( intelContextPtr intel, int seq )
|
|||||||
|
|
||||||
if ( ret ) {
|
if ( ret ) {
|
||||||
fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
|
fprintf( stderr, "%s: drmI830IrqWait: %d\n", __FUNCTION__, ret );
|
||||||
if (0)
|
|
||||||
intel_dump_batchbuffer( intel->alloc.offset,
|
|
||||||
intel->alloc.ptr,
|
|
||||||
intel->alloc.size );
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intel_batch_ioctl( struct intel_context *intel,
|
||||||
static void age_intel( intelContextPtr intel, int age )
|
GLuint start_offset,
|
||||||
{
|
GLuint used,
|
||||||
GLuint i;
|
GLboolean ignore_cliprects)
|
||||||
|
|
||||||
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
|
|
||||||
if (intel->CurrentTexObj[i])
|
|
||||||
intel->CurrentTexObj[i]->age = age;
|
|
||||||
}
|
|
||||||
|
|
||||||
void intel_dump_batchbuffer( long offset,
|
|
||||||
int *ptr,
|
|
||||||
int count )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count);
|
|
||||||
for (i = 0; i < count/4; i += 4)
|
|
||||||
fprintf(stderr, "\t0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
|
|
||||||
(unsigned int)offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
|
|
||||||
fprintf(stderr, "END BATCH\n\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock )
|
|
||||||
{
|
|
||||||
GLuint last_irq = intel->alloc.irq_emitted;
|
|
||||||
GLuint half = intel->alloc.size / 2;
|
|
||||||
GLuint buf = (intel->alloc.active_buf ^= 1);
|
|
||||||
|
|
||||||
intel->alloc.irq_emitted = intelEmitIrqLocked( intel );
|
|
||||||
|
|
||||||
if (last_irq) {
|
|
||||||
if (allow_unlock) UNLOCK_HARDWARE( intel );
|
|
||||||
intelWaitIrq( intel, last_irq );
|
|
||||||
if (allow_unlock) LOCK_HARDWARE( intel );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s: now using half %d\n", __FUNCTION__, buf);
|
|
||||||
|
|
||||||
intel->batch.start_offset = intel->alloc.offset + buf * half;
|
|
||||||
intel->batch.ptr = (GLubyte *)intel->alloc.ptr + buf * half;
|
|
||||||
intel->batch.size = half - 8;
|
|
||||||
intel->batch.space = half - 8;
|
|
||||||
assert(intel->batch.space >= 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define MI_BATCH_BUFFER_END (0xA<<23)
|
|
||||||
|
|
||||||
|
|
||||||
void intelFlushBatchLocked( intelContextPtr intel,
|
|
||||||
GLboolean ignore_cliprects,
|
|
||||||
GLboolean refill,
|
|
||||||
GLboolean allow_unlock)
|
|
||||||
{
|
{
|
||||||
drmI830BatchBuffer batch;
|
drmI830BatchBuffer batch;
|
||||||
|
|
||||||
assert(intel->locked);
|
assert(intel->locked);
|
||||||
|
assert(used);
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
fprintf(stderr, "%s used %d of %d offset %x..%x refill %d\n",
|
fprintf(stderr, "%s used %d offset %x..%x ignore_cliprects %d\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
(intel->batch.size - intel->batch.space),
|
used,
|
||||||
intel->batch.size,
|
start_offset,
|
||||||
intel->batch.start_offset,
|
start_offset + used,
|
||||||
intel->batch.start_offset +
|
ignore_cliprects);
|
||||||
(intel->batch.size - intel->batch.space),
|
|
||||||
refill);
|
|
||||||
|
|
||||||
/* Throw away non-effective packets. Won't work once we have
|
/* Throw away non-effective packets. Won't work once we have
|
||||||
* hardware contexts which would preserve statechanges beyond a
|
* hardware contexts which would preserve statechanges beyond a
|
||||||
* single buffer.
|
* single buffer.
|
||||||
*/
|
*/
|
||||||
if (intel->numClipRects == 0 && !ignore_cliprects) {
|
if (intel->numClipRects == 0 && !ignore_cliprects) {
|
||||||
|
|
||||||
/* Without this yeild, an application with no cliprects can hog
|
|
||||||
* the hardware. Without unlocking, the effect is much worse -
|
|
||||||
* effectively a lock-out of other contexts.
|
|
||||||
*/
|
|
||||||
if (allow_unlock) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
sched_yield();
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note that any state thought to have been emitted actually
|
|
||||||
* hasn't:
|
|
||||||
*/
|
|
||||||
intel->batch.ptr -= (intel->batch.size - intel->batch.space);
|
|
||||||
intel->batch.space = intel->batch.size;
|
|
||||||
intel->vtbl.lost_hardware( intel );
|
intel->vtbl.lost_hardware( intel );
|
||||||
}
|
|
||||||
|
|
||||||
if (intel->batch.space != intel->batch.size) {
|
|
||||||
batch.start = intel->batch.start_offset;
|
|
||||||
batch.used = intel->batch.size - intel->batch.space;
|
|
||||||
batch.cliprects = intel->pClipRects;
|
|
||||||
batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
|
|
||||||
batch.DR1 = 0;
|
|
||||||
batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
|
|
||||||
(((GLuint)intel->drawY) << 16));
|
|
||||||
|
|
||||||
if (intel->alloc.offset) {
|
|
||||||
if ((batch.used & 0x4) == 0) {
|
|
||||||
((int *)intel->batch.ptr)[0] = 0;
|
|
||||||
((int *)intel->batch.ptr)[1] = MI_BATCH_BUFFER_END;
|
|
||||||
batch.used += 0x8;
|
|
||||||
intel->batch.ptr += 0x8;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
((int *)intel->batch.ptr)[0] = MI_BATCH_BUFFER_END;
|
|
||||||
batch.used += 0x4;
|
|
||||||
intel->batch.ptr += 0x4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
intel_dump_batchbuffer( batch.start,
|
|
||||||
(int *)(intel->batch.ptr - batch.used),
|
|
||||||
batch.used );
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
|
|
||||||
__FUNCTION__,
|
|
||||||
batch.start,
|
|
||||||
batch.start + batch.used,
|
|
||||||
batch.DR4, batch.num_cliprects);
|
|
||||||
|
|
||||||
intel->batch.start_offset += batch.used;
|
|
||||||
intel->batch.size -= batch.used;
|
|
||||||
|
|
||||||
if (intel->batch.size < 8) {
|
|
||||||
refill = GL_TRUE;
|
|
||||||
intel->batch.space = intel->batch.size = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
intel->batch.size -= 8;
|
|
||||||
intel->batch.space = intel->batch.size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
assert(intel->batch.space >= 0);
|
|
||||||
assert(batch.start >= intel->alloc.offset);
|
|
||||||
assert(batch.start < intel->alloc.offset + intel->alloc.size);
|
|
||||||
assert(batch.start + batch.used > intel->alloc.offset);
|
|
||||||
assert(batch.start + batch.used <=
|
|
||||||
intel->alloc.offset + intel->alloc.size);
|
|
||||||
|
|
||||||
|
|
||||||
if (intel->alloc.offset) {
|
|
||||||
if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch,
|
|
||||||
sizeof(batch))) {
|
|
||||||
fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno);
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
drmI830CmdBuffer cmd;
|
|
||||||
cmd.buf = (char *)intel->alloc.ptr + batch.start;
|
|
||||||
cmd.sz = batch.used;
|
|
||||||
cmd.DR1 = batch.DR1;
|
|
||||||
cmd.DR4 = batch.DR4;
|
|
||||||
cmd.num_cliprects = batch.num_cliprects;
|
|
||||||
cmd.cliprects = batch.cliprects;
|
|
||||||
|
|
||||||
if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd,
|
|
||||||
sizeof(cmd))) {
|
|
||||||
fprintf(stderr, "DRM_I830_CMDBUFFER: %d\n", -errno);
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
age_intel(intel, intel->sarea->last_enqueue);
|
|
||||||
|
|
||||||
/* FIXME: use hardware contexts to avoid 'losing' hardware after
|
|
||||||
* each buffer flush.
|
|
||||||
*/
|
|
||||||
intel->vtbl.lost_hardware( intel );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (refill)
|
|
||||||
intelRefillBatchLocked( intel, allow_unlock );
|
|
||||||
}
|
|
||||||
|
|
||||||
void intelFlushBatch( intelContextPtr intel, GLboolean refill )
|
|
||||||
{
|
|
||||||
if (intel->locked) {
|
|
||||||
intelFlushBatchLocked( intel, GL_FALSE, refill, GL_FALSE );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOCK_HARDWARE(intel);
|
|
||||||
intelFlushBatchLocked( intel, GL_FALSE, refill, GL_TRUE );
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelWaitForIdle( intelContextPtr intel )
|
|
||||||
{
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
intel->vtbl.emit_flush( intel );
|
|
||||||
intelFlushBatch( intel, GL_TRUE );
|
|
||||||
|
|
||||||
/* Use an irq to wait for dma idle -- Need to track lost contexts
|
|
||||||
* to shortcircuit consecutive calls to this function:
|
|
||||||
*/
|
|
||||||
intelWaitIrq( intel, intel->alloc.irq_emitted );
|
|
||||||
intel->alloc.irq_emitted = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelFlush( GLcontext *ctx )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
|
||||||
|
|
||||||
if (intel->Fallback)
|
|
||||||
_swrast_flush( ctx );
|
|
||||||
|
|
||||||
INTEL_FIREVERTICES( intel );
|
|
||||||
|
|
||||||
if (intel->batch.size != intel->batch.space)
|
|
||||||
intelFlushBatch( intel, GL_FALSE );
|
|
||||||
}
|
|
||||||
|
|
||||||
void intelFinish( GLcontext *ctx )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
|
||||||
intelFlush( ctx );
|
|
||||||
intelWaitForIdle( intel );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
|
|
||||||
GLint cx, GLint cy, GLint cw, GLint ch)
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
|
||||||
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
|
|
||||||
GLbitfield tri_mask = 0;
|
|
||||||
GLbitfield blit_mask = 0;
|
|
||||||
GLbitfield swrast_mask = 0;
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
/* Take care of cliprects, which are handled differently for
|
|
||||||
* clears, etc.
|
|
||||||
*/
|
|
||||||
intelFlush( &intel->ctx );
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_FRONT_LEFT) {
|
|
||||||
if (colorMask == ~0) {
|
|
||||||
blit_mask |= BUFFER_BIT_FRONT_LEFT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tri_mask |= BUFFER_BIT_FRONT_LEFT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_BACK_LEFT) {
|
|
||||||
if (colorMask == ~0) {
|
|
||||||
blit_mask |= BUFFER_BIT_BACK_LEFT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
tri_mask |= BUFFER_BIT_BACK_LEFT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_DEPTH) {
|
|
||||||
blit_mask |= BUFFER_BIT_DEPTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & BUFFER_BIT_STENCIL) {
|
|
||||||
if (!intel->hw_stencil) {
|
|
||||||
swrast_mask |= BUFFER_BIT_STENCIL;
|
|
||||||
}
|
|
||||||
else if (ctx->Stencil.WriteMask[0] != 0xff) {
|
|
||||||
tri_mask |= BUFFER_BIT_STENCIL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
blit_mask |= BUFFER_BIT_STENCIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
swrast_mask |= (mask & BUFFER_BIT_ACCUM);
|
|
||||||
|
|
||||||
if (blit_mask)
|
|
||||||
intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch );
|
|
||||||
|
|
||||||
if (tri_mask)
|
|
||||||
intel->vtbl.clear_with_tris( intel, tri_mask, all, cx, cy, cw, ch);
|
|
||||||
|
|
||||||
if (swrast_mask)
|
|
||||||
_swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
|
|
||||||
{
|
|
||||||
int region_offset = 0;
|
|
||||||
drmI830MemAlloc alloc;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s: %d bytes\n", __FUNCTION__, size);
|
|
||||||
|
|
||||||
alloc.region = I830_MEM_REGION_AGP;
|
|
||||||
alloc.alignment = 0;
|
|
||||||
alloc.size = size;
|
|
||||||
alloc.region_offset = ®ion_offset;
|
|
||||||
|
|
||||||
LOCK_HARDWARE(intel);
|
|
||||||
|
|
||||||
/* Make sure the global heap is initialized
|
|
||||||
*/
|
|
||||||
if (intel->texture_heaps[0])
|
|
||||||
driAgeTextures( intel->texture_heaps[0] );
|
|
||||||
|
|
||||||
|
|
||||||
ret = drmCommandWriteRead( intel->driFd,
|
|
||||||
DRM_I830_ALLOC,
|
|
||||||
&alloc, sizeof(alloc));
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
fprintf(stderr, "%s: DRM_I830_ALLOC ret %d\n", __FUNCTION__, ret);
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s: allocated %d bytes\n", __FUNCTION__, size);
|
|
||||||
|
|
||||||
/* Need to propogate this information (agp memory in use) to our
|
|
||||||
* local texture lru. The kernel has already updated the global
|
|
||||||
* lru. An alternative would have been to allocate memory the
|
|
||||||
* usual way and then notify the kernel to pin the allocation.
|
|
||||||
*/
|
|
||||||
if (intel->texture_heaps[0])
|
|
||||||
driAgeTextures( intel->texture_heaps[0] );
|
|
||||||
|
|
||||||
UNLOCK_HARDWARE(intel);
|
|
||||||
|
|
||||||
return (void *)((char *)intel->intelScreen->tex.map + region_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void intelFreeAGP( intelContextPtr intel, void *pointer )
|
|
||||||
{
|
|
||||||
int region_offset;
|
|
||||||
drmI830MemFree memfree;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
region_offset = (char *)pointer - (char *)intel->intelScreen->tex.map;
|
|
||||||
|
|
||||||
if (region_offset < 0 ||
|
|
||||||
region_offset > intel->intelScreen->tex.size) {
|
|
||||||
fprintf(stderr, "offset %d outside range 0..%d\n", region_offset,
|
|
||||||
intel->intelScreen->tex.size);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
memfree.region = I830_MEM_REGION_AGP;
|
batch.start = start_offset;
|
||||||
memfree.region_offset = region_offset;
|
batch.used = used;
|
||||||
|
batch.cliprects = intel->pClipRects;
|
||||||
ret = drmCommandWrite( intel->driFd,
|
batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
|
||||||
DRM_I830_FREE,
|
batch.DR1 = 0;
|
||||||
&memfree, sizeof(memfree));
|
batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
|
||||||
|
(((GLuint)intel->drawY) << 16));
|
||||||
if (ret)
|
|
||||||
fprintf(stderr, "%s: DRM_I830_FREE ret %d\n", __FUNCTION__, ret);
|
if (INTEL_DEBUG & DEBUG_DMA)
|
||||||
}
|
fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
|
||||||
|
__FUNCTION__,
|
||||||
/* This version of AllocateMemoryMESA allocates only agp memory, and
|
batch.start,
|
||||||
* only does so after the point at which the driver has been
|
batch.start + batch.used * 4,
|
||||||
* initialized.
|
batch.DR4, batch.num_cliprects);
|
||||||
*
|
#if 1
|
||||||
* Theoretically a valid context isn't required. However, in this
|
if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch,
|
||||||
* implementation, it is, as I'm using the hardware lock to protect
|
sizeof(batch))) {
|
||||||
* the kernel data structures, and the current context to get the
|
fprintf(stderr, "DRM_I830_BATCHBUFFER: %d\n", -errno);
|
||||||
* device fd.
|
UNLOCK_HARDWARE(intel);
|
||||||
*/
|
|
||||||
void *intelAllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn,
|
|
||||||
GLsizei size, GLfloat readfreq,
|
|
||||||
GLfloat writefreq, GLfloat priority)
|
|
||||||
{
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_IOCTL)
|
|
||||||
fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq,
|
|
||||||
writefreq, priority);
|
|
||||||
|
|
||||||
if (getenv("INTEL_NO_ALLOC"))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!ctx || INTEL_CONTEXT(ctx) == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return intelAllocateAGP( INTEL_CONTEXT(ctx), size );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Called via glXFreeMemoryMESA() */
|
|
||||||
void intelFreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer)
|
|
||||||
{
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
|
||||||
if (INTEL_DEBUG & DEBUG_IOCTL)
|
|
||||||
fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);
|
|
||||||
|
|
||||||
if (!ctx || INTEL_CONTEXT(ctx) == 0) {
|
|
||||||
fprintf(stderr, "%s: no context\n", __FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
intelFreeAGP( INTEL_CONTEXT(ctx), pointer );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Called via glXGetMemoryOffsetMESA()
|
|
||||||
*
|
|
||||||
* Returns offset of pointer from the start of agp aperture.
|
|
||||||
*/
|
|
||||||
GLuint intelGetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn,
|
|
||||||
const GLvoid *pointer)
|
|
||||||
{
|
|
||||||
GET_CURRENT_CONTEXT(ctx);
|
|
||||||
intelContextPtr intel;
|
|
||||||
|
|
||||||
if (!ctx || !(intel = INTEL_CONTEXT(ctx)) ) {
|
|
||||||
fprintf(stderr, "%s: no context\n", __FUNCTION__);
|
|
||||||
return ~0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!intelIsAgpMemory( intel, pointer, 0 ))
|
|
||||||
return ~0;
|
|
||||||
|
|
||||||
return intelAgpOffsetFromVirtual( intel, pointer );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer,
|
|
||||||
GLint size )
|
|
||||||
{
|
|
||||||
int offset = (char *)pointer - (char *)intel->intelScreen->tex.map;
|
|
||||||
int valid = (size >= 0 &&
|
|
||||||
offset >= 0 &&
|
|
||||||
offset + size < intel->intelScreen->tex.size);
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_IOCTL)
|
|
||||||
fprintf(stderr, "intelIsAgpMemory( %p ) : %d\n", pointer, valid );
|
|
||||||
|
|
||||||
return valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *pointer )
|
|
||||||
{
|
|
||||||
int offset = (char *)pointer - (char *)intel->intelScreen->tex.map;
|
|
||||||
|
|
||||||
if (offset < 0 || offset > intel->intelScreen->tex.size)
|
|
||||||
return ~0;
|
|
||||||
else
|
|
||||||
return intel->intelScreen->tex.offset + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Flip the front & back buffes
|
|
||||||
*/
|
|
||||||
void intelPageFlip( const __DRIdrawablePrivate *dPriv )
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
intelContextPtr intel;
|
|
||||||
int tmp, ret;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_IOCTL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
assert(dPriv);
|
|
||||||
assert(dPriv->driContextPriv);
|
|
||||||
assert(dPriv->driContextPriv->driverPrivate);
|
|
||||||
|
|
||||||
intel = (intelContextPtr) dPriv->driContextPriv->driverPrivate;
|
|
||||||
|
|
||||||
intelFlush( &intel->ctx );
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
|
|
||||||
if (dPriv->pClipRects) {
|
|
||||||
*(drm_clip_rect_t *)intel->sarea->boxes = dPriv->pClipRects[0];
|
|
||||||
intel->sarea->nbox = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = drmCommandNone(intel->driFd, DRM_I830_FLIP);
|
|
||||||
if (ret) {
|
|
||||||
fprintf(stderr, "%s: %d\n", __FUNCTION__, ret);
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = intel->sarea->last_enqueue;
|
|
||||||
intelRefillBatchLocked( intel );
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
|
|
||||||
|
|
||||||
intelSetDrawBuffer( &intel->ctx, intel->ctx.Color.DriverDrawBuffer );
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* FIXME: use hardware contexts to avoid 'losing' hardware after
|
||||||
|
* each buffer flush.
|
||||||
|
*/
|
||||||
|
intel->vtbl.lost_hardware( intel );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,37 +30,13 @@
|
|||||||
|
|
||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
|
|
||||||
extern void intelWaitAgeLocked( intelContextPtr intel, int age, GLboolean unlock );
|
void intelWaitIrq( struct intel_context *intel, int seq );
|
||||||
|
int intelEmitIrqLocked( struct intel_context *intel );
|
||||||
|
|
||||||
extern void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
|
void intel_batch_ioctl( struct intel_context *intel,
|
||||||
GLint cx, GLint cy, GLint cw, GLint ch);
|
GLuint start_offset,
|
||||||
|
GLuint used,
|
||||||
extern void intelPageFlip( const __DRIdrawablePrivate *dpriv );
|
GLboolean ignore_cliprects);
|
||||||
extern void intelWaitForIdle( intelContextPtr intel );
|
|
||||||
extern void intelFlushBatch( intelContextPtr intel, GLboolean refill );
|
|
||||||
extern void intelFlushBatchLocked( intelContextPtr intel,
|
|
||||||
GLboolean ignore_cliprects,
|
|
||||||
GLboolean refill,
|
|
||||||
GLboolean allow_unlock);
|
|
||||||
extern void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock );
|
|
||||||
extern void intelFinish( GLcontext *ctx );
|
|
||||||
extern void intelFlush( GLcontext *ctx );
|
|
||||||
|
|
||||||
extern void *intelAllocateAGP( intelContextPtr intel, GLsizei size );
|
|
||||||
extern void intelFreeAGP( intelContextPtr intel, void *pointer );
|
|
||||||
|
|
||||||
extern void *intelAllocateMemoryMESA( __DRInativeDisplay *dpy, int scrn,
|
|
||||||
GLsizei size, GLfloat readfreq,
|
|
||||||
GLfloat writefreq, GLfloat priority );
|
|
||||||
|
|
||||||
extern void intelFreeMemoryMESA( __DRInativeDisplay *dpy, int scrn,
|
|
||||||
GLvoid *pointer );
|
|
||||||
|
|
||||||
extern GLuint intelGetMemoryOffsetMESA( __DRInativeDisplay *dpy, int scrn, const GLvoid *pointer );
|
|
||||||
extern GLboolean intelIsAgpMemory( intelContextPtr intel, const GLvoid *pointer,
|
|
||||||
GLint size );
|
|
||||||
|
|
||||||
extern GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *p );
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
296
src/mesa/drivers/dri/i915/intel_mipmap_tree.c
Normal file
296
src/mesa/drivers/dri/i915/intel_mipmap_tree.c
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
#include "enums.h"
|
||||||
|
|
||||||
|
static GLenum target_to_target( GLenum target )
|
||||||
|
{
|
||||||
|
switch (target) {
|
||||||
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
|
||||||
|
return GL_TEXTURE_CUBE_MAP_ARB;
|
||||||
|
default:
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel,
|
||||||
|
GLenum target,
|
||||||
|
GLenum internal_format,
|
||||||
|
GLuint first_level,
|
||||||
|
GLuint last_level,
|
||||||
|
GLuint width0,
|
||||||
|
GLuint height0,
|
||||||
|
GLuint depth0,
|
||||||
|
GLuint cpp,
|
||||||
|
GLboolean compressed)
|
||||||
|
{
|
||||||
|
GLboolean ok;
|
||||||
|
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
|
||||||
|
|
||||||
|
DBG("%s target %s format %s level %d..%d\n", __FUNCTION__,
|
||||||
|
_mesa_lookup_enum_by_nr(target),
|
||||||
|
_mesa_lookup_enum_by_nr(internal_format),
|
||||||
|
first_level,
|
||||||
|
last_level);
|
||||||
|
|
||||||
|
mt->target = target_to_target(target);
|
||||||
|
mt->internal_format = internal_format;
|
||||||
|
mt->first_level = first_level;
|
||||||
|
mt->last_level = last_level;
|
||||||
|
mt->width0 = width0;
|
||||||
|
mt->height0 = height0;
|
||||||
|
mt->depth0 = depth0;
|
||||||
|
mt->cpp = cpp;
|
||||||
|
mt->compressed = compressed;
|
||||||
|
mt->refcount = 1;
|
||||||
|
|
||||||
|
switch (intel->intelScreen->deviceID) {
|
||||||
|
case PCI_CHIP_I945_G:
|
||||||
|
ok = i945_miptree_layout( mt );
|
||||||
|
break;
|
||||||
|
case PCI_CHIP_I915_G:
|
||||||
|
case PCI_CHIP_I915_GM:
|
||||||
|
ok = i915_miptree_layout( mt );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ok = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
mt->region = intel_region_alloc( intel,
|
||||||
|
mt->cpp,
|
||||||
|
mt->pitch,
|
||||||
|
mt->total_height );
|
||||||
|
|
||||||
|
if (!mt->region) {
|
||||||
|
free(mt);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intel_miptree_reference( struct intel_mipmap_tree **dst,
|
||||||
|
struct intel_mipmap_tree *src )
|
||||||
|
{
|
||||||
|
src->refcount++;
|
||||||
|
*dst = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_miptree_release( struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree **mt )
|
||||||
|
{
|
||||||
|
if (!*mt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DBG("%s %d\n", __FUNCTION__, (*mt)->refcount-1);
|
||||||
|
if (--(*mt)->refcount == 0) {
|
||||||
|
intel_region_release(intel, &((*mt)->region));
|
||||||
|
free(*mt);
|
||||||
|
}
|
||||||
|
*mt = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Can the image be pulled into a unified mipmap tree. This mirrors
|
||||||
|
* the completeness test in a lot of ways.
|
||||||
|
*
|
||||||
|
* Not sure whether I want to pass gl_texture_image here.
|
||||||
|
*/
|
||||||
|
GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt,
|
||||||
|
struct gl_texture_image *image,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level )
|
||||||
|
{
|
||||||
|
DBG("%s %d %d/%d %d/%d\n", __FUNCTION__,
|
||||||
|
image->Border,
|
||||||
|
image->InternalFormat, mt->internal_format,
|
||||||
|
image->IsCompressed, mt->compressed);
|
||||||
|
|
||||||
|
/* Images with borders are never pulled into mipmap trees.
|
||||||
|
*/
|
||||||
|
if (image->Border)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
if (image->InternalFormat != mt->internal_format ||
|
||||||
|
image->IsCompressed != mt->compressed)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
DBG("%s: %d/%d %d/%d %d/%d\n", __FUNCTION__,
|
||||||
|
image->Width, mt->offset[face][level].width,
|
||||||
|
image->Height, mt->offset[face][level].height,
|
||||||
|
image->Depth, mt->offset[face][level].depth);
|
||||||
|
|
||||||
|
/* Test image dimensions against the base level image adjusted for
|
||||||
|
* minification. This will also catch images not present in the
|
||||||
|
* tree, changed targets, etc.
|
||||||
|
*/
|
||||||
|
if (image->Width != mt->offset[face][level].width ||
|
||||||
|
image->Height != mt->offset[face][level].height ||
|
||||||
|
image->Depth != mt->offset[face][level].depth)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
DBG("%s: success\n", __FUNCTION__);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level)
|
||||||
|
{
|
||||||
|
return mt->offset[face][level].offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint intel_miptree_depth_image_stride(struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level)
|
||||||
|
{
|
||||||
|
return mt->offset[face][level].depth_image_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level,
|
||||||
|
GLuint x, GLuint y,
|
||||||
|
GLuint w, GLuint h, GLuint d)
|
||||||
|
{
|
||||||
|
mt->offset[face][level].offset = (x + y * mt->pitch) * mt->cpp;
|
||||||
|
mt->offset[face][level].width = w;
|
||||||
|
mt->offset[face][level].height = h;
|
||||||
|
mt->offset[face][level].depth = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLubyte *intel_miptree_image_map(struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level,
|
||||||
|
GLuint *row_stride,
|
||||||
|
GLuint *image_stride)
|
||||||
|
{
|
||||||
|
DBG("%s \n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (row_stride)
|
||||||
|
*row_stride = mt->pitch * mt->cpp;
|
||||||
|
|
||||||
|
if (image_stride)
|
||||||
|
*image_stride = mt->offset[face][level].depth_image_stride;
|
||||||
|
|
||||||
|
return (intel_region_map(intel, mt->region) +
|
||||||
|
intel_miptree_image_offset(mt, face, level));
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_miptree_image_unmap(struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *mt)
|
||||||
|
{
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
intel_region_unmap(intel, mt->region);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Upload data for a particular image.
|
||||||
|
*/
|
||||||
|
void intel_miptree_image_data(struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *dst,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level,
|
||||||
|
void *src,
|
||||||
|
GLuint src_row_pitch,
|
||||||
|
GLuint src_image_pitch)
|
||||||
|
{
|
||||||
|
GLuint depth = dst->offset[face][level].depth;
|
||||||
|
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
|
||||||
|
GLuint dst_image_stride = intel_miptree_depth_image_stride(dst, face, level);
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
for (i = 0; i < depth; i++) {
|
||||||
|
intel_region_data(intel,
|
||||||
|
dst->region, dst_offset,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
src,
|
||||||
|
src_row_pitch,
|
||||||
|
0, 0, /* source x,y */
|
||||||
|
dst->offset[face][level].width,
|
||||||
|
dst->offset[face][level].height);
|
||||||
|
dst_offset += dst_image_stride;
|
||||||
|
src += src_image_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy mipmap image between trees
|
||||||
|
*/
|
||||||
|
void intel_miptree_image_copy( struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *dst,
|
||||||
|
GLuint face, GLuint level,
|
||||||
|
struct intel_mipmap_tree *src )
|
||||||
|
{
|
||||||
|
GLuint width = src->offset[face][level].width;
|
||||||
|
GLuint height = src->offset[face][level].height;
|
||||||
|
GLuint depth = src->offset[face][level].depth;
|
||||||
|
GLuint dst_offset = intel_miptree_image_offset(dst, face, level);
|
||||||
|
GLuint src_offset = intel_miptree_image_offset(src, face, level);
|
||||||
|
GLuint dst_image_stride = intel_miptree_depth_image_stride(dst, face, level);
|
||||||
|
GLuint src_image_stride = intel_miptree_depth_image_stride(src, face, level);
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
for (i = 0; i < depth; i++) {
|
||||||
|
intel_region_copy(intel,
|
||||||
|
dst->region, dst_offset,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
src->region, src_offset,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width,
|
||||||
|
height);
|
||||||
|
|
||||||
|
dst_offset += dst_image_stride;
|
||||||
|
src_offset += src_image_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
180
src/mesa/drivers/dri/i915/intel_mipmap_tree.h
Normal file
180
src/mesa/drivers/dri/i915/intel_mipmap_tree.h
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INTEL_MIPMAP_TREE_H
|
||||||
|
#define INTEL_MIPMAP_TREE_H
|
||||||
|
|
||||||
|
#include "intel_regions.h"
|
||||||
|
|
||||||
|
/* A layer on top of the intel_regions code which adds:
|
||||||
|
*
|
||||||
|
* - Code to size and layout a region to hold a set of mipmaps.
|
||||||
|
* - Query to determine if a new image fits in an existing tree.
|
||||||
|
* - More refcounting
|
||||||
|
* - maybe able to remove refcounting from intel_region?
|
||||||
|
* - ?
|
||||||
|
*
|
||||||
|
* The fixed mipmap layout of intel hardware where one offset
|
||||||
|
* specifies the position of all images in a mipmap hierachy
|
||||||
|
* complicates the implementation of GL texture image commands,
|
||||||
|
* compared to hardware where each image is specified with an
|
||||||
|
* independent offset.
|
||||||
|
*
|
||||||
|
* In an ideal world, each texture object would be associated with a
|
||||||
|
* single bufmgr buffer or 2d intel_region, and all the images within
|
||||||
|
* the texture object would slot into the tree as they arrive. The
|
||||||
|
* reality can be a little messier, as images can arrive from the user
|
||||||
|
* with sizes that don't fit in the existing tree, or in an order
|
||||||
|
* where the tree layout cannot be guessed immediately.
|
||||||
|
*
|
||||||
|
* This structure encodes an idealized mipmap tree. The GL image
|
||||||
|
* commands build these where possible, otherwise store the images in
|
||||||
|
* temporary system buffers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
struct intel_mipmap_offset {
|
||||||
|
GLuint offset;
|
||||||
|
GLuint width;
|
||||||
|
GLuint height;
|
||||||
|
GLuint depth;
|
||||||
|
GLuint depth_image_stride;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct intel_mipmap_tree {
|
||||||
|
/* Effectively the key:
|
||||||
|
*/
|
||||||
|
GLenum target;
|
||||||
|
GLenum internal_format;
|
||||||
|
|
||||||
|
GLuint first_level;
|
||||||
|
GLuint last_level;
|
||||||
|
|
||||||
|
GLuint width0, height0, depth0;
|
||||||
|
GLuint cpp;
|
||||||
|
GLboolean compressed;
|
||||||
|
|
||||||
|
/* Derived from the above:
|
||||||
|
*/
|
||||||
|
GLuint pitch;
|
||||||
|
GLuint depth_pitch; /* per-image on i945? */
|
||||||
|
GLuint total_height;
|
||||||
|
struct intel_mipmap_offset offset[MAX_FACES][MAX_TEXTURE_LEVELS];
|
||||||
|
|
||||||
|
/* The data is held here:
|
||||||
|
*/
|
||||||
|
struct intel_region *region;
|
||||||
|
|
||||||
|
/* These are also refcounted:
|
||||||
|
*/
|
||||||
|
GLuint refcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct intel_mipmap_tree *intel_miptree_create( struct intel_context *intel,
|
||||||
|
GLenum target,
|
||||||
|
GLenum internal_format,
|
||||||
|
GLuint first_level,
|
||||||
|
GLuint last_level,
|
||||||
|
GLuint width0,
|
||||||
|
GLuint height0,
|
||||||
|
GLuint depth0,
|
||||||
|
GLuint cpp,
|
||||||
|
GLboolean compressed);
|
||||||
|
|
||||||
|
void intel_miptree_reference( struct intel_mipmap_tree **dst,
|
||||||
|
struct intel_mipmap_tree *src );
|
||||||
|
|
||||||
|
void intel_miptree_release( struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree **mt );
|
||||||
|
|
||||||
|
/* Check if an image fits an existing mipmap tree layout
|
||||||
|
*/
|
||||||
|
GLboolean intel_miptree_match_image( struct intel_mipmap_tree *mt,
|
||||||
|
struct gl_texture_image *image,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level );
|
||||||
|
|
||||||
|
/* Return a pointer to an image within a tree. Return image stride as
|
||||||
|
* well.
|
||||||
|
*/
|
||||||
|
GLubyte *intel_miptree_image_map( struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level,
|
||||||
|
GLuint *row_stride,
|
||||||
|
GLuint *image_stride);
|
||||||
|
|
||||||
|
void intel_miptree_image_unmap( struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *mt );
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the linear offset of an image relative to the start of the
|
||||||
|
* tree:
|
||||||
|
*/
|
||||||
|
GLuint intel_miptree_image_offset( struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level );
|
||||||
|
|
||||||
|
void intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level,
|
||||||
|
GLuint x, GLuint y,
|
||||||
|
GLuint w, GLuint h, GLuint d);
|
||||||
|
|
||||||
|
GLuint intel_miptree_depth_image_stride(struct intel_mipmap_tree *mt,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Upload an image into a tree
|
||||||
|
*/
|
||||||
|
void intel_miptree_image_data(struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *dst,
|
||||||
|
GLuint face,
|
||||||
|
GLuint level,
|
||||||
|
void *src,
|
||||||
|
GLuint src_row_pitch,
|
||||||
|
GLuint src_image_pitch);
|
||||||
|
|
||||||
|
/* Copy an image between two trees
|
||||||
|
*/
|
||||||
|
void intel_miptree_image_copy( struct intel_context *intel,
|
||||||
|
struct intel_mipmap_tree *dst,
|
||||||
|
GLuint face, GLuint level,
|
||||||
|
struct intel_mipmap_tree *src );
|
||||||
|
|
||||||
|
/* i915_mipmap_tree.c:
|
||||||
|
*/
|
||||||
|
GLboolean i915_miptree_layout( struct intel_mipmap_tree *mt );
|
||||||
|
GLboolean i945_miptree_layout( struct intel_mipmap_tree *mt );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,109 +1,89 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "glheader.h"
|
|
||||||
#include "enums.h"
|
|
||||||
#include "mtypes.h"
|
|
||||||
#include "macros.h"
|
|
||||||
#include "swrast/swrast.h"
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
#include "intel_screen.h"
|
|
||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
#include "intel_ioctl.h"
|
#include "intel_pixel.h"
|
||||||
#include "intel_batchbuffer.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GLboolean
|
#if 0
|
||||||
check_color( const GLcontext *ctx, GLenum type, GLenum format,
|
struct intel_client_region *intel_pack_region( struct intel_context *intel,
|
||||||
const struct gl_pixelstore_attrib *packing,
|
const struct gl_pixelstore_attrib *pack,
|
||||||
const void *pixels, GLint sz, GLint pitch )
|
GLenum format,
|
||||||
|
GLenum type,
|
||||||
|
GLvoid *pixels )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
}
|
||||||
GLuint cpp = intel->intelScreen->cpp;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
if ( (pitch & 63) ||
|
struct intel_client_region *intel_unpack_region( struct intel_context *intel,
|
||||||
ctx->_ImageTransferState ||
|
const struct gl_pixelstore_attrib *pack,
|
||||||
packing->SwapBytes ||
|
GLenum format,
|
||||||
packing->LsbFirst) {
|
GLenum type,
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
GLvoid *pixels )
|
||||||
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
|
{
|
||||||
return GL_FALSE;
|
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
|
||||||
}
|
/* XXX: Need to adjust pixels pointer for unpack->skip pixels/rows
|
||||||
|
* offsets.
|
||||||
|
*/
|
||||||
|
|
||||||
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV &&
|
}
|
||||||
cpp == 4 &&
|
|
||||||
format == GL_BGRA ) {
|
void release_client_region( struct intel_context *intel,
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
struct intel_region *region )
|
||||||
fprintf(stderr, "%s: passed 2\n", __FUNCTION__);
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx )
|
||||||
|
{
|
||||||
|
return !(ctx->Color.AlphaEnabled ||
|
||||||
|
ctx->Depth.Test ||
|
||||||
|
ctx->Fog.Enabled ||
|
||||||
|
ctx->Scissor.Enabled ||
|
||||||
|
ctx->Stencil.Enabled ||
|
||||||
|
!ctx->Color.ColorMask[0] ||
|
||||||
|
!ctx->Color.ColorMask[1] ||
|
||||||
|
!ctx->Color.ColorMask[2] ||
|
||||||
|
!ctx->Color.ColorMask[3] ||
|
||||||
|
ctx->Color.ColorLogicOpEnabled ||
|
||||||
|
ctx->Texture._EnabledUnits);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* The intel_region struct doesn't really do enough to capture the
|
||||||
|
* format of the pixels in the region. For now this code assumes that
|
||||||
|
* the region is a display surface and hence is either ARGB8888 or
|
||||||
|
* RGB565.
|
||||||
|
*/
|
||||||
|
GLboolean intel_check_blit_format( struct intel_region *region,
|
||||||
|
struct intel_client_region *client_region )
|
||||||
|
{
|
||||||
|
if (region->cpp == 4
|
||||||
|
client_region->cpp == 4 &&
|
||||||
|
client_region->type == GL_UNSIGNED_INT_8_8_8_8_REV &&
|
||||||
|
client_region->format == GL_BGRA ) {
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
if (region->cpp == 2 &&
|
||||||
fprintf(stderr, "%s: failed\n", __FUNCTION__);
|
client_region->cpp == 2 &&
|
||||||
|
client_region->type == GL_UNSIGNED_INT_5_6_5_REV &&
|
||||||
|
client_region->format == GL_BGR ) {
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "%s: request doesn't match pixel format\n", __FUNCTION__);
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static GLboolean
|
|
||||||
check_color_per_fragment_ops( const GLcontext *ctx )
|
GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
|
||||||
|
const GLframebuffer *buffer,
|
||||||
|
GLint *x, GLint *y,
|
||||||
|
GLsizei *width, GLsizei *height )
|
||||||
{
|
{
|
||||||
int result;
|
|
||||||
result = (!( ctx->Color.AlphaEnabled ||
|
|
||||||
ctx->Depth.Test ||
|
|
||||||
ctx->Fog.Enabled ||
|
|
||||||
ctx->Scissor.Enabled ||
|
|
||||||
ctx->Stencil.Enabled ||
|
|
||||||
!ctx->Color.ColorMask[0] ||
|
|
||||||
!ctx->Color.ColorMask[1] ||
|
|
||||||
!ctx->Color.ColorMask[2] ||
|
|
||||||
!ctx->Color.ColorMask[3] ||
|
|
||||||
ctx->Color.ColorLogicOpEnabled ||
|
|
||||||
ctx->Texture._EnabledUnits
|
|
||||||
) &&
|
|
||||||
ctx->Current.RasterPosValid);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GLboolean
|
|
||||||
clip_pixelrect( const GLcontext *ctx,
|
|
||||||
const GLframebuffer *buffer,
|
|
||||||
GLint *x, GLint *y,
|
|
||||||
GLsizei *width, GLsizei *height,
|
|
||||||
GLint *size )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
|
|
||||||
/* left clipping */
|
/* left clipping */
|
||||||
if (*x < buffer->_Xmin) {
|
if (*x < buffer->_Xmin) {
|
||||||
*width -= (buffer->_Xmin - *x);
|
*width -= (buffer->_Xmin - *x);
|
||||||
@@ -130,343 +110,9 @@ clip_pixelrect( const GLcontext *ctx,
|
|||||||
if (*height <= 0)
|
if (*height <= 0)
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
|
||||||
*size = ((*y + *height - 1) * intel->intelScreen->front.pitch +
|
|
||||||
(*x + *width - 1) * intel->intelScreen->cpp);
|
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLboolean
|
|
||||||
intelTryReadPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *pack,
|
|
||||||
GLvoid *pixels )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
GLint size = 0;
|
|
||||||
GLint pitch = pack->RowLength ? pack->RowLength : width;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
/* Only accelerate reading to agp buffers.
|
|
||||||
*/
|
|
||||||
if ( !intelIsAgpMemory(intel, pixels,
|
|
||||||
pitch * height * intel->intelScreen->cpp ) ) {
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s: dest not agp\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
|
|
||||||
* blitter:
|
|
||||||
*/
|
|
||||||
if (!pack->Invert) {
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_color(ctx, type, format, pack, pixels, size, pitch))
|
|
||||||
return GL_FALSE;
|
|
||||||
|
|
||||||
switch ( intel->intelScreen->cpp ) {
|
|
||||||
case 4:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Although the blits go on the command buffer, need to do this and
|
|
||||||
* fire with lock held to guarentee cliprects and drawOffset are
|
|
||||||
* correct.
|
|
||||||
*
|
|
||||||
* This is an unusual situation however, as the code which flushes
|
|
||||||
* a full command buffer expects to be called unlocked. As a
|
|
||||||
* workaround, immediately flush the buffer on aquiring the lock.
|
|
||||||
*/
|
|
||||||
intelFlush( &intel->ctx );
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
{
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
int nbox = dPriv->numClipRects;
|
|
||||||
int src_offset = intel->drawOffset;
|
|
||||||
int src_pitch = intel->intelScreen->front.pitch;
|
|
||||||
int dst_offset = intelAgpOffsetFromVirtual( intel, pixels);
|
|
||||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height,
|
|
||||||
&size)) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s totally clipped -- nothing to do\n",
|
|
||||||
__FUNCTION__);
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
y = dPriv->h - y - height;
|
|
||||||
x += dPriv->x;
|
|
||||||
y += dPriv->y;
|
|
||||||
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
|
|
||||||
src_pitch, pitch);
|
|
||||||
|
|
||||||
for (i = 0 ; i < nbox ; i++)
|
|
||||||
{
|
|
||||||
GLint bx = box[i].x1;
|
|
||||||
GLint by = box[i].y1;
|
|
||||||
GLint bw = box[i].x2 - bx;
|
|
||||||
GLint bh = box[i].y2 - by;
|
|
||||||
|
|
||||||
if (bx < x) bw -= x - bx, bx = x;
|
|
||||||
if (by < y) bh -= y - by, by = y;
|
|
||||||
if (bx + bw > x + width) bw = x + width - bx;
|
|
||||||
if (by + bh > y + height) bh = y + height - by;
|
|
||||||
if (bw <= 0) continue;
|
|
||||||
if (bh <= 0) continue;
|
|
||||||
|
|
||||||
intelEmitCopyBlitLocked( intel,
|
|
||||||
intel->intelScreen->cpp,
|
|
||||||
src_pitch, src_offset,
|
|
||||||
pitch, dst_offset,
|
|
||||||
bx, by,
|
|
||||||
bx - x, by - y,
|
|
||||||
bw, bh );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
intelFinish( &intel->ctx );
|
|
||||||
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
intelReadPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *pack,
|
|
||||||
GLvoid *pixels )
|
|
||||||
{
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
if (!intelTryReadPixels( ctx, x, y, width, height, format, type, pack,
|
|
||||||
pixels))
|
|
||||||
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack,
|
|
||||||
pixels);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void do_draw_pix( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLint pitch,
|
|
||||||
const void *pixels,
|
|
||||||
GLuint dest )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
|
||||||
drm_clip_rect_t *box = dPriv->pClipRects;
|
|
||||||
int nbox = dPriv->numClipRects;
|
|
||||||
int i;
|
|
||||||
int size;
|
|
||||||
int src_offset = intelAgpOffsetFromVirtual( intel, pixels);
|
|
||||||
int src_pitch = pitch;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
intelFlush( &intel->ctx );
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
if (ctx->DrawBuffer)
|
|
||||||
{
|
|
||||||
y -= height; /* cope with pixel zoom */
|
|
||||||
|
|
||||||
if (!clip_pixelrect(ctx, ctx->DrawBuffer,
|
|
||||||
&x, &y, &width, &height,
|
|
||||||
&size)) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
y = dPriv->h - y - height; /* convert from gl to hardware coords */
|
|
||||||
x += dPriv->x;
|
|
||||||
y += dPriv->y;
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0 ; i < nbox ; i++ )
|
|
||||||
{
|
|
||||||
GLint bx = box[i].x1;
|
|
||||||
GLint by = box[i].y1;
|
|
||||||
GLint bw = box[i].x2 - bx;
|
|
||||||
GLint bh = box[i].y2 - by;
|
|
||||||
|
|
||||||
if (bx < x) bw -= x - bx, bx = x;
|
|
||||||
if (by < y) bh -= y - by, by = y;
|
|
||||||
if (bx + bw > x + width) bw = x + width - bx;
|
|
||||||
if (by + bh > y + height) bh = y + height - by;
|
|
||||||
if (bw <= 0) continue;
|
|
||||||
if (bh <= 0) continue;
|
|
||||||
|
|
||||||
intelEmitCopyBlitLocked( intel,
|
|
||||||
intel->intelScreen->cpp,
|
|
||||||
src_pitch, src_offset,
|
|
||||||
intel->intelScreen->front.pitch,
|
|
||||||
intel->drawOffset,
|
|
||||||
bx - x, by - y,
|
|
||||||
bx, by,
|
|
||||||
bw, bh );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
intelFinish( &intel->ctx );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static GLboolean
|
|
||||||
intelTryDrawPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *unpack,
|
|
||||||
const GLvoid *pixels )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
|
|
||||||
GLuint dest;
|
|
||||||
GLuint cpp = intel->intelScreen->cpp;
|
|
||||||
GLint size = width * pitch * cpp;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
switch (format) {
|
|
||||||
case GL_RGB:
|
|
||||||
case GL_RGBA:
|
|
||||||
case GL_BGRA:
|
|
||||||
dest = intel->drawOffset;
|
|
||||||
|
|
||||||
/* Planemask doesn't have full support in blits.
|
|
||||||
*/
|
|
||||||
if (!ctx->Color.ColorMask[RCOMP] ||
|
|
||||||
!ctx->Color.ColorMask[GCOMP] ||
|
|
||||||
!ctx->Color.ColorMask[BCOMP] ||
|
|
||||||
!ctx->Color.ColorMask[ACOMP]) {
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s: planemask\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Can't do conversions on agp reads/draws.
|
|
||||||
*/
|
|
||||||
if ( !intelIsAgpMemory( intel, pixels, size ) ) {
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s: not agp memory\n", __FUNCTION__);
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) {
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
if (!check_color_per_fragment_ops(ctx)) {
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx->Pixel.ZoomX != 1.0F ||
|
|
||||||
ctx->Pixel.ZoomY != -1.0F)
|
|
||||||
return GL_FALSE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( intelIsAgpMemory(intel, pixels, size) )
|
|
||||||
{
|
|
||||||
do_draw_pix( ctx, x, y, width, height, pitch, pixels,
|
|
||||||
dest );
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
else if (0)
|
|
||||||
{
|
|
||||||
/* Pixels is in regular memory -- get dma buffers and perform
|
|
||||||
* upload through them. No point doing this for regular uploads
|
|
||||||
* but once we remove some of the restrictions above (colormask,
|
|
||||||
* pixelformat conversion, zoom?, etc), this could be a win.
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
intelDrawPixels( GLcontext *ctx,
|
|
||||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const struct gl_pixelstore_attrib *unpack,
|
|
||||||
const GLvoid *pixels )
|
|
||||||
{
|
|
||||||
if (INTEL_DEBUG & DEBUG_PIXEL)
|
|
||||||
fprintf(stderr, "%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
if (!intelTryDrawPixels( ctx, x, y, width, height, format, type,
|
|
||||||
unpack, pixels ))
|
|
||||||
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
|
|
||||||
unpack, pixels );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implement glCopyPixels for the front color buffer (or back buffer Pixmap)
|
|
||||||
* for the color buffer. Don't support zooming, pixel transfer, etc.
|
|
||||||
* We do support copying from one window to another, ala glXMakeCurrentRead.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
intelCopyPixels( GLcontext *ctx,
|
|
||||||
GLint srcx, GLint srcy, GLsizei width, GLsizei height,
|
|
||||||
GLint destx, GLint desty, GLenum type )
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
const XMesaContext xmesa = XMESA_CONTEXT(ctx);
|
|
||||||
const SWcontext *swrast = SWRAST_CONTEXT( ctx );
|
|
||||||
XMesaDisplay *dpy = xmesa->xm_visual->display;
|
|
||||||
const XMesaDrawable drawBuffer = xmesa->xm_draw_buffer->buffer;
|
|
||||||
const XMesaDrawable readBuffer = xmesa->xm_read_buffer->buffer;
|
|
||||||
const XMesaGC gc = xmesa->xm_draw_buffer->gc;
|
|
||||||
|
|
||||||
ASSERT(dpy);
|
|
||||||
ASSERT(gc);
|
|
||||||
|
|
||||||
if (drawBuffer && /* buffer != 0 means it's a Window or Pixmap */
|
|
||||||
readBuffer &&
|
|
||||||
type == GL_COLOR &&
|
|
||||||
(swrast->_RasterMask & ~CLIP_BIT) == 0 && /* no blend, z-test, etc */
|
|
||||||
ctx->_ImageTransferState == 0 && /* no color tables, scale/bias, etc */
|
|
||||||
ctx->Pixel.ZoomX == 1.0 && /* no zooming */
|
|
||||||
ctx->Pixel.ZoomY == 1.0) {
|
|
||||||
/* Note: we don't do any special clipping work here. We could,
|
|
||||||
* but X will do it for us.
|
|
||||||
*/
|
|
||||||
srcy = FLIP(xmesa->xm_read_buffer, srcy) - height + 1;
|
|
||||||
desty = FLIP(xmesa->xm_draw_buffer, desty) - height + 1;
|
|
||||||
XCopyArea(dpy, readBuffer, drawBuffer, gc,
|
|
||||||
srcx, srcy, width, height, destx, desty);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
_swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -476,14 +122,16 @@ void intelInitPixelFuncs( struct dd_function_table *functions )
|
|||||||
*/
|
*/
|
||||||
functions->Accum = _swrast_Accum;
|
functions->Accum = _swrast_Accum;
|
||||||
functions->Bitmap = _swrast_Bitmap;
|
functions->Bitmap = _swrast_Bitmap;
|
||||||
functions->CopyPixels = intelCopyPixels;
|
|
||||||
|
|
||||||
if (!getenv("INTEL_NO_BLITS")) {
|
if (getenv("INTEL_NO_BLITS") == 0) {
|
||||||
|
functions->CopyPixels = intelCopyPixels;
|
||||||
functions->ReadPixels = intelReadPixels;
|
functions->ReadPixels = intelReadPixels;
|
||||||
functions->DrawPixels = intelDrawPixels;
|
functions->DrawPixels = intelDrawPixels;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
functions->CopyPixels = _swrast_CopyPixels;
|
||||||
functions->ReadPixels = _swrast_ReadPixels;
|
functions->ReadPixels = _swrast_ReadPixels;
|
||||||
functions->DrawPixels = _swrast_DrawPixels;
|
functions->DrawPixels = _swrast_DrawPixels;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
63
src/mesa/drivers/dri/i915/intel_pixel.h
Normal file
63
src/mesa/drivers/dri/i915/intel_pixel.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INTEL_PIXEL_H
|
||||||
|
#define INTEL_PIXEL_H
|
||||||
|
|
||||||
|
#include "mtypes.h"
|
||||||
|
|
||||||
|
void intelInitPixelFuncs( struct dd_function_table *functions );
|
||||||
|
|
||||||
|
GLboolean intel_check_color_per_fragment_ops( const GLcontext *ctx );
|
||||||
|
|
||||||
|
GLboolean intel_clip_to_framebuffer( GLcontext *ctx,
|
||||||
|
const GLframebuffer *buffer,
|
||||||
|
GLint *x, GLint *y,
|
||||||
|
GLsizei *width, GLsizei *height );
|
||||||
|
|
||||||
|
void intelReadPixels( GLcontext *ctx,
|
||||||
|
GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *pack,
|
||||||
|
GLvoid *pixels );
|
||||||
|
|
||||||
|
void intelDrawPixels( GLcontext *ctx,
|
||||||
|
GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format,
|
||||||
|
GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
const GLvoid *pixels );
|
||||||
|
|
||||||
|
void intelCopyPixels( GLcontext *ctx,
|
||||||
|
GLint srcx, GLint srcy,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLint destx, GLint desty,
|
||||||
|
GLenum type );
|
||||||
|
|
||||||
|
#endif
|
||||||
196
src/mesa/drivers/dri/i915/intel_pixel_copy.c
Normal file
196
src/mesa/drivers/dri/i915/intel_pixel_copy.c
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "glheader.h"
|
||||||
|
#include "enums.h"
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
#include "intel_screen.h"
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_ioctl.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_pixel.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean do_texture_copypixels( GLcontext *ctx,
|
||||||
|
GLint srcx, GLint srcy,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLint dstx, GLint dsty,
|
||||||
|
GLenum type )
|
||||||
|
{
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
|
||||||
|
*/
|
||||||
|
static GLboolean do_blit_copypixels( GLcontext *ctx,
|
||||||
|
GLint srcx, GLint srcy,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLint dstx, GLint dsty,
|
||||||
|
GLenum type )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
struct intel_region *dst = intel_drawbuf_region( intel );
|
||||||
|
struct intel_region *src = NULL;
|
||||||
|
|
||||||
|
/* Copypixels can be more than a straight copy. Ensure all the
|
||||||
|
* extra operations are disabled:
|
||||||
|
*/
|
||||||
|
if (!intel_check_color_per_fragment_ops(ctx) ||
|
||||||
|
ctx->Pixel.ZoomX != 1.0F ||
|
||||||
|
ctx->Pixel.ZoomY != 1.0F)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case GL_COLOR:
|
||||||
|
src = intel_readbuf_region( intel );
|
||||||
|
break;
|
||||||
|
case GL_DEPTH:
|
||||||
|
/* Don't think this is really possible execpt at 16bpp, when we have no stencil.
|
||||||
|
*/
|
||||||
|
if (intel->intelScreen->cpp == 2)
|
||||||
|
src = intel->depth_region;
|
||||||
|
break;
|
||||||
|
case GL_STENCIL:
|
||||||
|
/* Don't think this is really possible.
|
||||||
|
*/
|
||||||
|
break;
|
||||||
|
case GL_DEPTH_STENCIL_EXT:
|
||||||
|
/* Does it matter whether it is stencil/depth or depth/stencil?
|
||||||
|
*/
|
||||||
|
src = intel->depth_region;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src || !dst)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
intelFlush( &intel->ctx );
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||||
|
GLint nbox = dPriv->numClipRects;
|
||||||
|
GLint delta_x = srcx - dstx;
|
||||||
|
GLint delta_y = srcy - dsty;
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &dstx, &dsty, &width, &height))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Update source for clipped dest. Need to also clip the source rect.
|
||||||
|
*/
|
||||||
|
srcx = dstx + delta_x;
|
||||||
|
srcy = dsty + delta_y;
|
||||||
|
|
||||||
|
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &srcx, &srcy, &width, &height))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Update dest for clipped source:
|
||||||
|
*/
|
||||||
|
dstx = srcx - delta_x;
|
||||||
|
dsty = srcy - delta_y;
|
||||||
|
|
||||||
|
|
||||||
|
srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */
|
||||||
|
dsty = dPriv->h - dsty - height; /* convert from gl to hardware coords */
|
||||||
|
srcx += dPriv->x;
|
||||||
|
dstx += dPriv->x;
|
||||||
|
srcy += dPriv->y;
|
||||||
|
dsty += dPriv->y;
|
||||||
|
|
||||||
|
|
||||||
|
/* Could do slightly more clipping: Eg, take the intersection of
|
||||||
|
* the existing set of cliprects and those cliprects translated
|
||||||
|
* by delta_x, delta_y:
|
||||||
|
*
|
||||||
|
* This code will not overwrite other windows, but will
|
||||||
|
* introduce garbage when copying from obscured window regions.
|
||||||
|
*/
|
||||||
|
for (i = 0 ; i < nbox ; i++ )
|
||||||
|
{
|
||||||
|
GLint bx = box[i].x1;
|
||||||
|
GLint by = box[i].y1;
|
||||||
|
GLint bw = box[i].x2 - bx;
|
||||||
|
GLint bh = box[i].y2 - by;
|
||||||
|
|
||||||
|
if (bx < dstx) bw -= dstx - bx, bx = dstx;
|
||||||
|
if (by < dsty) bh -= dsty - by, by = dsty;
|
||||||
|
if (bx + bw > dstx + width) bw = dstx + width - bx;
|
||||||
|
if (by + bh > dsty + height) bh = dsty + height - by;
|
||||||
|
if (bw <= 0) continue;
|
||||||
|
if (bh <= 0) continue;
|
||||||
|
|
||||||
|
intelEmitCopyBlit( intel,
|
||||||
|
dst->cpp,
|
||||||
|
src->pitch, src->buffer, 0,
|
||||||
|
dst->pitch, dst->buffer, 0,
|
||||||
|
bx + delta_x, by - delta_y, /* srcx, srcy */
|
||||||
|
bx, by, /* dstx, dsty */
|
||||||
|
bw, bh );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
intel_batchbuffer_flush( intel->batch );
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelCopyPixels( GLcontext *ctx,
|
||||||
|
GLint srcx, GLint srcy,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLint destx, GLint desty,
|
||||||
|
GLenum type )
|
||||||
|
{
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (do_blit_copypixels( ctx, srcx, srcy, width, height, destx, desty, type))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (do_texture_copypixels( ctx, srcx, srcy, width, height, destx, desty, type))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_mesa_printf("fallback to _swrast_CopyPixels\n");
|
||||||
|
_swrast_CopyPixels( ctx, srcx, srcy, width, height, destx, desty, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
242
src/mesa/drivers/dri/i915/intel_pixel_draw.c
Normal file
242
src/mesa/drivers/dri/i915/intel_pixel_draw.c
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "glheader.h"
|
||||||
|
#include "enums.h"
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
#include "intel_screen.h"
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_ioctl.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_pixel.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean do_texture_draw_pixels( struct intel_context *intel,
|
||||||
|
GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
const GLvoid *pixels )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
GLint pitch = unpack->RowLength ? unpack->RowLength : width;
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
int textureFormat;
|
||||||
|
GLenum glTextureFormat;
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
|
||||||
|
if ( ctx->_ImageTransferState ||
|
||||||
|
unpack->SwapBytes ||
|
||||||
|
unpack->LsbFirst ||
|
||||||
|
ctx->Texture._EnabledUnits ||
|
||||||
|
ctx->FragmentProgram._Enabled) {
|
||||||
|
fprintf(stderr, "%s: cannot use texture path\n", __FUNCTION__);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures();
|
||||||
|
glTextureImage2D();
|
||||||
|
glBindTexture();
|
||||||
|
glEnable(GL_TEXTURE_RECTANGLE_NV);
|
||||||
|
|
||||||
|
glDisable(GL_POLYGON_STIPPLE);
|
||||||
|
glDisable(GL_CULL);
|
||||||
|
|
||||||
|
_mesa_install_vp_passthrough(ctx);
|
||||||
|
_mesa_push_current(ctx);
|
||||||
|
|
||||||
|
if (intel->Fallback)
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex3f();
|
||||||
|
glTexCoord2f();
|
||||||
|
glVertex3f();
|
||||||
|
glTexCoord2f();
|
||||||
|
glVertex3f();
|
||||||
|
glTexCoord2f();
|
||||||
|
glVertex3f();
|
||||||
|
glTexCoord2f();
|
||||||
|
glEnd();
|
||||||
|
glFinish();
|
||||||
|
|
||||||
|
ASSIGN_4V(ctx->Current.Atrrib[VERT_ATTRIB_TEX0], tex0);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
glDisable(GL_TEXTURE_RECTANGLE_NV);
|
||||||
|
glDeleteTextures();
|
||||||
|
glBindTexture(old);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Pros:
|
||||||
|
* - no waiting for idle before updating framebuffer.
|
||||||
|
*
|
||||||
|
* Cons:
|
||||||
|
* - if upload is by memcpy, this may actually be slower than fallback path.
|
||||||
|
* - uploads the whole image even if destination is clipped
|
||||||
|
*
|
||||||
|
* Need to benchmark.
|
||||||
|
*/
|
||||||
|
static GLboolean do_blit_draw_pixels( struct intel_context *intel,
|
||||||
|
GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
const GLvoid *pixels )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct intel_region *dest = intel_drawbuf_region(intel);
|
||||||
|
struct intel_region *src = NULL;
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (!src || !dest)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
if (!intel_check_blit_format(dest, src))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
if (!intel_check_blit_fragment_ops(ctx))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
if (ctx->Pixel.ZoomX != 1.0F)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
if (ctx->Pixel.ZoomY == -1.0F)
|
||||||
|
y -= height;
|
||||||
|
else if (ctx->Pixel.ZoomY == 1.0F) {
|
||||||
|
src_pitch = -src_pitch;
|
||||||
|
src_y += height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
if (unpack->BufferObj->Name) {
|
||||||
|
src = intel_bufferobj_unpack_region(intel, unpack,
|
||||||
|
width, height,
|
||||||
|
format, type,
|
||||||
|
unpack->BufferObj);
|
||||||
|
src_offset = (unsigned long)pixels;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
src = intel_client_unpack_region(intel, unpack,
|
||||||
|
width, height,
|
||||||
|
format, type, pixels);
|
||||||
|
src_offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
intelFlush( &intel->ctx );
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
int nbox = dPriv->numClipRects;
|
||||||
|
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||||
|
drm_clip_rect_t rect;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
y = dPriv->h - y - height; /* convert from gl to hardware coords */
|
||||||
|
x += dPriv->x;
|
||||||
|
y += dPriv->y;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0 ; i < nbox ; i++ )
|
||||||
|
{
|
||||||
|
if (!intel_intersect_cliprects(rect, db_rect, &box[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
intelEmitCopyBlit( intel,
|
||||||
|
intel->intelScreen->cpp,
|
||||||
|
src->pitch, src->buffer, src_offset,
|
||||||
|
dst->pitch, dst->buffer, 0,
|
||||||
|
rect->x1 - x,
|
||||||
|
rect->y1 - y,
|
||||||
|
rect->x1,
|
||||||
|
rect->y1,
|
||||||
|
rect->x2 - rect->x1,
|
||||||
|
rect->y2 - rect->y1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_release_unpack_region( intel, src );
|
||||||
|
fence = intel_batchbuffer_flush( intel->batch );
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
|
||||||
|
bmWaitFence(intel->bm, fence);
|
||||||
|
intel_region_release(intel, &src);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelDrawPixels( GLcontext *ctx,
|
||||||
|
GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format,
|
||||||
|
GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
const GLvoid *pixels )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (do_texture_draw_pixels( intel, x, y, width, height, format, type,
|
||||||
|
unpack, pixels ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (do_blit_draw_pixels( intel, x, y, width, height, format, type,
|
||||||
|
unpack, pixels ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_swrast_DrawPixels( ctx, x, y, width, height, format, type,
|
||||||
|
unpack, pixels );
|
||||||
|
}
|
||||||
|
|
||||||
249
src/mesa/drivers/dri/i915/intel_pixel_read.c
Normal file
249
src/mesa/drivers/dri/i915/intel_pixel_read.c
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "glheader.h"
|
||||||
|
#include "enums.h"
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
#include "intel_screen.h"
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_ioctl.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_pixel.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean
|
||||||
|
do_texture_readpixels( GLcontext *ctx,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *pack,
|
||||||
|
struct intel_region *dest_region )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
intelScreenPrivate *screen = intel->intelScreen;
|
||||||
|
GLint pitch = pack->RowLength ? pack->RowLength : width;
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
int textureFormat;
|
||||||
|
GLenum glTextureFormat;
|
||||||
|
int destFormat, depthFormat, destPitch;
|
||||||
|
drm_clip_rect_t tmp;
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
|
||||||
|
if ( ctx->_ImageTransferState ||
|
||||||
|
pack->SwapBytes ||
|
||||||
|
pack->LsbFirst ||
|
||||||
|
!pack->Invert) {
|
||||||
|
fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
intel->vtbl.meta_texrect_source(intel, intel_readbuf_region(intel));
|
||||||
|
|
||||||
|
if (!intel->vtbl.meta_render_dest(intel,
|
||||||
|
dest_region,
|
||||||
|
type, format))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s: couldn't set dest %s/%s\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
_mesa_lookup_enum_by_nr(type),
|
||||||
|
_mesa_lookup_enum_by_nr(format));
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
intel->vtbl.install_meta_state(intel);
|
||||||
|
intel->vtbl.meta_no_depth_stencil_write(intel);
|
||||||
|
|
||||||
|
if (!driClipRectToFramebuffer(ctx->ReadBuffer, &x, &y, &width, &height)) {
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
SET_STATE(i830, state);
|
||||||
|
fprintf(stderr, "%s: cliprect failed\n", __FUNCTION__);
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
y = dPriv->h - y - height;
|
||||||
|
x += dPriv->x;
|
||||||
|
y += dPriv->y;
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the frontbuffer up as a large rectangular texture.
|
||||||
|
*/
|
||||||
|
intel->vtbl.meta_tex_rect_source( intel,
|
||||||
|
src_region,
|
||||||
|
textureFormat );
|
||||||
|
|
||||||
|
|
||||||
|
intel->vtbl.meta_texture_blend_replace( i830, glTextureFormat );
|
||||||
|
|
||||||
|
|
||||||
|
/* Set the 3d engine to draw into the destination region:
|
||||||
|
*/
|
||||||
|
|
||||||
|
intel->vtbl.meta_draw_region(intel, dest_region);
|
||||||
|
intel->vtbl.meta_draw_format(intel, destFormat, depthFormat ); /* ?? */
|
||||||
|
|
||||||
|
|
||||||
|
/* Draw a single quad, no cliprects:
|
||||||
|
*/
|
||||||
|
intel->vtbl.meta_disable_cliprects(intel);
|
||||||
|
|
||||||
|
intel->vtbl.draw_quad(intel,
|
||||||
|
0, width, 0, height,
|
||||||
|
0x00ff00ff,
|
||||||
|
x, x+width,
|
||||||
|
y, y+height );
|
||||||
|
|
||||||
|
intel->vtbl.leave_meta_state(intel);
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
|
||||||
|
intel_region_wait_fence( ctx, dest_region ); /* required by GL */
|
||||||
|
return GL_TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean do_blit_readpixels( GLcontext *ctx,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *pack,
|
||||||
|
GLvoid *pixels )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
GLint pitch = pack->RowLength ? pack->RowLength : width;
|
||||||
|
struct intel_region *src = intel_readbuf_region(intel);
|
||||||
|
struct intel_client_region *dst = intel_client_pack_region(intel,
|
||||||
|
pack,
|
||||||
|
pixels);
|
||||||
|
|
||||||
|
if (ctx->_ImageTransferState ||
|
||||||
|
pack->SwapBytes ||
|
||||||
|
pack->LsbFirst) {
|
||||||
|
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need GL_PACK_INVERT_MESA to cope with upsidedown results from
|
||||||
|
* blitter:
|
||||||
|
*/
|
||||||
|
if (!pack->Invert) {
|
||||||
|
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!intel_check_blit_format(src, format, type))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
/* Although the blits go on the command buffer, need to do this and
|
||||||
|
* fire with lock held to guarentee cliprects are correct.
|
||||||
|
*/
|
||||||
|
intelFlush( &intel->ctx );
|
||||||
|
LOCK_HARDWARE( intel );
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
int nbox = dPriv->numClipRects;
|
||||||
|
drm_clip_rect_t *box = dPriv->pClipRects;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
y = dPriv->h - y - height;
|
||||||
|
x += dPriv->x;
|
||||||
|
y += dPriv->y;
|
||||||
|
|
||||||
|
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
|
||||||
|
src_pitch, pitch);
|
||||||
|
|
||||||
|
for (i = 0 ; i < nbox ; i++)
|
||||||
|
{
|
||||||
|
GLint bx = box[i].x1;
|
||||||
|
GLint by = box[i].y1;
|
||||||
|
GLint bw = box[i].x2 - bx;
|
||||||
|
GLint bh = box[i].y2 - by;
|
||||||
|
|
||||||
|
if (bx < x) bw -= x - bx, bx = x;
|
||||||
|
if (by < y) bh -= y - by, by = y;
|
||||||
|
if (bx + bw > x + width) bw = x + width - bx;
|
||||||
|
if (by + bh > y + height) bh = y + height - by;
|
||||||
|
if (bw <= 0) continue;
|
||||||
|
if (bh <= 0) continue;
|
||||||
|
|
||||||
|
intelEmitCopyBlit( intel,
|
||||||
|
src->cpp,
|
||||||
|
src->pitch, src->buffer, 0,
|
||||||
|
dst->pitch, dst->buffer, 0,
|
||||||
|
bx, by,
|
||||||
|
bx - x, by - y,
|
||||||
|
bw, bh );
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_batchbuffer_flush(intel->batch);
|
||||||
|
intel_client_region_release(intel, dst);
|
||||||
|
}
|
||||||
|
UNLOCK_HARDWARE( intel );
|
||||||
|
return GL_TRUE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
intelReadPixels( GLcontext *ctx,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const struct gl_pixelstore_attrib *pack,
|
||||||
|
GLvoid *pixels )
|
||||||
|
{
|
||||||
|
if (INTEL_DEBUG & DEBUG_PIXEL)
|
||||||
|
fprintf(stderr, "%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
intelFlush( ctx );
|
||||||
|
|
||||||
|
if (do_blit_readpixels(ctx, x, y, width, height, format, type, pack, pixels))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (do_texture_readpixels(ctx, x, y, width, height, format, type, pack, pixels))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, pixels);
|
||||||
|
}
|
||||||
|
|
||||||
269
src/mesa/drivers/dri/i915/intel_regions.c
Normal file
269
src/mesa/drivers/dri/i915/intel_regions.c
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
/* Provide additional functionality on top of bufmgr buffers:
|
||||||
|
* - 2d semantics and blit operations
|
||||||
|
* - refcounting of buffers for multiple images in a buffer.
|
||||||
|
* - refcounting of buffer mappings.
|
||||||
|
* - some logic for moving the buffers to the best memory pools for
|
||||||
|
* given operations.
|
||||||
|
*
|
||||||
|
* Most of this is to make it easier to implement the fixed-layout
|
||||||
|
* mipmap tree required by intel hardware in the face of GL's
|
||||||
|
* programming interface where each image can be specifed in random
|
||||||
|
* order and it isn't clear what layout the tree should have until the
|
||||||
|
* last moment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
/* XXX: Thread safety?
|
||||||
|
*/
|
||||||
|
GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *region)
|
||||||
|
{
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
if (!region->map_refcount++) {
|
||||||
|
region->map = bmMapBuffer(intel->bm, region->buffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return region->map;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_region_unmap(struct intel_context *intel,
|
||||||
|
struct intel_region *region)
|
||||||
|
{
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
if (!--region->map_refcount) {
|
||||||
|
bmUnmapBuffer(intel->bm, region->buffer);
|
||||||
|
region->map = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct intel_region *intel_region_alloc( struct intel_context *intel,
|
||||||
|
GLuint cpp,
|
||||||
|
GLuint pitch,
|
||||||
|
GLuint height )
|
||||||
|
{
|
||||||
|
struct intel_region *region = calloc(sizeof(*region), 1);
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
region->cpp = cpp;
|
||||||
|
region->pitch = pitch;
|
||||||
|
region->height = height; /* needed? */
|
||||||
|
region->refcount = 1;
|
||||||
|
|
||||||
|
bmGenBuffers(intel->bm, 1, ®ion->buffer);
|
||||||
|
bmBufferData(intel->bm, region->buffer, pitch * cpp * height, NULL, 0);
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_region_reference( struct intel_region **dst,
|
||||||
|
struct intel_region *src)
|
||||||
|
{
|
||||||
|
src->refcount++;
|
||||||
|
assert(*dst == NULL);
|
||||||
|
*dst = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
void intel_region_release( struct intel_context *intel,
|
||||||
|
struct intel_region **region )
|
||||||
|
{
|
||||||
|
if (!*region)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DBG("%s %d\n", __FUNCTION__, (*region)->refcount-1);
|
||||||
|
|
||||||
|
if (--(*region)->refcount == 0) {
|
||||||
|
assert((*region)->map_refcount == 0);
|
||||||
|
bmDeleteBuffers(intel->bm, 1, &(*region)->buffer);
|
||||||
|
free(*region);
|
||||||
|
}
|
||||||
|
*region = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct intel_region *intel_region_create_static( struct intel_context *intel,
|
||||||
|
GLuint mem_type,
|
||||||
|
GLuint offset,
|
||||||
|
void *virtual,
|
||||||
|
GLuint cpp,
|
||||||
|
GLuint pitch,
|
||||||
|
GLuint height )
|
||||||
|
{
|
||||||
|
struct intel_region *region = calloc(sizeof(*region), 1);
|
||||||
|
GLuint size = cpp * pitch * height;
|
||||||
|
GLint pool;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
region->cpp = cpp;
|
||||||
|
region->pitch = pitch;
|
||||||
|
region->height = height; /* needed? */
|
||||||
|
region->refcount = 1;
|
||||||
|
|
||||||
|
/* Recipe for creating a static buffer - create a static pool with
|
||||||
|
* the right offset and size, generate a buffer and use a special
|
||||||
|
* call to bind it to all of the memory in that pool.
|
||||||
|
*/
|
||||||
|
pool = bmInitPool(intel->bm, offset, virtual, size,
|
||||||
|
(BM_MEM_AGP |
|
||||||
|
BM_NO_UPLOAD |
|
||||||
|
BM_NO_EVICT |
|
||||||
|
BM_NO_MOVE));
|
||||||
|
if (pool < 0) {
|
||||||
|
_mesa_printf("bmInitPool failed for static region\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bmGenBuffers(intel->bm, 1, ®ion->buffer);
|
||||||
|
bmBufferStatic(intel->bm, region->buffer, size, pool);
|
||||||
|
|
||||||
|
return region;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void _mesa_copy_rect( GLubyte *dst,
|
||||||
|
GLuint cpp,
|
||||||
|
GLuint dst_pitch,
|
||||||
|
GLuint dst_x,
|
||||||
|
GLuint dst_y,
|
||||||
|
GLuint width,
|
||||||
|
GLuint height,
|
||||||
|
GLubyte *src,
|
||||||
|
GLuint src_pitch,
|
||||||
|
GLuint src_x,
|
||||||
|
GLuint src_y )
|
||||||
|
{
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
dst_pitch *= cpp;
|
||||||
|
src_pitch *= cpp;
|
||||||
|
dst += dst_x * cpp;
|
||||||
|
src += src_x * cpp;
|
||||||
|
dst += dst_y * dst_pitch;
|
||||||
|
src += src_y * dst_pitch;
|
||||||
|
width *= cpp;
|
||||||
|
|
||||||
|
if (width == dst_pitch &&
|
||||||
|
width == src_pitch)
|
||||||
|
memcpy(dst, src, height * width);
|
||||||
|
else {
|
||||||
|
for (i = 0; i < height; i++) {
|
||||||
|
memcpy(dst, src, width);
|
||||||
|
dst += dst_pitch;
|
||||||
|
src += src_pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Upload data to a rectangular sub-region. Lots of choices how to do this:
|
||||||
|
*
|
||||||
|
* - memcpy by span to current destination
|
||||||
|
* - upload data as new buffer and blit
|
||||||
|
*
|
||||||
|
* Currently always memcpy.
|
||||||
|
*/
|
||||||
|
void intel_region_data(struct intel_context *intel,
|
||||||
|
struct intel_region *dst,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLuint dstx, GLuint dsty,
|
||||||
|
void *src, GLuint src_pitch,
|
||||||
|
GLuint srcx, GLuint srcy,
|
||||||
|
GLuint width, GLuint height)
|
||||||
|
{
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
|
||||||
|
_mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
|
||||||
|
dst->cpp,
|
||||||
|
dst->pitch,
|
||||||
|
dstx, dsty,
|
||||||
|
width, height,
|
||||||
|
src,
|
||||||
|
src_pitch,
|
||||||
|
srcx, srcy);
|
||||||
|
|
||||||
|
intel_region_unmap(intel, dst);
|
||||||
|
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy rectangular sub-regions. Need better logic about when to
|
||||||
|
* push buffers into AGP - will currently do so whenever possible.
|
||||||
|
*/
|
||||||
|
void intel_region_copy( struct intel_context *intel,
|
||||||
|
struct intel_region *dst,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLuint dstx, GLuint dsty,
|
||||||
|
struct intel_region *src,
|
||||||
|
GLuint src_offset,
|
||||||
|
GLuint srcx, GLuint srcy,
|
||||||
|
GLuint width, GLuint height )
|
||||||
|
{
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
assert(src->cpp == dst->cpp);
|
||||||
|
|
||||||
|
intelEmitCopyBlit(intel,
|
||||||
|
dst->cpp,
|
||||||
|
src->pitch, src->buffer, src_offset,
|
||||||
|
dst->pitch, dst->buffer, dst_offset,
|
||||||
|
srcx, srcy,
|
||||||
|
dstx, dsty,
|
||||||
|
width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill a rectangular sub-region. Need better logic about when to
|
||||||
|
* push buffers into AGP - will currently do so whenever possible.
|
||||||
|
*/
|
||||||
|
void intel_region_fill( struct intel_context *intel,
|
||||||
|
struct intel_region *dst,
|
||||||
|
GLuint dst_offset,
|
||||||
|
GLuint dstx, GLuint dsty,
|
||||||
|
GLuint width, GLuint height,
|
||||||
|
GLuint color )
|
||||||
|
{
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
intelEmitFillBlit(intel,
|
||||||
|
dst->cpp,
|
||||||
|
dst->pitch, dst->buffer, dst_offset,
|
||||||
|
dstx, dsty,
|
||||||
|
width, height,
|
||||||
|
color );
|
||||||
|
}
|
||||||
|
|
||||||
115
src/mesa/drivers/dri/i915/intel_regions.h
Normal file
115
src/mesa/drivers/dri/i915/intel_regions.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef INTEL_REGIONS_H
|
||||||
|
#define INTEL_REGIONS_H
|
||||||
|
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "bufmgr.h" /* for DBG! */
|
||||||
|
struct intel_context;
|
||||||
|
|
||||||
|
/* A layer on top of the bufmgr buffers that adds a few useful things:
|
||||||
|
*
|
||||||
|
* - Refcounting for local buffer references.
|
||||||
|
* - Refcounting for buffer maps
|
||||||
|
* - Buffer dimensions - pitch and height.
|
||||||
|
* - Blitter commands for copying 2D regions between buffers.
|
||||||
|
*/
|
||||||
|
struct intel_region {
|
||||||
|
GLuint buffer;
|
||||||
|
GLuint refcount;
|
||||||
|
GLuint cpp;
|
||||||
|
GLuint pitch;
|
||||||
|
GLuint height;
|
||||||
|
GLubyte *map;
|
||||||
|
GLuint map_refcount;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Allocate a refcounted region. Pointers to regions should only be
|
||||||
|
* copied by calling intel_reference_region().
|
||||||
|
*/
|
||||||
|
struct intel_region *intel_region_alloc( struct intel_context *intel,
|
||||||
|
GLuint cpp,
|
||||||
|
GLuint pitch,
|
||||||
|
GLuint height );
|
||||||
|
|
||||||
|
void intel_region_reference( struct intel_region **dst,
|
||||||
|
struct intel_region *src );
|
||||||
|
|
||||||
|
void intel_region_release(struct intel_context *intel,
|
||||||
|
struct intel_region **ib );
|
||||||
|
|
||||||
|
|
||||||
|
struct intel_region *intel_region_create_static( struct intel_context *intel,
|
||||||
|
GLuint mem_type,
|
||||||
|
GLuint offset,
|
||||||
|
void *virtual,
|
||||||
|
GLuint cpp,
|
||||||
|
GLuint pitch,
|
||||||
|
GLuint height );
|
||||||
|
|
||||||
|
/* Map/unmap regions. This is refcounted also:
|
||||||
|
*/
|
||||||
|
GLubyte *intel_region_map(struct intel_context *intel,
|
||||||
|
struct intel_region *ib);
|
||||||
|
|
||||||
|
void intel_region_unmap(struct intel_context *intel,
|
||||||
|
struct intel_region *ib);
|
||||||
|
|
||||||
|
|
||||||
|
/* Upload data to a rectangular sub-region
|
||||||
|
*/
|
||||||
|
void intel_region_data(struct intel_context *intel,
|
||||||
|
struct intel_region *dest,
|
||||||
|
GLuint dest_offset,
|
||||||
|
GLuint destx, GLuint desty,
|
||||||
|
void *src, GLuint src_stride,
|
||||||
|
GLuint srcx, GLuint srcy,
|
||||||
|
GLuint width, GLuint height);
|
||||||
|
|
||||||
|
/* Copy rectangular sub-regions
|
||||||
|
*/
|
||||||
|
void intel_region_copy( struct intel_context *intel,
|
||||||
|
struct intel_region *dest,
|
||||||
|
GLuint dest_offset,
|
||||||
|
GLuint destx, GLuint desty,
|
||||||
|
struct intel_region *src,
|
||||||
|
GLuint src_offset,
|
||||||
|
GLuint srcx, GLuint srcy,
|
||||||
|
GLuint width, GLuint height );
|
||||||
|
|
||||||
|
/* Fill a rectangular sub-region
|
||||||
|
*/
|
||||||
|
void intel_region_fill( struct intel_context *intel,
|
||||||
|
struct intel_region *dest,
|
||||||
|
GLuint dest_offset,
|
||||||
|
GLuint destx, GLuint desty,
|
||||||
|
GLuint width, GLuint height,
|
||||||
|
GLuint color );
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -106,7 +106,7 @@ static const int scale_prim[GL_POLYGON+1] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void intelDmaPrimitive( intelContextPtr intel, GLenum prim )
|
static void intelDmaPrimitive( struct intel_context *intel, GLenum prim )
|
||||||
{
|
{
|
||||||
if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
|
if (0) fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
|
||||||
INTEL_FIREVERTICES(intel);
|
INTEL_FIREVERTICES(intel);
|
||||||
@@ -115,7 +115,7 @@ static void intelDmaPrimitive( intelContextPtr intel, GLenum prim )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define LOCAL_VARS intelContextPtr intel = INTEL_CONTEXT(ctx)
|
#define LOCAL_VARS struct intel_context *intel = intel_context(ctx)
|
||||||
#define INIT( prim ) \
|
#define INIT( prim ) \
|
||||||
do { \
|
do { \
|
||||||
intelDmaPrimitive( intel, prim ); \
|
intelDmaPrimitive( intel, prim ); \
|
||||||
@@ -142,7 +142,7 @@ do { \
|
|||||||
|
|
||||||
/* Heuristic to choose between the two render paths:
|
/* Heuristic to choose between the two render paths:
|
||||||
*/
|
*/
|
||||||
static GLboolean choose_render( intelContextPtr intel,
|
static GLboolean choose_render( struct intel_context *intel,
|
||||||
struct vertex_buffer *VB )
|
struct vertex_buffer *VB )
|
||||||
{
|
{
|
||||||
int vertsz = intel->vertex_size;
|
int vertsz = intel->vertex_size;
|
||||||
@@ -194,11 +194,15 @@ static GLboolean choose_render( intelContextPtr intel,
|
|||||||
static GLboolean intel_run_render( GLcontext *ctx,
|
static GLboolean intel_run_render( GLcontext *ctx,
|
||||||
struct tnl_pipeline_stage *stage )
|
struct tnl_pipeline_stage *stage )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct vertex_buffer *VB = &tnl->vb;
|
struct vertex_buffer *VB = &tnl->vb;
|
||||||
GLuint i;
|
GLuint i;
|
||||||
|
|
||||||
|
/* disabled
|
||||||
|
*/
|
||||||
|
return GL_TRUE;
|
||||||
|
|
||||||
/* Don't handle clipping or indexed vertices.
|
/* Don't handle clipping or indexed vertices.
|
||||||
*/
|
*/
|
||||||
if (intel->RenderIndex != 0 ||
|
if (intel->RenderIndex != 0 ||
|
||||||
|
|||||||
@@ -104,14 +104,14 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
|
|||||||
intelScreen->cpp = gDRIPriv->cpp;
|
intelScreen->cpp = gDRIPriv->cpp;
|
||||||
|
|
||||||
switch (gDRIPriv->bitsPerPixel) {
|
switch (gDRIPriv->bitsPerPixel) {
|
||||||
case 15: intelScreen->fbFormat = DV_PF_555; break;
|
|
||||||
case 16: intelScreen->fbFormat = DV_PF_565; break;
|
case 16: intelScreen->fbFormat = DV_PF_565; break;
|
||||||
case 32: intelScreen->fbFormat = DV_PF_8888; break;
|
case 32: intelScreen->fbFormat = DV_PF_8888; break;
|
||||||
|
default: exit(1); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
intelScreen->front.pitch = gDRIPriv->fbStride;
|
intelScreen->front.pitch = gDRIPriv->fbStride;
|
||||||
intelScreen->front.offset = gDRIPriv->fbOffset;
|
intelScreen->front.offset = gDRIPriv->fbOffset;
|
||||||
intelScreen->front.map = sPriv->pFB;
|
intelScreen->front.map = (char *)sPriv->pFB;
|
||||||
|
|
||||||
intelScreen->back.offset = gDRIPriv->backOffset;
|
intelScreen->back.offset = gDRIPriv->backOffset;
|
||||||
intelScreen->back.pitch = gDRIPriv->backPitch;
|
intelScreen->back.pitch = gDRIPriv->backPitch;
|
||||||
@@ -166,7 +166,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
|
|||||||
|
|
||||||
intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
|
intelScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
|
||||||
|
|
||||||
if (0) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
|
if (1) intelPrintDRIInfo(intelScreen, sPriv, gDRIPriv);
|
||||||
|
|
||||||
intelScreen->drmMinor = sPriv->drmMinor;
|
intelScreen->drmMinor = sPriv->drmMinor;
|
||||||
|
|
||||||
@@ -202,13 +202,8 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
|
|||||||
|
|
||||||
if (glx_enable_extension != NULL) {
|
if (glx_enable_extension != NULL) {
|
||||||
(*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
|
(*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
|
||||||
(*glx_enable_extension)( psc, "GLX_MESA_allocate_memory" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sPriv->psc->allocateMemory = (void *) intelAllocateMemoryMESA;
|
|
||||||
sPriv->psc->freeMemory = (void *) intelFreeMemoryMESA;
|
|
||||||
sPriv->psc->memoryOffset = (void *) intelGetMemoryOffsetMESA;
|
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,12 +333,16 @@ static GLboolean intelCreateContext( const __GLcontextModes *mesaVis,
|
|||||||
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
|
intelScreenPrivate *intelScreen = (intelScreenPrivate *)sPriv->private;
|
||||||
|
|
||||||
switch (intelScreen->deviceID) {
|
switch (intelScreen->deviceID) {
|
||||||
|
#if 0
|
||||||
|
/* Don't deal with i830 until texture work complete:
|
||||||
|
*/
|
||||||
case PCI_CHIP_845_G:
|
case PCI_CHIP_845_G:
|
||||||
case PCI_CHIP_I830_M:
|
case PCI_CHIP_I830_M:
|
||||||
case PCI_CHIP_I855_GM:
|
case PCI_CHIP_I855_GM:
|
||||||
case PCI_CHIP_I865_G:
|
case PCI_CHIP_I865_G:
|
||||||
return i830CreateContext( mesaVis, driContextPriv,
|
return i830CreateContext( mesaVis, driContextPriv,
|
||||||
sharedContextPrivate );
|
sharedContextPrivate );
|
||||||
|
#endif
|
||||||
|
|
||||||
case PCI_CHIP_I915_G:
|
case PCI_CHIP_I915_G:
|
||||||
case PCI_CHIP_I915_GM:
|
case PCI_CHIP_I915_GM:
|
||||||
|
|||||||
@@ -32,6 +32,9 @@
|
|||||||
#include "dri_util.h"
|
#include "dri_util.h"
|
||||||
#include "xmlconfig.h"
|
#include "xmlconfig.h"
|
||||||
|
|
||||||
|
/* XXX: change name or eliminate to avoid conflict with "struct
|
||||||
|
* intel_region"!!!
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
drm_handle_t handle;
|
drm_handle_t handle;
|
||||||
drmSize size; /* region size in bytes */
|
drmSize size; /* region size in bytes */
|
||||||
|
|||||||
@@ -31,16 +31,18 @@
|
|||||||
#include "colormac.h"
|
#include "colormac.h"
|
||||||
|
|
||||||
#include "intel_screen.h"
|
#include "intel_screen.h"
|
||||||
|
|
||||||
#include "intel_span.h"
|
#include "intel_span.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
#include "intel_ioctl.h"
|
#include "intel_ioctl.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
|
||||||
#include "swrast/swrast.h"
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
#undef DBG
|
||||||
#define DBG 0
|
#define DBG 0
|
||||||
|
|
||||||
#define LOCAL_VARS \
|
#define LOCAL_VARS \
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx); \
|
struct intel_context *intel = intel_context(ctx); \
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
|
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
|
||||||
driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
||||||
GLuint pitch = drb->pitch * drb->cpp; \
|
GLuint pitch = drb->pitch * drb->cpp; \
|
||||||
@@ -52,7 +54,7 @@
|
|||||||
(void) buf; (void) p
|
(void) buf; (void) p
|
||||||
|
|
||||||
#define LOCAL_DEPTH_VARS \
|
#define LOCAL_DEPTH_VARS \
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx); \
|
struct intel_context *intel = intel_context(ctx); \
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
|
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
|
||||||
driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
||||||
GLuint pitch = drb->pitch * drb->cpp; \
|
GLuint pitch = drb->pitch * drb->cpp; \
|
||||||
@@ -93,27 +95,6 @@ do { \
|
|||||||
#define TAG(x) intel##x##_565
|
#define TAG(x) intel##x##_565
|
||||||
#include "spantmp.h"
|
#include "spantmp.h"
|
||||||
|
|
||||||
/* 15 bit, 555 rgb color spanline and pixel functions
|
|
||||||
*/
|
|
||||||
#define WRITE_RGBA( _x, _y, r, g, b, a ) \
|
|
||||||
*(GLushort *)(buf + _x*2 + _y*pitch) = (((r & 0xf8) << 7) | \
|
|
||||||
((g & 0xf8) << 3) | \
|
|
||||||
((b & 0xf8) >> 3))
|
|
||||||
|
|
||||||
#define WRITE_PIXEL( _x, _y, p ) \
|
|
||||||
*(GLushort *)(buf + _x*2 + _y*pitch) = p
|
|
||||||
|
|
||||||
#define READ_RGBA( rgba, _x, _y ) \
|
|
||||||
do { \
|
|
||||||
GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
|
|
||||||
rgba[0] = (p >> 7) & 0xf8; \
|
|
||||||
rgba[1] = (p >> 3) & 0xf8; \
|
|
||||||
rgba[2] = (p << 3) & 0xf8; \
|
|
||||||
rgba[3] = 255; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define TAG(x) intel##x##_555
|
|
||||||
#include "spantmp.h"
|
|
||||||
|
|
||||||
/* 16 bit depthbuffer functions.
|
/* 16 bit depthbuffer functions.
|
||||||
*/
|
*/
|
||||||
@@ -130,7 +111,7 @@ do { \
|
|||||||
|
|
||||||
#undef LOCAL_VARS
|
#undef LOCAL_VARS
|
||||||
#define LOCAL_VARS \
|
#define LOCAL_VARS \
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx); \
|
struct intel_context *intel = intel_context(ctx); \
|
||||||
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
|
__DRIdrawablePrivate *dPriv = intel->driDrawable; \
|
||||||
driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
driRenderbuffer *drb = (driRenderbuffer *) rb; \
|
||||||
GLuint pitch = drb->pitch * drb->cpp; \
|
GLuint pitch = drb->pitch * drb->cpp; \
|
||||||
@@ -204,17 +185,47 @@ do { \
|
|||||||
*/
|
*/
|
||||||
void intelSpanRenderStart( GLcontext *ctx )
|
void intelSpanRenderStart( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
intelFlush(&intel->ctx);
|
intelFlush(&intel->ctx);
|
||||||
LOCK_HARDWARE(intel);
|
LOCK_HARDWARE(intel);
|
||||||
intelWaitForIdle(intel);
|
|
||||||
|
/* Just map the framebuffer and all textures. Bufmgr code will
|
||||||
|
* take care of waiting on the necessary fences:
|
||||||
|
*/
|
||||||
|
intel_region_map(intel, intel->front_region);
|
||||||
|
intel_region_map(intel, intel->back_region);
|
||||||
|
intel_region_map(intel, intel->depth_region);
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
|
||||||
|
if (ctx->Texture.Unit[i]._ReallyEnabled) {
|
||||||
|
struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
|
||||||
|
intel_tex_map_images(intel, intel_texture_object(texObj));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void intelSpanRenderFinish( GLcontext *ctx )
|
void intelSpanRenderFinish( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
_swrast_flush( ctx );
|
_swrast_flush( ctx );
|
||||||
|
|
||||||
|
/* Now unmap the framebuffer:
|
||||||
|
*/
|
||||||
|
intel_region_unmap(intel, intel->front_region);
|
||||||
|
intel_region_unmap(intel, intel->back_region);
|
||||||
|
intel_region_unmap(intel, intel->depth_region);
|
||||||
|
|
||||||
|
for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
|
||||||
|
if (ctx->Texture.Unit[i]._ReallyEnabled) {
|
||||||
|
struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
|
||||||
|
intel_tex_unmap_images(intel, intel_texture_object(texObj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UNLOCK_HARDWARE( intel );
|
UNLOCK_HARDWARE( intel );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,10 +244,7 @@ void
|
|||||||
intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
|
intelSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
|
||||||
{
|
{
|
||||||
if (drb->Base.InternalFormat == GL_RGBA) {
|
if (drb->Base.InternalFormat == GL_RGBA) {
|
||||||
if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
|
if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
|
||||||
intelInitPointers_555(&drb->Base);
|
|
||||||
}
|
|
||||||
else if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
|
|
||||||
intelInitPointers_565(&drb->Base);
|
intelInitPointers_565(&drb->Base);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -30,10 +30,12 @@
|
|||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
#include "colormac.h"
|
||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
|
|
||||||
#include "intel_screen.h"
|
#include "intel_screen.h"
|
||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
#include "swrast/swrast.h"
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
int intel_translate_compare_func( GLenum func )
|
int intel_translate_compare_func( GLenum func )
|
||||||
@@ -164,70 +166,26 @@ int intel_translate_logic_op( GLenum opcode )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intelDrawBuffer(GLcontext *ctx, GLenum mode )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
|
||||||
intelScreenPrivate *screen = intel->intelScreen;
|
|
||||||
int front = 0;
|
|
||||||
|
|
||||||
if (!ctx->DrawBuffer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
|
|
||||||
case BUFFER_BIT_FRONT_LEFT:
|
|
||||||
front = 1;
|
|
||||||
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
|
|
||||||
break;
|
|
||||||
case BUFFER_BIT_BACK_LEFT:
|
|
||||||
front = 0;
|
|
||||||
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
FALLBACK( intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( intel->sarea->pf_current_page == 1 )
|
|
||||||
front ^= 1;
|
|
||||||
|
|
||||||
intelSetFrontClipRects( intel );
|
|
||||||
|
|
||||||
if (front) {
|
|
||||||
intel->drawOffset = screen->front.offset;
|
|
||||||
} else {
|
|
||||||
intel->drawOffset = screen->back.offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
intel->vtbl.set_draw_offset( intel, intel->drawOffset );
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intelReadBuffer( GLcontext *ctx, GLenum mode )
|
|
||||||
{
|
|
||||||
/* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void intelClearColor(GLcontext *ctx, const GLfloat color[4])
|
static void intelClearColor(GLcontext *ctx, const GLfloat color[4])
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
intelScreenPrivate *screen = intel->intelScreen;
|
intelScreenPrivate *screen = intel->intelScreen;
|
||||||
|
GLubyte clear_chan[4];
|
||||||
|
|
||||||
CLAMPED_FLOAT_TO_UBYTE(intel->clear_red, color[0]);
|
UNCLAMPED_FLOAT_TO_RGBA_CHAN(clear_chan, color);
|
||||||
CLAMPED_FLOAT_TO_UBYTE(intel->clear_green, color[1]);
|
|
||||||
CLAMPED_FLOAT_TO_UBYTE(intel->clear_blue, color[2]);
|
|
||||||
CLAMPED_FLOAT_TO_UBYTE(intel->clear_alpha, color[3]);
|
|
||||||
|
|
||||||
intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat,
|
intel->ClearColor = INTEL_PACKCOLOR(screen->fbFormat,
|
||||||
intel->clear_red,
|
clear_chan[0],
|
||||||
intel->clear_green,
|
clear_chan[1],
|
||||||
intel->clear_blue,
|
clear_chan[2],
|
||||||
intel->clear_alpha);
|
clear_chan[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void intelCalcViewport( GLcontext *ctx )
|
static void intelCalcViewport( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
const GLfloat *v = ctx->Viewport._WindowMap.m;
|
||||||
GLfloat *m = intel->ViewportMatrix.m;
|
GLfloat *m = intel->ViewportMatrix.m;
|
||||||
GLint h = 0;
|
GLint h = 0;
|
||||||
@@ -263,18 +221,111 @@ static void intelDepthRange( GLcontext *ctx,
|
|||||||
*/
|
*/
|
||||||
static void intelRenderMode( GLcontext *ctx, GLenum mode )
|
static void intelRenderMode( GLcontext *ctx, GLenum mode )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
|
FALLBACK( intel, INTEL_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void intelInitStateFuncs( struct dd_function_table *functions )
|
void intelInitStateFuncs( struct dd_function_table *functions )
|
||||||
{
|
{
|
||||||
functions->DrawBuffer = intelDrawBuffer;
|
|
||||||
functions->ReadBuffer = intelReadBuffer;
|
|
||||||
functions->RenderMode = intelRenderMode;
|
functions->RenderMode = intelRenderMode;
|
||||||
functions->Viewport = intelViewport;
|
functions->Viewport = intelViewport;
|
||||||
functions->DepthRange = intelDepthRange;
|
functions->DepthRange = intelDepthRange;
|
||||||
functions->ClearColor = intelClearColor;
|
functions->ClearColor = intelClearColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelInitState( GLcontext *ctx )
|
||||||
|
{
|
||||||
|
/* Mesa should do this for us:
|
||||||
|
*/
|
||||||
|
ctx->Driver.AlphaFunc( ctx,
|
||||||
|
ctx->Color.AlphaFunc,
|
||||||
|
ctx->Color.AlphaRef);
|
||||||
|
|
||||||
|
ctx->Driver.BlendColor( ctx,
|
||||||
|
ctx->Color.BlendColor );
|
||||||
|
|
||||||
|
ctx->Driver.BlendEquationSeparate( ctx,
|
||||||
|
ctx->Color.BlendEquationRGB,
|
||||||
|
ctx->Color.BlendEquationA);
|
||||||
|
|
||||||
|
ctx->Driver.BlendFuncSeparate( ctx,
|
||||||
|
ctx->Color.BlendSrcRGB,
|
||||||
|
ctx->Color.BlendDstRGB,
|
||||||
|
ctx->Color.BlendSrcA,
|
||||||
|
ctx->Color.BlendDstA);
|
||||||
|
|
||||||
|
ctx->Driver.ColorMask( ctx,
|
||||||
|
ctx->Color.ColorMask[RCOMP],
|
||||||
|
ctx->Color.ColorMask[GCOMP],
|
||||||
|
ctx->Color.ColorMask[BCOMP],
|
||||||
|
ctx->Color.ColorMask[ACOMP]);
|
||||||
|
|
||||||
|
ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode );
|
||||||
|
ctx->Driver.DepthFunc( ctx, ctx->Depth.Func );
|
||||||
|
ctx->Driver.DepthMask( ctx, ctx->Depth.Mask );
|
||||||
|
|
||||||
|
ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag );
|
||||||
|
ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test );
|
||||||
|
ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag );
|
||||||
|
ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag );
|
||||||
|
ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag );
|
||||||
|
ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled );
|
||||||
|
ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE );
|
||||||
|
ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE );
|
||||||
|
ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE );
|
||||||
|
ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE );
|
||||||
|
ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE );
|
||||||
|
|
||||||
|
ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color );
|
||||||
|
ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 );
|
||||||
|
ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density );
|
||||||
|
ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start );
|
||||||
|
ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End );
|
||||||
|
|
||||||
|
ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace );
|
||||||
|
|
||||||
|
{
|
||||||
|
GLfloat f = (GLfloat)ctx->Light.Model.ColorControl;
|
||||||
|
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f );
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->Driver.LineWidth( ctx, ctx->Line.Width );
|
||||||
|
ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp );
|
||||||
|
ctx->Driver.PointSize( ctx, ctx->Point.Size );
|
||||||
|
ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple );
|
||||||
|
ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
|
||||||
|
ctx->Scissor.Width, ctx->Scissor.Height );
|
||||||
|
ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel );
|
||||||
|
ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT,
|
||||||
|
ctx->Stencil.Function[0],
|
||||||
|
ctx->Stencil.Ref[0],
|
||||||
|
ctx->Stencil.ValueMask[0] );
|
||||||
|
ctx->Driver.StencilFuncSeparate( ctx, GL_BACK,
|
||||||
|
ctx->Stencil.Function[1],
|
||||||
|
ctx->Stencil.Ref[1],
|
||||||
|
ctx->Stencil.ValueMask[1] );
|
||||||
|
ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] );
|
||||||
|
ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] );
|
||||||
|
ctx->Driver.StencilOpSeparate( ctx, GL_FRONT,
|
||||||
|
ctx->Stencil.FailFunc[0],
|
||||||
|
ctx->Stencil.ZFailFunc[0],
|
||||||
|
ctx->Stencil.ZPassFunc[0]);
|
||||||
|
ctx->Driver.StencilOpSeparate( ctx, GL_BACK,
|
||||||
|
ctx->Stencil.FailFunc[1],
|
||||||
|
ctx->Stencil.ZFailFunc[1],
|
||||||
|
ctx->Stencil.ZPassFunc[1]);
|
||||||
|
|
||||||
|
|
||||||
|
ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,830 +1,162 @@
|
|||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
|
||||||
* All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the
|
|
||||||
* "Software"), to deal in the Software without restriction, including
|
|
||||||
* without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
* distribute, sub license, and/or sell copies of the Software, and to
|
|
||||||
* permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
* the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice (including the
|
|
||||||
* next paragraph) shall be included in all copies or substantial portions
|
|
||||||
* of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
|
||||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
|
||||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
||||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
||||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#include "glheader.h"
|
|
||||||
#include "mtypes.h"
|
|
||||||
#include "imports.h"
|
|
||||||
#include "macros.h"
|
|
||||||
#include "simple_list.h"
|
|
||||||
#include "enums.h"
|
|
||||||
#include "image.h"
|
|
||||||
#include "texstore.h"
|
|
||||||
#include "texformat.h"
|
|
||||||
#include "teximage.h"
|
|
||||||
#include "texmem.h"
|
|
||||||
#include "texobj.h"
|
#include "texobj.h"
|
||||||
#include "swrast/swrast.h"
|
|
||||||
|
|
||||||
#include "mm.h"
|
|
||||||
|
|
||||||
#include "intel_screen.h"
|
|
||||||
#include "intel_batchbuffer.h"
|
|
||||||
#include "intel_context.h"
|
#include "intel_context.h"
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
#include "intel_tex.h"
|
#include "intel_tex.h"
|
||||||
#include "intel_ioctl.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean intelIsTextureResident(GLcontext *ctx,
|
||||||
static GLboolean
|
struct gl_texture_object *texObj)
|
||||||
intelValidateClientStorage( intelContextPtr intel, GLenum target,
|
|
||||||
GLint internalFormat,
|
|
||||||
GLint srcWidth, GLint srcHeight,
|
|
||||||
GLenum format, GLenum type, const void *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &intel->ctx;
|
#if 0
|
||||||
int texelBytes;
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
struct intel_texture_object *intelObj = intel_texture_object(texObj);
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "intformat %s format %s type %s\n",
|
return
|
||||||
_mesa_lookup_enum_by_nr( internalFormat ),
|
intelObj->mt &&
|
||||||
_mesa_lookup_enum_by_nr( format ),
|
intelObj->mt->region &&
|
||||||
_mesa_lookup_enum_by_nr( type ));
|
intel_is_region_resident(intel, intelObj->mt->region);
|
||||||
|
#endif
|
||||||
if (!ctx->Unpack.ClientStorage)
|
return 1;
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ctx->_ImageTransferState ||
|
|
||||||
texImage->IsCompressed ||
|
|
||||||
texObj->GenerateMipmap)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* This list is incomplete
|
|
||||||
*/
|
|
||||||
switch ( internalFormat ) {
|
|
||||||
case GL_RGBA:
|
|
||||||
if ( format == GL_BGRA && type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
|
|
||||||
texImage->TexFormat = &_mesa_texformat_argb8888;
|
|
||||||
texelBytes = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GL_RGB:
|
|
||||||
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
|
|
||||||
texImage->TexFormat = &_mesa_texformat_rgb565;
|
|
||||||
texelBytes = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GL_YCBCR_MESA:
|
|
||||||
if ( format == GL_YCBCR_MESA &&
|
|
||||||
type == GL_UNSIGNED_SHORT_8_8_REV_APPLE ) {
|
|
||||||
texImage->TexFormat = &_mesa_texformat_ycbcr_rev;
|
|
||||||
texelBytes = 2;
|
|
||||||
}
|
|
||||||
else if ( format == GL_YCBCR_MESA &&
|
|
||||||
(type == GL_UNSIGNED_SHORT_8_8_APPLE ||
|
|
||||||
type == GL_UNSIGNED_BYTE)) {
|
|
||||||
texImage->TexFormat = &_mesa_texformat_ycbcr;
|
|
||||||
texelBytes = 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Could deal with these packing issues, but currently don't:
|
|
||||||
*/
|
|
||||||
if (packing->SkipPixels ||
|
|
||||||
packing->SkipRows ||
|
|
||||||
packing->SwapBytes ||
|
|
||||||
packing->LsbFirst) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
GLint srcRowStride = _mesa_image_row_stride(packing, srcWidth,
|
|
||||||
format, type);
|
|
||||||
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "%s: srcRowStride %d/%x\n",
|
|
||||||
__FUNCTION__, srcRowStride, srcRowStride);
|
|
||||||
|
|
||||||
/* Could check this later in upload, pitch restrictions could be
|
|
||||||
* relaxed, but would need to store the image pitch somewhere,
|
|
||||||
* as packing details might change before image is uploaded:
|
|
||||||
*/
|
|
||||||
if (!intelIsAgpMemory( intel, pixels, srcHeight * srcRowStride ) ||
|
|
||||||
(srcRowStride & 63))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
|
||||||
/* Have validated that _mesa_transfer_teximage would be a straight
|
|
||||||
* memcpy at this point. NOTE: future calls to TexSubImage will
|
|
||||||
* overwrite the client data. This is explicitly mentioned in the
|
|
||||||
* extension spec.
|
|
||||||
*/
|
|
||||||
texImage->Data = (void *)pixels;
|
|
||||||
texImage->IsClientData = GL_TRUE;
|
|
||||||
texImage->RowStride = srcRowStride / texelBytes;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void intelTexImage1D( GLcontext *ctx, GLenum target, GLint level,
|
|
||||||
GLint internalFormat,
|
|
||||||
GLint width, GLint border,
|
|
||||||
GLenum format, GLenum type, const GLvoid *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
|
||||||
|
|
||||||
assert(t);
|
|
||||||
intelFlush( ctx );
|
|
||||||
driSwapOutTextureObject( t );
|
|
||||||
|
|
||||||
texImage->IsClientData = GL_FALSE;
|
|
||||||
|
|
||||||
_mesa_store_teximage1d( ctx, target, level, internalFormat,
|
|
||||||
width, border, format, type,
|
|
||||||
pixels, packing, texObj, texImage );
|
|
||||||
|
|
||||||
t->dirty_images[0] |= (1 << level);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intelTexSubImage1D( GLcontext *ctx,
|
|
||||||
GLenum target,
|
|
||||||
GLint level,
|
|
||||||
GLint xoffset,
|
|
||||||
GLsizei width,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const GLvoid *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
|
||||||
|
|
||||||
assert(t);
|
|
||||||
intelFlush( ctx );
|
|
||||||
driSwapOutTextureObject( t );
|
|
||||||
|
|
||||||
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
|
|
||||||
format, type, pixels, packing, texObj,
|
|
||||||
texImage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Handles 2D, CUBE, RECT:
|
|
||||||
|
static struct gl_texture_image *intelNewTextureImage( GLcontext *ctx )
|
||||||
|
{
|
||||||
|
(void) ctx;
|
||||||
|
return (struct gl_texture_image *)CALLOC_STRUCT(intel_texture_image);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct gl_texture_object *intelNewTextureObject( GLcontext *ctx,
|
||||||
|
GLuint name,
|
||||||
|
GLenum target )
|
||||||
|
{
|
||||||
|
struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object);
|
||||||
|
|
||||||
|
_mesa_initialize_texture_object(&obj->base, name, target);
|
||||||
|
|
||||||
|
return &obj->base;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void intelFreeTextureImageData( GLcontext *ctx,
|
||||||
|
struct gl_texture_image *texImage )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
struct intel_texture_image *intelImage = intel_texture_image(texImage);
|
||||||
|
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intel_miptree_release(intel, &intelImage->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (texImage->Data) {
|
||||||
|
free(texImage->Data);
|
||||||
|
texImage->Data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __x86_64__
|
||||||
|
static unsigned
|
||||||
|
fastrdtsc(void)
|
||||||
|
{
|
||||||
|
unsigned eax;
|
||||||
|
__asm__ volatile ("\t"
|
||||||
|
"pushl %%ebx\n\t"
|
||||||
|
"cpuid\n\t" ".byte 0x0f, 0x31\n\t" "popl %%ebx\n":"=a" (eax)
|
||||||
|
:"0"(0)
|
||||||
|
:"ecx", "edx", "cc");
|
||||||
|
|
||||||
|
return eax;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static unsigned
|
||||||
|
fastrdtsc(void)
|
||||||
|
{
|
||||||
|
unsigned eax;
|
||||||
|
__asm__ volatile ("\t"
|
||||||
|
"cpuid\n\t" ".byte 0x0f, 0x31\n\t" :"=a" (eax)
|
||||||
|
:"0"(0)
|
||||||
|
:"ecx", "edx", "ebx", "cc");
|
||||||
|
|
||||||
|
return eax;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
time_diff(unsigned t, unsigned t2)
|
||||||
|
{
|
||||||
|
return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* The system memcpy (at least on ubuntu 5.10) has problems copying
|
||||||
|
* to agp (writecombined) memory from a source which isn't 64-byte
|
||||||
|
* aligned - there is a 4x performance falloff.
|
||||||
|
*
|
||||||
|
* The x86 __memcpy is immune to this but is slightly slower
|
||||||
|
* (10%-ish) than the system memcpy.
|
||||||
|
*
|
||||||
|
* The sse_memcpy seems to have a slight cliff at 64/32 bytes, but
|
||||||
|
* isn't much faster than x86_memcpy for agp copies.
|
||||||
|
*
|
||||||
|
* TODO: switch dynamically.
|
||||||
*/
|
*/
|
||||||
static void intelTexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
static void *do_memcpy( void *dest, const void *src, size_t n )
|
||||||
GLint internalFormat,
|
|
||||||
GLint width, GLint height, GLint border,
|
|
||||||
GLenum format, GLenum type, const GLvoid *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
{
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
if ( (((unsigned)src) & 63) ||
|
||||||
GLuint face;
|
(((unsigned)dest) & 63)) {
|
||||||
|
return __memcpy(dest, src, n);
|
||||||
/* which cube face or ordinary 2D image */
|
|
||||||
switch (target) {
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
||||||
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
||||||
ASSERT(face < 6);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
face = 0;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
assert(t);
|
return memcpy(dest, src, n);
|
||||||
intelFlush( ctx );
|
|
||||||
driSwapOutTextureObject( t );
|
|
||||||
texImage->IsClientData = GL_FALSE;
|
|
||||||
|
|
||||||
if (intelValidateClientStorage( INTEL_CONTEXT(ctx), target,
|
|
||||||
internalFormat,
|
|
||||||
width, height,
|
|
||||||
format, type, pixels,
|
|
||||||
packing, texObj, texImage)) {
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr, "%s: Using client storage\n", __FUNCTION__);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
_mesa_store_teximage2d( ctx, target, level, internalFormat,
|
|
||||||
width, height, border, format, type,
|
|
||||||
pixels, packing, texObj, texImage );
|
|
||||||
|
|
||||||
t->dirty_images[face] |= (1 << level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intelTexSubImage2D( GLcontext *ctx,
|
|
||||||
GLenum target,
|
|
||||||
GLint level,
|
|
||||||
GLint xoffset, GLint yoffset,
|
|
||||||
GLsizei width, GLsizei height,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const GLvoid *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
|
||||||
GLuint face;
|
|
||||||
|
|
||||||
/* which cube face or ordinary 2D image */
|
|
||||||
switch (target) {
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
||||||
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
||||||
ASSERT(face < 6);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
face = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texImage->IsClientData &&
|
|
||||||
(char *)pixels == (char *)texImage->Data +
|
|
||||||
((xoffset + yoffset * texImage->RowStride) *
|
|
||||||
texImage->TexFormat->TexelBytes)) {
|
|
||||||
|
|
||||||
/* Notification only - no upload required */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert( t ); /* this _should_ be true */
|
|
||||||
intelFlush( ctx );
|
|
||||||
driSwapOutTextureObject( t );
|
|
||||||
|
|
||||||
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
|
|
||||||
height, format, type, pixels, packing, texObj,
|
|
||||||
texImage);
|
|
||||||
|
|
||||||
t->dirty_images[face] |= (1 << level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
|
||||||
GLint internalFormat,
|
|
||||||
GLint width, GLint height, GLint border,
|
|
||||||
GLsizei imageSize, const GLvoid *data,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
|
||||||
GLuint face;
|
|
||||||
|
|
||||||
/* which cube face or ordinary 2D image */
|
|
||||||
switch (target) {
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
||||||
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
||||||
ASSERT(face < 6);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
face = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(t);
|
|
||||||
intelFlush( ctx );
|
|
||||||
|
|
||||||
driSwapOutTextureObject( t );
|
|
||||||
texImage->IsClientData = GL_FALSE;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr, "%s: Using normal storage\n", __FUNCTION__);
|
|
||||||
|
|
||||||
_mesa_store_compressed_teximage2d(ctx, target, level, internalFormat, width,
|
|
||||||
height, border, imageSize, data, texObj, texImage);
|
|
||||||
|
|
||||||
t->dirty_images[face] |= (1 << level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void intelCompressedTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
|
static void *timed_memcpy( void *dest, const void *src, size_t n )
|
||||||
GLint xoffset, GLint yoffset,
|
|
||||||
GLsizei width, GLsizei height,
|
|
||||||
GLenum format,
|
|
||||||
GLsizei imageSize, const GLvoid *data,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
{
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
void *ret;
|
||||||
GLuint face;
|
unsigned t1, t2;
|
||||||
|
double rate;
|
||||||
|
|
||||||
|
if ( (((unsigned)src) & 63) ||
|
||||||
|
(((unsigned)dest) & 63))
|
||||||
|
_mesa_printf("Warning - non-aligned texture copy!\n");
|
||||||
|
|
||||||
/* which cube face or ordinary 2D image */
|
t1 = fastrdtsc();
|
||||||
switch (target) {
|
ret = do_memcpy(dest, src, n);
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
t2 = fastrdtsc();
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
||||||
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
||||||
face = (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
|
||||||
ASSERT(face < 6);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
face = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert( t ); /* this _should_ be true */
|
rate = time_diff(t1, t2);
|
||||||
intelFlush( ctx );
|
rate /= (double) n;
|
||||||
driSwapOutTextureObject( t );
|
_mesa_printf("timed_memcpy: %u %u --> %f clocks/byte\n", t1, t2, rate);
|
||||||
|
return ret;
|
||||||
_mesa_store_compressed_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
|
|
||||||
height, format, imageSize, data, texObj, texImage);
|
|
||||||
|
|
||||||
t->dirty_images[face] |= (1 << level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void intelTexImage3D( GLcontext *ctx, GLenum target, GLint level,
|
void intelInitTextureFuncs(struct dd_function_table * functions)
|
||||||
GLint internalFormat,
|
|
||||||
GLint width, GLint height, GLint depth,
|
|
||||||
GLint border,
|
|
||||||
GLenum format, GLenum type, const GLvoid *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
{
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
functions->ChooseTextureFormat = intelChooseTextureFormat;
|
||||||
|
functions->TexImage1D = intelTexImage1D;
|
||||||
|
functions->TexImage2D = intelTexImage2D;
|
||||||
|
functions->TexImage3D = intelTexImage3D;
|
||||||
|
functions->TexSubImage1D = intelTexSubImage1D;
|
||||||
|
functions->TexSubImage2D = intelTexSubImage2D;
|
||||||
|
functions->TexSubImage3D = intelTexSubImage3D;
|
||||||
|
functions->CopyTexImage1D = intelCopyTexImage1D;
|
||||||
|
functions->CopyTexImage2D = intelCopyTexImage2D;
|
||||||
|
functions->CopyTexSubImage1D = intelCopyTexSubImage1D;
|
||||||
|
functions->CopyTexSubImage2D = intelCopyTexSubImage2D;
|
||||||
|
functions->NewTextureObject = intelNewTextureObject;
|
||||||
|
functions->NewTextureImage = intelNewTextureImage;
|
||||||
|
functions->DeleteTexture = _mesa_delete_texture_object;
|
||||||
|
functions->FreeTexImageData = intelFreeTextureImageData;
|
||||||
|
functions->UpdateTexturePalette = 0;
|
||||||
|
functions->IsTextureResident = intelIsTextureResident;
|
||||||
|
|
||||||
assert(t);
|
if (INTEL_DEBUG & DEBUG_BUFMGR)
|
||||||
driSwapOutTextureObject( t );
|
functions->TextureMemCpy = timed_memcpy;
|
||||||
texImage->IsClientData = GL_FALSE;
|
else
|
||||||
|
functions->TextureMemCpy = do_memcpy;
|
||||||
_mesa_store_teximage3d(ctx, target, level, internalFormat,
|
|
||||||
width, height, depth, border,
|
|
||||||
format, type, pixels,
|
|
||||||
&ctx->Unpack, texObj, texImage);
|
|
||||||
|
|
||||||
t->dirty_images[0] |= (1 << level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
intelTexSubImage3D( GLcontext *ctx, GLenum target, GLint level,
|
|
||||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
|
||||||
GLsizei width, GLsizei height, GLsizei depth,
|
|
||||||
GLenum format, GLenum type,
|
|
||||||
const GLvoid *pixels,
|
|
||||||
const struct gl_pixelstore_attrib *packing,
|
|
||||||
struct gl_texture_object *texObj,
|
|
||||||
struct gl_texture_image *texImage )
|
|
||||||
{
|
|
||||||
driTextureObject * t = (driTextureObject *) texObj->DriverData;
|
|
||||||
|
|
||||||
assert( t ); /* this _should_ be true */
|
|
||||||
driSwapOutTextureObject( t );
|
|
||||||
|
|
||||||
_mesa_store_texsubimage3d(ctx, target, level, xoffset, yoffset, zoffset,
|
|
||||||
width, height, depth,
|
|
||||||
format, type, pixels, packing, texObj, texImage);
|
|
||||||
|
|
||||||
t->dirty_images[0] |= (1 << level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void intelDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj )
|
|
||||||
{
|
|
||||||
driTextureObject * t = (driTextureObject *) tObj->DriverData;
|
|
||||||
|
|
||||||
if ( t != NULL ) {
|
|
||||||
intelFlush( ctx );
|
|
||||||
driDestroyTextureObject( t );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free mipmap images and the texture object itself */
|
|
||||||
_mesa_delete_texture_object(ctx, tObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const struct gl_texture_format *
|
|
||||||
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
|
|
||||||
GLenum format, GLenum type )
|
|
||||||
{
|
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
|
||||||
const GLboolean do32bpt = ( intel->intelScreen->cpp == 4 &&
|
|
||||||
intel->intelScreen->tex.size > 4*1024*1024);
|
|
||||||
|
|
||||||
switch ( internalFormat ) {
|
|
||||||
case 4:
|
|
||||||
case GL_RGBA:
|
|
||||||
case GL_COMPRESSED_RGBA:
|
|
||||||
if ( format == GL_BGRA ) {
|
|
||||||
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
|
|
||||||
return &_mesa_texformat_argb8888;
|
|
||||||
}
|
|
||||||
else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
|
|
||||||
return &_mesa_texformat_argb4444;
|
|
||||||
}
|
|
||||||
else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
|
|
||||||
return &_mesa_texformat_argb1555;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
case GL_RGB:
|
|
||||||
case GL_COMPRESSED_RGB:
|
|
||||||
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
|
|
||||||
return &_mesa_texformat_rgb565;
|
|
||||||
}
|
|
||||||
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
|
|
||||||
|
|
||||||
case GL_RGBA8:
|
|
||||||
case GL_RGB10_A2:
|
|
||||||
case GL_RGBA12:
|
|
||||||
case GL_RGBA16:
|
|
||||||
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
|
|
||||||
|
|
||||||
case GL_RGBA4:
|
|
||||||
case GL_RGBA2:
|
|
||||||
return &_mesa_texformat_argb4444;
|
|
||||||
|
|
||||||
case GL_RGB5_A1:
|
|
||||||
return &_mesa_texformat_argb1555;
|
|
||||||
|
|
||||||
case GL_RGB8:
|
|
||||||
case GL_RGB10:
|
|
||||||
case GL_RGB12:
|
|
||||||
case GL_RGB16:
|
|
||||||
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
|
|
||||||
|
|
||||||
case GL_RGB5:
|
|
||||||
case GL_RGB4:
|
|
||||||
case GL_R3_G3_B2:
|
|
||||||
return &_mesa_texformat_rgb565;
|
|
||||||
|
|
||||||
case GL_ALPHA:
|
|
||||||
case GL_ALPHA4:
|
|
||||||
case GL_ALPHA8:
|
|
||||||
case GL_ALPHA12:
|
|
||||||
case GL_ALPHA16:
|
|
||||||
case GL_COMPRESSED_ALPHA:
|
|
||||||
return &_mesa_texformat_a8;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
case GL_LUMINANCE:
|
|
||||||
case GL_LUMINANCE4:
|
|
||||||
case GL_LUMINANCE8:
|
|
||||||
case GL_LUMINANCE12:
|
|
||||||
case GL_LUMINANCE16:
|
|
||||||
case GL_COMPRESSED_LUMINANCE:
|
|
||||||
return &_mesa_texformat_l8;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
case GL_LUMINANCE_ALPHA:
|
|
||||||
case GL_LUMINANCE4_ALPHA4:
|
|
||||||
case GL_LUMINANCE6_ALPHA2:
|
|
||||||
case GL_LUMINANCE8_ALPHA8:
|
|
||||||
case GL_LUMINANCE12_ALPHA4:
|
|
||||||
case GL_LUMINANCE12_ALPHA12:
|
|
||||||
case GL_LUMINANCE16_ALPHA16:
|
|
||||||
case GL_COMPRESSED_LUMINANCE_ALPHA:
|
|
||||||
return &_mesa_texformat_al88;
|
|
||||||
|
|
||||||
case GL_INTENSITY:
|
|
||||||
case GL_INTENSITY4:
|
|
||||||
case GL_INTENSITY8:
|
|
||||||
case GL_INTENSITY12:
|
|
||||||
case GL_INTENSITY16:
|
|
||||||
case GL_COMPRESSED_INTENSITY:
|
|
||||||
return &_mesa_texformat_i8;
|
|
||||||
|
|
||||||
case GL_YCBCR_MESA:
|
|
||||||
if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
|
|
||||||
type == GL_UNSIGNED_BYTE)
|
|
||||||
return &_mesa_texformat_ycbcr;
|
|
||||||
else
|
|
||||||
return &_mesa_texformat_ycbcr_rev;
|
|
||||||
|
|
||||||
case GL_COMPRESSED_RGB_FXT1_3DFX:
|
|
||||||
return &_mesa_texformat_rgb_fxt1;
|
|
||||||
case GL_COMPRESSED_RGBA_FXT1_3DFX:
|
|
||||||
return &_mesa_texformat_rgba_fxt1;
|
|
||||||
|
|
||||||
case GL_RGB_S3TC:
|
|
||||||
case GL_RGB4_S3TC:
|
|
||||||
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
|
||||||
return &_mesa_texformat_rgb_dxt1;
|
|
||||||
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
|
||||||
return &_mesa_texformat_rgba_dxt1;
|
|
||||||
|
|
||||||
case GL_RGBA_S3TC:
|
|
||||||
case GL_RGBA4_S3TC:
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
|
||||||
return &_mesa_texformat_rgba_dxt3;
|
|
||||||
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
|
||||||
return &_mesa_texformat_rgba_dxt5;
|
|
||||||
|
|
||||||
case GL_DEPTH_COMPONENT:
|
|
||||||
case GL_DEPTH_COMPONENT16:
|
|
||||||
case GL_DEPTH_COMPONENT24:
|
|
||||||
case GL_DEPTH_COMPONENT32:
|
|
||||||
return &_mesa_texformat_depth_component16;
|
|
||||||
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "unexpected texture format %s in %s\n",
|
|
||||||
_mesa_lookup_enum_by_nr(internalFormat),
|
|
||||||
__FUNCTION__);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL; /* never get here */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelDestroyTexObj(intelContextPtr intel, intelTextureObjectPtr t)
|
|
||||||
{
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
if ( intel == NULL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( t->age > intel->dirtyAge )
|
|
||||||
intel->dirtyAge = t->age;
|
|
||||||
|
|
||||||
for ( i = 0 ; i < MAX_TEXTURE_UNITS ; i++ ) {
|
|
||||||
if ( t == intel->CurrentTexObj[ i ] )
|
|
||||||
intel->CurrentTexObj[ i ] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Upload an image from mesa's internal copy. Image may be 1D, 2D or
|
|
||||||
* 3D. Cubemaps are expanded elsewhere.
|
|
||||||
*/
|
|
||||||
static void intelUploadTexImage( intelContextPtr intel,
|
|
||||||
intelTextureObjectPtr t,
|
|
||||||
const struct gl_texture_image *image,
|
|
||||||
const GLuint offset )
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!image || !image->Data)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (image->Depth == 1 && image->IsClientData) {
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr, "Blit uploading\n");
|
|
||||||
|
|
||||||
/* Do it with a blit.
|
|
||||||
*/
|
|
||||||
intelEmitCopyBlitLocked( intel,
|
|
||||||
image->TexFormat->TexelBytes,
|
|
||||||
image->RowStride, /* ? */
|
|
||||||
intelGetMemoryOffsetMESA( NULL, 0, image->Data ),
|
|
||||||
t->Pitch / image->TexFormat->TexelBytes,
|
|
||||||
intelGetMemoryOffsetMESA( NULL, 0, t->BufAddr + offset ),
|
|
||||||
0, 0,
|
|
||||||
0, 0,
|
|
||||||
image->Width,
|
|
||||||
image->Height);
|
|
||||||
}
|
|
||||||
else if (image->IsCompressed) {
|
|
||||||
GLuint row_len = image->Width * 2;
|
|
||||||
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
|
|
||||||
GLubyte *src = (GLubyte *)image->Data;
|
|
||||||
GLuint j;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr,
|
|
||||||
"Upload image %dx%dx%d offset %xm row_len %x "
|
|
||||||
"pitch %x depth_pitch %x\n",
|
|
||||||
image->Width, image->Height, image->Depth, offset,
|
|
||||||
row_len, t->Pitch, t->depth_pitch);
|
|
||||||
|
|
||||||
switch (image->InternalFormat) {
|
|
||||||
case GL_COMPRESSED_RGB_FXT1_3DFX:
|
|
||||||
case GL_COMPRESSED_RGBA_FXT1_3DFX:
|
|
||||||
case GL_RGB_S3TC:
|
|
||||||
case GL_RGB4_S3TC:
|
|
||||||
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
|
||||||
for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
|
|
||||||
__memcpy(dst, src, row_len );
|
|
||||||
src += row_len;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GL_RGBA_S3TC:
|
|
||||||
case GL_RGBA4_S3TC:
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
|
||||||
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
|
||||||
for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) {
|
|
||||||
__memcpy(dst, src, (image->Width*4) );
|
|
||||||
src += image->Width*4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GLuint row_len = image->Width * image->TexFormat->TexelBytes;
|
|
||||||
GLubyte *dst = (GLubyte *)(t->BufAddr + offset);
|
|
||||||
GLubyte *src = (GLubyte *)image->Data;
|
|
||||||
GLuint d, j;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr,
|
|
||||||
"Upload image %dx%dx%d offset %xm row_len %x "
|
|
||||||
"pitch %x depth_pitch %x\n",
|
|
||||||
image->Width, image->Height, image->Depth, offset,
|
|
||||||
row_len, t->Pitch, t->depth_pitch);
|
|
||||||
|
|
||||||
if (row_len == t->Pitch) {
|
|
||||||
for (d = 0; d < image->Depth; d++) {
|
|
||||||
memcpy( dst, src, t->Pitch * image->Height );
|
|
||||||
dst += t->depth_pitch;
|
|
||||||
src += row_len * image->Height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (d = 0 ; d < image->Depth ; d++) {
|
|
||||||
for (j = 0 ; j < image->Height ; j++) {
|
|
||||||
__memcpy(dst, src, row_len );
|
|
||||||
src += row_len;
|
|
||||||
dst += t->Pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
dst += t->depth_pitch - (t->Pitch * image->Height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int intelUploadTexImages( intelContextPtr intel,
|
|
||||||
intelTextureObjectPtr t,
|
|
||||||
GLuint face)
|
|
||||||
{
|
|
||||||
const int numLevels = t->base.lastLevel - t->base.firstLevel + 1;
|
|
||||||
const struct gl_texture_image *firstImage = t->image[face][t->base.firstLevel].image;
|
|
||||||
int pitch = firstImage->RowStride * firstImage->TexFormat->TexelBytes;
|
|
||||||
|
|
||||||
/* Can we texture out of the existing client data? */
|
|
||||||
if ( numLevels == 1 &&
|
|
||||||
firstImage->IsClientData &&
|
|
||||||
(pitch & 3) == 0) {
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr, "AGP texturing from client memory\n");
|
|
||||||
|
|
||||||
t->TextureOffset = intelAgpOffsetFromVirtual( intel, firstImage->Data );
|
|
||||||
t->BufAddr = 0;
|
|
||||||
t->dirty = ~0;
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr, "Uploading client data to agp\n");
|
|
||||||
|
|
||||||
INTEL_FIREVERTICES( intel );
|
|
||||||
LOCK_HARDWARE( intel );
|
|
||||||
|
|
||||||
if ( t->base.memBlock == NULL ) {
|
|
||||||
int heap;
|
|
||||||
|
|
||||||
heap = driAllocateTexture( intel->texture_heaps, intel->nr_heaps,
|
|
||||||
(driTextureObject *) t );
|
|
||||||
if ( heap == -1 ) {
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
return GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the base offset of the texture image */
|
|
||||||
t->BufAddr = intel->intelScreen->tex.map + t->base.memBlock->ofs;
|
|
||||||
t->TextureOffset = intel->intelScreen->tex.offset + t->base.memBlock->ofs;
|
|
||||||
t->dirty = ~0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Let the world know we've used this memory recently.
|
|
||||||
*/
|
|
||||||
driUpdateTextureLRU( (driTextureObject *) t );
|
|
||||||
|
|
||||||
|
|
||||||
/* Upload any images that are new */
|
|
||||||
if (t->base.dirty_images[face]) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
intelWaitForIdle( intel );
|
|
||||||
|
|
||||||
for (i = 0 ; i < numLevels ; i++) {
|
|
||||||
int level = i + t->base.firstLevel;
|
|
||||||
|
|
||||||
if (t->base.dirty_images[face] & (1<<level)) {
|
|
||||||
|
|
||||||
const struct gl_texture_image *image = t->image[face][i].image;
|
|
||||||
GLuint offset = t->image[face][i].offset;
|
|
||||||
|
|
||||||
if (INTEL_DEBUG & DEBUG_TEXTURE)
|
|
||||||
fprintf(stderr, "upload level %d, offset %x\n",
|
|
||||||
level, offset);
|
|
||||||
|
|
||||||
intelUploadTexImage( intel, t, image, offset );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t->base.dirty_images[face] = 0;
|
|
||||||
intel->perf_boxes |= I830_BOX_TEXTURE_LOAD;
|
|
||||||
}
|
|
||||||
|
|
||||||
UNLOCK_HARDWARE( intel );
|
|
||||||
return GL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate a new texture object.
|
|
||||||
* Called via ctx->Driver.NewTextureObject.
|
|
||||||
* Note: this function will be called during context creation to
|
|
||||||
* allocate the default texture objects.
|
|
||||||
* Note: we could use containment here to 'derive' the driver-specific
|
|
||||||
* texture object from the core mesa gl_texture_object. Not done at this time.
|
|
||||||
*/
|
|
||||||
static struct gl_texture_object *
|
|
||||||
intelNewTextureObject( GLcontext *ctx, GLuint name, GLenum target )
|
|
||||||
{
|
|
||||||
struct gl_texture_object *obj = _mesa_new_texture_object(ctx, name, target);
|
|
||||||
INTEL_CONTEXT(ctx)->vtbl.alloc_tex_obj( obj );
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void intelInitTextureFuncs( struct dd_function_table *functions )
|
|
||||||
{
|
|
||||||
functions->NewTextureObject = intelNewTextureObject;
|
|
||||||
functions->ChooseTextureFormat = intelChooseTextureFormat;
|
|
||||||
functions->TexImage1D = intelTexImage1D;
|
|
||||||
functions->TexImage2D = intelTexImage2D;
|
|
||||||
functions->TexImage3D = intelTexImage3D;
|
|
||||||
functions->TexSubImage1D = intelTexSubImage1D;
|
|
||||||
functions->TexSubImage2D = intelTexSubImage2D;
|
|
||||||
functions->TexSubImage3D = intelTexSubImage3D;
|
|
||||||
functions->CopyTexImage1D = _swrast_copy_teximage1d;
|
|
||||||
functions->CopyTexImage2D = _swrast_copy_teximage2d;
|
|
||||||
functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
|
|
||||||
functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
|
|
||||||
functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
|
|
||||||
functions->DeleteTexture = intelDeleteTexture;
|
|
||||||
functions->UpdateTexturePalette = NULL;
|
|
||||||
functions->IsTextureResident = driIsTextureResident;
|
|
||||||
functions->TestProxyTexImage = _mesa_test_proxy_teximage;
|
|
||||||
functions->DeleteTexture = intelDeleteTexture;
|
|
||||||
functions->CompressedTexImage2D = intelCompressedTexImage2D;
|
|
||||||
functions->CompressedTexSubImage2D = intelCompressedTexSubImage2D;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,97 @@
|
|||||||
|
|
||||||
void intelInitTextureFuncs( struct dd_function_table *functions );
|
void intelInitTextureFuncs( struct dd_function_table *functions );
|
||||||
|
|
||||||
void intelDestroyTexObj( intelContextPtr intel, intelTextureObjectPtr t );
|
const struct gl_texture_format *
|
||||||
int intelUploadTexImages( intelContextPtr intel, intelTextureObjectPtr t,
|
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
|
||||||
GLuint face );
|
GLenum format, GLenum type );
|
||||||
|
|
||||||
|
|
||||||
|
void intelTexImage3D(GLcontext *ctx,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint depth,
|
||||||
|
GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
void intelTexSubImage3D(GLcontext *ctx,
|
||||||
|
GLenum target,
|
||||||
|
GLint level,
|
||||||
|
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||||
|
GLsizei width, GLsizei height, GLsizei depth,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
void intelTexImage2D(GLcontext *ctx,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
void intelTexSubImage2D(GLcontext *ctx,
|
||||||
|
GLenum target,
|
||||||
|
GLint level,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
void intelTexImage1D(GLcontext *ctx,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
void intelTexSubImage1D(GLcontext *ctx,
|
||||||
|
GLenum target,
|
||||||
|
GLint level,
|
||||||
|
GLint xoffset,
|
||||||
|
GLsizei width,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage);
|
||||||
|
|
||||||
|
void intelCopyTexImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLint x, GLint y, GLsizei width,
|
||||||
|
GLint border );
|
||||||
|
|
||||||
|
void intelCopyTexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
|
GLint border );
|
||||||
|
|
||||||
|
void intelCopyTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset,
|
||||||
|
GLint x, GLint y, GLsizei width );
|
||||||
|
|
||||||
|
void intelCopyTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height );
|
||||||
|
|
||||||
|
GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit );
|
||||||
|
|
||||||
|
void intel_tex_map_images( struct intel_context *intel,
|
||||||
|
struct intel_texture_object *intelObj );
|
||||||
|
|
||||||
|
void intel_tex_unmap_images( struct intel_context *intel,
|
||||||
|
struct intel_texture_object *intelObj );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
303
src/mesa/drivers/dri/i915/intel_tex_copy.c
Normal file
303
src/mesa/drivers/dri/i915/intel_tex_copy.c
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "enums.h"
|
||||||
|
#include "teximage.h"
|
||||||
|
#include "swrast/swrast.h"
|
||||||
|
|
||||||
|
#include "intel_screen.h"
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_batchbuffer.h"
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
|
#include "intel_regions.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
#include "intel_blit.h"
|
||||||
|
#include "intel_pixel.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
/* Do the best we can using the blitter. A future project is to use
|
||||||
|
* the texture engine and fragment programs for these copies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static struct intel_region *get_teximage_source( struct intel_context *intel,
|
||||||
|
GLenum internalFormat )
|
||||||
|
{
|
||||||
|
if (0)
|
||||||
|
_mesa_printf("%s %s\n", __FUNCTION__,
|
||||||
|
_mesa_lookup_enum_by_nr(internalFormat));
|
||||||
|
|
||||||
|
switch (internalFormat) {
|
||||||
|
case GL_DEPTH_COMPONENT:
|
||||||
|
case GL_DEPTH_COMPONENT16_ARB:
|
||||||
|
if (intel->intelScreen->cpp == 2)
|
||||||
|
return intel->depth_region;
|
||||||
|
return NULL;
|
||||||
|
case GL_DEPTH24_STENCIL8_EXT:
|
||||||
|
case GL_DEPTH_STENCIL_EXT:
|
||||||
|
if (intel->intelScreen->cpp == 4)
|
||||||
|
return intel->depth_region;
|
||||||
|
return NULL;
|
||||||
|
case GL_RGBA:
|
||||||
|
return intel_readbuf_region( intel );
|
||||||
|
case GL_RGB:
|
||||||
|
if (intel->intelScreen->cpp == 2)
|
||||||
|
return intel_readbuf_region( intel );
|
||||||
|
return NULL;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLboolean check_copytex_fragment_ops( const GLcontext *ctx )
|
||||||
|
{
|
||||||
|
return GL_TRUE;
|
||||||
|
|
||||||
|
return !(ctx->Color.AlphaEnabled ||
|
||||||
|
/* ctx->Depth.Test || */
|
||||||
|
ctx->Fog.Enabled ||
|
||||||
|
/* ctx->Scissor.Enabled || */
|
||||||
|
ctx->Stencil.Enabled ||
|
||||||
|
!ctx->Color.ColorMask[0] ||
|
||||||
|
!ctx->Color.ColorMask[1] ||
|
||||||
|
!ctx->Color.ColorMask[2] ||
|
||||||
|
!ctx->Color.ColorMask[3] ||
|
||||||
|
ctx->Color.ColorLogicOpEnabled ||
|
||||||
|
ctx->Texture._EnabledUnits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static GLboolean do_copy_texsubimage( struct intel_context *intel,
|
||||||
|
struct intel_texture_image *intelImage,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLint dstx, GLint dsty,
|
||||||
|
GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height )
|
||||||
|
{
|
||||||
|
GLcontext *ctx = &intel->ctx;
|
||||||
|
struct intel_region *src = get_teximage_source(intel, internalFormat);
|
||||||
|
GLuint ret = GL_TRUE;
|
||||||
|
|
||||||
|
if (!intelImage->mt || !src)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
if (!check_copytex_fragment_ops( ctx ))
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
intelFlush(ctx);
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
{
|
||||||
|
__DRIdrawablePrivate *dPriv = intel->driDrawable;
|
||||||
|
GLuint image_offset = intel_miptree_image_offset(intelImage->mt,
|
||||||
|
intelImage->face,
|
||||||
|
intelImage->level);
|
||||||
|
GLint orig_x = x;
|
||||||
|
GLint orig_y = y;
|
||||||
|
GLuint window_y;
|
||||||
|
|
||||||
|
if (!intel_clip_to_framebuffer(ctx, ctx->DrawBuffer, &x, &y, &width, &height)) {
|
||||||
|
ret = GL_TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update dst for clipped src. Need to also clip the source rect.
|
||||||
|
*/
|
||||||
|
dstx += x - orig_x;
|
||||||
|
dsty += y - orig_y;
|
||||||
|
|
||||||
|
x += dPriv->x;
|
||||||
|
|
||||||
|
window_y = intel->intelScreen->height - (dPriv->y + dPriv->h);
|
||||||
|
|
||||||
|
y = window_y + y;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A bit of fiddling to get the blitter to work with -ve
|
||||||
|
* pitches. But we get a nice inverted blit this way, so it's
|
||||||
|
* worth it:
|
||||||
|
*/
|
||||||
|
intelEmitCopyBlit( intel,
|
||||||
|
intelImage->mt->cpp,
|
||||||
|
|
||||||
|
-src->pitch,
|
||||||
|
src->buffer,
|
||||||
|
src->height * src->pitch * src->cpp,
|
||||||
|
|
||||||
|
intelImage->mt->pitch,
|
||||||
|
intelImage->mt->region->buffer,
|
||||||
|
image_offset,
|
||||||
|
|
||||||
|
x, y + height,
|
||||||
|
dstx, dsty,
|
||||||
|
width, height );
|
||||||
|
|
||||||
|
out:
|
||||||
|
intel_batchbuffer_flush( intel->batch );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
|
if (!ret)
|
||||||
|
return GL_FALSE;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
|
||||||
|
*/
|
||||||
|
if (level == texObj->BaseLevel &&
|
||||||
|
texObj->GenerateMipmap) {
|
||||||
|
intel_generate_mipmap(ctx, target,
|
||||||
|
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
|
||||||
|
texObj);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelCopyTexImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLint x, GLint y, GLsizei width,
|
||||||
|
GLint border )
|
||||||
|
{
|
||||||
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
|
struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||||
|
struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||||
|
|
||||||
|
if (border)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Setup or redefine the texture object, mipmap tree and texture
|
||||||
|
* image. Don't populate yet.
|
||||||
|
*/
|
||||||
|
ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
|
||||||
|
width, border,
|
||||||
|
GL_RGBA, CHAN_TYPE, NULL,
|
||||||
|
&ctx->DefaultPacking, texObj, texImage);
|
||||||
|
|
||||||
|
if (!do_copy_texsubimage(intel_context(ctx),
|
||||||
|
intel_texture_image(texImage),
|
||||||
|
internalFormat,
|
||||||
|
0, 0,
|
||||||
|
x, y,
|
||||||
|
width, 1))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
_swrast_copy_teximage1d( ctx, target, level, internalFormat, x, y,
|
||||||
|
width, border );
|
||||||
|
}
|
||||||
|
|
||||||
|
void intelCopyTexImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLenum internalFormat,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||||
|
GLint border )
|
||||||
|
{
|
||||||
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
|
struct gl_texture_object *texObj = _mesa_select_tex_object(ctx, texUnit, target);
|
||||||
|
struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||||
|
|
||||||
|
if (border)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Setup or redefine the texture object, mipmap tree and texture
|
||||||
|
* image. Don't populate yet.
|
||||||
|
*/
|
||||||
|
ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
|
||||||
|
width, height, border,
|
||||||
|
GL_RGBA, CHAN_TYPE, NULL,
|
||||||
|
&ctx->DefaultPacking, texObj, texImage);
|
||||||
|
|
||||||
|
|
||||||
|
if (!do_copy_texsubimage(intel_context(ctx),
|
||||||
|
intel_texture_image(texImage),
|
||||||
|
internalFormat,
|
||||||
|
0, 0,
|
||||||
|
x, y,
|
||||||
|
width, height))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
_swrast_copy_teximage2d( ctx, target, level, internalFormat, x, y,
|
||||||
|
width, height, border );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelCopyTexSubImage1D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset,
|
||||||
|
GLint x, GLint y, GLsizei width )
|
||||||
|
{
|
||||||
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
|
struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||||
|
GLenum internalFormat = texImage->InternalFormat;
|
||||||
|
|
||||||
|
/* Need to check texture is compatible with source format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!do_copy_texsubimage(intel_context(ctx),
|
||||||
|
intel_texture_image(texImage),
|
||||||
|
internalFormat,
|
||||||
|
xoffset, 0,
|
||||||
|
x, y, width, 1)) {
|
||||||
|
_swrast_copy_texsubimage1d( ctx, target, level,
|
||||||
|
xoffset, x, y, width );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelCopyTexSubImage2D( GLcontext *ctx, GLenum target, GLint level,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
|
GLint x, GLint y, GLsizei width, GLsizei height )
|
||||||
|
{
|
||||||
|
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
|
||||||
|
struct gl_texture_image *texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
|
||||||
|
GLenum internalFormat = texImage->InternalFormat;
|
||||||
|
|
||||||
|
|
||||||
|
/* Need to check texture is compatible with source format.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!do_copy_texsubimage(intel_context(ctx),
|
||||||
|
intel_texture_image(texImage),
|
||||||
|
internalFormat,
|
||||||
|
xoffset, yoffset,
|
||||||
|
x, y, width, height)) {
|
||||||
|
_swrast_copy_texsubimage2d( ctx, target, level,
|
||||||
|
xoffset, yoffset,
|
||||||
|
x, y, width, height );
|
||||||
|
}
|
||||||
|
}
|
||||||
148
src/mesa/drivers/dri/i915/intel_tex_format.c
Normal file
148
src/mesa/drivers/dri/i915/intel_tex_format.c
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
#include "texformat.h"
|
||||||
|
#include "enums.h"
|
||||||
|
|
||||||
|
/* It works out that this function is fine for all the supported
|
||||||
|
* hardware. However, there is still a need to map the formats onto
|
||||||
|
* hardware descriptors.
|
||||||
|
*/
|
||||||
|
/* Note that the i915 can actually support many more formats than
|
||||||
|
* these if we take the step of simply swizzling the colors
|
||||||
|
* immediately after sampling...
|
||||||
|
*/
|
||||||
|
const struct gl_texture_format *
|
||||||
|
intelChooseTextureFormat( GLcontext *ctx, GLint internalFormat,
|
||||||
|
GLenum format, GLenum type )
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context( ctx );
|
||||||
|
const GLboolean do32bpt = (intel->intelScreen->cpp == 4);
|
||||||
|
|
||||||
|
switch ( internalFormat ) {
|
||||||
|
case 4:
|
||||||
|
case GL_RGBA:
|
||||||
|
case GL_COMPRESSED_RGBA:
|
||||||
|
if ( format == GL_BGRA ) {
|
||||||
|
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV ) {
|
||||||
|
return &_mesa_texformat_argb8888;
|
||||||
|
}
|
||||||
|
else if ( type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) {
|
||||||
|
return &_mesa_texformat_argb4444;
|
||||||
|
}
|
||||||
|
else if ( type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) {
|
||||||
|
return &_mesa_texformat_argb1555;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
case GL_RGB:
|
||||||
|
case GL_COMPRESSED_RGB:
|
||||||
|
if ( format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 ) {
|
||||||
|
return &_mesa_texformat_rgb565;
|
||||||
|
}
|
||||||
|
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565;
|
||||||
|
|
||||||
|
case GL_RGBA8:
|
||||||
|
case GL_RGB10_A2:
|
||||||
|
case GL_RGBA12:
|
||||||
|
case GL_RGBA16:
|
||||||
|
return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444;
|
||||||
|
|
||||||
|
case GL_RGBA4:
|
||||||
|
case GL_RGBA2:
|
||||||
|
return &_mesa_texformat_argb4444;
|
||||||
|
|
||||||
|
case GL_RGB5_A1:
|
||||||
|
return &_mesa_texformat_argb1555;
|
||||||
|
|
||||||
|
case GL_RGB8:
|
||||||
|
case GL_RGB10:
|
||||||
|
case GL_RGB12:
|
||||||
|
case GL_RGB16:
|
||||||
|
return &_mesa_texformat_argb8888;
|
||||||
|
|
||||||
|
case GL_RGB5:
|
||||||
|
case GL_RGB4:
|
||||||
|
case GL_R3_G3_B2:
|
||||||
|
return &_mesa_texformat_rgb565;
|
||||||
|
|
||||||
|
case GL_ALPHA:
|
||||||
|
case GL_ALPHA4:
|
||||||
|
case GL_ALPHA8:
|
||||||
|
case GL_ALPHA12:
|
||||||
|
case GL_ALPHA16:
|
||||||
|
case GL_COMPRESSED_ALPHA:
|
||||||
|
return &_mesa_texformat_a8;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case GL_LUMINANCE:
|
||||||
|
case GL_LUMINANCE4:
|
||||||
|
case GL_LUMINANCE8:
|
||||||
|
case GL_LUMINANCE12:
|
||||||
|
case GL_LUMINANCE16:
|
||||||
|
case GL_COMPRESSED_LUMINANCE:
|
||||||
|
return &_mesa_texformat_l8;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case GL_LUMINANCE_ALPHA:
|
||||||
|
case GL_LUMINANCE4_ALPHA4:
|
||||||
|
case GL_LUMINANCE6_ALPHA2:
|
||||||
|
case GL_LUMINANCE8_ALPHA8:
|
||||||
|
case GL_LUMINANCE12_ALPHA4:
|
||||||
|
case GL_LUMINANCE12_ALPHA12:
|
||||||
|
case GL_LUMINANCE16_ALPHA16:
|
||||||
|
case GL_COMPRESSED_LUMINANCE_ALPHA:
|
||||||
|
return &_mesa_texformat_al88;
|
||||||
|
|
||||||
|
case GL_INTENSITY:
|
||||||
|
case GL_INTENSITY4:
|
||||||
|
case GL_INTENSITY8:
|
||||||
|
case GL_INTENSITY12:
|
||||||
|
case GL_INTENSITY16:
|
||||||
|
case GL_COMPRESSED_INTENSITY:
|
||||||
|
return &_mesa_texformat_i8;
|
||||||
|
|
||||||
|
case GL_YCBCR_MESA:
|
||||||
|
if (type == GL_UNSIGNED_SHORT_8_8_MESA ||
|
||||||
|
type == GL_UNSIGNED_BYTE)
|
||||||
|
return &_mesa_texformat_ycbcr;
|
||||||
|
else
|
||||||
|
return &_mesa_texformat_ycbcr_rev;
|
||||||
|
|
||||||
|
case GL_COMPRESSED_RGB_FXT1_3DFX:
|
||||||
|
return &_mesa_texformat_rgb_fxt1;
|
||||||
|
case GL_COMPRESSED_RGBA_FXT1_3DFX:
|
||||||
|
return &_mesa_texformat_rgba_fxt1;
|
||||||
|
|
||||||
|
case GL_RGB_S3TC:
|
||||||
|
case GL_RGB4_S3TC:
|
||||||
|
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
||||||
|
return &_mesa_texformat_rgb_dxt1;
|
||||||
|
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
|
||||||
|
return &_mesa_texformat_rgba_dxt1;
|
||||||
|
|
||||||
|
case GL_RGBA_S3TC:
|
||||||
|
case GL_RGBA4_S3TC:
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
|
||||||
|
return &_mesa_texformat_rgba_dxt3;
|
||||||
|
|
||||||
|
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
||||||
|
return &_mesa_texformat_rgba_dxt5;
|
||||||
|
|
||||||
|
case GL_DEPTH_COMPONENT:
|
||||||
|
case GL_DEPTH_COMPONENT16:
|
||||||
|
case GL_DEPTH_COMPONENT24:
|
||||||
|
case GL_DEPTH_COMPONENT32:
|
||||||
|
return &_mesa_texformat_depth_component16;
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "unexpected texture format %s in %s\n",
|
||||||
|
_mesa_lookup_enum_by_nr(internalFormat),
|
||||||
|
__FUNCTION__);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL; /* never get here */
|
||||||
|
}
|
||||||
400
src/mesa/drivers/dri/i915/intel_tex_image.c
Normal file
400
src/mesa/drivers/dri/i915/intel_tex_image.c
Normal file
@@ -0,0 +1,400 @@
|
|||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "glheader.h"
|
||||||
|
#include "macros.h"
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "enums.h"
|
||||||
|
#include "colortab.h"
|
||||||
|
#include "convolve.h"
|
||||||
|
#include "context.h"
|
||||||
|
#include "simple_list.h"
|
||||||
|
#include "texcompress.h"
|
||||||
|
#include "texformat.h"
|
||||||
|
#include "texobj.h"
|
||||||
|
#include "texstore.h"
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
#include "intel_ioctl.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Functions to store texture images. Where possible, mipmap_tree's
|
||||||
|
* will be created or further instantiated with image data, otherwise
|
||||||
|
* images will be stored in malloc'd memory. A validation step is
|
||||||
|
* required to pull those images into a mipmap tree, or otherwise
|
||||||
|
* decide a fallback is required.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static int logbase2(int n)
|
||||||
|
{
|
||||||
|
GLint i = 1;
|
||||||
|
GLint log2 = 0;
|
||||||
|
|
||||||
|
while (n > i) {
|
||||||
|
i *= 2;
|
||||||
|
log2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return log2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Otherwise, store it in memory if (Border != 0) or (any dimension ==
|
||||||
|
* 1).
|
||||||
|
*
|
||||||
|
* Otherwise, if max_level >= level >= min_level, create tree with
|
||||||
|
* space for textures from min_level down to max_level.
|
||||||
|
*
|
||||||
|
* Otherwise, create tree with space for textures from (level
|
||||||
|
* 0)..(1x1). Consider pruning this tree at a validation if the
|
||||||
|
* saving is worth it.
|
||||||
|
*/
|
||||||
|
static void guess_and_alloc_mipmap_tree( struct intel_context *intel,
|
||||||
|
struct intel_texture_object *intelObj,
|
||||||
|
struct intel_texture_image *intelImage )
|
||||||
|
{
|
||||||
|
GLuint firstLevel;
|
||||||
|
GLuint lastLevel;
|
||||||
|
GLuint width = intelImage->base.Width;
|
||||||
|
GLuint height = intelImage->base.Height;
|
||||||
|
GLuint depth = intelImage->base.Depth;
|
||||||
|
GLuint l2width, l2height, l2depth;
|
||||||
|
GLuint i;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (intelImage->base.Border)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (intelImage->level > intelObj->base.BaseLevel &&
|
||||||
|
(intelImage->base.Width == 1 ||
|
||||||
|
(intelObj->base.Target != GL_TEXTURE_1D &&
|
||||||
|
intelImage->base.Height == 1) ||
|
||||||
|
(intelObj->base.Target == GL_TEXTURE_3D &&
|
||||||
|
intelImage->base.Depth == 1)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If this image disrespects BaseLevel, allocate from level zero.
|
||||||
|
* Usually BaseLevel == 0, so it's unlikely to happen.
|
||||||
|
*/
|
||||||
|
if (intelImage->level < intelObj->base.BaseLevel)
|
||||||
|
firstLevel = 0;
|
||||||
|
else
|
||||||
|
firstLevel = intelObj->base.BaseLevel;
|
||||||
|
|
||||||
|
|
||||||
|
/* Figure out image dimensions at start level.
|
||||||
|
*/
|
||||||
|
for (i = intelImage->level; i > firstLevel; i--) {
|
||||||
|
width <<= 1;
|
||||||
|
if (height != 1) height <<= 1;
|
||||||
|
if (depth != 1) depth <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Guess a reasonable value for lastLevel. This is probably going
|
||||||
|
* to be wrong fairly often and might mean that we have to look at
|
||||||
|
* resizable buffers, or require that buffers implement lazy
|
||||||
|
* pagetable arrangements.
|
||||||
|
*/
|
||||||
|
if ((intelObj->base.MinFilter == GL_NEAREST ||
|
||||||
|
intelObj->base.MinFilter == GL_LINEAR) &&
|
||||||
|
intelImage->level == firstLevel) {
|
||||||
|
lastLevel = firstLevel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
l2width = logbase2(width);
|
||||||
|
l2height = logbase2(height);
|
||||||
|
l2depth = logbase2(depth);
|
||||||
|
lastLevel = firstLevel + MAX2(MAX2(l2width,l2height),l2depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!intelObj->mt);
|
||||||
|
intelObj->mt = intel_miptree_create( intel,
|
||||||
|
intelObj->base.Target,
|
||||||
|
intelImage->base.InternalFormat,
|
||||||
|
firstLevel,
|
||||||
|
lastLevel,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth,
|
||||||
|
intelImage->base.TexFormat->TexelBytes,
|
||||||
|
intelImage->base.IsCompressed );
|
||||||
|
|
||||||
|
DBG("%s - success\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static GLuint target_to_face( GLenum target )
|
||||||
|
{
|
||||||
|
switch (target) {
|
||||||
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
|
||||||
|
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
|
||||||
|
return ((GLuint) target -
|
||||||
|
(GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void intelTexImage(GLcontext *ctx,
|
||||||
|
GLint dims,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint depth,
|
||||||
|
GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
struct intel_texture_object *intelObj = intel_texture_object(texObj);
|
||||||
|
struct intel_texture_image *intelImage = intel_texture_image(texImage);
|
||||||
|
GLint postConvWidth = width;
|
||||||
|
GLint postConvHeight = height;
|
||||||
|
GLint texelBytes, sizeInBytes;
|
||||||
|
GLuint dstRowStride;
|
||||||
|
GLuint dstImageStride;
|
||||||
|
|
||||||
|
|
||||||
|
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
|
||||||
|
_mesa_lookup_enum_by_nr(target),
|
||||||
|
level,
|
||||||
|
width, height, depth, border);
|
||||||
|
|
||||||
|
intelFlush(ctx);
|
||||||
|
|
||||||
|
intelImage->face = target_to_face( target );
|
||||||
|
intelImage->level = level;
|
||||||
|
|
||||||
|
if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
|
||||||
|
_mesa_adjust_image_for_convolution(ctx, dims, &postConvWidth,
|
||||||
|
&postConvHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* choose the texture format */
|
||||||
|
texImage->TexFormat = intelChooseTextureFormat(ctx, internalFormat,
|
||||||
|
format, type);
|
||||||
|
|
||||||
|
assert(texImage->TexFormat);
|
||||||
|
|
||||||
|
switch (dims) {
|
||||||
|
case 1:
|
||||||
|
texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
|
||||||
|
texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
|
||||||
|
texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
|
||||||
|
texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
texelBytes = texImage->TexFormat->TexelBytes;
|
||||||
|
|
||||||
|
|
||||||
|
/* Minimum pitch of 32 bytes */
|
||||||
|
if (postConvWidth * texelBytes < 32) {
|
||||||
|
postConvWidth = 32 / texelBytes;
|
||||||
|
texImage->RowStride = postConvWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(texImage->RowStride == postConvWidth);
|
||||||
|
|
||||||
|
/* Release the reference to a potentially orphaned buffer.
|
||||||
|
* Release any old malloced memory.
|
||||||
|
*/
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intel_miptree_release(intel, &intelImage->mt);
|
||||||
|
assert(!texImage->Data);
|
||||||
|
}
|
||||||
|
else if (texImage->Data) {
|
||||||
|
free(texImage->Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If this is the only texture image in the tree, could call
|
||||||
|
* bmBufferData with NULL data to free the old block and avoid
|
||||||
|
* waiting on any outstanding fences.
|
||||||
|
*/
|
||||||
|
if (intelObj->mt &&
|
||||||
|
intelObj->mt->first_level == level &&
|
||||||
|
intelObj->mt->last_level == level &&
|
||||||
|
intelObj->mt->target != GL_TEXTURE_CUBE_MAP_ARB &&
|
||||||
|
!intel_miptree_match_image(intelObj->mt, &intelImage->base,
|
||||||
|
intelImage->face, intelImage->level)) {
|
||||||
|
|
||||||
|
DBG("release it\n");
|
||||||
|
intel_miptree_release(intel, &intelObj->mt);
|
||||||
|
assert(!intelObj->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!intelObj->mt) {
|
||||||
|
guess_and_alloc_mipmap_tree(intel, intelObj, intelImage);
|
||||||
|
if (!intelObj->mt)
|
||||||
|
_mesa_printf("guess_and_alloc_mipmap_tree: failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (intelObj->mt &&
|
||||||
|
intelObj->mt != intelImage->mt &&
|
||||||
|
intel_miptree_match_image(intelObj->mt, &intelImage->base,
|
||||||
|
intelImage->face, intelImage->level)) {
|
||||||
|
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intel_miptree_release(intel, &intelImage->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_miptree_reference(&intelImage->mt, intelObj->mt);
|
||||||
|
assert(intelImage->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!intelImage->mt)
|
||||||
|
_mesa_printf("XXX: Image did not fit into tree - storing in local memory!\n");
|
||||||
|
|
||||||
|
/* intelCopyTexImage calls this function with pixels == NULL, with
|
||||||
|
* the expectation that the mipmap tree will be set up but nothing
|
||||||
|
* more will be done. This is where those calls return:
|
||||||
|
*/
|
||||||
|
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1,
|
||||||
|
format, type,
|
||||||
|
pixels, unpack, "glTexImage");
|
||||||
|
if (!pixels)
|
||||||
|
return;
|
||||||
|
|
||||||
|
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
|
||||||
|
if (intelImage->mt) {
|
||||||
|
texImage->Data = intel_miptree_image_map(intel,
|
||||||
|
intelImage->mt,
|
||||||
|
intelImage->face,
|
||||||
|
intelImage->level,
|
||||||
|
&dstRowStride,
|
||||||
|
&dstImageStride);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Allocate regular memory and store the image there temporarily. */
|
||||||
|
if (texImage->IsCompressed) {
|
||||||
|
sizeInBytes = texImage->CompressedSize;
|
||||||
|
dstRowStride = _mesa_compressed_row_stride(texImage->InternalFormat,width);
|
||||||
|
dstImageStride = 0; /* ? */
|
||||||
|
assert(dims != 3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dstRowStride = postConvWidth * texelBytes;
|
||||||
|
dstImageStride = dstRowStride * postConvHeight;
|
||||||
|
sizeInBytes = depth * dstImageStride;
|
||||||
|
}
|
||||||
|
texImage->Data = malloc(sizeInBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"Upload image %dx%dx%d row_len %x "
|
||||||
|
"pitch %x depth_pitch %x\n",
|
||||||
|
width, height, depth,
|
||||||
|
width * texelBytes, dstRowStride, dstImageStride);
|
||||||
|
|
||||||
|
/* Copy data. Would like to know when it's ok for us to eg. use
|
||||||
|
* the blitter to copy. Or, use the hardware to do the format
|
||||||
|
* conversion and copy:
|
||||||
|
*/
|
||||||
|
if (!texImage->TexFormat->StoreImage(ctx, dims,
|
||||||
|
texImage->_BaseFormat,
|
||||||
|
texImage->TexFormat,
|
||||||
|
texImage->Data,
|
||||||
|
0, 0, 0, /* dstX/Y/Zoffset */
|
||||||
|
dstRowStride, dstImageStride,
|
||||||
|
width, height, depth,
|
||||||
|
format, type, pixels, unpack)) {
|
||||||
|
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
|
||||||
|
}
|
||||||
|
|
||||||
|
_mesa_unmap_teximage_pbo(ctx, unpack);
|
||||||
|
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intel_miptree_image_unmap(intel, intelImage->mt);
|
||||||
|
texImage->Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* GL_SGIS_generate_mipmap -- this can be accelerated now.
|
||||||
|
*/
|
||||||
|
if (level == texObj->BaseLevel &&
|
||||||
|
texObj->GenerateMipmap) {
|
||||||
|
intel_generate_mipmap(ctx, target,
|
||||||
|
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
|
||||||
|
texObj);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void intelTexImage3D(GLcontext *ctx,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint depth,
|
||||||
|
GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
intelTexImage( ctx, 3, target, level,
|
||||||
|
internalFormat, width, height, depth, border,
|
||||||
|
format, type, pixels,
|
||||||
|
unpack, texObj, texImage );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelTexImage2D(GLcontext *ctx,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint height, GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
intelTexImage( ctx, 2, target, level,
|
||||||
|
internalFormat, width, height, 1, border,
|
||||||
|
format, type, pixels,
|
||||||
|
unpack, texObj, texImage );
|
||||||
|
}
|
||||||
|
|
||||||
|
void intelTexImage1D(GLcontext *ctx,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint internalFormat,
|
||||||
|
GLint width, GLint border,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *unpack,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
intelTexImage( ctx, 1, target, level,
|
||||||
|
internalFormat, width, 1, 1, border,
|
||||||
|
format, type, pixels,
|
||||||
|
unpack, texObj, texImage );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
178
src/mesa/drivers/dri/i915/intel_tex_subimage.c
Normal file
178
src/mesa/drivers/dri/i915/intel_tex_subimage.c
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the
|
||||||
|
* "Software"), to deal in the Software without restriction, including
|
||||||
|
* without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
* distribute, sub license, and/or sell copies of the Software, and to
|
||||||
|
* permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
* the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the
|
||||||
|
* next paragraph) shall be included in all copies or substantial portions
|
||||||
|
* of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||||
|
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||||
|
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "mtypes.h"
|
||||||
|
#include "texobj.h"
|
||||||
|
#include "texstore.h"
|
||||||
|
#include "enums.h"
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void intelTexSubimage (GLcontext *ctx,
|
||||||
|
GLint dims,
|
||||||
|
GLenum target, GLint level,
|
||||||
|
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||||
|
GLint width, GLint height, GLint depth,
|
||||||
|
GLenum format, GLenum type, const void *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
struct intel_texture_image *intelImage = intel_texture_image(texImage);
|
||||||
|
GLuint dstImageStride;
|
||||||
|
GLuint dstRowStride;
|
||||||
|
|
||||||
|
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
|
||||||
|
_mesa_lookup_enum_by_nr(target),
|
||||||
|
level,
|
||||||
|
xoffset, yoffset,
|
||||||
|
width, height);
|
||||||
|
|
||||||
|
intelFlush(ctx);
|
||||||
|
|
||||||
|
pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format, type,
|
||||||
|
pixels, packing, "glTexSubImage2D");
|
||||||
|
if (!pixels)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LOCK_HARDWARE(intel);
|
||||||
|
|
||||||
|
/* Map buffer if necessary. Need to lock to prevent other contexts
|
||||||
|
* from uploading the buffer under us.
|
||||||
|
*/
|
||||||
|
if (intelImage->mt)
|
||||||
|
texImage->Data = intel_miptree_image_map(intel,
|
||||||
|
intelImage->mt,
|
||||||
|
intelImage->face,
|
||||||
|
intelImage->level,
|
||||||
|
&dstRowStride,
|
||||||
|
&dstImageStride );
|
||||||
|
|
||||||
|
assert(dstRowStride);
|
||||||
|
|
||||||
|
if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
|
||||||
|
texImage->TexFormat,
|
||||||
|
texImage->Data,
|
||||||
|
xoffset, yoffset, zoffset,
|
||||||
|
dstRowStride, dstImageStride,
|
||||||
|
width, height, depth,
|
||||||
|
format, type, pixels, packing)) {
|
||||||
|
_mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* GL_SGIS_generate_mipmap */
|
||||||
|
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
|
||||||
|
_mesa_generate_mipmap(ctx, target,
|
||||||
|
&ctx->Texture.Unit[ctx->Texture.CurrentUnit],
|
||||||
|
texObj);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_mesa_unmap_teximage_pbo(ctx, packing);
|
||||||
|
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intel_miptree_image_unmap(intel, intelImage->mt);
|
||||||
|
texImage->Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
UNLOCK_HARDWARE(intel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelTexSubImage3D(GLcontext *ctx,
|
||||||
|
GLenum target,
|
||||||
|
GLint level,
|
||||||
|
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||||
|
GLsizei width, GLsizei height, GLsizei depth,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
|
||||||
|
intelTexSubimage(ctx, 3,
|
||||||
|
target, level,
|
||||||
|
xoffset, yoffset, zoffset,
|
||||||
|
width, height, depth,
|
||||||
|
format, type, pixels, packing, texObj,
|
||||||
|
texImage);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intelTexSubImage2D(GLcontext *ctx,
|
||||||
|
GLenum target,
|
||||||
|
GLint level,
|
||||||
|
GLint xoffset, GLint yoffset,
|
||||||
|
GLsizei width, GLsizei height,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
|
||||||
|
intelTexSubimage(ctx, 2,
|
||||||
|
target, level,
|
||||||
|
xoffset, yoffset, 0,
|
||||||
|
width, height, 1,
|
||||||
|
format, type, pixels, packing, texObj,
|
||||||
|
texImage);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelTexSubImage1D(GLcontext *ctx,
|
||||||
|
GLenum target,
|
||||||
|
GLint level,
|
||||||
|
GLint xoffset,
|
||||||
|
GLsizei width,
|
||||||
|
GLenum format, GLenum type,
|
||||||
|
const GLvoid *pixels,
|
||||||
|
const struct gl_pixelstore_attrib *packing,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
struct gl_texture_image *texImage)
|
||||||
|
{
|
||||||
|
intelTexSubimage(ctx, 1,
|
||||||
|
target, level,
|
||||||
|
xoffset, 0, 0,
|
||||||
|
width, 1, 1,
|
||||||
|
format, type, pixels, packing, texObj,
|
||||||
|
texImage);
|
||||||
|
|
||||||
|
}
|
||||||
249
src/mesa/drivers/dri/i915/intel_tex_validate.c
Normal file
249
src/mesa/drivers/dri/i915/intel_tex_validate.c
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
#include "mtypes.h"
|
||||||
|
#include "macros.h"
|
||||||
|
|
||||||
|
#include "intel_context.h"
|
||||||
|
#include "intel_mipmap_tree.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
#include "bufmgr.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute which mipmap levels that really need to be sent to the hardware.
|
||||||
|
* This depends on the base image size, GL_TEXTURE_MIN_LOD,
|
||||||
|
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
|
||||||
|
*/
|
||||||
|
static void intel_calculate_first_last_level( struct intel_texture_object *intelObj )
|
||||||
|
{
|
||||||
|
struct gl_texture_object *tObj = &intelObj->base;
|
||||||
|
const struct gl_texture_image * const baseImage =
|
||||||
|
tObj->Image[0][tObj->BaseLevel];
|
||||||
|
|
||||||
|
/* These must be signed values. MinLod and MaxLod can be negative numbers,
|
||||||
|
* and having firstLevel and lastLevel as signed prevents the need for
|
||||||
|
* extra sign checks.
|
||||||
|
*/
|
||||||
|
int firstLevel;
|
||||||
|
int lastLevel;
|
||||||
|
|
||||||
|
/* Yes, this looks overly complicated, but it's all needed.
|
||||||
|
*/
|
||||||
|
switch (tObj->Target) {
|
||||||
|
case GL_TEXTURE_1D:
|
||||||
|
case GL_TEXTURE_2D:
|
||||||
|
case GL_TEXTURE_3D:
|
||||||
|
case GL_TEXTURE_CUBE_MAP:
|
||||||
|
if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
|
||||||
|
/* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
|
||||||
|
*/
|
||||||
|
firstLevel = lastLevel = tObj->BaseLevel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
|
||||||
|
firstLevel = MAX2(firstLevel, tObj->BaseLevel);
|
||||||
|
lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
|
||||||
|
lastLevel = MAX2(lastLevel, tObj->BaseLevel);
|
||||||
|
lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
|
||||||
|
lastLevel = MIN2(lastLevel, tObj->MaxLevel);
|
||||||
|
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GL_TEXTURE_RECTANGLE_NV:
|
||||||
|
case GL_TEXTURE_4D_SGIS:
|
||||||
|
firstLevel = lastLevel = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save these values */
|
||||||
|
intelObj->firstLevel = firstLevel;
|
||||||
|
intelObj->lastLevel = lastLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void copy_image_data_to_tree( struct intel_context *intel,
|
||||||
|
struct intel_texture_object *intelObj,
|
||||||
|
struct intel_texture_image *intelImage )
|
||||||
|
{
|
||||||
|
if (intelImage->mt) {
|
||||||
|
/* Copy potentially with the blitter:
|
||||||
|
*/
|
||||||
|
intel_miptree_image_copy(intel,
|
||||||
|
intelObj->mt,
|
||||||
|
intelImage->face,
|
||||||
|
intelImage->level,
|
||||||
|
intelImage->mt);
|
||||||
|
|
||||||
|
intel_miptree_release(intel, &intelImage->mt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assert(intelImage->base.Data != NULL);
|
||||||
|
|
||||||
|
/* More straightforward upload.
|
||||||
|
*/
|
||||||
|
intel_miptree_image_data(intel,
|
||||||
|
intelObj->mt,
|
||||||
|
intelImage->face,
|
||||||
|
intelImage->level,
|
||||||
|
intelImage->base.Data,
|
||||||
|
intelImage->base.RowStride,
|
||||||
|
intelImage->base.RowStride * intelImage->base.Height);
|
||||||
|
|
||||||
|
free(intelImage->base.Data);
|
||||||
|
intelImage->base.Data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_miptree_reference(&intelImage->mt, intelObj->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
GLuint intel_finalize_mipmap_tree( struct intel_context *intel, GLuint unit )
|
||||||
|
{
|
||||||
|
struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current;
|
||||||
|
struct intel_texture_object *intelObj = intel_texture_object(tObj);
|
||||||
|
|
||||||
|
GLuint face, i;
|
||||||
|
GLuint nr_faces = 0;
|
||||||
|
struct intel_texture_image *firstImage;
|
||||||
|
|
||||||
|
/* We know/require this is true by now:
|
||||||
|
*/
|
||||||
|
assert(intelObj->base.Complete);
|
||||||
|
|
||||||
|
/* What levels must the tree include at a minimum?
|
||||||
|
*/
|
||||||
|
intel_calculate_first_last_level( intelObj );
|
||||||
|
firstImage = intel_texture_image(intelObj->base.Image[0][intelObj->firstLevel]);
|
||||||
|
|
||||||
|
/* Fallback case:
|
||||||
|
*/
|
||||||
|
if (firstImage->base.Border) {
|
||||||
|
if (intelObj->mt) {
|
||||||
|
intel_miptree_release(intel, &intelObj->mt);
|
||||||
|
}
|
||||||
|
return GL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* If both firstImage and intelObj have a tree which can contain
|
||||||
|
* all active images, favour firstImage. Note that because of the
|
||||||
|
* completeness requirement, we know that the image dimensions
|
||||||
|
* will match.
|
||||||
|
*/
|
||||||
|
if (firstImage->mt &&
|
||||||
|
firstImage->mt != intelObj->mt &&
|
||||||
|
firstImage->mt->first_level <= intelObj->firstLevel &&
|
||||||
|
firstImage->mt->last_level >= intelObj->lastLevel) {
|
||||||
|
|
||||||
|
if (intelObj->mt)
|
||||||
|
intel_miptree_release(intel, &intelObj->mt);
|
||||||
|
|
||||||
|
intel_miptree_reference(&intelObj->mt, firstImage->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check tree can hold all active levels. Check tree matches
|
||||||
|
* target, imageFormat, etc.
|
||||||
|
*
|
||||||
|
* XXX: For some layouts (eg i945?), the test might have to be
|
||||||
|
* first_level == firstLevel, as the tree isn't valid except at the
|
||||||
|
* original start level. Hope to get around this by
|
||||||
|
* programming minLod, maxLod, baseLevel into the hardware and
|
||||||
|
* leaving the tree alone.
|
||||||
|
*/
|
||||||
|
if (intelObj->mt &&
|
||||||
|
((intelObj->mt->first_level > intelObj->firstLevel) ||
|
||||||
|
(intelObj->mt->last_level < intelObj->lastLevel) ||
|
||||||
|
(intelObj->mt->internal_format != firstImage->base.InternalFormat))) {
|
||||||
|
intel_miptree_release(intel, &intelObj->mt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* May need to create a new tree:
|
||||||
|
*/
|
||||||
|
if (!intelObj->mt) {
|
||||||
|
intelObj->mt = intel_miptree_create(intel,
|
||||||
|
intelObj->base.Target,
|
||||||
|
firstImage->base.InternalFormat,
|
||||||
|
intelObj->firstLevel,
|
||||||
|
intelObj->lastLevel,
|
||||||
|
firstImage->base.Width,
|
||||||
|
firstImage->base.Height,
|
||||||
|
firstImage->base.Depth,
|
||||||
|
firstImage->base.TexFormat->TexelBytes,
|
||||||
|
firstImage->base.IsCompressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pull in any images not in the object's tree:
|
||||||
|
*/
|
||||||
|
nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||||
|
for (face = 0; face < nr_faces; face++) {
|
||||||
|
for (i = intelObj->firstLevel; i < intelObj->lastLevel; i++) {
|
||||||
|
struct intel_texture_image *intelImage =
|
||||||
|
intel_texture_image(intelObj->base.Image[face][i]);
|
||||||
|
|
||||||
|
/* Need to import images in main memory or held in other trees.
|
||||||
|
*/
|
||||||
|
if (intelObj->mt != intelImage->mt) {
|
||||||
|
copy_image_data_to_tree(intel,
|
||||||
|
intelObj,
|
||||||
|
intelImage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intel_tex_map_images( struct intel_context *intel,
|
||||||
|
struct intel_texture_object *intelObj )
|
||||||
|
{
|
||||||
|
GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||||
|
GLuint face, i;
|
||||||
|
|
||||||
|
DBG("%s\n", __FUNCTION__);
|
||||||
|
|
||||||
|
for (face = 0; face < nr_faces; face++) {
|
||||||
|
for (i = intelObj->firstLevel; i < intelObj->lastLevel; i++) {
|
||||||
|
struct intel_texture_image *intelImage =
|
||||||
|
intel_texture_image(intelObj->base.Image[face][i]);
|
||||||
|
|
||||||
|
/* XXX: Fallbacks will fail for 3d textures because core mesa
|
||||||
|
* doesn't have a place to put ImageStride -- assumes each
|
||||||
|
* teximage's depth slices are packed contiguously. This
|
||||||
|
* isn't true for i915.
|
||||||
|
*/
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intelImage->base.Data =
|
||||||
|
intel_miptree_image_map(intel,
|
||||||
|
intelImage->mt,
|
||||||
|
intelImage->face,
|
||||||
|
intelImage->level,
|
||||||
|
&intelImage->base.RowStride,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void intel_tex_unmap_images( struct intel_context *intel,
|
||||||
|
struct intel_texture_object *intelObj )
|
||||||
|
{
|
||||||
|
GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||||
|
GLuint face, i;
|
||||||
|
|
||||||
|
for (face = 0; face < nr_faces; face++) {
|
||||||
|
for (i = intelObj->firstLevel; i < intelObj->lastLevel; i++) {
|
||||||
|
struct intel_texture_image *intelImage =
|
||||||
|
intel_texture_image(intelObj->base.Image[face][i]);
|
||||||
|
|
||||||
|
if (intelImage->mt) {
|
||||||
|
intel_miptree_image_unmap(intel, intelImage->mt);
|
||||||
|
intelImage->base.Data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,14 +38,108 @@
|
|||||||
#include "tnl/t_vertex.h"
|
#include "tnl/t_vertex.h"
|
||||||
|
|
||||||
#include "intel_screen.h"
|
#include "intel_screen.h"
|
||||||
|
#include "intel_context.h"
|
||||||
#include "intel_tris.h"
|
#include "intel_tris.h"
|
||||||
#include "intel_batchbuffer.h"
|
#include "intel_batchbuffer.h"
|
||||||
#include "intel_reg.h"
|
#include "intel_reg.h"
|
||||||
#include "intel_span.h"
|
#include "intel_span.h"
|
||||||
|
#include "intel_tex.h"
|
||||||
|
|
||||||
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim );
|
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim );
|
||||||
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
|
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim );
|
||||||
|
|
||||||
|
/* The simplest but least-good technique for integrating new buffer
|
||||||
|
* management:
|
||||||
|
*
|
||||||
|
* LOCK_HARDWARE
|
||||||
|
* validate_buffers
|
||||||
|
* emit_state to batch
|
||||||
|
* emit_vertices to batch
|
||||||
|
* flush batch
|
||||||
|
* fence_buffers
|
||||||
|
* UNLOCK_HARDWARE
|
||||||
|
*
|
||||||
|
* Will look later at ways to get the emit_state and emit_vertices out
|
||||||
|
* of the locked region - vertex buffers, second batch buffer for
|
||||||
|
* primitives, relocation fixups for texture addresses.
|
||||||
|
*/
|
||||||
|
static void intel_flush_inline_primitive( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
GLuint used = intel->batch->ptr - intel->prim.start_ptr;
|
||||||
|
|
||||||
|
assert(intel->prim.primitive != ~0);
|
||||||
|
|
||||||
|
if (used < 8)
|
||||||
|
goto do_discard;
|
||||||
|
|
||||||
|
*(int *)intel->prim.start_ptr = (_3DPRIMITIVE |
|
||||||
|
intel->prim.primitive |
|
||||||
|
(used/4-2));
|
||||||
|
|
||||||
|
goto finished;
|
||||||
|
|
||||||
|
do_discard:
|
||||||
|
intel->batch->ptr -= used;
|
||||||
|
|
||||||
|
finished:
|
||||||
|
intel->prim.primitive = ~0;
|
||||||
|
intel->prim.start_ptr = 0;
|
||||||
|
intel->prim.flush = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Emit a primitive referencing vertices in a vertex buffer.
|
||||||
|
*/
|
||||||
|
void intelStartInlinePrimitive( struct intel_context *intel,
|
||||||
|
GLuint prim,
|
||||||
|
GLuint batch_flags )
|
||||||
|
{
|
||||||
|
BATCH_LOCALS;
|
||||||
|
|
||||||
|
/* Emit a slot which will be filled with the inline primitive
|
||||||
|
* command later.
|
||||||
|
*/
|
||||||
|
BEGIN_BATCH(2, batch_flags);
|
||||||
|
OUT_BATCH( 0 );
|
||||||
|
|
||||||
|
intel->prim.start_ptr = intel->batch->ptr;
|
||||||
|
intel->prim.primitive = prim;
|
||||||
|
intel->prim.flush = intel_flush_inline_primitive;
|
||||||
|
|
||||||
|
OUT_BATCH( 0 );
|
||||||
|
ADVANCE_BATCH();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void intelWrapInlinePrimitive( struct intel_context *intel )
|
||||||
|
{
|
||||||
|
GLuint prim = intel->prim.primitive;
|
||||||
|
GLuint batchflags = intel->batch->flags;
|
||||||
|
|
||||||
|
intel_flush_inline_primitive(intel);
|
||||||
|
intel_batchbuffer_flush(intel->batch);
|
||||||
|
|
||||||
|
intel->vtbl.emit_state( intel );
|
||||||
|
intelStartInlinePrimitive( intel, prim, batchflags ); /* ??? */
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint *intelExtendInlinePrimitive( struct intel_context *intel,
|
||||||
|
GLuint dwords )
|
||||||
|
{
|
||||||
|
GLuint sz = dwords * sizeof(GLuint);
|
||||||
|
GLuint *ptr;
|
||||||
|
|
||||||
|
if (intel_batchbuffer_space(intel->batch) < sz)
|
||||||
|
intelWrapInlinePrimitive( intel );
|
||||||
|
|
||||||
|
ptr = (GLuint *)intel->batch->ptr;
|
||||||
|
intel->batch->ptr += sz;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Emit primitives as inline vertices *
|
* Emit primitives as inline vertices *
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
@@ -63,22 +157,18 @@ do { \
|
|||||||
#else
|
#else
|
||||||
#define COPY_DWORDS( j, vb, vertsize, v ) \
|
#define COPY_DWORDS( j, vb, vertsize, v ) \
|
||||||
do { \
|
do { \
|
||||||
if (0) fprintf(stderr, "\n"); \
|
|
||||||
for ( j = 0 ; j < vertsize ; j++ ) { \
|
for ( j = 0 ; j < vertsize ; j++ ) { \
|
||||||
if (0) fprintf(stderr, " -- v(%d): %x/%f\n",j, \
|
|
||||||
((GLuint *)v)[j], \
|
|
||||||
((GLfloat *)v)[j]); \
|
|
||||||
vb[j] = ((GLuint *)v)[j]; \
|
vb[j] = ((GLuint *)v)[j]; \
|
||||||
} \
|
} \
|
||||||
vb += vertsize; \
|
vb += vertsize; \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void __inline__ intel_draw_quad( intelContextPtr intel,
|
static void intel_draw_quad( struct intel_context *intel,
|
||||||
intelVertexPtr v0,
|
intelVertexPtr v0,
|
||||||
intelVertexPtr v1,
|
intelVertexPtr v1,
|
||||||
intelVertexPtr v2,
|
intelVertexPtr v2,
|
||||||
intelVertexPtr v3 )
|
intelVertexPtr v3 )
|
||||||
{
|
{
|
||||||
GLuint vertsize = intel->vertex_size;
|
GLuint vertsize = intel->vertex_size;
|
||||||
GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize );
|
GLuint *vb = intelExtendInlinePrimitive( intel, 6 * vertsize );
|
||||||
@@ -92,10 +182,10 @@ static void __inline__ intel_draw_quad( intelContextPtr intel,
|
|||||||
COPY_DWORDS( j, vb, vertsize, v3 );
|
COPY_DWORDS( j, vb, vertsize, v3 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __inline__ intel_draw_triangle( intelContextPtr intel,
|
static void intel_draw_triangle( struct intel_context *intel,
|
||||||
intelVertexPtr v0,
|
intelVertexPtr v0,
|
||||||
intelVertexPtr v1,
|
intelVertexPtr v1,
|
||||||
intelVertexPtr v2 )
|
intelVertexPtr v2 )
|
||||||
{
|
{
|
||||||
GLuint vertsize = intel->vertex_size;
|
GLuint vertsize = intel->vertex_size;
|
||||||
GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize );
|
GLuint *vb = intelExtendInlinePrimitive( intel, 3 * vertsize );
|
||||||
@@ -107,9 +197,9 @@ static void __inline__ intel_draw_triangle( intelContextPtr intel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline__ void intel_draw_line( intelContextPtr intel,
|
static void intel_draw_line( struct intel_context *intel,
|
||||||
intelVertexPtr v0,
|
intelVertexPtr v0,
|
||||||
intelVertexPtr v1 )
|
intelVertexPtr v1 )
|
||||||
{
|
{
|
||||||
GLuint vertsize = intel->vertex_size;
|
GLuint vertsize = intel->vertex_size;
|
||||||
GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize );
|
GLuint *vb = intelExtendInlinePrimitive( intel, 2 * vertsize );
|
||||||
@@ -120,8 +210,8 @@ static __inline__ void intel_draw_line( intelContextPtr intel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static __inline__ void intel_draw_point( intelContextPtr intel,
|
static void intel_draw_point( struct intel_context *intel,
|
||||||
intelVertexPtr v0 )
|
intelVertexPtr v0 )
|
||||||
{
|
{
|
||||||
GLuint vertsize = intel->vertex_size;
|
GLuint vertsize = intel->vertex_size;
|
||||||
GLuint *vb = intelExtendInlinePrimitive( intel, vertsize );
|
GLuint *vb = intelExtendInlinePrimitive( intel, vertsize );
|
||||||
@@ -140,7 +230,7 @@ static __inline__ void intel_draw_point( intelContextPtr intel,
|
|||||||
* Fixup for ARB_point_parameters *
|
* Fixup for ARB_point_parameters *
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 )
|
static void intel_atten_point( struct intel_context *intel, intelVertexPtr v0 )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
GLfloat psz[4], col[4], restore_psz, restore_alpha;
|
GLfloat psz[4], col[4], restore_psz, restore_alpha;
|
||||||
@@ -189,7 +279,7 @@ static void intel_atten_point( intelContextPtr intel, intelVertexPtr v0 )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void intel_wpos_triangle( intelContextPtr intel,
|
static void intel_wpos_triangle( struct intel_context *intel,
|
||||||
intelVertexPtr v0,
|
intelVertexPtr v0,
|
||||||
intelVertexPtr v1,
|
intelVertexPtr v1,
|
||||||
intelVertexPtr v2 )
|
intelVertexPtr v2 )
|
||||||
@@ -205,7 +295,7 @@ static void intel_wpos_triangle( intelContextPtr intel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void intel_wpos_line( intelContextPtr intel,
|
static void intel_wpos_line( struct intel_context *intel,
|
||||||
intelVertexPtr v0,
|
intelVertexPtr v0,
|
||||||
intelVertexPtr v1 )
|
intelVertexPtr v1 )
|
||||||
{
|
{
|
||||||
@@ -219,7 +309,7 @@ static void intel_wpos_line( intelContextPtr intel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void intel_wpos_point( intelContextPtr intel,
|
static void intel_wpos_point( struct intel_context *intel,
|
||||||
intelVertexPtr v0 )
|
intelVertexPtr v0 )
|
||||||
{
|
{
|
||||||
GLuint offset = intel->wpos_offset;
|
GLuint offset = intel->wpos_offset;
|
||||||
@@ -349,7 +439,7 @@ do { \
|
|||||||
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
|
#define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
|
||||||
|
|
||||||
#define LOCAL_VARS(n) \
|
#define LOCAL_VARS(n) \
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx); \
|
struct intel_context *intel = intel_context(ctx); \
|
||||||
GLuint color[n], spec[n]; \
|
GLuint color[n], spec[n]; \
|
||||||
GLuint coloroffset = intel->coloroffset; \
|
GLuint coloroffset = intel->coloroffset; \
|
||||||
GLboolean specoffset = intel->specoffset; \
|
GLboolean specoffset = intel->specoffset; \
|
||||||
@@ -481,7 +571,7 @@ static void init_rast_tab( void )
|
|||||||
* primitives.
|
* primitives.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
intel_fallback_tri( intelContextPtr intel,
|
intel_fallback_tri( struct intel_context *intel,
|
||||||
intelVertex *v0,
|
intelVertex *v0,
|
||||||
intelVertex *v1,
|
intelVertex *v1,
|
||||||
intelVertex *v2 )
|
intelVertex *v2 )
|
||||||
@@ -502,7 +592,7 @@ intel_fallback_tri( intelContextPtr intel,
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
intel_fallback_line( intelContextPtr intel,
|
intel_fallback_line( struct intel_context *intel,
|
||||||
intelVertex *v0,
|
intelVertex *v0,
|
||||||
intelVertex *v1 )
|
intelVertex *v1 )
|
||||||
{
|
{
|
||||||
@@ -520,22 +610,6 @@ intel_fallback_line( intelContextPtr intel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
intel_fallback_point( intelContextPtr intel,
|
|
||||||
intelVertex *v0 )
|
|
||||||
{
|
|
||||||
GLcontext *ctx = &intel->ctx;
|
|
||||||
SWvertex v[1];
|
|
||||||
|
|
||||||
if (0)
|
|
||||||
fprintf(stderr, "\n%s\n", __FUNCTION__);
|
|
||||||
|
|
||||||
_swsetup_Translate( ctx, v0, &v[0] );
|
|
||||||
intelSpanRenderStart( ctx );
|
|
||||||
_swrast_Point( ctx, &v[0] );
|
|
||||||
intelSpanRenderFinish( ctx );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@@ -552,7 +626,7 @@ intel_fallback_point( intelContextPtr intel,
|
|||||||
#define INIT(x) intelRenderPrimitive( ctx, x )
|
#define INIT(x) intelRenderPrimitive( ctx, x )
|
||||||
#undef LOCAL_VARS
|
#undef LOCAL_VARS
|
||||||
#define LOCAL_VARS \
|
#define LOCAL_VARS \
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx); \
|
struct intel_context *intel = intel_context(ctx); \
|
||||||
GLubyte *vertptr = (GLubyte *)intel->verts; \
|
GLubyte *vertptr = (GLubyte *)intel->verts; \
|
||||||
const GLuint vertsize = intel->vertex_size; \
|
const GLuint vertsize = intel->vertex_size; \
|
||||||
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
|
const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
|
||||||
@@ -578,7 +652,7 @@ intel_fallback_point( intelContextPtr intel,
|
|||||||
static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
|
static void intelRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
|
||||||
GLuint n )
|
GLuint n )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
|
||||||
GLuint prim = intel->render_primitive;
|
GLuint prim = intel->render_primitive;
|
||||||
@@ -609,7 +683,7 @@ static void intelRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj )
|
|||||||
static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
|
static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
|
||||||
GLuint n )
|
GLuint n )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT( ctx );
|
struct intel_context *intel = intel_context( ctx );
|
||||||
const GLuint vertsize = intel->vertex_size;
|
const GLuint vertsize = intel->vertex_size;
|
||||||
GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize );
|
GLuint *vb = intelExtendInlinePrimitive( intel, (n-2) * 3 * vertsize );
|
||||||
GLubyte *vertptr = (GLubyte *)intel->verts;
|
GLubyte *vertptr = (GLubyte *)intel->verts;
|
||||||
@@ -630,17 +704,13 @@ static void intelFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define POINT_FALLBACK (0)
|
#define ANY_FALLBACK_FLAGS (DD_LINE_STIPPLE | DD_TRI_STIPPLE | DD_POINT_ATTEN)
|
||||||
#define LINE_FALLBACK (DD_LINE_STIPPLE)
|
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_TRI_UNFILLED)
|
||||||
#define TRI_FALLBACK (0)
|
|
||||||
#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK|\
|
|
||||||
DD_TRI_STIPPLE|DD_POINT_ATTEN)
|
|
||||||
#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED)
|
|
||||||
|
|
||||||
void intelChooseRenderState(GLcontext *ctx)
|
void intelChooseRenderState(GLcontext *ctx)
|
||||||
{
|
{
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
GLuint flags = ctx->_TriangleCaps;
|
GLuint flags = ctx->_TriangleCaps;
|
||||||
struct fragment_program *fprog = ctx->FragmentProgram._Current;
|
struct fragment_program *fprog = ctx->FragmentProgram._Current;
|
||||||
GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS));
|
GLboolean have_wpos = (fprog && (fprog->Base.InputsRead & FRAG_BIT_WPOS));
|
||||||
@@ -672,19 +742,14 @@ void intelChooseRenderState(GLcontext *ctx)
|
|||||||
intel->draw_tri = intel_draw_triangle;
|
intel->draw_tri = intel_draw_triangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Hook in fallbacks for specific primitives.
|
/* Hook in fallbacks for specific primitives.
|
||||||
*/
|
*/
|
||||||
if (flags & ANY_FALLBACK_FLAGS)
|
if (flags & ANY_FALLBACK_FLAGS)
|
||||||
{
|
{
|
||||||
if (flags & POINT_FALLBACK)
|
if (flags & DD_LINE_STIPPLE)
|
||||||
intel->draw_point = intel_fallback_point;
|
|
||||||
|
|
||||||
if (flags & LINE_FALLBACK)
|
|
||||||
intel->draw_line = intel_fallback_line;
|
intel->draw_line = intel_fallback_line;
|
||||||
|
|
||||||
if (flags & TRI_FALLBACK)
|
|
||||||
intel->draw_tri = intel_fallback_tri;
|
|
||||||
|
|
||||||
if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple)
|
if ((flags & DD_TRI_STIPPLE) && !intel->hw_stipple)
|
||||||
intel->draw_tri = intel_fallback_tri;
|
intel->draw_tri = intel_fallback_tri;
|
||||||
|
|
||||||
@@ -693,6 +758,8 @@ void intelChooseRenderState(GLcontext *ctx)
|
|||||||
|
|
||||||
index |= INTEL_FALLBACK_BIT;
|
index |= INTEL_FALLBACK_BIT;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intel->RenderIndex != index) {
|
if (intel->RenderIndex != index) {
|
||||||
@@ -740,7 +807,7 @@ static const GLenum reduced_prim[GL_POLYGON+1] = {
|
|||||||
|
|
||||||
static void intelRunPipeline( GLcontext *ctx )
|
static void intelRunPipeline( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
|
||||||
if (intel->NewGLState) {
|
if (intel->NewGLState) {
|
||||||
if (intel->NewGLState & _NEW_TEXTURE) {
|
if (intel->NewGLState & _NEW_TEXTURE) {
|
||||||
@@ -760,13 +827,21 @@ static void intelRunPipeline( GLcontext *ctx )
|
|||||||
|
|
||||||
static void intelRenderStart( GLcontext *ctx )
|
static void intelRenderStart( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
INTEL_CONTEXT(ctx)->vtbl.render_start( INTEL_CONTEXT(ctx) );
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
|
||||||
|
intel->vtbl.render_start( intel_context(ctx) );
|
||||||
|
intel->vtbl.emit_state( intel );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void intelRenderFinish( GLcontext *ctx )
|
static void intelRenderFinish( GLcontext *ctx )
|
||||||
{
|
{
|
||||||
if (INTEL_CONTEXT(ctx)->RenderIndex & INTEL_FALLBACK_BIT)
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
|
||||||
|
if (intel->RenderIndex & INTEL_FALLBACK_BIT)
|
||||||
_swrast_flush( ctx );
|
_swrast_flush( ctx );
|
||||||
|
|
||||||
|
if (intel->prim.flush)
|
||||||
|
intel->prim.flush(intel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -777,7 +852,7 @@ static void intelRenderFinish( GLcontext *ctx )
|
|||||||
*/
|
*/
|
||||||
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
|
static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
fprintf(stderr, "%s %s %x\n", __FUNCTION__,
|
fprintf(stderr, "%s %s %x\n", __FUNCTION__,
|
||||||
@@ -788,111 +863,175 @@ static void intelRasterPrimitive( GLcontext *ctx, GLenum rprim, GLuint hwprim )
|
|||||||
/* Start a new primitive. Arrange to have it flushed later on.
|
/* Start a new primitive. Arrange to have it flushed later on.
|
||||||
*/
|
*/
|
||||||
if (hwprim != intel->prim.primitive)
|
if (hwprim != intel->prim.primitive)
|
||||||
intelStartInlinePrimitive( intel, hwprim );
|
intelStartInlinePrimitive( intel, hwprim, INTEL_BATCH_CLIPRECTS );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
|
static void intelRenderPrimitive( GLcontext *ctx, GLenum prim )
|
||||||
{
|
{
|
||||||
intelContextPtr intel = INTEL_CONTEXT(ctx);
|
struct intel_context *intel = intel_context(ctx);
|
||||||
|
|
||||||
if (0)
|
if (0)
|
||||||
fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
|
fprintf(stderr, "%s %s\n", __FUNCTION__, _mesa_lookup_enum_by_nr(prim));
|
||||||
|
|
||||||
/* Let some clipping routines know which primitive they're dealing
|
/* Let some clipping routines know which primitive they're dealing
|
||||||
* with.
|
* with.
|
||||||
*/
|
*/
|
||||||
intel->render_primitive = prim;
|
intel->render_primitive = prim;
|
||||||
|
|
||||||
/* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
|
/* Shortcircuit this when called from t_dd_rendertmp.h for unfilled
|
||||||
* triangles. The rasterized primitive will always be reset by
|
* triangles. The rasterized primitive will always be reset by
|
||||||
* lower level functions in that case, potentially pingponging the
|
* lower level functions in that case, potentially pingponging the
|
||||||
* state:
|
* state:
|
||||||
*/
|
*/
|
||||||
if (reduced_prim[prim] == GL_TRIANGLES &&
|
if (reduced_prim[prim] == GL_TRIANGLES &&
|
||||||
(ctx->_TriangleCaps & DD_TRI_UNFILLED))
|
(ctx->_TriangleCaps & DD_TRI_UNFILLED))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Set some primitive-dependent state and Start? a new primitive.
|
/* Set some primitive-dependent state and Start? a new primitive.
|
||||||
*/
|
*/
|
||||||
intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
|
intelRasterPrimitive( ctx, reduced_prim[prim], hw_prim[prim] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Transition to/from hardware rasterization. */
|
/* Transition to/from hardware rasterization. */
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
static char *fallbackStrings[] = {
|
static char *fallbackStrings[] = {
|
||||||
"Texture",
|
"Texture",
|
||||||
"Draw buffer",
|
"Draw buffer",
|
||||||
"Read buffer",
|
"Read buffer",
|
||||||
"Color mask",
|
"Color mask",
|
||||||
"Render mode",
|
"Render mode",
|
||||||
"Stencil",
|
"Stencil",
|
||||||
"Stipple",
|
"Stipple",
|
||||||
"User disable"
|
"User disable"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static char *getFallbackString(GLuint bit)
|
static char *getFallbackString(GLuint bit)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (bit > 1) {
|
while (bit > 1) {
|
||||||
i++;
|
i++;
|
||||||
bit >>= 1;
|
bit >>= 1;
|
||||||
}
|
}
|
||||||
return fallbackStrings[i];
|
return fallbackStrings[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void intelFallback( intelContextPtr intel, GLuint bit, GLboolean mode )
|
void intelFallback( struct intel_context *intel, GLuint bit, GLboolean mode )
|
||||||
{
|
{
|
||||||
GLcontext *ctx = &intel->ctx;
|
GLcontext *ctx = &intel->ctx;
|
||||||
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
TNLcontext *tnl = TNL_CONTEXT(ctx);
|
||||||
GLuint oldfallback = intel->Fallback;
|
GLuint oldfallback = intel->Fallback;
|
||||||
|
|
||||||
if (mode) {
|
if (mode) {
|
||||||
intel->Fallback |= bit;
|
intel->Fallback |= bit;
|
||||||
if (oldfallback == 0) {
|
if (oldfallback == 0) {
|
||||||
intelFlush(ctx);
|
intelFlush(ctx);
|
||||||
if (INTEL_DEBUG & DEBUG_FALLBACKS)
|
if (INTEL_DEBUG & DEBUG_FALLBACKS)
|
||||||
fprintf(stderr, "ENTER FALLBACK %x: %s\n",
|
fprintf(stderr, "ENTER FALLBACK %x: %s\n",
|
||||||
bit, getFallbackString( bit ));
|
bit, getFallbackString( bit ));
|
||||||
_swsetup_Wakeup( ctx );
|
_swsetup_Wakeup( ctx );
|
||||||
intel->RenderIndex = ~0;
|
intel->RenderIndex = ~0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
intel->Fallback &= ~bit;
|
intel->Fallback &= ~bit;
|
||||||
if (oldfallback == bit) {
|
if (oldfallback == bit) {
|
||||||
_swrast_flush( ctx );
|
_swrast_flush( ctx );
|
||||||
if (INTEL_DEBUG & DEBUG_FALLBACKS)
|
if (INTEL_DEBUG & DEBUG_FALLBACKS)
|
||||||
fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
|
fprintf(stderr, "LEAVE FALLBACK %s\n", getFallbackString( bit ));
|
||||||
tnl->Driver.Render.Start = intelRenderStart;
|
tnl->Driver.Render.Start = intelRenderStart;
|
||||||
tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive;
|
tnl->Driver.Render.PrimitiveNotify = intelRenderPrimitive;
|
||||||
tnl->Driver.Render.Finish = intelRenderFinish;
|
tnl->Driver.Render.Finish = intelRenderFinish;
|
||||||
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
|
||||||
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
|
||||||
tnl->Driver.Render.Interp = _tnl_interp;
|
tnl->Driver.Render.Interp = _tnl_interp;
|
||||||
|
|
||||||
_tnl_invalidate_vertex_state( ctx, ~0 );
|
_tnl_invalidate_vertex_state( ctx, ~0 );
|
||||||
_tnl_invalidate_vertices( ctx, ~0 );
|
_tnl_invalidate_vertices( ctx, ~0 );
|
||||||
_tnl_install_attrs( ctx,
|
_tnl_install_attrs( ctx,
|
||||||
intel->vertex_attrs,
|
intel->vertex_attrs,
|
||||||
intel->vertex_attr_count,
|
intel->vertex_attr_count,
|
||||||
intel->ViewportMatrix.m, 0 );
|
intel->ViewportMatrix.m, 0 );
|
||||||
|
|
||||||
intel->NewGLState |= _INTEL_NEW_RENDERSTATE;
|
intel->NewGLState |= _INTEL_NEW_RENDERSTATE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**********************************************************************/
|
||||||
|
/* Used only with the metaops callbacks. */
|
||||||
|
/**********************************************************************/
|
||||||
|
void intel_meta_draw_quad(struct intel_context *intel,
|
||||||
|
GLfloat x0, GLfloat x1,
|
||||||
|
GLfloat y0, GLfloat y1,
|
||||||
|
GLfloat z,
|
||||||
|
GLuint color,
|
||||||
|
GLfloat s0, GLfloat s1,
|
||||||
|
GLfloat t0, GLfloat t1,
|
||||||
|
GLuint flags)
|
||||||
|
{
|
||||||
|
union fi *vb;
|
||||||
|
|
||||||
|
if (0)
|
||||||
|
fprintf(stderr, "%s: %f,%f-%f,%f 0x%x %f,%f-%f,%f\n",
|
||||||
|
__FUNCTION__,
|
||||||
|
x0,y0,x1,y1,color,s0,t0,s1,t1);
|
||||||
|
|
||||||
|
intel->vtbl.emit_state( intel );
|
||||||
|
|
||||||
|
intelStartInlinePrimitive( intel, PRIM3D_TRIFAN, flags );
|
||||||
|
vb = (union fi *)intelExtendInlinePrimitive( intel, 4 * 6 );
|
||||||
|
|
||||||
|
|
||||||
|
/* initial vertex, left bottom */
|
||||||
|
vb[0].f = x0;
|
||||||
|
vb[1].f = y0;
|
||||||
|
vb[2].f = z;
|
||||||
|
vb[3].i = color;
|
||||||
|
vb[4].f = s0;
|
||||||
|
vb[5].f = t0;
|
||||||
|
vb += 6;
|
||||||
|
|
||||||
|
/* right bottom */
|
||||||
|
vb[0].f = x1;
|
||||||
|
vb[1].f = y0;
|
||||||
|
vb[2].f = z;
|
||||||
|
vb[3].i = color;
|
||||||
|
vb[4].f = s1;
|
||||||
|
vb[5].f = t0;
|
||||||
|
vb += 6;
|
||||||
|
|
||||||
|
/* right top */
|
||||||
|
vb[0].f = x1;
|
||||||
|
vb[1].f = y1;
|
||||||
|
vb[2].f = z;
|
||||||
|
vb[3].i = color;
|
||||||
|
vb[4].f = s1;
|
||||||
|
vb[5].f = t1;
|
||||||
|
vb += 6;
|
||||||
|
|
||||||
|
/* left top */
|
||||||
|
vb[0].f = x0;
|
||||||
|
vb[1].f = y1;
|
||||||
|
vb[2].f = z;
|
||||||
|
vb[3].i = color;
|
||||||
|
vb[4].f = s0;
|
||||||
|
vb[5].f = t1;
|
||||||
|
|
||||||
|
if (intel->prim.flush)
|
||||||
|
intel->prim.flush(intel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* Initialization. */
|
/* Initialization. */
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
|
#define _INTEL_NEW_RENDERSTATE (_DD_NEW_LINE_STIPPLE | \
|
||||||
_DD_NEW_TRI_UNFILLED | \
|
_DD_NEW_TRI_UNFILLED | \
|
||||||
_DD_NEW_TRI_LIGHT_TWOSIDE | \
|
_DD_NEW_TRI_LIGHT_TWOSIDE | \
|
||||||
@@ -40,7 +42,23 @@
|
|||||||
|
|
||||||
extern void intelInitTriFuncs( GLcontext *ctx );
|
extern void intelInitTriFuncs( GLcontext *ctx );
|
||||||
|
|
||||||
extern void intelPrintRenderState( const char *msg, GLuint state );
|
|
||||||
extern void intelChooseRenderState( GLcontext *ctx );
|
extern void intelChooseRenderState( GLcontext *ctx );
|
||||||
|
|
||||||
|
extern void intelStartInlinePrimitive( struct intel_context *intel, GLuint prim, GLuint flags );
|
||||||
|
extern void intelWrapInlinePrimitive( struct intel_context *intel );
|
||||||
|
|
||||||
|
GLuint *intelExtendInlinePrimitive( struct intel_context *intel,
|
||||||
|
GLuint dwords );
|
||||||
|
|
||||||
|
|
||||||
|
void intel_meta_draw_quad(struct intel_context *intel,
|
||||||
|
GLfloat x0, GLfloat x1,
|
||||||
|
GLfloat y0, GLfloat y1,
|
||||||
|
GLfloat z,
|
||||||
|
GLuint color,
|
||||||
|
GLfloat s0, GLfloat s1,
|
||||||
|
GLfloat t0, GLfloat t1,
|
||||||
|
GLuint flags );
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "colormac.h"
|
#include "colormac.h"
|
||||||
#include "mtypes.h"
|
#include "mtypes.h"
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
|
#include "teximage.h"
|
||||||
#include "swrast.h"
|
#include "swrast.h"
|
||||||
#include "s_blend.h"
|
#include "s_blend.h"
|
||||||
#include "s_context.h"
|
#include "s_context.h"
|
||||||
@@ -368,6 +369,83 @@ _swrast_validate_blend_func( GLcontext *ctx, GLuint n,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure we have texture image data for all the textures we may need
|
||||||
|
* for subsequent rendering.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
_swrast_validate_texture_images(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
SWcontext *swrast = SWRAST_CONTEXT(ctx);
|
||||||
|
GLuint u;
|
||||||
|
|
||||||
|
if (!swrast->ValidateTextureImage || !ctx->Texture._EnabledUnits) {
|
||||||
|
/* no textures enabled, or no way to validate images! */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
|
||||||
|
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||||
|
struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;
|
||||||
|
ASSERT(texObj);
|
||||||
|
if (texObj) {
|
||||||
|
GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||||
|
GLuint face;
|
||||||
|
for (face = 0; face < numFaces; face++) {
|
||||||
|
GLuint lvl;
|
||||||
|
for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
|
||||||
|
struct gl_texture_image *texImg = texObj->Image[face][lvl];
|
||||||
|
if (texImg && !texImg->Data) {
|
||||||
|
swrast->ValidateTextureImage(ctx, texObj, face, lvl);
|
||||||
|
ASSERT(texObj->Image[face][lvl]->Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free the texture image data attached to all currently enabled
|
||||||
|
* textures. Meant to be called by device drivers when transitioning
|
||||||
|
* from software to hardware rendering.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
_swrast_eject_texture_images(GLcontext *ctx)
|
||||||
|
{
|
||||||
|
GLuint u;
|
||||||
|
|
||||||
|
if (!ctx->Texture._EnabledUnits) {
|
||||||
|
/* no textures enabled */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) {
|
||||||
|
if (ctx->Texture.Unit[u]._ReallyEnabled) {
|
||||||
|
struct gl_texture_object *texObj = ctx->Texture.Unit[u]._Current;
|
||||||
|
ASSERT(texObj);
|
||||||
|
if (texObj) {
|
||||||
|
GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
|
||||||
|
GLuint face;
|
||||||
|
for (face = 0; face < numFaces; face++) {
|
||||||
|
GLuint lvl;
|
||||||
|
for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
|
||||||
|
struct gl_texture_image *texImg = texObj->Image[face][lvl];
|
||||||
|
if (texImg && texImg->Data) {
|
||||||
|
_mesa_free_texmemory(texImg->Data);
|
||||||
|
texImg->Data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_swrast_sleep( GLcontext *ctx, GLbitfield new_state )
|
_swrast_sleep( GLcontext *ctx, GLbitfield new_state )
|
||||||
{
|
{
|
||||||
@@ -452,6 +530,9 @@ _swrast_validate_derived( GLcontext *ctx )
|
|||||||
if (swrast->NewState & _NEW_TEXTURE)
|
if (swrast->NewState & _NEW_TEXTURE)
|
||||||
_swrast_update_texture_samplers( ctx );
|
_swrast_update_texture_samplers( ctx );
|
||||||
|
|
||||||
|
if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
|
||||||
|
_swrast_validate_texture_images( ctx );
|
||||||
|
|
||||||
swrast->NewState = 0;
|
swrast->NewState = 0;
|
||||||
swrast->StateChanges = 0;
|
swrast->StateChanges = 0;
|
||||||
swrast->InvalidateState = _swrast_invalidate_state;
|
swrast->InvalidateState = _swrast_invalidate_state;
|
||||||
|
|||||||
@@ -226,6 +226,11 @@ typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *,
|
|||||||
const SWvertex *, const SWvertex *);
|
const SWvertex *, const SWvertex *);
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*validate_texture_image_func)(GLcontext *ctx,
|
||||||
|
struct gl_texture_object *texObj,
|
||||||
|
GLuint face, GLuint level);
|
||||||
|
|
||||||
|
|
||||||
/** \defgroup Bitmasks
|
/** \defgroup Bitmasks
|
||||||
* Bitmasks to indicate which rasterization options are enabled
|
* Bitmasks to indicate which rasterization options are enabled
|
||||||
* (RasterMask)
|
* (RasterMask)
|
||||||
@@ -354,6 +359,8 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
GLchan *TexelBuffer;
|
GLchan *TexelBuffer;
|
||||||
|
|
||||||
|
validate_texture_image_func ValidateTextureImage;
|
||||||
|
|
||||||
} SWcontext;
|
} SWcontext;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -244,6 +244,10 @@ _swrast_copy_texsubimage3d(GLcontext *ctx,
|
|||||||
GLint x, GLint y, GLsizei width, GLsizei height);
|
GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
_swrast_eject_texture_images(GLcontext *ctx);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The driver interface for the software rasterizer.
|
* The driver interface for the software rasterizer.
|
||||||
* XXX this may go away.
|
* XXX this may go away.
|
||||||
|
|||||||
Reference in New Issue
Block a user