1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2 3 /* 4 * Copyright (C) 2014 Rob Clark <robclark (at) 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 (at) freedesktop.org> 27 */ 28 29 #ifndef FD4_DRAW_H_ 30 #define FD4_DRAW_H_ 31 32 #include "pipe/p_context.h" 33 34 #include "freedreno_draw.h" 35 36 void fd4_draw_init(struct pipe_context *pctx); 37 38 /* draw packet changed on a4xx, so cannot reuse one from a2xx/a3xx.. */ 39 40 static inline uint32_t DRAW4(enum pc_di_primtype prim_type, 41 enum pc_di_src_sel source_select, enum a4xx_index_size index_size, 42 enum pc_di_vis_cull_mode vis_cull_mode) 43 { 44 return CP_DRAW_INDX_OFFSET_0_PRIM_TYPE(prim_type) | 45 CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT(source_select) | 46 CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(index_size) | 47 CP_DRAW_INDX_OFFSET_0_VIS_CULL(vis_cull_mode); 48 } 49 50 static inline void 51 fd4_draw(struct fd_batch *batch, struct fd_ringbuffer *ring, 52 enum pc_di_primtype primtype, 53 enum pc_di_vis_cull_mode vismode, 54 enum pc_di_src_sel src_sel, uint32_t count, 55 uint32_t instances, enum a4xx_index_size idx_type, 56 uint32_t idx_size, uint32_t idx_offset, 57 struct pipe_resource *idx_buffer) 58 { 59 /* for debug after a lock up, write a unique counter value 60 * to scratch7 for each draw, to make it easier to match up 61 * register dumps to cmdstream. The combination of IB 62 * (scratch6) and DRAW is enough to "triangulate" the 63 * particular draw that caused lockup. 64 */ 65 emit_marker(ring, 7); 66 67 OUT_PKT3(ring, CP_DRAW_INDX_OFFSET, idx_buffer ? 6 : 3); 68 if (vismode == USE_VISIBILITY) { 69 /* leave vis mode blank for now, it will be patched up when 70 * we know if we are binning or not 71 */ 72 OUT_RINGP(ring, DRAW4(primtype, src_sel, idx_type, 0), 73 &batch->draw_patches); 74 } else { 75 OUT_RING(ring, DRAW4(primtype, src_sel, idx_type, vismode)); 76 } 77 OUT_RING(ring, instances); /* NumInstances */ 78 OUT_RING(ring, count); /* NumIndices */ 79 if (idx_buffer) { 80 OUT_RING(ring, 0x0); /* XXX */ 81 OUT_RELOC(ring, fd_resource(idx_buffer)->bo, idx_offset, 0, 0); 82 OUT_RING (ring, idx_size); 83 } 84 85 emit_marker(ring, 7); 86 87 fd_reset_wfi(batch); 88 } 89 90 static inline enum a4xx_index_size 91 fd4_size2indextype(unsigned index_size) 92 { 93 switch (index_size) { 94 case 1: return INDEX4_SIZE_8_BIT; 95 case 2: return INDEX4_SIZE_16_BIT; 96 case 4: return INDEX4_SIZE_32_BIT; 97 } 98 DBG("unsupported index size: %d", index_size); 99 assert(0); 100 return INDEX4_SIZE_32_BIT; 101 } 102 103 static inline void 104 fd4_draw_emit(struct fd_batch *batch, struct fd_ringbuffer *ring, 105 enum pc_di_primtype primtype, 106 enum pc_di_vis_cull_mode vismode, 107 const struct pipe_draw_info *info) 108 { 109 struct pipe_resource *idx_buffer = NULL; 110 enum a4xx_index_size idx_type; 111 enum pc_di_src_sel src_sel; 112 uint32_t idx_size, idx_offset; 113 114 if (info->indexed) { 115 struct pipe_index_buffer *idx = &batch->ctx->indexbuf; 116 117 assert(!idx->user_buffer); 118 119 idx_buffer = idx->buffer; 120 idx_type = fd4_size2indextype(idx->index_size); 121 idx_size = idx->index_size * info->count; 122 idx_offset = idx->offset + (info->start * idx->index_size); 123 src_sel = DI_SRC_SEL_DMA; 124 } else { 125 idx_buffer = NULL; 126 idx_type = INDEX4_SIZE_32_BIT; 127 idx_size = 0; 128 idx_offset = 0; 129 src_sel = DI_SRC_SEL_AUTO_INDEX; 130 } 131 132 fd4_draw(batch, ring, primtype, vismode, src_sel, 133 info->count, info->instance_count, 134 idx_type, idx_size, idx_offset, idx_buffer); 135 } 136 137 #endif /* FD4_DRAW_H_ */ 138