1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2007 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "pipe/p_defines.h"
29bf215546Sopenharmony_ci#include "util/u_memory.h"
30bf215546Sopenharmony_ci#include "lp_context.h"
31bf215546Sopenharmony_ci#include "lp_state.h"
32bf215546Sopenharmony_ci#include "lp_setup.h"
33bf215546Sopenharmony_ci#include "draw/draw_context.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_cistruct lp_rasterizer_state {
36bf215546Sopenharmony_ci   struct pipe_rasterizer_state lp_state;
37bf215546Sopenharmony_ci   struct pipe_rasterizer_state draw_state;
38bf215546Sopenharmony_ci};
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci/* State which might be handled in either the draw module or locally.
41bf215546Sopenharmony_ci * This function is used to turn that state off in one of the two
42bf215546Sopenharmony_ci * places.
43bf215546Sopenharmony_ci */
44bf215546Sopenharmony_cistatic void
45bf215546Sopenharmony_ciclear_flags(struct pipe_rasterizer_state *rast)
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   rast->light_twoside = 0;
48bf215546Sopenharmony_ci   rast->offset_tri = 0;
49bf215546Sopenharmony_ci   rast->offset_line = 0;
50bf215546Sopenharmony_ci   rast->offset_point = 0;
51bf215546Sopenharmony_ci   rast->offset_units = 0.0f;
52bf215546Sopenharmony_ci   rast->offset_scale = 0.0f;
53bf215546Sopenharmony_ci}
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_cistatic void *
58bf215546Sopenharmony_cillvmpipe_create_rasterizer_state(struct pipe_context *pipe,
59bf215546Sopenharmony_ci                                 const struct pipe_rasterizer_state *rast)
60bf215546Sopenharmony_ci{
61bf215546Sopenharmony_ci   boolean need_pipeline;
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   /* Partition rasterizer state into what we want the draw module to
64bf215546Sopenharmony_ci    * handle, and what we'll look after ourselves.
65bf215546Sopenharmony_ci    */
66bf215546Sopenharmony_ci   struct lp_rasterizer_state *state = MALLOC_STRUCT(lp_rasterizer_state);
67bf215546Sopenharmony_ci   if (!state)
68bf215546Sopenharmony_ci      return NULL;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   memcpy(&state->draw_state, rast, sizeof *rast);
71bf215546Sopenharmony_ci   memcpy(&state->lp_state, rast, sizeof *rast);
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   /* We rely on draw module to do unfilled polygons, AA lines and
74bf215546Sopenharmony_ci    * points and stipple.
75bf215546Sopenharmony_ci    *
76bf215546Sopenharmony_ci    * Over time, reduce this list of conditions, and expand the list
77bf215546Sopenharmony_ci    * of flags which get cleared in clear_flags().
78bf215546Sopenharmony_ci    */
79bf215546Sopenharmony_ci   need_pipeline = (rast->fill_front != PIPE_POLYGON_MODE_FILL ||
80bf215546Sopenharmony_ci		    rast->fill_back != PIPE_POLYGON_MODE_FILL ||
81bf215546Sopenharmony_ci		    rast->point_smooth ||
82bf215546Sopenharmony_ci		    rast->line_smooth ||
83bf215546Sopenharmony_ci		    rast->line_stipple_enable ||
84bf215546Sopenharmony_ci		    rast->poly_stipple_enable);
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   /* If not using the pipeline, clear out the flags which we can
87bf215546Sopenharmony_ci    * handle ourselves.  If we *are* using the pipeline, do everything
88bf215546Sopenharmony_ci    * on the pipeline and clear those flags on our internal copy of
89bf215546Sopenharmony_ci    * the state.
90bf215546Sopenharmony_ci    */
91bf215546Sopenharmony_ci   if (need_pipeline)
92bf215546Sopenharmony_ci      clear_flags(&state->lp_state);
93bf215546Sopenharmony_ci   else
94bf215546Sopenharmony_ci      clear_flags(&state->draw_state);
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ci   return state;
97bf215546Sopenharmony_ci}
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_cistatic void
102bf215546Sopenharmony_cillvmpipe_bind_rasterizer_state(struct pipe_context *pipe, void *handle)
103bf215546Sopenharmony_ci{
104bf215546Sopenharmony_ci   struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
105bf215546Sopenharmony_ci   const struct lp_rasterizer_state *state =
106bf215546Sopenharmony_ci      (const struct lp_rasterizer_state *) handle;
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci   if (state) {
109bf215546Sopenharmony_ci      llvmpipe->rasterizer = &state->lp_state;
110bf215546Sopenharmony_ci      draw_set_rasterizer_state(llvmpipe->draw, &state->draw_state, handle);
111bf215546Sopenharmony_ci      lp_setup_bind_rasterizer( llvmpipe->setup, &state->lp_state);
112bf215546Sopenharmony_ci   }
113bf215546Sopenharmony_ci   else {
114bf215546Sopenharmony_ci      llvmpipe->rasterizer = NULL;
115bf215546Sopenharmony_ci      draw_set_rasterizer_state(llvmpipe->draw, NULL, handle);
116bf215546Sopenharmony_ci   }
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   llvmpipe->dirty |= LP_NEW_RASTERIZER;
119bf215546Sopenharmony_ci}
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_cistatic void
123bf215546Sopenharmony_cillvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
124bf215546Sopenharmony_ci                                 void *rasterizer)
125bf215546Sopenharmony_ci{
126bf215546Sopenharmony_ci   FREE( rasterizer );
127bf215546Sopenharmony_ci}
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_civoid
132bf215546Sopenharmony_cillvmpipe_init_rasterizer_funcs(struct llvmpipe_context *llvmpipe)
133bf215546Sopenharmony_ci{
134bf215546Sopenharmony_ci   llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
135bf215546Sopenharmony_ci   llvmpipe->pipe.bind_rasterizer_state   = llvmpipe_bind_rasterizer_state;
136bf215546Sopenharmony_ci   llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
137bf215546Sopenharmony_ci}
138