diff --git a/src/panfrost/ci/panfrost-g52-fails.txt b/src/panfrost/ci/panfrost-g52-fails.txt index fa14bb2bb54..9929c8f7648 100644 --- a/src/panfrost/ci/panfrost-g52-fails.txt +++ b/src/panfrost/ci/panfrost-g52-fails.txt @@ -369,27 +369,6 @@ dEQP-VK.rasterization.interpolation_multisample_4_bit.non_strict_lines,Crash dEQP-VK.rasterization.interpolation_multisample_4_bit.non_strict_lines_wide,Crash dEQP-VK.rasterization.interpolation_multisample_4_bit.triangles,Crash -dEQP-VK.glsl.operator.sequence.no_side_effects.highp_bool_vec2_fragment,Fail -dEQP-VK.glsl.operator.sequence.no_side_effects.highp_float_uint_fragment,Fail -dEQP-VK.glsl.operator.sequence.no_side_effects.highp_vec4_ivec4_bvec4_fragment,Fail -dEQP-VK.glsl.operator.sequence.no_side_effects.mediump_bool_vec2_fragment,Fail -dEQP-VK.glsl.operator.sequence.no_side_effects.mediump_float_uint_fragment,Fail -dEQP-VK.glsl.operator.sequence.no_side_effects.mediump_vec4_ivec4_bvec4_fragment,Fail -dEQP-VK.glsl.operator.sequence.side_effects.highp_bool_vec2_fragment,Fail -dEQP-VK.glsl.operator.sequence.side_effects.highp_float_uint_fragment,Fail -dEQP-VK.glsl.operator.sequence.side_effects.highp_vec4_fragment,Fail -dEQP-VK.glsl.operator.sequence.side_effects.mediump_bool_vec2_fragment,Fail -dEQP-VK.glsl.operator.sequence.side_effects.mediump_float_uint_fragment,Fail -dEQP-VK.glsl.operator.sequence.side_effects.mediump_vec4_fragment,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.linear_linear_mipmap_linear,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.linear_linear_mipmap_nearest,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.linear_nearest_mipmap_linear,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.linear_nearest_mipmap_nearest,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.nearest_linear_mipmap_linear,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.nearest_linear_mipmap_nearest,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.nearest_nearest_mipmap_linear,Fail -dEQP-VK.texture.explicit_lod.2d.derivatives.nearest_nearest_mipmap_nearest,Fail - # Seems to be caused by an off-by-0.5 in the position. Also passes if we change # the line shape mode to rectangular. This needs further investigation dEQP-VK.pipeline.monolithic.depth.format.d16_unorm.compare_ops.line_list_always_always_never_greater,Fail @@ -1215,9 +1194,6 @@ dEQP-VK.pipeline.monolithic.render_to_image.core.cube.small.r8g8b8a8_unorm_d24_u dEQP-VK.pipeline.monolithic.render_to_image.core.cube.small.r8g8b8a8_unorm_d32_sfloat_s8_uint,Fail dEQP-VK.pipeline.monolithic.render_to_image.core.cube.small.r8g8b8a8_unorm,Fail -# New test from VKCTS 1.3.8.x failing -dEQP-VK.pipeline.monolithic.vertex_input.misc.stride_change_vert_frag,Fail - # uprev Piglit in Mesa spec@ext_image_dma_buf_import@ext_image_dma_buf_import-refcount-multithread,Crash diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.h b/src/panfrost/vulkan/panvk_cmd_buffer.h index 7d6b1411092..4d6a1c4414f 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.h +++ b/src/panfrost/vulkan/panvk_cmd_buffer.h @@ -110,7 +110,6 @@ struct panvk_cmd_graphics_state { struct panvk_graphics_sysvals sysvals; - struct panvk_varyings_info varyings; mali_ptr fs_rsd; struct { diff --git a/src/panfrost/vulkan/panvk_pipeline.h b/src/panfrost/vulkan/panvk_pipeline.h index 9880ce09e65..cab02e62c1f 100644 --- a/src/panfrost/vulkan/panvk_pipeline.h +++ b/src/panfrost/vulkan/panvk_pipeline.h @@ -21,13 +21,19 @@ #include "pan_blend.h" #include "pan_desc.h" -#include "panvk_varyings.h" +#include "panvk_shader.h" #define MAX_RTS 8 struct panvk_pipeline_shader { mali_ptr code; mali_ptr rsd; + + struct { + mali_ptr attribs; + unsigned buf_strides[PANVK_VARY_BUF_MAX]; + } varyings; + struct pan_shader_info info; bool has_img_access; }; @@ -56,8 +62,6 @@ struct panvk_graphics_pipeline { struct panvk_pipeline_shader vs; struct panvk_pipeline_shader fs; - struct panvk_varyings_info varyings; - struct { struct { bool required; diff --git a/src/panfrost/vulkan/panvk_shader.h b/src/panfrost/vulkan/panvk_shader.h index 177699dfb0d..a8233d5049e 100644 --- a/src/panfrost/vulkan/panvk_shader.h +++ b/src/panfrost/vulkan/panvk_shader.h @@ -26,6 +26,15 @@ struct nir_shader; struct pan_blend_state; struct panvk_device; +enum panvk_varying_buf_id { + PANVK_VARY_BUF_GENERAL, + PANVK_VARY_BUF_POSITION, + PANVK_VARY_BUF_PSIZ, + + /* Keep last */ + PANVK_VARY_BUF_MAX, +}; + struct panvk_graphics_sysvals { struct { struct { diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index ba4ed54f9a1..325b2ec74a3 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -696,78 +696,53 @@ panvk_draw_prepare_varyings(struct panvk_cmd_buffer *cmdbuf, struct panvk_draw_info *draw) { const struct panvk_graphics_pipeline *pipeline = cmdbuf->state.gfx.pipeline; - struct panvk_varyings_info *varyings = &cmdbuf->state.gfx.varyings; - - panvk_varyings_alloc(varyings, &cmdbuf->varying_pool.base, - draw->padded_vertex_count * draw->instance_count); - - unsigned buf_count = panvk_varyings_buf_count(varyings); struct panfrost_ptr bufs = pan_pool_alloc_desc_array( - &cmdbuf->desc_pool.base, buf_count + 1, ATTRIBUTE_BUFFER); + &cmdbuf->desc_pool.base, PANVK_VARY_BUF_MAX + 1, ATTRIBUTE_BUFFER); struct mali_attribute_buffer_packed *buf_descs = bufs.cpu; const struct vk_input_assembly_state *ia = &cmdbuf->vk.dynamic_graphics_state.ia; bool writes_point_size = pipeline->vs.info.vs.writes_point_size && ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + unsigned vertex_count = draw->padded_vertex_count * draw->instance_count; + mali_ptr psiz_buf = 0; - for (unsigned i = 0, buf_idx = 0; i < PANVK_VARY_BUF_MAX; i++) { - if (varyings->buf_mask & (1 << i)) { - pan_pack(&buf_descs[buf_idx], ATTRIBUTE_BUFFER, cfg) { - unsigned offset = varyings->buf[buf_idx].address & 63; + for (unsigned i = 0; i < PANVK_VARY_BUF_MAX; i++) { + unsigned buf_size = vertex_count * pipeline->vs.varyings.buf_strides[i]; + mali_ptr buf_addr = + buf_size + ? pan_pool_alloc_aligned(&cmdbuf->varying_pool.base, buf_size, 64) + .gpu + : 0; - cfg.stride = varyings->buf[buf_idx].stride; - cfg.size = varyings->buf[buf_idx].size + offset; - cfg.pointer = varyings->buf[buf_idx].address & ~63ULL; - } - - buf_idx++; + pan_pack(&buf_descs[i], ATTRIBUTE_BUFFER, cfg) { + cfg.stride = pipeline->vs.varyings.buf_strides[i]; + cfg.size = buf_size; + cfg.pointer = buf_addr; } + + if (i == PANVK_VARY_BUF_POSITION) + draw->position = buf_addr; + + if (i == PANVK_VARY_BUF_PSIZ) + psiz_buf = buf_addr; } /* We need an empty entry to stop prefetching on Bifrost */ - memset(bufs.cpu + (pan_size(ATTRIBUTE_BUFFER) * buf_count), 0, + memset(bufs.cpu + (pan_size(ATTRIBUTE_BUFFER) * PANVK_VARY_BUF_MAX), 0, pan_size(ATTRIBUTE_BUFFER)); - if (BITSET_TEST(varyings->active, VARYING_SLOT_POS)) { - draw->position = - varyings->buf[varyings->varying[VARYING_SLOT_POS].buf].address + - varyings->varying[VARYING_SLOT_POS].offset; - } - - if (writes_point_size) { - draw->psiz = - varyings->buf[varyings->varying[VARYING_SLOT_PSIZ].buf].address + - varyings->varying[VARYING_SLOT_POS].offset; - } else if (ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || - ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) { + if (writes_point_size) + draw->psiz = psiz_buf; + else if (ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST || + ia->primitive_topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP) draw->line_width = cmdbuf->vk.dynamic_graphics_state.rs.line.width; - } else { + else draw->line_width = 1.0f; - } + draw->varying_bufs = bufs.gpu; - - for (unsigned s = 0; s < MESA_SHADER_STAGES; s++) { - if (!varyings->stage[s].count) - continue; - - struct panfrost_ptr attribs = pan_pool_alloc_desc_array( - &cmdbuf->desc_pool.base, varyings->stage[s].count, ATTRIBUTE); - struct mali_attribute_packed *attrib_descs = attribs.cpu; - - draw->stages[s].varyings = attribs.gpu; - for (unsigned i = 0; i < varyings->stage[s].count; i++) { - gl_varying_slot loc = varyings->stage[s].loc[i]; - - pan_pack(&attrib_descs[i], ATTRIBUTE, cfg) { - cfg.buffer_index = varyings->varying[loc].buf; - cfg.offset = varyings->varying[loc].offset; - cfg.offset_enable = false; - cfg.format = - panvk_varying_hw_format(s, loc, varyings->varying[loc].format); - } - } - } + draw->stages[MESA_SHADER_VERTEX].varyings = pipeline->vs.varyings.attribs; + draw->stages[MESA_SHADER_FRAGMENT].varyings = pipeline->fs.varyings.attribs; } static void @@ -2198,7 +2173,6 @@ panvk_per_arch(CmdBindPipeline)(VkCommandBuffer commandBuffer, &gfx_pipeline->state.dynamic); cmdbuf->state.gfx.fs_rsd = 0; - cmdbuf->state.gfx.varyings = gfx_pipeline->varyings; cmdbuf->state.gfx.pipeline = gfx_pipeline; break; } diff --git a/src/panfrost/vulkan/panvk_vX_pipeline.c b/src/panfrost/vulkan/panvk_vX_pipeline.c index 07fa6bb1ed9..43e4b14a7a7 100644 --- a/src/panfrost/vulkan/panvk_vX_pipeline.c +++ b/src/panfrost/vulkan/panvk_vX_pipeline.c @@ -477,79 +477,6 @@ init_fs_state(struct panvk_graphics_pipeline *pipeline, emit_blend(pipeline, i, &bds[i]); } -static void -update_varying_slot(struct panvk_varyings_info *varyings, gl_shader_stage stage, - const struct pan_shader_varying *varying, bool input) -{ - gl_varying_slot loc = varying->location; - enum panvk_varying_buf_id buf_id = panvk_varying_buf_id(loc); - - varyings->stage[stage].loc[varyings->stage[stage].count++] = loc; - - assert(loc < ARRAY_SIZE(varyings->varying)); - - enum pipe_format new_fmt = varying->format; - enum pipe_format old_fmt = varyings->varying[loc].format; - - BITSET_SET(varyings->active, loc); - - /* We expect inputs to either be set by a previous stage or be built - * in, skip the entry if that's not the case, we'll emit a const - * varying returning zero for those entries. - */ - if (input && old_fmt == PIPE_FORMAT_NONE) - return; - - unsigned new_size = util_format_get_blocksize(new_fmt); - unsigned old_size = util_format_get_blocksize(old_fmt); - - if (old_size < new_size) - varyings->varying[loc].format = new_fmt; - - /* Type (float or not) information is only known in the fragment shader, so - * override for that - */ - if (input) { - assert(stage == MESA_SHADER_FRAGMENT && "no geom/tess on Bifrost"); - varyings->varying[loc].format = new_fmt; - } - - varyings->buf_mask |= 1 << buf_id; -} - -static void -collect_varyings(struct panvk_graphics_pipeline *pipeline) -{ - const struct pan_shader_info *vs_info = &pipeline->vs.info; - const struct pan_shader_info *fs_info = &pipeline->fs.info; - - for (unsigned i = 0; i < vs_info->varyings.output_count; i++) { - update_varying_slot(&pipeline->varyings, MESA_SHADER_VERTEX, - &vs_info->varyings.output[i], false); - } - - for (unsigned i = 0; i < fs_info->varyings.input_count; i++) { - update_varying_slot(&pipeline->varyings, MESA_SHADER_FRAGMENT, - &fs_info->varyings.input[i], true); - } - - /* TODO: Xfb */ - gl_varying_slot loc; - BITSET_FOREACH_SET(loc, pipeline->varyings.active, VARYING_SLOT_MAX) { - if (pipeline->varyings.varying[loc].format == PIPE_FORMAT_NONE) - continue; - - enum panvk_varying_buf_id buf_id = panvk_varying_buf_id(loc); - unsigned buf_idx = panvk_varying_buf_index(&pipeline->varyings, buf_id); - unsigned varying_sz = panvk_varying_size(&pipeline->varyings, loc); - - pipeline->varyings.varying[loc].buf = buf_idx; - pipeline->varyings.varying[loc].offset = - pipeline->varyings.buf[buf_idx].stride; - pipeline->varyings.buf[buf_idx].stride += varying_sz; - } -} - static VkResult init_pipeline_shader(struct panvk_pipeline *pipeline, const VkPipelineShaderStageCreateInfo *stage_info, @@ -604,6 +531,202 @@ init_pipeline_shader(struct panvk_pipeline *pipeline, return VK_SUCCESS; } +static mali_pixel_format +get_varying_format(gl_shader_stage stage, gl_varying_slot loc, + enum pipe_format pfmt) +{ + switch (loc) { + case VARYING_SLOT_PNTC: + case VARYING_SLOT_PSIZ: +#if PAN_ARCH <= 6 + return (MALI_R16F << 12) | panfrost_get_default_swizzle(1); +#else + return (MALI_R16F << 12) | MALI_RGB_COMPONENT_ORDER_R000; +#endif + case VARYING_SLOT_POS: +#if PAN_ARCH <= 6 + return (MALI_SNAP_4 << 12) | panfrost_get_default_swizzle(4); +#else + return (MALI_SNAP_4 << 12) | MALI_RGB_COMPONENT_ORDER_RGBA; +#endif + default: + assert(pfmt != PIPE_FORMAT_NONE); + return GENX(panfrost_format_from_pipe_format)(pfmt)->hw; + } +} + +struct varyings_info { + enum pipe_format fmts[VARYING_SLOT_MAX]; + BITSET_DECLARE(active, VARYING_SLOT_MAX); +}; + +static void +collect_varyings_info(const struct pan_shader_varying *varyings, + unsigned varying_count, struct varyings_info *info) +{ + for (unsigned i = 0; i < varying_count; i++) { + gl_varying_slot loc = varyings[i].location; + + if (varyings[i].format == PIPE_FORMAT_NONE) + continue; + + info->fmts[loc] = varyings[i].format; + BITSET_SET(info->active, loc); + } +} + +static inline enum panvk_varying_buf_id +varying_buf_id(gl_varying_slot loc) +{ + switch (loc) { + case VARYING_SLOT_POS: + return PANVK_VARY_BUF_POSITION; + case VARYING_SLOT_PSIZ: + return PANVK_VARY_BUF_PSIZ; + default: + return PANVK_VARY_BUF_GENERAL; + } +} + +static mali_pixel_format +varying_format(gl_varying_slot loc, enum pipe_format pfmt) +{ + switch (loc) { + case VARYING_SLOT_PNTC: + case VARYING_SLOT_PSIZ: +#if PAN_ARCH <= 6 + return (MALI_R16F << 12) | panfrost_get_default_swizzle(1); +#else + return (MALI_R16F << 12) | MALI_RGB_COMPONENT_ORDER_R000; +#endif + case VARYING_SLOT_POS: +#if PAN_ARCH <= 6 + return (MALI_SNAP_4 << 12) | panfrost_get_default_swizzle(4); +#else + return (MALI_SNAP_4 << 12) | MALI_RGB_COMPONENT_ORDER_RGBA; +#endif + default: + return GENX(panfrost_format_from_pipe_format)(pfmt)->hw; + } +} + +static mali_ptr +emit_varying_attrs(struct pan_pool *desc_pool, + const struct pan_shader_varying *varyings, + unsigned varying_count, const struct varyings_info *info, + unsigned *buf_offsets) +{ + unsigned attr_count = BITSET_COUNT(info->active); + struct panfrost_ptr ptr = + pan_pool_alloc_desc_array(desc_pool, attr_count, ATTRIBUTE); + struct mali_attribute_packed *attrs = ptr.cpu; + unsigned attr_idx = 0; + + for (unsigned i = 0; i < varying_count; i++) { + pan_pack(&attrs[attr_idx++], ATTRIBUTE, cfg) { + gl_varying_slot loc = varyings[i].location; + enum pipe_format pfmt = varyings[i].format != PIPE_FORMAT_NONE + ? info->fmts[loc] + : PIPE_FORMAT_NONE; + + if (pfmt == PIPE_FORMAT_NONE) { +#if PAN_ARCH >= 7 + cfg.format = (MALI_CONSTANT << 12) | MALI_RGB_COMPONENT_ORDER_0000; +#else + cfg.format = (MALI_CONSTANT << 12) | PAN_V6_SWIZZLE(0, 0, 0, 0); +#endif + } else { + cfg.buffer_index = varying_buf_id(loc); + cfg.offset = buf_offsets[loc]; + cfg.format = varying_format(loc, info->fmts[loc]); + } + cfg.offset_enable = false; + } + } + + return ptr.gpu; +} + +static void +link_shaders(struct panvk_graphics_pipeline *pipeline, + struct panvk_pipeline_shader *stage, + struct panvk_pipeline_shader *next_stage) +{ + BITSET_DECLARE(active_attrs, VARYING_SLOT_MAX) = {0}; + unsigned buf_strides[PANVK_VARY_BUF_MAX] = {0}; + unsigned buf_offsets[VARYING_SLOT_MAX] = {0}; + struct varyings_info out_vars = {0}; + struct varyings_info in_vars = {0}; + unsigned loc; + + collect_varyings_info(stage->info.varyings.output, + stage->info.varyings.output_count, &out_vars); + collect_varyings_info(next_stage->info.varyings.input, + next_stage->info.varyings.input_count, &in_vars); + + BITSET_OR(active_attrs, in_vars.active, out_vars.active); + + /* Handle the position and point size buffers explicitly, as they are + * passed through separate buffer pointers to the tiler job. + */ + if (next_stage->info.stage == MESA_SHADER_FRAGMENT) { + if (BITSET_TEST(out_vars.active, VARYING_SLOT_POS)) { + buf_strides[PANVK_VARY_BUF_POSITION] = sizeof(float) * 4; + BITSET_CLEAR(active_attrs, VARYING_SLOT_POS); + } + + if (BITSET_TEST(out_vars.active, VARYING_SLOT_PSIZ)) { + buf_strides[PANVK_VARY_BUF_PSIZ] = sizeof(uint16_t); + BITSET_CLEAR(active_attrs, VARYING_SLOT_PSIZ); + } + } + + BITSET_FOREACH_SET(loc, active_attrs, VARYING_SLOT_MAX) { + /* We expect stage to write to all inputs read by next_stage, and + * next_stage to read all inputs written by stage. If that's not the + * case, we keep PIPE_FORMAT_NONE to reflect the fact we should use a + * sink attribute (writes are discarded, reads return zeros). + */ + if (in_vars.fmts[loc] == PIPE_FORMAT_NONE || + out_vars.fmts[loc] == PIPE_FORMAT_NONE) { + in_vars.fmts[loc] = PIPE_FORMAT_NONE; + out_vars.fmts[loc] = PIPE_FORMAT_NONE; + continue; + } + + unsigned out_size = util_format_get_blocksize(out_vars.fmts[loc]); + unsigned buf_idx = varying_buf_id(loc); + + /* Always trust the 'next_stage' input format, so we can: + * - discard components that are never read + * - use float types for interpolated fragment shader inputs + * - use fp16 for floats with mediump + * - make sure components that are not written by 'stage' are set to zero + */ + out_vars.fmts[loc] = in_vars.fmts[loc]; + + /* Special buffers are handled explicitly before this loop, everything + * else should be laid out in the general varying buffer. + */ + assert(buf_idx == PANVK_VARY_BUF_GENERAL); + + /* Keep things aligned a 32-bit component. */ + buf_offsets[loc] = buf_strides[buf_idx]; + buf_strides[buf_idx] += ALIGN_POT(out_size, 4); + } + + stage->varyings.attribs = emit_varying_attrs( + &pipeline->base.desc_pool.base, stage->info.varyings.output, + stage->info.varyings.output_count, &out_vars, buf_offsets); + next_stage->varyings.attribs = emit_varying_attrs( + &pipeline->base.desc_pool.base, next_stage->info.varyings.input, + next_stage->info.varyings.input_count, &in_vars, buf_offsets); + memcpy(stage->varyings.buf_strides, buf_strides, + sizeof(stage->varyings.buf_strides)); + memcpy(next_stage->varyings.buf_strides, buf_strides, + sizeof(next_stage->varyings.buf_strides)); +} + static VkResult panvk_graphics_pipeline_create(struct panvk_device *dev, struct vk_pipeline_cache *cache, @@ -670,8 +793,8 @@ panvk_graphics_pipeline_create(struct panvk_device *dev, return result; } - collect_varyings(gfx_pipeline); init_fs_state(gfx_pipeline, &state); + link_shaders(gfx_pipeline, &gfx_pipeline->vs, &gfx_pipeline->fs); return VK_SUCCESS; } diff --git a/src/panfrost/vulkan/panvk_varyings.h b/src/panfrost/vulkan/panvk_varyings.h deleted file mode 100644 index d3fb80c5453..00000000000 --- a/src/panfrost/vulkan/panvk_varyings.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2021 Collabora Ltd. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef PANVK_VARYINGS_H -#define PANVK_VARYINGS_H - -#include "util/bitset.h" -#include "util/format/u_format.h" - -#include "compiler/shader_enums.h" -#include "panfrost-job.h" - -#include "pan_pool.h" - -struct pan_pool; -struct panvk_device; - -enum panvk_varying_buf_id { - PANVK_VARY_BUF_GENERAL, - PANVK_VARY_BUF_POSITION, - PANVK_VARY_BUF_PSIZ, - - /* Keep last */ - PANVK_VARY_BUF_MAX, -}; - -struct panvk_varying { - unsigned buf; - unsigned offset; - enum pipe_format format; -}; - -struct panvk_varying_buf { - mali_ptr address; - void *cpu; - unsigned stride; - unsigned size; -}; - -struct panvk_varyings_info { - struct panvk_varying varying[VARYING_SLOT_MAX]; - BITSET_DECLARE(active, VARYING_SLOT_MAX); - struct panvk_varying_buf buf[VARYING_SLOT_MAX]; - struct { - unsigned count; - gl_varying_slot loc[VARYING_SLOT_MAX]; - } stage[MESA_SHADER_STAGES]; - unsigned buf_mask; -}; - -static inline unsigned -panvk_varying_buf_index(const struct panvk_varyings_info *varyings, - enum panvk_varying_buf_id b) -{ - return util_bitcount(varyings->buf_mask & BITFIELD_MASK(b)); -} - -static inline enum panvk_varying_buf_id -panvk_varying_buf_id(gl_varying_slot loc) -{ - switch (loc) { - case VARYING_SLOT_POS: - return PANVK_VARY_BUF_POSITION; - case VARYING_SLOT_PSIZ: - return PANVK_VARY_BUF_PSIZ; - default: - return PANVK_VARY_BUF_GENERAL; - } -} - -static inline unsigned -panvk_varying_size(const struct panvk_varyings_info *varyings, - gl_varying_slot loc) -{ - switch (loc) { - case VARYING_SLOT_POS: - return sizeof(float) * 4; - case VARYING_SLOT_PSIZ: - return sizeof(uint16_t); - default: - return util_format_get_blocksize(varyings->varying[loc].format); - } -} - -static inline unsigned -panvk_varyings_buf_count(struct panvk_varyings_info *varyings) -{ - return util_bitcount(varyings->buf_mask); -} - -static inline void -panvk_varyings_alloc(struct panvk_varyings_info *varyings, - struct pan_pool *varying_mem_pool, unsigned vertex_count) -{ - for (unsigned i = 0; i < PANVK_VARY_BUF_MAX; i++) { - if (!(varyings->buf_mask & (1 << i))) - continue; - - unsigned buf_idx = panvk_varying_buf_index(varyings, i); - unsigned size = varyings->buf[buf_idx].stride * vertex_count; - if (!size) - continue; - - struct panfrost_ptr ptr = - pan_pool_alloc_aligned(varying_mem_pool, size, 64); - - varyings->buf[buf_idx].size = size; - varyings->buf[buf_idx].address = ptr.gpu; - varyings->buf[buf_idx].cpu = ptr.cpu; - } -} - -#endif