mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-10-31 10:58:03 +03:00
218 lines
6.9 KiB
C
218 lines
6.9 KiB
C
/*
|
|
* Copyright (C) 2021 Collabora, Ltd.
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
#ifndef __PAN_SHADER_H__
|
|
#define __PAN_SHADER_H__
|
|
|
|
#include "compiler/nir/nir.h"
|
|
#include "genxml/gen_macros.h"
|
|
#include "panfrost/lib/pan_props.h"
|
|
#include "panfrost/compiler/pan_compiler.h"
|
|
|
|
#ifdef PAN_ARCH
|
|
|
|
#if PAN_ARCH >= 9
|
|
static inline enum mali_shader_stage
|
|
pan_shader_stage(const struct pan_shader_info *info)
|
|
{
|
|
switch (info->stage) {
|
|
case MESA_SHADER_VERTEX:
|
|
return MALI_SHADER_STAGE_VERTEX;
|
|
case MESA_SHADER_FRAGMENT:
|
|
return MALI_SHADER_STAGE_FRAGMENT;
|
|
default:
|
|
return MALI_SHADER_STAGE_COMPUTE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if PAN_ARCH >= 7
|
|
static inline enum mali_shader_register_allocation
|
|
pan_register_allocation(unsigned work_reg_count)
|
|
{
|
|
return (work_reg_count <= 32)
|
|
? MALI_SHADER_REGISTER_ALLOCATION_32_PER_THREAD
|
|
: MALI_SHADER_REGISTER_ALLOCATION_64_PER_THREAD;
|
|
}
|
|
#endif
|
|
|
|
static inline enum mali_depth_source
|
|
pan_depth_source(const struct pan_shader_info *info)
|
|
{
|
|
return info->fs.writes_depth ? MALI_DEPTH_SOURCE_SHADER
|
|
: MALI_DEPTH_SOURCE_FIXED_FUNCTION;
|
|
}
|
|
|
|
#if PAN_ARCH < 9
|
|
#if PAN_ARCH <= 5
|
|
static inline void
|
|
pan_shader_prepare_midgard_rsd(const struct pan_shader_info *info,
|
|
struct MALI_RENDERER_STATE *rsd)
|
|
{
|
|
assert((info->push.count & 3) == 0);
|
|
|
|
rsd->properties.uniform_count = info->push.count / 4;
|
|
rsd->properties.shader_has_side_effects = info->writes_global;
|
|
rsd->properties.fp_mode = MALI_FP_MODE_GL_INF_NAN_ALLOWED;
|
|
|
|
/* For fragment shaders, work register count, early-z, reads at draw-time */
|
|
|
|
if (info->stage != MESA_SHADER_FRAGMENT) {
|
|
rsd->properties.work_register_count = info->work_reg_count;
|
|
} else {
|
|
rsd->properties.shader_reads_tilebuffer = info->fs.outputs_read;
|
|
|
|
/* However, forcing early-z in the shader overrides draw-time */
|
|
rsd->properties.force_early_z = info->fs.early_fragment_tests;
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
#define pan_preloads(reg) (preload & BITFIELD64_BIT(reg))
|
|
|
|
static void
|
|
pan_make_preload(mesa_shader_stage stage, uint64_t preload,
|
|
struct MALI_PRELOAD *out)
|
|
{
|
|
switch (stage) {
|
|
case MESA_SHADER_VERTEX:
|
|
out->vertex.position_result_address_lo = pan_preloads(58);
|
|
out->vertex.position_result_address_hi = pan_preloads(59);
|
|
out->vertex.vertex_id = pan_preloads(61);
|
|
out->vertex.instance_id = pan_preloads(62);
|
|
break;
|
|
|
|
case MESA_SHADER_FRAGMENT:
|
|
out->fragment.primitive_id = pan_preloads(57);
|
|
out->fragment.primitive_flags = pan_preloads(58);
|
|
out->fragment.fragment_position = pan_preloads(59);
|
|
out->fragment.sample_mask_id = pan_preloads(61);
|
|
out->fragment.coverage = true;
|
|
break;
|
|
|
|
default:
|
|
out->compute.local_invocation_xy = pan_preloads(55);
|
|
out->compute.local_invocation_z = pan_preloads(56);
|
|
out->compute.work_group_x = pan_preloads(57);
|
|
out->compute.work_group_y = pan_preloads(58);
|
|
out->compute.work_group_z = pan_preloads(59);
|
|
out->compute.global_invocation_x = pan_preloads(60);
|
|
out->compute.global_invocation_y = pan_preloads(61);
|
|
out->compute.global_invocation_z = pan_preloads(62);
|
|
break;
|
|
}
|
|
}
|
|
|
|
#if PAN_ARCH == 7
|
|
static inline void
|
|
pan_pack_message_preload(struct MALI_MESSAGE_PRELOAD *cfg,
|
|
const struct bifrost_message_preload *msg)
|
|
{
|
|
enum mali_message_preload_register_format regfmt =
|
|
msg->fp16 ? MALI_MESSAGE_PRELOAD_REGISTER_FORMAT_F16
|
|
: MALI_MESSAGE_PRELOAD_REGISTER_FORMAT_F32;
|
|
|
|
if (msg->enabled && msg->texture) {
|
|
cfg->type = MALI_MESSAGE_TYPE_VAR_TEX;
|
|
cfg->var_tex.varying_index = msg->varying_index;
|
|
cfg->var_tex.texture_index = msg->texture_index;
|
|
cfg->var_tex.register_format = regfmt;
|
|
cfg->var_tex.skip = msg->skip;
|
|
cfg->var_tex.zero_lod = msg->zero_lod;
|
|
} else if (msg->enabled) {
|
|
cfg->type = MALI_MESSAGE_TYPE_LD_VAR;
|
|
cfg->ld_var.varying_index = msg->varying_index;
|
|
cfg->ld_var.register_format = regfmt;
|
|
cfg->ld_var.num_components = msg->num_components;
|
|
} else {
|
|
cfg->type = MALI_MESSAGE_TYPE_DISABLED;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static inline void
|
|
pan_shader_prepare_bifrost_rsd(const struct pan_shader_info *info,
|
|
struct MALI_RENDERER_STATE *rsd)
|
|
{
|
|
unsigned fau_count = DIV_ROUND_UP(info->push.count, 2);
|
|
rsd->preload.uniform_count = fau_count;
|
|
|
|
#if PAN_ARCH >= 7
|
|
rsd->properties.shader_register_allocation =
|
|
pan_register_allocation(info->work_reg_count);
|
|
#endif
|
|
|
|
pan_make_preload(info->stage, info->preload, &rsd->preload);
|
|
|
|
if (info->stage == MESA_SHADER_FRAGMENT) {
|
|
rsd->properties.shader_modifies_coverage =
|
|
info->fs.writes_coverage || info->fs.can_discard;
|
|
|
|
rsd->properties.allow_forward_pixel_to_be_killed = !info->writes_global;
|
|
|
|
#if PAN_ARCH >= 7
|
|
rsd->properties.shader_wait_dependency_6 = info->bifrost.wait_6;
|
|
rsd->properties.shader_wait_dependency_7 = info->bifrost.wait_7;
|
|
|
|
pan_pack_message_preload(&rsd->message_preload_1,
|
|
&info->bifrost.messages[0]);
|
|
pan_pack_message_preload(&rsd->message_preload_2,
|
|
&info->bifrost.messages[1]);
|
|
#endif
|
|
} else if (info->stage == MESA_SHADER_VERTEX && info->vs.secondary_enable) {
|
|
rsd->secondary_preload.uniform_count = fau_count;
|
|
|
|
pan_make_preload(info->stage, info->vs.secondary_preload,
|
|
&rsd->secondary_preload);
|
|
|
|
rsd->secondary_shader = rsd->shader.shader + info->vs.secondary_offset;
|
|
|
|
#if PAN_ARCH >= 7
|
|
rsd->properties.secondary_shader_register_allocation =
|
|
pan_register_allocation(info->vs.secondary_work_reg_count);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
static inline void
|
|
pan_shader_prepare_rsd(const struct pan_shader_info *shader_info,
|
|
uint64_t shader_ptr, struct MALI_RENDERER_STATE *rsd)
|
|
{
|
|
#if PAN_ARCH <= 5
|
|
shader_ptr |= shader_info->midgard.first_tag;
|
|
#endif
|
|
|
|
rsd->shader.shader = shader_ptr;
|
|
rsd->shader.attribute_count = shader_info->attribute_count;
|
|
rsd->shader.varying_count = shader_info->varyings.formats.count;
|
|
rsd->shader.texture_count = shader_info->texture_count;
|
|
rsd->shader.sampler_count = shader_info->sampler_count;
|
|
rsd->properties.shader_contains_barrier = shader_info->contains_barrier;
|
|
rsd->properties.uniform_buffer_count = shader_info->ubo_count;
|
|
|
|
if (shader_info->stage == MESA_SHADER_FRAGMENT) {
|
|
rsd->properties.stencil_from_shader = shader_info->fs.writes_stencil;
|
|
rsd->properties.depth_source = pan_depth_source(shader_info);
|
|
|
|
/* This also needs to be set if the API forces per-sample
|
|
* shading, but that'll just got ORed in */
|
|
rsd->multisample_misc.evaluate_per_sample =
|
|
shader_info->fs.sample_shading;
|
|
}
|
|
|
|
#if PAN_ARCH >= 6
|
|
pan_shader_prepare_bifrost_rsd(shader_info, rsd);
|
|
#else
|
|
pan_shader_prepare_midgard_rsd(shader_info, rsd);
|
|
#endif
|
|
}
|
|
#endif /* PAN_ARCH */
|
|
#endif
|
|
|
|
#endif
|