panfrost: Move the const buf emission logic out of panfrost_emit_for_draw()
Let's move the constant buffer emission logic in a dedicated helper to make panfrost_emit_for_draw() a bit more dry. 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:
@@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pan_allocate.h"
|
#include "pan_allocate.h"
|
||||||
|
#include "pan_bo.h"
|
||||||
#include "pan_cmdstream.h"
|
#include "pan_cmdstream.h"
|
||||||
#include "pan_context.h"
|
#include "pan_context.h"
|
||||||
#include "pan_job.h"
|
#include "pan_job.h"
|
||||||
@@ -142,3 +143,282 @@ panfrost_emit_viewport(struct panfrost_batch *batch,
|
|||||||
tp->postfix.viewport = panfrost_upload_transient(batch, &mvp,
|
tp->postfix.viewport = panfrost_upload_transient(batch, &mvp,
|
||||||
sizeof(mvp));
|
sizeof(mvp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static mali_ptr
|
||||||
|
panfrost_map_constant_buffer_gpu(struct panfrost_batch *batch,
|
||||||
|
enum pipe_shader_type st,
|
||||||
|
struct panfrost_constant_buffer *buf,
|
||||||
|
unsigned index)
|
||||||
|
{
|
||||||
|
struct pipe_constant_buffer *cb = &buf->cb[index];
|
||||||
|
struct panfrost_resource *rsrc = pan_resource(cb->buffer);
|
||||||
|
|
||||||
|
if (rsrc) {
|
||||||
|
panfrost_batch_add_bo(batch, rsrc->bo,
|
||||||
|
PAN_BO_ACCESS_SHARED |
|
||||||
|
PAN_BO_ACCESS_READ |
|
||||||
|
panfrost_bo_access_for_stage(st));
|
||||||
|
|
||||||
|
/* Alignment gauranteed by
|
||||||
|
* PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT */
|
||||||
|
return rsrc->bo->gpu + cb->buffer_offset;
|
||||||
|
} else if (cb->user_buffer) {
|
||||||
|
return panfrost_upload_transient(batch,
|
||||||
|
cb->user_buffer +
|
||||||
|
cb->buffer_offset,
|
||||||
|
cb->buffer_size);
|
||||||
|
} else {
|
||||||
|
unreachable("No constant buffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sysval_uniform {
|
||||||
|
union {
|
||||||
|
float f[4];
|
||||||
|
int32_t i[4];
|
||||||
|
uint32_t u[4];
|
||||||
|
uint64_t du[2];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
panfrost_upload_viewport_scale_sysval(struct panfrost_batch *batch,
|
||||||
|
struct sysval_uniform *uniform)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
|
||||||
|
|
||||||
|
uniform->f[0] = vp->scale[0];
|
||||||
|
uniform->f[1] = vp->scale[1];
|
||||||
|
uniform->f[2] = vp->scale[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panfrost_upload_viewport_offset_sysval(struct panfrost_batch *batch,
|
||||||
|
struct sysval_uniform *uniform)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
|
||||||
|
|
||||||
|
uniform->f[0] = vp->translate[0];
|
||||||
|
uniform->f[1] = vp->translate[1];
|
||||||
|
uniform->f[2] = vp->translate[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void panfrost_upload_txs_sysval(struct panfrost_batch *batch,
|
||||||
|
enum pipe_shader_type st,
|
||||||
|
unsigned int sysvalid,
|
||||||
|
struct sysval_uniform *uniform)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
unsigned texidx = PAN_SYSVAL_ID_TO_TXS_TEX_IDX(sysvalid);
|
||||||
|
unsigned dim = PAN_SYSVAL_ID_TO_TXS_DIM(sysvalid);
|
||||||
|
bool is_array = PAN_SYSVAL_ID_TO_TXS_IS_ARRAY(sysvalid);
|
||||||
|
struct pipe_sampler_view *tex = &ctx->sampler_views[st][texidx]->base;
|
||||||
|
|
||||||
|
assert(dim);
|
||||||
|
uniform->i[0] = u_minify(tex->texture->width0, tex->u.tex.first_level);
|
||||||
|
|
||||||
|
if (dim > 1)
|
||||||
|
uniform->i[1] = u_minify(tex->texture->height0,
|
||||||
|
tex->u.tex.first_level);
|
||||||
|
|
||||||
|
if (dim > 2)
|
||||||
|
uniform->i[2] = u_minify(tex->texture->depth0,
|
||||||
|
tex->u.tex.first_level);
|
||||||
|
|
||||||
|
if (is_array)
|
||||||
|
uniform->i[dim] = tex->texture->array_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panfrost_upload_ssbo_sysval(struct panfrost_batch *batch,
|
||||||
|
enum pipe_shader_type st,
|
||||||
|
unsigned ssbo_id,
|
||||||
|
struct sysval_uniform *uniform)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
|
||||||
|
assert(ctx->ssbo_mask[st] & (1 << ssbo_id));
|
||||||
|
struct pipe_shader_buffer sb = ctx->ssbo[st][ssbo_id];
|
||||||
|
|
||||||
|
/* Compute address */
|
||||||
|
struct panfrost_bo *bo = pan_resource(sb.buffer)->bo;
|
||||||
|
|
||||||
|
panfrost_batch_add_bo(batch, bo,
|
||||||
|
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_RW |
|
||||||
|
panfrost_bo_access_for_stage(st));
|
||||||
|
|
||||||
|
/* Upload address and size as sysval */
|
||||||
|
uniform->du[0] = bo->gpu + sb.buffer_offset;
|
||||||
|
uniform->u[2] = sb.buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panfrost_upload_sampler_sysval(struct panfrost_batch *batch,
|
||||||
|
enum pipe_shader_type st,
|
||||||
|
unsigned samp_idx,
|
||||||
|
struct sysval_uniform *uniform)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
struct pipe_sampler_state *sampl = &ctx->samplers[st][samp_idx]->base;
|
||||||
|
|
||||||
|
uniform->f[0] = sampl->min_lod;
|
||||||
|
uniform->f[1] = sampl->max_lod;
|
||||||
|
uniform->f[2] = sampl->lod_bias;
|
||||||
|
|
||||||
|
/* Even without any errata, Midgard represents "no mipmapping" as
|
||||||
|
* fixing the LOD with the clamps; keep behaviour consistent. c.f.
|
||||||
|
* panfrost_create_sampler_state which also explains our choice of
|
||||||
|
* epsilon value (again to keep behaviour consistent) */
|
||||||
|
|
||||||
|
if (sampl->min_mip_filter == PIPE_TEX_MIPFILTER_NONE)
|
||||||
|
uniform->f[1] = uniform->f[0] + (1.0/256.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panfrost_upload_num_work_groups_sysval(struct panfrost_batch *batch,
|
||||||
|
struct sysval_uniform *uniform)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
|
||||||
|
uniform->u[0] = ctx->compute_grid->grid[0];
|
||||||
|
uniform->u[1] = ctx->compute_grid->grid[1];
|
||||||
|
uniform->u[2] = ctx->compute_grid->grid[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
panfrost_upload_sysvals(struct panfrost_batch *batch, void *buf,
|
||||||
|
struct panfrost_shader_state *ss,
|
||||||
|
enum pipe_shader_type st)
|
||||||
|
{
|
||||||
|
struct sysval_uniform *uniforms = (void *)buf;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < ss->sysval_count; ++i) {
|
||||||
|
int sysval = ss->sysval[i];
|
||||||
|
|
||||||
|
switch (PAN_SYSVAL_TYPE(sysval)) {
|
||||||
|
case PAN_SYSVAL_VIEWPORT_SCALE:
|
||||||
|
panfrost_upload_viewport_scale_sysval(batch,
|
||||||
|
&uniforms[i]);
|
||||||
|
break;
|
||||||
|
case PAN_SYSVAL_VIEWPORT_OFFSET:
|
||||||
|
panfrost_upload_viewport_offset_sysval(batch,
|
||||||
|
&uniforms[i]);
|
||||||
|
break;
|
||||||
|
case PAN_SYSVAL_TEXTURE_SIZE:
|
||||||
|
panfrost_upload_txs_sysval(batch, st,
|
||||||
|
PAN_SYSVAL_ID(sysval),
|
||||||
|
&uniforms[i]);
|
||||||
|
break;
|
||||||
|
case PAN_SYSVAL_SSBO:
|
||||||
|
panfrost_upload_ssbo_sysval(batch, st,
|
||||||
|
PAN_SYSVAL_ID(sysval),
|
||||||
|
&uniforms[i]);
|
||||||
|
break;
|
||||||
|
case PAN_SYSVAL_NUM_WORK_GROUPS:
|
||||||
|
panfrost_upload_num_work_groups_sysval(batch,
|
||||||
|
&uniforms[i]);
|
||||||
|
break;
|
||||||
|
case PAN_SYSVAL_SAMPLER:
|
||||||
|
panfrost_upload_sampler_sysval(batch, st,
|
||||||
|
PAN_SYSVAL_ID(sysval),
|
||||||
|
&uniforms[i]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const void *
|
||||||
|
panfrost_map_constant_buffer_cpu(struct panfrost_constant_buffer *buf,
|
||||||
|
unsigned index)
|
||||||
|
{
|
||||||
|
struct pipe_constant_buffer *cb = &buf->cb[index];
|
||||||
|
struct panfrost_resource *rsrc = pan_resource(cb->buffer);
|
||||||
|
|
||||||
|
if (rsrc)
|
||||||
|
return rsrc->bo->cpu;
|
||||||
|
else if (cb->user_buffer)
|
||||||
|
return cb->user_buffer;
|
||||||
|
else
|
||||||
|
unreachable("No constant buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
panfrost_emit_const_buf(struct panfrost_batch *batch,
|
||||||
|
enum pipe_shader_type stage,
|
||||||
|
struct midgard_payload_vertex_tiler *vtp)
|
||||||
|
{
|
||||||
|
struct panfrost_context *ctx = batch->ctx;
|
||||||
|
struct panfrost_shader_variants *all = ctx->shader[stage];
|
||||||
|
|
||||||
|
if (!all)
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct panfrost_constant_buffer *buf = &ctx->constant_buffer[stage];
|
||||||
|
|
||||||
|
struct panfrost_shader_state *ss = &all->variants[all->active_variant];
|
||||||
|
|
||||||
|
/* Uniforms are implicitly UBO #0 */
|
||||||
|
bool has_uniforms = buf->enabled_mask & (1 << 0);
|
||||||
|
|
||||||
|
/* Allocate room for the sysval and the uniforms */
|
||||||
|
size_t sys_size = sizeof(float) * 4 * ss->sysval_count;
|
||||||
|
size_t uniform_size = has_uniforms ? (buf->cb[0].buffer_size) : 0;
|
||||||
|
size_t size = sys_size + uniform_size;
|
||||||
|
struct panfrost_transfer transfer = panfrost_allocate_transient(batch,
|
||||||
|
size);
|
||||||
|
|
||||||
|
/* Upload sysvals requested by the shader */
|
||||||
|
panfrost_upload_sysvals(batch, transfer.cpu, ss, stage);
|
||||||
|
|
||||||
|
/* Upload uniforms */
|
||||||
|
if (has_uniforms && uniform_size) {
|
||||||
|
const void *cpu = panfrost_map_constant_buffer_cpu(buf, 0);
|
||||||
|
memcpy(transfer.cpu + sys_size, cpu, uniform_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mali_vertex_tiler_postfix *postfix = &vtp->postfix;
|
||||||
|
|
||||||
|
/* Next up, attach UBOs. UBO #0 is the uniforms we just
|
||||||
|
* uploaded */
|
||||||
|
|
||||||
|
unsigned ubo_count = panfrost_ubo_count(ctx, stage);
|
||||||
|
assert(ubo_count >= 1);
|
||||||
|
|
||||||
|
size_t sz = sizeof(uint64_t) * ubo_count;
|
||||||
|
uint64_t ubos[PAN_MAX_CONST_BUFFERS];
|
||||||
|
int uniform_count = ss->uniform_count;
|
||||||
|
|
||||||
|
/* Upload uniforms as a UBO */
|
||||||
|
ubos[0] = MALI_MAKE_UBO(2 + uniform_count, transfer.gpu);
|
||||||
|
|
||||||
|
/* The rest are honest-to-goodness UBOs */
|
||||||
|
|
||||||
|
for (unsigned ubo = 1; ubo < ubo_count; ++ubo) {
|
||||||
|
size_t usz = buf->cb[ubo].buffer_size;
|
||||||
|
bool enabled = buf->enabled_mask & (1 << ubo);
|
||||||
|
bool empty = usz == 0;
|
||||||
|
|
||||||
|
if (!enabled || empty) {
|
||||||
|
/* Stub out disabled UBOs to catch accesses */
|
||||||
|
ubos[ubo] = MALI_MAKE_UBO(0, 0xDEAD0000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mali_ptr gpu = panfrost_map_constant_buffer_gpu(batch, stage,
|
||||||
|
buf, ubo);
|
||||||
|
|
||||||
|
unsigned bytes_per_field = 16;
|
||||||
|
unsigned aligned = ALIGN_POT(usz, bytes_per_field);
|
||||||
|
ubos[ubo] = MALI_MAKE_UBO(aligned / bytes_per_field, gpu);
|
||||||
|
}
|
||||||
|
|
||||||
|
mali_ptr ubufs = panfrost_upload_transient(batch, ubos, sz);
|
||||||
|
postfix->uniforms = transfer.gpu;
|
||||||
|
postfix->uniform_buffers = ubufs;
|
||||||
|
|
||||||
|
buf->dirty_mask = 0;
|
||||||
|
}
|
||||||
|
@@ -25,6 +25,8 @@
|
|||||||
#ifndef __PAN_CMDSTREAM_H__
|
#ifndef __PAN_CMDSTREAM_H__
|
||||||
#define __PAN_CMDSTREAM_H__
|
#define __PAN_CMDSTREAM_H__
|
||||||
|
|
||||||
|
#include "pipe/p_defines.h"
|
||||||
|
|
||||||
#include "panfrost-job.h"
|
#include "panfrost-job.h"
|
||||||
|
|
||||||
#include "pan_job.h"
|
#include "pan_job.h"
|
||||||
@@ -33,4 +35,9 @@ void
|
|||||||
panfrost_emit_viewport(struct panfrost_batch *batch,
|
panfrost_emit_viewport(struct panfrost_batch *batch,
|
||||||
struct midgard_payload_vertex_tiler *tp);
|
struct midgard_payload_vertex_tiler *tp);
|
||||||
|
|
||||||
|
void
|
||||||
|
panfrost_emit_const_buf(struct panfrost_batch *batch,
|
||||||
|
enum pipe_shader_type stage,
|
||||||
|
struct midgard_payload_vertex_tiler *vtp);
|
||||||
|
|
||||||
#endif /* __PAN_CMDSTREAM_H__ */
|
#endif /* __PAN_CMDSTREAM_H__ */
|
||||||
|
@@ -518,196 +518,12 @@ panfrost_upload_texture_descriptors(struct panfrost_context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sysval_uniform {
|
|
||||||
union {
|
|
||||||
float f[4];
|
|
||||||
int32_t i[4];
|
|
||||||
uint32_t u[4];
|
|
||||||
uint64_t du[2];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
static void panfrost_upload_viewport_scale_sysval(struct panfrost_context *ctx,
|
|
||||||
struct sysval_uniform *uniform)
|
|
||||||
{
|
|
||||||
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
|
|
||||||
|
|
||||||
uniform->f[0] = vp->scale[0];
|
|
||||||
uniform->f[1] = vp->scale[1];
|
|
||||||
uniform->f[2] = vp->scale[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void panfrost_upload_viewport_offset_sysval(struct panfrost_context *ctx,
|
|
||||||
struct sysval_uniform *uniform)
|
|
||||||
{
|
|
||||||
const struct pipe_viewport_state *vp = &ctx->pipe_viewport;
|
|
||||||
|
|
||||||
uniform->f[0] = vp->translate[0];
|
|
||||||
uniform->f[1] = vp->translate[1];
|
|
||||||
uniform->f[2] = vp->translate[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void panfrost_upload_txs_sysval(struct panfrost_context *ctx,
|
|
||||||
enum pipe_shader_type st,
|
|
||||||
unsigned int sysvalid,
|
|
||||||
struct sysval_uniform *uniform)
|
|
||||||
{
|
|
||||||
unsigned texidx = PAN_SYSVAL_ID_TO_TXS_TEX_IDX(sysvalid);
|
|
||||||
unsigned dim = PAN_SYSVAL_ID_TO_TXS_DIM(sysvalid);
|
|
||||||
bool is_array = PAN_SYSVAL_ID_TO_TXS_IS_ARRAY(sysvalid);
|
|
||||||
struct pipe_sampler_view *tex = &ctx->sampler_views[st][texidx]->base;
|
|
||||||
|
|
||||||
assert(dim);
|
|
||||||
uniform->i[0] = u_minify(tex->texture->width0, tex->u.tex.first_level);
|
|
||||||
|
|
||||||
if (dim > 1)
|
|
||||||
uniform->i[1] = u_minify(tex->texture->height0,
|
|
||||||
tex->u.tex.first_level);
|
|
||||||
|
|
||||||
if (dim > 2)
|
|
||||||
uniform->i[2] = u_minify(tex->texture->depth0,
|
|
||||||
tex->u.tex.first_level);
|
|
||||||
|
|
||||||
if (is_array)
|
|
||||||
uniform->i[dim] = tex->texture->array_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void panfrost_upload_ssbo_sysval(
|
|
||||||
struct panfrost_context *ctx,
|
|
||||||
enum pipe_shader_type st,
|
|
||||||
unsigned ssbo_id,
|
|
||||||
struct sysval_uniform *uniform)
|
|
||||||
{
|
|
||||||
assert(ctx->ssbo_mask[st] & (1 << ssbo_id));
|
|
||||||
struct pipe_shader_buffer sb = ctx->ssbo[st][ssbo_id];
|
|
||||||
|
|
||||||
/* Compute address */
|
|
||||||
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
|
|
||||||
struct panfrost_bo *bo = pan_resource(sb.buffer)->bo;
|
|
||||||
|
|
||||||
panfrost_batch_add_bo(batch, bo,
|
|
||||||
PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_RW |
|
|
||||||
panfrost_bo_access_for_stage(st));
|
|
||||||
|
|
||||||
/* Upload address and size as sysval */
|
|
||||||
uniform->du[0] = bo->gpu + sb.buffer_offset;
|
|
||||||
uniform->u[2] = sb.buffer_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
panfrost_upload_sampler_sysval(
|
|
||||||
struct panfrost_context *ctx,
|
|
||||||
enum pipe_shader_type st,
|
|
||||||
unsigned sampler_index,
|
|
||||||
struct sysval_uniform *uniform)
|
|
||||||
{
|
|
||||||
struct pipe_sampler_state *sampl =
|
|
||||||
&ctx->samplers[st][sampler_index]->base;
|
|
||||||
|
|
||||||
uniform->f[0] = sampl->min_lod;
|
|
||||||
uniform->f[1] = sampl->max_lod;
|
|
||||||
uniform->f[2] = sampl->lod_bias;
|
|
||||||
|
|
||||||
/* Even without any errata, Midgard represents "no mipmapping" as
|
|
||||||
* fixing the LOD with the clamps; keep behaviour consistent. c.f.
|
|
||||||
* panfrost_create_sampler_state which also explains our choice of
|
|
||||||
* epsilon value (again to keep behaviour consistent) */
|
|
||||||
|
|
||||||
if (sampl->min_mip_filter == PIPE_TEX_MIPFILTER_NONE)
|
|
||||||
uniform->f[1] = uniform->f[0] + (1.0/256.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void panfrost_upload_num_work_groups_sysval(struct panfrost_context *ctx,
|
|
||||||
struct sysval_uniform *uniform)
|
|
||||||
{
|
|
||||||
uniform->u[0] = ctx->compute_grid->grid[0];
|
|
||||||
uniform->u[1] = ctx->compute_grid->grid[1];
|
|
||||||
uniform->u[2] = ctx->compute_grid->grid[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void panfrost_upload_sysvals(struct panfrost_context *ctx, void *buf,
|
|
||||||
struct panfrost_shader_state *ss,
|
|
||||||
enum pipe_shader_type st)
|
|
||||||
{
|
|
||||||
struct sysval_uniform *uniforms = (void *)buf;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < ss->sysval_count; ++i) {
|
|
||||||
int sysval = ss->sysval[i];
|
|
||||||
|
|
||||||
switch (PAN_SYSVAL_TYPE(sysval)) {
|
|
||||||
case PAN_SYSVAL_VIEWPORT_SCALE:
|
|
||||||
panfrost_upload_viewport_scale_sysval(ctx, &uniforms[i]);
|
|
||||||
break;
|
|
||||||
case PAN_SYSVAL_VIEWPORT_OFFSET:
|
|
||||||
panfrost_upload_viewport_offset_sysval(ctx, &uniforms[i]);
|
|
||||||
break;
|
|
||||||
case PAN_SYSVAL_TEXTURE_SIZE:
|
|
||||||
panfrost_upload_txs_sysval(ctx, st, PAN_SYSVAL_ID(sysval),
|
|
||||||
&uniforms[i]);
|
|
||||||
break;
|
|
||||||
case PAN_SYSVAL_SSBO:
|
|
||||||
panfrost_upload_ssbo_sysval(ctx, st, PAN_SYSVAL_ID(sysval),
|
|
||||||
&uniforms[i]);
|
|
||||||
break;
|
|
||||||
case PAN_SYSVAL_NUM_WORK_GROUPS:
|
|
||||||
panfrost_upload_num_work_groups_sysval(ctx, &uniforms[i]);
|
|
||||||
break;
|
|
||||||
case PAN_SYSVAL_SAMPLER:
|
|
||||||
panfrost_upload_sampler_sysval(ctx, st, PAN_SYSVAL_ID(sysval),
|
|
||||||
&uniforms[i]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const void *
|
|
||||||
panfrost_map_constant_buffer_cpu(struct panfrost_constant_buffer *buf, unsigned index)
|
|
||||||
{
|
|
||||||
struct pipe_constant_buffer *cb = &buf->cb[index];
|
|
||||||
struct panfrost_resource *rsrc = pan_resource(cb->buffer);
|
|
||||||
|
|
||||||
if (rsrc)
|
|
||||||
return rsrc->bo->cpu;
|
|
||||||
else if (cb->user_buffer)
|
|
||||||
return cb->user_buffer;
|
|
||||||
else
|
|
||||||
unreachable("No constant buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
static mali_ptr
|
|
||||||
panfrost_map_constant_buffer_gpu(
|
|
||||||
struct panfrost_context *ctx,
|
|
||||||
enum pipe_shader_type st,
|
|
||||||
struct panfrost_constant_buffer *buf,
|
|
||||||
unsigned index)
|
|
||||||
{
|
|
||||||
struct pipe_constant_buffer *cb = &buf->cb[index];
|
|
||||||
struct panfrost_resource *rsrc = pan_resource(cb->buffer);
|
|
||||||
struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
|
|
||||||
|
|
||||||
if (rsrc) {
|
|
||||||
panfrost_batch_add_bo(batch, rsrc->bo,
|
|
||||||
PAN_BO_ACCESS_SHARED |
|
|
||||||
PAN_BO_ACCESS_READ |
|
|
||||||
panfrost_bo_access_for_stage(st));
|
|
||||||
|
|
||||||
/* Alignment gauranteed by PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT */
|
|
||||||
return rsrc->bo->gpu + cb->buffer_offset;
|
|
||||||
} else if (cb->user_buffer) {
|
|
||||||
return panfrost_upload_transient(batch, cb->user_buffer + cb->buffer_offset, cb->buffer_size);
|
|
||||||
} else {
|
|
||||||
unreachable("No constant buffer");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute number of UBOs active (more specifically, compute the highest UBO
|
/* Compute number of UBOs active (more specifically, compute the highest UBO
|
||||||
* number addressable -- if there are gaps, include them in the count anyway).
|
* number addressable -- if there are gaps, include them in the count anyway).
|
||||||
* We always include UBO #0 in the count, since we *need* uniforms enabled for
|
* We always include UBO #0 in the count, since we *need* uniforms enabled for
|
||||||
* sysvals. */
|
* sysvals. */
|
||||||
|
|
||||||
static unsigned
|
unsigned
|
||||||
panfrost_ubo_count(struct panfrost_context *ctx, enum pipe_shader_type stage)
|
panfrost_ubo_count(struct panfrost_context *ctx, enum pipe_shader_type stage)
|
||||||
{
|
{
|
||||||
unsigned mask = ctx->constant_buffer[stage].enabled_mask | 1;
|
unsigned mask = ctx->constant_buffer[stage].enabled_mask | 1;
|
||||||
@@ -953,79 +769,8 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
|
|||||||
panfrost_upload_sampler_descriptors(ctx);
|
panfrost_upload_sampler_descriptors(ctx);
|
||||||
panfrost_upload_texture_descriptors(ctx);
|
panfrost_upload_texture_descriptors(ctx);
|
||||||
|
|
||||||
for (int i = 0; i < PIPE_SHADER_TYPES; ++i) {
|
for (int i = 0; i < PIPE_SHADER_TYPES; ++i)
|
||||||
struct panfrost_shader_variants *all = ctx->shader[i];
|
panfrost_emit_const_buf(batch, i, &ctx->payloads[i]);
|
||||||
|
|
||||||
if (!all)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
struct panfrost_constant_buffer *buf = &ctx->constant_buffer[i];
|
|
||||||
|
|
||||||
struct panfrost_shader_state *ss = &all->variants[all->active_variant];
|
|
||||||
|
|
||||||
/* Uniforms are implicitly UBO #0 */
|
|
||||||
bool has_uniforms = buf->enabled_mask & (1 << 0);
|
|
||||||
|
|
||||||
/* Allocate room for the sysval and the uniforms */
|
|
||||||
size_t sys_size = sizeof(float) * 4 * ss->sysval_count;
|
|
||||||
size_t uniform_size = has_uniforms ? (buf->cb[0].buffer_size) : 0;
|
|
||||||
size_t size = sys_size + uniform_size;
|
|
||||||
struct panfrost_transfer transfer = panfrost_allocate_transient(batch, size);
|
|
||||||
|
|
||||||
/* Upload sysvals requested by the shader */
|
|
||||||
panfrost_upload_sysvals(ctx, transfer.cpu, ss, i);
|
|
||||||
|
|
||||||
/* Upload uniforms */
|
|
||||||
if (has_uniforms && uniform_size) {
|
|
||||||
const void *cpu = panfrost_map_constant_buffer_cpu(buf, 0);
|
|
||||||
memcpy(transfer.cpu + sys_size, cpu, uniform_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int uniform_count =
|
|
||||||
ctx->shader[i]->variants[ctx->shader[i]->active_variant].uniform_count;
|
|
||||||
|
|
||||||
struct mali_vertex_tiler_postfix *postfix =
|
|
||||||
&ctx->payloads[i].postfix;
|
|
||||||
|
|
||||||
/* Next up, attach UBOs. UBO #0 is the uniforms we just
|
|
||||||
* uploaded */
|
|
||||||
|
|
||||||
unsigned ubo_count = panfrost_ubo_count(ctx, i);
|
|
||||||
assert(ubo_count >= 1);
|
|
||||||
|
|
||||||
size_t sz = sizeof(uint64_t) * ubo_count;
|
|
||||||
uint64_t ubos[PAN_MAX_CONST_BUFFERS];
|
|
||||||
|
|
||||||
/* Upload uniforms as a UBO */
|
|
||||||
ubos[0] = MALI_MAKE_UBO(2 + uniform_count, transfer.gpu);
|
|
||||||
|
|
||||||
/* The rest are honest-to-goodness UBOs */
|
|
||||||
|
|
||||||
for (unsigned ubo = 1; ubo < ubo_count; ++ubo) {
|
|
||||||
size_t usz = buf->cb[ubo].buffer_size;
|
|
||||||
|
|
||||||
bool enabled = buf->enabled_mask & (1 << ubo);
|
|
||||||
bool empty = usz == 0;
|
|
||||||
|
|
||||||
if (!enabled || empty) {
|
|
||||||
/* Stub out disabled UBOs to catch accesses */
|
|
||||||
ubos[ubo] = MALI_MAKE_UBO(0, 0xDEAD0000);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
mali_ptr gpu = panfrost_map_constant_buffer_gpu(ctx, i, buf, ubo);
|
|
||||||
|
|
||||||
unsigned bytes_per_field = 16;
|
|
||||||
unsigned aligned = ALIGN_POT(usz, bytes_per_field);
|
|
||||||
ubos[ubo] = MALI_MAKE_UBO(aligned / bytes_per_field, gpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
mali_ptr ubufs = panfrost_upload_transient(batch, ubos, sz);
|
|
||||||
postfix->uniforms = transfer.gpu;
|
|
||||||
postfix->uniform_buffers = ubufs;
|
|
||||||
|
|
||||||
buf->dirty_mask = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Upload the viewport somewhere more appropriate */
|
/* TODO: Upload the viewport somewhere more appropriate */
|
||||||
|
|
||||||
|
@@ -330,6 +330,9 @@ panfrost_shader_compile(
|
|||||||
struct panfrost_shader_state *state,
|
struct panfrost_shader_state *state,
|
||||||
uint64_t *outputs_written);
|
uint64_t *outputs_written);
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
panfrost_ubo_count(struct panfrost_context *ctx, enum pipe_shader_type stage);
|
||||||
|
|
||||||
/* Instancing */
|
/* Instancing */
|
||||||
|
|
||||||
mali_ptr
|
mali_ptr
|
||||||
|
Reference in New Issue
Block a user