Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
  2.  
  3. /*
  4.  * Copyright (C) 2013 Rob Clark <robclark@freedesktop.org>
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the next
  14.  * paragraph) shall be included in all copies or substantial portions of the
  15.  * Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  20.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23.  * SOFTWARE.
  24.  *
  25.  * Authors:
  26.  *    Rob Clark <robclark@freedesktop.org>
  27.  */
  28.  
  29. #include "pipe/p_state.h"
  30. #include "util/u_string.h"
  31. #include "util/u_memory.h"
  32. #include "util/u_prim.h"
  33.  
  34. #include "freedreno_state.h"
  35. #include "freedreno_resource.h"
  36.  
  37. #include "fd3_draw.h"
  38. #include "fd3_context.h"
  39. #include "fd3_emit.h"
  40. #include "fd3_program.h"
  41. #include "fd3_util.h"
  42. #include "fd3_zsa.h"
  43.  
  44.  
  45. static void
  46. emit_vertexbufs(struct fd_context *ctx)
  47. {
  48.         struct fd_vertex_stateobj *vtx = ctx->vtx;
  49.         struct fd_vertexbuf_stateobj *vertexbuf = &ctx->vertexbuf;
  50.         struct fd3_vertex_buf bufs[PIPE_MAX_ATTRIBS];
  51.         unsigned i;
  52.  
  53.         if (!vtx->num_elements)
  54.                 return;
  55.  
  56.         for (i = 0; i < vtx->num_elements; i++) {
  57.                 struct pipe_vertex_element *elem = &vtx->pipe[i];
  58.                 struct pipe_vertex_buffer *vb =
  59.                                 &vertexbuf->vb[elem->vertex_buffer_index];
  60.                 bufs[i].offset = vb->buffer_offset + elem->src_offset;
  61.                 bufs[i].stride = vb->stride;
  62.                 bufs[i].prsc   = vb->buffer;
  63.                 bufs[i].format = elem->src_format;
  64.         }
  65.  
  66.         fd3_emit_vertex_bufs(ctx->ring, &ctx->prog, bufs, vtx->num_elements);
  67. }
  68.  
  69. static void
  70. fd3_draw(struct fd_context *ctx, const struct pipe_draw_info *info)
  71. {
  72.         struct fd_ringbuffer *ring = ctx->ring;
  73.         unsigned dirty = ctx->dirty;
  74.  
  75.         fd3_emit_state(ctx, dirty);
  76.  
  77.         if (dirty & FD_DIRTY_VTXBUF)
  78.                 emit_vertexbufs(ctx);
  79.  
  80.         OUT_PKT0(ring, REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL, 1);
  81.         OUT_RING(ring, 0x0000000b);                  /* PC_VERTEX_REUSE_BLOCK_CNTL */
  82.  
  83.         OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
  84.         OUT_RING(ring, 0x0000000);
  85.  
  86.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  87.         OUT_RING(ring, info->min_index);        /* VFD_INDEX_MIN */
  88.         OUT_RING(ring, info->max_index + 1);    /* VFD_INDEX_MAX */
  89.         OUT_RING(ring, info->start_instance);   /* VFD_INSTANCEID_OFFSET */
  90.         OUT_RING(ring, info->start);            /* VFD_INDEX_OFFSET */
  91.  
  92.         OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
  93.         OUT_RING(ring, info->primitive_restart ? /* PC_RESTART_INDEX */
  94.                         info->restart_index : 0xffffffff);
  95.  
  96.         fd_draw_emit(ctx, info);
  97. }
  98.  
  99. static void
  100. fd3_clear(struct fd_context *ctx, unsigned buffers,
  101.                 const union pipe_color_union *color, double depth, unsigned stencil)
  102. {
  103.         struct fd3_context *fd3_ctx = fd3_context(ctx);
  104.         struct fd_ringbuffer *ring = ctx->ring;
  105.         unsigned ce, i;
  106.  
  107.         /* emit generic state now: */
  108.         fd3_emit_state(ctx, ctx->dirty & (FD_DIRTY_VIEWPORT |
  109.                         FD_DIRTY_FRAMEBUFFER | FD_DIRTY_SCISSOR));
  110.  
  111.         OUT_PKT0(ring, REG_A3XX_RB_BLEND_ALPHA, 1);
  112.         OUT_RING(ring, 0X3c0000ff);
  113.  
  114.         fd3_emit_rbrc_draw_state(ring,
  115.                         A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(FUNC_NEVER));
  116.  
  117.         if (buffers & PIPE_CLEAR_DEPTH) {
  118.                 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  119.                 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE |
  120.                                 A3XX_RB_DEPTH_CONTROL_Z_ENABLE |
  121.                                 A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_ALWAYS));
  122.  
  123.                 OUT_PKT0(ring, REG_A3XX_GRAS_CL_VPORT_ZOFFSET, 2);
  124.                 OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZOFFSET(0.0));
  125.                 OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(depth));
  126.         } else {
  127.                 OUT_PKT0(ring, REG_A3XX_RB_DEPTH_CONTROL, 1);
  128.                 OUT_RING(ring, A3XX_RB_DEPTH_CONTROL_ZFUNC(FUNC_NEVER));
  129.         }
  130.  
  131.         if (buffers & PIPE_CLEAR_STENCIL) {
  132.                 OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
  133.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_STENCILREF(stencil) |
  134.                                 A3XX_RB_STENCILREFMASK_STENCILMASK(stencil) |
  135.                                 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  136.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  137.                                 A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  138.                                 0xff000000 | // XXX ???
  139.                                 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0xff));
  140.  
  141.                 OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  142.                 OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE |
  143.                                 A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_ALWAYS) |
  144.                                 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  145.                                 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_REPLACE) |
  146.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  147.                                 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  148.                                 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  149.                                 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  150.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  151.         } else {
  152.                 OUT_PKT0(ring, REG_A3XX_RB_STENCILREFMASK, 2);
  153.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_STENCILREF(0) |
  154.                                 A3XX_RB_STENCILREFMASK_STENCILMASK(0) |
  155.                                 A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(0));
  156.                 OUT_RING(ring, A3XX_RB_STENCILREFMASK_BF_STENCILREF(0) |
  157.                                 A3XX_RB_STENCILREFMASK_BF_STENCILMASK(0) |
  158.                                 A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(0));
  159.  
  160.                 OUT_PKT0(ring, REG_A3XX_RB_STENCIL_CONTROL, 1);
  161.                 OUT_RING(ring, A3XX_RB_STENCIL_CONTROL_FUNC(FUNC_NEVER) |
  162.                                 A3XX_RB_STENCIL_CONTROL_FAIL(STENCIL_KEEP) |
  163.                                 A3XX_RB_STENCIL_CONTROL_ZPASS(STENCIL_KEEP) |
  164.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL(STENCIL_KEEP) |
  165.                                 A3XX_RB_STENCIL_CONTROL_FUNC_BF(FUNC_NEVER) |
  166.                                 A3XX_RB_STENCIL_CONTROL_FAIL_BF(STENCIL_KEEP) |
  167.                                 A3XX_RB_STENCIL_CONTROL_ZPASS_BF(STENCIL_KEEP) |
  168.                                 A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(STENCIL_KEEP));
  169.         }
  170.  
  171.         if (buffers & PIPE_CLEAR_COLOR) {
  172.                 ce = 0xf;
  173.         } else {
  174.                 ce = 0x0;
  175.         }
  176.  
  177.         for (i = 0; i < 4; i++) {
  178.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_CONTROL(i), 1);
  179.                 OUT_RING(ring, A3XX_RB_MRT_CONTROL_ROP_CODE(12) |
  180.                                 A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_ALWAYS) |
  181.                                 A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(ce));
  182.  
  183.                 OUT_PKT0(ring, REG_A3XX_RB_MRT_BLEND_CONTROL(i), 1);
  184.                 OUT_RING(ring, A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(FACTOR_ONE) |
  185.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  186.                                 A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(FACTOR_ZERO) |
  187.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(FACTOR_ONE) |
  188.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(BLEND_DST_PLUS_SRC) |
  189.                                 A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(FACTOR_ZERO) |
  190.                                 A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE);
  191.         }
  192.  
  193.         OUT_PKT0(ring, REG_A3XX_GRAS_SU_MODE_CONTROL, 1);
  194.         OUT_RING(ring, A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(0));
  195.  
  196.         fd3_program_emit(ring, &ctx->solid_prog);
  197.  
  198.         fd3_emit_vertex_bufs(ring, &ctx->solid_prog, (struct fd3_vertex_buf[]) {
  199.                         { .prsc = fd3_ctx->solid_vbuf, .stride = 12, .format = PIPE_FORMAT_R32G32B32_FLOAT },
  200.                 }, 1);
  201.  
  202.         fd3_emit_constant(ring, SB_FRAG_SHADER, 0, 0, 4, color->ui, NULL);
  203.  
  204.         OUT_PKT0(ring, REG_A3XX_PC_PRIM_VTX_CNTL, 1);
  205.         OUT_RING(ring, A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(0) |
  206.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(PC_DRAW_TRIANGLES) |
  207.                         A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(PC_DRAW_TRIANGLES) |
  208.                         A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST);
  209.         OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
  210.         OUT_RING(ring, 0);            /* VFD_INDEX_MIN */
  211.         OUT_RING(ring, 2);            /* VFD_INDEX_MAX */
  212.         OUT_RING(ring, 0);            /* VFD_INSTANCEID_OFFSET */
  213.         OUT_RING(ring, 0);            /* VFD_INDEX_OFFSET */
  214.         OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
  215.         OUT_RING(ring, 0xffffffff);   /* PC_RESTART_INDEX */
  216.  
  217.         OUT_PKT3(ring, CP_EVENT_WRITE, 1);
  218.         OUT_RING(ring, PERFCOUNTER_STOP);
  219.  
  220.         OUT_PKT3(ring, CP_DRAW_INDX, 3);
  221.         OUT_RING(ring, 0x00000000);
  222.         OUT_RING(ring, DRAW(DI_PT_RECTLIST, DI_SRC_SEL_AUTO_INDEX,
  223.                         INDEX_SIZE_IGN, IGNORE_VISIBILITY));
  224.         OUT_RING(ring, 2);                                      /* NumIndices */
  225.  
  226.         OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
  227.         OUT_RING(ring, 0x00000000);
  228. }
  229.  
  230. void
  231. fd3_draw_init(struct pipe_context *pctx)
  232. {
  233.         struct fd_context *ctx = fd_context(pctx);
  234.         ctx->draw = fd3_draw;
  235.         ctx->clear = fd3_clear;
  236. }
  237.