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
41e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecastatic enum pipe_error
42e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecaemit_framebuffer( struct svga_context *svga,
43e8f646fa7e9cf6f6793864384128157735aa03b3José Fonseca                  unsigned dirty )
443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct pipe_framebuffer_state *curr = &svga->curr.framebuffer;
463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
476b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   boolean reemit = svga->rebind.rendertargets;
483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
515a70db643295e99ca3f821a34abe474d56a6c872José Fonseca   /*
525a70db643295e99ca3f821a34abe474d56a6c872José Fonseca    * We need to reemit non-null surface bindings, even when they are not
535a70db643295e99ca3f821a34abe474d56a6c872José Fonseca    * dirty, to ensure that the resources are paged in.
543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   for(i = 0; i < PIPE_MAX_COLOR_BUFS; ++i) {
575a70db643295e99ca3f821a34abe474d56a6c872José Fonseca      if (curr->cbufs[i] != hw->cbufs[i] ||
585a70db643295e99ca3f821a34abe474d56a6c872José Fonseca          (reemit && hw->cbufs[i])) {
59b84b7f19dfdc0ac02175847065b39110db7ad98fKeith Whitwell         if (svga->curr.nr_fbs++ > 8)
60b84b7f19dfdc0ac02175847065b39110db7ad98fKeith Whitwell            return PIPE_ERROR_OUT_OF_MEMORY;
61b84b7f19dfdc0ac02175847065b39110db7ad98fKeith Whitwell
623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, curr->cbufs[i]);
633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (ret != PIPE_OK)
643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return ret;
653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         pipe_surface_reference(&hw->cbufs[i], curr->cbufs[i]);
673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
715a70db643295e99ca3f821a34abe474d56a6c872José Fonseca   if (curr->zsbuf != hw->zsbuf ||
725a70db643295e99ca3f821a34abe474d56a6c872José Fonseca       (reemit && hw->zsbuf)) {
733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, curr->zsbuf);
743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (ret != PIPE_OK)
753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if (curr->zsbuf &&
78866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie          curr->zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) {
793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, curr->zsbuf);
803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (ret != PIPE_OK)
813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return ret;
823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      else {
843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, NULL);
853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         if (ret != PIPE_OK)
863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz            return ret;
873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      pipe_surface_reference(&hw->zsbuf, curr->zsbuf);
903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
926b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   svga->rebind.rendertargets = FALSE;
933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
942786343896030ed4abcf6674a3e66f3a0d246e0dBrian Paul   return PIPE_OK;
953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
98369ece170257ef687ca609cacd1d66d186274eb3José Fonseca/*
99369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * Rebind rendertargets.
100369ece170257ef687ca609cacd1d66d186274eb3José Fonseca *
101369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * Similar to emit_framebuffer, but without any state checking/update.
102369ece170257ef687ca609cacd1d66d186274eb3José Fonseca *
103369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * Called at the beginning of every new command buffer to ensure that
104369ece170257ef687ca609cacd1d66d186274eb3José Fonseca * non-dirty rendertargets are properly paged-in.
105369ece170257ef687ca609cacd1d66d186274eb3José Fonseca */
106369ece170257ef687ca609cacd1d66d186274eb3José Fonsecaenum pipe_error
107369ece170257ef687ca609cacd1d66d186274eb3José Fonsecasvga_reemit_framebuffer_bindings(struct svga_context *svga)
108369ece170257ef687ca609cacd1d66d186274eb3José Fonseca{
109369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   struct pipe_framebuffer_state *hw = &svga->state.hw_clear.framebuffer;
110369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   unsigned i;
111369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   enum pipe_error ret;
112369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
1136b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   assert(svga->rebind.rendertargets);
1146b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca
115369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   for (i = 0; i < MIN2(PIPE_MAX_COLOR_BUFS, 8); ++i) {
116369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      if (hw->cbufs[i]) {
117369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_COLOR0 + i, hw->cbufs[i]);
118369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         if (ret != PIPE_OK) {
119369ece170257ef687ca609cacd1d66d186274eb3José Fonseca            return ret;
120369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         }
121369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
122369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   }
123369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
124369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   if (hw->zsbuf) {
125369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_DEPTH, hw->zsbuf);
126369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      if (ret != PIPE_OK) {
127369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         return ret;
128369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
129369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
130369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      if (hw->zsbuf &&
131866f9b18c68ede63c00917ec9c3dae3524ca8826Dave Airlie          hw->zsbuf->format == PIPE_FORMAT_S8_UINT_Z24_UNORM) {
132369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, hw->zsbuf);
133369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         if (ret != PIPE_OK) {
134369ece170257ef687ca609cacd1d66d186274eb3José Fonseca            return ret;
135369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         }
136369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
137369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      else {
138369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         ret = SVGA3D_SetRenderTarget(svga->swc, SVGA3D_RT_STENCIL, NULL);
139369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         if (ret != PIPE_OK) {
140369ece170257ef687ca609cacd1d66d186274eb3José Fonseca            return ret;
141369ece170257ef687ca609cacd1d66d186274eb3José Fonseca         }
142369ece170257ef687ca609cacd1d66d186274eb3José Fonseca      }
143369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   }
144369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
1456b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   svga->rebind.rendertargets = FALSE;
1466b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca
147369ece170257ef687ca609cacd1d66d186274eb3José Fonseca   return PIPE_OK;
148369ece170257ef687ca609cacd1d66d186274eb3José Fonseca}
149369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
150369ece170257ef687ca609cacd1d66d186274eb3José Fonseca
1513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_framebuffer =
1523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw framebuffer state",
1546b95cfb0de1bcd680679a20d6ecc32b42e5d1546José Fonseca   SVGA_NEW_FRAME_BUFFER,
1553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_framebuffer
1563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
1573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
1623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
1633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
164e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecastatic enum pipe_error
165e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecaemit_viewport( struct svga_context *svga,
166e8f646fa7e9cf6f6793864384128157735aa03b3José Fonseca               unsigned dirty )
1673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
1683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct pipe_viewport_state *viewport = &svga->curr.viewport;
1693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   struct svga_prescale prescale;
1703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dRect rect;
1713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* Not sure if this state is relevant with POSITIONT.  Probably
1723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    * not, but setting to 0,1 avoids some state pingponging.
1733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
1743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float range_min = 0.0;
1753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float range_max = 1.0;
1763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float flip = -1.0;
1773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   boolean degenerate = FALSE;
1781459c18f45f5bd2a2d99145247093f1b540478adBrian Paul   boolean invertY = FALSE;
1793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
1803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
1813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float fb_width = svga->curr.framebuffer.width;
1823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   float fb_height = svga->curr.framebuffer.height;
1833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fx =        viewport->scale[0] * -1.0 + viewport->translate[0];
18563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fy = flip * viewport->scale[1] * -1.0 + viewport->translate[1];
18663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fw =        viewport->scale[0] * 2;
18763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   float fh = flip * viewport->scale[1] * 2;
1883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
18963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   memset( &prescale, 0, sizeof(prescale) );
1903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* Examine gallium viewport transformation and produce a screen
19263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * rectangle and possibly vertex shader pre-transformation to
19363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * get the same results.
19463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
1953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
19663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   SVGA_DBG(DEBUG_VIEWPORT,
19763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            "\ninitial %f,%f %fx%f\n",
19863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fx,
19963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fy,
20063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fw,
20163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fh);
20263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
20363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[0] = 1.0;
20463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[1] = 1.0;
20563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[2] = 1.0;
20663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.scale[3] = 1.0;
20763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[0] = 0;
20863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[1] = 0;
20963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[2] = 0;
21063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.translate[3] = 0;
21163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   prescale.enabled = TRUE;
21263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
21363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
21463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
21563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fw < 0) {
21663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[0] *= -1.0;
21763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += -fw;
21863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw = -fw;
21963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fx =        viewport->scale[0] * 1.0 + viewport->translate[0];
22063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2221459c18f45f5bd2a2d99145247093f1b540478adBrian Paul   if (fh < 0.0) {
2231459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      prescale.translate[1] = fh - 1 + fy * 2;
22463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fh = -fh;
2251459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      fy -= fh;
2261459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      prescale.scale[1] = -1.0;
2271459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      invertY = TRUE;
22863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fx < 0) {
23163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += fx;
23263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[0] *= fw / (fw + fx);
23363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw += fx;
23463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fx = 0;
23563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
23763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fy < 0) {
2381459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      if (invertY) {
2391459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         prescale.translate[1] -= fy;
2401459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      }
2411459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      else {
2421459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         prescale.translate[1] += fy;
2431459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      }
24463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[1] *= fh / (fh + fy);
24563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fh += fy;
24663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fy = 0;
24763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
24963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fx + fw > fb_width) {
25063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[0] *= fw / (fb_width - fx);
25163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] -= fx * (fw / (fb_width - fx));
25263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += fx;
25363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw = fb_width - fx;
25463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
25563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
25763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fy + fh > fb_height) {
25863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[1] *= fh / (fb_height - fy);
2591459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      if (invertY) {
2601459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         float in = fb_height - fy;       /* number of vp pixels inside view */
2611459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         float out = fy + fh - fb_height; /* number of vp pixels out of view */
2621459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         prescale.translate[1] += fy * out / in;
2631459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      }
2641459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      else {
2651459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         prescale.translate[1] -= fy * (fh / (fb_height - fy));
2661459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         prescale.translate[1] += fy;
2671459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      }
26863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fh = fb_height - fy;
26963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (fw < 0 || fh < 0) {
27263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      fw = fh = fx = fy = 0;
27363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      degenerate = TRUE;
27463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      goto out;
27563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
2763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
2773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
27863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* D3D viewport is integer space.  Convert fx,fy,etc. to
27963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * integers.
28063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    *
28163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * TODO: adjust pretranslate correct for any subpixel error
28263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * introduced converting to integers.
28363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
28463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.x = fx;
28563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.y = fy;
28663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.w = fw;
28763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   rect.h = fh;
28863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
28963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   SVGA_DBG(DEBUG_VIEWPORT,
29063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            "viewport error %f,%f %fx%f\n",
29163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.x - fx),
29263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.y - fy),
29363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.w - fw),
29463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            fabs((float)rect.h - fh));
29563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
29663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   SVGA_DBG(DEBUG_VIEWPORT,
29763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            "viewport %d,%d %dx%d\n",
29863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.x,
29963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.y,
30063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.w,
30163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol            rect.h);
30263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
30363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
30463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* Finally, to get GL rasterization rules, need to tweak the
30563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * screen-space coordinates slightly relative to D3D which is
30663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * what hardware implements natively.
30763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
30863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (svga->curr.rast->templ.gl_rasterization_rules) {
30963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      float adjust_x = 0.0;
31063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      float adjust_y = 0.0;
31163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
31263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      switch (svga->curr.reduced_prim) {
31363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      case PIPE_PRIM_LINES:
31463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         adjust_x = -0.5;
31563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         adjust_y = 0;
31663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         break;
31763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      case PIPE_PRIM_POINTS:
31863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      case PIPE_PRIM_TRIANGLES:
3196638b4a590aa07dbe05f6647da90a00a4c0d57a8Brian Paul         adjust_x = -0.5;
32063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         adjust_y = -0.5;
32163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol         break;
3223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
3233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3241459c18f45f5bd2a2d99145247093f1b540478adBrian Paul      if (invertY)
3251459c18f45f5bd2a2d99145247093f1b540478adBrian Paul         adjust_y = -adjust_y;
3261459c18f45f5bd2a2d99145247093f1b540478adBrian Paul
32763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[0] += adjust_x;
32863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[1] += adjust_y;
32963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.translate[2] = 0.5; /* D3D clip space */
33063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[2]     = 0.5; /* D3D clip space */
33163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   }
3323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
33463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   range_min = viewport->scale[2] * -1.0 + viewport->translate[2];
33563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   range_max = viewport->scale[2] *  1.0 + viewport->translate[2];
33663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol
33763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   /* D3D (and by implication SVGA) doesn't like dealing with zmax
33863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * less than zmin.  Detect that case, flip the depth range and
33963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    * invert our z-scale factor to achieve the same effect.
34063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol    */
34163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   if (range_min > range_max) {
34263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      float range_tmp;
34363cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      range_tmp = range_min;
34463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      range_min = range_max;
34563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      range_max = range_tmp;
34663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      prescale.scale[2]     = -prescale.scale[2];
3473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
3483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (prescale.enabled) {
3503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      float H[2];
3513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      float J[2];
3523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      int i;
3533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA_DBG(DEBUG_VIEWPORT,
3553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "prescale %f,%f %fx%f\n",
3563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[0],
3573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[1],
3583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[0],
3593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[1]);
3603192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3613192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      H[0] = (float)rect.w / 2.0;
3623192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      H[1] = -(float)rect.h / 2.0;
3633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      J[0] = (float)rect.x + (float)rect.w / 2.0;
3643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      J[1] = (float)rect.y + (float)rect.h / 2.0;
3653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA_DBG(DEBUG_VIEWPORT,
3673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "H %f,%f\n"
3683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "J %fx%f\n",
3693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               H[0],
3703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               H[1],
3713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               J[0],
3723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               J[1]);
3733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
3743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      /* Adjust prescale to take into account the fact that it is
3753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * going to be applied prior to the perspective divide and
3763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * viewport transformation.
3773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Vwin = H(Vc/Vc.w) + J
3793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * We want to tweak Vwin with scale and translation from above,
3813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * as in:
3823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Vwin' = S Vwin + T
3843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * But we can only modify the values at Vc.  Plugging all the
3863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * above together, and rearranging, eventually we get:
3873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3883192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   Vwin' = H(Vc'/Vc'.w) + J
3893192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * where:
3903192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   Vc' = SVc + KVc.w
3913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *   K = (T + (S-1)J) / H
3923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       *
3933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       * Overwrite prescale.translate with values for K:
3943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       */
3953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      for (i = 0; i < 2; i++) {
3963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         prescale.translate[i] = ((prescale.translate[i] +
3973192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz                                   (prescale.scale[i] - 1.0) * J[i]) / H[i]);
3983192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      }
3993192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4003192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      SVGA_DBG(DEBUG_VIEWPORT,
4013192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               "clipspace %f,%f %fx%f\n",
4023192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[0],
4033192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.translate[1],
4043192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[0],
4053192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz               prescale.scale[1]);
4063192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4073192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4083192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzout:
4093192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (degenerate) {
4103192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.x = 0;
4113192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.y = 0;
4123192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.w = 1;
4133192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      rect.h = 1;
4143192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      prescale.enabled = FALSE;
4153192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4163192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4173192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (memcmp(&rect, &svga->state.hw_clear.viewport, sizeof(rect)) != 0) {
4183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = SVGA3D_SetViewport(svga->swc, &rect);
4193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(ret != PIPE_OK)
4203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
4213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4223192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      memcpy(&svga->state.hw_clear.viewport, &rect, sizeof(rect));
4233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      assert(sizeof(rect) == sizeof(svga->state.hw_clear.viewport));
4243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (svga->state.hw_clear.depthrange.zmin != range_min ||
4273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz       svga->state.hw_clear.depthrange.zmax != range_max)
4283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   {
4293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      ret = SVGA3D_SetZRange(svga->swc, range_min, range_max );
4303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(ret != PIPE_OK)
4313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
4323192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4333192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->state.hw_clear.depthrange.zmin = range_min;
4343192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->state.hw_clear.depthrange.zmax = range_max;
4353192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4363192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4373192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   if (memcmp(&prescale, &svga->state.hw_clear.prescale, sizeof prescale) != 0) {
4383192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->dirty |= SVGA_NEW_PRESCALE;
4393192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      svga->state.hw_clear.prescale = prescale;
4403192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
4413192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4422786343896030ed4abcf6674a3e66f3a0d246e0dBrian Paul   return PIPE_OK;
4433192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4443192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4453192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4463192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_viewport =
4473192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4483192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw viewport state",
4493192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   ( SVGA_NEW_FRAME_BUFFER |
4503192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz     SVGA_NEW_VIEWPORT |
4513192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz     SVGA_NEW_RAST |
4523192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz     SVGA_NEW_REDUCED_PRIMITIVE ),
4533192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_viewport
4543192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
4553192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4563192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4573192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
4583192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Scissor state
4593192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
460e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecastatic enum pipe_error
461e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecaemit_scissor_rect( struct svga_context *svga,
462e8f646fa7e9cf6f6793864384128157735aa03b3José Fonseca                   unsigned dirty )
4633192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4643192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   const struct pipe_scissor_state *scissor = &svga->curr.scissor;
4653192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA3dRect rect;
4663192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4673192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.x = scissor->minx;
4683192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.y = scissor->miny;
4693192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.w = scissor->maxx - scissor->minx; /* + 1 ?? */
4703192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   rect.h = scissor->maxy - scissor->miny; /* + 1 ?? */
4713192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4723192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   return SVGA3D_SetScissorRect(svga->swc, &rect);
4733192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
4743192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4753192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4763192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_scissor =
4773192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4783192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw scissor state",
4793192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA_NEW_SCISSOR,
4803192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_scissor_rect
4813192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
4823192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4833192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4843192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz/***********************************************************************
4853192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz * Userclip state
4863192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz */
4873192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
488e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecastatic enum pipe_error
489e8f646fa7e9cf6f6793864384128157735aa03b3José Fonsecaemit_clip_planes( struct svga_context *svga,
490e8f646fa7e9cf6f6793864384128157735aa03b3José Fonseca                  unsigned dirty )
4913192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
4923192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   unsigned i;
4933192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   enum pipe_error ret;
4943192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
4953192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   /* TODO: just emit directly from svga_set_clip_state()?
4963192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz    */
497ce2929dde021e5754a3926b77b86b4de3208f4b0José Fonseca   for (i = 0; i < SVGA3D_MAX_CLIP_PLANES; i++) {
4980be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      /* need to express the plane in D3D-style coordinate space.
4990be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * GL coords get converted to D3D coords with the matrix:
5000be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 1  0  0  0 ]
5010be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 0 -1  0  0 ]
5020be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 0  0  2  0 ]
5030be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * [ 0  0 -1  1 ]
5040be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       * Apply that matrix to our plane equation, and invert Y.
5050be6ae74e9a56e84df088392ef3b09229508404fBrian Paul       */
5060be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float a = svga->curr.clip.ucp[i][0];
5070be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float b = svga->curr.clip.ucp[i][1];
5080be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float c = svga->curr.clip.ucp[i][2];
5090be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float d = svga->curr.clip.ucp[i][3];
5100be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      float plane[4];
5110be6ae74e9a56e84df088392ef3b09229508404fBrian Paul
5120be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[0] = a;
5130be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[1] = b;
5140be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[2] = 2.0f * c;
5150be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      plane[3] = d - c;
5160be6ae74e9a56e84df088392ef3b09229508404fBrian Paul
5170be6ae74e9a56e84df088392ef3b09229508404fBrian Paul      ret = SVGA3D_SetClipPlane(svga->swc, i, plane);
5183192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz      if(ret != PIPE_OK)
5193192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz         return ret;
5203192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   }
5213192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5222786343896030ed4abcf6674a3e66f3a0d246e0dBrian Paul   return PIPE_OK;
5233192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz}
5243192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5253192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz
5263192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantzstruct svga_tracked_state svga_hw_clip_planes =
5273192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz{
5283192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   "hw viewport state",
5293192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   SVGA_NEW_CLIP,
5303192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz   emit_clip_planes
5313192633d4abe262d413e41feb871fe8deed409d8Jakob Bornecrantz};
532