1bf215546Sopenharmony_ci/********************************************************** 2bf215546Sopenharmony_ci * Copyright 2008-2009 VMware, Inc. All rights reserved. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person 5bf215546Sopenharmony_ci * obtaining a copy of this software and associated documentation 6bf215546Sopenharmony_ci * files (the "Software"), to deal in the Software without 7bf215546Sopenharmony_ci * restriction, including without limitation the rights to use, copy, 8bf215546Sopenharmony_ci * modify, merge, publish, distribute, sublicense, and/or sell copies 9bf215546Sopenharmony_ci * of the Software, and to permit persons to whom the Software is 10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be 13bf215546Sopenharmony_ci * included in all copies or substantial portions of the Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18bf215546Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19bf215546Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20bf215546Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21bf215546Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci **********************************************************/ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include "pipe/p_defines.h" 27bf215546Sopenharmony_ci#include "draw/draw_context.h" 28bf215546Sopenharmony_ci#include "util/u_bitmask.h" 29bf215546Sopenharmony_ci#include "util/u_inlines.h" 30bf215546Sopenharmony_ci#include "util/u_math.h" 31bf215546Sopenharmony_ci#include "util/u_memory.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "svga_cmd.h" 34bf215546Sopenharmony_ci#include "svga_context.h" 35bf215546Sopenharmony_ci#include "svga_hw_reg.h" 36bf215546Sopenharmony_ci#include "svga_screen.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci/* Hardware frontwinding is always set up as SVGA3D_FRONTWINDING_CW. 40bf215546Sopenharmony_ci */ 41bf215546Sopenharmony_cistatic SVGA3dFace 42bf215546Sopenharmony_cisvga_translate_cullmode(unsigned mode, unsigned front_ccw) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci const int hw_front_ccw = 0; /* hardware is always CW */ 45bf215546Sopenharmony_ci switch (mode) { 46bf215546Sopenharmony_ci case PIPE_FACE_NONE: 47bf215546Sopenharmony_ci return SVGA3D_FACE_NONE; 48bf215546Sopenharmony_ci case PIPE_FACE_FRONT: 49bf215546Sopenharmony_ci return front_ccw == hw_front_ccw ? SVGA3D_FACE_FRONT : SVGA3D_FACE_BACK; 50bf215546Sopenharmony_ci case PIPE_FACE_BACK: 51bf215546Sopenharmony_ci return front_ccw == hw_front_ccw ? SVGA3D_FACE_BACK : SVGA3D_FACE_FRONT; 52bf215546Sopenharmony_ci case PIPE_FACE_FRONT_AND_BACK: 53bf215546Sopenharmony_ci return SVGA3D_FACE_FRONT_BACK; 54bf215546Sopenharmony_ci default: 55bf215546Sopenharmony_ci assert(0); 56bf215546Sopenharmony_ci return SVGA3D_FACE_NONE; 57bf215546Sopenharmony_ci } 58bf215546Sopenharmony_ci} 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_cistatic SVGA3dShadeMode 61bf215546Sopenharmony_cisvga_translate_flatshade(unsigned mode) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci return mode ? SVGA3D_SHADEMODE_FLAT : SVGA3D_SHADEMODE_SMOOTH; 64bf215546Sopenharmony_ci} 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_cistatic unsigned 68bf215546Sopenharmony_citranslate_fill_mode(unsigned fill) 69bf215546Sopenharmony_ci{ 70bf215546Sopenharmony_ci switch (fill) { 71bf215546Sopenharmony_ci case PIPE_POLYGON_MODE_POINT: 72bf215546Sopenharmony_ci return SVGA3D_FILLMODE_POINT; 73bf215546Sopenharmony_ci case PIPE_POLYGON_MODE_LINE: 74bf215546Sopenharmony_ci return SVGA3D_FILLMODE_LINE; 75bf215546Sopenharmony_ci case PIPE_POLYGON_MODE_FILL: 76bf215546Sopenharmony_ci return SVGA3D_FILLMODE_FILL; 77bf215546Sopenharmony_ci default: 78bf215546Sopenharmony_ci assert(!"Bad fill mode"); 79bf215546Sopenharmony_ci return SVGA3D_FILLMODE_FILL; 80bf215546Sopenharmony_ci } 81bf215546Sopenharmony_ci} 82bf215546Sopenharmony_ci 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_cistatic unsigned 85bf215546Sopenharmony_citranslate_cull_mode(unsigned cull) 86bf215546Sopenharmony_ci{ 87bf215546Sopenharmony_ci switch (cull) { 88bf215546Sopenharmony_ci case PIPE_FACE_NONE: 89bf215546Sopenharmony_ci return SVGA3D_CULL_NONE; 90bf215546Sopenharmony_ci case PIPE_FACE_FRONT: 91bf215546Sopenharmony_ci return SVGA3D_CULL_FRONT; 92bf215546Sopenharmony_ci case PIPE_FACE_BACK: 93bf215546Sopenharmony_ci return SVGA3D_CULL_BACK; 94bf215546Sopenharmony_ci case PIPE_FACE_FRONT_AND_BACK: 95bf215546Sopenharmony_ci /* NOTE: we simply no-op polygon drawing in svga_draw_vbo() */ 96bf215546Sopenharmony_ci return SVGA3D_CULL_NONE; 97bf215546Sopenharmony_ci default: 98bf215546Sopenharmony_ci assert(!"Bad cull mode"); 99bf215546Sopenharmony_ci return SVGA3D_CULL_NONE; 100bf215546Sopenharmony_ci } 101bf215546Sopenharmony_ci} 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ciint 105bf215546Sopenharmony_cisvga_define_rasterizer_object(struct svga_context *svga, 106bf215546Sopenharmony_ci struct svga_rasterizer_state *rast, 107bf215546Sopenharmony_ci unsigned samples) 108bf215546Sopenharmony_ci{ 109bf215546Sopenharmony_ci struct svga_screen *svgascreen = svga_screen(svga->pipe.screen); 110bf215546Sopenharmony_ci unsigned fill_mode = translate_fill_mode(rast->templ.fill_front); 111bf215546Sopenharmony_ci const unsigned cull_mode = translate_cull_mode(rast->templ.cull_face); 112bf215546Sopenharmony_ci const int depth_bias = rast->templ.offset_units; 113bf215546Sopenharmony_ci const float slope_scaled_depth_bias = rast->templ.offset_scale; 114bf215546Sopenharmony_ci /* PIPE_CAP_POLYGON_OFFSET_CLAMP not supported: */ 115bf215546Sopenharmony_ci const float depth_bias_clamp = 0.0; 116bf215546Sopenharmony_ci const float line_width = rast->templ.line_width > 0.0f ? 117bf215546Sopenharmony_ci rast->templ.line_width : 1.0f; 118bf215546Sopenharmony_ci const uint8 line_factor = rast->templ.line_stipple_enable ? 119bf215546Sopenharmony_ci rast->templ.line_stipple_factor : 0; 120bf215546Sopenharmony_ci const uint16 line_pattern = rast->templ.line_stipple_enable ? 121bf215546Sopenharmony_ci rast->templ.line_stipple_pattern : 0; 122bf215546Sopenharmony_ci const uint8 pv_last = !rast->templ.flatshade_first && 123bf215546Sopenharmony_ci svgascreen->haveProvokingVertex; 124bf215546Sopenharmony_ci int rastId; 125bf215546Sopenharmony_ci enum pipe_error ret; 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci rastId = util_bitmask_add(svga->rast_object_id_bm); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci if (rast->templ.fill_front != rast->templ.fill_back) { 130bf215546Sopenharmony_ci /* The VGPU10 device can't handle different front/back fill modes. 131bf215546Sopenharmony_ci * We'll handle that with a swtnl/draw fallback. But we need to 132bf215546Sopenharmony_ci * make sure we always fill triangles in that case. 133bf215546Sopenharmony_ci */ 134bf215546Sopenharmony_ci fill_mode = SVGA3D_FILLMODE_FILL; 135bf215546Sopenharmony_ci } 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci if (samples > 1 && svga_have_gl43(svga) && 138bf215546Sopenharmony_ci svgascreen->sws->have_rasterizer_state_v2_cmd) { 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci ret = SVGA3D_sm5_DefineRasterizerState_v2(svga->swc, 141bf215546Sopenharmony_ci rastId, 142bf215546Sopenharmony_ci fill_mode, 143bf215546Sopenharmony_ci cull_mode, 144bf215546Sopenharmony_ci rast->templ.front_ccw, 145bf215546Sopenharmony_ci depth_bias, 146bf215546Sopenharmony_ci depth_bias_clamp, 147bf215546Sopenharmony_ci slope_scaled_depth_bias, 148bf215546Sopenharmony_ci rast->templ.depth_clip_near, 149bf215546Sopenharmony_ci rast->templ.scissor, 150bf215546Sopenharmony_ci rast->templ.multisample, 151bf215546Sopenharmony_ci rast->templ.line_smooth, 152bf215546Sopenharmony_ci line_width, 153bf215546Sopenharmony_ci rast->templ.line_stipple_enable, 154bf215546Sopenharmony_ci line_factor, 155bf215546Sopenharmony_ci line_pattern, 156bf215546Sopenharmony_ci pv_last, 157bf215546Sopenharmony_ci samples); 158bf215546Sopenharmony_ci } else { 159bf215546Sopenharmony_ci ret = SVGA3D_vgpu10_DefineRasterizerState(svga->swc, 160bf215546Sopenharmony_ci rastId, 161bf215546Sopenharmony_ci fill_mode, 162bf215546Sopenharmony_ci cull_mode, 163bf215546Sopenharmony_ci rast->templ.front_ccw, 164bf215546Sopenharmony_ci depth_bias, 165bf215546Sopenharmony_ci depth_bias_clamp, 166bf215546Sopenharmony_ci slope_scaled_depth_bias, 167bf215546Sopenharmony_ci rast->templ.depth_clip_near, 168bf215546Sopenharmony_ci rast->templ.scissor, 169bf215546Sopenharmony_ci rast->templ.multisample, 170bf215546Sopenharmony_ci rast->templ.line_smooth, 171bf215546Sopenharmony_ci line_width, 172bf215546Sopenharmony_ci rast->templ.line_stipple_enable, 173bf215546Sopenharmony_ci line_factor, 174bf215546Sopenharmony_ci line_pattern, 175bf215546Sopenharmony_ci pv_last); 176bf215546Sopenharmony_ci } 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci if (ret != PIPE_OK) { 179bf215546Sopenharmony_ci util_bitmask_clear(svga->rast_object_id_bm, rastId); 180bf215546Sopenharmony_ci return SVGA3D_INVALID_ID; 181bf215546Sopenharmony_ci } 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci return rastId; 184bf215546Sopenharmony_ci} 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_cistatic void * 188bf215546Sopenharmony_cisvga_create_rasterizer_state(struct pipe_context *pipe, 189bf215546Sopenharmony_ci const struct pipe_rasterizer_state *templ) 190bf215546Sopenharmony_ci{ 191bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 192bf215546Sopenharmony_ci struct svga_rasterizer_state *rast = CALLOC_STRUCT(svga_rasterizer_state); 193bf215546Sopenharmony_ci struct svga_screen *screen = svga_screen(pipe->screen); 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci if (!rast) 196bf215546Sopenharmony_ci return NULL; 197bf215546Sopenharmony_ci 198bf215546Sopenharmony_ci /* need this for draw module. */ 199bf215546Sopenharmony_ci rast->templ = *templ; 200bf215546Sopenharmony_ci 201bf215546Sopenharmony_ci rast->shademode = svga_translate_flatshade(templ->flatshade); 202bf215546Sopenharmony_ci rast->cullmode = svga_translate_cullmode(templ->cull_face, templ->front_ccw); 203bf215546Sopenharmony_ci rast->scissortestenable = templ->scissor; 204bf215546Sopenharmony_ci rast->multisampleantialias = templ->multisample; 205bf215546Sopenharmony_ci rast->antialiasedlineenable = templ->line_smooth; 206bf215546Sopenharmony_ci rast->lastpixel = templ->line_last_pixel; 207bf215546Sopenharmony_ci rast->pointsprite = templ->point_quad_rasterization; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci if (rast->templ.multisample) { 210bf215546Sopenharmony_ci /* The OpenGL 3.0 spec says points are always drawn as circles when 211bf215546Sopenharmony_ci * MSAA is enabled. Note that our implementation isn't 100% correct, 212bf215546Sopenharmony_ci * though. Our smooth point implementation involves drawing a square, 213bf215546Sopenharmony_ci * computing fragment distance from point center, then attenuating 214bf215546Sopenharmony_ci * the fragment alpha value. We should not attenuate alpha if msaa 215bf215546Sopenharmony_ci * is enabled. We should discard fragments entirely outside the circle 216bf215546Sopenharmony_ci * and let the GPU compute per-fragment coverage. 217bf215546Sopenharmony_ci * But as-is, our implementation gives acceptable results and passes 218bf215546Sopenharmony_ci * Piglit's MSAA point smooth test. 219bf215546Sopenharmony_ci */ 220bf215546Sopenharmony_ci rast->templ.point_smooth = TRUE; 221bf215546Sopenharmony_ci } 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci if (rast->templ.point_smooth && 224bf215546Sopenharmony_ci rast->templ.point_size_per_vertex == 0 && 225bf215546Sopenharmony_ci rast->templ.point_size <= screen->pointSmoothThreshold) { 226bf215546Sopenharmony_ci /* If the point size is less than the threshold, deactivate smoothing. 227bf215546Sopenharmony_ci * Note that this only effects point rendering when we use the 228bf215546Sopenharmony_ci * pipe_rasterizer_state::point_size value, not when the point size 229bf215546Sopenharmony_ci * is set in the VS. 230bf215546Sopenharmony_ci */ 231bf215546Sopenharmony_ci rast->templ.point_smooth = FALSE; 232bf215546Sopenharmony_ci } 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci if (rast->templ.point_smooth) { 235bf215546Sopenharmony_ci /* For smooth points we need to generate fragments for at least 236bf215546Sopenharmony_ci * a 2x2 region. Otherwise the quad we draw may be too small and 237bf215546Sopenharmony_ci * we may generate no fragments at all. 238bf215546Sopenharmony_ci */ 239bf215546Sopenharmony_ci rast->pointsize = MAX2(2.0f, templ->point_size); 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci else { 242bf215546Sopenharmony_ci rast->pointsize = templ->point_size; 243bf215546Sopenharmony_ci } 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci rast->hw_fillmode = PIPE_POLYGON_MODE_FILL; 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci /* Use swtnl + decomposition implement these: 248bf215546Sopenharmony_ci */ 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci if (templ->line_width <= screen->maxLineWidth) { 251bf215546Sopenharmony_ci /* pass line width to device */ 252bf215546Sopenharmony_ci rast->linewidth = MAX2(1.0F, templ->line_width); 253bf215546Sopenharmony_ci } 254bf215546Sopenharmony_ci else if (svga->debug.no_line_width) { 255bf215546Sopenharmony_ci /* nothing */ 256bf215546Sopenharmony_ci } 257bf215546Sopenharmony_ci else { 258bf215546Sopenharmony_ci /* use 'draw' pipeline for wide line */ 259bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES; 260bf215546Sopenharmony_ci rast->need_pipeline_lines_str = "line width"; 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci if (templ->line_stipple_enable) { 264bf215546Sopenharmony_ci if (screen->haveLineStipple || svga->debug.force_hw_line_stipple) { 265bf215546Sopenharmony_ci SVGA3dLinePattern lp; 266bf215546Sopenharmony_ci lp.repeat = templ->line_stipple_factor + 1; 267bf215546Sopenharmony_ci lp.pattern = templ->line_stipple_pattern; 268bf215546Sopenharmony_ci rast->linepattern = lp.uintValue; 269bf215546Sopenharmony_ci } 270bf215546Sopenharmony_ci else { 271bf215546Sopenharmony_ci /* use 'draw' module to decompose into short line segments */ 272bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES; 273bf215546Sopenharmony_ci rast->need_pipeline_lines_str = "line stipple"; 274bf215546Sopenharmony_ci } 275bf215546Sopenharmony_ci } 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci if (!svga_have_vgpu10(svga) && rast->templ.point_smooth) { 278bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_POINTS; 279bf215546Sopenharmony_ci rast->need_pipeline_points_str = "smooth points"; 280bf215546Sopenharmony_ci } 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci if (templ->line_smooth && !screen->haveLineSmooth) { 283bf215546Sopenharmony_ci /* 284bf215546Sopenharmony_ci * XXX: Enabling the pipeline slows down performance immensely, so ignore 285bf215546Sopenharmony_ci * line smooth state, where there is very little visual improvement. 286bf215546Sopenharmony_ci * Smooth lines will still be drawn for wide lines. 287bf215546Sopenharmony_ci */ 288bf215546Sopenharmony_ci#if 0 289bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_LINES; 290bf215546Sopenharmony_ci rast->need_pipeline_lines_str = "smooth lines"; 291bf215546Sopenharmony_ci#endif 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci { 295bf215546Sopenharmony_ci int fill_front = templ->fill_front; 296bf215546Sopenharmony_ci int fill_back = templ->fill_back; 297bf215546Sopenharmony_ci int fill = PIPE_POLYGON_MODE_FILL; 298bf215546Sopenharmony_ci boolean offset_front = util_get_offset(templ, fill_front); 299bf215546Sopenharmony_ci boolean offset_back = util_get_offset(templ, fill_back); 300bf215546Sopenharmony_ci boolean offset = FALSE; 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci switch (templ->cull_face) { 303bf215546Sopenharmony_ci case PIPE_FACE_FRONT_AND_BACK: 304bf215546Sopenharmony_ci offset = FALSE; 305bf215546Sopenharmony_ci fill = PIPE_POLYGON_MODE_FILL; 306bf215546Sopenharmony_ci break; 307bf215546Sopenharmony_ci 308bf215546Sopenharmony_ci case PIPE_FACE_FRONT: 309bf215546Sopenharmony_ci offset = offset_back; 310bf215546Sopenharmony_ci fill = fill_back; 311bf215546Sopenharmony_ci break; 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_ci case PIPE_FACE_BACK: 314bf215546Sopenharmony_ci offset = offset_front; 315bf215546Sopenharmony_ci fill = fill_front; 316bf215546Sopenharmony_ci break; 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci case PIPE_FACE_NONE: 319bf215546Sopenharmony_ci if (fill_front != fill_back || offset_front != offset_back) { 320bf215546Sopenharmony_ci /* Always need the draw module to work out different 321bf215546Sopenharmony_ci * front/back fill modes: 322bf215546Sopenharmony_ci */ 323bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; 324bf215546Sopenharmony_ci rast->need_pipeline_tris_str = "different front/back fillmodes"; 325bf215546Sopenharmony_ci fill = PIPE_POLYGON_MODE_FILL; 326bf215546Sopenharmony_ci } 327bf215546Sopenharmony_ci else { 328bf215546Sopenharmony_ci offset = offset_front; 329bf215546Sopenharmony_ci fill = fill_front; 330bf215546Sopenharmony_ci } 331bf215546Sopenharmony_ci break; 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci default: 334bf215546Sopenharmony_ci assert(0); 335bf215546Sopenharmony_ci break; 336bf215546Sopenharmony_ci } 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci /* Unfilled primitive modes aren't implemented on all virtual 339bf215546Sopenharmony_ci * hardware. We can do some unfilled processing with index 340bf215546Sopenharmony_ci * translation, but otherwise need the draw module: 341bf215546Sopenharmony_ci */ 342bf215546Sopenharmony_ci if (fill != PIPE_POLYGON_MODE_FILL && 343bf215546Sopenharmony_ci (templ->flatshade || 344bf215546Sopenharmony_ci templ->light_twoside || 345bf215546Sopenharmony_ci offset)) { 346bf215546Sopenharmony_ci fill = PIPE_POLYGON_MODE_FILL; 347bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; 348bf215546Sopenharmony_ci rast->need_pipeline_tris_str = "unfilled primitives with no index manipulation"; 349bf215546Sopenharmony_ci } 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci /* If we are decomposing to lines, and lines need the pipeline, 352bf215546Sopenharmony_ci * then we also need the pipeline for tris. 353bf215546Sopenharmony_ci */ 354bf215546Sopenharmony_ci if (fill == PIPE_POLYGON_MODE_LINE && 355bf215546Sopenharmony_ci (rast->need_pipeline & SVGA_PIPELINE_FLAG_LINES)) { 356bf215546Sopenharmony_ci fill = PIPE_POLYGON_MODE_FILL; 357bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; 358bf215546Sopenharmony_ci rast->need_pipeline_tris_str = "decomposing lines"; 359bf215546Sopenharmony_ci } 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci /* Similarly for points: 362bf215546Sopenharmony_ci */ 363bf215546Sopenharmony_ci if (fill == PIPE_POLYGON_MODE_POINT && 364bf215546Sopenharmony_ci (rast->need_pipeline & SVGA_PIPELINE_FLAG_POINTS)) { 365bf215546Sopenharmony_ci fill = PIPE_POLYGON_MODE_FILL; 366bf215546Sopenharmony_ci rast->need_pipeline |= SVGA_PIPELINE_FLAG_TRIS; 367bf215546Sopenharmony_ci rast->need_pipeline_tris_str = "decomposing points"; 368bf215546Sopenharmony_ci } 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci if (offset) { 371bf215546Sopenharmony_ci rast->slopescaledepthbias = templ->offset_scale; 372bf215546Sopenharmony_ci rast->depthbias = templ->offset_units; 373bf215546Sopenharmony_ci } 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci rast->hw_fillmode = fill; 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci if (rast->need_pipeline & SVGA_PIPELINE_FLAG_TRIS) { 379bf215546Sopenharmony_ci /* Turn off stuff which will get done in the draw module: 380bf215546Sopenharmony_ci */ 381bf215546Sopenharmony_ci rast->hw_fillmode = PIPE_POLYGON_MODE_FILL; 382bf215546Sopenharmony_ci rast->slopescaledepthbias = 0; 383bf215546Sopenharmony_ci rast->depthbias = 0; 384bf215546Sopenharmony_ci } 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci if (0 && rast->need_pipeline) { 387bf215546Sopenharmony_ci debug_printf("svga: rast need_pipeline = 0x%x\n", rast->need_pipeline); 388bf215546Sopenharmony_ci debug_printf(" pnts: %s \n", rast->need_pipeline_points_str); 389bf215546Sopenharmony_ci debug_printf(" lins: %s \n", rast->need_pipeline_lines_str); 390bf215546Sopenharmony_ci debug_printf(" tris: %s \n", rast->need_pipeline_tris_str); 391bf215546Sopenharmony_ci } 392bf215546Sopenharmony_ci 393bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 394bf215546Sopenharmony_ci rast->id = svga_define_rasterizer_object(svga, rast, 0); 395bf215546Sopenharmony_ci if (rast->id == SVGA3D_INVALID_ID) { 396bf215546Sopenharmony_ci svga_context_flush(svga, NULL); 397bf215546Sopenharmony_ci rast->id = svga_define_rasterizer_object(svga, rast, 0); 398bf215546Sopenharmony_ci assert(rast->id != SVGA3D_INVALID_ID); 399bf215546Sopenharmony_ci } 400bf215546Sopenharmony_ci } 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci if (svga_have_gl43(svga)) { 403bf215546Sopenharmony_ci /* initialize the alternate rasterizer state ids. 404bf215546Sopenharmony_ci * For 0 and 1 sample count, we can use the same rasterizer object. 405bf215546Sopenharmony_ci */ 406bf215546Sopenharmony_ci rast->altRastIds[0] = rast->altRastIds[1] = rast->id; 407bf215546Sopenharmony_ci 408bf215546Sopenharmony_ci for (unsigned i = 2; i < ARRAY_SIZE(rast->altRastIds); i++) { 409bf215546Sopenharmony_ci rast->altRastIds[i] = SVGA3D_INVALID_ID; 410bf215546Sopenharmony_ci } 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci if (templ->poly_smooth) { 414bf215546Sopenharmony_ci util_debug_message(&svga->debug.callback, CONFORMANCE, 415bf215546Sopenharmony_ci "GL_POLYGON_SMOOTH not supported"); 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci svga->hud.num_rasterizer_objects++; 419bf215546Sopenharmony_ci SVGA_STATS_COUNT_INC(svga_screen(svga->pipe.screen)->sws, 420bf215546Sopenharmony_ci SVGA_STATS_COUNT_RASTERIZERSTATE); 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci return rast; 423bf215546Sopenharmony_ci} 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_cistatic void 427bf215546Sopenharmony_cisvga_bind_rasterizer_state(struct pipe_context *pipe, void *state) 428bf215546Sopenharmony_ci{ 429bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 430bf215546Sopenharmony_ci struct svga_rasterizer_state *raster = (struct svga_rasterizer_state *)state; 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci if (!raster || !svga->curr.rast) { 433bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_STIPPLE | SVGA_NEW_DEPTH_STENCIL_ALPHA; 434bf215546Sopenharmony_ci } 435bf215546Sopenharmony_ci else { 436bf215546Sopenharmony_ci if (raster->templ.poly_stipple_enable != 437bf215546Sopenharmony_ci svga->curr.rast->templ.poly_stipple_enable) { 438bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_STIPPLE; 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci if (raster->templ.rasterizer_discard != 441bf215546Sopenharmony_ci svga->curr.rast->templ.rasterizer_discard) { 442bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_DEPTH_STENCIL_ALPHA; 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci } 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci svga->curr.rast = raster; 447bf215546Sopenharmony_ci 448bf215546Sopenharmony_ci svga->dirty |= SVGA_NEW_RAST; 449bf215546Sopenharmony_ci} 450bf215546Sopenharmony_ci 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_cistatic void 453bf215546Sopenharmony_cisvga_delete_rasterizer_state(struct pipe_context *pipe, void *state) 454bf215546Sopenharmony_ci{ 455bf215546Sopenharmony_ci struct svga_context *svga = svga_context(pipe); 456bf215546Sopenharmony_ci struct svga_rasterizer_state *raster = 457bf215546Sopenharmony_ci (struct svga_rasterizer_state *) state; 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci /* free any alternate rasterizer state used for point sprite */ 460bf215546Sopenharmony_ci if (raster->no_cull_rasterizer) 461bf215546Sopenharmony_ci svga_delete_rasterizer_state(pipe, (void *)(raster->no_cull_rasterizer)); 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci if (svga_have_vgpu10(svga)) { 464bf215546Sopenharmony_ci SVGA_RETRY(svga, SVGA3D_vgpu10_DestroyRasterizerState(svga->swc, 465bf215546Sopenharmony_ci raster->id)); 466bf215546Sopenharmony_ci 467bf215546Sopenharmony_ci if (raster->id == svga->state.hw_draw.rasterizer_id) 468bf215546Sopenharmony_ci svga->state.hw_draw.rasterizer_id = SVGA3D_INVALID_ID; 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_ci util_bitmask_clear(svga->rast_object_id_bm, raster->id); 471bf215546Sopenharmony_ci } 472bf215546Sopenharmony_ci 473bf215546Sopenharmony_ci FREE(state); 474bf215546Sopenharmony_ci svga->hud.num_rasterizer_objects--; 475bf215546Sopenharmony_ci} 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_civoid 479bf215546Sopenharmony_cisvga_init_rasterizer_functions(struct svga_context *svga) 480bf215546Sopenharmony_ci{ 481bf215546Sopenharmony_ci svga->pipe.create_rasterizer_state = svga_create_rasterizer_state; 482bf215546Sopenharmony_ci svga->pipe.bind_rasterizer_state = svga_bind_rasterizer_state; 483bf215546Sopenharmony_ci svga->pipe.delete_rasterizer_state = svga_delete_rasterizer_state; 484bf215546Sopenharmony_ci} 485