diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2017-12-31 06:33:44 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2017-12-31 06:33:44 +0000 |
commit | b90fb74e3c85f2799d21d1e07bf91c5fb8359eb8 (patch) | |
tree | 385895e8835e6989d7730ee516b433eb41826885 /lib/mesa/src/gallium/drivers/nouveau | |
parent | d9c6ca3ea74f178cbd2d5f0fb0bc14843854fd0f (diff) |
Import Mesa 17.2.8
Diffstat (limited to 'lib/mesa/src/gallium/drivers/nouveau')
14 files changed, 364 insertions, 180 deletions
diff --git a/lib/mesa/src/gallium/drivers/nouveau/codegen/unordered_set.h b/lib/mesa/src/gallium/drivers/nouveau/codegen/unordered_set.h index 8ef6d462f..0e2945f66 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/codegen/unordered_set.h +++ b/lib/mesa/src/gallium/drivers/nouveau/codegen/unordered_set.h @@ -1,7 +1,7 @@ #ifndef __NV50_UNORDERED_SET_H__ #define __NV50_UNORDERED_SET_H__ -#if (__cplusplus >= 201103L) || defined(ANDROID) +#if (__cplusplus >= 201103L) #include <unordered_set> #else #include <tr1/unordered_set> @@ -11,36 +11,8 @@ namespace nv50_ir { #if __cplusplus >= 201103L using std::unordered_set; -#elif !defined(ANDROID) +#else using std::tr1::unordered_set; -#else // Android release before lollipop -using std::isfinite; -typedef std::tr1::unordered_set<void *> voidptr_unordered_set; - -template <typename V> -class unordered_set : public voidptr_unordered_set { - public: - typedef voidptr_unordered_set _base; - typedef _base::iterator _biterator; - typedef _base::const_iterator const_biterator; - - class iterator : public _biterator { - public: - iterator(const _biterator & i) : _biterator(i) {} - V operator*() const { return reinterpret_cast<V>(*_biterator(*this)); } - }; - class const_iterator : public const_biterator { - public: - const_iterator(const iterator & i) : const_biterator(i) {} - const_iterator(const const_biterator & i) : const_biterator(i) {} - const V operator*() const { return reinterpret_cast<const V>(*const_biterator(*this)); } - }; - - iterator begin() { return _base::begin(); } - iterator end() { return _base::end(); } - const_iterator begin() const { return _base::begin(); } - const_iterator end() const { return _base::end(); } -}; #endif } // namespace nv50_ir diff --git a/lib/mesa/src/gallium/drivers/nouveau/nouveau_compiler.c b/lib/mesa/src/gallium/drivers/nouveau/nouveau_compiler.c index d8009f5bf..3151a6f42 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nouveau_compiler.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nouveau_compiler.c @@ -109,7 +109,7 @@ nouveau_codegen(int chipset, int type, struct tgsi_token tokens[], info.type = type; info.target = chipset; - info.bin.sourceRep = NV50_PROGRAM_IR_TGSI; + info.bin.sourceRep = PIPE_SHADER_IR_TGSI; info.bin.source = tokens; info.io.auxCBSlot = 15; diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_context.h b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_context.h index 0ab2f95bc..1496b3760 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_context.h +++ b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_context.h @@ -110,7 +110,6 @@ struct nv30_context { struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned num_vtxbufs; - struct pipe_index_buffer idxbuf; uint32_t vbo_fifo; uint32_t vbo_user; unsigned vbo_min_index; diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_draw.c b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_draw.c index 10c9f56fa..4c587fca7 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_draw.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_draw.c @@ -419,25 +419,26 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } for (i = 0; i < nv30->num_vtxbufs; i++) { - const void *map = nv30->vtxbuf[i].user_buffer; + const void *map = nv30->vtxbuf[i].is_user_buffer ? + nv30->vtxbuf[i].buffer.user : NULL; if (!map) { - if (nv30->vtxbuf[i].buffer) - map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer, + if (nv30->vtxbuf[i].buffer.resource) + map = pipe_buffer_map(pipe, nv30->vtxbuf[i].buffer.resource, PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_READ, &transfer[i]); } draw_set_mapped_vertex_buffer(draw, i, map, ~0); } - if (info->indexed) { - const void *map = nv30->idxbuf.user_buffer; + if (info->index_size) { + const void *map = info->has_user_indices ? info->index.user : NULL; if (!map) - map = pipe_buffer_map(pipe, nv30->idxbuf.buffer, + map = pipe_buffer_map(pipe, info->index.resource, PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_READ, &transferi); draw_set_indexes(draw, - (ubyte *) map + nv30->idxbuf.offset, - nv30->idxbuf.index_size, ~0); + (ubyte *) map, + info->index_size, ~0); } else { draw_set_indexes(draw, NULL, 0, 0); } @@ -445,7 +446,7 @@ nv30_render_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) draw_vbo(draw, info); draw_flush(draw); - if (info->indexed && transferi) + if (info->index_size && transferi) pipe_buffer_unmap(pipe, transferi); for (i = 0; i < nv30->num_vtxbufs; i++) if (transfer[i]) diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_push.c b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_push.c index 67ab0508c..fc8520b89 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_push.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_push.c @@ -199,7 +199,7 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info) { struct push_context ctx; unsigned i, index_size; - bool apply_bias = info->indexed && info->index_bias; + bool apply_bias = info->index_size && info->index_bias; ctx.push = nv30->base.pushbuf; ctx.translate = nv30->vertex->translate; @@ -209,9 +209,9 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info) for (i = 0; i < nv30->num_vtxbufs; ++i) { uint8_t *data; struct pipe_vertex_buffer *vb = &nv30->vtxbuf[i]; - struct nv04_resource *res = nv04_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer.resource); - if (!vb->buffer && !vb->user_buffer) { + if (!vb->buffer.resource) { continue; } @@ -224,18 +224,18 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info) ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0); } - if (info->indexed) { - if (nv30->idxbuf.buffer) + if (info->index_size) { + if (!info->has_user_indices) ctx.idxbuf = nouveau_resource_map_offset(&nv30->base, - nv04_resource(nv30->idxbuf.buffer), nv30->idxbuf.offset, + nv04_resource(info->index.resource), info->start * info->index_size, NOUVEAU_BO_RD); else - ctx.idxbuf = nv30->idxbuf.user_buffer; + ctx.idxbuf = info->index.user; if (!ctx.idxbuf) { nv30_state_release(nv30); return; } - index_size = nv30->idxbuf.index_size; + index_size = info->index_size; ctx.primitive_restart = info->primitive_restart; ctx.restart_index = info->restart_index; } else { @@ -277,12 +277,12 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info) BEGIN_NV04(ctx.push, NV30_3D(VERTEX_BEGIN_END), 1); PUSH_DATA (ctx.push, NV30_3D_VERTEX_BEGIN_END_STOP); - if (info->indexed) - nouveau_resource_unmap(nv04_resource(nv30->idxbuf.buffer)); + if (info->index_size && !info->has_user_indices) + nouveau_resource_unmap(nv04_resource(info->index.resource)); for (i = 0; i < nv30->num_vtxbufs; ++i) { - if (nv30->vtxbuf[i].buffer) { - nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer)); + if (nv30->vtxbuf[i].buffer.resource) { + nouveau_resource_unmap(nv04_resource(nv30->vtxbuf[i].buffer.resource)); } } diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_resource.c b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_resource.c index 6238a2384..ff34f6e5f 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_resource.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_resource.c @@ -39,15 +39,11 @@ nv30_memory_barrier(struct pipe_context *pipe, unsigned flags) if (flags & PIPE_BARRIER_MAPPED_BUFFER) { for (i = 0; i < nv30->num_vtxbufs; ++i) { - if (!nv30->vtxbuf[i].buffer) + if (!nv30->vtxbuf[i].buffer.resource) continue; - if (nv30->vtxbuf[i].buffer->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) + if (nv30->vtxbuf[i].buffer.resource->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) nv30->base.vbo_dirty = true; } - - if (nv30->idxbuf.buffer && - nv30->idxbuf.buffer->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) - nv30->base.vbo_dirty = true; } } diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_vbo.c index bc9b9a16e..bb0a8a0b1 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_vbo.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nv30/nv30_vbo.c @@ -25,6 +25,7 @@ #include "util/u_format.h" #include "util/u_inlines.h" +#include "util/u_prim.h" #include "translate/translate.h" #include "nouveau_fence.h" @@ -39,7 +40,7 @@ nv30_emit_vtxattr(struct nv30_context *nv30, struct pipe_vertex_buffer *vb, { const unsigned nc = util_format_get_nr_components(ve->src_format); struct nouveau_pushbuf *push = nv30->base.pushbuf; - struct nv04_resource *res = nv04_resource(vb->buffer); + struct nv04_resource *res = nv04_resource(vb->buffer.resource); const struct util_format_description *desc = util_format_description(ve->src_format); const void *data; @@ -101,12 +102,12 @@ nv30_prevalidate_vbufs(struct nv30_context *nv30) for (i = 0; i < nv30->num_vtxbufs; i++) { vb = &nv30->vtxbuf[i]; - if (!vb->stride || !vb->buffer) /* NOTE: user_buffer not implemented */ + if (!vb->stride || !vb->buffer.resource) /* NOTE: user_buffer not implemented */ continue; - buf = nv04_resource(vb->buffer); + buf = nv04_resource(vb->buffer.resource); /* NOTE: user buffers with temporary storage count as mapped by GPU */ - if (!nouveau_resource_mapped_by_gpu(vb->buffer)) { + if (!nouveau_resource_mapped_by_gpu(vb->buffer.resource)) { if (nv30->vbo_push_hint) { nv30->vbo_fifo = ~0; continue; @@ -137,7 +138,7 @@ nv30_update_user_vbufs(struct nv30_context *nv30) struct pipe_vertex_element *ve = &nv30->vertex->pipe[i]; const int b = ve->vertex_buffer_index; struct pipe_vertex_buffer *vb = &nv30->vtxbuf[b]; - struct nv04_resource *buf = nv04_resource(vb->buffer); + struct nv04_resource *buf = nv04_resource(vb->buffer.resource); if (!(nv30->vbo_user & (1 << b))) continue; @@ -172,7 +173,7 @@ nv30_release_user_vbufs(struct nv30_context *nv30) int i = ffs(vbo_user) - 1; vbo_user &= ~(1 << i); - nouveau_buffer_release_gpu_storage(nv04_resource(nv30->vtxbuf[i].buffer)); + nouveau_buffer_release_gpu_storage(nv04_resource(nv30->vtxbuf[i].buffer.resource)); } nouveau_bufctx_reset(nv30->bufctx, BUFCTX_VTXTMP); @@ -234,7 +235,7 @@ nv30_vbo_validate(struct nv30_context *nv30) vb = &nv30->vtxbuf[ve->vertex_buffer_index]; user = (nv30->vbo_user & (1 << ve->vertex_buffer_index)); - res = nv04_resource(vb->buffer); + res = nv04_resource(vb->buffer.resource); if (nv30->vbo_fifo || unlikely(vb->stride == 0)) { if (!nv30->vbo_fifo) @@ -458,10 +459,11 @@ nv30_draw_elements_inline_u32_short(struct nouveau_pushbuf *push, static void nv30_draw_elements(struct nv30_context *nv30, bool shorten, + const struct pipe_draw_info *info, unsigned mode, unsigned start, unsigned count, - unsigned instance_count, int32_t index_bias) + unsigned instance_count, int32_t index_bias, + unsigned index_size) { - const unsigned index_size = nv30->idxbuf.index_size; struct nouveau_pushbuf *push = nv30->base.pushbuf; struct nouveau_object *eng3d = nv30->screen->eng3d; unsigned prim = nv30_prim_gl(mode); @@ -473,9 +475,9 @@ nv30_draw_elements(struct nv30_context *nv30, bool shorten, } if (eng3d->oclass == NV40_3D_CLASS && index_size > 1 && - nv30->idxbuf.buffer) { - struct nv04_resource *res = nv04_resource(nv30->idxbuf.buffer); - unsigned offset = nv30->idxbuf.offset; + !info->has_user_indices) { + struct nv04_resource *res = nv04_resource(info->index.resource); + unsigned offset = 0; assert(nouveau_resource_mapped_by_gpu(&res->base)); @@ -510,12 +512,12 @@ nv30_draw_elements(struct nv30_context *nv30, bool shorten, PUSH_RESET(push, BUFCTX_IDXBUF); } else { const void *data; - if (nv30->idxbuf.buffer) + if (!info->has_user_indices) data = nouveau_resource_map_offset(&nv30->base, - nv04_resource(nv30->idxbuf.buffer), - nv30->idxbuf.offset, NOUVEAU_BO_RD); + nv04_resource(info->index.resource), + start * index_size, NOUVEAU_BO_RD); else - data = nv30->idxbuf.user_buffer; + data = info->index.user; if (!data) return; @@ -550,11 +552,15 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) struct nouveau_pushbuf *push = nv30->base.pushbuf; int i; + if (!info->primitive_restart && + !u_trim_pipe_prim(info->mode, (unsigned*)&info->count)) + return; + /* For picking only a few vertices from a large user buffer, push is better, * if index count is larger and we expect repeated vertices, suggest upload. */ nv30->vbo_push_hint = /* the 64 is heuristic */ - !(info->indexed && + !(info->index_size && ((info->max_index - info->min_index + 64) < info->count)); nv30->vbo_min_index = info->min_index; @@ -578,14 +584,14 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) } for (i = 0; i < nv30->num_vtxbufs && !nv30->base.vbo_dirty; ++i) { - if (!nv30->vtxbuf[i].buffer) + if (!nv30->vtxbuf[i].buffer.resource) continue; - if (nv30->vtxbuf[i].buffer->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT) + if (nv30->vtxbuf[i].buffer.resource->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT) nv30->base.vbo_dirty = true; } - if (!nv30->base.vbo_dirty && nv30->idxbuf.buffer && - nv30->idxbuf.buffer->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT) + if (!nv30->base.vbo_dirty && info->index_size && !info->has_user_indices && + info->index.resource->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT) nv30->base.vbo_dirty = true; if (nv30->base.vbo_dirty) { @@ -594,7 +600,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) nv30->base.vbo_dirty = false; } - if (!info->indexed) { + if (!info->index_size) { nv30_draw_arrays(nv30, info->mode, info->start, info->count, info->instance_count); @@ -623,9 +629,9 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info) shorten = false; } - nv30_draw_elements(nv30, shorten, + nv30_draw_elements(nv30, shorten, info, info->mode, info->start, info->count, - info->instance_count, info->index_bias); + info->instance_count, info->index_bias, info->index_size); } nv30_state_release(nv30); diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_context.h b/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_context.h index cca44f5bb..224535a93 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_context.h +++ b/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_context.h @@ -143,7 +143,6 @@ struct nv50_context { struct pipe_vertex_buffer vtxbuf[PIPE_MAX_ATTRIBS]; unsigned num_vtxbufs; uint32_t vtxbufs_coherent; - struct pipe_index_buffer idxbuf; uint32_t vbo_fifo; /* bitmask of vertex elements to be pushed to FIFO */ uint32_t vbo_user; /* bitmask of vertex buffers pointing to user memory */ uint32_t vbo_constant; /* bitmask of user buffers with stride 0 */ diff --git a/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_push.c b/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_push.c index 6a53ad097..bec2d42e0 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_push.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nv50/nv50_push.c @@ -244,7 +244,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) unsigned i, index_size; unsigned inst_count = info->instance_count; unsigned vert_count = info->count; - bool apply_bias = info->indexed && info->index_bias; + bool apply_bias = info->index_size && info->index_bias; ctx.push = nv50->base.pushbuf; ctx.translate = nv50->vertex->translate; @@ -264,11 +264,11 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) const struct pipe_vertex_buffer *vb = &nv50->vtxbuf[i]; const uint8_t *data; - if (unlikely(vb->buffer)) + if (unlikely(!vb->is_user_buffer)) data = nouveau_resource_map_offset(&nv50->base, - nv04_resource(vb->buffer), vb->buffer_offset, NOUVEAU_BO_RD); + nv04_resource(vb->buffer.resource), vb->buffer_offset, NOUVEAU_BO_RD); else - data = vb->user_buffer; + data = vb->buffer.user; if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i)))) data += (ptrdiff_t)info->index_bias * vb->stride; @@ -276,17 +276,16 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info) ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0); } - if (info->indexed) { - if (nv50->idxbuf.buffer) { + if (info->index_size) { + if (!info->has_user_indices) { ctx.idxbuf = nouveau_resource_map_offset(&nv50->base, - nv04_resource(nv50->idxbuf.buffer), nv50->idxbuf.offset, - NOUVEAU_BO_RD); + nv04_resource(info->index.resource), 0, NOUVEAU_BO_RD); } else { - ctx.idxbuf = nv50->idxbuf.user_buffer; + ctx.idxbuf = info->index.user; } if (!ctx.idxbuf) return; - index_size = nv50->idxbuf.index_size; + index_size = info->index_size; ctx.primitive_restart = info->primitive_restart; ctx.restart_index = info->restart_index; } else { diff --git a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c index c644fe992..697bf491a 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_shader_state.c @@ -146,6 +146,11 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0) nvc0->state.early_z_forced = fp->fp.early_z; IMMED_NVC0(push, NVC0_3D(FORCE_EARLY_FRAGMENT_TESTS), fp->fp.early_z); } + if (fp->fp.post_depth_coverage != nvc0->state.post_depth_coverage) { + nvc0->state.post_depth_coverage = fp->fp.post_depth_coverage; + IMMED_NVC0(push, NVC0_3D(POST_DEPTH_COVERAGE), + fp->fp.post_depth_coverage); + } BEGIN_NVC0(push, NVC0_3D(SP_SELECT(5)), 2); PUSH_DATA (push, 0x51); @@ -220,18 +225,13 @@ nvc0_gmtyprog_validate(struct nvc0_context *nvc0) /* we allow GPs with no code for specifying stream output state only */ if (gp && nvc0_program_validate(nvc0, gp) && gp->code_size) { - const bool gp_selects_layer = !!(gp->hdr[13] & (1 << 9)); - BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1); PUSH_DATA (push, 0x41); BEGIN_NVC0(push, NVC0_3D(SP_START_ID(4)), 1); PUSH_DATA (push, gp->code_base); BEGIN_NVC0(push, NVC0_3D(SP_GPR_ALLOC(4)), 1); PUSH_DATA (push, gp->num_gprs); - BEGIN_NVC0(push, NVC0_3D(LAYER), 1); - PUSH_DATA (push, gp_selects_layer ? NVC0_3D_LAYER_USE_GP : 0); } else { - IMMED_NVC0(push, NVC0_3D(LAYER), 0); BEGIN_NVC0(push, NVC0_3D(MACRO_GP_SELECT), 1); PUSH_DATA (push, 0x40); } @@ -252,6 +252,27 @@ nvc0_compprog_validate(struct nvc0_context *nvc0) } void +nvc0_layer_validate(struct nvc0_context *nvc0) +{ + struct nouveau_pushbuf *push = nvc0->base.pushbuf; + struct nvc0_program *last; + bool prog_selects_layer = false; + + if (nvc0->gmtyprog) + last = nvc0->gmtyprog; + else if (nvc0->tevlprog) + last = nvc0->tevlprog; + else + last = nvc0->vertprog; + + if (last) + prog_selects_layer = !!(last->hdr[13] & (1 << 9)); + + BEGIN_NVC0(push, NVC0_3D(LAYER), 1); + PUSH_DATA (push, prog_selects_layer ? NVC0_3D_LAYER_USE_GP : 0); +} + +void nvc0_tfb_validate(struct nvc0_context *nvc0) { struct nouveau_pushbuf *push = nvc0->base.pushbuf; diff --git a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c index 14fb53cb8..225b89471 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_transfer.c @@ -112,13 +112,27 @@ nve4_m2mf_transfer_rect(struct nvc0_context *nvc0, const struct nv50_m2mf_rect *src, uint32_t nblocksx, uint32_t nblocksy) { + static const struct { + int cs; + int nc; + } cpbs[] = { + [ 1] = { 1, 1 }, + [ 2] = { 1, 2 }, + [ 3] = { 1, 3 }, + [ 4] = { 1, 4 }, + [ 6] = { 2, 3 }, + [ 8] = { 2, 4 }, + [ 9] = { 3, 3 }, + [12] = { 3, 4 }, + [16] = { 4, 4 }, + }; struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nouveau_bufctx *bctx = nvc0->bufctx; uint32_t exec; uint32_t src_base = src->base; uint32_t dst_base = dst->base; - const int cpp = dst->cpp; + assert(dst->cpp < ARRAY_SIZE(cpbs) && cpbs[dst->cpp].cs); assert(dst->cpp == src->cpp); nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR); @@ -126,35 +140,45 @@ nve4_m2mf_transfer_rect(struct nvc0_context *nvc0, nouveau_pushbuf_bufctx(push, bctx); nouveau_pushbuf_validate(push); - exec = 0x200 /* 2D_ENABLE */ | 0x6 /* UNK */; + exec = 0x400 /* REMAP_ENABLE */ | 0x200 /* 2D_ENABLE */ | 0x6 /* UNK */; + + BEGIN_NVC0(push, SUBC_COPY(0x0708), 1); + PUSH_DATA (push, (cpbs[dst->cpp].nc - 1) << 24 | + (cpbs[src->cpp].nc - 1) << 20 | + (cpbs[src->cpp].cs - 1) << 16 | + 3 << 12 /* DST_W = SRC_W */ | + 2 << 8 /* DST_Z = SRC_Z */ | + 1 << 4 /* DST_Y = SRC_Y */ | + 0 << 0 /* DST_X = SRC_X */); - if (!nouveau_bo_memtype(dst->bo)) { + if (nouveau_bo_memtype(dst->bo)) { + BEGIN_NVC0(push, SUBC_COPY(0x070c), 6); + PUSH_DATA (push, 0x1000 | dst->tile_mode); + PUSH_DATA (push, dst->width); + PUSH_DATA (push, dst->height); + PUSH_DATA (push, dst->depth); + PUSH_DATA (push, dst->z); + PUSH_DATA (push, (dst->y << 16) | dst->x); + } else { assert(!dst->z); - dst_base += dst->y * dst->pitch + dst->x * cpp; + dst_base += dst->y * dst->pitch + dst->x * dst->cpp; exec |= 0x100; /* DST_MODE_2D_LINEAR */ } - if (!nouveau_bo_memtype(src->bo)) { + + if (nouveau_bo_memtype(src->bo)) { + BEGIN_NVC0(push, SUBC_COPY(0x0728), 6); + PUSH_DATA (push, 0x1000 | src->tile_mode); + PUSH_DATA (push, src->width); + PUSH_DATA (push, src->height); + PUSH_DATA (push, src->depth); + PUSH_DATA (push, src->z); + PUSH_DATA (push, (src->y << 16) | src->x); + } else { assert(!src->z); - src_base += src->y * src->pitch + src->x * cpp; + src_base += src->y * src->pitch + src->x * src->cpp; exec |= 0x080; /* SRC_MODE_2D_LINEAR */ } - BEGIN_NVC0(push, SUBC_COPY(0x070c), 6); - PUSH_DATA (push, 0x1000 | dst->tile_mode); - PUSH_DATA (push, dst->pitch); - PUSH_DATA (push, dst->height); - PUSH_DATA (push, dst->depth); - PUSH_DATA (push, dst->z); - PUSH_DATA (push, (dst->y << 16) | (dst->x * cpp)); - - BEGIN_NVC0(push, SUBC_COPY(0x0728), 6); - PUSH_DATA (push, 0x1000 | src->tile_mode); - PUSH_DATA (push, src->pitch); - PUSH_DATA (push, src->height); - PUSH_DATA (push, src->depth); - PUSH_DATA (push, src->z); - PUSH_DATA (push, (src->y << 16) | (src->x * cpp)); - BEGIN_NVC0(push, SUBC_COPY(0x0400), 8); PUSH_DATAh(push, src->bo->offset + src_base); PUSH_DATA (push, src->bo->offset + src_base); @@ -162,7 +186,7 @@ nve4_m2mf_transfer_rect(struct nvc0_context *nvc0, PUSH_DATA (push, dst->bo->offset + dst_base); PUSH_DATA (push, src->pitch); PUSH_DATA (push, dst->pitch); - PUSH_DATA (push, nblocksx * cpp); + PUSH_DATA (push, nblocksx); PUSH_DATA (push, nblocksy); BEGIN_NVC0(push, SUBC_COPY(0x0300), 1); diff --git a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c index fd2bcbb96..256e20df2 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c @@ -69,11 +69,11 @@ nvc0_vertex_configure_translate(struct nvc0_context *nvc0, int32_t index_bias) const uint8_t *map; const struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[i]; - if (likely(!vb->buffer)) - map = (const uint8_t *)vb->user_buffer; + if (likely(vb->is_user_buffer)) + map = (const uint8_t *)vb->buffer.user; else map = nouveau_resource_map_offset(&nvc0->base, - nv04_resource(vb->buffer), vb->buffer_offset, NOUVEAU_BO_RD); + nv04_resource(vb->buffer.resource), vb->buffer_offset, NOUVEAU_BO_RD); if (index_bias && !unlikely(nvc0->vertex->instance_bufs & (1 << i))) map += (intptr_t)index_bias * vb->stride; @@ -83,14 +83,15 @@ nvc0_vertex_configure_translate(struct nvc0_context *nvc0, int32_t index_bias) } static inline void -nvc0_push_map_idxbuf(struct push_context *ctx, struct nvc0_context *nvc0) +nvc0_push_map_idxbuf(struct push_context *ctx, struct nvc0_context *nvc0, + const struct pipe_draw_info *info) { - if (nvc0->idxbuf.buffer) { - struct nv04_resource *buf = nv04_resource(nvc0->idxbuf.buffer); - ctx->idxbuf = nouveau_resource_map_offset(&nvc0->base, - buf, nvc0->idxbuf.offset, NOUVEAU_BO_RD); + if (!info->has_user_indices) { + struct nv04_resource *buf = nv04_resource(info->index.resource); + ctx->idxbuf = nouveau_resource_map_offset( + &nvc0->base, buf, 0, NOUVEAU_BO_RD); } else { - ctx->idxbuf = nvc0->idxbuf.user_buffer; + ctx->idxbuf = info->index.user; } } @@ -101,16 +102,16 @@ nvc0_push_map_edgeflag(struct push_context *ctx, struct nvc0_context *nvc0, unsigned attr = nvc0->vertprog->vp.edgeflag; struct pipe_vertex_element *ve = &nvc0->vertex->element[attr].pipe; struct pipe_vertex_buffer *vb = &nvc0->vtxbuf[ve->vertex_buffer_index]; - struct nv04_resource *buf = nv04_resource(vb->buffer); + struct nv04_resource *buf = nv04_resource(vb->buffer.resource); ctx->edgeflag.stride = vb->stride; ctx->edgeflag.width = util_format_get_blocksize(ve->src_format); - if (buf) { + if (!vb->is_user_buffer) { unsigned offset = vb->buffer_offset + ve->src_offset; ctx->edgeflag.data = nouveau_resource_map_offset(&nvc0->base, buf, offset, NOUVEAU_BO_RD); } else { - ctx->edgeflag.data = (const uint8_t *)vb->user_buffer + ve->src_offset; + ctx->edgeflag.data = (const uint8_t *)vb->buffer.user + ve->src_offset; } if (index_bias) @@ -499,16 +500,16 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) */ BEGIN_NVC0(ctx.push, NVC0_3D(PRIM_RESTART_ENABLE), 2); PUSH_DATA (ctx.push, 1); - PUSH_DATA (ctx.push, info->indexed ? 0xffffffff : info->restart_index); + PUSH_DATA (ctx.push, info->index_size ? 0xffffffff : info->restart_index); } else if (nvc0->state.prim_restart) { IMMED_NVC0(ctx.push, NVC0_3D(PRIM_RESTART_ENABLE), 0); } nvc0->state.prim_restart = info->primitive_restart; - if (info->indexed) { - nvc0_push_map_idxbuf(&ctx, nvc0); - index_size = nvc0->idxbuf.index_size; + if (info->index_size) { + nvc0_push_map_idxbuf(&ctx, nvc0, info); + index_size = info->index_size; } else { if (unlikely(info->count_from_stream_output)) { struct pipe_context *pipe = &nvc0->base.pipe; @@ -583,10 +584,10 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info) IMMED_NVC0(ctx.push, NVC0_3D(VERTEX_ARRAY_FETCH(1)), 0); } - if (info->indexed) - nouveau_resource_unmap(nv04_resource(nvc0->idxbuf.buffer)); + if (info->index_size && !info->has_user_indices) + nouveau_resource_unmap(nv04_resource(info->index.resource)); for (i = 0; i < nvc0->num_vtxbufs; ++i) - nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer)); + nouveau_resource_unmap(nv04_resource(nvc0->vtxbuf[i].buffer.resource)); NOUVEAU_DRV_STAT(&nvc0->screen->base, draw_calls_fallback_count, 1); } @@ -626,7 +627,7 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx, uint64_t va; uint32_t *data; uint32_t format; - unsigned index_size = nvc0->idxbuf.index_size; + unsigned index_size = info->index_size; unsigned i; unsigned a = nvc0->vertex->num_elements; @@ -639,11 +640,11 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx, bo); nouveau_pushbuf_validate(push); - if (info->indexed) { + if (info->index_size) { if (!info->index_bias) { memcpy(data, ctx->idxbuf, info->count * index_size); } else { - switch (nvc0->idxbuf.index_size) { + switch (info->index_size) { case 1: copy_indices_u8(data, ctx->idxbuf, info->index_bias, info->count); break; diff --git a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.c b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.c index 798761deb..bc5d9e044 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.c +++ b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.c @@ -29,6 +29,7 @@ #ifdef DEBUG static void nve4_compute_dump_launch_desc(const struct nve4_cp_launch_desc *); +static void gp100_compute_dump_launch_desc(const struct gp100_cp_launch_desc *); #endif @@ -57,6 +58,9 @@ nve4_screen_compute_setup(struct nvc0_screen *screen, case 0x120: obj_class = GM200_COMPUTE_CLASS; break; + case 0x130: + obj_class = dev->chipset == 0x130 ? GP100_COMPUTE_CLASS : GP104_COMPUTE_CLASS; + break; default: NOUVEAU_ERR("unsupported chipset: NV%02x\n", dev->chipset); return -1; @@ -585,7 +589,45 @@ nve4_compute_setup_launch_desc(struct nvc0_context *nvc0, NVC0_CB_AUX_INFO(5), 1 << 11); } -static inline struct nve4_cp_launch_desc * +static void +gp100_compute_setup_launch_desc(struct nvc0_context *nvc0, + struct gp100_cp_launch_desc *desc, + const struct pipe_grid_info *info) +{ + const struct nvc0_screen *screen = nvc0->screen; + const struct nvc0_program *cp = nvc0->compprog; + + gp100_cp_launch_desc_init_default(desc); + + desc->entry = nvc0_program_symbol_offset(cp, info->pc); + + desc->griddim_x = info->grid[0]; + desc->griddim_y = info->grid[1]; + desc->griddim_z = info->grid[2]; + desc->blockdim_x = info->block[0]; + desc->blockdim_y = info->block[1]; + desc->blockdim_z = info->block[2]; + + desc->shared_size = align(cp->cp.smem_size, 0x100); + desc->local_size_p = (cp->hdr[1] & 0xfffff0) + align(cp->cp.lmem_size, 0x10); + desc->local_size_n = 0; + desc->cstack_size = 0x800; + + desc->gpr_alloc = cp->num_gprs; + desc->bar_alloc = cp->num_barriers; + + // Only bind user uniforms and the driver constant buffer through the + // launch descriptor because UBOs are sticked to the driver cb to avoid the + // limitation of 8 CBs. + if (nvc0->constbuf[5][0].user || cp->parm_size) { + gp100_cp_launch_desc_set_cb(desc, 0, screen->uniform_bo, + NVC0_CB_USR_INFO(5), 1 << 16); + } + gp100_cp_launch_desc_set_cb(desc, 7, screen->uniform_bo, + NVC0_CB_AUX_INFO(5), 1 << 11); +} + +static inline void * nve4_compute_alloc_launch_desc(struct nouveau_context *nv, struct nouveau_bo **pbo, uint64_t *pgpuaddr) { @@ -597,7 +639,28 @@ nve4_compute_alloc_launch_desc(struct nouveau_context *nv, ptr += adj; *pgpuaddr += adj; } - return (struct nve4_cp_launch_desc *)ptr; + return ptr; +} + +static void +nve4_upload_indirect_desc(struct nouveau_pushbuf *push, + struct nv04_resource *res, uint64_t gpuaddr, + uint32_t length, uint32_t bo_offset) +{ + BEGIN_NVC0(push, NVE4_CP(UPLOAD_DST_ADDRESS_HIGH), 2); + PUSH_DATAh(push, gpuaddr); + PUSH_DATA (push, gpuaddr); + BEGIN_NVC0(push, NVE4_CP(UPLOAD_LINE_LENGTH_IN), 2); + PUSH_DATA (push, length); + PUSH_DATA (push, 1); + + nouveau_pushbuf_space(push, 32, 0, 1); + PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain); + + BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + (length / 4)); + PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x08 << 1)); + nouveau_pushbuf_data(push, res->bo, bo_offset, + NVC0_IB_ENTRY_1_NO_PREFETCH | length); } void @@ -605,7 +668,7 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info) { struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_pushbuf *push = nvc0->base.pushbuf; - struct nve4_cp_launch_desc *desc; + void *desc; uint64_t desc_gpuaddr; struct nouveau_bo *desc_bo; int ret; @@ -622,13 +685,20 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info) if (ret) goto out; - nve4_compute_setup_launch_desc(nvc0, desc, info); + if (nvc0->screen->compute->oclass >= GP100_COMPUTE_CLASS) + gp100_compute_setup_launch_desc(nvc0, desc, info); + else + nve4_compute_setup_launch_desc(nvc0, desc, info); nve4_compute_upload_input(nvc0, info); #ifdef DEBUG - if (debug_get_num_option("NV50_PROG_DEBUG", 0)) - nve4_compute_dump_launch_desc(desc); + if (debug_get_num_option("NV50_PROG_DEBUG", 0)) { + if (nvc0->screen->compute->oclass >= GP100_COMPUTE_CLASS) + gp100_compute_dump_launch_desc(desc); + else + nve4_compute_dump_launch_desc(desc); + } #endif if (unlikely(info->indirect)) { @@ -646,35 +716,17 @@ nve4_launch_grid(struct pipe_context *pipe, const struct pipe_grid_info *info) PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x08 << 1)); PUSH_DATAp(push, (const uint32_t *)desc, 256 / 4); - /* overwrite griddim_x and griddim_y as two 32-bits integers even - * if griddim_y must be a 16-bits integer */ - BEGIN_NVC0(push, NVE4_CP(UPLOAD_DST_ADDRESS_HIGH), 2); - PUSH_DATAh(push, desc_gpuaddr + 48); - PUSH_DATA (push, desc_gpuaddr + 48); - BEGIN_NVC0(push, NVE4_CP(UPLOAD_LINE_LENGTH_IN), 2); - PUSH_DATA (push, 8); - PUSH_DATA (push, 1); - - nouveau_pushbuf_space(push, 32, 0, 1); - PUSH_REFN(push, res->bo, NOUVEAU_BO_RD | res->domain); - - BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + (8 / 4)); - PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x08 << 1)); - nouveau_pushbuf_data(push, res->bo, offset, - NVC0_IB_ENTRY_1_NO_PREFETCH | 2 * 4); + if (nvc0->screen->compute->oclass >= GP100_COMPUTE_CLASS) { + nve4_upload_indirect_desc(push, res, desc_gpuaddr + 48, 12, offset); + } else { + /* overwrite griddim_x and griddim_y as two 32-bits integers even + * if griddim_y must be a 16-bits integer */ + nve4_upload_indirect_desc(push, res, desc_gpuaddr + 48, 8, offset); - /* overwrite the 16 high bits of griddim_y with griddim_z because - * we need (z << 16) | x */ - BEGIN_NVC0(push, NVE4_CP(UPLOAD_DST_ADDRESS_HIGH), 2); - PUSH_DATAh(push, desc_gpuaddr + 54); - PUSH_DATA (push, desc_gpuaddr + 54); - BEGIN_NVC0(push, NVE4_CP(UPLOAD_LINE_LENGTH_IN), 2); - PUSH_DATA (push, 4); - PUSH_DATA (push, 1); - BEGIN_1IC0(push, NVE4_CP(UPLOAD_EXEC), 1 + (4 / 4)); - PUSH_DATA (push, NVE4_COMPUTE_UPLOAD_EXEC_LINEAR | (0x08 << 1)); - nouveau_pushbuf_data(push, res->bo, offset + 8, - NVC0_IB_ENTRY_1_NO_PREFETCH | 1 * 4); + /* overwrite the 16 high bits of griddim_y with griddim_z because + * we need (z << 16) | x */ + nve4_upload_indirect_desc(push, res, desc_gpuaddr + 54, 4, offset + 8); + } } /* upload descriptor and flush */ @@ -831,6 +883,53 @@ nve4_compute_dump_launch_desc(const struct nve4_cp_launch_desc *desc) i, address, size, valid ? "" : " (invalid)"); } } + +static void +gp100_compute_dump_launch_desc(const struct gp100_cp_launch_desc *desc) +{ + const uint32_t *data = (const uint32_t *)desc; + unsigned i; + bool zero = false; + + debug_printf("COMPUTE LAUNCH DESCRIPTOR:\n"); + + for (i = 0; i < sizeof(*desc); i += 4) { + if (data[i / 4]) { + debug_printf("[%x]: 0x%08x\n", i, data[i / 4]); + zero = false; + } else + if (!zero) { + debug_printf("...\n"); + zero = true; + } + } + + debug_printf("entry = 0x%x\n", desc->entry); + debug_printf("grid dimensions = %ux%ux%u\n", + desc->griddim_x, desc->griddim_y, desc->griddim_z); + debug_printf("block dimensions = %ux%ux%u\n", + desc->blockdim_x, desc->blockdim_y, desc->blockdim_z); + debug_printf("s[] size: 0x%x\n", desc->shared_size); + debug_printf("l[] size: -0x%x / +0x%x\n", + desc->local_size_n, desc->local_size_p); + debug_printf("stack size: 0x%x\n", desc->cstack_size); + debug_printf("barrier count: %u\n", desc->bar_alloc); + debug_printf("$r count: %u\n", desc->gpr_alloc); + debug_printf("linked tsc: %d\n", desc->linked_tsc); + + for (i = 0; i < 8; ++i) { + uint64_t address; + uint32_t size = desc->cb[i].size_sh4 << 4; + bool valid = !!(desc->cb_mask & (1 << i)); + + address = ((uint64_t)desc->cb[i].address_h << 32) | desc->cb[i].address_l; + + if (!valid && !address && !size) + continue; + debug_printf("CB[%u]: address = 0x%"PRIx64", size 0x%x%s\n", + i, address, size, valid ? "" : " (invalid)"); + } +} #endif #ifdef NOUVEAU_NVE4_MP_TRAP_HANDLER diff --git a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.h b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.h index 5fe58b967..7ff6935cc 100644 --- a/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.h +++ b/lib/mesa/src/gallium/drivers/nouveau/nvc0/nve4_compute.h @@ -18,8 +18,8 @@ struct nve4_cp_launch_desc u16 griddim_z; u32 unk14[3]; u16 shared_size; /* must be aligned to 0x100 */ - u16 unk15; - u16 unk16; + u16 unk17; + u16 unk18; u16 blockdim_x; u16 blockdim_y; u16 blockdim_z; @@ -45,6 +45,46 @@ struct nve4_cp_launch_desc u32 unk48[16]; }; +struct gp100_cp_launch_desc +{ + u32 unk0[8]; + u32 entry; + u32 unk9[2]; + u32 unk11_0 : 30; + u32 linked_tsc : 1; + u32 unk11_31 : 1; + u32 griddim_x : 31; + u32 unk12 : 1; + u16 griddim_y; + u16 unk13; + u16 griddim_z; + u16 unk14; + u32 unk15[2]; + u32 shared_size : 18; + u32 unk17 : 14; + u16 unk18; + u16 blockdim_x; + u16 blockdim_y; + u16 blockdim_z; + u32 cb_mask : 8; + u32 unk20 : 24; + u32 unk21[8]; + u32 local_size_p : 24; + u32 unk29 : 3; + u32 bar_alloc : 5; + u32 local_size_n : 24; + u32 gpr_alloc : 8; + u32 cstack_size : 24; + u32 unk31 : 8; + struct { + u32 address_l; + u32 address_h : 17; + u32 reserved : 2; + u32 size_sh4 : 13; + } cb[8]; + u32 unk48[16]; +}; + static inline void nve4_cp_launch_desc_init_default(struct nve4_cp_launch_desc *desc) { @@ -73,6 +113,33 @@ nve4_cp_launch_desc_set_cb(struct nve4_cp_launch_desc *desc, desc->cb_mask |= 1 << index; } +static inline void +gp100_cp_launch_desc_init_default(struct gp100_cp_launch_desc *desc) +{ + memset(desc, 0, sizeof(*desc)); + + desc->unk0[4] = 0x40; + desc->unk11_0 = 0x04014000; +} + +static inline void +gp100_cp_launch_desc_set_cb(struct gp100_cp_launch_desc *desc, + unsigned index, + struct nouveau_bo *bo, + uint32_t base, uint32_t size) +{ + uint64_t address = bo->offset + base; + + assert(index < 8); + assert(!(base & 0xff)); + + desc->cb[index].address_l = address; + desc->cb[index].address_h = address >> 32; + desc->cb[index].size_sh4 = DIV_ROUND_UP(size, 16); + + desc->cb_mask |= 1 << index; +} + struct nve4_mp_trap_info { u32 lock; u32 pc; |