⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i915_state.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************** *  * 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 "context.h"#include "macros.h"#include "enums.h"#include "dd.h"#include "tnl/tnl.h"#include "tnl/t_context.h"#include "texmem.h"#include "drivers/common/driverfuncs.h"#include "intel_fbo.h"#include "intel_screen.h"#include "intel_batchbuffer.h"#include "i915_context.h"#include "i915_reg.h"#define FILE_DEBUG_FLAG DEBUG_STATEstatic voidi915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,                        GLuint mask){   struct i915_context *i915 = I915_CONTEXT(ctx);   int test = intel_translate_compare_func(func);   mask = mask & 0xff;   DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,       _mesa_lookup_enum_by_nr(func), ref, mask);   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;   i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |                                           STENCIL_TEST_MASK(mask));   i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK |                                          S5_STENCIL_TEST_FUNC_MASK);   i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) |                                         (test <<                                          S5_STENCIL_TEST_FUNC_SHIFT));}static voidi915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask){   struct i915_context *i915 = I915_CONTEXT(ctx);   DBG("%s : mask 0x%x\n", __FUNCTION__, mask);      mask = mask & 0xff;   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;   i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |                                           STENCIL_WRITE_MASK(mask));}static voidi915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail,                      GLenum zpass){   struct i915_context *i915 = I915_CONTEXT(ctx);   int fop = intel_translate_stencil_op(fail);   int dfop = intel_translate_stencil_op(zfail);   int dpop = intel_translate_stencil_op(zpass);   DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,       _mesa_lookup_enum_by_nr(fail),       _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass));   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |                                          S5_STENCIL_PASS_Z_FAIL_MASK |                                          S5_STENCIL_PASS_Z_PASS_MASK);   i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) |                                         (dfop <<                                          S5_STENCIL_PASS_Z_FAIL_SHIFT) |                                         (dpop <<                                          S5_STENCIL_PASS_Z_PASS_SHIFT));}static voidi915AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref){   struct i915_context *i915 = I915_CONTEXT(ctx);   int test = intel_translate_compare_func(func);   GLubyte refByte;   UNCLAMPED_FLOAT_TO_UBYTE(refByte, ref);   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_ALPHA_TEST_FUNC_MASK |                                          S6_ALPHA_REF_MASK);   i915->state.Ctx[I915_CTXREG_LIS6] |= ((test << S6_ALPHA_TEST_FUNC_SHIFT) |                                         (((GLuint) refByte) <<                                          S6_ALPHA_REF_SHIFT));}/* This function makes sure that the proper enables are * set for LogicOp, Independant Alpha Blend, and Blending. * It needs to be called from numerous places where we * could change the LogicOp or Independant Alpha Blend without subsequent * calls to glEnable. */static voidi915EvalLogicOpBlendState(GLcontext * ctx){   struct i915_context *i915 = I915_CONTEXT(ctx);   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   if (RGBA_LOGICOP_ENABLED(ctx)) {      i915->state.Ctx[I915_CTXREG_LIS5] |= S5_LOGICOP_ENABLE;      i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;   }   else {      i915->state.Ctx[I915_CTXREG_LIS5] &= ~S5_LOGICOP_ENABLE;      if (ctx->Color.BlendEnabled) {         i915->state.Ctx[I915_CTXREG_LIS6] |= S6_CBUF_BLEND_ENABLE;      }      else {         i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_CBUF_BLEND_ENABLE;      }   }}static voidi915BlendColor(GLcontext * ctx, const GLfloat color[4]){   struct i915_context *i915 = I915_CONTEXT(ctx);   GLubyte r, g, b, a;   DBG("%s\n", __FUNCTION__);      UNCLAMPED_FLOAT_TO_UBYTE(r, color[RCOMP]);   UNCLAMPED_FLOAT_TO_UBYTE(g, color[GCOMP]);   UNCLAMPED_FLOAT_TO_UBYTE(b, color[BCOMP]);   UNCLAMPED_FLOAT_TO_UBYTE(a, color[ACOMP]);   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] =      (a << 24) | (r << 16) | (g << 8) | b;}#define DST_BLND_FACT(f) ((f)<<S6_CBUF_DST_BLEND_FACT_SHIFT)#define SRC_BLND_FACT(f) ((f)<<S6_CBUF_SRC_BLEND_FACT_SHIFT)#define DST_ABLND_FACT(f) ((f)<<IAB_DST_FACTOR_SHIFT)#define SRC_ABLND_FACT(f) ((f)<<IAB_SRC_FACTOR_SHIFT)static GLuinttranslate_blend_equation(GLenum mode){   switch (mode) {   case GL_FUNC_ADD:      return BLENDFUNC_ADD;   case GL_MIN:      return BLENDFUNC_MIN;   case GL_MAX:      return BLENDFUNC_MAX;   case GL_FUNC_SUBTRACT:      return BLENDFUNC_SUBTRACT;   case GL_FUNC_REVERSE_SUBTRACT:      return BLENDFUNC_REVERSE_SUBTRACT;   default:      return 0;   }}static voidi915UpdateBlendState(GLcontext * ctx){   struct i915_context *i915 = I915_CONTEXT(ctx);   GLuint iab = (i915->state.Ctx[I915_CTXREG_IAB] &                 ~(IAB_SRC_FACTOR_MASK |                   IAB_DST_FACTOR_MASK |                   (BLENDFUNC_MASK << IAB_FUNC_SHIFT) | IAB_ENABLE));   GLuint lis6 = (i915->state.Ctx[I915_CTXREG_LIS6] &                  ~(S6_CBUF_SRC_BLEND_FACT_MASK |                    S6_CBUF_DST_BLEND_FACT_MASK | S6_CBUF_BLEND_FUNC_MASK));   GLuint eqRGB = ctx->Color.BlendEquationRGB;   GLuint eqA = ctx->Color.BlendEquationA;   GLuint srcRGB = ctx->Color.BlendSrcRGB;   GLuint dstRGB = ctx->Color.BlendDstRGB;   GLuint srcA = ctx->Color.BlendSrcA;   GLuint dstA = ctx->Color.BlendDstA;   if (eqRGB == GL_MIN || eqRGB == GL_MAX) {      srcRGB = dstRGB = GL_ONE;   }   if (eqA == GL_MIN || eqA == GL_MAX) {      srcA = dstA = GL_ONE;   }   lis6 |= SRC_BLND_FACT(intel_translate_blend_factor(srcRGB));   lis6 |= DST_BLND_FACT(intel_translate_blend_factor(dstRGB));   lis6 |= translate_blend_equation(eqRGB) << S6_CBUF_BLEND_FUNC_SHIFT;   iab |= SRC_ABLND_FACT(intel_translate_blend_factor(srcA));   iab |= DST_ABLND_FACT(intel_translate_blend_factor(dstA));   iab |= translate_blend_equation(eqA) << IAB_FUNC_SHIFT;   if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB)      iab |= IAB_ENABLE;   if (iab != i915->state.Ctx[I915_CTXREG_IAB] ||       lis6 != i915->state.Ctx[I915_CTXREG_LIS6]) {      I915_STATECHANGE(i915, I915_UPLOAD_CTX);      i915->state.Ctx[I915_CTXREG_IAB] = iab;      i915->state.Ctx[I915_CTXREG_LIS6] = lis6;   }   /* This will catch a logicop blend equation */   i915EvalLogicOpBlendState(ctx);}static voidi915BlendFuncSeparate(GLcontext * ctx, GLenum srcRGB,                      GLenum dstRGB, GLenum srcA, GLenum dstA){   i915UpdateBlendState(ctx);}static voidi915BlendEquationSeparate(GLcontext * ctx, GLenum eqRGB, GLenum eqA){   i915UpdateBlendState(ctx);}static voidi915DepthFunc(GLcontext * ctx, GLenum func){   struct i915_context *i915 = I915_CONTEXT(ctx);   int test = intel_translate_compare_func(func);   DBG("%s\n", __FUNCTION__);      I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_TEST_FUNC_MASK;   i915->state.Ctx[I915_CTXREG_LIS6] |= test << S6_DEPTH_TEST_FUNC_SHIFT;}static voidi915DepthMask(GLcontext * ctx, GLboolean flag){   struct i915_context *i915 = I915_CONTEXT(ctx);   DBG("%s flag (%d)\n", __FUNCTION__, flag);      I915_STATECHANGE(i915, I915_UPLOAD_CTX);   if (flag && ctx->Depth.Test)      i915->state.Ctx[I915_CTXREG_LIS6] |= S6_DEPTH_WRITE_ENABLE;   else      i915->state.Ctx[I915_CTXREG_LIS6] &= ~S6_DEPTH_WRITE_ENABLE;}/* ============================================================= * Polygon stipple * * The i915 supports a 4x4 stipple natively, GL wants 32x32. * Fortunately stipple is usually a repeating pattern. */static voidi915PolygonStipple(GLcontext * ctx, const GLubyte * mask){   struct i915_context *i915 = I915_CONTEXT(ctx);   const GLubyte *m;   GLubyte p[4];   int i, j, k;   int active = (ctx->Polygon.StippleFlag &&                 i915->intel.reduced_primitive == GL_TRIANGLES);   GLuint newMask;   if (active) {      I915_STATECHANGE(i915, I915_UPLOAD_STIPPLE);      i915->state.Stipple[I915_STPREG_ST1] &= ~ST1_ENABLE;   }   /* Use the already unpacked stipple data from the context rather than the    * uninterpreted mask passed in.    */   mask = (const GLubyte *)ctx->PolygonStipple;   m = mask;   p[0] = mask[12] & 0xf;   p[0] |= p[0] << 4;   p[1] = mask[8] & 0xf;   p[1] |= p[1] << 4;   p[2] = mask[4] & 0xf;   p[2] |= p[2] << 4;   p[3] = mask[0] & 0xf;   p[3] |= p[3] << 4;   for (k = 0; k < 8; k++)      for (j = 3; j >= 0; j--)         for (i = 0; i < 4; i++, m++)            if (*m != p[j]) {               i915->intel.hw_stipple = 0;               return;            }   newMask = (((p[0] & 0xf) << 0) |              ((p[1] & 0xf) << 4) |              ((p[2] & 0xf) << 8) | ((p[3] & 0xf) << 12));   if (newMask == 0xffff || newMask == 0x0) {      /* this is needed to make conform pass */      i915->intel.hw_stipple = 0;      return;   }   i915->state.Stipple[I915_STPREG_ST1] &= ~0xffff;   i915->state.Stipple[I915_STPREG_ST1] |= newMask;   i915->intel.hw_stipple = 1;   if (active)      i915->state.Stipple[I915_STPREG_ST1] |= ST1_ENABLE;}/* ============================================================= * Hardware clipping */static voidi915Scissor(GLcontext * ctx, GLint x, GLint y, GLsizei w, GLsizei h){   struct i915_context *i915 = I915_CONTEXT(ctx);   int x1, y1, x2, y2;   if (!ctx->DrawBuffer)      return;   DBG("%s %d,%d %dx%d\n", __FUNCTION__, x, y, w, h);   if (ctx->DrawBuffer->Name == 0) {      x1 = x;      y1 = ctx->DrawBuffer->Height - (y + h);      x2 = x + w - 1;      y2 = y1 + h - 1;      DBG("%s %d..%d,%d..%d (inverted)\n", __FUNCTION__, x1, x2, y1, y2);   }   else {      /* FBO - not inverted       */      x1 = x;      y1 = y;      x2 = x + w - 1;      y2 = y + h - 1;      DBG("%s %d..%d,%d..%d (not inverted)\n", __FUNCTION__, x1, x2, y1, y2);   }      x1 = CLAMP(x1, 0, ctx->DrawBuffer->Width - 1);   y1 = CLAMP(y1, 0, ctx->DrawBuffer->Height - 1);   x2 = CLAMP(x2, 0, ctx->DrawBuffer->Width - 1);   y2 = CLAMP(y2, 0, ctx->DrawBuffer->Height - 1);      DBG("%s %d..%d,%d..%d (clamped)\n", __FUNCTION__, x1, x2, y1, y2);   I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);   i915->state.Buffer[I915_DESTREG_SR1] = (y1 << 16) | (x1 & 0xffff);   i915->state.Buffer[I915_DESTREG_SR2] = (y2 << 16) | (x2 & 0xffff);}static voidi915LogicOp(GLcontext * ctx, GLenum opcode){   struct i915_context *i915 = I915_CONTEXT(ctx);   int tmp = intel_translate_logic_op(opcode);   DBG("%s\n", __FUNCTION__);      I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_STATE4] &= ~LOGICOP_MASK;   i915->state.Ctx[I915_CTXREG_STATE4] |= LOGIC_OP_FUNC(tmp);}static voidi915CullFaceFrontFace(GLcontext * ctx, GLenum unused){   struct i915_context *i915 = I915_CONTEXT(ctx);   GLuint mode;   DBG("%s %d\n", __FUNCTION__,       ctx->DrawBuffer ? ctx->DrawBuffer->Name : 0);   if (!ctx->Polygon.CullFlag) {      mode = S4_CULLMODE_NONE;   }   else if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {      mode = S4_CULLMODE_CW;      if (ctx->DrawBuffer && ctx->DrawBuffer->Name != 0)         mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);      if (ctx->Polygon.CullFaceMode == GL_FRONT)         mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);      if (ctx->Polygon.FrontFace != GL_CCW)         mode ^= (S4_CULLMODE_CW ^ S4_CULLMODE_CCW);   }   else {      mode = S4_CULLMODE_BOTH;   }   I915_STATECHANGE(i915, I915_UPLOAD_CTX);   i915->state.Ctx[I915_CTXREG_LIS4] &= ~S4_CULLMODE_MASK;   i915->state.Ctx[I915_CTXREG_LIS4] |= mode;}static voidi915LineWidth(GLcontext * ctx, GLfloat widthf){   struct i915_context *i915 = I915_CONTEXT(ctx);   int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_LINE_WIDTH_MASK;   int width;   DBG("%s\n", __FUNCTION__);      width = (int) (widthf * 2);   CLAMP_SELF(width, 1, 0xf);   lis4 |= width << S4_LINE_WIDTH_SHIFT;   if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {      I915_STATECHANGE(i915, I915_UPLOAD_CTX);      i915->state.Ctx[I915_CTXREG_LIS4] = lis4;   }}static voidi915PointSize(GLcontext * ctx, GLfloat size){   struct i915_context *i915 = I915_CONTEXT(ctx);   int lis4 = i915->state.Ctx[I915_CTXREG_LIS4] & ~S4_POINT_WIDTH_MASK;   GLint point_size = (int) size;   DBG("%s\n", __FUNCTION__);      CLAMP_SELF(point_size, 1, 255);   lis4 |= point_size << S4_POINT_WIDTH_SHIFT;   if (lis4 != i915->state.Ctx[I915_CTXREG_LIS4]) {      I915_STATECHANGE(i915, I915_UPLOAD_CTX);      i915->state.Ctx[I915_CTXREG_LIS4] = lis4;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -