Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2012 Advanced Micro Devices, Inc.
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *      Christian König <christian.koenig@amd.com>
  25.  */
  26.  
  27. #include "util/u_memory.h"
  28. #include "util/u_framebuffer.h"
  29. #include "util/u_blitter.h"
  30. #include "tgsi/tgsi_parse.h"
  31. #include "radeonsi_pipe.h"
  32. #include "radeonsi_shader.h"
  33. #include "si_state.h"
  34. #include "sid.h"
  35.  
  36. /*
  37.  * Shaders
  38.  */
  39.  
  40. static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *shader)
  41. {
  42.         struct r600_context *rctx = (struct r600_context *)ctx;
  43.         struct si_pm4_state *pm4;
  44.         unsigned num_sgprs, num_user_sgprs;
  45.         unsigned nparams, i, vgpr_comp_cnt;
  46.         uint64_t va;
  47.  
  48.         si_pm4_delete_state(rctx, vs, shader->pm4);
  49.         pm4 = shader->pm4 = si_pm4_alloc_state(rctx);
  50.  
  51.         if (pm4 == NULL)
  52.                 return;
  53.  
  54.         si_pm4_inval_shader_cache(pm4);
  55.  
  56.         /* Certain attributes (position, psize, etc.) don't count as params.
  57.          * VS is required to export at least one param and r600_shader_from_tgsi()
  58.          * takes care of adding a dummy export.
  59.          */
  60.         for (nparams = 0, i = 0 ; i < shader->shader.noutput; i++) {
  61.                 switch (shader->shader.output[i].name) {
  62.                 case TGSI_SEMANTIC_POSITION:
  63.                 case TGSI_SEMANTIC_PSIZE:
  64.                         break;
  65.                 default:
  66.                         nparams++;
  67.                 }
  68.         }
  69.         if (nparams < 1)
  70.                 nparams = 1;
  71.  
  72.         si_pm4_set_reg(pm4, R_0286C4_SPI_VS_OUT_CONFIG,
  73.                        S_0286C4_VS_EXPORT_COUNT(nparams - 1));
  74.  
  75.         si_pm4_set_reg(pm4, R_02870C_SPI_SHADER_POS_FORMAT,
  76.                        S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
  77.                        S_02870C_POS1_EXPORT_FORMAT(shader->shader.nr_pos_exports > 1 ?
  78.                                                    V_02870C_SPI_SHADER_4COMP :
  79.                                                    V_02870C_SPI_SHADER_NONE) |
  80.                        S_02870C_POS2_EXPORT_FORMAT(shader->shader.nr_pos_exports > 2 ?
  81.                                                    V_02870C_SPI_SHADER_4COMP :
  82.                                                    V_02870C_SPI_SHADER_NONE) |
  83.                        S_02870C_POS3_EXPORT_FORMAT(shader->shader.nr_pos_exports > 3 ?
  84.                                                    V_02870C_SPI_SHADER_4COMP :
  85.                                                    V_02870C_SPI_SHADER_NONE));
  86.  
  87.         va = r600_resource_va(ctx->screen, (void *)shader->bo);
  88.         si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
  89.         si_pm4_set_reg(pm4, R_00B120_SPI_SHADER_PGM_LO_VS, va >> 8);
  90.         si_pm4_set_reg(pm4, R_00B124_SPI_SHADER_PGM_HI_VS, va >> 40);
  91.  
  92.         num_user_sgprs = SI_VS_NUM_USER_SGPR;
  93.         num_sgprs = shader->num_sgprs;
  94.         if (num_user_sgprs > num_sgprs) {
  95.                 /* Last 2 reserved SGPRs are used for VCC */
  96.                 num_sgprs = num_user_sgprs + 2;
  97.         }
  98.         assert(num_sgprs <= 104);
  99.  
  100.         vgpr_comp_cnt = shader->shader.uses_instanceid ? 3 : 0;
  101.  
  102.         si_pm4_set_reg(pm4, R_00B128_SPI_SHADER_PGM_RSRC1_VS,
  103.                        S_00B128_VGPRS((shader->num_vgprs - 1) / 4) |
  104.                        S_00B128_SGPRS((num_sgprs - 1) / 8) |
  105.                        S_00B128_VGPR_COMP_CNT(vgpr_comp_cnt));
  106.         si_pm4_set_reg(pm4, R_00B12C_SPI_SHADER_PGM_RSRC2_VS,
  107.                        S_00B12C_USER_SGPR(num_user_sgprs));
  108.  
  109.         if (rctx->chip_class >= CIK) {
  110.                 si_pm4_set_reg(pm4, R_00B118_SPI_SHADER_PGM_RSRC3_VS,
  111.                                S_00B118_CU_EN(0xffff));
  112.                 si_pm4_set_reg(pm4, R_00B11C_SPI_SHADER_LATE_ALLOC_VS,
  113.                                S_00B11C_LIMIT(0));
  114.         }
  115.  
  116.         si_pm4_bind_state(rctx, vs, shader->pm4);
  117. }
  118.  
  119. static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *shader)
  120. {
  121.         struct r600_context *rctx = (struct r600_context *)ctx;
  122.         struct si_pm4_state *pm4;
  123.         unsigned i, exports_ps, num_cout, spi_ps_in_control, db_shader_control;
  124.         unsigned num_sgprs, num_user_sgprs;
  125.         boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
  126.         unsigned fragcoord_interp_mode = 0;
  127.         unsigned spi_baryc_cntl, spi_ps_input_ena, spi_shader_z_format;
  128.         uint64_t va;
  129.  
  130.         si_pm4_delete_state(rctx, ps, shader->pm4);
  131.         pm4 = shader->pm4 = si_pm4_alloc_state(rctx);
  132.  
  133.         if (pm4 == NULL)
  134.                 return;
  135.  
  136.         si_pm4_inval_shader_cache(pm4);
  137.  
  138.         db_shader_control = S_02880C_Z_ORDER(V_02880C_EARLY_Z_THEN_LATE_Z);
  139.         for (i = 0; i < shader->shader.ninput; i++) {
  140.                 switch (shader->shader.input[i].name) {
  141.                 case TGSI_SEMANTIC_POSITION:
  142.                         if (shader->shader.input[i].centroid) {
  143.                                 /* fragcoord_interp_mode will be written to
  144.                                  * SPI_BARYC_CNTL.POS_FLOAT_LOCATION
  145.                                  * Possible vaules:
  146.                                  * 0 -> Position = pixel center (default)
  147.                                  * 1 -> Position = pixel centroid
  148.                                  * 2 -> Position = iterated sample number XXX:
  149.                                  *                        What does this mean?
  150.                                  */
  151.                                 fragcoord_interp_mode = 1;
  152.                         }
  153.                         /* Fall through */
  154.                 case TGSI_SEMANTIC_FACE:
  155.                         continue;
  156.                 }
  157.  
  158.                 if (shader->shader.input[i].interpolate == TGSI_INTERPOLATE_LINEAR)
  159.                         have_linear = TRUE;
  160.                 if (shader->shader.input[i].interpolate == TGSI_INTERPOLATE_PERSPECTIVE)
  161.                         have_perspective = TRUE;
  162.                 if (shader->shader.input[i].centroid)
  163.                         have_centroid = TRUE;
  164.         }
  165.  
  166.         for (i = 0; i < shader->shader.noutput; i++) {
  167.                 if (shader->shader.output[i].name == TGSI_SEMANTIC_POSITION)
  168.                         db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1);
  169.                 if (shader->shader.output[i].name == TGSI_SEMANTIC_STENCIL)
  170.                         db_shader_control |= S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(1);
  171.         }
  172.         if (shader->shader.uses_kill || shader->key.ps.alpha_func != PIPE_FUNC_ALWAYS)
  173.                 db_shader_control |= S_02880C_KILL_ENABLE(1);
  174.  
  175.         exports_ps = 0;
  176.         num_cout = 0;
  177.         for (i = 0; i < shader->shader.noutput; i++) {
  178.                 if (shader->shader.output[i].name == TGSI_SEMANTIC_POSITION ||
  179.                     shader->shader.output[i].name == TGSI_SEMANTIC_STENCIL)
  180.                         exports_ps |= 1;
  181.                 else if (shader->shader.output[i].name == TGSI_SEMANTIC_COLOR) {
  182.                         if (shader->shader.fs_write_all)
  183.                                 num_cout = shader->shader.nr_cbufs;
  184.                         else
  185.                                 num_cout++;
  186.                 }
  187.         }
  188.         if (!exports_ps) {
  189.                 /* always at least export 1 component per pixel */
  190.                 exports_ps = 2;
  191.         }
  192.  
  193.         spi_ps_in_control = S_0286D8_NUM_INTERP(shader->shader.ninterp) |
  194.                 S_0286D8_BC_OPTIMIZE_DISABLE(1);
  195.  
  196.         spi_baryc_cntl = 0;
  197.         if (have_perspective)
  198.                 spi_baryc_cntl |= have_centroid ?
  199.                         S_0286E0_PERSP_CENTROID_CNTL(1) : S_0286E0_PERSP_CENTER_CNTL(1);
  200.         if (have_linear)
  201.                 spi_baryc_cntl |= have_centroid ?
  202.                         S_0286E0_LINEAR_CENTROID_CNTL(1) : S_0286E0_LINEAR_CENTER_CNTL(1);
  203.         spi_baryc_cntl |= S_0286E0_POS_FLOAT_LOCATION(fragcoord_interp_mode);
  204.  
  205.         si_pm4_set_reg(pm4, R_0286E0_SPI_BARYC_CNTL, spi_baryc_cntl);
  206.         spi_ps_input_ena = shader->spi_ps_input_ena;
  207.         /* we need to enable at least one of them, otherwise we hang the GPU */
  208.         assert(G_0286CC_PERSP_SAMPLE_ENA(spi_ps_input_ena) ||
  209.             G_0286CC_PERSP_CENTER_ENA(spi_ps_input_ena) ||
  210.             G_0286CC_PERSP_CENTROID_ENA(spi_ps_input_ena) ||
  211.             G_0286CC_PERSP_PULL_MODEL_ENA(spi_ps_input_ena) ||
  212.             G_0286CC_LINEAR_SAMPLE_ENA(spi_ps_input_ena) ||
  213.             G_0286CC_LINEAR_CENTER_ENA(spi_ps_input_ena) ||
  214.             G_0286CC_LINEAR_CENTROID_ENA(spi_ps_input_ena) ||
  215.             G_0286CC_LINE_STIPPLE_TEX_ENA(spi_ps_input_ena));
  216.  
  217.         si_pm4_set_reg(pm4, R_0286CC_SPI_PS_INPUT_ENA, spi_ps_input_ena);
  218.         si_pm4_set_reg(pm4, R_0286D0_SPI_PS_INPUT_ADDR, spi_ps_input_ena);
  219.         si_pm4_set_reg(pm4, R_0286D8_SPI_PS_IN_CONTROL, spi_ps_in_control);
  220.  
  221.         if (G_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(db_shader_control))
  222.                 spi_shader_z_format = V_028710_SPI_SHADER_32_GR;
  223.         else if (G_02880C_Z_EXPORT_ENABLE(db_shader_control))
  224.                 spi_shader_z_format = V_028710_SPI_SHADER_32_R;
  225.         else
  226.                 spi_shader_z_format = 0;
  227.         si_pm4_set_reg(pm4, R_028710_SPI_SHADER_Z_FORMAT, spi_shader_z_format);
  228.         si_pm4_set_reg(pm4, R_028714_SPI_SHADER_COL_FORMAT,
  229.                        shader->spi_shader_col_format);
  230.         si_pm4_set_reg(pm4, R_02823C_CB_SHADER_MASK, shader->cb_shader_mask);
  231.  
  232.         va = r600_resource_va(ctx->screen, (void *)shader->bo);
  233.         si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
  234.         si_pm4_set_reg(pm4, R_00B020_SPI_SHADER_PGM_LO_PS, va >> 8);
  235.         si_pm4_set_reg(pm4, R_00B024_SPI_SHADER_PGM_HI_PS, va >> 40);
  236.  
  237.         num_user_sgprs = SI_PS_NUM_USER_SGPR;
  238.         num_sgprs = shader->num_sgprs;
  239.         if (num_user_sgprs > num_sgprs) {
  240.                 /* Last 2 reserved SGPRs are used for VCC */
  241.                 num_sgprs = num_user_sgprs + 2;
  242.         }
  243.         assert(num_sgprs <= 104);
  244.  
  245.         si_pm4_set_reg(pm4, R_00B028_SPI_SHADER_PGM_RSRC1_PS,
  246.                        S_00B028_VGPRS((shader->num_vgprs - 1) / 4) |
  247.                        S_00B028_SGPRS((num_sgprs - 1) / 8));
  248.         si_pm4_set_reg(pm4, R_00B02C_SPI_SHADER_PGM_RSRC2_PS,
  249.                        S_00B02C_EXTRA_LDS_SIZE(shader->lds_size) |
  250.                        S_00B02C_USER_SGPR(num_user_sgprs));
  251.         if (rctx->chip_class >= CIK) {
  252.                 si_pm4_set_reg(pm4, R_00B01C_SPI_SHADER_PGM_RSRC3_PS,
  253.                                S_00B01C_CU_EN(0xffff));
  254.         }
  255.  
  256.         si_pm4_set_reg(pm4, R_02880C_DB_SHADER_CONTROL, db_shader_control);
  257.  
  258.         shader->sprite_coord_enable = rctx->sprite_coord_enable;
  259.         si_pm4_bind_state(rctx, ps, shader->pm4);
  260. }
  261.  
  262. /*
  263.  * Drawing
  264.  */
  265.  
  266. static unsigned si_conv_pipe_prim(unsigned pprim)
  267. {
  268.         static const unsigned prim_conv[] = {
  269.                 [PIPE_PRIM_POINTS]                      = V_008958_DI_PT_POINTLIST,
  270.                 [PIPE_PRIM_LINES]                       = V_008958_DI_PT_LINELIST,
  271.                 [PIPE_PRIM_LINE_LOOP]                   = V_008958_DI_PT_LINELOOP,
  272.                 [PIPE_PRIM_LINE_STRIP]                  = V_008958_DI_PT_LINESTRIP,
  273.                 [PIPE_PRIM_TRIANGLES]                   = V_008958_DI_PT_TRILIST,
  274.                 [PIPE_PRIM_TRIANGLE_STRIP]              = V_008958_DI_PT_TRISTRIP,
  275.                 [PIPE_PRIM_TRIANGLE_FAN]                = V_008958_DI_PT_TRIFAN,
  276.                 [PIPE_PRIM_QUADS]                       = V_008958_DI_PT_QUADLIST,
  277.                 [PIPE_PRIM_QUAD_STRIP]                  = V_008958_DI_PT_QUADSTRIP,
  278.                 [PIPE_PRIM_POLYGON]                     = V_008958_DI_PT_POLYGON,
  279.                 [PIPE_PRIM_LINES_ADJACENCY]             = ~0,
  280.                 [PIPE_PRIM_LINE_STRIP_ADJACENCY]        = ~0,
  281.                 [PIPE_PRIM_TRIANGLES_ADJACENCY]         = ~0,
  282.                 [PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY]    = ~0
  283.         };
  284.         unsigned result = prim_conv[pprim];
  285.         if (result == ~0) {
  286.                 R600_ERR("unsupported primitive type %d\n", pprim);
  287.         }
  288.         return result;
  289. }
  290.  
  291. static bool si_update_draw_info_state(struct r600_context *rctx,
  292.                                const struct pipe_draw_info *info)
  293. {
  294.         struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
  295.         struct si_shader *vs = &rctx->vs_shader->current->shader;
  296.         unsigned prim = si_conv_pipe_prim(info->mode);
  297.         unsigned ls_mask = 0;
  298.  
  299.         if (pm4 == NULL)
  300.                 return false;
  301.  
  302.         if (prim == ~0) {
  303.                 FREE(pm4);
  304.                 return false;
  305.         }
  306.  
  307.         if (rctx->chip_class >= CIK)
  308.                 si_pm4_set_reg(pm4, R_030908_VGT_PRIMITIVE_TYPE, prim);
  309.         else
  310.                 si_pm4_set_reg(pm4, R_008958_VGT_PRIMITIVE_TYPE, prim);
  311.         si_pm4_set_reg(pm4, R_028400_VGT_MAX_VTX_INDX, ~0);
  312.         si_pm4_set_reg(pm4, R_028404_VGT_MIN_VTX_INDX, 0);
  313.         si_pm4_set_reg(pm4, R_028408_VGT_INDX_OFFSET,
  314.                        info->indexed ? info->index_bias : info->start);
  315.         si_pm4_set_reg(pm4, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX, info->restart_index);
  316.         si_pm4_set_reg(pm4, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, info->primitive_restart);
  317.         si_pm4_set_reg(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0 + SI_SGPR_START_INSTANCE * 4,
  318.                        info->start_instance);
  319.  
  320.         if (prim == V_008958_DI_PT_LINELIST)
  321.                 ls_mask = 1;
  322.         else if (prim == V_008958_DI_PT_LINESTRIP)
  323.                 ls_mask = 2;
  324.         si_pm4_set_reg(pm4, R_028A0C_PA_SC_LINE_STIPPLE,
  325.                        S_028A0C_AUTO_RESET_CNTL(ls_mask) |
  326.                        rctx->pa_sc_line_stipple);
  327.  
  328.         if (info->mode == PIPE_PRIM_QUADS || info->mode == PIPE_PRIM_QUAD_STRIP || info->mode == PIPE_PRIM_POLYGON) {
  329.                 si_pm4_set_reg(pm4, R_028814_PA_SU_SC_MODE_CNTL,
  330.                                S_028814_PROVOKING_VTX_LAST(1) | rctx->pa_su_sc_mode_cntl);
  331.         } else {
  332.                 si_pm4_set_reg(pm4, R_028814_PA_SU_SC_MODE_CNTL, rctx->pa_su_sc_mode_cntl);
  333.         }
  334.         si_pm4_set_reg(pm4, R_02881C_PA_CL_VS_OUT_CNTL,
  335.                        S_02881C_USE_VTX_POINT_SIZE(vs->vs_out_point_size) |
  336.                        S_02881C_VS_OUT_CCDIST0_VEC_ENA((vs->clip_dist_write & 0x0F) != 0) |
  337.                        S_02881C_VS_OUT_CCDIST1_VEC_ENA((vs->clip_dist_write & 0xF0) != 0) |
  338.                        S_02881C_VS_OUT_MISC_VEC_ENA(vs->vs_out_misc_write) |
  339.                        (rctx->queued.named.rasterizer->clip_plane_enable &
  340.                         vs->clip_dist_write));
  341.         si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL,
  342.                        rctx->queued.named.rasterizer->pa_cl_clip_cntl |
  343.                        (vs->clip_dist_write ? 0 :
  344.                         rctx->queued.named.rasterizer->clip_plane_enable & 0x3F));
  345.  
  346.         si_pm4_set_state(rctx, draw_info, pm4);
  347.         return true;
  348. }
  349.  
  350. static void si_update_spi_map(struct r600_context *rctx)
  351. {
  352.         struct si_shader *ps = &rctx->ps_shader->current->shader;
  353.         struct si_shader *vs = &rctx->vs_shader->current->shader;
  354.         struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
  355.         unsigned i, j, tmp;
  356.  
  357.         for (i = 0; i < ps->ninput; i++) {
  358.                 unsigned name = ps->input[i].name;
  359.                 unsigned param_offset = ps->input[i].param_offset;
  360.  
  361.                 if (name == TGSI_SEMANTIC_POSITION)
  362.                         /* Read from preloaded VGPRs, not parameters */
  363.                         continue;
  364.  
  365. bcolor:
  366.                 tmp = 0;
  367.  
  368.                 if (ps->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT ||
  369.                     (ps->input[i].interpolate == TGSI_INTERPOLATE_COLOR &&
  370.                      rctx->ps_shader->current->key.ps.flatshade)) {
  371.                         tmp |= S_028644_FLAT_SHADE(1);
  372.                 }
  373.  
  374.                 if (name == TGSI_SEMANTIC_GENERIC &&
  375.                     rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
  376.                         tmp |= S_028644_PT_SPRITE_TEX(1);
  377.                 }
  378.  
  379.                 for (j = 0; j < vs->noutput; j++) {
  380.                         if (name == vs->output[j].name &&
  381.                             ps->input[i].sid == vs->output[j].sid) {
  382.                                 tmp |= S_028644_OFFSET(vs->output[j].param_offset);
  383.                                 break;
  384.                         }
  385.                 }
  386.  
  387.                 if (j == vs->noutput) {
  388.                         /* No corresponding output found, load defaults into input */
  389.                         tmp |= S_028644_OFFSET(0x20);
  390.                 }
  391.  
  392.                 si_pm4_set_reg(pm4,
  393.                                R_028644_SPI_PS_INPUT_CNTL_0 + param_offset * 4,
  394.                                tmp);
  395.  
  396.                 if (name == TGSI_SEMANTIC_COLOR &&
  397.                     rctx->ps_shader->current->key.ps.color_two_side) {
  398.                         name = TGSI_SEMANTIC_BCOLOR;
  399.                         param_offset++;
  400.                         goto bcolor;
  401.                 }
  402.         }
  403.  
  404.         si_pm4_set_state(rctx, spi, pm4);
  405. }
  406.  
  407. static void si_update_derived_state(struct r600_context *rctx)
  408. {
  409.         struct pipe_context * ctx = (struct pipe_context*)rctx;
  410.         unsigned vs_dirty = 0, ps_dirty = 0;
  411.  
  412.         if (!rctx->blitter->running) {
  413.                 /* Flush depth textures which need to be flushed. */
  414.                 if (rctx->vs_samplers.depth_texture_mask) {
  415.                         si_flush_depth_textures(rctx, &rctx->vs_samplers);
  416.                 }
  417.                 if (rctx->ps_samplers.depth_texture_mask) {
  418.                         si_flush_depth_textures(rctx, &rctx->ps_samplers);
  419.                 }
  420.         }
  421.  
  422.         si_shader_select(ctx, rctx->vs_shader, &vs_dirty);
  423.  
  424.         if (!rctx->vs_shader->current->pm4) {
  425.                 si_pipe_shader_vs(ctx, rctx->vs_shader->current);
  426.                 vs_dirty = 0;
  427.         }
  428.  
  429.         if (vs_dirty) {
  430.                 si_pm4_bind_state(rctx, vs, rctx->vs_shader->current->pm4);
  431.         }
  432.  
  433.  
  434.         si_shader_select(ctx, rctx->ps_shader, &ps_dirty);
  435.  
  436.         if (!rctx->ps_shader->current->pm4) {
  437.                 si_pipe_shader_ps(ctx, rctx->ps_shader->current);
  438.                 ps_dirty = 0;
  439.         }
  440.         if (!rctx->ps_shader->current->bo) {
  441.                 if (!rctx->dummy_pixel_shader->pm4)
  442.                         si_pipe_shader_ps(ctx, rctx->dummy_pixel_shader);
  443.                 else
  444.                         si_pm4_bind_state(rctx, vs, rctx->dummy_pixel_shader->pm4);
  445.  
  446.                 ps_dirty = 0;
  447.         }
  448.  
  449.         if (ps_dirty) {
  450.                 si_pm4_bind_state(rctx, ps, rctx->ps_shader->current->pm4);
  451.         }
  452.  
  453.         if (si_pm4_state_changed(rctx, ps) || si_pm4_state_changed(rctx, vs)) {
  454.                 /* XXX: Emitting the PS state even when only the VS changed
  455.                  * fixes random failures with piglit glsl-max-varyings.
  456.                  * Not sure why...
  457.                  */
  458.                 rctx->emitted.named.ps = NULL;
  459.                 si_update_spi_map(rctx);
  460.         }
  461. }
  462.  
  463. static void si_constant_buffer_update(struct r600_context *rctx)
  464. {
  465.         struct pipe_context *ctx = &rctx->context;
  466.         struct si_pm4_state *pm4;
  467.         unsigned shader, i;
  468.         uint64_t va;
  469.  
  470.         if (!rctx->constbuf_state[PIPE_SHADER_VERTEX].dirty_mask &&
  471.             !rctx->constbuf_state[PIPE_SHADER_FRAGMENT].dirty_mask)
  472.                 return;
  473.  
  474.         for (shader = PIPE_SHADER_VERTEX ; shader <= PIPE_SHADER_FRAGMENT; shader++) {
  475.                 struct r600_constbuf_state *state = &rctx->constbuf_state[shader];
  476.  
  477.                 pm4 = CALLOC_STRUCT(si_pm4_state);
  478.                 if (!pm4)
  479.                         continue;
  480.  
  481.                 si_pm4_inval_shader_cache(pm4);
  482.                 si_pm4_sh_data_begin(pm4);
  483.  
  484.                 for (i = 0; i < 2; i++) {
  485.                         if (state->enabled_mask & (1 << i)) {
  486.                                 struct pipe_constant_buffer *cb = &state->cb[i];
  487.                                 struct si_resource *rbuffer = si_resource(cb->buffer);
  488.  
  489.                                 va = r600_resource_va(ctx->screen, (void*)rbuffer);
  490.                                 va += cb->buffer_offset;
  491.  
  492.                                 si_pm4_add_bo(pm4, rbuffer, RADEON_USAGE_READ);
  493.  
  494.                                 /* Fill in a T# buffer resource description */
  495.                                 si_pm4_sh_data_add(pm4, va);
  496.                                 si_pm4_sh_data_add(pm4, (S_008F04_BASE_ADDRESS_HI(va >> 32) |
  497.                                                          S_008F04_STRIDE(0)));
  498.                                 si_pm4_sh_data_add(pm4, cb->buffer_size);
  499.                                 si_pm4_sh_data_add(pm4, S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
  500.                                                    S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
  501.                                                    S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
  502.                                                    S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
  503.                                                    S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
  504.                                                    S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32));
  505.                         } else {
  506.                                 /* Fill in an empty T# buffer resource description */
  507.                                 si_pm4_sh_data_add(pm4, 0);
  508.                                 si_pm4_sh_data_add(pm4, 0);
  509.                                 si_pm4_sh_data_add(pm4, 0);
  510.                                 si_pm4_sh_data_add(pm4, 0);
  511.                         }
  512.                 }
  513.  
  514.                 switch (shader) {
  515.                 case PIPE_SHADER_VERTEX:
  516.                         si_pm4_sh_data_end(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0, SI_SGPR_CONST);
  517.                         si_pm4_set_state(rctx, vs_const, pm4);
  518.                         break;
  519.  
  520.                 case PIPE_SHADER_FRAGMENT:
  521.                         si_pm4_sh_data_end(pm4, R_00B030_SPI_SHADER_USER_DATA_PS_0, SI_SGPR_CONST);
  522.                         si_pm4_set_state(rctx, ps_const, pm4);
  523.                         break;
  524.  
  525.                 default:
  526.                         R600_ERR("unsupported %d\n", shader);
  527.                         FREE(pm4);
  528.                         return;
  529.                 }
  530.  
  531.                 state->dirty_mask = 0;
  532.         }
  533. }
  534.  
  535. static void si_vertex_buffer_update(struct r600_context *rctx)
  536. {
  537.         struct pipe_context *ctx = &rctx->context;
  538.         struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
  539.         bool bound[PIPE_MAX_ATTRIBS] = {};
  540.         unsigned i, count;
  541.         uint64_t va;
  542.  
  543.         si_pm4_inval_texture_cache(pm4);
  544.  
  545.         /* bind vertex buffer once */
  546.         count = rctx->vertex_elements->count;
  547.         assert(count <= 256 / 4);
  548.  
  549.         si_pm4_sh_data_begin(pm4);
  550.         for (i = 0 ; i < count; i++) {
  551.                 struct pipe_vertex_element *ve = &rctx->vertex_elements->elements[i];
  552.                 struct pipe_vertex_buffer *vb;
  553.                 struct si_resource *rbuffer;
  554.                 unsigned offset;
  555.  
  556.                 if (ve->vertex_buffer_index >= rctx->nr_vertex_buffers)
  557.                         continue;
  558.  
  559.                 vb = &rctx->vertex_buffer[ve->vertex_buffer_index];
  560.                 rbuffer = (struct si_resource*)vb->buffer;
  561.                 if (rbuffer == NULL)
  562.                         continue;
  563.  
  564.                 offset = 0;
  565.                 offset += vb->buffer_offset;
  566.                 offset += ve->src_offset;
  567.  
  568.                 va = r600_resource_va(ctx->screen, (void*)rbuffer);
  569.                 va += offset;
  570.  
  571.                 /* Fill in T# buffer resource description */
  572.                 si_pm4_sh_data_add(pm4, va & 0xFFFFFFFF);
  573.                 si_pm4_sh_data_add(pm4, (S_008F04_BASE_ADDRESS_HI(va >> 32) |
  574.                                          S_008F04_STRIDE(vb->stride)));
  575.                 if (vb->stride)
  576.                         /* Round up by rounding down and adding 1 */
  577.                         si_pm4_sh_data_add(pm4,
  578.                                            (vb->buffer->width0 - offset -
  579.                                             util_format_get_blocksize(ve->src_format)) /
  580.                                            vb->stride + 1);
  581.                 else
  582.                         si_pm4_sh_data_add(pm4, vb->buffer->width0 - offset);
  583.                 si_pm4_sh_data_add(pm4, rctx->vertex_elements->rsrc_word3[i]);
  584.  
  585.                 if (!bound[ve->vertex_buffer_index]) {
  586.                         si_pm4_add_bo(pm4, rbuffer, RADEON_USAGE_READ);
  587.                         bound[ve->vertex_buffer_index] = true;
  588.                 }
  589.         }
  590.         si_pm4_sh_data_end(pm4, R_00B130_SPI_SHADER_USER_DATA_VS_0, SI_SGPR_VERTEX_BUFFER);
  591.         si_pm4_set_state(rctx, vertex_buffers, pm4);
  592. }
  593.  
  594. static void si_state_draw(struct r600_context *rctx,
  595.                           const struct pipe_draw_info *info,
  596.                           const struct pipe_index_buffer *ib)
  597. {
  598.         struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
  599.  
  600.         if (pm4 == NULL)
  601.                 return;
  602.  
  603.         /* queries need some special values
  604.          * (this is non-zero if any query is active) */
  605.         if (rctx->num_cs_dw_queries_suspend) {
  606.                 struct si_state_dsa *dsa = rctx->queued.named.dsa;
  607.  
  608.                 si_pm4_set_reg(pm4, R_028004_DB_COUNT_CONTROL,
  609.                                S_028004_PERFECT_ZPASS_COUNTS(1));
  610.                 si_pm4_set_reg(pm4, R_02800C_DB_RENDER_OVERRIDE,
  611.                                dsa->db_render_override |
  612.                                S_02800C_NOOP_CULL_DISABLE(1));
  613.         }
  614.  
  615.         /* draw packet */
  616.         si_pm4_cmd_begin(pm4, PKT3_INDEX_TYPE);
  617.         if (ib->index_size == 4) {
  618.                 si_pm4_cmd_add(pm4, V_028A7C_VGT_INDEX_32 | (R600_BIG_ENDIAN ?
  619.                                 V_028A7C_VGT_DMA_SWAP_32_BIT : 0));
  620.         } else {
  621.                 si_pm4_cmd_add(pm4, V_028A7C_VGT_INDEX_16 | (R600_BIG_ENDIAN ?
  622.                                 V_028A7C_VGT_DMA_SWAP_16_BIT : 0));
  623.         }
  624.         si_pm4_cmd_end(pm4, rctx->predicate_drawing);
  625.  
  626.         si_pm4_cmd_begin(pm4, PKT3_NUM_INSTANCES);
  627.         si_pm4_cmd_add(pm4, info->instance_count);
  628.         si_pm4_cmd_end(pm4, rctx->predicate_drawing);
  629.  
  630.         if (info->indexed) {
  631.                 uint32_t max_size = (ib->buffer->width0 - ib->offset) /
  632.                                  rctx->index_buffer.index_size;
  633.                 uint64_t va;
  634.                 va = r600_resource_va(&rctx->screen->screen, ib->buffer);
  635.                 va += ib->offset;
  636.  
  637.                 si_pm4_add_bo(pm4, (struct si_resource *)ib->buffer, RADEON_USAGE_READ);
  638.                 si_cmd_draw_index_2(pm4, max_size, va, info->count,
  639.                                     V_0287F0_DI_SRC_SEL_DMA,
  640.                                     rctx->predicate_drawing);
  641.         } else {
  642.                 uint32_t initiator = V_0287F0_DI_SRC_SEL_AUTO_INDEX;
  643.                 initiator |= S_0287F0_USE_OPAQUE(!!info->count_from_stream_output);
  644.                 si_cmd_draw_index_auto(pm4, info->count, initiator, rctx->predicate_drawing);
  645.         }
  646.         si_pm4_set_state(rctx, draw, pm4);
  647. }
  648.  
  649. void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info)
  650. {
  651.         struct r600_context *rctx = (struct r600_context *)ctx;
  652.         struct pipe_index_buffer ib = {};
  653.         uint32_t cp_coher_cntl;
  654.  
  655.         if (!info->count && (info->indexed || !info->count_from_stream_output))
  656.                 return;
  657.  
  658.         if (!rctx->ps_shader || !rctx->vs_shader)
  659.                 return;
  660.  
  661.         si_update_derived_state(rctx);
  662.         si_constant_buffer_update(rctx);
  663.         si_vertex_buffer_update(rctx);
  664.  
  665.         if (info->indexed) {
  666.                 /* Initialize the index buffer struct. */
  667.                 pipe_resource_reference(&ib.buffer, rctx->index_buffer.buffer);
  668.                 ib.user_buffer = rctx->index_buffer.user_buffer;
  669.                 ib.index_size = rctx->index_buffer.index_size;
  670.                 ib.offset = rctx->index_buffer.offset + info->start * ib.index_size;
  671.  
  672.                 /* Translate or upload, if needed. */
  673.                 r600_translate_index_buffer(rctx, &ib, info->count);
  674.  
  675.                 if (ib.user_buffer && !ib.buffer) {
  676.                         r600_upload_index_buffer(rctx, &ib, info->count);
  677.                 }
  678.  
  679.         } else if (info->count_from_stream_output) {
  680.                 r600_context_draw_opaque_count(rctx, (struct r600_so_target*)info->count_from_stream_output);
  681.         }
  682.  
  683.         rctx->vs_shader_so_strides = rctx->vs_shader->current->so_strides;
  684.  
  685.         if (!si_update_draw_info_state(rctx, info))
  686.                 return;
  687.  
  688.         si_state_draw(rctx, info, &ib);
  689.  
  690.         cp_coher_cntl = si_pm4_sync_flags(rctx);
  691.         if (cp_coher_cntl) {
  692.                 struct si_pm4_state *pm4 = si_pm4_alloc_state(rctx);
  693.  
  694.                 if (pm4 == NULL)
  695.                         return;
  696.  
  697.                 si_cmd_surface_sync(pm4, cp_coher_cntl);
  698.                 si_pm4_set_state(rctx, sync, pm4);
  699.         }
  700.  
  701.         /* Emit states. */
  702.         rctx->pm4_dirty_cdwords += si_pm4_dirty_dw(rctx);
  703.  
  704.         si_need_cs_space(rctx, 0, TRUE);
  705.  
  706.         si_pm4_emit_dirty(rctx);
  707.         rctx->pm4_dirty_cdwords = 0;
  708.  
  709. #if R600_TRACE_CS
  710.         if (rctx->screen->trace_bo) {
  711.                 r600_trace_emit(rctx);
  712.         }
  713. #endif
  714.  
  715. #if 0
  716.         /* Enable stream out if needed. */
  717.         if (rctx->streamout_start) {
  718.                 r600_context_streamout_begin(rctx);
  719.                 rctx->streamout_start = FALSE;
  720.         }
  721. #endif
  722.  
  723.         rctx->flags |= R600_CONTEXT_DST_CACHES_DIRTY;
  724.  
  725.         /* Set the depth buffer as dirty. */
  726.         if (rctx->framebuffer.zsbuf) {
  727.                 struct pipe_surface *surf = rctx->framebuffer.zsbuf;
  728.                 struct r600_resource_texture *rtex = (struct r600_resource_texture *)surf->texture;
  729.  
  730.                 rtex->dirty_db_mask |= 1 << surf->u.tex.level;
  731.         }
  732.  
  733.         pipe_resource_reference(&ib.buffer, NULL);
  734. }
  735.