Path: blob/21.2-virgl/src/gallium/drivers/radeon/radeon_winsys.h
4570 views
/*1* Copyright 2008 Corbin Simpson <[email protected]>2* Copyright 2010 Marek Olšák <[email protected]>3* Copyright 2018 Advanced Micro Devices, Inc.4* All Rights Reserved.5*6* Permission is hereby granted, free of charge, to any person obtaining a7* copy of this software and associated documentation files (the "Software"),8* to deal in the Software without restriction, including without limitation9* on the rights to use, copy, modify, merge, publish, distribute, sub10* license, and/or sell copies of the Software, and to permit persons to whom11* the Software is furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice (including the next14* paragraph) shall be included in all copies or substantial portions of the15* Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL20* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,21* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR22* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE23* USE OR OTHER DEALINGS IN THE SOFTWARE. */2425#ifndef RADEON_WINSYS_H26#define RADEON_WINSYS_H2728/* The public winsys interface header for the radeon driver. */2930/* Skip command submission. Same as RADEON_NOOP=1. */31#define RADEON_FLUSH_NOOP (1u << 29)3233/* Toggle the secure submission boolean after the flush */34#define RADEON_FLUSH_TOGGLE_SECURE_SUBMISSION (1u << 30)3536/* Whether the next IB can start immediately and not wait for draws and37* dispatches from the current IB to finish. */38#define RADEON_FLUSH_START_NEXT_GFX_IB_NOW (1u << 31)3940#define RADEON_FLUSH_ASYNC_START_NEXT_GFX_IB_NOW \41(PIPE_FLUSH_ASYNC | RADEON_FLUSH_START_NEXT_GFX_IB_NOW)4243#include "amd/common/ac_gpu_info.h"44#include "amd/common/ac_surface.h"45#include "pipebuffer/pb_buffer.h"4647/* Tiling flags. */48enum radeon_bo_layout49{50RADEON_LAYOUT_LINEAR = 0,51RADEON_LAYOUT_TILED,52RADEON_LAYOUT_SQUARETILED,5354RADEON_LAYOUT_UNKNOWN55};5657enum radeon_bo_domain58{ /* bitfield */59RADEON_DOMAIN_GTT = 2,60RADEON_DOMAIN_VRAM = 4,61RADEON_DOMAIN_VRAM_GTT = RADEON_DOMAIN_VRAM | RADEON_DOMAIN_GTT,62RADEON_DOMAIN_GDS = 8,63RADEON_DOMAIN_OA = 16,64};6566enum radeon_bo_flag67{ /* bitfield */68RADEON_FLAG_GTT_WC = (1 << 0),69RADEON_FLAG_NO_CPU_ACCESS = (1 << 1),70RADEON_FLAG_NO_SUBALLOC = (1 << 2),71RADEON_FLAG_SPARSE = (1 << 3),72RADEON_FLAG_NO_INTERPROCESS_SHARING = (1 << 4),73RADEON_FLAG_READ_ONLY = (1 << 5),74RADEON_FLAG_32BIT = (1 << 6),75RADEON_FLAG_ENCRYPTED = (1 << 7),76RADEON_FLAG_UNCACHED = (1 << 8), /* only gfx9 and newer */77RADEON_FLAG_DRIVER_INTERNAL = (1 << 9),78};7980enum radeon_dependency_flag81{82/* Add the dependency to the parallel compute IB only. */83RADEON_DEPENDENCY_PARALLEL_COMPUTE_ONLY = 1 << 0,8485/* Instead of waiting for a job to finish execution, the dependency will86* be signaled when the job starts execution.87*/88RADEON_DEPENDENCY_START_FENCE = 1 << 1,89};9091enum radeon_bo_usage92{ /* bitfield */93RADEON_USAGE_READ = 2,94RADEON_USAGE_WRITE = 4,95RADEON_USAGE_READWRITE = RADEON_USAGE_READ | RADEON_USAGE_WRITE,9697/* The winsys ensures that the CS submission will be scheduled after98* previously flushed CSs referencing this BO in a conflicting way.99*/100RADEON_USAGE_SYNCHRONIZED = 8,101102/* When used, an implicit sync is done to make sure a compute shader103* will read the written values from a previous draw.104*/105RADEON_USAGE_NEEDS_IMPLICIT_SYNC = 16,106};107108enum radeon_map_flags109{110/* Indicates that the caller will unmap the buffer.111*112* Not unmapping buffers is an important performance optimization for113* OpenGL (avoids kernel overhead for frequently mapped buffers).114*/115RADEON_MAP_TEMPORARY = (PIPE_MAP_DRV_PRV << 0),116};117118#define RADEON_SPARSE_PAGE_SIZE (64 * 1024)119120enum radeon_value_id121{122RADEON_REQUESTED_VRAM_MEMORY,123RADEON_REQUESTED_GTT_MEMORY,124RADEON_MAPPED_VRAM,125RADEON_MAPPED_GTT,126RADEON_SLAB_WASTED_VRAM,127RADEON_SLAB_WASTED_GTT,128RADEON_BUFFER_WAIT_TIME_NS,129RADEON_NUM_MAPPED_BUFFERS,130RADEON_TIMESTAMP,131RADEON_NUM_GFX_IBS,132RADEON_NUM_SDMA_IBS,133RADEON_GFX_BO_LIST_COUNTER, /* number of BOs submitted in gfx IBs */134RADEON_GFX_IB_SIZE_COUNTER,135RADEON_NUM_BYTES_MOVED,136RADEON_NUM_EVICTIONS,137RADEON_NUM_VRAM_CPU_PAGE_FAULTS,138RADEON_VRAM_USAGE,139RADEON_VRAM_VIS_USAGE,140RADEON_GTT_USAGE,141RADEON_GPU_TEMPERATURE, /* DRM 2.42.0 */142RADEON_CURRENT_SCLK,143RADEON_CURRENT_MCLK,144RADEON_CS_THREAD_TIME,145};146147enum radeon_bo_priority148{149/* Each group of two has the same priority. */150RADEON_PRIO_FENCE = 0,151RADEON_PRIO_TRACE,152153RADEON_PRIO_SO_FILLED_SIZE = 2,154RADEON_PRIO_QUERY,155156RADEON_PRIO_IB1 = 4, /* main IB submitted to the kernel */157RADEON_PRIO_IB2, /* IB executed with INDIRECT_BUFFER */158159RADEON_PRIO_DRAW_INDIRECT = 6,160RADEON_PRIO_INDEX_BUFFER,161162RADEON_PRIO_CP_DMA = 8,163RADEON_PRIO_BORDER_COLORS,164165RADEON_PRIO_CONST_BUFFER = 10,166RADEON_PRIO_DESCRIPTORS,167168RADEON_PRIO_SAMPLER_BUFFER = 12,169RADEON_PRIO_VERTEX_BUFFER,170171RADEON_PRIO_SHADER_RW_BUFFER = 14,172RADEON_PRIO_COMPUTE_GLOBAL,173174RADEON_PRIO_SAMPLER_TEXTURE = 16,175RADEON_PRIO_SHADER_RW_IMAGE,176177RADEON_PRIO_SAMPLER_TEXTURE_MSAA = 18,178RADEON_PRIO_COLOR_BUFFER,179180RADEON_PRIO_DEPTH_BUFFER = 20,181182RADEON_PRIO_COLOR_BUFFER_MSAA = 22,183184RADEON_PRIO_DEPTH_BUFFER_MSAA = 24,185186RADEON_PRIO_SEPARATE_META = 26,187RADEON_PRIO_SHADER_BINARY, /* the hw can't hide instruction cache misses */188189RADEON_PRIO_SHADER_RINGS = 28,190191RADEON_PRIO_SCRATCH_BUFFER = 30,192/* 31 is the maximum value */193};194195struct winsys_handle;196struct radeon_winsys_ctx;197198struct radeon_cmdbuf_chunk {199unsigned cdw; /* Number of used dwords. */200unsigned max_dw; /* Maximum number of dwords. */201uint32_t *buf; /* The base pointer of the chunk. */202};203204struct radeon_cmdbuf {205struct radeon_cmdbuf_chunk current;206struct radeon_cmdbuf_chunk *prev;207uint16_t num_prev; /* Number of previous chunks. */208uint16_t max_prev; /* Space in array pointed to by prev. */209unsigned prev_dw; /* Total number of dwords in previous chunks. */210211/* Memory usage of the buffer list. These are always 0 for preamble IBs. */212uint32_t used_vram_kb;213uint32_t used_gart_kb;214uint64_t gpu_address;215216/* Private winsys data. */217void *priv;218};219220/* Tiling info for display code, DRI sharing, and other data. */221struct radeon_bo_metadata {222/* Tiling flags describing the texture layout for display code223* and DRI sharing.224*/225union {226struct {227enum radeon_bo_layout microtile;228enum radeon_bo_layout macrotile;229unsigned pipe_config;230unsigned bankw;231unsigned bankh;232unsigned tile_split;233unsigned mtilea;234unsigned num_banks;235unsigned stride;236bool scanout;237} legacy;238} u;239240enum radeon_surf_mode mode; /* Output from buffer_get_metadata */241242/* Additional metadata associated with the buffer, in bytes.243* The maximum size is 64 * 4. This is opaque for the winsys & kernel.244* Supported by amdgpu only.245*/246uint32_t size_metadata;247uint32_t metadata[64];248};249250enum radeon_feature_id251{252RADEON_FID_R300_HYPERZ_ACCESS, /* ZMask + HiZ */253RADEON_FID_R300_CMASK_ACCESS,254};255256struct radeon_bo_list_item {257uint64_t bo_size;258uint64_t vm_address;259uint32_t priority_usage; /* mask of (1 << RADEON_PRIO_*) */260};261262struct radeon_winsys {263/**264* The screen object this winsys was created for265*/266struct pipe_screen *screen;267/**268* Has the application created at least one TMZ buffer.269*/270const bool uses_secure_bos;271272/**273* Decrement the winsys reference count.274*275* \param ws The winsys this function is called for.276* \return True if the winsys and screen should be destroyed.277*/278bool (*unref)(struct radeon_winsys *ws);279280/**281* Destroy this winsys.282*283* \param ws The winsys this function is called from.284*/285void (*destroy)(struct radeon_winsys *ws);286287/**288* Query an info structure from winsys.289*290* \param ws The winsys this function is called from.291* \param info Return structure292*/293void (*query_info)(struct radeon_winsys *ws, struct radeon_info *info,294bool enable_smart_access_memory,295bool disable_smart_access_memory);296297/**298* A hint for the winsys that it should pin its execution threads to299* a group of cores sharing a specific L3 cache if the CPU has multiple300* L3 caches. This is needed for good multithreading performance on301* AMD Zen CPUs.302*/303void (*pin_threads_to_L3_cache)(struct radeon_winsys *ws, unsigned cache);304305/**************************************************************************306* Buffer management. Buffer attributes are mostly fixed over its lifetime.307*308* Remember that gallium gets to choose the interface it needs, and the309* window systems must then implement that interface (rather than the310* other way around...).311*************************************************************************/312313/**314* Create a buffer object.315*316* \param ws The winsys this function is called from.317* \param size The size to allocate.318* \param alignment An alignment of the buffer in memory.319* \param use_reusable_pool Whether the cache buffer manager should be used.320* \param domain A bitmask of the RADEON_DOMAIN_* flags.321* \return The created buffer object.322*/323struct pb_buffer *(*buffer_create)(struct radeon_winsys *ws, uint64_t size, unsigned alignment,324enum radeon_bo_domain domain, enum radeon_bo_flag flags);325326/**327* Map the entire data store of a buffer object into the client's address328* space.329*330* Callers are expected to unmap buffers again if and only if the331* RADEON_MAP_TEMPORARY flag is set in \p usage.332*333* \param buf A winsys buffer object to map.334* \param cs A command stream to flush if the buffer is referenced by it.335* \param usage A bitmask of the PIPE_MAP_* and RADEON_MAP_* flags.336* \return The pointer at the beginning of the buffer.337*/338void *(*buffer_map)(struct radeon_winsys *ws, struct pb_buffer *buf,339struct radeon_cmdbuf *cs, enum pipe_map_flags usage);340341/**342* Unmap a buffer object from the client's address space.343*344* \param buf A winsys buffer object to unmap.345*/346void (*buffer_unmap)(struct radeon_winsys *ws, struct pb_buffer *buf);347348/**349* Wait for the buffer and return true if the buffer is not used350* by the device.351*352* The timeout of 0 will only return the status.353* The timeout of PIPE_TIMEOUT_INFINITE will always wait until the buffer354* is idle.355*/356bool (*buffer_wait)(struct radeon_winsys *ws, struct pb_buffer *buf,357uint64_t timeout, enum radeon_bo_usage usage);358359/**360* Return buffer metadata.361* (tiling info for display code, DRI sharing, and other data)362*363* \param buf A winsys buffer object to get the flags from.364* \param md Metadata365*/366void (*buffer_get_metadata)(struct radeon_winsys *ws, struct pb_buffer *buf,367struct radeon_bo_metadata *md, struct radeon_surf *surf);368369/**370* Set buffer metadata.371* (tiling info for display code, DRI sharing, and other data)372*373* \param buf A winsys buffer object to set the flags for.374* \param md Metadata375*/376void (*buffer_set_metadata)(struct radeon_winsys *ws, struct pb_buffer *buf,377struct radeon_bo_metadata *md, struct radeon_surf *surf);378379/**380* Get a winsys buffer from a winsys handle. The internal structure381* of the handle is platform-specific and only a winsys should access it.382*383* \param ws The winsys this function is called from.384* \param whandle A winsys handle pointer as was received from a state385* tracker.386*/387struct pb_buffer *(*buffer_from_handle)(struct radeon_winsys *ws, struct winsys_handle *whandle,388unsigned vm_alignment);389390/**391* Get a winsys buffer from a user pointer. The resulting buffer can't392* be exported. Both pointer and size must be page aligned.393*394* \param ws The winsys this function is called from.395* \param pointer User pointer to turn into a buffer object.396* \param Size Size in bytes for the new buffer.397*/398struct pb_buffer *(*buffer_from_ptr)(struct radeon_winsys *ws, void *pointer, uint64_t size);399400/**401* Whether the buffer was created from a user pointer.402*403* \param buf A winsys buffer object404* \return whether \p buf was created via buffer_from_ptr405*/406bool (*buffer_is_user_ptr)(struct pb_buffer *buf);407408/** Whether the buffer was suballocated. */409bool (*buffer_is_suballocated)(struct pb_buffer *buf);410411/**412* Get a winsys handle from a winsys buffer. The internal structure413* of the handle is platform-specific and only a winsys should access it.414*415* \param ws The winsys instance for which the handle is to be valid416* \param buf A winsys buffer object to get the handle from.417* \param whandle A winsys handle pointer.418* \return true on success.419*/420bool (*buffer_get_handle)(struct radeon_winsys *ws, struct pb_buffer *buf,421struct winsys_handle *whandle);422423/**424* Change the commitment of a (64KB-page aligned) region of the given425* sparse buffer.426*427* \warning There is no automatic synchronization with command submission.428*429* \note Only implemented by the amdgpu winsys.430*431* \return false on out of memory or other failure, true on success.432*/433bool (*buffer_commit)(struct radeon_winsys *ws, struct pb_buffer *buf,434uint64_t offset, uint64_t size, bool commit);435436/**437* Return the virtual address of a buffer.438*439* When virtual memory is not in use, this is the offset relative to the440* relocation base (non-zero for sub-allocated buffers).441*442* \param buf A winsys buffer object443* \return virtual address444*/445uint64_t (*buffer_get_virtual_address)(struct pb_buffer *buf);446447/**448* Return the offset of this buffer relative to the relocation base.449* This is only non-zero for sub-allocated buffers.450*451* This is only supported in the radeon winsys, since amdgpu uses virtual452* addresses in submissions even for the video engines.453*454* \param buf A winsys buffer object455* \return the offset for relocations456*/457unsigned (*buffer_get_reloc_offset)(struct pb_buffer *buf);458459/**460* Query the initial placement of the buffer from the kernel driver.461*/462enum radeon_bo_domain (*buffer_get_initial_domain)(struct pb_buffer *buf);463464/**465* Query the flags used for creation of this buffer.466*467* Note that for imported buffer this may be lossy since not all flags468* are passed 1:1.469*/470enum radeon_bo_flag (*buffer_get_flags)(struct pb_buffer *buf);471472/**************************************************************************473* Command submission.474*475* Each pipe context should create its own command stream and submit476* commands independently of other contexts.477*************************************************************************/478479/**480* Create a command submission context.481* Various command streams can be submitted to the same context.482*/483struct radeon_winsys_ctx *(*ctx_create)(struct radeon_winsys *ws);484485/**486* Destroy a context.487*/488void (*ctx_destroy)(struct radeon_winsys_ctx *ctx);489490/**491* Query a GPU reset status.492*/493enum pipe_reset_status (*ctx_query_reset_status)(struct radeon_winsys_ctx *ctx,494bool full_reset_only,495bool *needs_reset);496497/**498* Create a command stream.499*500* \param cs The returned structure that is initialized by cs_create.501* \param ctx The submission context502* \param ring_type The ring type (GFX, DMA, UVD)503* \param flush Flush callback function associated with the command stream.504* \param user User pointer that will be passed to the flush callback.505*506* \return true on success507*/508bool (*cs_create)(struct radeon_cmdbuf *cs,509struct radeon_winsys_ctx *ctx, enum ring_type ring_type,510void (*flush)(void *ctx, unsigned flags,511struct pipe_fence_handle **fence),512void *flush_ctx, bool stop_exec_on_failure);513514/**515* Add a parallel compute IB to a gfx IB. It will share the buffer list516* and fence dependencies with the gfx IB. The gfx flush call will submit517* both IBs at the same time.518*519* The compute IB doesn't have an output fence, so the primary IB has520* to use a wait packet for synchronization.521*522* The returned IB is only a stream for writing packets to the new523* IB. The only function that can be used on the compute cs is cs_check_space.524*525* \param compute_cs The returned structure of the command stream.526* \param gfx_cs Gfx IB527*528* \return true on success529*/530bool (*cs_add_parallel_compute_ib)(struct radeon_cmdbuf *compute_cs,531struct radeon_cmdbuf *gfx_cs,532bool uses_gds_ordered_append);533534/**535* Set up and enable mid command buffer preemption for the command stream.536*537* \param cs Command stream538* \param preamble_ib Non-preemptible preamble IB for the context.539* \param preamble_num_dw Number of dwords in the preamble IB.540*/541bool (*cs_setup_preemption)(struct radeon_cmdbuf *cs, const uint32_t *preamble_ib,542unsigned preamble_num_dw);543544/**545* Destroy a command stream.546*547* \param cs A command stream to destroy.548*/549void (*cs_destroy)(struct radeon_cmdbuf *cs);550551/**552* Add a buffer. Each buffer used by a CS must be added using this function.553*554* \param cs Command stream555* \param buf Buffer556* \param usage Whether the buffer is used for read and/or write.557* \param domain Bitmask of the RADEON_DOMAIN_* flags.558* \param priority A higher number means a greater chance of being559* placed in the requested domain. 15 is the maximum.560* \return Buffer index.561*/562unsigned (*cs_add_buffer)(struct radeon_cmdbuf *cs, struct pb_buffer *buf,563enum radeon_bo_usage usage, enum radeon_bo_domain domain,564enum radeon_bo_priority priority);565566/**567* Return the index of an already-added buffer.568*569* Not supported on amdgpu. Drivers with GPUVM should not care about570* buffer indices.571*572* \param cs Command stream573* \param buf Buffer574* \return The buffer index, or -1 if the buffer has not been added.575*/576int (*cs_lookup_buffer)(struct radeon_cmdbuf *cs, struct pb_buffer *buf);577578/**579* Return true if there is enough memory in VRAM and GTT for the buffers580* added so far. If the validation fails, all buffers which have581* been added since the last call of cs_validate will be removed and582* the CS will be flushed (provided there are still any buffers).583*584* \param cs A command stream to validate.585*/586bool (*cs_validate)(struct radeon_cmdbuf *cs);587588/**589* Check whether the given number of dwords is available in the IB.590* Optionally chain a new chunk of the IB if necessary and supported.591*592* \param cs A command stream.593* \param dw Number of CS dwords requested by the caller.594* \param force_chaining Chain the IB into a new buffer now to discard595* the CP prefetch cache (to emulate PKT3_REWIND)596* \return true if there is enough space597*/598bool (*cs_check_space)(struct radeon_cmdbuf *cs, unsigned dw, bool force_chaining);599600/**601* Return the buffer list.602*603* This is the buffer list as passed to the kernel, i.e. it only contains604* the parent buffers of sub-allocated buffers.605*606* \param cs Command stream607* \param list Returned buffer list. Set to NULL to query the count only.608* \return The buffer count.609*/610unsigned (*cs_get_buffer_list)(struct radeon_cmdbuf *cs, struct radeon_bo_list_item *list);611612/**613* Flush a command stream.614*615* \param cs A command stream to flush.616* \param flags, PIPE_FLUSH_* flags.617* \param fence Pointer to a fence. If non-NULL, a fence is inserted618* after the CS and is returned through this parameter.619* \return Negative POSIX error code or 0 for success.620* Asynchronous submissions never return an error.621*/622int (*cs_flush)(struct radeon_cmdbuf *cs, unsigned flags, struct pipe_fence_handle **fence);623624/**625* Create a fence before the CS is flushed.626* The user must flush manually to complete the initializaton of the fence.627*628* The fence must not be used for anything except \ref cs_add_fence_dependency629* before the flush.630*/631struct pipe_fence_handle *(*cs_get_next_fence)(struct radeon_cmdbuf *cs);632633/**634* Return true if a buffer is referenced by a command stream.635*636* \param cs A command stream.637* \param buf A winsys buffer.638*/639bool (*cs_is_buffer_referenced)(struct radeon_cmdbuf *cs, struct pb_buffer *buf,640enum radeon_bo_usage usage);641642/**643* Request access to a feature for a command stream.644*645* \param cs A command stream.646* \param fid Feature ID, one of RADEON_FID_*647* \param enable Whether to enable or disable the feature.648*/649bool (*cs_request_feature)(struct radeon_cmdbuf *cs, enum radeon_feature_id fid, bool enable);650/**651* Make sure all asynchronous flush of the cs have completed652*653* \param cs A command stream.654*/655void (*cs_sync_flush)(struct radeon_cmdbuf *cs);656657/**658* Add a fence dependency to the CS, so that the CS will wait for659* the fence before execution.660*661* \param dependency_flags Bitmask of RADEON_DEPENDENCY_*662*/663void (*cs_add_fence_dependency)(struct radeon_cmdbuf *cs, struct pipe_fence_handle *fence,664unsigned dependency_flags);665666/**667* Signal a syncobj when the CS finishes execution.668*/669void (*cs_add_syncobj_signal)(struct radeon_cmdbuf *cs, struct pipe_fence_handle *fence);670671/**672* Wait for the fence and return true if the fence has been signalled.673* The timeout of 0 will only return the status.674* The timeout of PIPE_TIMEOUT_INFINITE will always wait until the fence675* is signalled.676*/677bool (*fence_wait)(struct radeon_winsys *ws, struct pipe_fence_handle *fence, uint64_t timeout);678679/**680* Reference counting for fences.681*/682void (*fence_reference)(struct pipe_fence_handle **dst, struct pipe_fence_handle *src);683684/**685* Create a new fence object corresponding to the given syncobj fd.686*/687struct pipe_fence_handle *(*fence_import_syncobj)(struct radeon_winsys *ws, int fd);688689/**690* Create a new fence object corresponding to the given sync_file.691*/692struct pipe_fence_handle *(*fence_import_sync_file)(struct radeon_winsys *ws, int fd);693694/**695* Return a sync_file FD corresponding to the given fence object.696*/697int (*fence_export_sync_file)(struct radeon_winsys *ws, struct pipe_fence_handle *fence);698699/**700* Return a sync file FD that is already signalled.701*/702int (*export_signalled_sync_file)(struct radeon_winsys *ws);703704/**705* Initialize surface706*707* \param ws The winsys this function is called from.708* \param tex Input texture description709* \param flags Bitmask of RADEON_SURF_* flags710* \param bpe Bytes per pixel, it can be different for Z buffers.711* \param mode Preferred tile mode. (linear, 1D, or 2D)712* \param surf Output structure713*/714int (*surface_init)(struct radeon_winsys *ws, const struct pipe_resource *tex, unsigned flags,715unsigned bpe, enum radeon_surf_mode mode, struct radeon_surf *surf);716717uint64_t (*query_value)(struct radeon_winsys *ws, enum radeon_value_id value);718719bool (*read_registers)(struct radeon_winsys *ws, unsigned reg_offset, unsigned num_registers,720uint32_t *out);721722/**723* Secure context724*/725bool (*cs_is_secure)(struct radeon_cmdbuf *cs);726};727728static inline bool radeon_emitted(struct radeon_cmdbuf *cs, unsigned num_dw)729{730return cs && (cs->prev_dw + cs->current.cdw > num_dw);731}732733static inline void radeon_emit(struct radeon_cmdbuf *cs, uint32_t value)734{735cs->current.buf[cs->current.cdw++] = value;736}737738static inline void radeon_emit_array(struct radeon_cmdbuf *cs, const uint32_t *values,739unsigned count)740{741memcpy(cs->current.buf + cs->current.cdw, values, count * 4);742cs->current.cdw += count;743}744745static inline bool radeon_uses_secure_bos(struct radeon_winsys* ws)746{747return ws->uses_secure_bos;748}749750static inline void751radeon_bo_reference(struct radeon_winsys *rws, struct pb_buffer **dst, struct pb_buffer *src)752{753pb_reference_with_winsys(rws, dst, src);754}755756enum radeon_heap757{758RADEON_HEAP_VRAM_NO_CPU_ACCESS,759RADEON_HEAP_VRAM_READ_ONLY,760RADEON_HEAP_VRAM_READ_ONLY_32BIT,761RADEON_HEAP_VRAM_32BIT,762RADEON_HEAP_VRAM,763RADEON_HEAP_GTT_WC,764RADEON_HEAP_GTT_WC_READ_ONLY,765RADEON_HEAP_GTT_WC_READ_ONLY_32BIT,766RADEON_HEAP_GTT_WC_32BIT,767RADEON_HEAP_GTT,768RADEON_HEAP_GTT_UNCACHED_WC,769RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY,770RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY_32BIT,771RADEON_HEAP_GTT_UNCACHED_WC_32BIT,772RADEON_HEAP_GTT_UNCACHED,773RADEON_MAX_SLAB_HEAPS,774RADEON_MAX_CACHED_HEAPS = RADEON_MAX_SLAB_HEAPS,775};776777static inline enum radeon_bo_domain radeon_domain_from_heap(enum radeon_heap heap)778{779switch (heap) {780case RADEON_HEAP_VRAM_NO_CPU_ACCESS:781case RADEON_HEAP_VRAM_READ_ONLY:782case RADEON_HEAP_VRAM_READ_ONLY_32BIT:783case RADEON_HEAP_VRAM_32BIT:784case RADEON_HEAP_VRAM:785return RADEON_DOMAIN_VRAM;786case RADEON_HEAP_GTT_WC:787case RADEON_HEAP_GTT_WC_READ_ONLY:788case RADEON_HEAP_GTT_WC_READ_ONLY_32BIT:789case RADEON_HEAP_GTT_WC_32BIT:790case RADEON_HEAP_GTT:791case RADEON_HEAP_GTT_UNCACHED_WC:792case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY:793case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY_32BIT:794case RADEON_HEAP_GTT_UNCACHED_WC_32BIT:795case RADEON_HEAP_GTT_UNCACHED:796return RADEON_DOMAIN_GTT;797default:798assert(0);799return (enum radeon_bo_domain)0;800}801}802803static inline unsigned radeon_flags_from_heap(enum radeon_heap heap)804{805unsigned flags = RADEON_FLAG_NO_INTERPROCESS_SHARING;806807switch (heap) {808case RADEON_HEAP_GTT:809case RADEON_HEAP_GTT_UNCACHED:810break;811default:812flags |= RADEON_FLAG_GTT_WC;813}814815switch (heap) {816case RADEON_HEAP_GTT_UNCACHED_WC:817case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY:818case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY_32BIT:819case RADEON_HEAP_GTT_UNCACHED_WC_32BIT:820case RADEON_HEAP_GTT_UNCACHED:821flags |= RADEON_FLAG_UNCACHED;822break;823default:824break;825}826827switch (heap) {828case RADEON_HEAP_VRAM_READ_ONLY:829case RADEON_HEAP_VRAM_READ_ONLY_32BIT:830case RADEON_HEAP_GTT_WC_READ_ONLY:831case RADEON_HEAP_GTT_WC_READ_ONLY_32BIT:832case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY:833case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY_32BIT:834flags |= RADEON_FLAG_READ_ONLY;835break;836default:837break;838}839840switch (heap) {841case RADEON_HEAP_VRAM_READ_ONLY_32BIT:842case RADEON_HEAP_VRAM_32BIT:843case RADEON_HEAP_GTT_WC_READ_ONLY_32BIT:844case RADEON_HEAP_GTT_WC_32BIT:845case RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY_32BIT:846case RADEON_HEAP_GTT_UNCACHED_WC_32BIT:847flags |= RADEON_FLAG_32BIT;848FALLTHROUGH;849default:850break;851}852853switch (heap) {854case RADEON_HEAP_VRAM_NO_CPU_ACCESS:855flags |= RADEON_FLAG_NO_CPU_ACCESS;856break;857default:858break;859}860861return flags;862}863864/* Return the heap index for winsys allocators, or -1 on failure. */865static inline int radeon_get_heap_index(enum radeon_bo_domain domain, enum radeon_bo_flag flags)866{867bool uncached;868869/* VRAM implies WC (write combining) */870assert(!(domain & RADEON_DOMAIN_VRAM) || flags & RADEON_FLAG_GTT_WC);871/* NO_CPU_ACCESS implies VRAM only. */872assert(!(flags & RADEON_FLAG_NO_CPU_ACCESS) || domain == RADEON_DOMAIN_VRAM);873874/* Resources with interprocess sharing don't use any winsys allocators. */875if (!(flags & RADEON_FLAG_NO_INTERPROCESS_SHARING))876return -1;877878/* Unsupported flags: NO_SUBALLOC, SPARSE. */879if (flags & ~(RADEON_FLAG_GTT_WC | RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_UNCACHED |880RADEON_FLAG_NO_INTERPROCESS_SHARING | RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT |881RADEON_FLAG_DRIVER_INTERNAL))882return -1;883884switch (domain) {885case RADEON_DOMAIN_VRAM:886switch (flags & (RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT)) {887case RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT:888case RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_READ_ONLY:889assert(!"NO_CPU_ACCESS | READ_ONLY doesn't make sense");890return -1;891case RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_32BIT:892assert(!"NO_CPU_ACCESS with 32BIT is disallowed");893return -1;894case RADEON_FLAG_NO_CPU_ACCESS:895return RADEON_HEAP_VRAM_NO_CPU_ACCESS;896case RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT:897return RADEON_HEAP_VRAM_READ_ONLY_32BIT;898case RADEON_FLAG_READ_ONLY:899return RADEON_HEAP_VRAM_READ_ONLY;900case RADEON_FLAG_32BIT:901return RADEON_HEAP_VRAM_32BIT;902case 0:903return RADEON_HEAP_VRAM;904}905break;906case RADEON_DOMAIN_GTT:907uncached = flags & RADEON_FLAG_UNCACHED;908909switch (flags & (RADEON_FLAG_GTT_WC | RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT)) {910case RADEON_FLAG_GTT_WC | RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT:911return uncached ? RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY_32BIT912: RADEON_HEAP_GTT_WC_READ_ONLY_32BIT;913case RADEON_FLAG_GTT_WC | RADEON_FLAG_READ_ONLY:914return uncached ? RADEON_HEAP_GTT_UNCACHED_WC_READ_ONLY915: RADEON_HEAP_GTT_WC_READ_ONLY;916case RADEON_FLAG_GTT_WC | RADEON_FLAG_32BIT:917return uncached ? RADEON_HEAP_GTT_UNCACHED_WC_32BIT918: RADEON_HEAP_GTT_WC_32BIT;919case RADEON_FLAG_GTT_WC:920return uncached ? RADEON_HEAP_GTT_UNCACHED_WC : RADEON_HEAP_GTT_WC;921case RADEON_FLAG_READ_ONLY | RADEON_FLAG_32BIT:922case RADEON_FLAG_READ_ONLY:923assert(!"READ_ONLY without WC is disallowed");924return -1;925case RADEON_FLAG_32BIT:926assert(!"32BIT without WC is disallowed");927return -1;928case 0:929return uncached ? RADEON_HEAP_GTT_UNCACHED : RADEON_HEAP_GTT;930}931break;932default:933break;934}935return -1;936}937938#endif939940941