Path: blob/21.2-virgl/src/gallium/drivers/vc4/vc4_cl.h
4570 views
/*1* Copyright © 2014 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 VC4_CL_H24#define VC4_CL_H2526#include <stdint.h>2728#include "util/u_math.h"29#include "util/macros.h"3031struct vc4_bo;32struct vc4_job;33struct vc4_cl;3435/**36* Undefined structure, used for typechecking that you're passing the pointers37* to these functions correctly.38*/39struct vc4_cl_out;4041/** A reference to a BO used in the CL packing functions */42struct vc4_cl_reloc {43struct vc4_bo *bo;44uint32_t offset;45};4647static inline void cl_pack_emit_reloc(struct vc4_cl *cl, const struct vc4_cl_reloc *);4849#define __gen_user_data struct vc4_cl50#define __gen_address_type struct vc4_cl_reloc51#define __gen_address_offset(reloc) ((reloc)->offset)52#define __gen_emit_reloc cl_pack_emit_reloc5354#include "kernel/vc4_packet.h"55#include "broadcom/cle/v3d_packet_v21_pack.h"5657struct vc4_cl {58void *base;59struct vc4_job *job;60struct vc4_cl_out *next;61struct vc4_cl_out *reloc_next;62uint32_t size;63#ifndef NDEBUG64uint32_t reloc_count;65#endif66};6768void vc4_init_cl(struct vc4_job *job, struct vc4_cl *cl);69void vc4_reset_cl(struct vc4_cl *cl);70uint32_t vc4_gem_hindex(struct vc4_job *job, struct vc4_bo *bo);7172struct PACKED unaligned_16 { uint16_t x; };73struct PACKED unaligned_32 { uint32_t x; };7475static inline uint32_t cl_offset(struct vc4_cl *cl)76{77return (char *)cl->next - (char *)cl->base;78}7980static inline void81cl_advance(struct vc4_cl_out **cl, uint32_t n)82{83(*cl) = (struct vc4_cl_out *)((char *)(*cl) + n);84}8586static inline struct vc4_cl_out *87cl_start(struct vc4_cl *cl)88{89return cl->next;90}9192static inline void93cl_end(struct vc4_cl *cl, struct vc4_cl_out *next)94{95cl->next = next;96assert(cl_offset(cl) <= cl->size);97}9899100static inline void101put_unaligned_32(struct vc4_cl_out *ptr, uint32_t val)102{103struct unaligned_32 *p = (void *)ptr;104p->x = val;105}106107static inline void108put_unaligned_16(struct vc4_cl_out *ptr, uint16_t val)109{110struct unaligned_16 *p = (void *)ptr;111p->x = val;112}113114static inline void115cl_u8(struct vc4_cl_out **cl, uint8_t n)116{117*(uint8_t *)(*cl) = n;118cl_advance(cl, 1);119}120121static inline void122cl_u16(struct vc4_cl_out **cl, uint16_t n)123{124put_unaligned_16(*cl, n);125cl_advance(cl, 2);126}127128static inline void129cl_u32(struct vc4_cl_out **cl, uint32_t n)130{131put_unaligned_32(*cl, n);132cl_advance(cl, 4);133}134135static inline void136cl_aligned_u32(struct vc4_cl_out **cl, uint32_t n)137{138*(uint32_t *)(*cl) = n;139cl_advance(cl, 4);140}141142static inline void143cl_ptr(struct vc4_cl_out **cl, void *ptr)144{145*(struct vc4_cl_out **)(*cl) = ptr;146cl_advance(cl, sizeof(void *));147}148149static inline void150cl_f(struct vc4_cl_out **cl, float f)151{152cl_u32(cl, fui(f));153}154155static inline void156cl_aligned_f(struct vc4_cl_out **cl, float f)157{158cl_aligned_u32(cl, fui(f));159}160161static inline struct vc4_cl_out *162cl_start_shader_reloc(struct vc4_cl *cl, uint32_t n)163{164assert(cl->reloc_count == 0);165#ifndef NDEBUG166cl->reloc_count = n;167#endif168cl->reloc_next = cl->next;169170/* Reserve the space where hindex will be written. */171cl_advance(&cl->next, n * 4);172173return cl->next;174}175176static inline void177cl_reloc(struct vc4_job *job, struct vc4_cl *cl, struct vc4_cl_out **cl_out,178struct vc4_bo *bo, uint32_t offset)179{180*(uint32_t *)cl->reloc_next = vc4_gem_hindex(job, bo);181cl_advance(&cl->reloc_next, 4);182183#ifndef NDEBUG184cl->reloc_count--;185#endif186187cl_u32(cl_out, offset);188}189190static inline void191cl_aligned_reloc(struct vc4_job *job, struct vc4_cl *cl,192struct vc4_cl_out **cl_out,193struct vc4_bo *bo, uint32_t offset)194{195*(uint32_t *)cl->reloc_next = vc4_gem_hindex(job, bo);196cl_advance(&cl->reloc_next, 4);197198#ifndef NDEBUG199cl->reloc_count--;200#endif201202cl_aligned_u32(cl_out, offset);203}204205/**206* Reference to a BO with its associated offset, used in the pack process.207*/208static inline struct vc4_cl_reloc209cl_address(struct vc4_bo *bo, uint32_t offset)210{211struct vc4_cl_reloc reloc = {212.bo = bo,213.offset = offset,214};215return reloc;216}217218void cl_ensure_space(struct vc4_cl *cl, uint32_t size);219220#define cl_packet_header(packet) V3D21_ ## packet ## _header221#define cl_packet_length(packet) V3D21_ ## packet ## _length222#define cl_packet_pack(packet) V3D21_ ## packet ## _pack223#define cl_packet_struct(packet) V3D21_ ## packet224225static inline void *226cl_get_emit_space(struct vc4_cl_out **cl, size_t size)227{228void *addr = *cl;229cl_advance(cl, size);230return addr;231}232233/* Macro for setting up an emit of a CL struct. A temporary unpacked struct234* is created, which you get to set fields in of the form:235*236* cl_emit(bcl, FLAT_SHADE_FLAGS, flags) {237* .flags.flat_shade_flags = 1 << 2,238* }239*240* or default values only can be emitted with just:241*242* cl_emit(bcl, FLAT_SHADE_FLAGS, flags);243*244* The trick here is that we make a for loop that will execute the body245* (either the block or the ';' after the macro invocation) exactly once.246* Also, *dst is actually of the wrong type, it's the247* uint8_t[cl_packet_length()] in the CL, not a cl_packet_struct(packet).248*/249#define cl_emit(cl, packet, name) \250for (struct cl_packet_struct(packet) name = { \251cl_packet_header(packet) \252}, \253*_loop_terminate = &name; \254__builtin_expect(_loop_terminate != NULL, 1); \255({ \256struct vc4_cl_out *cl_out = cl_start(cl); \257cl_packet_pack(packet)(cl, (uint8_t *)cl_out, &name); \258VG(VALGRIND_CHECK_MEM_IS_DEFINED(cl_out, \259cl_packet_length(packet))); \260cl_advance(&cl_out, cl_packet_length(packet)); \261cl_end(cl, cl_out); \262_loop_terminate = NULL; \263})) \264265#define cl_emit_prepacked(cl, packet) do { \266memcpy((cl)->next, packet, sizeof(*packet)); \267cl_advance(&(cl)->next, sizeof(*packet)); \268} while (0)269270/**271* Helper function called by the XML-generated pack functions for filling in272* an address field in shader records.273*274* Relocations for shader recs and texturing involve the packet (or uniforms275* stream) being preceded by the handles to the BOs, and the offset within the276* BO being in the stream (the output of this function).277*/278static inline void279cl_pack_emit_reloc(struct vc4_cl *cl, const struct vc4_cl_reloc *reloc)280{281*(uint32_t *)cl->reloc_next = vc4_gem_hindex(cl->job, reloc->bo);282cl_advance(&cl->reloc_next, 4);283284#ifndef NDEBUG285cl->reloc_count--;286#endif287}288289#endif /* VC4_CL_H */290291292