--- /dev/null
+typedef unsigned int GLenum;
+typedef unsigned char GLubyte;
+typedef unsigned int GLuint;
+typedef union {
+ float f;
+ int i;
+} fi_type;
+static __inline__ int IS_INF_OR_NAN(float x)
+{
+ fi_type tmp;
+ tmp.f = x;
+ return !(int)((unsigned int)((tmp.i & 0x7fffffff) - 0x7f800000) >> 31);
+}
+
+typedef enum {
+ MESA_FORMAT_RGBA8888, MESA_FORMAT_RGB888,
+} gl_format;
+typedef enum {
+ FRAG_ATTRIB_WPOS = 0, FRAG_ATTRIB_COL0 = 1, FRAG_ATTRIB_COL1 =
+ 2, FRAG_ATTRIB_FOGC = 3, FRAG_ATTRIB_TEX0 = 4, FRAG_ATTRIB_TEX1 =
+ 5, FRAG_ATTRIB_TEX2 = 6, FRAG_ATTRIB_TEX3 = 7, FRAG_ATTRIB_TEX4 =
+ 8, FRAG_ATTRIB_TEX5 = 9, FRAG_ATTRIB_TEX6 = 10, FRAG_ATTRIB_TEX7 =
+ 11, FRAG_ATTRIB_FACE = 12, FRAG_ATTRIB_PNTC = 13, FRAG_ATTRIB_VAR0 =
+ 14, FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + 16)
+} gl_frag_result;
+struct gl_config {
+ int depthBits;
+};
+struct gl_lightmodel {
+ GLenum ColorControl;
+};
+struct gl_depthbuffer_attrib {
+ GLenum Func;
+ unsigned char Mask;
+};
+struct gl_hint_attrib {
+ GLenum PerspectiveCorrection;
+};
+struct gl_light_attrib {
+ struct gl_lightmodel Model;
+};
+struct gl_polygon_attrib {
+ unsigned char StippleFlag;
+};
+typedef enum {
+ TEXTURE_BUFFER_INDEX, TEXTURE_2D_ARRAY_INDEX, TEXTURE_1D_ARRAY_INDEX,
+ TEXTURE_CUBE_INDEX, TEXTURE_3D_INDEX, TEXTURE_RECT_INDEX,
+ TEXTURE_2D_INDEX, TEXTURE_1D_INDEX, NUM_TEXTURE_TARGETS
+} gl_texture_index;
+struct gl_texture_image {
+ GLuint Border;
+ GLuint Width;
+ GLuint Height;
+ GLuint WidthLog2;
+ unsigned char _IsPowerOfTwo;
+ GLuint RowStride;
+ void *Data;
+};
+typedef enum {
+ MAX_FACES = 6
+} gl_face_index;
+struct gl_sampler_object {
+ GLenum WrapS;
+ GLenum WrapT;
+};
+struct gl_texture_object {
+ struct gl_sampler_object Sampler;
+ int BaseLevel;
+ GLuint _Swizzle;
+ struct gl_texture_image *Image[MAX_FACES][15];
+};
+struct gl_texture_unit {
+ unsigned int _ReallyEnabled;
+ GLenum EnvMode;
+ struct gl_texture_object *CurrentTex[NUM_TEXTURE_TARGETS];
+};
+struct gl_texture_attrib {
+ struct gl_texture_unit Unit[(16 + 16)];
+ unsigned int _EnabledUnits;
+ unsigned int _EnabledCoordUnits;
+};
+struct gl_fragment_program_state {
+ struct gl_fragment_program *_Current;
+};
+struct gl_ati_fragment_shader_state {
+ unsigned char _Enabled;
+};
+struct gl_renderbuffer {
+ void (*PutRowRGB) (struct gl_context * ctx, struct gl_renderbuffer * rb,
+ GLuint count, int x, int y, const void *values);
+};
+struct gl_framebuffer {
+ struct gl_config Visual;
+ struct gl_renderbuffer *_ColorDrawBuffers[8];
+};
+struct gl_context {
+ struct gl_framebuffer *DrawBuffer;
+ struct gl_depthbuffer_attrib Depth;
+ struct gl_hint_attrib Hint;
+ struct gl_light_attrib Light;
+ struct gl_polygon_attrib Polygon;
+ struct gl_texture_attrib Texture;
+ struct gl_fragment_program_state FragmentProgram;
+ struct gl_ati_fragment_shader_state ATIFragmentShader;
+ GLenum RenderMode;
+};
+typedef struct {
+ float attrib[FRAG_ATTRIB_MAX][4];
+} SWvertex;
+typedef struct sw_span {
+ int x, y;
+ GLuint end;
+ float attrStepX[FRAG_ATTRIB_MAX][4];
+ int intTex[2], intTexStep[2];
+} SWspan;
+typedef void (*swrast_tri_func) (struct gl_context * ctx, const SWvertex *,
+ const SWvertex *, const SWvertex *);
+typedef struct {
+ unsigned int _RasterMask;
+ unsigned char _FogEnabled;
+ swrast_tri_func Triangle;
+} SWcontext;
+static void simple_textured_triangle(struct gl_context *ctx,
+ const SWvertex * v0, const SWvertex * v1,
+ const SWvertex * v2)
+{
+ typedef struct {
+ float dx;
+ float dy;
+ int fsx;
+ int fx0;
+ int lines;
+ } EdgeT;
+ EdgeT eMaj;
+ EdgeT eTop;
+ EdgeT eBot;
+ float oneOverArea;
+ const SWvertex *vMin;
+ const SWvertex *vMid;
+ const SWvertex *vMax;
+ const int snapMask = ~(((1 << 11) / (1 << 4)) - 1);
+ int vMin_fx;
+ int vMin_fy;
+ int vMid_fx;
+ int vMid_fy;
+ int vMax_fx;
+ int vMax_fy;
+ SWspan span;
+ const int fy0 =
+ (((int)
+ ((((v0->attrib[FRAG_ATTRIB_WPOS][1] -
+ 0.5F) * ((float)(1 << 11))) >=
+ 0.0F) ? (((v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) *
+ ((float)(1 << 11))) +
+ 0.5F)
+ : (((v0->attrib[FRAG_ATTRIB_WPOS][1] -
+ 0.5F) * ((float)(1 << 11))) - 0.5F)))) & snapMask;
+ const int fy1 =
+ (((int)
+ ((((v1->attrib[FRAG_ATTRIB_WPOS][1] -
+ 0.5F) * ((float)(1 << 11))) >=
+ 0.0F) ? (((v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) *
+ ((float)(1 << 11))) +
+ 0.5F)
+ : (((v1->attrib[FRAG_ATTRIB_WPOS][1] -
+ 0.5F) * ((float)(1 << 11))) - 0.5F)))) & snapMask;
+ const int fy2 =
+ (((int)
+ ((((v2->attrib[FRAG_ATTRIB_WPOS][1] -
+ 0.5F) * ((float)(1 << 11))) >=
+ 0.0F) ? (((v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) *
+ ((float)(1 << 11))) +
+ 0.5F)
+ : (((v2->attrib[FRAG_ATTRIB_WPOS][1] -
+ 0.5F) * ((float)(1 << 11))) - 0.5F)))) & snapMask;
+ if (fy0 <= fy1) {
+ if (fy1 <= fy2) {
+ vMin = v0;
+ vMax = v1;
+ vMin_fy = fy0;
+ }
+ }
+ vMin_fx =
+ (((int)
+ ((((vMin->attrib[FRAG_ATTRIB_WPOS][0] +
+ 0.5F) * ((float)(1 << 11))) >=
+ 0.0F) ? (((vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) *
+ ((float)(1 << 11))) +
+ 0.5F)
+ : (((vMin->attrib[FRAG_ATTRIB_WPOS][0] +
+ 0.5F) * ((float)(1 << 11))) - 0.5F)))) & snapMask;
+ vMid_fx =
+ (((int)
+ ((((vMid->attrib[FRAG_ATTRIB_WPOS][0] +
+ 0.5F) * ((float)(1 << 11))) >=
+ 0.0F) ? (((vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) *
+ ((float)(1 << 11))) +
+ 0.5F)
+ : (((vMid->attrib[FRAG_ATTRIB_WPOS][0] +
+ 0.5F) * ((float)(1 << 11))) - 0.5F)))) & snapMask;
+ eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / ((float)(1 << 11))));
+ eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / ((float)(1 << 11))));
+ eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / ((float)(1 << 11))));
+ eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / ((float)(1 << 11))));
+ const float area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
+ if (IS_INF_OR_NAN(area) || area == 0.0F)
+ return;
+ oneOverArea = 1.0F / area;
+ if (eBot.lines > 0) {
+ eBot.fx0 = vMin_fx;
+ }
+ int scan_from_left_to_right;
+ struct gl_renderbuffer *rb =
+ ctx->DrawBuffer->_ColorDrawBuffers[0];
+ const struct gl_texture_object *obj =
+ ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX];
+ const struct gl_texture_image *texImg =
+ obj->Image[0][obj->BaseLevel];
+ const float twidth = (float) texImg->Width;
+ const int twidth_log2 = texImg->WidthLog2;
+ const GLubyte *texture = (const GLubyte *)texImg->Data;
+ const int smask = texImg->Width - 1;
+ const int tmask = texImg->Height - 1;
+ if (!rb || !texture) {
+ return;
+ }
+ float eMaj_ds =
+ (vMax->attrib[FRAG_ATTRIB_TEX0][0] -
+ vMin->attrib[FRAG_ATTRIB_TEX0][0]) * twidth;
+ float eBot_ds =
+ (vMid->attrib[FRAG_ATTRIB_TEX0][0] -
+ vMin->attrib[FRAG_ATTRIB_TEX0][0]) * twidth;
+ span.attrStepX[FRAG_ATTRIB_TEX0][0] =
+ oneOverArea * (eMaj_ds * eBot.dy -
+ eMaj.dy * eBot_ds);
+ span.intTexStep[0] =
+ (((int)
+ ((((span.attrStepX[FRAG_ATTRIB_TEX0][0]) *
+ ((float)(1 << 11))) >=
+ 0.0F) ? (((span.attrStepX[FRAG_ATTRIB_TEX0][0])
+ * ((float)(1 << 11))) +
+ 0.5F)
+ : (((span.attrStepX[FRAG_ATTRIB_TEX0][0]) *
+ ((float)(1 << 11))) - 0.5F))));
+ int subTriangle;
+ int fxLeftEdge = 0;
+ int fxRightEdge = 0;
+ int sLeft = 0;
+ for (subTriangle = 0; subTriangle <= 1; subTriangle++) {
+ EdgeT *eRight;
+ int lines;
+ if (subTriangle == 0) {
+ if (scan_from_left_to_right) {
+ eRight = &eBot;
+ lines = eRight->lines;
+ } else {
+ eRight = &eMaj;
+ }
+ } else {
+ if (scan_from_left_to_right) {
+ eRight = &eTop;
+ }
+ fxRightEdge = eRight->fsx - 1;
+ }
+ while (lines > 0) {
+ const int right= fxRightEdge >> 11;
+ span.x = fxLeftEdge >> 11;
+ if (right <= span.x)
+ span.end = 0;
+ else
+ span.end = right - span.x;
+ span.intTex[0] = sLeft;
+ if (span.end > 0 && span.y >= 0) {
+ GLuint i;
+ GLubyte rgb[16384][3];
+ for (i = 0;
+ i < span.end;
+ i++) {
+ int s =
+ ((span.
+ intTex[0])
+ >> 11) &
+ smask;
+ int t =
+ ((span.
+ intTex[1])
+ >> 11) &
+ tmask;
+ int pos =
+ (t <<
+ twidth_log2)
+ + s;
+ rgb[i][0] =
+ texture[pos
+ +
+ 2];
+ span.
+ intTex[0] +=
+ span.
+ intTexStep
+ [0];
+ }
+ rb->PutRowRGB(ctx, rb,
+ span.end,
+ span.x,
+ span.y,
+ rgb);
+ }
+ }
+ }
+}
+
+void _swrast_choose_triangle(struct gl_context *ctx)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ if (ctx->RenderMode == 0x1C00) {
+ if (ctx->Texture._EnabledCoordUnits
+ || ctx->FragmentProgram._Current
+ || ctx->ATIFragmentShader._Enabled
+ || _mesa_need_secondary_color(ctx) || swrast->_FogEnabled) {
+ const struct gl_texture_object *texObj2D;
+ const struct gl_texture_image *texImg;
+ GLenum minFilter;
+ GLenum magFilter;
+ GLenum envMode;
+ gl_format format;
+ if (ctx->Texture._EnabledCoordUnits == 0x1
+ && !ctx->FragmentProgram._Current
+ && !ctx->ATIFragmentShader._Enabled
+ && ctx->Texture._EnabledUnits == 0x1
+ && ctx->Texture.Unit[0]._ReallyEnabled ==
+ (1 << TEXTURE_2D_INDEX)
+ && texObj2D->Sampler.WrapS == 0x2901
+ && texObj2D->Sampler.WrapT == 0x2901
+ && texObj2D->_Swizzle ==
+ (((0) << 0) | ((1) << 3) | ((2) << 6) | ((3) << 9))
+ && texImg->_IsPowerOfTwo && texImg->Border == 0
+ && texImg->Width == texImg->RowStride
+ && (format == MESA_FORMAT_RGB888
+ || format == MESA_FORMAT_RGBA8888)
+ && minFilter == magFilter
+ && ctx->Light.Model.ColorControl == 0x81F9
+ && !swrast->_FogEnabled
+ && ctx->Texture.Unit[0].EnvMode != 0x8570
+ && ctx->Texture.Unit[0].EnvMode != 0x8503) {
+ if (ctx->Hint.PerspectiveCorrection == 0x1101) {
+ if (minFilter == 0x2600
+ && format == MESA_FORMAT_RGB888
+ && (envMode == 0x1E01
+ || envMode == 0x2101)
+ &&
+ ((swrast->_RasterMask ==
+ (0x004 | 0x1000)
+ && ctx->Depth.Func == 0x0201
+ && ctx->Depth.Mask == 0x1)
+ || swrast->_RasterMask == 0x1000)
+ && ctx->Polygon.StippleFlag == 0x0
+ && ctx->DrawBuffer->Visual.
+ depthBits <= 16) {
+ if (swrast->_RasterMask ==
+ (0x004 | 0x1000)) {
+ swrast->Triangle =
+ simple_textured_triangle;
+ }
+ }
+ }
+ }
+ }
+ }
+}