1af69d88dSmrg/* 2af69d88dSmrg * Copyright © 2014 Broadcom 3af69d88dSmrg * 4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 6af69d88dSmrg * to deal in the Software without restriction, including without limitation 7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 10af69d88dSmrg * 11af69d88dSmrg * The above copyright notice and this permission notice (including the next 12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the 13af69d88dSmrg * Software. 14af69d88dSmrg * 15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21af69d88dSmrg * IN THE SOFTWARE. 22af69d88dSmrg */ 23af69d88dSmrg 24af69d88dSmrg#include "vc4_context.h" 25af69d88dSmrg 26af69d88dSmrgvoid 27af69d88dSmrgvc4_emit_state(struct pipe_context *pctx) 28af69d88dSmrg{ 29af69d88dSmrg struct vc4_context *vc4 = vc4_context(pctx); 3001e04c3fSmrg struct vc4_job *job = vc4->job; 31af69d88dSmrg 3201e04c3fSmrg if (vc4->dirty & (VC4_DIRTY_SCISSOR | VC4_DIRTY_VIEWPORT | 3301e04c3fSmrg VC4_DIRTY_RASTERIZER)) { 3401e04c3fSmrg float *vpscale = vc4->viewport.scale; 3501e04c3fSmrg float *vptranslate = vc4->viewport.translate; 3601e04c3fSmrg float vp_minx = -fabsf(vpscale[0]) + vptranslate[0]; 3701e04c3fSmrg float vp_maxx = fabsf(vpscale[0]) + vptranslate[0]; 3801e04c3fSmrg float vp_miny = -fabsf(vpscale[1]) + vptranslate[1]; 3901e04c3fSmrg float vp_maxy = fabsf(vpscale[1]) + vptranslate[1]; 4001e04c3fSmrg 4101e04c3fSmrg /* Clip to the scissor if it's enabled, but still clip to the 4201e04c3fSmrg * drawable regardless since that controls where the binner 4301e04c3fSmrg * tries to put things. 4401e04c3fSmrg * 4501e04c3fSmrg * Additionally, always clip the rendering to the viewport, 4601e04c3fSmrg * since the hardware does guardband clipping, meaning 4701e04c3fSmrg * primitives would rasterize outside of the view volume. 4801e04c3fSmrg */ 4901e04c3fSmrg uint32_t minx, miny, maxx, maxy; 5001e04c3fSmrg if (!vc4->rasterizer->base.scissor) { 5101e04c3fSmrg minx = MAX2(vp_minx, 0); 5201e04c3fSmrg miny = MAX2(vp_miny, 0); 537ec681f3Smrg maxx = MAX2(MIN2(vp_maxx, job->draw_width), minx); 547ec681f3Smrg maxy = MAX2(MIN2(vp_maxy, job->draw_height), miny); 5501e04c3fSmrg } else { 5601e04c3fSmrg minx = MAX2(vp_minx, vc4->scissor.minx); 5701e04c3fSmrg miny = MAX2(vp_miny, vc4->scissor.miny); 587ec681f3Smrg maxx = MAX2(MIN2(vp_maxx, vc4->scissor.maxx), minx); 597ec681f3Smrg maxy = MAX2(MIN2(vp_maxy, vc4->scissor.maxy), miny); 6001e04c3fSmrg } 6101e04c3fSmrg 6201e04c3fSmrg cl_emit(&job->bcl, CLIP_WINDOW, clip) { 6301e04c3fSmrg clip.clip_window_left_pixel_coordinate = minx; 6401e04c3fSmrg clip.clip_window_bottom_pixel_coordinate = miny; 6501e04c3fSmrg clip.clip_window_height_in_pixels = maxy - miny; 6601e04c3fSmrg clip.clip_window_width_in_pixels = maxx - minx; 6701e04c3fSmrg } 6801e04c3fSmrg 6901e04c3fSmrg job->draw_min_x = MIN2(job->draw_min_x, minx); 7001e04c3fSmrg job->draw_min_y = MIN2(job->draw_min_y, miny); 7101e04c3fSmrg job->draw_max_x = MAX2(job->draw_max_x, maxx); 7201e04c3fSmrg job->draw_max_y = MAX2(job->draw_max_y, maxy); 73af69d88dSmrg } 74af69d88dSmrg 7501e04c3fSmrg if (vc4->dirty & (VC4_DIRTY_RASTERIZER | 7601e04c3fSmrg VC4_DIRTY_ZSA | 7701e04c3fSmrg VC4_DIRTY_COMPILED_FS)) { 7801e04c3fSmrg uint8_t ez_enable_mask_out = ~0; 7901e04c3fSmrg uint8_t rasosm_mask_out = ~0; 8001e04c3fSmrg 8101e04c3fSmrg struct vc4_cl_out *bcl = cl_start(&job->bcl); 8201e04c3fSmrg /* HW-2905: If the RCL ends up doing a full-res load when 8301e04c3fSmrg * multisampling, then early Z tracking may end up with values 8401e04c3fSmrg * from the previous tile due to a HW bug. Disable it to 8501e04c3fSmrg * avoid that. 8601e04c3fSmrg * 8701e04c3fSmrg * We should be able to skip this when the Z is cleared, but I 8801e04c3fSmrg * was seeing bad rendering on glxgears -samples 4 even in 8901e04c3fSmrg * that case. 9001e04c3fSmrg */ 9101e04c3fSmrg if (job->msaa || vc4->prog.fs->disable_early_z) 9201e04c3fSmrg ez_enable_mask_out &= ~VC4_CONFIG_BITS_EARLY_Z; 9301e04c3fSmrg 9401e04c3fSmrg /* Don't set the rasterizer to oversample if we're doing our 9501e04c3fSmrg * binning and load/stores in single-sample mode. This is for 9601e04c3fSmrg * the samples == 1 case, where vc4 doesn't do any 9701e04c3fSmrg * multisampling behavior. 9801e04c3fSmrg */ 9901e04c3fSmrg if (!job->msaa) { 10001e04c3fSmrg rasosm_mask_out &= 10101e04c3fSmrg ~VC4_CONFIG_BITS_RASTERIZER_OVERSAMPLE_4X; 10201e04c3fSmrg } 10301e04c3fSmrg 10401e04c3fSmrg cl_u8(&bcl, VC4_PACKET_CONFIGURATION_BITS); 10501e04c3fSmrg cl_u8(&bcl, 10601e04c3fSmrg (vc4->rasterizer->config_bits[0] | 10701e04c3fSmrg vc4->zsa->config_bits[0]) & rasosm_mask_out); 10801e04c3fSmrg cl_u8(&bcl, 109af69d88dSmrg vc4->rasterizer->config_bits[1] | 110af69d88dSmrg vc4->zsa->config_bits[1]); 11101e04c3fSmrg cl_u8(&bcl, 11201e04c3fSmrg (vc4->rasterizer->config_bits[2] | 11301e04c3fSmrg vc4->zsa->config_bits[2]) & ez_enable_mask_out); 11401e04c3fSmrg cl_end(&job->bcl, bcl); 11501e04c3fSmrg } 11601e04c3fSmrg 11701e04c3fSmrg if (vc4->dirty & VC4_DIRTY_RASTERIZER) { 11801e04c3fSmrg cl_emit_prepacked(&job->bcl, &vc4->rasterizer->packed); 119af69d88dSmrg } 120af69d88dSmrg 121af69d88dSmrg if (vc4->dirty & VC4_DIRTY_VIEWPORT) { 12201e04c3fSmrg cl_emit(&job->bcl, CLIPPER_XY_SCALING, clip) { 12301e04c3fSmrg clip.viewport_half_width_in_1_16th_of_pixel = 12401e04c3fSmrg vc4->viewport.scale[0] * 16.0f; 12501e04c3fSmrg clip.viewport_half_height_in_1_16th_of_pixel = 12601e04c3fSmrg vc4->viewport.scale[1] * 16.0f; 12701e04c3fSmrg } 128af69d88dSmrg 12901e04c3fSmrg cl_emit(&job->bcl, CLIPPER_Z_SCALE_AND_OFFSET, clip) { 13001e04c3fSmrg clip.viewport_z_offset_zc_to_zs = 13101e04c3fSmrg vc4->viewport.translate[2]; 13201e04c3fSmrg clip.viewport_z_scale_zc_to_zs = 13301e04c3fSmrg vc4->viewport.scale[2]; 13401e04c3fSmrg } 13501e04c3fSmrg 13601e04c3fSmrg cl_emit(&job->bcl, VIEWPORT_OFFSET, vp) { 13701e04c3fSmrg vp.viewport_centre_x_coordinate = 13801e04c3fSmrg vc4->viewport.translate[0]; 13901e04c3fSmrg vp.viewport_centre_y_coordinate = 14001e04c3fSmrg vc4->viewport.translate[1]; 14101e04c3fSmrg } 14201e04c3fSmrg } 143af69d88dSmrg 14401e04c3fSmrg if (vc4->dirty & VC4_DIRTY_FLAT_SHADE_FLAGS) { 14501e04c3fSmrg cl_emit(&job->bcl, FLAT_SHADE_FLAGS, flags) { 14601e04c3fSmrg if (vc4->rasterizer->base.flatshade) 14701e04c3fSmrg flags.flat_shading_flags = 14801e04c3fSmrg vc4->prog.fs->color_inputs; 14901e04c3fSmrg } 150af69d88dSmrg } 151af69d88dSmrg} 152