1/* 2 * Copyright (C) 2021 Collabora Ltd. 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 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#ifndef PANVK_VARYINGS_H 25#define PANVK_VARYINGS_H 26 27#include "util/bitset.h" 28#include "util/format/u_format.h" 29 30#include "compiler/shader_enums.h" 31#include "panfrost-job.h" 32 33#include "pan_pool.h" 34 35struct pan_pool; 36struct panvk_device; 37 38enum panvk_varying_buf_id { 39 PANVK_VARY_BUF_GENERAL, 40 PANVK_VARY_BUF_POSITION, 41 PANVK_VARY_BUF_PSIZ, 42 43 /* Keep last */ 44 PANVK_VARY_BUF_MAX, 45}; 46 47struct panvk_varying { 48 unsigned buf; 49 unsigned offset; 50 enum pipe_format format; 51}; 52 53struct panvk_varying_buf { 54 mali_ptr address; 55 void *cpu; 56 unsigned stride; 57 unsigned size; 58}; 59 60struct panvk_varyings_info { 61 struct panvk_varying varying[VARYING_SLOT_MAX]; 62 BITSET_DECLARE(active, VARYING_SLOT_MAX); 63 struct panvk_varying_buf buf[VARYING_SLOT_MAX]; 64 struct { 65 unsigned count; 66 gl_varying_slot loc[VARYING_SLOT_MAX]; 67 } stage[MESA_SHADER_STAGES]; 68 unsigned buf_mask; 69}; 70 71static inline unsigned 72panvk_varying_buf_index(const struct panvk_varyings_info *varyings, 73 enum panvk_varying_buf_id b) 74{ 75 return util_bitcount(varyings->buf_mask & BITFIELD_MASK(b)); 76} 77 78static inline enum panvk_varying_buf_id 79panvk_varying_buf_id(gl_varying_slot loc) 80{ 81 switch (loc) { 82 case VARYING_SLOT_POS: 83 return PANVK_VARY_BUF_POSITION; 84 case VARYING_SLOT_PSIZ: 85 return PANVK_VARY_BUF_PSIZ; 86 default: 87 return PANVK_VARY_BUF_GENERAL; 88 } 89} 90 91static inline unsigned 92panvk_varying_size(const struct panvk_varyings_info *varyings, 93 gl_varying_slot loc) 94{ 95 switch (loc) { 96 case VARYING_SLOT_POS: 97 return sizeof(float) * 4; 98 case VARYING_SLOT_PSIZ: 99 return sizeof(uint16_t); 100 default: 101 return util_format_get_blocksize(varyings->varying[loc].format); 102 } 103} 104 105static inline unsigned 106panvk_varyings_buf_count(struct panvk_varyings_info *varyings) 107{ 108 return util_bitcount(varyings->buf_mask); 109} 110 111static inline void 112panvk_varyings_alloc(struct panvk_varyings_info *varyings, 113 struct pan_pool *varying_mem_pool, 114 unsigned vertex_count) 115{ 116 for (unsigned i = 0; i < PANVK_VARY_BUF_MAX; i++) { 117 if (!(varyings->buf_mask & (1 << i))) continue; 118 119 unsigned buf_idx = panvk_varying_buf_index(varyings, i); 120 unsigned size = varyings->buf[buf_idx].stride * vertex_count; 121 if (!size) 122 continue; 123 124 struct panfrost_ptr ptr = 125 pan_pool_alloc_aligned(varying_mem_pool, size, 64); 126 127 varyings->buf[buf_idx].size = size; 128 varyings->buf[buf_idx].address = ptr.gpu; 129 varyings->buf[buf_idx].cpu = ptr.cpu; 130 } 131} 132 133#endif 134