summaryrefslogtreecommitdiff
path: root/src/panfrost/vulkan/panvk_vX_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/panfrost/vulkan/panvk_vX_cs.c')
-rw-r--r--src/panfrost/vulkan/panvk_vX_cs.c922
1 files changed, 0 insertions, 922 deletions
diff --git a/src/panfrost/vulkan/panvk_vX_cs.c b/src/panfrost/vulkan/panvk_vX_cs.c
deleted file mode 100644
index b5dfe8ec768..00000000000
--- a/src/panfrost/vulkan/panvk_vX_cs.c
+++ /dev/null
@@ -1,922 +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.
- */
-
-#include "gen_macros.h"
-
-#include "util/macros.h"
-#include "compiler/shader_enums.h"
-
-#include "vk_util.h"
-
-#include "panfrost-quirks.h"
-#include "pan_cs.h"
-#include "pan_encoder.h"
-#include "pan_pool.h"
-#include "pan_shader.h"
-
-#include "panvk_cs.h"
-#include "panvk_private.h"
-#include "panvk_varyings.h"
-
-static enum mali_mipmap_mode
-panvk_translate_sampler_mipmap_mode(VkSamplerMipmapMode mode)
-{
- switch (mode) {
- case VK_SAMPLER_MIPMAP_MODE_NEAREST: return MALI_MIPMAP_MODE_NEAREST;
- case VK_SAMPLER_MIPMAP_MODE_LINEAR: return MALI_MIPMAP_MODE_TRILINEAR;
- default: unreachable("Invalid mipmap mode");
- }
-}
-
-static unsigned
-panvk_translate_sampler_address_mode(VkSamplerAddressMode mode)
-{
- switch (mode) {
- case VK_SAMPLER_ADDRESS_MODE_REPEAT: return MALI_WRAP_MODE_REPEAT;
- case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: return MALI_WRAP_MODE_MIRRORED_REPEAT;
- case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: return MALI_WRAP_MODE_CLAMP_TO_EDGE;
- case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER: return MALI_WRAP_MODE_CLAMP_TO_BORDER;
- case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: return MALI_WRAP_MODE_MIRRORED_CLAMP_TO_EDGE;
- default: unreachable("Invalid wrap");
- }
-}
-
-static void
-panvk_translate_sampler_border_color(const VkSamplerCreateInfo *pCreateInfo,
- uint32_t border_color[4])
-{
- const VkSamplerCustomBorderColorCreateInfoEXT *pBorderColor =
- vk_find_struct_const(pCreateInfo->pNext, SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
-
- switch (pCreateInfo->borderColor) {
- case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
- case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
- border_color[0] = border_color[1] = border_color[2] = fui(0.0);
- border_color[3] =
- pCreateInfo->borderColor == VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK ?
- fui(1.0) : fui(0.0);
- break;
- case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
- case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
- border_color[0] = border_color[1] = border_color[2] = 0;
- border_color[3] =
- pCreateInfo->borderColor == VK_BORDER_COLOR_INT_OPAQUE_BLACK ?
- UINT_MAX : 0;
- break;
- case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
- border_color[0] = border_color[1] = border_color[2] = border_color[3] = fui(1.0);
- break;
- case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
- border_color[0] = border_color[1] = border_color[2] = border_color[3] = UINT_MAX;
- break;
- case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
- case VK_BORDER_COLOR_INT_CUSTOM_EXT:
- memcpy(border_color, pBorderColor->customBorderColor.int32, sizeof(uint32_t) * 4);
- break;
- default:
- unreachable("Invalid border color");
- }
-}
-
-static mali_pixel_format
-panvk_varying_hw_format(const struct panvk_device *dev,
- const struct panvk_varyings_info *varyings,
- gl_shader_stage stage, unsigned idx)
-{
- const struct panfrost_device *pdev = &dev->physical_device->pdev;
- gl_varying_slot loc = varyings->stage[stage].loc[idx];
- bool fs = stage == MESA_SHADER_FRAGMENT;
-
- switch (loc) {
- case VARYING_SLOT_PNTC:
- case VARYING_SLOT_PSIZ:
- return (MALI_R16F << 12) | panfrost_get_default_swizzle(1);
- case VARYING_SLOT_POS:
- return ((fs ? MALI_RGBA32F : MALI_SNAP_4) << 12) |
- panfrost_get_default_swizzle(4);
- default:
- assert(!panvk_varying_is_builtin(stage, loc));
- return pdev->formats[varyings->varying[loc].format].hw;
- }
-}
-
-static void
-panvk_emit_varying(const struct panvk_device *dev,
- const struct panvk_varyings_info *varyings,
- gl_shader_stage stage, unsigned idx,
- void *attrib)
-{
- gl_varying_slot loc = varyings->stage[stage].loc[idx];
- bool fs = stage == MESA_SHADER_FRAGMENT;
-
- pan_pack(attrib, ATTRIBUTE, cfg) {
- if (!panvk_varying_is_builtin(stage, loc)) {
- cfg.buffer_index = varyings->varying[loc].buf;
- cfg.offset = varyings->varying[loc].offset;
- } else {
- cfg.buffer_index =
- panvk_varying_buf_index(varyings,
- panvk_varying_buf_id(fs, loc));
- }
- cfg.offset_enable = PAN_ARCH == 5;
- cfg.format = panvk_varying_hw_format(dev, varyings, stage, idx);
- }
-}
-
-void
-panvk_per_arch(emit_varyings)(const struct panvk_device *dev,
- const struct panvk_varyings_info *varyings,
- gl_shader_stage stage,
- void *descs)
-{
- struct mali_attribute_packed *attrib = descs;
-
- for (unsigned i = 0; i < varyings->stage[stage].count; i++)
- panvk_emit_varying(dev, varyings, stage, i, attrib++);
-}
-
-static void
-panvk_emit_varying_buf(const struct panvk_varyings_info *varyings,
- enum panvk_varying_buf_id id, void *buf)
-{
- unsigned buf_idx = panvk_varying_buf_index(varyings, id);
-
- pan_pack(buf, ATTRIBUTE_BUFFER, cfg) {
-#if PAN_ARCH == 5
- enum mali_attribute_special special_id = panvk_varying_special_buf_id(id);
- if (special_id) {
- cfg.type = 0;
- cfg.special = special_id;
- continue;
- }
-#endif
- unsigned offset = varyings->buf[buf_idx].address & 63;
-
- cfg.stride = varyings->buf[buf_idx].stride;
- cfg.size = varyings->buf[buf_idx].size + offset;
- cfg.pointer = varyings->buf[buf_idx].address & ~63ULL;
- }
-}
-
-void
-panvk_per_arch(emit_varying_bufs)(const struct panvk_varyings_info *varyings,
- void *descs)
-{
- struct mali_attribute_buffer_packed *buf = descs;
-
- for (unsigned i = 0; i < PANVK_VARY_BUF_MAX; i++) {
- if (varyings->buf_mask & (1 << i))
- panvk_emit_varying_buf(varyings, i, buf++);
- }
-
- /* We need an empty entry to stop prefetching on Bifrost */
-#if PAN_ARCH >= 6
- memset(buf, 0, sizeof(*buf));
-#endif
-}
-
-static void
-panvk_emit_attrib_buf(const struct panvk_attribs_info *info,
- const struct panvk_draw_info *draw,
- const struct panvk_attrib_buf *bufs,
- unsigned buf_count,
- unsigned idx, void *desc)
-{
- const struct panvk_attrib_buf_info *buf_info = &info->buf[idx];
-
-#if PAN_ARCH == 5
- if (buf_info->special) {
- switch (buf_info->special_id) {
- case PAN_VERTEX_ID:
- panfrost_vertex_id(draw->padded_vertex_count, desc,
- draw->instance_count > 1);
- return;
- case PAN_INSTANCE_ID:
- panfrost_instance_id(draw->padded_vertex_count, desc,
- draw->instance_count > 1);
- return;
- default:
- unreachable("Invalid attribute ID");
- }
- }
-#endif
-
- assert(idx < buf_count);
- const struct panvk_attrib_buf *buf = &bufs[idx];
- unsigned divisor = buf_info->per_instance ?
- draw->padded_vertex_count : 0;
- unsigned stride = divisor && draw->instance_count == 1 ?
- 0 : buf_info->stride;
- mali_ptr addr = buf->address & ~63ULL;
- unsigned size = buf->size + (buf->address & 63);
-
- /* TODO: support instanced arrays */
- pan_pack(desc, ATTRIBUTE_BUFFER, cfg) {
- if (draw->instance_count > 1 && divisor) {
- cfg.type = MALI_ATTRIBUTE_TYPE_1D_MODULUS;
- cfg.divisor = divisor;
- }
-
- cfg.pointer = addr;
- cfg.stride = stride;
- cfg.size = size;
- }
-}
-
-void
-panvk_per_arch(emit_attrib_bufs)(const struct panvk_attribs_info *info,
- const struct panvk_attrib_buf *bufs,
- unsigned buf_count,
- const struct panvk_draw_info *draw,
- void *descs)
-{
- struct mali_attribute_buffer_packed *buf = descs;
-
- for (unsigned i = 0; i < info->buf_count; i++)
- panvk_emit_attrib_buf(info, draw, bufs, buf_count, i, buf++);
-
- /* A NULL entry is needed to stop prefecting on Bifrost */
-#if PAN_ARCH >= 6
- memset(buf, 0, sizeof(*buf));
-#endif
-}
-
-void
-panvk_per_arch(emit_sampler)(const VkSamplerCreateInfo *pCreateInfo,
- void *desc)
-{
- uint32_t border_color[4];
-
- panvk_translate_sampler_border_color(pCreateInfo, border_color);
-
- pan_pack(desc, SAMPLER, cfg) {
- cfg.magnify_nearest = pCreateInfo->magFilter == VK_FILTER_NEAREST;
- cfg.minify_nearest = pCreateInfo->minFilter == VK_FILTER_NEAREST;
- cfg.mipmap_mode = panvk_translate_sampler_mipmap_mode(pCreateInfo->mipmapMode);
- cfg.normalized_coordinates = !pCreateInfo->unnormalizedCoordinates;
-
- cfg.lod_bias = FIXED_16(pCreateInfo->mipLodBias, true);
- cfg.minimum_lod = FIXED_16(pCreateInfo->minLod, false);
- cfg.maximum_lod = FIXED_16(pCreateInfo->maxLod, false);
- cfg.wrap_mode_s = panvk_translate_sampler_address_mode(pCreateInfo->addressModeU);
- cfg.wrap_mode_t = panvk_translate_sampler_address_mode(pCreateInfo->addressModeV);
- cfg.wrap_mode_r = panvk_translate_sampler_address_mode(pCreateInfo->addressModeW);
- cfg.compare_function = panvk_per_arch(translate_sampler_compare_func)(pCreateInfo);
- cfg.border_color_r = border_color[0];
- cfg.border_color_g = border_color[1];
- cfg.border_color_b = border_color[2];
- cfg.border_color_a = border_color[3];
- }
-}
-
-static void
-panvk_emit_attrib(const struct panvk_device *dev,
- const struct panvk_attribs_info *attribs,
- const struct panvk_attrib_buf *bufs,
- unsigned buf_count,
- unsigned idx, void *attrib)
-{
- const struct panfrost_device *pdev = &dev->physical_device->pdev;
-
- pan_pack(attrib, ATTRIBUTE, cfg) {
- cfg.buffer_index = attribs->attrib[idx].buf;
- cfg.offset = attribs->attrib[idx].offset +
- (bufs[cfg.buffer_index].address & 63);
- cfg.format = pdev->formats[attribs->attrib[idx].format].hw;
- }
-}
-
-void
-panvk_per_arch(emit_attribs)(const struct panvk_device *dev,
- const struct panvk_attribs_info *attribs,
- const struct panvk_attrib_buf *bufs,
- unsigned buf_count,
- void *descs)
-{
- struct mali_attribute_packed *attrib = descs;
-
- for (unsigned i = 0; i < attribs->attrib_count; i++)
- panvk_emit_attrib(dev, attribs, bufs, buf_count, i, attrib++);
-}
-
-void
-panvk_per_arch(emit_ubo)(mali_ptr address, size_t size, void *desc)
-{
- pan_pack(desc, UNIFORM_BUFFER, cfg) {
- cfg.pointer = address;
- cfg.entries = DIV_ROUND_UP(size, 16);
- }
-}
-
-void
-panvk_per_arch(emit_ubos)(const struct panvk_pipeline *pipeline,
- const struct panvk_descriptor_state *state,
- void *descs)
-{
- struct mali_uniform_buffer_packed *ubos = descs;
-
- for (unsigned i = 0; i < ARRAY_SIZE(state->sets); i++) {
- const struct panvk_descriptor_set_layout *set_layout =
- pipeline->layout->sets[i].layout;
- const struct panvk_descriptor_set *set = state->sets[i].set;
- unsigned offset = pipeline->layout->sets[i].ubo_offset;
-
- if (!set_layout)
- continue;
-
- if (!set) {
- unsigned num_ubos = (set_layout->num_dynoffsets != 0) + set_layout->num_ubos;
- memset(&ubos[offset], 0, num_ubos * sizeof(*ubos));
- } else {
- memcpy(&ubos[offset], set->ubos, set_layout->num_ubos * sizeof(*ubos));
- if (set_layout->num_dynoffsets) {
- panvk_per_arch(emit_ubo)(state->sets[i].dynoffsets.gpu,
- set->layout->num_dynoffsets * sizeof(uint32_t),
- &ubos[offset + set_layout->num_ubos]);
- }
- }
- }
-
- for (unsigned i = 0; i < ARRAY_SIZE(pipeline->sysvals); i++) {
- if (!pipeline->sysvals[i].ids.sysval_count)
- continue;
-
- panvk_per_arch(emit_ubo)(pipeline->sysvals[i].ubo ? : state->sysvals[i],
- pipeline->sysvals[i].ids.sysval_count * 16,
- &ubos[pipeline->sysvals[i].ubo_idx]);
- }
-}
-
-void
-panvk_per_arch(emit_vertex_job)(const struct panvk_pipeline *pipeline,
- const struct panvk_draw_info *draw,
- void *job)
-{
- void *section = pan_section_ptr(job, COMPUTE_JOB, INVOCATION);
-
- memcpy(section, &draw->invocation, pan_size(INVOCATION));
-
- pan_section_pack(job, COMPUTE_JOB, PARAMETERS, cfg) {
- cfg.job_task_split = 5;
- }
-
- pan_section_pack(job, COMPUTE_JOB, DRAW, cfg) {
- cfg.draw_descriptor_is_64b = true;
-#if PAN_ARCH == 5
- cfg.texture_descriptor_is_64b = true;
-#endif
- cfg.state = pipeline->rsds[MESA_SHADER_VERTEX];
- cfg.attributes = draw->stages[MESA_SHADER_VERTEX].attributes;
- cfg.attribute_buffers = draw->attribute_bufs;
- cfg.varyings = draw->stages[MESA_SHADER_VERTEX].varyings;
- cfg.varying_buffers = draw->varying_bufs;
- cfg.thread_storage = draw->tls;
- cfg.offset_start = draw->offset_start;
- cfg.instance_size = draw->instance_count > 1 ?
- draw->padded_vertex_count : 1;
- cfg.uniform_buffers = draw->ubos;
- cfg.push_uniforms = draw->stages[PIPE_SHADER_VERTEX].push_constants;
- cfg.textures = draw->textures;
- cfg.samplers = draw->samplers;
- }
-
- pan_section_pack(job, COMPUTE_JOB, DRAW_PADDING, cfg);
-}
-
-static void
-panvk_emit_tiler_primitive(const struct panvk_pipeline *pipeline,
- const struct panvk_draw_info *draw,
- void *prim)
-{
- pan_pack(prim, PRIMITIVE, cfg) {
- cfg.draw_mode = pipeline->ia.topology;
- if (pipeline->ia.writes_point_size)
- cfg.point_size_array_format = MALI_POINT_SIZE_ARRAY_FORMAT_FP16;
-
- cfg.first_provoking_vertex = true;
- if (pipeline->ia.primitive_restart)
- cfg.primitive_restart = MALI_PRIMITIVE_RESTART_IMPLICIT;
- cfg.job_task_split = 6;
- /* TODO: indexed draws */
- cfg.index_count = draw->vertex_count;
- }
-}
-
-static void
-panvk_emit_tiler_primitive_size(const struct panvk_pipeline *pipeline,
- const struct panvk_draw_info *draw,
- void *primsz)
-{
- pan_pack(primsz, PRIMITIVE_SIZE, cfg) {
- if (pipeline->ia.writes_point_size) {
- cfg.size_array = draw->psiz;
- } else {
- cfg.constant = draw->line_width;
- }
- }
-}
-
-static void
-panvk_emit_tiler_dcd(const struct panvk_pipeline *pipeline,
- const struct panvk_draw_info *draw,
- void *dcd)
-{
- pan_pack(dcd, DRAW, cfg) {
- cfg.four_components_per_vertex = true;
- cfg.draw_descriptor_is_64b = true;
-#if PAN_ARCH == 5
- cfg.texture_descriptor_is_64b = true;
-#endif
- cfg.front_face_ccw = pipeline->rast.front_ccw;
- cfg.cull_front_face = pipeline->rast.cull_front_face;
- cfg.cull_back_face = pipeline->rast.cull_back_face;
- cfg.position = draw->position;
- cfg.state = draw->fs_rsd;
- cfg.attributes = draw->stages[MESA_SHADER_FRAGMENT].attributes;
- cfg.attribute_buffers = draw->attribute_bufs;
- cfg.viewport = draw->viewport;
- cfg.varyings = draw->stages[MESA_SHADER_FRAGMENT].varyings;
- cfg.varying_buffers = cfg.varyings ? draw->varying_bufs : 0;
-#if PAN_ARCH == 5
- cfg.fbd = draw->fb;
-#else
- cfg.thread_storage = draw->tls;
-#endif
-
- /* For all primitives but lines DRAW.flat_shading_vertex must
- * be set to 0 and the provoking vertex is selected with the
- * PRIMITIVE.first_provoking_vertex field.
- */
- if (pipeline->ia.topology == MALI_DRAW_MODE_LINES ||
- pipeline->ia.topology == MALI_DRAW_MODE_LINE_STRIP ||
- pipeline->ia.topology == MALI_DRAW_MODE_LINE_LOOP) {
- /* The logic is inverted on bifrost. */
-#if PAN_ARCH == 5
- cfg.flat_shading_vertex = false;
-#else
- cfg.flat_shading_vertex = true;
-#endif
- }
-
- cfg.offset_start = draw->offset_start;
- cfg.instance_size = draw->instance_count > 1 ?
- draw->padded_vertex_count : 1;
- cfg.uniform_buffers = draw->ubos;
- cfg.push_uniforms = draw->stages[PIPE_SHADER_FRAGMENT].push_constants;
- cfg.textures = draw->textures;
- cfg.samplers = draw->samplers;
-
- /* TODO: occlusion queries */
- }
-}
-
-void
-panvk_per_arch(emit_tiler_job)(const struct panvk_pipeline *pipeline,
- const struct panvk_draw_info *draw,
- void *job)
-{
- void *section;
-
- section = pan_section_ptr(job, TILER_JOB, INVOCATION);
- memcpy(section, &draw->invocation, pan_size(INVOCATION));
-
- section = pan_section_ptr(job, TILER_JOB, PRIMITIVE);
- panvk_emit_tiler_primitive(pipeline, draw, section);
-
- section = pan_section_ptr(job, TILER_JOB, PRIMITIVE_SIZE);
- panvk_emit_tiler_primitive_size(pipeline, draw, section);
-
- section = pan_section_ptr(job, TILER_JOB, DRAW);
- panvk_emit_tiler_dcd(pipeline, draw, section);
-
-#if PAN_ARCH >= 6
- pan_section_pack(job, TILER_JOB, TILER, cfg) {
- cfg.address = draw->tiler_ctx->bifrost;
- }
- pan_section_pack(job, TILER_JOB, DRAW_PADDING, padding);
- pan_section_pack(job, TILER_JOB, PADDING, padding);
-#endif
-}
-
-void
-panvk_per_arch(emit_fragment_job)(const struct panvk_framebuffer *fb,
- mali_ptr fbdesc,
- void *job)
-{
- pan_section_pack(job, FRAGMENT_JOB, HEADER, header) {
- header.type = MALI_JOB_TYPE_FRAGMENT;
- header.index = 1;
- }
-
- pan_section_pack(job, FRAGMENT_JOB, PAYLOAD, payload) {
- payload.bound_min_x = 0;
- payload.bound_min_y = 0;
-
- payload.bound_max_x = (fb->width - 1) >> MALI_TILE_SHIFT;
- payload.bound_max_y = (fb->height - 1) >> MALI_TILE_SHIFT;
- payload.framebuffer = fbdesc;
- }
-}
-
-void
-panvk_per_arch(emit_viewport)(const VkViewport *viewport,
- const VkRect2D *scissor,
- void *vpd)
-{
- /* The spec says "width must be greater than 0.0" */
- assert(viewport->x >= 0);
- int minx = (int)viewport->x;
- int maxx = (int)(viewport->x + viewport->width);
-
- /* Viewport height can be negative */
- int miny = MIN2((int)viewport->y, (int)(viewport->y + viewport->height));
- int maxy = MAX2((int)viewport->y, (int)(viewport->y + viewport->height));
-
- assert(scissor->offset.x >= 0 && scissor->offset.y >= 0);
- miny = MAX2(scissor->offset.x, minx);
- miny = MAX2(scissor->offset.y, miny);
- maxx = MIN2(scissor->offset.x + scissor->extent.width, maxx);
- maxy = MIN2(scissor->offset.y + scissor->extent.height, maxy);
-
- /* Make sure we don't end up with a max < min when width/height is 0 */
- maxx = maxx > minx ? maxx - 1 : maxx;
- maxy = maxy > miny ? maxy - 1 : maxy;
-
- assert(viewport->minDepth >= 0.0f && viewport->minDepth <= 1.0f);
- assert(viewport->maxDepth >= 0.0f && viewport->maxDepth <= 1.0f);
-
- pan_pack(vpd, VIEWPORT, cfg) {
- cfg.scissor_minimum_x = minx;
- cfg.scissor_minimum_y = miny;
- cfg.scissor_maximum_x = maxx;
- cfg.scissor_maximum_y = maxy;
- cfg.minimum_z = MIN2(viewport->minDepth, viewport->maxDepth);
- cfg.maximum_z = MAX2(viewport->minDepth, viewport->maxDepth);
- }
-}
-
-#if PAN_ARCH >= 6
-static enum mali_bifrost_register_file_format
-bifrost_blend_type_from_nir(nir_alu_type nir_type)
-{
- switch(nir_type) {
- case 0: /* Render target not in use */
- return 0;
- case nir_type_float16:
- return MALI_BIFROST_REGISTER_FILE_FORMAT_F16;
- case nir_type_float32:
- return MALI_BIFROST_REGISTER_FILE_FORMAT_F32;
- case nir_type_int32:
- return MALI_BIFROST_REGISTER_FILE_FORMAT_I32;
- case nir_type_uint32:
- return MALI_BIFROST_REGISTER_FILE_FORMAT_U32;
- case nir_type_int16:
- return MALI_BIFROST_REGISTER_FILE_FORMAT_I16;
- case nir_type_uint16:
- return MALI_BIFROST_REGISTER_FILE_FORMAT_U16;
- default:
- unreachable("Unsupported blend shader type for NIR alu type");
- }
-}
-#endif
-
-void
-panvk_per_arch(emit_blend)(const struct panvk_device *dev,
- const struct panvk_pipeline *pipeline,
- unsigned rt, void *bd)
-{
- const struct pan_blend_state *blend = &pipeline->blend.state;
- const struct pan_blend_rt_state *rts = &blend->rts[rt];
- bool dithered = false;
-
- pan_pack(bd, BLEND, cfg) {
- if (!blend->rt_count || !rts->equation.color_mask) {
- cfg.enable = false;
-#if PAN_ARCH >= 6
- cfg.bifrost.internal.mode = MALI_BIFROST_BLEND_MODE_OFF;
-#endif
- continue;
- }
-
- cfg.srgb = util_format_is_srgb(rts->format);
- cfg.load_destination = pan_blend_reads_dest(blend->rts[rt].equation);
- cfg.round_to_fb_precision = !dithered;
-
-#if PAN_ARCH <= 5
- cfg.midgard.blend_shader = false;
- pan_blend_to_fixed_function_equation(blend->rts[rt].equation,
- &cfg.midgard.equation);
- cfg.midgard.constant =
- pan_blend_get_constant(pan_blend_constant_mask(blend->rts[rt].equation),
- blend->constants);
-#else
- const struct panfrost_device *pdev = &dev->physical_device->pdev;
- const struct util_format_description *format_desc =
- util_format_description(rts->format);
- unsigned chan_size = 0;
- for (unsigned i = 0; i < format_desc->nr_channels; i++)
- chan_size = MAX2(format_desc->channel[i].size, chan_size);
-
- pan_blend_to_fixed_function_equation(blend->rts[rt].equation,
- &cfg.bifrost.equation);
-
- /* Fixed point constant */
- float fconst =
- pan_blend_get_constant(pan_blend_constant_mask(blend->rts[rt].equation),
- blend->constants);
- u16 constant = fconst * ((1 << chan_size) - 1);
- constant <<= 16 - chan_size;
- cfg.bifrost.constant = constant;
-
- if (pan_blend_is_opaque(blend->rts[rt].equation))
- cfg.bifrost.internal.mode = MALI_BIFROST_BLEND_MODE_OPAQUE;
- else
- cfg.bifrost.internal.mode = MALI_BIFROST_BLEND_MODE_FIXED_FUNCTION;
-
- /* If we want the conversion to work properly,
- * num_comps must be set to 4
- */
- cfg.bifrost.internal.fixed_function.num_comps = 4;
- cfg.bifrost.internal.fixed_function.conversion.memory_format =
- panfrost_format_to_bifrost_blend(pdev, rts->format, dithered);
- cfg.bifrost.internal.fixed_function.conversion.register_format =
- bifrost_blend_type_from_nir(pipeline->fs.info.bifrost.blend[rt].type);
- cfg.bifrost.internal.fixed_function.rt = rt;
-#endif
- }
-}
-
-void
-panvk_per_arch(emit_blend_constant)(const struct panvk_device *dev,
- const struct panvk_pipeline *pipeline,
- unsigned rt, const float *constants,
- void *bd)
-{
- float constant = constants[pipeline->blend.constant[rt].index];
-
- pan_pack(bd, BLEND, cfg) {
- cfg.enable = false;
-#if PAN_ARCH == 5
- cfg.midgard.constant = constant;
-#else
- cfg.bifrost.constant = constant * pipeline->blend.constant[rt].bifrost_factor;
-#endif
- }
-}
-
-void
-panvk_per_arch(emit_dyn_fs_rsd)(const struct panvk_pipeline *pipeline,
- const struct panvk_cmd_state *state,
- void *rsd)
-{
- pan_pack(rsd, RENDERER_STATE, cfg) {
- if (pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) {
- cfg.depth_units = state->rast.depth_bias.constant_factor * 2.0f;
- cfg.depth_factor = state->rast.depth_bias.slope_factor;
- cfg.depth_bias_clamp = state->rast.depth_bias.clamp;
- }
-
- if (pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) {
- cfg.stencil_front.mask = state->zs.s_front.compare_mask;
- cfg.stencil_back.mask = state->zs.s_back.compare_mask;
- }
-
- if (pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) {
- cfg.stencil_mask_misc.stencil_mask_front = state->zs.s_front.write_mask;
- cfg.stencil_mask_misc.stencil_mask_back = state->zs.s_back.write_mask;
- }
-
- if (pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) {
- cfg.stencil_front.reference_value = state->zs.s_front.ref;
- cfg.stencil_back.reference_value = state->zs.s_back.ref;
- }
- }
-}
-
-void
-panvk_per_arch(emit_base_fs_rsd)(const struct panvk_device *dev,
- const struct panvk_pipeline *pipeline,
- void *rsd)
-{
- const struct pan_shader_info *info = &pipeline->fs.info;
-
- pan_pack(rsd, RENDERER_STATE, cfg) {
- if (pipeline->fs.required) {
- pan_shader_prepare_rsd(info, pipeline->fs.address, &cfg);
-
-#if PAN_ARCH == 5
- /* If either depth or stencil is enabled, discard matters */
- bool zs_enabled =
- (pipeline->zs.z_test && pipeline->zs.z_compare_func != MALI_FUNC_ALWAYS) ||
- pipeline->zs.s_test;
-
- cfg.properties.midgard.work_register_count = info->work_reg_count;
- cfg.properties.midgard.force_early_z =
- info->fs.can_early_z && !pipeline->ms.alpha_to_coverage &&
- pipeline->zs.z_compare_func == MALI_FUNC_ALWAYS;
-
-
- /* Workaround a hardware errata where early-z cannot be enabled
- * when discarding even when the depth buffer is read-only, by
- * lying to the hardware about the discard and setting the
- * reads tilebuffer? flag to compensate */
- cfg.properties.midgard.shader_reads_tilebuffer =
- info->fs.outputs_read ||
- (!zs_enabled && info->fs.can_discard);
- cfg.properties.midgard.shader_contains_discard =
- zs_enabled && info->fs.can_discard;
-#else
- uint8_t rt_written = pipeline->fs.info.outputs_written >> FRAG_RESULT_DATA0;
- uint8_t rt_mask = pipeline->fs.rt_mask;
- cfg.properties.bifrost.allow_forward_pixel_to_kill =
- pipeline->fs.info.fs.can_fpk &&
- !(rt_mask & ~rt_written) &&
- !pipeline->ms.alpha_to_coverage &&
- !pipeline->blend.reads_dest;
-#endif
- } else {
-#if PAN_ARCH == 5
- cfg.shader.shader = 0x1;
- cfg.properties.midgard.work_register_count = 1;
- cfg.properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
- cfg.properties.midgard.force_early_z = true;
-#else
- cfg.properties.bifrost.shader_modifies_coverage = true;
- cfg.properties.bifrost.allow_forward_pixel_to_kill = true;
- cfg.properties.bifrost.allow_forward_pixel_to_be_killed = true;
- cfg.properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
-#endif
- }
-
- bool msaa = pipeline->ms.rast_samples > 1;
- cfg.multisample_misc.multisample_enable = msaa;
- cfg.multisample_misc.sample_mask =
- msaa ? pipeline->ms.sample_mask : UINT16_MAX;
-
- cfg.multisample_misc.depth_function =
- pipeline->zs.z_test ? pipeline->zs.z_compare_func : MALI_FUNC_ALWAYS;
-
- cfg.multisample_misc.depth_write_mask = pipeline->zs.z_write;
- cfg.multisample_misc.fixed_function_near_discard = !pipeline->rast.clamp_depth;
- cfg.multisample_misc.fixed_function_far_discard = !pipeline->rast.clamp_depth;
- cfg.multisample_misc.shader_depth_range_fixed = true;
-
- cfg.stencil_mask_misc.stencil_enable = pipeline->zs.s_test;
- cfg.stencil_mask_misc.alpha_to_coverage = pipeline->ms.alpha_to_coverage;
- cfg.stencil_mask_misc.alpha_test_compare_function = MALI_FUNC_ALWAYS;
- cfg.stencil_mask_misc.depth_range_1 = pipeline->rast.depth_bias.enable;
- cfg.stencil_mask_misc.depth_range_2 = pipeline->rast.depth_bias.enable;
- cfg.stencil_mask_misc.single_sampled_lines = pipeline->ms.rast_samples <= 1;
-
- if (!(pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS))) {
- cfg.depth_units = pipeline->rast.depth_bias.constant_factor * 2.0f;
- cfg.depth_factor = pipeline->rast.depth_bias.slope_factor;
- cfg.depth_bias_clamp = pipeline->rast.depth_bias.clamp;
- }
-
- if (!(pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))) {
- cfg.stencil_front.mask = pipeline->zs.s_front.compare_mask;
- cfg.stencil_back.mask = pipeline->zs.s_back.compare_mask;
- }
-
- if (!(pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))) {
- cfg.stencil_mask_misc.stencil_mask_front = pipeline->zs.s_front.write_mask;
- cfg.stencil_mask_misc.stencil_mask_back = pipeline->zs.s_back.write_mask;
- }
-
- if (!(pipeline->dynamic_state_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))) {
- cfg.stencil_front.reference_value = pipeline->zs.s_front.ref;
- cfg.stencil_back.reference_value = pipeline->zs.s_back.ref;
- }
-
- cfg.stencil_front.compare_function = pipeline->zs.s_front.compare_func;
- cfg.stencil_front.stencil_fail = pipeline->zs.s_front.fail_op;
- cfg.stencil_front.depth_fail = pipeline->zs.s_front.z_fail_op;
- cfg.stencil_front.depth_pass = pipeline->zs.s_front.pass_op;
- cfg.stencil_back.compare_function = pipeline->zs.s_back.compare_func;
- cfg.stencil_back.stencil_fail = pipeline->zs.s_back.fail_op;
- cfg.stencil_back.depth_fail = pipeline->zs.s_back.z_fail_op;
- cfg.stencil_back.depth_pass = pipeline->zs.s_back.pass_op;
- }
-}
-
-void
-panvk_per_arch(emit_non_fs_rsd)(const struct panvk_device *dev,
- const struct pan_shader_info *shader_info,
- mali_ptr shader_ptr,
- void *rsd)
-{
- assert(shader_info->stage != MESA_SHADER_FRAGMENT);
-
- pan_pack(rsd, RENDERER_STATE, cfg) {
- pan_shader_prepare_rsd(shader_info, shader_ptr, &cfg);
- }
-}
-
-void
-panvk_per_arch(emit_tiler_context)(const struct panvk_device *dev,
- unsigned width, unsigned height,
- const struct panfrost_ptr *descs)
-{
-#if PAN_ARCH == 5
- unreachable("Not supported on v5");
-#else
- const struct panfrost_device *pdev = &dev->physical_device->pdev;
-
- pan_pack(descs->cpu + pan_size(TILER_CONTEXT), TILER_HEAP, cfg) {
- cfg.size = pdev->tiler_heap->size;
- cfg.base = pdev->tiler_heap->ptr.gpu;
- cfg.bottom = pdev->tiler_heap->ptr.gpu;
- cfg.top = pdev->tiler_heap->ptr.gpu + pdev->tiler_heap->size;
- }
-
- pan_pack(descs->cpu, TILER_CONTEXT, cfg) {
- cfg.hierarchy_mask = 0x28;
- cfg.fb_width = width;
- cfg.fb_height = height;
- cfg.heap = descs->gpu + pan_size(TILER_CONTEXT);
- }
-#endif
-}
-
-unsigned
-panvk_per_arch(emit_fb)(const struct panvk_device *dev,
- const struct panvk_batch *batch,
- const struct panvk_subpass *subpass,
- const struct panvk_framebuffer *fb,
- const struct panvk_clear_value *clears,
- const struct pan_tls_info *tlsinfo,
- const struct pan_tiler_context *tilerctx,
- void *desc)
-{
- const struct panfrost_device *pdev = &dev->physical_device->pdev;
- struct panvk_image_view *view;
- bool crc_valid[8] = { false };
- struct pan_fb_info fbinfo = {
- .width = fb->width,
- .height = fb->height,
- .extent.maxx = fb->width - 1,
- .extent.maxy = fb->height - 1,
- .nr_samples = 1,
- };
-
- for (unsigned cb = 0; cb < subpass->color_count; cb++) {
- int idx = subpass->color_attachments[cb].idx;
- view = idx != VK_ATTACHMENT_UNUSED ?
- fb->attachments[idx].iview : NULL;
- if (!view)
- continue;
- fbinfo.rts[cb].view = &view->pview;
- fbinfo.rts[cb].clear = subpass->color_attachments[idx].clear;
- fbinfo.rts[cb].crc_valid = &crc_valid[cb];
-
- memcpy(fbinfo.rts[cb].clear_value, clears[idx].color,
- sizeof(fbinfo.rts[cb].clear_value));
- fbinfo.nr_samples =
- MAX2(fbinfo.nr_samples, view->pview.image->layout.nr_samples);
- }
-
- if (subpass->zs_attachment.idx != VK_ATTACHMENT_UNUSED) {
- view = fb->attachments[subpass->zs_attachment.idx].iview;
- const struct util_format_description *fdesc =
- util_format_description(view->pview.format);
-
- fbinfo.nr_samples =
- MAX2(fbinfo.nr_samples, view->pview.image->layout.nr_samples);
-
- if (util_format_has_depth(fdesc)) {
- fbinfo.zs.clear.z = subpass->zs_attachment.clear;
- fbinfo.zs.clear_value.depth = clears[subpass->zs_attachment.idx].depth;
- fbinfo.zs.view.zs = &view->pview;
- }
-
- if (util_format_has_depth(fdesc)) {
- fbinfo.zs.clear.s = subpass->zs_attachment.clear;
- fbinfo.zs.clear_value.stencil = clears[subpass->zs_attachment.idx].depth;
- if (!fbinfo.zs.view.zs)
- fbinfo.zs.view.s = &view->pview;
- }
- }
-
- return GENX(pan_emit_fbd)(pdev, &fbinfo, tlsinfo, tilerctx, desc);
-}