panfrost: Break out pan_varyings.c

This code is fairly self-contained, so let's factor it out of the giant
pan_context.c monster.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Alyssa Rosenzweig 2019-08-07 09:16:32 -07:00
parent 4dba493fd7
commit af6d3f7cb5
4 changed files with 190 additions and 156 deletions

View File

@ -51,6 +51,7 @@ files_panfrost = files(
'pan_sfbd.c',
'pan_mfbd.c',
'pan_tiler.c',
'pan_varyings.c',
)
panfrost_includes = [

View File

@ -463,162 +463,6 @@ panfrost_vertex_tiler_job(struct panfrost_context *ctx, bool is_tiler)
return transfer;
}
static mali_ptr
panfrost_emit_varyings(
struct panfrost_context *ctx,
union mali_attr *slot,
unsigned stride,
unsigned count)
{
/* Fill out the descriptor */
slot->stride = stride;
slot->size = stride * count;
slot->shift = slot->extra_flags = 0;
struct panfrost_transfer transfer =
panfrost_allocate_transient(ctx, slot->size);
slot->elements = transfer.gpu | MALI_ATTR_LINEAR;
return transfer.gpu;
}
static void
panfrost_emit_point_coord(union mali_attr *slot)
{
slot->elements = MALI_VARYING_POINT_COORD | MALI_ATTR_LINEAR;
slot->stride = slot->size = slot->shift = slot->extra_flags = 0;
}
static void
panfrost_emit_front_face(union mali_attr *slot)
{
slot->elements = MALI_VARYING_FRONT_FACING | MALI_ATTR_INTERNAL;
}
static void
panfrost_emit_varying_descriptor(
struct panfrost_context *ctx,
unsigned vertex_count)
{
/* Load the shaders */
struct panfrost_shader_state *vs = &ctx->shader[PIPE_SHADER_VERTEX]->variants[ctx->shader[PIPE_SHADER_VERTEX]->active_variant];
struct panfrost_shader_state *fs = &ctx->shader[PIPE_SHADER_FRAGMENT]->variants[ctx->shader[PIPE_SHADER_FRAGMENT]->active_variant];
unsigned int num_gen_varyings = 0;
/* Allocate the varying descriptor */
size_t vs_size = sizeof(struct mali_attr_meta) * vs->tripipe->varying_count;
size_t fs_size = sizeof(struct mali_attr_meta) * fs->tripipe->varying_count;
struct panfrost_transfer trans = panfrost_allocate_transient(ctx,
vs_size + fs_size);
/*
* Assign ->src_offset now that we know about all the general purpose
* varyings that will be used by the fragment and vertex shaders.
*/
for (unsigned i = 0; i < vs->tripipe->varying_count; i++) {
/*
* General purpose varyings have ->index set to 0, skip other
* entries.
*/
if (vs->varyings[i].index)
continue;
vs->varyings[i].src_offset = 16 * (num_gen_varyings++);
}
for (unsigned i = 0; i < fs->tripipe->varying_count; i++) {
unsigned j;
/* If we have a point sprite replacement, handle that here. We
* have to translate location first. TODO: Flip y in shader.
* We're already keying ... just time crunch .. */
unsigned loc = fs->varyings_loc[i];
unsigned pnt_loc =
(loc >= VARYING_SLOT_VAR0) ? (loc - VARYING_SLOT_VAR0) :
(loc == VARYING_SLOT_PNTC) ? 8 :
~0;
if (~pnt_loc && fs->point_sprite_mask & (1 << pnt_loc)) {
/* gl_PointCoord index by convention */
fs->varyings[i].index = 3;
fs->reads_point_coord = true;
/* Swizzle out the z/w to 0/1 */
fs->varyings[i].format = MALI_RG16F;
fs->varyings[i].swizzle =
panfrost_get_default_swizzle(2);
continue;
}
if (fs->varyings[i].index)
continue;
/*
* Re-use the VS general purpose varying pos if it exists,
* create a new one otherwise.
*/
for (j = 0; j < vs->tripipe->varying_count; j++) {
if (fs->varyings_loc[i] == vs->varyings_loc[j])
break;
}
if (j < vs->tripipe->varying_count)
fs->varyings[i].src_offset = vs->varyings[j].src_offset;
else
fs->varyings[i].src_offset = 16 * (num_gen_varyings++);
}
memcpy(trans.cpu, vs->varyings, vs_size);
memcpy(trans.cpu + vs_size, fs->varyings, fs_size);
ctx->payloads[PIPE_SHADER_VERTEX].postfix.varying_meta = trans.gpu;
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.varying_meta = trans.gpu + vs_size;
/* Buffer indices must be in this order per our convention */
union mali_attr varyings[PIPE_MAX_ATTRIBS];
unsigned idx = 0;
panfrost_emit_varyings(ctx, &varyings[idx++], num_gen_varyings * 16,
vertex_count);
/* fp32 vec4 gl_Position */
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.position_varying =
panfrost_emit_varyings(ctx, &varyings[idx++],
sizeof(float) * 4, vertex_count);
if (vs->writes_point_size || fs->reads_point_coord) {
/* fp16 vec1 gl_PointSize */
ctx->payloads[PIPE_SHADER_FRAGMENT].primitive_size.pointer =
panfrost_emit_varyings(ctx, &varyings[idx++],
2, vertex_count);
} else if (fs->reads_face) {
/* Dummy to advance index */
++idx;
}
if (fs->reads_point_coord) {
/* Special descriptor */
panfrost_emit_point_coord(&varyings[idx++]);
} else if (fs->reads_face) {
++idx;
}
if (fs->reads_face) {
panfrost_emit_front_face(&varyings[idx++]);
}
mali_ptr varyings_p = panfrost_upload_transient(ctx, &varyings, idx * sizeof(union mali_attr));
ctx->payloads[PIPE_SHADER_VERTEX].postfix.varyings = varyings_p;
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.varyings = varyings_p;
}
mali_ptr
panfrost_vertex_buffer_address(struct panfrost_context *ctx, unsigned i)
{

View File

@ -369,4 +369,11 @@ pan_expand_shift_odd(struct pan_shift_odd o);
void
panfrost_compute_context_init(struct pipe_context *pctx);
/* Varyings */
void
panfrost_emit_varying_descriptor(
struct panfrost_context *ctx,
unsigned vertex_count);
#endif

View File

@ -0,0 +1,182 @@
/*
* Copyright (C) 2018-2019 Alyssa Rosenzweig
* Copyright (C) 2019 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 "pan_context.h"
static mali_ptr
panfrost_emit_varyings(
struct panfrost_context *ctx,
union mali_attr *slot,
unsigned stride,
unsigned count)
{
/* Fill out the descriptor */
slot->stride = stride;
slot->size = stride * count;
slot->shift = slot->extra_flags = 0;
struct panfrost_transfer transfer =
panfrost_allocate_transient(ctx, slot->size);
slot->elements = transfer.gpu | MALI_ATTR_LINEAR;
return transfer.gpu;
}
static void
panfrost_emit_point_coord(union mali_attr *slot)
{
slot->elements = MALI_VARYING_POINT_COORD | MALI_ATTR_LINEAR;
slot->stride = slot->size = slot->shift = slot->extra_flags = 0;
}
static void
panfrost_emit_front_face(union mali_attr *slot)
{
slot->elements = MALI_VARYING_FRONT_FACING | MALI_ATTR_INTERNAL;
}
void
panfrost_emit_varying_descriptor(
struct panfrost_context *ctx,
unsigned vertex_count)
{
/* Load the shaders */
struct panfrost_shader_state *vs = &ctx->shader[PIPE_SHADER_VERTEX]->variants[ctx->shader[PIPE_SHADER_VERTEX]->active_variant];
struct panfrost_shader_state *fs = &ctx->shader[PIPE_SHADER_FRAGMENT]->variants[ctx->shader[PIPE_SHADER_FRAGMENT]->active_variant];
unsigned int num_gen_varyings = 0;
/* Allocate the varying descriptor */
size_t vs_size = sizeof(struct mali_attr_meta) * vs->tripipe->varying_count;
size_t fs_size = sizeof(struct mali_attr_meta) * fs->tripipe->varying_count;
struct panfrost_transfer trans = panfrost_allocate_transient(ctx,
vs_size + fs_size);
/*
* Assign ->src_offset now that we know about all the general purpose
* varyings that will be used by the fragment and vertex shaders.
*/
for (unsigned i = 0; i < vs->tripipe->varying_count; i++) {
/*
* General purpose varyings have ->index set to 0, skip other
* entries.
*/
if (vs->varyings[i].index)
continue;
vs->varyings[i].src_offset = 16 * (num_gen_varyings++);
}
for (unsigned i = 0; i < fs->tripipe->varying_count; i++) {
unsigned j;
/* If we have a point sprite replacement, handle that here. We
* have to translate location first. TODO: Flip y in shader.
* We're already keying ... just time crunch .. */
unsigned loc = fs->varyings_loc[i];
unsigned pnt_loc =
(loc >= VARYING_SLOT_VAR0) ? (loc - VARYING_SLOT_VAR0) :
(loc == VARYING_SLOT_PNTC) ? 8 :
~0;
if (~pnt_loc && fs->point_sprite_mask & (1 << pnt_loc)) {
/* gl_PointCoord index by convention */
fs->varyings[i].index = 3;
fs->reads_point_coord = true;
/* Swizzle out the z/w to 0/1 */
fs->varyings[i].format = MALI_RG16F;
fs->varyings[i].swizzle =
panfrost_get_default_swizzle(2);
continue;
}
if (fs->varyings[i].index)
continue;
/*
* Re-use the VS general purpose varying pos if it exists,
* create a new one otherwise.
*/
for (j = 0; j < vs->tripipe->varying_count; j++) {
if (fs->varyings_loc[i] == vs->varyings_loc[j])
break;
}
if (j < vs->tripipe->varying_count)
fs->varyings[i].src_offset = vs->varyings[j].src_offset;
else
fs->varyings[i].src_offset = 16 * (num_gen_varyings++);
}
memcpy(trans.cpu, vs->varyings, vs_size);
memcpy(trans.cpu + vs_size, fs->varyings, fs_size);
ctx->payloads[PIPE_SHADER_VERTEX].postfix.varying_meta = trans.gpu;
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.varying_meta = trans.gpu + vs_size;
/* Buffer indices must be in this order per our convention */
union mali_attr varyings[PIPE_MAX_ATTRIBS];
unsigned idx = 0;
panfrost_emit_varyings(ctx, &varyings[idx++], num_gen_varyings * 16,
vertex_count);
/* fp32 vec4 gl_Position */
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.position_varying =
panfrost_emit_varyings(ctx, &varyings[idx++],
sizeof(float) * 4, vertex_count);
if (vs->writes_point_size || fs->reads_point_coord) {
/* fp16 vec1 gl_PointSize */
ctx->payloads[PIPE_SHADER_FRAGMENT].primitive_size.pointer =
panfrost_emit_varyings(ctx, &varyings[idx++],
2, vertex_count);
} else if (fs->reads_face) {
/* Dummy to advance index */
++idx;
}
if (fs->reads_point_coord) {
/* Special descriptor */
panfrost_emit_point_coord(&varyings[idx++]);
} else if (fs->reads_face) {
++idx;
}
if (fs->reads_face) {
panfrost_emit_front_face(&varyings[idx++]);
}
mali_ptr varyings_p = panfrost_upload_transient(ctx, &varyings, idx * sizeof(union mali_attr));
ctx->payloads[PIPE_SHADER_VERTEX].postfix.varyings = varyings_p;
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.varyings = varyings_p;
}