panvk: Fix/simplify the shader linking logic
Stop passing panvk_varyings_info around and emit varying attributes when building the pipeline. All the command buffer logic has to do is allocate varying memory, and emit the attribute buffer descriptors pointing to these buffers. We also keep the buffer index fixed to keep things simple, when a buffer is missing, it will simply be filled with a zero-sized/NULL entry. Note that we store the buffer stride information in panvk_pipeline_shader to prepare the transition to vk_shader. As a bonus, this simplification seems to fix a few CTS failures. Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Mary Guillemard <mary.guillemard@collabora.com> Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28927>
This commit is contained in:
committed by
Marge Bot
parent
dfbec67cb0
commit
0471a30fcc
@@ -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
|
||||
|
||||
|
||||
@@ -110,7 +110,6 @@ struct panvk_cmd_graphics_state {
|
||||
|
||||
struct panvk_graphics_sysvals sysvals;
|
||||
|
||||
struct panvk_varyings_info varyings;
|
||||
mali_ptr fs_rsd;
|
||||
|
||||
struct {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user