Path: blob/21.2-virgl/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h
4561 views
/*1* Copyright © 2011 Marek Olšák <[email protected]>2* Copyright © 2015 Advanced Micro Devices, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining6* a copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,14* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES15* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND16* NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS17* AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*22* The above copyright notice and this permission notice (including the23* next paragraph) shall be included in all copies or substantial portions24* of the Software.25*/2627#ifndef AMDGPU_CS_H28#define AMDGPU_CS_H2930#include "amdgpu_bo.h"31#include "util/u_memory.h"32#include "drm-uapi/amdgpu_drm.h"3334struct amdgpu_ctx {35struct amdgpu_winsys *ws;36amdgpu_context_handle ctx;37amdgpu_bo_handle user_fence_bo;38uint64_t *user_fence_cpu_address_base;39int refcount;40unsigned initial_num_total_rejected_cs;41unsigned num_rejected_cs;42};4344struct amdgpu_cs_buffer {45struct amdgpu_winsys_bo *bo;46union {47struct {48uint32_t priority_usage;49} real;50struct {51uint32_t real_idx; /* index of underlying real BO */52} slab;53} u;54enum radeon_bo_usage usage;55};5657enum ib_type {58IB_PREAMBLE,59IB_MAIN,60IB_PARALLEL_COMPUTE,61IB_NUM,62};6364struct amdgpu_ib {65struct radeon_cmdbuf *rcs; /* pointer to the driver-owned data */6667/* A buffer out of which new IBs are allocated. */68struct pb_buffer *big_ib_buffer;69uint8_t *ib_mapped;70unsigned used_ib_space;7172/* The maximum seen size from cs_check_space. If the driver does73* cs_check_space and flush, the newly allocated IB should have at least74* this size.75*/76unsigned max_check_space_size;7778unsigned max_ib_size;79uint32_t *ptr_ib_size;80bool ptr_ib_size_inside_ib;81enum ib_type ib_type;82};8384struct amdgpu_fence_list {85struct pipe_fence_handle **list;86unsigned num;87unsigned max;88};8990struct amdgpu_cs_context {91struct drm_amdgpu_cs_chunk_ib ib[IB_NUM];9293/* Buffers. */94unsigned max_real_buffers;95unsigned num_real_buffers;96struct amdgpu_cs_buffer *real_buffers;9798unsigned num_slab_buffers;99unsigned max_slab_buffers;100struct amdgpu_cs_buffer *slab_buffers;101102unsigned num_sparse_buffers;103unsigned max_sparse_buffers;104struct amdgpu_cs_buffer *sparse_buffers;105106int16_t *buffer_indices_hashlist;107108struct amdgpu_winsys_bo *last_added_bo;109unsigned last_added_bo_index;110unsigned last_added_bo_usage;111uint32_t last_added_bo_priority_usage;112113struct amdgpu_fence_list fence_dependencies;114struct amdgpu_fence_list syncobj_dependencies;115struct amdgpu_fence_list syncobj_to_signal;116117/* The compute IB uses the dependencies above + these: */118struct amdgpu_fence_list compute_fence_dependencies;119struct amdgpu_fence_list compute_start_fence_dependencies;120121struct pipe_fence_handle *fence;122123/* the error returned from cs_flush for non-async submissions */124int error_code;125126/* TMZ: will this command be submitted using the TMZ flag */127bool secure;128};129130#define BUFFER_HASHLIST_SIZE 4096131132struct amdgpu_cs {133struct amdgpu_ib main; /* must be first because this is inherited */134struct amdgpu_ib compute_ib; /* optional parallel compute IB */135struct amdgpu_winsys *ws;136struct amdgpu_ctx *ctx;137enum ring_type ring_type;138struct drm_amdgpu_cs_chunk_fence fence_chunk;139140/* We flip between these two CS. While one is being consumed141* by the kernel in another thread, the other one is being filled142* by the pipe driver. */143struct amdgpu_cs_context csc1;144struct amdgpu_cs_context csc2;145/* The currently-used CS. */146struct amdgpu_cs_context *csc;147/* The CS being currently-owned by the other thread. */148struct amdgpu_cs_context *cst;149/* buffer_indices_hashlist[hash(bo)] returns -1 if the bo150* isn't part of any buffer lists or the index where the bo could be found.151* Since 1) hash collisions of 2 different bo can happen and 2) we use a152* single hashlist for the 3 buffer list, this is only a hint.153* amdgpu_lookup_buffer uses this hint to speed up buffers look up.154*/155int16_t buffer_indices_hashlist[BUFFER_HASHLIST_SIZE];156157/* Flush CS. */158void (*flush_cs)(void *ctx, unsigned flags, struct pipe_fence_handle **fence);159void *flush_data;160bool stop_exec_on_failure;161bool noop;162bool has_chaining;163164struct util_queue_fence flush_completed;165struct pipe_fence_handle *next_fence;166struct pb_buffer *preamble_ib_bo;167};168169struct amdgpu_fence {170struct pipe_reference reference;171/* If ctx == NULL, this fence is syncobj-based. */172uint32_t syncobj;173174struct amdgpu_winsys *ws;175struct amdgpu_ctx *ctx; /* submission context */176struct amdgpu_cs_fence fence;177uint64_t *user_fence_cpu_address;178179/* If the fence has been submitted. This is unsignalled for deferred fences180* (cs->next_fence) and while an IB is still being submitted in the submit181* thread. */182struct util_queue_fence submitted;183184volatile int signalled; /* bool (int for atomicity) */185};186187static inline bool amdgpu_fence_is_syncobj(struct amdgpu_fence *fence)188{189return fence->ctx == NULL;190}191192static inline void amdgpu_ctx_unref(struct amdgpu_ctx *ctx)193{194if (p_atomic_dec_zero(&ctx->refcount)) {195amdgpu_cs_ctx_free(ctx->ctx);196amdgpu_bo_free(ctx->user_fence_bo);197FREE(ctx);198}199}200201static inline void amdgpu_fence_reference(struct pipe_fence_handle **dst,202struct pipe_fence_handle *src)203{204struct amdgpu_fence **adst = (struct amdgpu_fence **)dst;205struct amdgpu_fence *asrc = (struct amdgpu_fence *)src;206207if (pipe_reference(&(*adst)->reference, &asrc->reference)) {208struct amdgpu_fence *fence = *adst;209210if (amdgpu_fence_is_syncobj(fence))211amdgpu_cs_destroy_syncobj(fence->ws->dev, fence->syncobj);212else213amdgpu_ctx_unref(fence->ctx);214215util_queue_fence_destroy(&fence->submitted);216FREE(fence);217}218*adst = asrc;219}220221int amdgpu_lookup_buffer_any_type(struct amdgpu_cs_context *cs, struct amdgpu_winsys_bo *bo);222223static inline struct amdgpu_cs *224amdgpu_cs(struct radeon_cmdbuf *rcs)225{226struct amdgpu_cs *cs = (struct amdgpu_cs*)rcs->priv;227assert(!cs || cs->main.ib_type == IB_MAIN);228return cs;229}230231#define get_container(member_ptr, container_type, container_member) \232(container_type *)((char *)(member_ptr) - offsetof(container_type, container_member))233234static inline bool235amdgpu_bo_is_referenced_by_cs(struct amdgpu_cs *cs,236struct amdgpu_winsys_bo *bo)237{238return amdgpu_lookup_buffer_any_type(cs->csc, bo) != -1;239}240241static inline bool242amdgpu_bo_is_referenced_by_cs_with_usage(struct amdgpu_cs *cs,243struct amdgpu_winsys_bo *bo,244enum radeon_bo_usage usage)245{246int index;247struct amdgpu_cs_buffer *buffer;248249index = amdgpu_lookup_buffer_any_type(cs->csc, bo);250if (index == -1)251return false;252253buffer = bo->bo ? &cs->csc->real_buffers[index] :254bo->base.usage & RADEON_FLAG_SPARSE ? &cs->csc->sparse_buffers[index] :255&cs->csc->slab_buffers[index];256257return (buffer->usage & usage) != 0;258}259260bool amdgpu_fence_wait(struct pipe_fence_handle *fence, uint64_t timeout,261bool absolute);262void amdgpu_add_fences(struct amdgpu_winsys_bo *bo,263unsigned num_fences,264struct pipe_fence_handle **fences);265void amdgpu_cs_sync_flush(struct radeon_cmdbuf *rcs);266void amdgpu_cs_init_functions(struct amdgpu_screen_winsys *ws);267268#endif269270271