Commit 1fdd85ab authored by Patrick Lerda's avatar Patrick Lerda Committed by repojohnray

WIP: lima: lima_draw: overcome the current maximum vertices limitation

The hardware can't handle more than 65535 vertices per operation. This
update configures the hardware accordingly.

Some code refactoring is still required.
Signed-off-by: default avatarPatrick Lerda <patrick9876@free.fr>
parent 6f8d66be
Pipeline #56945 passed with stages
in 16 minutes and 55 seconds
......@@ -45,10 +45,39 @@
int lima_ctx_num_plb = LIMA_CTX_PLB_DEF_NUM;
void
lima_ctx_buff_state_alloc(struct lima_context *ctx, uint32_t n)
{
if (!n)
n = ctx->state_depth ? ctx->state_depth : 1;
if (!ctx->buffer_state) {
ctx->buffer_state = rzalloc_size(ctx, n * sizeof(struct lima_ctx_buff_state[lima_ctx_buff_num]));
ctx->state_depth = n;
} else if (n != ctx->state_depth) {
ctx->buffer_state = reralloc_size(ctx, ctx->buffer_state, n * sizeof(struct lima_ctx_buff_state[lima_ctx_buff_num]));
if (n > ctx->state_depth)
memset(&(*ctx->buffer_state)[ctx->state_depth], 0, (n - ctx->state_depth) * sizeof(struct lima_ctx_buff_state[lima_ctx_buff_num]));
ctx->state_depth = n;
}
}
static void
lima_ctx_buff_state_free(struct lima_context *ctx)
{
if (ctx->buffer_state) {
ralloc_free(ctx->buffer_state);
ctx->buffer_state = NULL;
ctx->state_depth = 0;
}
}
uint32_t
lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff, unsigned submit)
lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff, unsigned submit, int k)
{
struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
struct lima_ctx_buff_state *cbs = (*ctx->buffer_state)[k] + buff;
struct lima_resource *res = lima_resource(cbs->res);
if (submit & LIMA_CTX_BUFF_SUBMIT_GP)
......@@ -60,9 +89,9 @@ lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff, unsigned sub
}
void *
lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff)
lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff, int k)
{
struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
struct lima_ctx_buff_state *cbs = (*ctx->buffer_state)[k] + buff;
struct lima_resource *res = lima_resource(cbs->res);
return lima_bo_map(res->bo) + cbs->offset;
......@@ -70,9 +99,9 @@ lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff)
void *
lima_ctx_buff_alloc(struct lima_context *ctx, enum lima_ctx_buff buff,
unsigned size, bool uploader)
unsigned size, bool uploader, int k)
{
struct lima_ctx_buff_state *cbs = ctx->buffer_state + buff;
struct lima_ctx_buff_state *cbs = (*ctx->buffer_state)[k] + buff;
void *ret = NULL;
cbs->size = align(size, 0x40);
......@@ -128,8 +157,10 @@ lima_context_destroy(struct pipe_context *pctx)
if (ctx->gp_submit)
lima_submit_free(ctx->gp_submit);
for (int i = 0; i < lima_ctx_buff_num; i++)
pipe_resource_reference(&ctx->buffer_state[i].res, NULL);
if (ctx->buffer_state)
for (unsigned k = 0; k < ctx->state_depth; k++)
for (int i = 0; i < lima_ctx_buff_num; i++)
pipe_resource_reference(&(*ctx->buffer_state)[k][i].res, NULL);
lima_state_fini(ctx);
......@@ -159,6 +190,8 @@ lima_context_destroy(struct pipe_context *pctx)
lima_context_free_drm_ctx(screen, ctx->id);
lima_ctx_buff_state_free(ctx);
ralloc_free(ctx);
}
......
......@@ -31,6 +31,14 @@
#include "pipe/p_context.h"
#include "pipe/p_state.h"
#define LIMA_VERTICES_OUTPUTMAX 65535
static inline unsigned
lima_vertices_loop(const unsigned n)
{
return ((int)n - 1) / LIMA_VERTICES_OUTPUTMAX + 1;
}
struct lima_context_framebuffer {
struct pipe_framebuffer_state base;
int tiled_w, tiled_h;
......@@ -233,7 +241,8 @@ struct lima_context {
struct hash_table *plb_pp_stream;
uint32_t plb_index;
struct lima_ctx_buff_state buffer_state[lima_ctx_buff_num];
uint32_t state_depth;
struct lima_ctx_buff_state (*buffer_state)[][lima_ctx_buff_num];
struct util_dynarray vs_cmd_array;
struct util_dynarray plbu_cmd_array;
......@@ -275,11 +284,13 @@ lima_sampler_view(struct pipe_sampler_view *psview)
#define LIMA_CTX_BUFF_SUBMIT_GP (1 << 0)
#define LIMA_CTX_BUFF_SUBMIT_PP (1 << 1)
void lima_ctx_buff_state_alloc(struct lima_context *ctx, uint32_t n);
uint32_t lima_ctx_buff_va(struct lima_context *ctx, enum lima_ctx_buff buff,
unsigned submit);
void *lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff);
unsigned submit, int k);
void *lima_ctx_buff_map(struct lima_context *ctx, enum lima_ctx_buff buff, int k);
void *lima_ctx_buff_alloc(struct lima_context *ctx, enum lima_ctx_buff buff,
unsigned size, bool uploader);
unsigned size, bool uploader, int k);
void lima_state_init(struct lima_context *ctx);
void lima_state_fini(struct lima_context *ctx);
......
......@@ -808,39 +808,46 @@ lima_pipe_format_to_attrib_type(enum pipe_format format)
static void
lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
{
VS_CMD_BEGIN(24);
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : info->count;
const unsigned loop = lima_vertices_loop(num);
VS_CMD_BEGIN(24 * loop);
if (!info->index_size) {
VS_CMD_ARRAYS_SEMAPHORE_BEGIN_1();
VS_CMD_ARRAYS_SEMAPHORE_BEGIN_2();
}
int uniform_size = ctx->vs->uniform_pending_offset + ctx->vs->constant_size + 32;
VS_CMD_UNIFORMS_ADDRESS(
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform, LIMA_CTX_BUFF_SUBMIT_GP),
align(uniform_size, 16));
for (unsigned k = 0; k < loop; k++) {
const unsigned count = MIN2(LIMA_VERTICES_OUTPUTMAX, num);
VS_CMD_SHADER_ADDRESS(ctx->vs->bo->va, ctx->vs->shader_size);
VS_CMD_SHADER_INFO(ctx->vs->prefetch, ctx->vs->shader_size);
int uniform_size = ctx->vs->uniform_pending_offset + ctx->vs->constant_size + 32;
VS_CMD_UNIFORMS_ADDRESS(
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform, LIMA_CTX_BUFF_SUBMIT_GP, 0),
align(uniform_size, 16));
int num_varryings = ctx->vs->num_varying;
int num_attributes = ctx->vertex_elements->num_elements;
VS_CMD_VARYING_ATTRIBUTE_COUNT(num_varryings, num_attributes);
VS_CMD_SHADER_ADDRESS(ctx->vs->bo->va, ctx->vs->shader_size);
VS_CMD_SHADER_INFO(ctx->vs->prefetch, ctx->vs->shader_size);
VS_CMD_UNKNOWN1();
int num_varryings = ctx->vs->num_varying;
int num_attributes = ctx->vertex_elements->num_elements;
VS_CMD_VARYING_ATTRIBUTE_COUNT(num_varryings, num_attributes);
VS_CMD_ATTRIBUTES_ADDRESS(
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_attribute_info, LIMA_CTX_BUFF_SUBMIT_GP),
num_attributes);
VS_CMD_UNKNOWN1();
VS_CMD_VARYINGS_ADDRESS(
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_varying_info, LIMA_CTX_BUFF_SUBMIT_GP),
num_varryings);
VS_CMD_ATTRIBUTES_ADDRESS(
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_attribute_info, LIMA_CTX_BUFF_SUBMIT_GP, k),
num_attributes);
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : info->count;
VS_CMD_DRAW(num, info->index_size);
VS_CMD_VARYINGS_ADDRESS(
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_varying_info, LIMA_CTX_BUFF_SUBMIT_GP, k),
num_varryings);
VS_CMD_UNKNOWN2();
VS_CMD_DRAW(count, info->index_size);
VS_CMD_UNKNOWN2();
num -= count;
}
VS_CMD_ARRAYS_SEMAPHORE_END(info->index_size);
......@@ -850,13 +857,17 @@ lima_pack_vs_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
static void
lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
{
const unsigned loop = lima_vertices_loop(info->count);
unsigned num = info->count;
unsigned offset = 0;
lima_pack_head_plbu_cmd(ctx);
/* If it's zero scissor, we skip adding all other commands */
if (lima_is_scissor_zero(ctx))
return;
PLBU_CMD_BEGIN(30);
PLBU_CMD_BEGIN(30 * loop);
PLBU_CMD_VIEWPORT_X(fui(ctx->viewport.x));
PLBU_CMD_VIEWPORT_W(fui(ctx->viewport.width));
......@@ -866,67 +877,76 @@ lima_pack_plbu_cmd(struct lima_context *ctx, const struct pipe_draw_info *info)
if (!info->index_size)
PLBU_CMD_ARRAYS_SEMAPHORE_BEGIN();
bool low_prim = info->mode < PIPE_PRIM_TRIANGLES;
int cf = ctx->rasterizer->base.cull_face;
int ccw = ctx->rasterizer->base.front_ccw;
uint32_t cull = 0;
if (cf != PIPE_FACE_NONE) {
if (cf & PIPE_FACE_FRONT)
cull |= ccw ? 0x00040000 : 0x00020000;
if (cf & PIPE_FACE_BACK)
cull |= ccw ? 0x00020000 : 0x00040000;
}
PLBU_CMD_PRIMITIVE_SETUP(low_prim, cull, info->index_size);
for (unsigned k = 0; k < loop; k++) {
const unsigned count = MIN2(LIMA_VERTICES_OUTPUTMAX, num);
bool low_prim = info->mode < PIPE_PRIM_TRIANGLES;
int cf = ctx->rasterizer->base.cull_face;
int ccw = ctx->rasterizer->base.front_ccw;
uint32_t cull = 0;
if (cf != PIPE_FACE_NONE) {
if (cf & PIPE_FACE_FRONT)
cull |= ccw ? 0x00040000 : 0x00020000;
if (cf & PIPE_FACE_BACK)
cull |= ccw ? 0x00020000 : 0x00040000;
}
PLBU_CMD_PRIMITIVE_SETUP(low_prim, cull, info->index_size);
uint32_t gl_position_va =
lima_ctx_buff_va(ctx, lima_ctx_buff_sh_gl_pos,
LIMA_CTX_BUFF_SUBMIT_GP | LIMA_CTX_BUFF_SUBMIT_PP, k);
PLBU_CMD_RSW_VERTEX_ARRAY(
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw, LIMA_CTX_BUFF_SUBMIT_PP, k),
gl_position_va);
/* TODO
* - we should set it only for the first draw that enabled the scissor and for
* latter draw only if scissor is dirty
*/
if (ctx->rasterizer->base.scissor) {
struct pipe_scissor_state *scissor = &ctx->scissor;
PLBU_CMD_SCISSORS(scissor->minx, scissor->maxx, scissor->miny, scissor->maxy);
}
uint32_t gl_position_va =
lima_ctx_buff_va(ctx, lima_ctx_buff_sh_gl_pos,
LIMA_CTX_BUFF_SUBMIT_GP | LIMA_CTX_BUFF_SUBMIT_PP);
PLBU_CMD_RSW_VERTEX_ARRAY(
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw, LIMA_CTX_BUFF_SUBMIT_PP),
gl_position_va);
if (!k) {
PLBU_CMD_UNKNOWN1();
/* TODO
* - we should set it only for the first draw that enabled the scissor and for
* latter draw only if scissor is dirty
*/
if (ctx->rasterizer->base.scissor) {
struct pipe_scissor_state *scissor = &ctx->scissor;
PLBU_CMD_SCISSORS(scissor->minx, scissor->maxx, scissor->miny, scissor->maxy);
}
PLBU_CMD_DEPTH_RANGE_NEAR(fui(ctx->viewport.near));
PLBU_CMD_DEPTH_RANGE_FAR(fui(ctx->viewport.far));
}
PLBU_CMD_UNKNOWN1();
if (low_prim) {
uint32_t v = info->mode == PIPE_PRIM_POINTS ?
fui(ctx->rasterizer->base.point_size) : fui(ctx->rasterizer->base.line_width);
PLBU_CMD_LOW_PRIM_SIZE(v);
}
PLBU_CMD_DEPTH_RANGE_NEAR(fui(ctx->viewport.near));
PLBU_CMD_DEPTH_RANGE_FAR(fui(ctx->viewport.far));
if (info->index_size) {
PLBU_CMD_INDEXED_DEST(gl_position_va);
if (low_prim) {
uint32_t v = info->mode == PIPE_PRIM_POINTS ?
fui(ctx->rasterizer->base.point_size) : fui(ctx->rasterizer->base.line_width);
PLBU_CMD_LOW_PRIM_SIZE(v);
}
struct pipe_resource *indexbuf = NULL;
unsigned index_offset = 0;
struct lima_resource *res;
if (info->has_user_indices) {
util_upload_index_buffer(&ctx->base, info, &indexbuf, &index_offset);
res = lima_resource(indexbuf);
}
else
res = lima_resource(info->index.resource);
if (info->index_size) {
PLBU_CMD_INDEXED_DEST(gl_position_va);
lima_submit_add_bo(ctx->gp_submit, res->bo, LIMA_SUBMIT_BO_READ);
PLBU_CMD_INDICES(res->bo->va + info->start * info->index_size + index_offset);
struct pipe_resource *indexbuf = NULL;
unsigned index_offset = 0;
struct lima_resource *res;
if (info->has_user_indices) {
util_upload_index_buffer(&ctx->base, info, &indexbuf, &index_offset);
res = lima_resource(indexbuf);
if (indexbuf)
pipe_resource_reference(&indexbuf, NULL);
}
else {
/* can this make the attribute info static? */
PLBU_CMD_DRAW_ARRAYS(info->mode, info->start + offset, count);
}
else
res = lima_resource(info->index.resource);
lima_submit_add_bo(ctx->gp_submit, res->bo, LIMA_SUBMIT_BO_READ);
PLBU_CMD_INDICES(res->bo->va + info->start * info->index_size + index_offset);
if (indexbuf)
pipe_resource_reference(&indexbuf, NULL);
}
else {
/* can this make the attribute info static? */
PLBU_CMD_DRAW_ARRAYS(info->mode, info->start, info->count);
num -= count;
offset += count;
}
PLBU_CMD_ARRAYS_SEMAPHORE_END();
......@@ -1067,142 +1087,146 @@ lima_calculate_depth_test(struct pipe_depth_state *depth, struct pipe_rasterizer
static void
lima_pack_render_state(struct lima_context *ctx, const struct pipe_draw_info *info)
{
struct lima_render_state *render =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_plb_rsw,
sizeof(*render), true);
/* do hw support RGBA independ blend?
* PIPE_CAP_INDEP_BLEND_ENABLE
*
* how to handle the no cbuf only zbuf case?
*/
struct pipe_rt_blend_state *rt = ctx->blend->base.rt;
render->blend_color_bg = float_to_ubyte(ctx->blend_color.color[2]) |
(float_to_ubyte(ctx->blend_color.color[1]) << 16);
render->blend_color_ra = float_to_ubyte(ctx->blend_color.color[0]) |
(float_to_ubyte(ctx->blend_color.color[3]) << 16);
if (rt->blend_enable) {
render->alpha_blend = lima_calculate_alpha_blend(rt->rgb_func, rt->alpha_func,
rt->rgb_src_factor, rt->rgb_dst_factor,
rt->alpha_src_factor, rt->alpha_dst_factor);
}
else {
/*
* Special handling for blending disabled.
* Binary driver is generating the same alpha_value,
* as when we would just enable blending, without changing/setting any blend equation/params.
* Normaly in this case mesa would set all rt fields (func/factor) to zero.
const unsigned loop = lima_vertices_loop(info->count);
for (unsigned k = 0; k < loop; k++) {
struct lima_render_state *render =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_plb_rsw,
sizeof(*render), true, k);
/* do hw support RGBA independ blend?
* PIPE_CAP_INDEP_BLEND_ENABLE
*
* how to handle the no cbuf only zbuf case?
*/
render->alpha_blend = lima_calculate_alpha_blend(PIPE_BLEND_ADD, PIPE_BLEND_ADD,
PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO,
PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO);
}
struct pipe_rt_blend_state *rt = ctx->blend->base.rt;
render->blend_color_bg = float_to_ubyte(ctx->blend_color.color[2]) |
(float_to_ubyte(ctx->blend_color.color[1]) << 16);
render->blend_color_ra = float_to_ubyte(ctx->blend_color.color[0]) |
(float_to_ubyte(ctx->blend_color.color[3]) << 16);
if (rt->blend_enable) {
render->alpha_blend = lima_calculate_alpha_blend(rt->rgb_func, rt->alpha_func,
rt->rgb_src_factor, rt->rgb_dst_factor,
rt->alpha_src_factor, rt->alpha_dst_factor);
}
else {
/*
* Special handling for blending disabled.
* Binary driver is generating the same alpha_value,
* as when we would just enable blending, without changing/setting any blend equation/params.
* Normaly in this case mesa would set all rt fields (func/factor) to zero.
*/
render->alpha_blend = lima_calculate_alpha_blend(PIPE_BLEND_ADD, PIPE_BLEND_ADD,
PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO,
PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ZERO);
}
render->alpha_blend |= (rt->colormask & PIPE_MASK_RGBA) << 28;
render->alpha_blend |= (rt->colormask & PIPE_MASK_RGBA) << 28;
struct pipe_rasterizer_state *rst = &ctx->rasterizer->base;
struct pipe_depth_state *depth = &ctx->zsa->base.depth;
render->depth_test = lima_calculate_depth_test(depth, rst);
struct pipe_rasterizer_state *rst = &ctx->rasterizer->base;
struct pipe_depth_state *depth = &ctx->zsa->base.depth;
render->depth_test = lima_calculate_depth_test(depth, rst);
/* overlap with plbu? any place can remove one? */
render->depth_range = float_to_ushort(ctx->viewport.near) |
(float_to_ushort(ctx->viewport.far) << 16);
/* overlap with plbu? any place can remove one? */
render->depth_range = float_to_ushort(ctx->viewport.near) |
(float_to_ushort(ctx->viewport.far) << 16);
#if 0
struct pipe_stencil_state *stencil = ctx->zsa->base.stencil;
struct pipe_stencil_ref *ref = &ctx->stencil_ref;
render->stencil_front = stencil[0].func |
(lima_stencil_op(stencil[0].fail_op) << 3) |
(lima_stencil_op(stencil[0].zfail_op) << 6) |
(lima_stencil_op(stencil[0].zpass_op) << 9) |
(ref->ref_value[0] << 16) |
(stencil[0].valuemask << 24);
render->stencil_back = stencil[1].func |
(lima_stencil_op(stencil[1].fail_op) << 3) |
(lima_stencil_op(stencil[1].zfail_op) << 6) |
(lima_stencil_op(stencil[1].zpass_op) << 9) |
(ref->ref_value[1] << 16) |
(stencil[1].valuemask << 24);
struct pipe_stencil_state *stencil = ctx->zsa->base.stencil;
struct pipe_stencil_ref *ref = &ctx->stencil_ref;
render->stencil_front = stencil[0].func |
(lima_stencil_op(stencil[0].fail_op) << 3) |
(lima_stencil_op(stencil[0].zfail_op) << 6) |
(lima_stencil_op(stencil[0].zpass_op) << 9) |
(ref->ref_value[0] << 16) |
(stencil[0].valuemask << 24);
render->stencil_back = stencil[1].func |
(lima_stencil_op(stencil[1].fail_op) << 3) |
(lima_stencil_op(stencil[1].zfail_op) << 6) |
(lima_stencil_op(stencil[1].zpass_op) << 9) |
(ref->ref_value[1] << 16) |
(stencil[1].valuemask << 24);
#else
render->stencil_front = 0xff000007;
render->stencil_back = 0xff000007;
render->stencil_front = 0xff000007;
render->stencil_back = 0xff000007;
#endif
/* seems not correct? */
//struct pipe_alpha_state *alpha = &ctx->zsa->base.alpha;
render->stencil_test = 0;
//(stencil->enabled ? 0xFF : 0x00) | (float_to_ubyte(alpha->ref_value) << 16)
/* need more investigation */
if (info->mode == PIPE_PRIM_POINTS)
render->multi_sample = 0x0000F007;
else if (info->mode < PIPE_PRIM_TRIANGLES)
render->multi_sample = 0x0000F407;
else
render->multi_sample = 0x0000F807;
if (ctx->framebuffer.base.samples)
render->multi_sample |= 0x68;
/* seems not correct? */
//struct pipe_alpha_state *alpha = &ctx->zsa->base.alpha;
render->stencil_test = 0;
//(stencil->enabled ? 0xFF : 0x00) | (float_to_ubyte(alpha->ref_value) << 16)
render->shader_address =
ctx->fs->bo->va | (((uint32_t *)ctx->fs->bo->map)[0] & 0x1F);
/* need more investigation */
if (info->mode == PIPE_PRIM_POINTS)
render->multi_sample = 0x0000F007;
else if (info->mode < PIPE_PRIM_TRIANGLES)
render->multi_sample = 0x0000F407;
else
render->multi_sample = 0x0000F807;
if (ctx->framebuffer.base.samples)
render->multi_sample |= 0x68;
/* seems not needed */
render->uniforms_address = 0x00000000;
render->shader_address =
ctx->fs->bo->va | (((uint32_t *)ctx->fs->bo->map)[0] & 0x1F);
render->textures_address = 0x00000000;
/* seems not needed */
render->uniforms_address = 0x00000000;
/* more investigation */
render->aux0 = 0x00000300 | (ctx->vs->varying_stride >> 3);
render->aux1 = 0x00003000;
render->textures_address = 0x00000000;
if (ctx->tex_stateobj.num_samplers) {
render->textures_address =
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc, LIMA_CTX_BUFF_SUBMIT_PP);
render->aux0 |= ctx->tex_stateobj.num_samplers << 14;
render->aux0 |= 0x20;
}
/* more investigation */
render->aux0 = 0x00000300 | (ctx->vs->varying_stride >> 3);
render->aux1 = 0x00003000;
if (ctx->const_buffer[PIPE_SHADER_FRAGMENT].buffer) {
render->uniforms_address =
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_uniform_array, LIMA_CTX_BUFF_SUBMIT_PP);
render->uniforms_address |= ((ctx->buffer_state[lima_ctx_buff_pp_uniform].size) / 4 - 1);
render->aux0 |= 0x80;
render->aux1 |= 0x10000;
}
if (ctx->tex_stateobj.num_samplers) {
render->textures_address =
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_tex_desc, LIMA_CTX_BUFF_SUBMIT_PP, 0);
render->aux0 |= ctx->tex_stateobj.num_samplers << 14;
render->aux0 |= 0x20;
}
if (ctx->vs->num_varying > 1) {
render->varying_types = 0x00000000;
render->varyings_address =
lima_ctx_buff_va(ctx, lima_ctx_buff_sh_varying, LIMA_CTX_BUFF_SUBMIT_PP);
for (int i = 1; i < ctx->vs->num_varying; i++) {
int val;
if (ctx->const_buffer[PIPE_SHADER_FRAGMENT].buffer) {
render->uniforms_address =
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_uniform_array, LIMA_CTX_BUFF_SUBMIT_PP, 0);
render->uniforms_address |= (((*ctx->buffer_state)[0][lima_ctx_buff_pp_uniform].size) / 4 - 1);
render->aux0 |= 0x80;
render->aux1 |= 0x10000;
}
struct lima_varying_info *v = ctx->vs->varying + i;
if (v->component_size == 4)
val = v->components > 2 ? 0 : 1;
else
val = v->components > 2 ? 2 : 3;
int index = i - 1;
if (index < 10)
render->varying_types |= val << (3 * index);
else if (index == 10) {
render->varying_types |= val << 30;
render->varyings_address |= val >> 2;
if (ctx->vs->num_varying > 1) {
render->varying_types = 0x00000000;
render->varyings_address =
lima_ctx_buff_va(ctx, lima_ctx_buff_sh_varying, LIMA_CTX_BUFF_SUBMIT_PP, k);
for (int i = 1; i < ctx->vs->num_varying; i++) {
int val;
struct lima_varying_info *v = ctx->vs->varying + i;
if (v->component_size == 4)
val = v->components > 2 ? 0 : 1;
else
val = v->components > 2 ? 2 : 3;
int index = i - 1;
if (index < 10)
render->varying_types |= val << (3 * index);
else if (index == 10) {
render->varying_types |= val << 30;
render->varyings_address |= val >> 2;
}
else if (index == 11)
render->varyings_address |= val << 1;
}
else if (index == 11)
render->varyings_address |= val << 1;
}
}
else {
render->varying_types = 0x00000000;
render->varyings_address = 0x00000000;
}
else {
render->varying_types = 0x00000000;
render->varyings_address = 0x00000000;
}
lima_dump_command_stream_print(
render, sizeof(*render), false, "add render state at va %x\n",
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw, 0));
lima_dump_command_stream_print(
render, sizeof(*render), false, "add render(%d) state at va %x\n", k,
lima_ctx_buff_va(ctx, lima_ctx_buff_pp_plb_rsw, 0, k));
}
}
static void
......@@ -1210,34 +1234,40 @@ lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_i
{
struct lima_vertex_element_state *ve = ctx->vertex_elements;
struct lima_context_vertex_buffer *vb = &ctx->vertex_buffers;
unsigned num = info->index_size ? (ctx->max_index - ctx->min_index + 1) : info->count;
const unsigned loop = lima_vertices_loop(num);
uint32_t *attribute =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_attribute_info,
ve->num_elements * 8, true);
lima_ctx_buff_state_alloc(ctx, loop);
int n = 0;
for (int i = 0; i < ve->num_elements; i++) {
struct pipe_vertex_element *pve = ve->pipe + i;
for (unsigned k = 0; k < loop; k++) {
uint32_t *attribute =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_attribute_info,
ve->num_elements * 8, true, k);
assert(pve->vertex_buffer_index < vb->count);
assert(vb->enabled_mask & (1 << pve->vertex_buffer_index));
int n = 0;
for (int i = 0; i < ve->num_elements; i++) {
struct pipe_vertex_element *pve = ve->pipe + i;
struct pipe_vertex_buffer *pvb = vb->vb + pve->vertex_buffer_index;
struct lima_resource *res = lima_resource(pvb->buffer.resource);
assert(pve->vertex_buffer_index < vb->count);
assert(vb->enabled_mask & (1 << pve->vertex_buffer_index));
lima_submit_add_bo(ctx->gp_submit, res->bo, LIMA_SUBMIT_BO_READ);
struct pipe_vertex_buffer *pvb = vb->vb + pve->vertex_buffer_index;
struct lima_resource *res = lima_resource(pvb->buffer.resource);
unsigned start = info->index_size ? ctx->min_index : info->start;
attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
+ start * pvb->stride;
attribute[n++] = (pvb->stride << 11) |
(lima_pipe_format_to_attrib_type(pve->src_format) << 2) |
(util_format_get_nr_components(pve->src_format) - 1);
}
lima_submit_add_bo(ctx->gp_submit, res->bo, LIMA_SUBMIT_BO_READ);
lima_dump_command_stream_print(
attribute, n * 4, false, "update attribute info at va %x\n",
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_attribute_info, 0));
unsigned start = info->index_size ? ctx->min_index : info->start;
attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
+ (start + k * LIMA_VERTICES_OUTPUTMAX) * pvb->stride;
attribute[n++] = (pvb->stride << 11) |
(lima_pipe_format_to_attrib_type(pve->src_format) << 2) |
(util_format_get_nr_components(pve->src_format) - 1);
}
lima_dump_command_stream_print(
attribute, n * 4, false, "update attribute info(%d) at va %x\n", k,
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_attribute_info, 0, k));
}
}
static void
......@@ -1249,7 +1279,7 @@ lima_update_gp_uniform(struct lima_context *ctx)
int size = vs->uniform_pending_offset + vs->constant_size + 32;
void *vs_const_buff =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_uniform, size, true);
lima_ctx_buff_alloc(ctx, lima_ctx_buff_gp_uniform, size, true, 0);
if (ccb->buffer)
memcpy(vs_const_buff, ccb->buffer, ccb->size);
......@@ -1268,7 +1298,7 @@ lima_update_gp_uniform(struct lima_context *ctx)
lima_dump_command_stream_print(
vs_const_buff, size, true,
"update gp uniform at va %x\n",
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform, 0));
lima_ctx_buff_va(ctx, lima_ctx_buff_gp_uniform, 0, 0));
}
static void
......@@ -1282,75 +1312,82 @@ lima_update_pp_uniform(struct lima_context *ctx)
uint16_t *fp16_const_buff =
lima_ctx_buff_alloc(ctx, lima_ctx_buff_pp_uniform,
const_buff_size * sizeof(uint16_t), true);
const_buff_size * sizeof(uint16_t), true, 0);