svga_state_framebuffer.c revision 866f9b18c68ede63c00917ec9c3dae3524ca8826
13192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/**********************************************************
23192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Copyright 2008-2009 VMware, Inc.  All rights reserved.
33192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
43192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Permission is hereby granted, free of charge, to any person
53192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * obtaining a copy of this software and associated documentation
63192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * files (the "Software"), to deal in the Software without
73192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * restriction, including without limitation the rights to use, copy,
83192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * modify, merge, publish, distribute, sublicense, and/or sell copies
93192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * of the Software, and to permit persons to whom the Software is
103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * furnished to do so, subject to the following conditions:
113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * The above copyright notice and this permission notice shall be
133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * included in all copies or substantial portions of the Software.
143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * SOFTWARE.
233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz *
243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz **********************************************************/
253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2628486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "pipe/p_defines.h"
283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "util/u_math.h"
293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_context.h"
313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_state.h"
323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_cmd.h"
333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz#include "svga_debug.h"
343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Hardware state update
383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic int emit_framebuffer( struct svga_context *svga,
423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             unsigned dirty )
433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
466b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   boolean reemit = svga->rebind.rendertargets;
473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
505a70db643295e99ca3f821a34abe474d56a6c872José Fonseca   /*
515a70db643295e99ca3f821a34abe474d56a6c872José Fonseca    * We need to reemit non-null surface bindings, even when they are not
525a70db643295e99ca3f821a34abe474d56a6c872José Fonseca    * dirty, to ensure that the resources are paged in.
533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
565a70db643295e99ca3f821a34abe474d56a6c872José Fonseca      if (curr->cbufs[i] != hw->cbufs[i] ||
575a70db643295e99ca3f821a34abe474d56a6c872José Fonseca          (reemit && hw->cbufs[i])) {
58b84b7f19dfdc0ac02175847065b39110db7ad98fKeith Whitwell         if (svga->curr.nr_fbs++ > 8)
59b84b7f19dfdc0ac02175847065b39110db7ad98fKeith Whitwell            return PIPE_ERROR_OUT_OF_MEMORY;
60b84b7f19dfdc0ac02175847065b39110db7ad98fKeith Whitwell
613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]);
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (ret != PIPE_OK)
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return ret;
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
705a70db643295e99ca3f821a34abe474d56a6c872José Fonseca   if (curr->zsbuf != hw->zsbuf ||
715a70db643295e99ca3f821a34abe474d56a6c872José Fonseca       (reemit && hw->zsbuf)) {
723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, curr->zsbuf);
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (ret != PIPE_OK)
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (curr->zsbuf &&
77866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie          curr->zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) {
783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, curr->zsbuf);
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (ret != PIPE_OK)
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return ret;
813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else {
833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, NULL);
843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (ret != PIPE_OK)
853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return ret;
863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
916b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   svga->rebind.rendertargets = FALSE;
923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return 0;
943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
97369ece170257ef687ca609cacd1d66d186274eb3José Fonseca/*
98369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * Rebind rendertargets.
99369ece170257ef687ca609cacd1d66d186274eb3José Fonseca *
100369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * Similar to emit_framebuffer, but without any state checking/update.
101369ece170257ef687ca609cacd1d66d186274eb3José Fonseca *
102369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * Called at the beginning of every new command buffer to ensure that
103369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * non-dirty rendertargets are properly paged-in.
104369ece170257ef687ca609cacd1d66d186274eb3José Fonseca */
105369ece170257ef687ca609cacd1d66d186274eb3José Fonsecaenum pipe_error
106369ece170257ef687ca609cacd1d66d186274eb3José Fonsecasvga_reemit_framebuffer_bindings(struct svga_context *svga)
107369ece170257ef687ca609cacd1d66d186274eb3José Fonseca{
108369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
109369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   unsigned i;
110369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   enum pipe_error ret;
111369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
1126b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   assert(svga->rebind.rendertargets);
1136b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca
114369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, 8); ++i) {
115369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      if (hw->cbufs[i]) {
116369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, hw->cbufs[i]);
117369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         if (ret != PIPE_OK) {
118369ece170257ef687ca609cacd1d66d186274eb3José Fonseca            return ret;
119369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         }
120369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
121369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   }
122369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
123369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   if (hw->zsbuf) {
124369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, hw->zsbuf);
125369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      if (ret != PIPE_OK) {
126369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         return ret;
127369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
128369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
129369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      if (hw->zsbuf &&
130866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie          hw->zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) {
131369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, hw->zsbuf);
132369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         if (ret != PIPE_OK) {
133369ece170257ef687ca609cacd1d66d186274eb3José Fonseca            return ret;
134369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         }
135369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
136369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      else {
137369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, NULL);
138369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         if (ret != PIPE_OK) {
139369ece170257ef687ca609cacd1d66d186274eb3José Fonseca            return ret;
140369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         }
141369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
142369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   }
143369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
1446b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   svga->rebind.rendertargets = FALSE;
1456b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca
146369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   return PIPE_OK;
147369ece170257ef687ca609cacd1d66d186274eb3José Fonseca}
148369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
149369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
1503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_framebuffer =
1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw framebuffer state",
1536b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   SVGA_NEW_FRAME_BUFFER,
1543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_framebuffer
1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
1563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic int emit_viewport( struct svga_context *svga,
1643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                          unsigned dirty )
1653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct pipe_viewport_state *viewport = &svga->curr.viewport;
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_prescale prescale;
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dRect rect;
1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Not sure if this state is relevant with POSITIONT.  Probably
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * not, but setting to 0,1 avoids some state pingponging.
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float range_min = 0.0;
1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float range_max = 1.0;
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float flip = -1.0;
1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean degenerate = FALSE;
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float fb_width = svga->curr.framebuffer.width;
1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float fb_height = svga->curr.framebuffer.height;
1803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fx =        viewport->scale[0] * -1.0 + viewport->translate[0];
18263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
18363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fw =        viewport->scale[0] * 2;
18463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fh = flip * viewport->scale[1] * 2;
1853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   memset( &prescale, 0, sizeof(prescale) );
1873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* Examine gallium viewport transformation and produce a screen
18963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * rectangle and possibly vertex shader pre-transformation to
19063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * get the same results.
19163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
1923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   SVGA_DBG(DEBUG_VIEWPORT,
19463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            "\ninitial %f,%f %fx%f\n",
19563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fx,
19663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fy,
19763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fw,
19863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fh);
19963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
20063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[0] = 1.0;
20163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[1] = 1.0;
20263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[2] = 1.0;
20363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[3] = 1.0;
20463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[0] = 0;
20563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[1] = 0;
20663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[2] = 0;
20763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[3] = 0;
20863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.enabled = TRUE;
20963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
21063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
21163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
21263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fw < 0) {
21363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[0] *= -1.0;
21463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += -fw;
21563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw = -fw;
21663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fx =        viewport->scale[0] * 1.0 + viewport->translate[0];
21763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
21963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fh < 0) {
22063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[1] *= -1.0;
22163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[1] += -fh;
22263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fh = -fh;
22363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fy = flip * viewport->scale[1] * 1.0 + viewport->translate[1];
22463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
22663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fx < 0) {
22763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += fx;
22863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[0] *= fw / (fw + fx);
22963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw += fx;
23063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fx = 0;
23163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fy < 0) {
23463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[1] += fy;
23563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[1] *= fh / (fh + fy);
23663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fh += fy;
23763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fy = 0;
23863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fx + fw > fb_width) {
24163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[0] *= fw / (fb_width - fx);
24263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] -= fx * (fw / (fb_width - fx));
24363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += fx;
24463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw = fb_width - fx;
24563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
24663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fy + fh > fb_height) {
24963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[1] *= fh / (fb_height - fy);
25063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[1] -= fy * (fh / (fb_height - fy));
25163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[1] += fy;
25263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fh = fb_height - fy;
25363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fw < 0 || fh < 0) {
25663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw = fh = fx = fy = 0;
25763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      degenerate = TRUE;
25863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      goto out;
25963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
26263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* D3D viewport is integer space.  Convert fx,fy,etc. to
26363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * integers.
26463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    *
26563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * TODO: adjust pretranslate correct for any subpixel error
26663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * introduced converting to integers.
26763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
26863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.x = fx;
26963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.y = fy;
27063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.w = fw;
27163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.h = fh;
27263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
27363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   SVGA_DBG(DEBUG_VIEWPORT,
27463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            "viewport error %f,%f %fx%f\n",
27563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.x - fx),
27663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.y - fy),
27763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.w - fw),
27863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.h - fh));
27963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
28063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   SVGA_DBG(DEBUG_VIEWPORT,
28163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            "viewport %d,%d %dx%d\n",
28263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.x,
28363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.y,
28463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.w,
28563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.h);
28663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
28763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
28863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* Finally, to get GL rasterization rules, need to tweak the
28963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * screen-space coordinates slightly relative to D3D which is
29063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * what hardware implements natively.
29163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
29263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (svga->curr.rast->templ.gl_rasterization_rules) {
29363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      float adjust_x = 0.0;
29463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      float adjust_y = 0.0;
29563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
29663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      switch (svga->curr.reduced_prim) {
29763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      case PIPE_PRIM_LINES:
29863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         adjust_x = -0.5;
29963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         adjust_y = 0;
30063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         break;
30163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      case PIPE_PRIM_POINTS:
30263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      case PIPE_PRIM_TRIANGLES:
3036638b4a590aa07dbe05f6647da90a00a4c0d57a8Brian Paul         adjust_x = -0.5;
30463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         adjust_y = -0.5;
30563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         break;
3063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
3073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
30863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += adjust_x;
30963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[1] += adjust_y;
31063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[2] = 0.5; /* D3D clip space */
31163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[2]     = 0.5; /* D3D clip space */
31263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
3133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
31563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
31663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   range_max = viewport->scale[2] *  1.0 + viewport->translate[2];
31763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
31863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* D3D (and by implication SVGA) doesn't like dealing with zmax
31963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * less than zmin.  Detect that case, flip the depth range and
32063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * invert our z-scale factor to achieve the same effect.
32163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
32263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (range_min > range_max) {
32363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      float range_tmp;
32463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      range_tmp = range_min;
32563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      range_min = range_max;
32663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      range_max = range_tmp;
32763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[2]     = -prescale.scale[2];
3283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (prescale.enabled) {
3313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      float H[2];
3323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      float J[2];
3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      int i;
3343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA_DBG(DEBUG_VIEWPORT,
3363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "prescale %f,%f %fx%f\n",
3373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[0],
3383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[1],
3393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[0],
3403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[1]);
3413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      H[0] = (float)rect.w / 2.0;
3433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      H[1] = -(float)rect.h / 2.0;
3443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      J[0] = (float)rect.x + (float)rect.w / 2.0;
3453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      J[1] = (float)rect.y + (float)rect.h / 2.0;
3463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA_DBG(DEBUG_VIEWPORT,
3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "H %f,%f\n"
3493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "J %fx%f\n",
3503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               H[0],
3513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               H[1],
3523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               J[0],
3533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               J[1]);
3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Adjust prescale to take into account the fact that it is
3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * going to be applied prior to the perspective divide and
3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * viewport transformation.
3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Vwin = H(Vc/Vc.w) + J
3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * We want to tweak Vwin with scale and translation from above,
3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * as in:
3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Vwin' = S Vwin + T
3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * But we can only modify the values at Vc.  Plugging all the
3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * above together, and rearranging, eventually we get:
3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   Vwin' = H(Vc'/Vc'.w) + J
3703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * where:
3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   Vc' = SVc + KVc.w
3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   K = (T + (S-1)J) / H
3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Overwrite prescale.translate with values for K:
3753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      for (i = 0; i < 2; i++) {
3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         prescale.translate[i] = ((prescale.translate[i] +
3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                   (prescale.scale[i] - 1.0) * J[i]) / H[i]);
3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA_DBG(DEBUG_VIEWPORT,
3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "clipspace %f,%f %fx%f\n",
3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[0],
3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[1],
3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[0],
3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[1]);
3873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzout:
3903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (degenerate) {
3913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.x = 0;
3923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.y = 0;
3933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.w = 1;
3943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.h = 1;
3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      prescale.enabled = FALSE;
3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
3993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = SVGA3D_SetViewport(svga->swc, &rect);
4003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(ret != PIPE_OK)
4013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
4023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      memcpy(&svga->state.hw_clear.viewport, &rect, sizeof(rect));
4043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(sizeof(rect) == sizeof(svga->state.hw_clear.viewport));
4053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga->state.hw_clear.depthrange.zmin != range_min ||
4083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       svga->state.hw_clear.depthrange.zmax != range_max)
4093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   {
4103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = SVGA3D_SetZRange(svga->swc, range_min, range_max );
4113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(ret != PIPE_OK)
4123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
4133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->state.hw_clear.depthrange.zmin = range_min;
4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->state.hw_clear.depthrange.zmax = range_max;
4163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (memcmp(&prescale, &svga->state.hw_clear.prescale, sizeof prescale) != 0) {
4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->dirty |= SVGA_NEW_PRESCALE;
4203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->state.hw_clear.prescale = prescale;
4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return 0;
4243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_viewport =
4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw viewport state",
4303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ( SVGA_NEW_FRAME_BUFFER |
4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz     SVGA_NEW_VIEWPORT |
4323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz     SVGA_NEW_RAST |
4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz     SVGA_NEW_REDUCED_PRIMITIVE ),
4343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_viewport
4353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
4363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
4393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Scissor state
4403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
4413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic int emit_scissor_rect( struct svga_context *svga,
4423192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                              unsigned dirty )
4433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct pipe_scissor_state *scissor = &svga->curr.scissor;
4453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dRect rect;
4463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.x = scissor->minx;
4483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.y = scissor->miny;
4493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.w = scissor->maxx - scissor->minx; /* + 1 ?? */
4503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.h = scissor->maxy - scissor->miny; /* + 1 ?? */
4513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return SVGA3D_SetScissorRect(svga->swc, &rect);
4533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_scissor =
4573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw scissor state",
4593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA_NEW_SCISSOR,
4603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_scissor_rect
4613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
4623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
4653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Userclip state
4663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
4673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstatic int emit_clip_planes( struct svga_context *svga,
4693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                             unsigned dirty )
4703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
4723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
4733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* TODO: just emit directly from svga_set_clip_state()?
4753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
4763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for (i = 0; i < svga->curr.clip.nr; i++) {
4770be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      /* need to express the plane in D3D-style coordinate space.
4780be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * GL coords get converted to D3D coords with the matrix:
4790be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 1  0  0  0 ]
4800be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 0 -1  0  0 ]
4810be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 0  0  2  0 ]
4820be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 0  0 -1  1 ]
4830be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * Apply that matrix to our plane equation, and invert Y.
4840be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       */
4850be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float a = svga->curr.clip.ucp[i][0];
4860be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float b = svga->curr.clip.ucp[i][1];
4870be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float c = svga->curr.clip.ucp[i][2];
4880be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float d = svga->curr.clip.ucp[i][3];
4890be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float plane[4];
4900be6ae74e9a56e84df088392ef3b09229508404fBrian Paul
4910be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[0] = a;
4920be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[1] = b;
4930be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[2] = 2.0f * c;
4940be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[3] = d - c;
4950be6ae74e9a56e84df088392ef3b09229508404fBrian Paul
4960be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      ret = SVGA3D_SetClipPlane(svga->swc, i, plane);
4973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(ret != PIPE_OK)
4983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
4993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
5003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return 0;
5023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_clip_planes =
5063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw viewport state",
5083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA_NEW_CLIP,
5093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_clip_planes
5103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
511