101e6ff90560d588418e706ce4d2a16d5a15520e5David Li/**
213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** Copyright 2010, The Android Open Source Project
413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
501e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** Licensed under the Apache License, Version 2.0 (the "License");
601e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** you may not use this file except in compliance with the License.
701e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** You may obtain a copy of the License at
813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
901e6ff90560d588418e706ce4d2a16d5a15520e5David Li **     http://www.apache.org/licenses/LICENSE-2.0
1013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li **
1101e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** Unless required by applicable law or agreed to in writing, software
1201e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** distributed under the License is distributed on an "AS IS" BASIS,
1301e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1401e6ff90560d588418e706ce4d2a16d5a15520e5David Li ** See the License for the specific language governing permissions and
1513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li ** limitations under the License.
1613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li */
1713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
1813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include "src/pixelflinger2/pixelflinger2.h"
1913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
2013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li#include <string.h>
2160afd53a1257f900a8878b2c0c72b8c192d2992aDavid Li#include <stdio.h>
2213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
2313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Livoid SetShaderVerifyFunctions(GGLInterface *);
2413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
2513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void DepthFunc(GGLInterface * iface, GLenum func)
2613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
2701e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
2801e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_NEVER > func || GL_ALWAYS < func)
2901e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return gglError(GL_INVALID_ENUM);
3001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   ctx->state.bufferState.depthFunc = func & 0x7;
3101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   SetShaderVerifyFunctions(iface);
3213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
3313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
3413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void StencilFuncSeparate(GGLInterface * iface, GLenum face, GLenum func, GLint ref, GLuint mask)
3513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
3601e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
3701e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_FRONT > face || GL_FRONT_AND_BACK < face)
3801e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return gglError(GL_INVALID_ENUM);
3901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_NEVER > func || GL_ALWAYS < func)
4001e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return gglError(GL_INVALID_ENUM);
4101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   mask &= 0xff;
4201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   ref = MAX2(MIN2(ref, 0xff), 0);
4301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   ref &= mask;
4401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_FRONT == face || GL_FRONT_AND_BACK == face) {
4501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.frontStencil.ref = ref;
4601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.frontStencil.mask = mask;
4701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.frontStencil.func = func & 0x7;
4801e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
4901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_BACK == face || GL_FRONT_AND_BACK == face) {
5001e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.backStencil.ref = ref;
5101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.backStencil.mask = mask;
5201e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.backStencil.func = func & 0x7;
5301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
5401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   SetShaderVerifyFunctions(iface);
5513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
5613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
5713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic unsigned StencilOpEnum(GLenum func, unsigned oldValue)
5813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
5901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   switch (func) {
6001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_ZERO:
6101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return 0;
6201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_KEEP: // fall through
6301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_REPLACE: // fall through
6401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_INCR: // fall through
6501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_DECR:
6601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return func - GL_KEEP + 1;
6701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      break;
6801e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_INVERT:
6901e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return 5;
7001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_INCR_WRAP:
7101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return 6;
7201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   case GL_DECR_WRAP:
7301e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return 7;
7401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   default:
7501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      gglError(GL_INVALID_ENUM);
7601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return oldValue;
7701e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
7813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
7913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
8013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void StencilOpSeparate(GGLInterface * iface, GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass)
8113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
8201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
8301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_FRONT > face || GL_FRONT_AND_BACK < face)
8401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      return gglError(GL_INVALID_ENUM);
8501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_FRONT == face || GL_FRONT_AND_BACK == face) {
8601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.frontStencil.sFail = StencilOpEnum(sfail, ctx->state.frontStencil.sFail);
8701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.frontStencil.dFail = StencilOpEnum(dpfail, ctx->state.frontStencil.dFail);
8801e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.frontStencil.dPass = StencilOpEnum(dppass, ctx->state.frontStencil.dPass);
8901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
9001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_BACK == face || GL_FRONT_AND_BACK == face) {
9101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.backStencil.sFail = StencilOpEnum(sfail, ctx->state.backStencil.sFail);
9201e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.backStencil.dFail = StencilOpEnum(dpfail, ctx->state.backStencil.dFail);
9301e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.backStencil.dPass = StencilOpEnum(dppass, ctx->state.backStencil.dPass);
9401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
9501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   SetShaderVerifyFunctions(iface);
9613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
9713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
9813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void StencilSelect(const GGLInterface * iface, GLenum face)
9913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
10001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
10101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_FRONT == face) {
10201e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->activeStencil.face = 0;
10301e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->activeStencil.ref = ctx->state.frontStencil.ref;
10401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->activeStencil.mask = ctx->state.frontStencil.mask;
10501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   } else if (GL_BACK == face) {
10601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->activeStencil.face = 1;
10701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->activeStencil.ref = ctx->state.backStencil.ref;
10801e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->activeStencil.mask = ctx->state.backStencil.mask;
10901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
11013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
11113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
11213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void ClearStencil(GGLInterface * iface, GLint s)
11313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
11401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
11501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   ctx->clearState.stencil = 0x01010101 * ((unsigned &)s & 0xff);
11613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
11713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
11813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void ClearColor(GGLInterface * iface, GLclampf r, GLclampf g, GLclampf b, GLclampf a)
11913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
12001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
12101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   r = MAX2(MIN2(r, 1.0f), 0);
12201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   g = MAX2(MIN2(g, 1.0f), 0);
12301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   b = MAX2(MIN2(b, 1.0f), 0);
12401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   a = MAX2(MIN2(a, 1.0f), 0);
12501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   ctx->clearState.color = (unsigned(a * 255) << 24) | (unsigned(b * 255) << 16) |
12601e6ff90560d588418e706ce4d2a16d5a15520e5David Li                           (unsigned(g * 255) << 8) | unsigned(r * 255);
12713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
12813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
12913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void ClearDepthf(GGLInterface * iface, GLclampf d)
13013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
13101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
13201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   // assuming ieee 754 32 bit float and 32 bit 2's complement int
13301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   assert(sizeof(d) == sizeof(ctx->clearState.depth));
13401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   ctx->clearState.depth = (int &)d; // bit reinterpretation
13501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (0x80000000 & ctx->clearState.depth) // smaller negative float has bigger int representation, so flip
13601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->clearState.depth ^= 0x7fffffff; // since -FLT_MAX is close to -1 when bitcasted
13713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
13813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
13913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void Clear(const GGLInterface * iface, GLbitfield buf)
14013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
14101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONST_CONTEXT(ctx, iface);
14201e6ff90560d588418e706ce4d2a16d5a15520e5David Li
14301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   // TODO DXL scissor test
14401e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_COLOR_BUFFER_BIT & buf && ctx->frameSurface.data) {
14501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      if (GGL_PIXEL_FORMAT_RGBA_8888 == ctx->frameSurface.format) {
14601e6ff90560d588418e706ce4d2a16d5a15520e5David Li         unsigned * const end = (unsigned *)ctx->frameSurface.data +
14701e6ff90560d588418e706ce4d2a16d5a15520e5David Li                                ctx->frameSurface.width * ctx->frameSurface.height;
14801e6ff90560d588418e706ce4d2a16d5a15520e5David Li         const unsigned color = ctx->clearState.color;
14901e6ff90560d588418e706ce4d2a16d5a15520e5David Li         for (unsigned * start = (unsigned *)ctx->frameSurface.data; start < end; start++)
15001e6ff90560d588418e706ce4d2a16d5a15520e5David Li            *start = color;
15101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      } else if (GGL_PIXEL_FORMAT_RGB_565 == ctx->frameSurface.format) {
15201e6ff90560d588418e706ce4d2a16d5a15520e5David Li         short * const end = (short *)ctx->frameSurface.data +
15301e6ff90560d588418e706ce4d2a16d5a15520e5David Li                             ctx->frameSurface.width * ctx->frameSurface.height;
15401e6ff90560d588418e706ce4d2a16d5a15520e5David Li         unsigned r = ctx->clearState.color & 0xf8, g = ctx->clearState.color & 0xfc00,
15501e6ff90560d588418e706ce4d2a16d5a15520e5David Li                      b = ctx->clearState.color & 0xf80000;
15601e6ff90560d588418e706ce4d2a16d5a15520e5David Li         const short color = (b >> 19) | (g >> 5) | (r >> 3);
15701e6ff90560d588418e706ce4d2a16d5a15520e5David Li         for (short * start = (short *)ctx->frameSurface.data; start < end; start++)
15813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li            *start = color;
15901e6ff90560d588418e706ce4d2a16d5a15520e5David Li      } else
16001e6ff90560d588418e706ce4d2a16d5a15520e5David Li         assert(0);
16101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
16201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_DEPTH_BUFFER_BIT & buf && ctx->depthSurface.data) {
16301e6ff90560d588418e706ce4d2a16d5a15520e5David Li      assert(GGL_PIXEL_FORMAT_Z_32 == ctx->depthSurface.format);
16401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      unsigned * const end = (unsigned *)ctx->depthSurface.data +
16501e6ff90560d588418e706ce4d2a16d5a15520e5David Li                             ctx->depthSurface.width * ctx->depthSurface.height;
16601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      const unsigned depth = ctx->clearState.depth;
16701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      for (unsigned * start = (unsigned *)ctx->depthSurface.data; start < end; start++)
16801e6ff90560d588418e706ce4d2a16d5a15520e5David Li         *start = depth;
16901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
17001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_STENCIL_BUFFER_BIT & buf && ctx->stencilSurface.data) {
17101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      assert(GGL_PIXEL_FORMAT_S_8 == ctx->stencilSurface.format);
17201e6ff90560d588418e706ce4d2a16d5a15520e5David Li      unsigned * const end = (unsigned *)((unsigned char *)ctx->stencilSurface.data +
17301e6ff90560d588418e706ce4d2a16d5a15520e5David Li                                          ctx->stencilSurface.width * ctx->stencilSurface.height);
17401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      unsigned * start = (unsigned *)ctx->stencilSurface.data;
17501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      const unsigned stencil = ctx->clearState.stencil;
17601e6ff90560d588418e706ce4d2a16d5a15520e5David Li      for (start; start < end; start++)
17701e6ff90560d588418e706ce4d2a16d5a15520e5David Li         *start = stencil;
17801e6ff90560d588418e706ce4d2a16d5a15520e5David Li      start--;
17901e6ff90560d588418e706ce4d2a16d5a15520e5David Li      for (unsigned char * i = (unsigned char *)start; i < (unsigned char *)end; i++)
18001e6ff90560d588418e706ce4d2a16d5a15520e5David Li         *i = stencil & 0xff;
18101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
18213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
18313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
18413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Listatic void SetBuffer(GGLInterface * iface, const GLenum type, GGLSurface * surface)
18513fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
18601e6ff90560d588418e706ce4d2a16d5a15520e5David Li   GGL_GET_CONTEXT(ctx, iface);
18701e6ff90560d588418e706ce4d2a16d5a15520e5David Li   bool changed = false;
18801e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (GL_COLOR_BUFFER_BIT == type) {
18901e6ff90560d588418e706ce4d2a16d5a15520e5David Li      if (surface) {
19001e6ff90560d588418e706ce4d2a16d5a15520e5David Li         ctx->frameSurface = *surface;
19101e6ff90560d588418e706ce4d2a16d5a15520e5David Li         changed |= ctx->frameSurface.format ^ surface->format;
19201e6ff90560d588418e706ce4d2a16d5a15520e5David Li         switch (surface->format) {
19301e6ff90560d588418e706ce4d2a16d5a15520e5David Li         case GGL_PIXEL_FORMAT_RGBA_8888:
19401e6ff90560d588418e706ce4d2a16d5a15520e5David Li         case GGL_PIXEL_FORMAT_RGB_565:
19501e6ff90560d588418e706ce4d2a16d5a15520e5David Li            break;
19601e6ff90560d588418e706ce4d2a16d5a15520e5David Li         case GGL_PIXEL_FORMAT_RGBX_8888:
19701e6ff90560d588418e706ce4d2a16d5a15520e5David Li         default:
198a5ca04aebd1a0df7c52e170252cf3c2f3ee3e8a2Steve Block            ALOGD("pf2: SetBuffer 0x%.04X format=0x%.02X \n", type, surface ? surface->format : 0);
19901e6ff90560d588418e706ce4d2a16d5a15520e5David Li            assert(0);
20001e6ff90560d588418e706ce4d2a16d5a15520e5David Li         }
20101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      } else {
20201e6ff90560d588418e706ce4d2a16d5a15520e5David Li         memset(&ctx->frameSurface, 0, sizeof(ctx->frameSurface));
20301e6ff90560d588418e706ce4d2a16d5a15520e5David Li         changed = true;
20401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      }
20501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.bufferState.colorFormat = ctx->frameSurface.format;
20601e6ff90560d588418e706ce4d2a16d5a15520e5David Li   } else if (GL_DEPTH_BUFFER_BIT == type) {
20701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      if (surface) {
20801e6ff90560d588418e706ce4d2a16d5a15520e5David Li         ctx->depthSurface = *surface;
20901e6ff90560d588418e706ce4d2a16d5a15520e5David Li         changed |= ctx->depthSurface.format ^ surface->format;
21001e6ff90560d588418e706ce4d2a16d5a15520e5David Li         assert(GGL_PIXEL_FORMAT_Z_32 == ctx->depthSurface.format);
21101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      } else {
21201e6ff90560d588418e706ce4d2a16d5a15520e5David Li         memset(&ctx->depthSurface, 0, sizeof(ctx->depthSurface));
21301e6ff90560d588418e706ce4d2a16d5a15520e5David Li         changed = true;
21401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      }
21501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.bufferState.depthFormat = ctx->depthSurface.format;
21601e6ff90560d588418e706ce4d2a16d5a15520e5David Li   } else if (GL_STENCIL_BUFFER_BIT == type) {
21701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      if (surface) {
21801e6ff90560d588418e706ce4d2a16d5a15520e5David Li         ctx->stencilSurface = *surface;
21901e6ff90560d588418e706ce4d2a16d5a15520e5David Li         changed |= ctx->stencilSurface.format ^ surface->format;
22001e6ff90560d588418e706ce4d2a16d5a15520e5David Li         assert(GGL_PIXEL_FORMAT_S_8 == ctx->stencilSurface.format);
22101e6ff90560d588418e706ce4d2a16d5a15520e5David Li      } else {
22201e6ff90560d588418e706ce4d2a16d5a15520e5David Li         memset(&ctx->stencilSurface, 0, sizeof(ctx->stencilSurface));
22301e6ff90560d588418e706ce4d2a16d5a15520e5David Li         changed = true;
22401e6ff90560d588418e706ce4d2a16d5a15520e5David Li      }
22501e6ff90560d588418e706ce4d2a16d5a15520e5David Li      ctx->state.bufferState.stencilFormat = ctx->stencilSurface.format;
22601e6ff90560d588418e706ce4d2a16d5a15520e5David Li   } else
22701e6ff90560d588418e706ce4d2a16d5a15520e5David Li      gglError(GL_INVALID_ENUM);
22801e6ff90560d588418e706ce4d2a16d5a15520e5David Li   if (changed) {
22901e6ff90560d588418e706ce4d2a16d5a15520e5David Li      SetShaderVerifyFunctions(iface);
23001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   }
23113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li}
23213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li
23313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Livoid InitializeBufferFunctions(GGLInterface * iface)
23413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li{
23501e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->DepthFunc = DepthFunc;
23601e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->StencilFuncSeparate = StencilFuncSeparate;
23701e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->StencilOpSeparate = StencilOpSeparate;
23801e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->StencilSelect = StencilSelect;
23901e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->ClearStencil = ClearStencil;
24001e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->ClearColor = ClearColor;
24101e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->ClearDepthf = ClearDepthf;
24201e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->Clear = Clear;
24301e6ff90560d588418e706ce4d2a16d5a15520e5David Li   iface->SetBuffer = SetBuffer;
24401e6ff90560d588418e706ce4d2a16d5a15520e5David Li}
245