Path: blob/21.2-virgl/src/gallium/drivers/v3d/v3d_cl.h
4570 views
/*1* Copyright © 2014-2017 Broadcom2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#ifndef V3D_CL_H24#define V3D_CL_H2526#include <stdint.h>2728#include "util/u_math.h"29#include "util/macros.h"30#include "broadcom/cle/v3d_packet_helpers.h"3132struct v3d_bo;33struct v3d_job;34struct v3d_cl;3536/**37* Undefined structure, used for typechecking that you're passing the pointers38* to these functions correctly.39*/40struct v3d_cl_out;4142/** A reference to a BO used in the CL packing functions */43struct v3d_cl_reloc {44struct v3d_bo *bo;45uint32_t offset;46};4748static inline void cl_pack_emit_reloc(struct v3d_cl *cl, const struct v3d_cl_reloc *);4950#define __gen_user_data struct v3d_cl51#define __gen_address_type struct v3d_cl_reloc52#define __gen_address_offset(reloc) (((reloc)->bo ? (reloc)->bo->offset : 0) + \53(reloc)->offset)54#define __gen_emit_reloc cl_pack_emit_reloc55#define __gen_unpack_address(cl, s, e) __unpack_address(cl, s, e)5657static inline struct v3d_cl_reloc58__unpack_address(const uint8_t *cl, uint32_t s, uint32_t e)59{60struct v3d_cl_reloc reloc =61{ NULL, __gen_unpack_uint(cl, s, e) << (31 - (e - s)) };62return reloc;63}6465struct v3d_cl {66void *base;67struct v3d_job *job;68struct v3d_cl_out *next;69struct v3d_bo *bo;70uint32_t size;71};7273void v3d_init_cl(struct v3d_job *job, struct v3d_cl *cl);74void v3d_destroy_cl(struct v3d_cl *cl);75void v3d_dump_cl(void *cl, uint32_t size, bool is_render);76uint32_t v3d_gem_hindex(struct v3d_job *job, struct v3d_bo *bo);7778struct PACKED unaligned_16 { uint16_t x; };79struct PACKED unaligned_32 { uint32_t x; };8081static inline uint32_t cl_offset(struct v3d_cl *cl)82{83return (char *)cl->next - (char *)cl->base;84}8586static inline struct v3d_cl_reloc cl_get_address(struct v3d_cl *cl)87{88return (struct v3d_cl_reloc){ .bo = cl->bo, .offset = cl_offset(cl) };89}9091static inline void92cl_advance(struct v3d_cl_out **cl, uint32_t n)93{94(*cl) = (struct v3d_cl_out *)((char *)(*cl) + n);95}9697static inline struct v3d_cl_out *98cl_start(struct v3d_cl *cl)99{100return cl->next;101}102103static inline void104cl_end(struct v3d_cl *cl, struct v3d_cl_out *next)105{106cl->next = next;107assert(cl_offset(cl) <= cl->size);108}109110111static inline void112put_unaligned_32(struct v3d_cl_out *ptr, uint32_t val)113{114struct unaligned_32 *p = (void *)ptr;115p->x = val;116}117118static inline void119put_unaligned_16(struct v3d_cl_out *ptr, uint16_t val)120{121struct unaligned_16 *p = (void *)ptr;122p->x = val;123}124125static inline void126cl_u8(struct v3d_cl_out **cl, uint8_t n)127{128*(uint8_t *)(*cl) = n;129cl_advance(cl, 1);130}131132static inline void133cl_u16(struct v3d_cl_out **cl, uint16_t n)134{135put_unaligned_16(*cl, n);136cl_advance(cl, 2);137}138139static inline void140cl_u32(struct v3d_cl_out **cl, uint32_t n)141{142put_unaligned_32(*cl, n);143cl_advance(cl, 4);144}145146static inline void147cl_aligned_u32(struct v3d_cl_out **cl, uint32_t n)148{149*(uint32_t *)(*cl) = n;150cl_advance(cl, 4);151}152153static inline void154cl_aligned_reloc(struct v3d_cl *cl,155struct v3d_cl_out **cl_out,156struct v3d_bo *bo, uint32_t offset)157{158cl_aligned_u32(cl_out, bo->offset + offset);159v3d_job_add_bo(cl->job, bo);160}161162static inline void163cl_ptr(struct v3d_cl_out **cl, void *ptr)164{165*(struct v3d_cl_out **)(*cl) = ptr;166cl_advance(cl, sizeof(void *));167}168169static inline void170cl_f(struct v3d_cl_out **cl, float f)171{172cl_u32(cl, fui(f));173}174175static inline void176cl_aligned_f(struct v3d_cl_out **cl, float f)177{178cl_aligned_u32(cl, fui(f));179}180181/**182* Reference to a BO with its associated offset, used in the pack process.183*/184static inline struct v3d_cl_reloc185cl_address(struct v3d_bo *bo, uint32_t offset)186{187struct v3d_cl_reloc reloc = {188.bo = bo,189.offset = offset,190};191return reloc;192}193194uint32_t v3d_cl_ensure_space(struct v3d_cl *cl, uint32_t size, uint32_t align);195void v3d_cl_ensure_space_with_branch(struct v3d_cl *cl, uint32_t size);196197#define cl_packet_header(packet) V3DX(packet ## _header)198#define cl_packet_length(packet) V3DX(packet ## _length)199#define cl_packet_pack(packet) V3DX(packet ## _pack)200#define cl_packet_struct(packet) V3DX(packet)201202static inline void *203cl_get_emit_space(struct v3d_cl_out **cl, size_t size)204{205void *addr = *cl;206cl_advance(cl, size);207return addr;208}209210/* Macro for setting up an emit of a CL struct. A temporary unpacked struct211* is created, which you get to set fields in of the form:212*213* cl_emit(bcl, FLAT_SHADE_FLAGS, flags) {214* .flags.flat_shade_flags = 1 << 2,215* }216*217* or default values only can be emitted with just:218*219* cl_emit(bcl, FLAT_SHADE_FLAGS, flags);220*221* The trick here is that we make a for loop that will execute the body222* (either the block or the ';' after the macro invocation) exactly once.223*/224#define cl_emit(cl, packet, name) \225for (struct cl_packet_struct(packet) name = { \226cl_packet_header(packet) \227}, \228*_loop_terminate = &name; \229__builtin_expect(_loop_terminate != NULL, 1); \230({ \231struct v3d_cl_out *cl_out = cl_start(cl); \232cl_packet_pack(packet)(cl, (uint8_t *)cl_out, &name); \233cl_advance(&cl_out, cl_packet_length(packet)); \234cl_end(cl, cl_out); \235_loop_terminate = NULL; \236})) \237238#define cl_emit_with_prepacked(cl, packet, prepacked, name) \239for (struct cl_packet_struct(packet) name = { \240cl_packet_header(packet) \241}, \242*_loop_terminate = &name; \243__builtin_expect(_loop_terminate != NULL, 1); \244({ \245struct v3d_cl_out *cl_out = cl_start(cl); \246uint8_t packed[cl_packet_length(packet)]; \247cl_packet_pack(packet)(cl, packed, &name); \248for (int _i = 0; _i < cl_packet_length(packet); _i++) \249((uint8_t *)cl_out)[_i] = packed[_i] | (prepacked)[_i]; \250cl_advance(&cl_out, cl_packet_length(packet)); \251cl_end(cl, cl_out); \252_loop_terminate = NULL; \253})) \254255#define cl_emit_prepacked_sized(cl, packet, size) do { \256memcpy((cl)->next, packet, size); \257cl_advance(&(cl)->next, size); \258} while (0)259260#define cl_emit_prepacked(cl, packet) \261cl_emit_prepacked_sized(cl, packet, sizeof(*(packet)))262263#define v3dx_pack(packed, packet, name) \264for (struct cl_packet_struct(packet) name = { \265cl_packet_header(packet) \266}, \267*_loop_terminate = &name; \268__builtin_expect(_loop_terminate != NULL, 1); \269({ \270cl_packet_pack(packet)(NULL, (uint8_t *)packed, &name); \271VG(VALGRIND_CHECK_MEM_IS_DEFINED((uint8_t *)packed, \272cl_packet_length(packet))); \273_loop_terminate = NULL; \274})) \275276/**277* Helper function called by the XML-generated pack functions for filling in278* an address field in shader records.279*280* Since we have a private address space as of V3D, our BOs can have lifelong281* offsets, and all the kernel needs to know is which BOs need to be paged in282* for this exec.283*/284static inline void285cl_pack_emit_reloc(struct v3d_cl *cl, const struct v3d_cl_reloc *reloc)286{287if (reloc->bo)288v3d_job_add_bo(cl->job, reloc->bo);289}290291#endif /* V3D_CL_H */292293294