panfrost: Move viewport desc emission out of panfrost_emit_for_draw()

Let's move the viewport descriptor emission logic to a dedicated helper
in order to shrink a bit the panfrost_emit_for_draw().

Note that this helper is placed in a new pan_cmdstream.c file where we
will group all cmdstream related helpers (everything that's related to
HW descriptor initialization emission).

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4083>
This commit is contained in:
Boris Brezillon
2020-03-05 09:30:58 +01:00
parent 79f8850527
commit a72bab1c3e
4 changed files with 183 additions and 96 deletions
+1
View File
@@ -38,6 +38,7 @@ files_panfrost = files(
'pan_blending.c',
'pan_blend_shaders.c',
'pan_blend_cso.c',
'pan_cmdstream.c',
'pan_compute.c',
'pan_fragment.c',
'pan_attributes.c',
@@ -0,0 +1,144 @@
/*
* Copyright (C) 2018 Alyssa Rosenzweig
* Copyright (C) 2020 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_allocate.h"
#include "pan_cmdstream.h"
#include "pan_context.h"
#include "pan_job.h"
static void
panfrost_mali_viewport_init(struct panfrost_context *ctx,
struct mali_viewport *mvp)
{
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
/* Clip bounds are encoded as floats. The viewport itself is encoded as
* (somewhat) asymmetric ints. */
const struct pipe_scissor_state *ss = &ctx->scissor;
memset(mvp, 0, sizeof(*mvp));
/* By default, do no viewport clipping, i.e. clip to (-inf, inf) in
* each direction. Clipping to the viewport in theory should work, but
* in practice causes issues when we're not explicitly trying to
* scissor */
*mvp = (struct mali_viewport) {
.clip_minx = -INFINITY,
.clip_miny = -INFINITY,
.clip_maxx = INFINITY,
.clip_maxy = INFINITY,
};
/* Always scissor to the viewport by default. */
float vp_minx = (int) (vp->translate[0] - fabsf(vp->scale[0]));
float vp_maxx = (int) (vp->translate[0] + fabsf(vp->scale[0]));
float vp_miny = (int) (vp->translate[1] - fabsf(vp->scale[1]));
float vp_maxy = (int) (vp->translate[1] + fabsf(vp->scale[1]));
float minz = (vp->translate[2] - fabsf(vp->scale[2]));
float maxz = (vp->translate[2] + fabsf(vp->scale[2]));
/* Apply the scissor test */
unsigned minx, miny, maxx, maxy;
if (ss && ctx->rasterizer && ctx->rasterizer->base.scissor) {
minx = MAX2(ss->minx, vp_minx);
miny = MAX2(ss->miny, vp_miny);
maxx = MIN2(ss->maxx, vp_maxx);
maxy = MIN2(ss->maxy, vp_maxy);
} else {
minx = vp_minx;
miny = vp_miny;
maxx = vp_maxx;
maxy = vp_maxy;
}
/* Hardware needs the min/max to be strictly ordered, so flip if we
* need to. The viewport transformation in the vertex shader will
* handle the negatives if we don't */
if (miny > maxy) {
unsigned temp = miny;
miny = maxy;
maxy = temp;
}
if (minx > maxx) {
unsigned temp = minx;
minx = maxx;
maxx = temp;
}
if (minz > maxz) {
float temp = minz;
minz = maxz;
maxz = temp;
}
/* Clamp to the framebuffer size as a last check */
minx = MIN2(ctx->pipe_framebuffer.width, minx);
maxx = MIN2(ctx->pipe_framebuffer.width, maxx);
miny = MIN2(ctx->pipe_framebuffer.height, miny);
maxy = MIN2(ctx->pipe_framebuffer.height, maxy);
/* Upload */
mvp->viewport0[0] = minx;
mvp->viewport1[0] = MALI_POSITIVE(maxx);
mvp->viewport0[1] = miny;
mvp->viewport1[1] = MALI_POSITIVE(maxy);
mvp->clip_minz = minz;
mvp->clip_maxz = maxz;
}
void
panfrost_emit_viewport(struct panfrost_batch *batch,
struct midgard_payload_vertex_tiler *tp)
{
struct panfrost_context *ctx = batch->ctx;
struct mali_viewport mvp;
panfrost_mali_viewport_init(batch->ctx, &mvp);
/* Update the job, unless we're doing wallpapering (whose lack of
* scissor we can ignore, since if we "miss" a tile of wallpaper, it'll
* just... be faster :) */
if (!ctx->wallpaper_batch)
panfrost_batch_union_scissor(batch, mvp.viewport0[0],
mvp.viewport0[1],
mvp.viewport1[0] + 1,
mvp.viewport1[1] + 1);
tp->postfix.viewport = panfrost_upload_transient(batch, &mvp,
sizeof(mvp));
}
@@ -0,0 +1,36 @@
/*
* Copyright (C) 2018 Alyssa Rosenzweig
* Copyright (C) 2020 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 __PAN_CMDSTREAM_H__
#define __PAN_CMDSTREAM_H__
#include "panfrost-job.h"
#include "pan_job.h"
void
panfrost_emit_viewport(struct panfrost_batch *batch,
struct midgard_payload_vertex_tiler *tp);
#endif /* __PAN_CMDSTREAM_H__ */
+2 -96
View File
@@ -51,6 +51,7 @@
#include "pan_screen.h"
#include "pan_blending.h"
#include "pan_blend_shaders.h"
#include "pan_cmdstream.h"
#include "pan_util.h"
#include "pandecode/decode.h"
@@ -952,8 +953,6 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
panfrost_upload_sampler_descriptors(ctx);
panfrost_upload_texture_descriptors(ctx);
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
for (int i = 0; i < PIPE_SHADER_TYPES; ++i) {
struct panfrost_shader_variants *all = ctx->shader[i];
@@ -1030,100 +1029,7 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
/* TODO: Upload the viewport somewhere more appropriate */
/* Clip bounds are encoded as floats. The viewport itself is encoded as
* (somewhat) asymmetric ints. */
const struct pipe_scissor_state *ss = &ctx->scissor;
struct mali_viewport view = {
/* By default, do no viewport clipping, i.e. clip to (-inf,
* inf) in each direction. Clipping to the viewport in theory
* should work, but in practice causes issues when we're not
* explicitly trying to scissor */
.clip_minx = -INFINITY,
.clip_miny = -INFINITY,
.clip_maxx = INFINITY,
.clip_maxy = INFINITY,
};
/* Always scissor to the viewport by default. */
float vp_minx = (int) (vp->translate[0] - fabsf(vp->scale[0]));
float vp_maxx = (int) (vp->translate[0] + fabsf(vp->scale[0]));
float vp_miny = (int) (vp->translate[1] - fabsf(vp->scale[1]));
float vp_maxy = (int) (vp->translate[1] + fabsf(vp->scale[1]));
float minz = (vp->translate[2] - fabsf(vp->scale[2]));
float maxz = (vp->translate[2] + fabsf(vp->scale[2]));
/* Apply the scissor test */
unsigned minx, miny, maxx, maxy;
if (ss && ctx->rasterizer && ctx->rasterizer->base.scissor) {
minx = MAX2(ss->minx, vp_minx);
miny = MAX2(ss->miny, vp_miny);
maxx = MIN2(ss->maxx, vp_maxx);
maxy = MIN2(ss->maxy, vp_maxy);
} else {
minx = vp_minx;
miny = vp_miny;
maxx = vp_maxx;
maxy = vp_maxy;
}
/* Hardware needs the min/max to be strictly ordered, so flip if we
* need to. The viewport transformation in the vertex shader will
* handle the negatives if we don't */
if (miny > maxy) {
unsigned temp = miny;
miny = maxy;
maxy = temp;
}
if (minx > maxx) {
unsigned temp = minx;
minx = maxx;
maxx = temp;
}
if (minz > maxz) {
float temp = minz;
minz = maxz;
maxz = temp;
}
/* Clamp to the framebuffer size as a last check */
minx = MIN2(ctx->pipe_framebuffer.width, minx);
maxx = MIN2(ctx->pipe_framebuffer.width, maxx);
miny = MIN2(ctx->pipe_framebuffer.height, miny);
maxy = MIN2(ctx->pipe_framebuffer.height, maxy);
/* Update the job, unless we're doing wallpapering (whose lack of
* scissor we can ignore, since if we "miss" a tile of wallpaper, it'll
* just... be faster :) */
if (!ctx->wallpaper_batch)
panfrost_batch_union_scissor(batch, minx, miny, maxx, maxy);
/* Upload */
view.viewport0[0] = minx;
view.viewport1[0] = MALI_POSITIVE(maxx);
view.viewport0[1] = miny;
view.viewport1[1] = MALI_POSITIVE(maxy);
view.clip_minz = minz;
view.clip_maxz = maxz;
ctx->payloads[PIPE_SHADER_FRAGMENT].postfix.viewport =
panfrost_upload_transient(batch,
&view,
sizeof(struct mali_viewport));
panfrost_emit_viewport(batch, &ctx->payloads[PIPE_SHADER_FRAGMENT]);
}
/* Corresponds to exactly one draw, but does not submit anything */