diff options
-rw-r--r-- | src/gallium/drivers/panfrost/meson.build | 1 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.c | 156 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_context.h | 7 | ||||
-rw-r--r-- | src/gallium/drivers/panfrost/pan_varyings.c | 182 |
4 files changed, 190 insertions, 156 deletions
diff --git a/src/gallium/drivers/panfrost/meson.build b/src/gallium/drivers/panfrost/meson.build index 1efe11f4962..76ec702ee4f 100644 --- a/src/gallium/drivers/panfrost/meson.build +++ b/src/gallium/drivers/panfrost/meson.build @@ -51,6 +51,7 @@ files_panfrost = files( 'pan_sfbd.c', 'pan_mfbd.c', 'pan_tiler.c', + 'pan_varyings.c', ) panfrost_includes = [ diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 26df0caa706..ac1d1b9429b 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -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) { diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 4e32a691200..542d24d2c27 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -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 diff --git a/src/gallium/drivers/panfrost/pan_varyings.c b/src/gallium/drivers/panfrost/pan_varyings.c new file mode 100644 index 00000000000..53c05bab61e --- /dev/null +++ b/src/gallium/drivers/panfrost/pan_varyings.c @@ -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; +} |