1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2013 Advanced Micro Devices, Inc. 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21bf215546Sopenharmony_ci * SOFTWARE. 22bf215546Sopenharmony_ci * 23bf215546Sopenharmony_ci * Authors: Marek Olšák <maraeo@gmail.com> 24bf215546Sopenharmony_ci * 25bf215546Sopenharmony_ci */ 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#include "r600_pipe_common.h" 28bf215546Sopenharmony_ci#include "r600_cs.h" 29bf215546Sopenharmony_ci#include "evergreen_compute.h" 30bf215546Sopenharmony_ci#include "tgsi/tgsi_parse.h" 31bf215546Sopenharmony_ci#include "util/list.h" 32bf215546Sopenharmony_ci#include "util/u_draw_quad.h" 33bf215546Sopenharmony_ci#include "util/u_memory.h" 34bf215546Sopenharmony_ci#include "util/format/u_format_s3tc.h" 35bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 36bf215546Sopenharmony_ci#include "util/os_time.h" 37bf215546Sopenharmony_ci#include "vl/vl_decoder.h" 38bf215546Sopenharmony_ci#include "vl/vl_video_buffer.h" 39bf215546Sopenharmony_ci#include "radeon_video.h" 40bf215546Sopenharmony_ci#include <inttypes.h> 41bf215546Sopenharmony_ci#include <sys/utsname.h> 42bf215546Sopenharmony_ci#include <stdlib.h> 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci#ifdef LLVM_AVAILABLE 45bf215546Sopenharmony_ci#include <llvm-c/TargetMachine.h> 46bf215546Sopenharmony_ci#endif 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistruct r600_multi_fence { 49bf215546Sopenharmony_ci struct pipe_reference reference; 50bf215546Sopenharmony_ci struct pipe_fence_handle *gfx; 51bf215546Sopenharmony_ci struct pipe_fence_handle *sdma; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci /* If the context wasn't flushed at fence creation, this is non-NULL. */ 54bf215546Sopenharmony_ci struct { 55bf215546Sopenharmony_ci struct r600_common_context *ctx; 56bf215546Sopenharmony_ci unsigned ib_index; 57bf215546Sopenharmony_ci } gfx_unflushed; 58bf215546Sopenharmony_ci}; 59bf215546Sopenharmony_ci 60bf215546Sopenharmony_ci/* 61bf215546Sopenharmony_ci * pipe_context 62bf215546Sopenharmony_ci */ 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci/** 65bf215546Sopenharmony_ci * Write an EOP event. 66bf215546Sopenharmony_ci * 67bf215546Sopenharmony_ci * \param event EVENT_TYPE_* 68bf215546Sopenharmony_ci * \param event_flags Optional cache flush flags (TC) 69bf215546Sopenharmony_ci * \param data_sel 1 = fence, 3 = timestamp 70bf215546Sopenharmony_ci * \param buf Buffer 71bf215546Sopenharmony_ci * \param va GPU address 72bf215546Sopenharmony_ci * \param old_value Previous fence value (for a bug workaround) 73bf215546Sopenharmony_ci * \param new_value Fence value to write for this event. 74bf215546Sopenharmony_ci */ 75bf215546Sopenharmony_civoid r600_gfx_write_event_eop(struct r600_common_context *ctx, 76bf215546Sopenharmony_ci unsigned event, unsigned event_flags, 77bf215546Sopenharmony_ci unsigned data_sel, 78bf215546Sopenharmony_ci struct r600_resource *buf, uint64_t va, 79bf215546Sopenharmony_ci uint32_t new_fence, unsigned query_type) 80bf215546Sopenharmony_ci{ 81bf215546Sopenharmony_ci struct radeon_cmdbuf *cs = &ctx->gfx.cs; 82bf215546Sopenharmony_ci unsigned op = EVENT_TYPE(event) | 83bf215546Sopenharmony_ci EVENT_INDEX(5) | 84bf215546Sopenharmony_ci event_flags; 85bf215546Sopenharmony_ci unsigned sel = EOP_DATA_SEL(data_sel); 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_EVENT_WRITE_EOP, 4, 0)); 88bf215546Sopenharmony_ci radeon_emit(cs, op); 89bf215546Sopenharmony_ci radeon_emit(cs, va); 90bf215546Sopenharmony_ci radeon_emit(cs, ((va >> 32) & 0xffff) | sel); 91bf215546Sopenharmony_ci radeon_emit(cs, new_fence); /* immediate data */ 92bf215546Sopenharmony_ci radeon_emit(cs, 0); /* unused */ 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci if (buf) 95bf215546Sopenharmony_ci r600_emit_reloc(ctx, &ctx->gfx, buf, RADEON_USAGE_WRITE | 96bf215546Sopenharmony_ci RADEON_PRIO_QUERY); 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_ciunsigned r600_gfx_write_fence_dwords(struct r600_common_screen *screen) 100bf215546Sopenharmony_ci{ 101bf215546Sopenharmony_ci unsigned dwords = 6; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci if (!screen->info.r600_has_virtual_memory) 104bf215546Sopenharmony_ci dwords += 2; 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci return dwords; 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_civoid r600_gfx_wait_fence(struct r600_common_context *ctx, 110bf215546Sopenharmony_ci struct r600_resource *buf, 111bf215546Sopenharmony_ci uint64_t va, uint32_t ref, uint32_t mask) 112bf215546Sopenharmony_ci{ 113bf215546Sopenharmony_ci struct radeon_cmdbuf *cs = &ctx->gfx.cs; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci radeon_emit(cs, PKT3(PKT3_WAIT_REG_MEM, 5, 0)); 116bf215546Sopenharmony_ci radeon_emit(cs, WAIT_REG_MEM_EQUAL | WAIT_REG_MEM_MEM_SPACE(1)); 117bf215546Sopenharmony_ci radeon_emit(cs, va); 118bf215546Sopenharmony_ci radeon_emit(cs, va >> 32); 119bf215546Sopenharmony_ci radeon_emit(cs, ref); /* reference value */ 120bf215546Sopenharmony_ci radeon_emit(cs, mask); /* mask */ 121bf215546Sopenharmony_ci radeon_emit(cs, 4); /* poll interval */ 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci if (buf) 124bf215546Sopenharmony_ci r600_emit_reloc(ctx, &ctx->gfx, buf, RADEON_USAGE_READ | 125bf215546Sopenharmony_ci RADEON_PRIO_QUERY); 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_civoid r600_draw_rectangle(struct blitter_context *blitter, 129bf215546Sopenharmony_ci void *vertex_elements_cso, 130bf215546Sopenharmony_ci blitter_get_vs_func get_vs, 131bf215546Sopenharmony_ci int x1, int y1, int x2, int y2, 132bf215546Sopenharmony_ci float depth, unsigned num_instances, 133bf215546Sopenharmony_ci enum blitter_attrib_type type, 134bf215546Sopenharmony_ci const union blitter_attrib *attrib) 135bf215546Sopenharmony_ci{ 136bf215546Sopenharmony_ci struct r600_common_context *rctx = 137bf215546Sopenharmony_ci (struct r600_common_context*)util_blitter_get_pipe(blitter); 138bf215546Sopenharmony_ci struct pipe_viewport_state viewport; 139bf215546Sopenharmony_ci struct pipe_resource *buf = NULL; 140bf215546Sopenharmony_ci unsigned offset = 0; 141bf215546Sopenharmony_ci float *vb; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci rctx->b.bind_vertex_elements_state(&rctx->b, vertex_elements_cso); 144bf215546Sopenharmony_ci rctx->b.bind_vs_state(&rctx->b, get_vs(blitter)); 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_ci /* Some operations (like color resolve on r6xx) don't work 147bf215546Sopenharmony_ci * with the conventional primitive types. 148bf215546Sopenharmony_ci * One that works is PT_RECTLIST, which we use here. */ 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci /* setup viewport */ 151bf215546Sopenharmony_ci viewport.scale[0] = 1.0f; 152bf215546Sopenharmony_ci viewport.scale[1] = 1.0f; 153bf215546Sopenharmony_ci viewport.scale[2] = 1.0f; 154bf215546Sopenharmony_ci viewport.translate[0] = 0.0f; 155bf215546Sopenharmony_ci viewport.translate[1] = 0.0f; 156bf215546Sopenharmony_ci viewport.translate[2] = 0.0f; 157bf215546Sopenharmony_ci rctx->b.set_viewport_states(&rctx->b, 0, 1, &viewport); 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci /* Upload vertices. The hw rectangle has only 3 vertices, 160bf215546Sopenharmony_ci * The 4th one is derived from the first 3. 161bf215546Sopenharmony_ci * The vertex specification should match u_blitter's vertex element state. */ 162bf215546Sopenharmony_ci u_upload_alloc(rctx->b.stream_uploader, 0, sizeof(float) * 24, 163bf215546Sopenharmony_ci rctx->screen->info.tcc_cache_line_size, 164bf215546Sopenharmony_ci &offset, &buf, (void**)&vb); 165bf215546Sopenharmony_ci if (!buf) 166bf215546Sopenharmony_ci return; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci vb[0] = x1; 169bf215546Sopenharmony_ci vb[1] = y1; 170bf215546Sopenharmony_ci vb[2] = depth; 171bf215546Sopenharmony_ci vb[3] = 1; 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_ci vb[8] = x1; 174bf215546Sopenharmony_ci vb[9] = y2; 175bf215546Sopenharmony_ci vb[10] = depth; 176bf215546Sopenharmony_ci vb[11] = 1; 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci vb[16] = x2; 179bf215546Sopenharmony_ci vb[17] = y1; 180bf215546Sopenharmony_ci vb[18] = depth; 181bf215546Sopenharmony_ci vb[19] = 1; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci switch (type) { 184bf215546Sopenharmony_ci case UTIL_BLITTER_ATTRIB_COLOR: 185bf215546Sopenharmony_ci memcpy(vb+4, attrib->color, sizeof(float)*4); 186bf215546Sopenharmony_ci memcpy(vb+12, attrib->color, sizeof(float)*4); 187bf215546Sopenharmony_ci memcpy(vb+20, attrib->color, sizeof(float)*4); 188bf215546Sopenharmony_ci break; 189bf215546Sopenharmony_ci case UTIL_BLITTER_ATTRIB_TEXCOORD_XYZW: 190bf215546Sopenharmony_ci case UTIL_BLITTER_ATTRIB_TEXCOORD_XY: 191bf215546Sopenharmony_ci vb[6] = vb[14] = vb[22] = attrib->texcoord.z; 192bf215546Sopenharmony_ci vb[7] = vb[15] = vb[23] = attrib->texcoord.w; 193bf215546Sopenharmony_ci /* fall through */ 194bf215546Sopenharmony_ci vb[4] = attrib->texcoord.x1; 195bf215546Sopenharmony_ci vb[5] = attrib->texcoord.y1; 196bf215546Sopenharmony_ci vb[12] = attrib->texcoord.x1; 197bf215546Sopenharmony_ci vb[13] = attrib->texcoord.y2; 198bf215546Sopenharmony_ci vb[20] = attrib->texcoord.x2; 199bf215546Sopenharmony_ci vb[21] = attrib->texcoord.y1; 200bf215546Sopenharmony_ci break; 201bf215546Sopenharmony_ci default:; /* Nothing to do. */ 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci /* draw */ 205bf215546Sopenharmony_ci struct pipe_vertex_buffer vbuffer = {}; 206bf215546Sopenharmony_ci vbuffer.buffer.resource = buf; 207bf215546Sopenharmony_ci vbuffer.stride = 2 * 4 * sizeof(float); /* vertex size */ 208bf215546Sopenharmony_ci vbuffer.buffer_offset = offset; 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci rctx->b.set_vertex_buffers(&rctx->b, blitter->vb_slot, 1, 0, false, &vbuffer); 211bf215546Sopenharmony_ci util_draw_arrays_instanced(&rctx->b, R600_PRIM_RECTANGLE_LIST, 0, 3, 212bf215546Sopenharmony_ci 0, num_instances); 213bf215546Sopenharmony_ci pipe_resource_reference(&buf, NULL); 214bf215546Sopenharmony_ci} 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_cistatic void r600_dma_emit_wait_idle(struct r600_common_context *rctx) 217bf215546Sopenharmony_ci{ 218bf215546Sopenharmony_ci struct radeon_cmdbuf *cs = &rctx->dma.cs; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci if (rctx->gfx_level >= EVERGREEN) 221bf215546Sopenharmony_ci radeon_emit(cs, 0xf0000000); /* NOP */ 222bf215546Sopenharmony_ci else { 223bf215546Sopenharmony_ci /* TODO: R600-R700 should use the FENCE packet. 224bf215546Sopenharmony_ci * CS checker support is required. */ 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci} 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_civoid r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw, 229bf215546Sopenharmony_ci struct r600_resource *dst, struct r600_resource *src) 230bf215546Sopenharmony_ci{ 231bf215546Sopenharmony_ci uint64_t vram = (uint64_t)ctx->dma.cs.used_vram_kb * 1024; 232bf215546Sopenharmony_ci uint64_t gtt = (uint64_t)ctx->dma.cs.used_gart_kb * 1024; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci if (dst) { 235bf215546Sopenharmony_ci vram += dst->vram_usage; 236bf215546Sopenharmony_ci gtt += dst->gart_usage; 237bf215546Sopenharmony_ci } 238bf215546Sopenharmony_ci if (src) { 239bf215546Sopenharmony_ci vram += src->vram_usage; 240bf215546Sopenharmony_ci gtt += src->gart_usage; 241bf215546Sopenharmony_ci } 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci /* Flush the GFX IB if DMA depends on it. */ 244bf215546Sopenharmony_ci if (radeon_emitted(&ctx->gfx.cs, ctx->initial_gfx_cs_size) && 245bf215546Sopenharmony_ci ((dst && 246bf215546Sopenharmony_ci ctx->ws->cs_is_buffer_referenced(&ctx->gfx.cs, dst->buf, 247bf215546Sopenharmony_ci RADEON_USAGE_READWRITE)) || 248bf215546Sopenharmony_ci (src && 249bf215546Sopenharmony_ci ctx->ws->cs_is_buffer_referenced(&ctx->gfx.cs, src->buf, 250bf215546Sopenharmony_ci RADEON_USAGE_WRITE)))) 251bf215546Sopenharmony_ci ctx->gfx.flush(ctx, PIPE_FLUSH_ASYNC, NULL); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci /* Flush if there's not enough space, or if the memory usage per IB 254bf215546Sopenharmony_ci * is too large. 255bf215546Sopenharmony_ci * 256bf215546Sopenharmony_ci * IBs using too little memory are limited by the IB submission overhead. 257bf215546Sopenharmony_ci * IBs using too much memory are limited by the kernel/TTM overhead. 258bf215546Sopenharmony_ci * Too long IBs create CPU-GPU pipeline bubbles and add latency. 259bf215546Sopenharmony_ci * 260bf215546Sopenharmony_ci * This heuristic makes sure that DMA requests are executed 261bf215546Sopenharmony_ci * very soon after the call is made and lowers memory usage. 262bf215546Sopenharmony_ci * It improves texture upload performance by keeping the DMA 263bf215546Sopenharmony_ci * engine busy while uploads are being submitted. 264bf215546Sopenharmony_ci */ 265bf215546Sopenharmony_ci num_dw++; /* for emit_wait_idle below */ 266bf215546Sopenharmony_ci if (!ctx->ws->cs_check_space(&ctx->dma.cs, num_dw) || 267bf215546Sopenharmony_ci ctx->dma.cs.used_vram_kb + ctx->dma.cs.used_gart_kb > 64 * 1024 || 268bf215546Sopenharmony_ci !radeon_cs_memory_below_limit(ctx->screen, &ctx->dma.cs, vram, gtt)) { 269bf215546Sopenharmony_ci ctx->dma.flush(ctx, PIPE_FLUSH_ASYNC, NULL); 270bf215546Sopenharmony_ci assert((num_dw + ctx->dma.cs.current.cdw) <= ctx->dma.cs.current.max_dw); 271bf215546Sopenharmony_ci } 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci /* Wait for idle if either buffer has been used in the IB before to 274bf215546Sopenharmony_ci * prevent read-after-write hazards. 275bf215546Sopenharmony_ci */ 276bf215546Sopenharmony_ci if ((dst && 277bf215546Sopenharmony_ci ctx->ws->cs_is_buffer_referenced(&ctx->dma.cs, dst->buf, 278bf215546Sopenharmony_ci RADEON_USAGE_READWRITE)) || 279bf215546Sopenharmony_ci (src && 280bf215546Sopenharmony_ci ctx->ws->cs_is_buffer_referenced(&ctx->dma.cs, src->buf, 281bf215546Sopenharmony_ci RADEON_USAGE_WRITE))) 282bf215546Sopenharmony_ci r600_dma_emit_wait_idle(ctx); 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci /* If GPUVM is not supported, the CS checker needs 2 entries 285bf215546Sopenharmony_ci * in the buffer list per packet, which has to be done manually. 286bf215546Sopenharmony_ci */ 287bf215546Sopenharmony_ci if (ctx->screen->info.r600_has_virtual_memory) { 288bf215546Sopenharmony_ci if (dst) 289bf215546Sopenharmony_ci radeon_add_to_buffer_list(ctx, &ctx->dma, dst, 290bf215546Sopenharmony_ci RADEON_USAGE_WRITE); 291bf215546Sopenharmony_ci if (src) 292bf215546Sopenharmony_ci radeon_add_to_buffer_list(ctx, &ctx->dma, src, 293bf215546Sopenharmony_ci RADEON_USAGE_READ); 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci /* this function is called before all DMA calls, so increment this. */ 297bf215546Sopenharmony_ci ctx->num_dma_calls++; 298bf215546Sopenharmony_ci} 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_civoid r600_preflush_suspend_features(struct r600_common_context *ctx) 301bf215546Sopenharmony_ci{ 302bf215546Sopenharmony_ci /* suspend queries */ 303bf215546Sopenharmony_ci if (!list_is_empty(&ctx->active_queries)) 304bf215546Sopenharmony_ci r600_suspend_queries(ctx); 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci ctx->streamout.suspended = false; 307bf215546Sopenharmony_ci if (ctx->streamout.begin_emitted) { 308bf215546Sopenharmony_ci r600_emit_streamout_end(ctx); 309bf215546Sopenharmony_ci ctx->streamout.suspended = true; 310bf215546Sopenharmony_ci } 311bf215546Sopenharmony_ci} 312bf215546Sopenharmony_ci 313bf215546Sopenharmony_civoid r600_postflush_resume_features(struct r600_common_context *ctx) 314bf215546Sopenharmony_ci{ 315bf215546Sopenharmony_ci if (ctx->streamout.suspended) { 316bf215546Sopenharmony_ci ctx->streamout.append_bitmask = ctx->streamout.enabled_mask; 317bf215546Sopenharmony_ci r600_streamout_buffers_dirty(ctx); 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci /* resume queries */ 321bf215546Sopenharmony_ci if (!list_is_empty(&ctx->active_queries)) 322bf215546Sopenharmony_ci r600_resume_queries(ctx); 323bf215546Sopenharmony_ci} 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_cistatic void r600_fence_server_sync(struct pipe_context *ctx, 326bf215546Sopenharmony_ci struct pipe_fence_handle *fence) 327bf215546Sopenharmony_ci{ 328bf215546Sopenharmony_ci /* radeon synchronizes all rings by default and will not implement 329bf215546Sopenharmony_ci * fence imports. 330bf215546Sopenharmony_ci */ 331bf215546Sopenharmony_ci} 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_cistatic void r600_flush_from_st(struct pipe_context *ctx, 334bf215546Sopenharmony_ci struct pipe_fence_handle **fence, 335bf215546Sopenharmony_ci unsigned flags) 336bf215546Sopenharmony_ci{ 337bf215546Sopenharmony_ci struct pipe_screen *screen = ctx->screen; 338bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context *)ctx; 339bf215546Sopenharmony_ci struct radeon_winsys *ws = rctx->ws; 340bf215546Sopenharmony_ci struct pipe_fence_handle *gfx_fence = NULL; 341bf215546Sopenharmony_ci struct pipe_fence_handle *sdma_fence = NULL; 342bf215546Sopenharmony_ci bool deferred_fence = false; 343bf215546Sopenharmony_ci unsigned rflags = PIPE_FLUSH_ASYNC; 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci if (flags & PIPE_FLUSH_END_OF_FRAME) 346bf215546Sopenharmony_ci rflags |= PIPE_FLUSH_END_OF_FRAME; 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci /* DMA IBs are preambles to gfx IBs, therefore must be flushed first. */ 349bf215546Sopenharmony_ci if (rctx->dma.cs.priv) 350bf215546Sopenharmony_ci rctx->dma.flush(rctx, rflags, fence ? &sdma_fence : NULL); 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci if (!radeon_emitted(&rctx->gfx.cs, rctx->initial_gfx_cs_size)) { 353bf215546Sopenharmony_ci if (fence) 354bf215546Sopenharmony_ci ws->fence_reference(&gfx_fence, rctx->last_gfx_fence); 355bf215546Sopenharmony_ci if (!(flags & PIPE_FLUSH_DEFERRED)) 356bf215546Sopenharmony_ci ws->cs_sync_flush(&rctx->gfx.cs); 357bf215546Sopenharmony_ci } else { 358bf215546Sopenharmony_ci /* Instead of flushing, create a deferred fence. Constraints: 359bf215546Sopenharmony_ci * - the gallium frontend must allow a deferred flush. 360bf215546Sopenharmony_ci * - the gallium frontend must request a fence. 361bf215546Sopenharmony_ci * Thread safety in fence_finish must be ensured by the gallium frontend. 362bf215546Sopenharmony_ci */ 363bf215546Sopenharmony_ci if (flags & PIPE_FLUSH_DEFERRED && fence) { 364bf215546Sopenharmony_ci gfx_fence = rctx->ws->cs_get_next_fence(&rctx->gfx.cs); 365bf215546Sopenharmony_ci deferred_fence = true; 366bf215546Sopenharmony_ci } else { 367bf215546Sopenharmony_ci rctx->gfx.flush(rctx, rflags, fence ? &gfx_fence : NULL); 368bf215546Sopenharmony_ci } 369bf215546Sopenharmony_ci } 370bf215546Sopenharmony_ci 371bf215546Sopenharmony_ci /* Both engines can signal out of order, so we need to keep both fences. */ 372bf215546Sopenharmony_ci if (fence) { 373bf215546Sopenharmony_ci struct r600_multi_fence *multi_fence = 374bf215546Sopenharmony_ci CALLOC_STRUCT(r600_multi_fence); 375bf215546Sopenharmony_ci if (!multi_fence) { 376bf215546Sopenharmony_ci ws->fence_reference(&sdma_fence, NULL); 377bf215546Sopenharmony_ci ws->fence_reference(&gfx_fence, NULL); 378bf215546Sopenharmony_ci goto finish; 379bf215546Sopenharmony_ci } 380bf215546Sopenharmony_ci 381bf215546Sopenharmony_ci multi_fence->reference.count = 1; 382bf215546Sopenharmony_ci /* If both fences are NULL, fence_finish will always return true. */ 383bf215546Sopenharmony_ci multi_fence->gfx = gfx_fence; 384bf215546Sopenharmony_ci multi_fence->sdma = sdma_fence; 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci if (deferred_fence) { 387bf215546Sopenharmony_ci multi_fence->gfx_unflushed.ctx = rctx; 388bf215546Sopenharmony_ci multi_fence->gfx_unflushed.ib_index = rctx->num_gfx_cs_flushes; 389bf215546Sopenharmony_ci } 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci screen->fence_reference(screen, fence, NULL); 392bf215546Sopenharmony_ci *fence = (struct pipe_fence_handle*)multi_fence; 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_cifinish: 395bf215546Sopenharmony_ci if (!(flags & PIPE_FLUSH_DEFERRED)) { 396bf215546Sopenharmony_ci if (rctx->dma.cs.priv) 397bf215546Sopenharmony_ci ws->cs_sync_flush(&rctx->dma.cs); 398bf215546Sopenharmony_ci ws->cs_sync_flush(&rctx->gfx.cs); 399bf215546Sopenharmony_ci } 400bf215546Sopenharmony_ci} 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_cistatic void r600_flush_dma_ring(void *ctx, unsigned flags, 403bf215546Sopenharmony_ci struct pipe_fence_handle **fence) 404bf215546Sopenharmony_ci{ 405bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context *)ctx; 406bf215546Sopenharmony_ci struct radeon_cmdbuf *cs = &rctx->dma.cs; 407bf215546Sopenharmony_ci struct radeon_saved_cs saved; 408bf215546Sopenharmony_ci bool check_vm = 409bf215546Sopenharmony_ci (rctx->screen->debug_flags & DBG_CHECK_VM) && 410bf215546Sopenharmony_ci rctx->check_vm_faults; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci if (!radeon_emitted(cs, 0)) { 413bf215546Sopenharmony_ci if (fence) 414bf215546Sopenharmony_ci rctx->ws->fence_reference(fence, rctx->last_sdma_fence); 415bf215546Sopenharmony_ci return; 416bf215546Sopenharmony_ci } 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci if (check_vm) 419bf215546Sopenharmony_ci radeon_save_cs(rctx->ws, cs, &saved, true); 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci rctx->ws->cs_flush(cs, flags, &rctx->last_sdma_fence); 422bf215546Sopenharmony_ci if (fence) 423bf215546Sopenharmony_ci rctx->ws->fence_reference(fence, rctx->last_sdma_fence); 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci if (check_vm) { 426bf215546Sopenharmony_ci /* Use conservative timeout 800ms, after which we won't wait any 427bf215546Sopenharmony_ci * longer and assume the GPU is hung. 428bf215546Sopenharmony_ci */ 429bf215546Sopenharmony_ci rctx->ws->fence_wait(rctx->ws, rctx->last_sdma_fence, 800*1000*1000); 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci rctx->check_vm_faults(rctx, &saved, AMD_IP_SDMA); 432bf215546Sopenharmony_ci radeon_clear_saved_cs(&saved); 433bf215546Sopenharmony_ci } 434bf215546Sopenharmony_ci} 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci/** 437bf215546Sopenharmony_ci * Store a linearized copy of all chunks of \p cs together with the buffer 438bf215546Sopenharmony_ci * list in \p saved. 439bf215546Sopenharmony_ci */ 440bf215546Sopenharmony_civoid radeon_save_cs(struct radeon_winsys *ws, struct radeon_cmdbuf *cs, 441bf215546Sopenharmony_ci struct radeon_saved_cs *saved, bool get_buffer_list) 442bf215546Sopenharmony_ci{ 443bf215546Sopenharmony_ci uint32_t *buf; 444bf215546Sopenharmony_ci unsigned i; 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci /* Save the IB chunks. */ 447bf215546Sopenharmony_ci saved->num_dw = cs->prev_dw + cs->current.cdw; 448bf215546Sopenharmony_ci saved->ib = MALLOC(4 * saved->num_dw); 449bf215546Sopenharmony_ci if (!saved->ib) 450bf215546Sopenharmony_ci goto oom; 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci buf = saved->ib; 453bf215546Sopenharmony_ci for (i = 0; i < cs->num_prev; ++i) { 454bf215546Sopenharmony_ci memcpy(buf, cs->prev[i].buf, cs->prev[i].cdw * 4); 455bf215546Sopenharmony_ci buf += cs->prev[i].cdw; 456bf215546Sopenharmony_ci } 457bf215546Sopenharmony_ci memcpy(buf, cs->current.buf, cs->current.cdw * 4); 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci if (!get_buffer_list) 460bf215546Sopenharmony_ci return; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci /* Save the buffer list. */ 463bf215546Sopenharmony_ci saved->bo_count = ws->cs_get_buffer_list(cs, NULL); 464bf215546Sopenharmony_ci saved->bo_list = CALLOC(saved->bo_count, 465bf215546Sopenharmony_ci sizeof(saved->bo_list[0])); 466bf215546Sopenharmony_ci if (!saved->bo_list) { 467bf215546Sopenharmony_ci FREE(saved->ib); 468bf215546Sopenharmony_ci goto oom; 469bf215546Sopenharmony_ci } 470bf215546Sopenharmony_ci ws->cs_get_buffer_list(cs, saved->bo_list); 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci return; 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_cioom: 475bf215546Sopenharmony_ci fprintf(stderr, "%s: out of memory\n", __func__); 476bf215546Sopenharmony_ci memset(saved, 0, sizeof(*saved)); 477bf215546Sopenharmony_ci} 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_civoid radeon_clear_saved_cs(struct radeon_saved_cs *saved) 480bf215546Sopenharmony_ci{ 481bf215546Sopenharmony_ci FREE(saved->ib); 482bf215546Sopenharmony_ci FREE(saved->bo_list); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci memset(saved, 0, sizeof(*saved)); 485bf215546Sopenharmony_ci} 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_cistatic enum pipe_reset_status r600_get_reset_status(struct pipe_context *ctx) 488bf215546Sopenharmony_ci{ 489bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context *)ctx; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci return rctx->ws->ctx_query_reset_status(rctx->ctx, false, NULL); 492bf215546Sopenharmony_ci} 493bf215546Sopenharmony_ci 494bf215546Sopenharmony_cistatic void r600_set_debug_callback(struct pipe_context *ctx, 495bf215546Sopenharmony_ci const struct util_debug_callback *cb) 496bf215546Sopenharmony_ci{ 497bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context *)ctx; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci if (cb) 500bf215546Sopenharmony_ci rctx->debug = *cb; 501bf215546Sopenharmony_ci else 502bf215546Sopenharmony_ci memset(&rctx->debug, 0, sizeof(rctx->debug)); 503bf215546Sopenharmony_ci} 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_cistatic void r600_set_device_reset_callback(struct pipe_context *ctx, 506bf215546Sopenharmony_ci const struct pipe_device_reset_callback *cb) 507bf215546Sopenharmony_ci{ 508bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context *)ctx; 509bf215546Sopenharmony_ci 510bf215546Sopenharmony_ci if (cb) 511bf215546Sopenharmony_ci rctx->device_reset_callback = *cb; 512bf215546Sopenharmony_ci else 513bf215546Sopenharmony_ci memset(&rctx->device_reset_callback, 0, 514bf215546Sopenharmony_ci sizeof(rctx->device_reset_callback)); 515bf215546Sopenharmony_ci} 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_cibool r600_check_device_reset(struct r600_common_context *rctx) 518bf215546Sopenharmony_ci{ 519bf215546Sopenharmony_ci enum pipe_reset_status status; 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci if (!rctx->device_reset_callback.reset) 522bf215546Sopenharmony_ci return false; 523bf215546Sopenharmony_ci 524bf215546Sopenharmony_ci if (!rctx->b.get_device_reset_status) 525bf215546Sopenharmony_ci return false; 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci status = rctx->b.get_device_reset_status(&rctx->b); 528bf215546Sopenharmony_ci if (status == PIPE_NO_RESET) 529bf215546Sopenharmony_ci return false; 530bf215546Sopenharmony_ci 531bf215546Sopenharmony_ci rctx->device_reset_callback.reset(rctx->device_reset_callback.data, status); 532bf215546Sopenharmony_ci return true; 533bf215546Sopenharmony_ci} 534bf215546Sopenharmony_ci 535bf215546Sopenharmony_cistatic void r600_dma_clear_buffer_fallback(struct pipe_context *ctx, 536bf215546Sopenharmony_ci struct pipe_resource *dst, 537bf215546Sopenharmony_ci uint64_t offset, uint64_t size, 538bf215546Sopenharmony_ci unsigned value) 539bf215546Sopenharmony_ci{ 540bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context *)ctx; 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_ci rctx->clear_buffer(ctx, dst, offset, size, value, R600_COHERENCY_NONE); 543bf215546Sopenharmony_ci} 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_cistatic bool r600_resource_commit(struct pipe_context *pctx, 546bf215546Sopenharmony_ci struct pipe_resource *resource, 547bf215546Sopenharmony_ci unsigned level, struct pipe_box *box, 548bf215546Sopenharmony_ci bool commit) 549bf215546Sopenharmony_ci{ 550bf215546Sopenharmony_ci struct r600_common_context *ctx = (struct r600_common_context *)pctx; 551bf215546Sopenharmony_ci struct r600_resource *res = r600_resource(resource); 552bf215546Sopenharmony_ci 553bf215546Sopenharmony_ci /* 554bf215546Sopenharmony_ci * Since buffer commitment changes cannot be pipelined, we need to 555bf215546Sopenharmony_ci * (a) flush any pending commands that refer to the buffer we're about 556bf215546Sopenharmony_ci * to change, and 557bf215546Sopenharmony_ci * (b) wait for threaded submit to finish, including those that were 558bf215546Sopenharmony_ci * triggered by some other, earlier operation. 559bf215546Sopenharmony_ci */ 560bf215546Sopenharmony_ci if (radeon_emitted(&ctx->gfx.cs, ctx->initial_gfx_cs_size) && 561bf215546Sopenharmony_ci ctx->ws->cs_is_buffer_referenced(&ctx->gfx.cs, 562bf215546Sopenharmony_ci res->buf, RADEON_USAGE_READWRITE)) { 563bf215546Sopenharmony_ci ctx->gfx.flush(ctx, PIPE_FLUSH_ASYNC, NULL); 564bf215546Sopenharmony_ci } 565bf215546Sopenharmony_ci if (radeon_emitted(&ctx->dma.cs, 0) && 566bf215546Sopenharmony_ci ctx->ws->cs_is_buffer_referenced(&ctx->dma.cs, 567bf215546Sopenharmony_ci res->buf, RADEON_USAGE_READWRITE)) { 568bf215546Sopenharmony_ci ctx->dma.flush(ctx, PIPE_FLUSH_ASYNC, NULL); 569bf215546Sopenharmony_ci } 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci ctx->ws->cs_sync_flush(&ctx->dma.cs); 572bf215546Sopenharmony_ci ctx->ws->cs_sync_flush(&ctx->gfx.cs); 573bf215546Sopenharmony_ci 574bf215546Sopenharmony_ci assert(resource->target == PIPE_BUFFER); 575bf215546Sopenharmony_ci 576bf215546Sopenharmony_ci return ctx->ws->buffer_commit(ctx->ws, res->buf, box->x, box->width, commit); 577bf215546Sopenharmony_ci} 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_cibool r600_common_context_init(struct r600_common_context *rctx, 580bf215546Sopenharmony_ci struct r600_common_screen *rscreen, 581bf215546Sopenharmony_ci unsigned context_flags) 582bf215546Sopenharmony_ci{ 583bf215546Sopenharmony_ci slab_create_child(&rctx->pool_transfers, &rscreen->pool_transfers); 584bf215546Sopenharmony_ci slab_create_child(&rctx->pool_transfers_unsync, &rscreen->pool_transfers); 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci rctx->screen = rscreen; 587bf215546Sopenharmony_ci rctx->ws = rscreen->ws; 588bf215546Sopenharmony_ci rctx->family = rscreen->family; 589bf215546Sopenharmony_ci rctx->gfx_level = rscreen->gfx_level; 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci rctx->b.invalidate_resource = r600_invalidate_resource; 592bf215546Sopenharmony_ci rctx->b.resource_commit = r600_resource_commit; 593bf215546Sopenharmony_ci rctx->b.buffer_map = r600_buffer_transfer_map; 594bf215546Sopenharmony_ci rctx->b.texture_map = r600_texture_transfer_map; 595bf215546Sopenharmony_ci rctx->b.transfer_flush_region = r600_buffer_flush_region; 596bf215546Sopenharmony_ci rctx->b.buffer_unmap = r600_buffer_transfer_unmap; 597bf215546Sopenharmony_ci rctx->b.texture_unmap = r600_texture_transfer_unmap; 598bf215546Sopenharmony_ci rctx->b.texture_subdata = u_default_texture_subdata; 599bf215546Sopenharmony_ci rctx->b.flush = r600_flush_from_st; 600bf215546Sopenharmony_ci rctx->b.set_debug_callback = r600_set_debug_callback; 601bf215546Sopenharmony_ci rctx->b.fence_server_sync = r600_fence_server_sync; 602bf215546Sopenharmony_ci rctx->dma_clear_buffer = r600_dma_clear_buffer_fallback; 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci /* evergreen_compute.c has a special codepath for global buffers. 605bf215546Sopenharmony_ci * Everything else can use the direct path. 606bf215546Sopenharmony_ci */ 607bf215546Sopenharmony_ci if ((rscreen->gfx_level == EVERGREEN || rscreen->gfx_level == CAYMAN) && 608bf215546Sopenharmony_ci (context_flags & PIPE_CONTEXT_COMPUTE_ONLY)) 609bf215546Sopenharmony_ci rctx->b.buffer_subdata = u_default_buffer_subdata; 610bf215546Sopenharmony_ci else 611bf215546Sopenharmony_ci rctx->b.buffer_subdata = r600_buffer_subdata; 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ci rctx->b.get_device_reset_status = r600_get_reset_status; 614bf215546Sopenharmony_ci rctx->b.set_device_reset_callback = r600_set_device_reset_callback; 615bf215546Sopenharmony_ci 616bf215546Sopenharmony_ci r600_init_context_texture_functions(rctx); 617bf215546Sopenharmony_ci r600_init_viewport_functions(rctx); 618bf215546Sopenharmony_ci r600_streamout_init(rctx); 619bf215546Sopenharmony_ci r600_query_init(rctx); 620bf215546Sopenharmony_ci cayman_init_msaa(&rctx->b); 621bf215546Sopenharmony_ci 622bf215546Sopenharmony_ci u_suballocator_init(&rctx->allocator_zeroed_memory, &rctx->b, rscreen->info.gart_page_size, 623bf215546Sopenharmony_ci 0, PIPE_USAGE_DEFAULT, 0, true); 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci rctx->b.stream_uploader = u_upload_create(&rctx->b, 1024 * 1024, 626bf215546Sopenharmony_ci 0, PIPE_USAGE_STREAM, 0); 627bf215546Sopenharmony_ci if (!rctx->b.stream_uploader) 628bf215546Sopenharmony_ci return false; 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci rctx->b.const_uploader = u_upload_create(&rctx->b, 128 * 1024, 631bf215546Sopenharmony_ci 0, PIPE_USAGE_DEFAULT, 0); 632bf215546Sopenharmony_ci if (!rctx->b.const_uploader) 633bf215546Sopenharmony_ci return false; 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci rctx->ctx = rctx->ws->ctx_create(rctx->ws, RADEON_CTX_PRIORITY_MEDIUM); 636bf215546Sopenharmony_ci if (!rctx->ctx) 637bf215546Sopenharmony_ci return false; 638bf215546Sopenharmony_ci 639bf215546Sopenharmony_ci if (rscreen->info.ip[AMD_IP_SDMA].num_queues && !(rscreen->debug_flags & DBG_NO_ASYNC_DMA)) { 640bf215546Sopenharmony_ci rctx->ws->cs_create(&rctx->dma.cs, rctx->ctx, AMD_IP_SDMA, 641bf215546Sopenharmony_ci r600_flush_dma_ring, rctx, false); 642bf215546Sopenharmony_ci rctx->dma.flush = r600_flush_dma_ring; 643bf215546Sopenharmony_ci } 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci return true; 646bf215546Sopenharmony_ci} 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_civoid r600_common_context_cleanup(struct r600_common_context *rctx) 649bf215546Sopenharmony_ci{ 650bf215546Sopenharmony_ci if (rctx->query_result_shader) 651bf215546Sopenharmony_ci rctx->b.delete_compute_state(&rctx->b, rctx->query_result_shader); 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci rctx->ws->cs_destroy(&rctx->gfx.cs); 654bf215546Sopenharmony_ci rctx->ws->cs_destroy(&rctx->dma.cs); 655bf215546Sopenharmony_ci if (rctx->ctx) 656bf215546Sopenharmony_ci rctx->ws->ctx_destroy(rctx->ctx); 657bf215546Sopenharmony_ci 658bf215546Sopenharmony_ci if (rctx->b.stream_uploader) 659bf215546Sopenharmony_ci u_upload_destroy(rctx->b.stream_uploader); 660bf215546Sopenharmony_ci if (rctx->b.const_uploader) 661bf215546Sopenharmony_ci u_upload_destroy(rctx->b.const_uploader); 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci slab_destroy_child(&rctx->pool_transfers); 664bf215546Sopenharmony_ci slab_destroy_child(&rctx->pool_transfers_unsync); 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_ci u_suballocator_destroy(&rctx->allocator_zeroed_memory); 667bf215546Sopenharmony_ci rctx->ws->fence_reference(&rctx->last_gfx_fence, NULL); 668bf215546Sopenharmony_ci rctx->ws->fence_reference(&rctx->last_sdma_fence, NULL); 669bf215546Sopenharmony_ci r600_resource_reference(&rctx->eop_bug_scratch, NULL); 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci/* 673bf215546Sopenharmony_ci * pipe_screen 674bf215546Sopenharmony_ci */ 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_cistatic const struct debug_named_value common_debug_options[] = { 677bf215546Sopenharmony_ci /* logging */ 678bf215546Sopenharmony_ci { "tex", DBG_TEX, "Print texture info" }, 679bf215546Sopenharmony_ci { "nir", DBG_NIR, "Enable experimental NIR shaders" }, 680bf215546Sopenharmony_ci { "compute", DBG_COMPUTE, "Print compute info" }, 681bf215546Sopenharmony_ci { "vm", DBG_VM, "Print virtual addresses when creating resources" }, 682bf215546Sopenharmony_ci { "info", DBG_INFO, "Print driver information" }, 683bf215546Sopenharmony_ci 684bf215546Sopenharmony_ci /* shaders */ 685bf215546Sopenharmony_ci { "fs", DBG_FS, "Print fetch shaders" }, 686bf215546Sopenharmony_ci { "vs", DBG_VS, "Print vertex shaders" }, 687bf215546Sopenharmony_ci { "gs", DBG_GS, "Print geometry shaders" }, 688bf215546Sopenharmony_ci { "ps", DBG_PS, "Print pixel shaders" }, 689bf215546Sopenharmony_ci { "cs", DBG_CS, "Print compute shaders" }, 690bf215546Sopenharmony_ci { "tcs", DBG_TCS, "Print tessellation control shaders" }, 691bf215546Sopenharmony_ci { "tes", DBG_TES, "Print tessellation evaluation shaders" }, 692bf215546Sopenharmony_ci { "preoptir", DBG_PREOPT_IR, "Print the LLVM IR before initial optimizations" }, 693bf215546Sopenharmony_ci { "checkir", DBG_CHECK_IR, "Enable additional sanity checks on shader IR" }, 694bf215546Sopenharmony_ci { "use_tgsi", DBG_USE_TGSI, "Take TGSI directly instead of using NIR-to-TGSI"}, 695bf215546Sopenharmony_ci 696bf215546Sopenharmony_ci { "testdma", DBG_TEST_DMA, "Invoke SDMA tests and exit." }, 697bf215546Sopenharmony_ci { "testvmfaultcp", DBG_TEST_VMFAULT_CP, "Invoke a CP VM fault test and exit." }, 698bf215546Sopenharmony_ci { "testvmfaultsdma", DBG_TEST_VMFAULT_SDMA, "Invoke a SDMA VM fault test and exit." }, 699bf215546Sopenharmony_ci { "testvmfaultshader", DBG_TEST_VMFAULT_SHADER, "Invoke a shader VM fault test and exit." }, 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci /* features */ 702bf215546Sopenharmony_ci { "nodma", DBG_NO_ASYNC_DMA, "Disable asynchronous DMA" }, 703bf215546Sopenharmony_ci { "nohyperz", DBG_NO_HYPERZ, "Disable Hyper-Z" }, 704bf215546Sopenharmony_ci /* GL uses the word INVALIDATE, gallium uses the word DISCARD */ 705bf215546Sopenharmony_ci { "noinvalrange", DBG_NO_DISCARD_RANGE, "Disable handling of INVALIDATE_RANGE map flags" }, 706bf215546Sopenharmony_ci { "no2d", DBG_NO_2D_TILING, "Disable 2D tiling" }, 707bf215546Sopenharmony_ci { "notiling", DBG_NO_TILING, "Disable tiling" }, 708bf215546Sopenharmony_ci { "switch_on_eop", DBG_SWITCH_ON_EOP, "Program WD/IA to switch on end-of-packet." }, 709bf215546Sopenharmony_ci { "forcedma", DBG_FORCE_DMA, "Use asynchronous DMA for all operations when possible." }, 710bf215546Sopenharmony_ci { "nowc", DBG_NO_WC, "Disable GTT write combining" }, 711bf215546Sopenharmony_ci { "check_vm", DBG_CHECK_VM, "Check VM faults and dump debug info." }, 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_ci DEBUG_NAMED_VALUE_END /* must be last */ 714bf215546Sopenharmony_ci}; 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_cistatic const char* r600_get_vendor(struct pipe_screen* pscreen) 717bf215546Sopenharmony_ci{ 718bf215546Sopenharmony_ci return "X.Org"; 719bf215546Sopenharmony_ci} 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_cistatic const char* r600_get_device_vendor(struct pipe_screen* pscreen) 722bf215546Sopenharmony_ci{ 723bf215546Sopenharmony_ci return "AMD"; 724bf215546Sopenharmony_ci} 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_cistatic const char *r600_get_family_name(const struct r600_common_screen *rscreen) 727bf215546Sopenharmony_ci{ 728bf215546Sopenharmony_ci switch (rscreen->info.family) { 729bf215546Sopenharmony_ci case CHIP_R600: return "AMD R600"; 730bf215546Sopenharmony_ci case CHIP_RV610: return "AMD RV610"; 731bf215546Sopenharmony_ci case CHIP_RV630: return "AMD RV630"; 732bf215546Sopenharmony_ci case CHIP_RV670: return "AMD RV670"; 733bf215546Sopenharmony_ci case CHIP_RV620: return "AMD RV620"; 734bf215546Sopenharmony_ci case CHIP_RV635: return "AMD RV635"; 735bf215546Sopenharmony_ci case CHIP_RS780: return "AMD RS780"; 736bf215546Sopenharmony_ci case CHIP_RS880: return "AMD RS880"; 737bf215546Sopenharmony_ci case CHIP_RV770: return "AMD RV770"; 738bf215546Sopenharmony_ci case CHIP_RV730: return "AMD RV730"; 739bf215546Sopenharmony_ci case CHIP_RV710: return "AMD RV710"; 740bf215546Sopenharmony_ci case CHIP_RV740: return "AMD RV740"; 741bf215546Sopenharmony_ci case CHIP_CEDAR: return "AMD CEDAR"; 742bf215546Sopenharmony_ci case CHIP_REDWOOD: return "AMD REDWOOD"; 743bf215546Sopenharmony_ci case CHIP_JUNIPER: return "AMD JUNIPER"; 744bf215546Sopenharmony_ci case CHIP_CYPRESS: return "AMD CYPRESS"; 745bf215546Sopenharmony_ci case CHIP_HEMLOCK: return "AMD HEMLOCK"; 746bf215546Sopenharmony_ci case CHIP_PALM: return "AMD PALM"; 747bf215546Sopenharmony_ci case CHIP_SUMO: return "AMD SUMO"; 748bf215546Sopenharmony_ci case CHIP_SUMO2: return "AMD SUMO2"; 749bf215546Sopenharmony_ci case CHIP_BARTS: return "AMD BARTS"; 750bf215546Sopenharmony_ci case CHIP_TURKS: return "AMD TURKS"; 751bf215546Sopenharmony_ci case CHIP_CAICOS: return "AMD CAICOS"; 752bf215546Sopenharmony_ci case CHIP_CAYMAN: return "AMD CAYMAN"; 753bf215546Sopenharmony_ci case CHIP_ARUBA: return "AMD ARUBA"; 754bf215546Sopenharmony_ci default: return "AMD unknown"; 755bf215546Sopenharmony_ci } 756bf215546Sopenharmony_ci} 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_cistatic void r600_disk_cache_create(struct r600_common_screen *rscreen) 759bf215546Sopenharmony_ci{ 760bf215546Sopenharmony_ci /* Don't use the cache if shader dumping is enabled. */ 761bf215546Sopenharmony_ci if (rscreen->debug_flags & DBG_ALL_SHADERS) 762bf215546Sopenharmony_ci return; 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci struct mesa_sha1 ctx; 765bf215546Sopenharmony_ci unsigned char sha1[20]; 766bf215546Sopenharmony_ci char cache_id[20 * 2 + 1]; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci _mesa_sha1_init(&ctx); 769bf215546Sopenharmony_ci if (!disk_cache_get_function_identifier(r600_disk_cache_create, 770bf215546Sopenharmony_ci &ctx)) 771bf215546Sopenharmony_ci return; 772bf215546Sopenharmony_ci 773bf215546Sopenharmony_ci _mesa_sha1_final(&ctx, sha1); 774bf215546Sopenharmony_ci disk_cache_format_hex_id(cache_id, sha1, 20 * 2); 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci /* These flags affect shader compilation. */ 777bf215546Sopenharmony_ci uint64_t shader_debug_flags = 778bf215546Sopenharmony_ci rscreen->debug_flags & 779bf215546Sopenharmony_ci (DBG_NIR | 780bf215546Sopenharmony_ci DBG_NIR_PREFERRED | 781bf215546Sopenharmony_ci DBG_USE_TGSI); 782bf215546Sopenharmony_ci 783bf215546Sopenharmony_ci rscreen->disk_shader_cache = 784bf215546Sopenharmony_ci disk_cache_create(r600_get_family_name(rscreen), 785bf215546Sopenharmony_ci cache_id, 786bf215546Sopenharmony_ci shader_debug_flags); 787bf215546Sopenharmony_ci} 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_cistatic struct disk_cache *r600_get_disk_shader_cache(struct pipe_screen *pscreen) 790bf215546Sopenharmony_ci{ 791bf215546Sopenharmony_ci struct r600_common_screen *rscreen = (struct r600_common_screen*)pscreen; 792bf215546Sopenharmony_ci return rscreen->disk_shader_cache; 793bf215546Sopenharmony_ci} 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_cistatic const char* r600_get_name(struct pipe_screen* pscreen) 796bf215546Sopenharmony_ci{ 797bf215546Sopenharmony_ci struct r600_common_screen *rscreen = (struct r600_common_screen*)pscreen; 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_ci return rscreen->renderer_string; 800bf215546Sopenharmony_ci} 801bf215546Sopenharmony_ci 802bf215546Sopenharmony_cistatic float r600_get_paramf(struct pipe_screen* pscreen, 803bf215546Sopenharmony_ci enum pipe_capf param) 804bf215546Sopenharmony_ci{ 805bf215546Sopenharmony_ci switch (param) { 806bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH: 807bf215546Sopenharmony_ci case PIPE_CAPF_MIN_LINE_WIDTH_AA: 808bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE: 809bf215546Sopenharmony_ci case PIPE_CAPF_MIN_POINT_SIZE_AA: 810bf215546Sopenharmony_ci return 1; 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci case PIPE_CAPF_POINT_SIZE_GRANULARITY: 813bf215546Sopenharmony_ci case PIPE_CAPF_LINE_WIDTH_GRANULARITY: 814bf215546Sopenharmony_ci return 0.1; 815bf215546Sopenharmony_ci 816bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH: 817bf215546Sopenharmony_ci case PIPE_CAPF_MAX_LINE_WIDTH_AA: 818bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE: 819bf215546Sopenharmony_ci case PIPE_CAPF_MAX_POINT_SIZE_AA: 820bf215546Sopenharmony_ci return 8191.0f; 821bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: 822bf215546Sopenharmony_ci return 16.0f; 823bf215546Sopenharmony_ci case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: 824bf215546Sopenharmony_ci return 16.0f; 825bf215546Sopenharmony_ci case PIPE_CAPF_MIN_CONSERVATIVE_RASTER_DILATE: 826bf215546Sopenharmony_ci case PIPE_CAPF_MAX_CONSERVATIVE_RASTER_DILATE: 827bf215546Sopenharmony_ci case PIPE_CAPF_CONSERVATIVE_RASTER_DILATE_GRANULARITY: 828bf215546Sopenharmony_ci return 0.0f; 829bf215546Sopenharmony_ci } 830bf215546Sopenharmony_ci return 0.0f; 831bf215546Sopenharmony_ci} 832bf215546Sopenharmony_ci 833bf215546Sopenharmony_cistatic int r600_get_video_param(struct pipe_screen *screen, 834bf215546Sopenharmony_ci enum pipe_video_profile profile, 835bf215546Sopenharmony_ci enum pipe_video_entrypoint entrypoint, 836bf215546Sopenharmony_ci enum pipe_video_cap param) 837bf215546Sopenharmony_ci{ 838bf215546Sopenharmony_ci switch (param) { 839bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_SUPPORTED: 840bf215546Sopenharmony_ci return vl_profile_supported(screen, profile, entrypoint); 841bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_NPOT_TEXTURES: 842bf215546Sopenharmony_ci return 1; 843bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_MAX_WIDTH: 844bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_MAX_HEIGHT: 845bf215546Sopenharmony_ci return vl_video_buffer_max_size(screen); 846bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_PREFERED_FORMAT: 847bf215546Sopenharmony_ci return PIPE_FORMAT_NV12; 848bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_PREFERS_INTERLACED: 849bf215546Sopenharmony_ci return false; 850bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED: 851bf215546Sopenharmony_ci return false; 852bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE: 853bf215546Sopenharmony_ci return true; 854bf215546Sopenharmony_ci case PIPE_VIDEO_CAP_MAX_LEVEL: 855bf215546Sopenharmony_ci return vl_level_supported(screen, profile); 856bf215546Sopenharmony_ci default: 857bf215546Sopenharmony_ci return 0; 858bf215546Sopenharmony_ci } 859bf215546Sopenharmony_ci} 860bf215546Sopenharmony_ci 861bf215546Sopenharmony_ciconst char *r600_get_llvm_processor_name(enum radeon_family family) 862bf215546Sopenharmony_ci{ 863bf215546Sopenharmony_ci switch (family) { 864bf215546Sopenharmony_ci case CHIP_R600: 865bf215546Sopenharmony_ci case CHIP_RV630: 866bf215546Sopenharmony_ci case CHIP_RV635: 867bf215546Sopenharmony_ci case CHIP_RV670: 868bf215546Sopenharmony_ci return "r600"; 869bf215546Sopenharmony_ci case CHIP_RV610: 870bf215546Sopenharmony_ci case CHIP_RV620: 871bf215546Sopenharmony_ci case CHIP_RS780: 872bf215546Sopenharmony_ci case CHIP_RS880: 873bf215546Sopenharmony_ci return "rs880"; 874bf215546Sopenharmony_ci case CHIP_RV710: 875bf215546Sopenharmony_ci return "rv710"; 876bf215546Sopenharmony_ci case CHIP_RV730: 877bf215546Sopenharmony_ci return "rv730"; 878bf215546Sopenharmony_ci case CHIP_RV740: 879bf215546Sopenharmony_ci case CHIP_RV770: 880bf215546Sopenharmony_ci return "rv770"; 881bf215546Sopenharmony_ci case CHIP_PALM: 882bf215546Sopenharmony_ci case CHIP_CEDAR: 883bf215546Sopenharmony_ci return "cedar"; 884bf215546Sopenharmony_ci case CHIP_SUMO: 885bf215546Sopenharmony_ci case CHIP_SUMO2: 886bf215546Sopenharmony_ci return "sumo"; 887bf215546Sopenharmony_ci case CHIP_REDWOOD: 888bf215546Sopenharmony_ci return "redwood"; 889bf215546Sopenharmony_ci case CHIP_JUNIPER: 890bf215546Sopenharmony_ci return "juniper"; 891bf215546Sopenharmony_ci case CHIP_HEMLOCK: 892bf215546Sopenharmony_ci case CHIP_CYPRESS: 893bf215546Sopenharmony_ci return "cypress"; 894bf215546Sopenharmony_ci case CHIP_BARTS: 895bf215546Sopenharmony_ci return "barts"; 896bf215546Sopenharmony_ci case CHIP_TURKS: 897bf215546Sopenharmony_ci return "turks"; 898bf215546Sopenharmony_ci case CHIP_CAICOS: 899bf215546Sopenharmony_ci return "caicos"; 900bf215546Sopenharmony_ci case CHIP_CAYMAN: 901bf215546Sopenharmony_ci case CHIP_ARUBA: 902bf215546Sopenharmony_ci return "cayman"; 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci default: 905bf215546Sopenharmony_ci return ""; 906bf215546Sopenharmony_ci } 907bf215546Sopenharmony_ci} 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_cistatic unsigned get_max_threads_per_block(struct r600_common_screen *screen, 910bf215546Sopenharmony_ci enum pipe_shader_ir ir_type) 911bf215546Sopenharmony_ci{ 912bf215546Sopenharmony_ci if (ir_type != PIPE_SHADER_IR_TGSI && 913bf215546Sopenharmony_ci ir_type != PIPE_SHADER_IR_NIR) 914bf215546Sopenharmony_ci return 256; 915bf215546Sopenharmony_ci if (screen->gfx_level >= EVERGREEN) 916bf215546Sopenharmony_ci return 1024; 917bf215546Sopenharmony_ci return 256; 918bf215546Sopenharmony_ci} 919bf215546Sopenharmony_ci 920bf215546Sopenharmony_cistatic int r600_get_compute_param(struct pipe_screen *screen, 921bf215546Sopenharmony_ci enum pipe_shader_ir ir_type, 922bf215546Sopenharmony_ci enum pipe_compute_cap param, 923bf215546Sopenharmony_ci void *ret) 924bf215546Sopenharmony_ci{ 925bf215546Sopenharmony_ci struct r600_common_screen *rscreen = (struct r600_common_screen *)screen; 926bf215546Sopenharmony_ci 927bf215546Sopenharmony_ci //TODO: select these params by asic 928bf215546Sopenharmony_ci switch (param) { 929bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IR_TARGET: { 930bf215546Sopenharmony_ci const char *gpu; 931bf215546Sopenharmony_ci const char *triple = "r600--"; 932bf215546Sopenharmony_ci gpu = r600_get_llvm_processor_name(rscreen->family); 933bf215546Sopenharmony_ci if (ret) { 934bf215546Sopenharmony_ci sprintf(ret, "%s-%s", gpu, triple); 935bf215546Sopenharmony_ci } 936bf215546Sopenharmony_ci /* +2 for dash and terminating NIL byte */ 937bf215546Sopenharmony_ci return (strlen(triple) + strlen(gpu) + 2) * sizeof(char); 938bf215546Sopenharmony_ci } 939bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_GRID_DIMENSION: 940bf215546Sopenharmony_ci if (ret) { 941bf215546Sopenharmony_ci uint64_t *grid_dimension = ret; 942bf215546Sopenharmony_ci grid_dimension[0] = 3; 943bf215546Sopenharmony_ci } 944bf215546Sopenharmony_ci return 1 * sizeof(uint64_t); 945bf215546Sopenharmony_ci 946bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: 947bf215546Sopenharmony_ci if (ret) { 948bf215546Sopenharmony_ci uint64_t *grid_size = ret; 949bf215546Sopenharmony_ci grid_size[0] = 65535; 950bf215546Sopenharmony_ci grid_size[1] = 65535; 951bf215546Sopenharmony_ci grid_size[2] = 65535; 952bf215546Sopenharmony_ci } 953bf215546Sopenharmony_ci return 3 * sizeof(uint64_t) ; 954bf215546Sopenharmony_ci 955bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: 956bf215546Sopenharmony_ci if (ret) { 957bf215546Sopenharmony_ci uint64_t *block_size = ret; 958bf215546Sopenharmony_ci unsigned threads_per_block = get_max_threads_per_block(rscreen, ir_type); 959bf215546Sopenharmony_ci block_size[0] = threads_per_block; 960bf215546Sopenharmony_ci block_size[1] = threads_per_block; 961bf215546Sopenharmony_ci block_size[2] = threads_per_block; 962bf215546Sopenharmony_ci } 963bf215546Sopenharmony_ci return 3 * sizeof(uint64_t); 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: 966bf215546Sopenharmony_ci if (ret) { 967bf215546Sopenharmony_ci uint64_t *max_threads_per_block = ret; 968bf215546Sopenharmony_ci *max_threads_per_block = get_max_threads_per_block(rscreen, ir_type); 969bf215546Sopenharmony_ci } 970bf215546Sopenharmony_ci return sizeof(uint64_t); 971bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_ADDRESS_BITS: 972bf215546Sopenharmony_ci if (ret) { 973bf215546Sopenharmony_ci uint32_t *address_bits = ret; 974bf215546Sopenharmony_ci address_bits[0] = 32; 975bf215546Sopenharmony_ci } 976bf215546Sopenharmony_ci return 1 * sizeof(uint32_t); 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE: 979bf215546Sopenharmony_ci if (ret) { 980bf215546Sopenharmony_ci uint64_t *max_global_size = ret; 981bf215546Sopenharmony_ci uint64_t max_mem_alloc_size; 982bf215546Sopenharmony_ci 983bf215546Sopenharmony_ci r600_get_compute_param(screen, ir_type, 984bf215546Sopenharmony_ci PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE, 985bf215546Sopenharmony_ci &max_mem_alloc_size); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci /* In OpenCL, the MAX_MEM_ALLOC_SIZE must be at least 988bf215546Sopenharmony_ci * 1/4 of the MAX_GLOBAL_SIZE. Since the 989bf215546Sopenharmony_ci * MAX_MEM_ALLOC_SIZE is fixed for older kernels, 990bf215546Sopenharmony_ci * make sure we never report more than 991bf215546Sopenharmony_ci * 4 * MAX_MEM_ALLOC_SIZE. 992bf215546Sopenharmony_ci */ 993bf215546Sopenharmony_ci *max_global_size = MIN2(4 * max_mem_alloc_size, 994bf215546Sopenharmony_ci rscreen->info.max_heap_size_kb * 1024ull); 995bf215546Sopenharmony_ci } 996bf215546Sopenharmony_ci return sizeof(uint64_t); 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE: 999bf215546Sopenharmony_ci if (ret) { 1000bf215546Sopenharmony_ci uint64_t *max_local_size = ret; 1001bf215546Sopenharmony_ci /* Value reported by the closed source driver. */ 1002bf215546Sopenharmony_ci *max_local_size = 32768; 1003bf215546Sopenharmony_ci } 1004bf215546Sopenharmony_ci return sizeof(uint64_t); 1005bf215546Sopenharmony_ci 1006bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE: 1007bf215546Sopenharmony_ci if (ret) { 1008bf215546Sopenharmony_ci uint64_t *max_input_size = ret; 1009bf215546Sopenharmony_ci /* Value reported by the closed source driver. */ 1010bf215546Sopenharmony_ci *max_input_size = 1024; 1011bf215546Sopenharmony_ci } 1012bf215546Sopenharmony_ci return sizeof(uint64_t); 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE: 1015bf215546Sopenharmony_ci if (ret) { 1016bf215546Sopenharmony_ci uint64_t *max_mem_alloc_size = ret; 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ci *max_mem_alloc_size = (rscreen->info.max_heap_size_kb / 4) * 1024ull; 1019bf215546Sopenharmony_ci } 1020bf215546Sopenharmony_ci return sizeof(uint64_t); 1021bf215546Sopenharmony_ci 1022bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY: 1023bf215546Sopenharmony_ci if (ret) { 1024bf215546Sopenharmony_ci uint32_t *max_clock_frequency = ret; 1025bf215546Sopenharmony_ci *max_clock_frequency = rscreen->info.max_gpu_freq_mhz; 1026bf215546Sopenharmony_ci } 1027bf215546Sopenharmony_ci return sizeof(uint32_t); 1028bf215546Sopenharmony_ci 1029bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: 1030bf215546Sopenharmony_ci if (ret) { 1031bf215546Sopenharmony_ci uint32_t *max_compute_units = ret; 1032bf215546Sopenharmony_ci *max_compute_units = rscreen->info.num_cu; 1033bf215546Sopenharmony_ci } 1034bf215546Sopenharmony_ci return sizeof(uint32_t); 1035bf215546Sopenharmony_ci 1036bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: 1037bf215546Sopenharmony_ci if (ret) { 1038bf215546Sopenharmony_ci uint32_t *images_supported = ret; 1039bf215546Sopenharmony_ci *images_supported = 0; 1040bf215546Sopenharmony_ci } 1041bf215546Sopenharmony_ci return sizeof(uint32_t); 1042bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE: 1043bf215546Sopenharmony_ci break; /* unused */ 1044bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: 1045bf215546Sopenharmony_ci if (ret) { 1046bf215546Sopenharmony_ci uint32_t *subgroup_size = ret; 1047bf215546Sopenharmony_ci *subgroup_size = r600_wavefront_size(rscreen->family); 1048bf215546Sopenharmony_ci } 1049bf215546Sopenharmony_ci return sizeof(uint32_t); 1050bf215546Sopenharmony_ci case PIPE_COMPUTE_CAP_MAX_VARIABLE_THREADS_PER_BLOCK: 1051bf215546Sopenharmony_ci if (ret) { 1052bf215546Sopenharmony_ci uint64_t *max_variable_threads_per_block = ret; 1053bf215546Sopenharmony_ci *max_variable_threads_per_block = 0; 1054bf215546Sopenharmony_ci } 1055bf215546Sopenharmony_ci return sizeof(uint64_t); 1056bf215546Sopenharmony_ci } 1057bf215546Sopenharmony_ci 1058bf215546Sopenharmony_ci fprintf(stderr, "unknown PIPE_COMPUTE_CAP %d\n", param); 1059bf215546Sopenharmony_ci return 0; 1060bf215546Sopenharmony_ci} 1061bf215546Sopenharmony_ci 1062bf215546Sopenharmony_cistatic uint64_t r600_get_timestamp(struct pipe_screen *screen) 1063bf215546Sopenharmony_ci{ 1064bf215546Sopenharmony_ci struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; 1065bf215546Sopenharmony_ci 1066bf215546Sopenharmony_ci return 1000000 * rscreen->ws->query_value(rscreen->ws, RADEON_TIMESTAMP) / 1067bf215546Sopenharmony_ci rscreen->info.clock_crystal_freq; 1068bf215546Sopenharmony_ci} 1069bf215546Sopenharmony_ci 1070bf215546Sopenharmony_cistatic void r600_fence_reference(struct pipe_screen *screen, 1071bf215546Sopenharmony_ci struct pipe_fence_handle **dst, 1072bf215546Sopenharmony_ci struct pipe_fence_handle *src) 1073bf215546Sopenharmony_ci{ 1074bf215546Sopenharmony_ci struct radeon_winsys *ws = ((struct r600_common_screen*)screen)->ws; 1075bf215546Sopenharmony_ci struct r600_multi_fence **rdst = (struct r600_multi_fence **)dst; 1076bf215546Sopenharmony_ci struct r600_multi_fence *rsrc = (struct r600_multi_fence *)src; 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_ci if (pipe_reference(&(*rdst)->reference, &rsrc->reference)) { 1079bf215546Sopenharmony_ci ws->fence_reference(&(*rdst)->gfx, NULL); 1080bf215546Sopenharmony_ci ws->fence_reference(&(*rdst)->sdma, NULL); 1081bf215546Sopenharmony_ci FREE(*rdst); 1082bf215546Sopenharmony_ci } 1083bf215546Sopenharmony_ci *rdst = rsrc; 1084bf215546Sopenharmony_ci} 1085bf215546Sopenharmony_ci 1086bf215546Sopenharmony_cistatic bool r600_fence_finish(struct pipe_screen *screen, 1087bf215546Sopenharmony_ci struct pipe_context *ctx, 1088bf215546Sopenharmony_ci struct pipe_fence_handle *fence, 1089bf215546Sopenharmony_ci uint64_t timeout) 1090bf215546Sopenharmony_ci{ 1091bf215546Sopenharmony_ci struct radeon_winsys *rws = ((struct r600_common_screen*)screen)->ws; 1092bf215546Sopenharmony_ci struct r600_multi_fence *rfence = (struct r600_multi_fence *)fence; 1093bf215546Sopenharmony_ci struct r600_common_context *rctx; 1094bf215546Sopenharmony_ci int64_t abs_timeout = os_time_get_absolute_timeout(timeout); 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_ci ctx = threaded_context_unwrap_sync(ctx); 1097bf215546Sopenharmony_ci rctx = ctx ? (struct r600_common_context*)ctx : NULL; 1098bf215546Sopenharmony_ci 1099bf215546Sopenharmony_ci if (rfence->sdma) { 1100bf215546Sopenharmony_ci if (!rws->fence_wait(rws, rfence->sdma, timeout)) 1101bf215546Sopenharmony_ci return false; 1102bf215546Sopenharmony_ci 1103bf215546Sopenharmony_ci /* Recompute the timeout after waiting. */ 1104bf215546Sopenharmony_ci if (timeout && timeout != PIPE_TIMEOUT_INFINITE) { 1105bf215546Sopenharmony_ci int64_t time = os_time_get_nano(); 1106bf215546Sopenharmony_ci timeout = abs_timeout > time ? abs_timeout - time : 0; 1107bf215546Sopenharmony_ci } 1108bf215546Sopenharmony_ci } 1109bf215546Sopenharmony_ci 1110bf215546Sopenharmony_ci if (!rfence->gfx) 1111bf215546Sopenharmony_ci return true; 1112bf215546Sopenharmony_ci 1113bf215546Sopenharmony_ci /* Flush the gfx IB if it hasn't been flushed yet. */ 1114bf215546Sopenharmony_ci if (rctx && 1115bf215546Sopenharmony_ci rfence->gfx_unflushed.ctx == rctx && 1116bf215546Sopenharmony_ci rfence->gfx_unflushed.ib_index == rctx->num_gfx_cs_flushes) { 1117bf215546Sopenharmony_ci rctx->gfx.flush(rctx, timeout ? 0 : PIPE_FLUSH_ASYNC, NULL); 1118bf215546Sopenharmony_ci rfence->gfx_unflushed.ctx = NULL; 1119bf215546Sopenharmony_ci 1120bf215546Sopenharmony_ci if (!timeout) 1121bf215546Sopenharmony_ci return false; 1122bf215546Sopenharmony_ci 1123bf215546Sopenharmony_ci /* Recompute the timeout after all that. */ 1124bf215546Sopenharmony_ci if (timeout && timeout != PIPE_TIMEOUT_INFINITE) { 1125bf215546Sopenharmony_ci int64_t time = os_time_get_nano(); 1126bf215546Sopenharmony_ci timeout = abs_timeout > time ? abs_timeout - time : 0; 1127bf215546Sopenharmony_ci } 1128bf215546Sopenharmony_ci } 1129bf215546Sopenharmony_ci 1130bf215546Sopenharmony_ci return rws->fence_wait(rws, rfence->gfx, timeout); 1131bf215546Sopenharmony_ci} 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_cistatic void r600_query_memory_info(struct pipe_screen *screen, 1134bf215546Sopenharmony_ci struct pipe_memory_info *info) 1135bf215546Sopenharmony_ci{ 1136bf215546Sopenharmony_ci struct r600_common_screen *rscreen = (struct r600_common_screen*)screen; 1137bf215546Sopenharmony_ci struct radeon_winsys *ws = rscreen->ws; 1138bf215546Sopenharmony_ci unsigned vram_usage, gtt_usage; 1139bf215546Sopenharmony_ci 1140bf215546Sopenharmony_ci info->total_device_memory = rscreen->info.vram_size_kb; 1141bf215546Sopenharmony_ci info->total_staging_memory = rscreen->info.gart_size_kb; 1142bf215546Sopenharmony_ci 1143bf215546Sopenharmony_ci /* The real TTM memory usage is somewhat random, because: 1144bf215546Sopenharmony_ci * 1145bf215546Sopenharmony_ci * 1) TTM delays freeing memory, because it can only free it after 1146bf215546Sopenharmony_ci * fences expire. 1147bf215546Sopenharmony_ci * 1148bf215546Sopenharmony_ci * 2) The memory usage can be really low if big VRAM evictions are 1149bf215546Sopenharmony_ci * taking place, but the real usage is well above the size of VRAM. 1150bf215546Sopenharmony_ci * 1151bf215546Sopenharmony_ci * Instead, return statistics of this process. 1152bf215546Sopenharmony_ci */ 1153bf215546Sopenharmony_ci vram_usage = ws->query_value(ws, RADEON_REQUESTED_VRAM_MEMORY) / 1024; 1154bf215546Sopenharmony_ci gtt_usage = ws->query_value(ws, RADEON_REQUESTED_GTT_MEMORY) / 1024; 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci info->avail_device_memory = 1157bf215546Sopenharmony_ci vram_usage <= info->total_device_memory ? 1158bf215546Sopenharmony_ci info->total_device_memory - vram_usage : 0; 1159bf215546Sopenharmony_ci info->avail_staging_memory = 1160bf215546Sopenharmony_ci gtt_usage <= info->total_staging_memory ? 1161bf215546Sopenharmony_ci info->total_staging_memory - gtt_usage : 0; 1162bf215546Sopenharmony_ci 1163bf215546Sopenharmony_ci info->device_memory_evicted = 1164bf215546Sopenharmony_ci ws->query_value(ws, RADEON_NUM_BYTES_MOVED) / 1024; 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci /* Just return the number of evicted 64KB pages. */ 1167bf215546Sopenharmony_ci info->nr_device_memory_evictions = info->device_memory_evicted / 64; 1168bf215546Sopenharmony_ci} 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_cistruct pipe_resource *r600_resource_create_common(struct pipe_screen *screen, 1171bf215546Sopenharmony_ci const struct pipe_resource *templ) 1172bf215546Sopenharmony_ci{ 1173bf215546Sopenharmony_ci if (templ->target == PIPE_BUFFER) { 1174bf215546Sopenharmony_ci return r600_buffer_create(screen, templ, 256); 1175bf215546Sopenharmony_ci } else { 1176bf215546Sopenharmony_ci return r600_texture_create(screen, templ); 1177bf215546Sopenharmony_ci } 1178bf215546Sopenharmony_ci} 1179bf215546Sopenharmony_ci 1180bf215546Sopenharmony_cistatic const void * 1181bf215546Sopenharmony_cir600_get_compiler_options(struct pipe_screen *screen, 1182bf215546Sopenharmony_ci enum pipe_shader_ir ir, 1183bf215546Sopenharmony_ci enum pipe_shader_type shader) 1184bf215546Sopenharmony_ci{ 1185bf215546Sopenharmony_ci assert(ir == PIPE_SHADER_IR_NIR); 1186bf215546Sopenharmony_ci 1187bf215546Sopenharmony_ci struct r600_common_screen *rscreen = (struct r600_common_screen *)screen; 1188bf215546Sopenharmony_ci 1189bf215546Sopenharmony_ci if (shader != PIPE_SHADER_FRAGMENT) 1190bf215546Sopenharmony_ci return &rscreen->nir_options; 1191bf215546Sopenharmony_ci else 1192bf215546Sopenharmony_ci return &rscreen->nir_options_fs; 1193bf215546Sopenharmony_ci} 1194bf215546Sopenharmony_ci 1195bf215546Sopenharmony_ciextern bool r600_lower_to_scalar_instr_filter(const nir_instr *instr, const void *); 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_cistatic void r600_resource_destroy(struct pipe_screen *screen, 1198bf215546Sopenharmony_ci struct pipe_resource *res) 1199bf215546Sopenharmony_ci{ 1200bf215546Sopenharmony_ci if (res->target == PIPE_BUFFER) { 1201bf215546Sopenharmony_ci if (r600_resource(res)->compute_global_bo) 1202bf215546Sopenharmony_ci r600_compute_global_buffer_destroy(screen, res); 1203bf215546Sopenharmony_ci else 1204bf215546Sopenharmony_ci r600_buffer_destroy(screen, res); 1205bf215546Sopenharmony_ci } else { 1206bf215546Sopenharmony_ci r600_texture_destroy(screen, res); 1207bf215546Sopenharmony_ci } 1208bf215546Sopenharmony_ci} 1209bf215546Sopenharmony_ci 1210bf215546Sopenharmony_cibool r600_common_screen_init(struct r600_common_screen *rscreen, 1211bf215546Sopenharmony_ci struct radeon_winsys *ws) 1212bf215546Sopenharmony_ci{ 1213bf215546Sopenharmony_ci char family_name[32] = {}, kernel_version[128] = {}; 1214bf215546Sopenharmony_ci struct utsname uname_data; 1215bf215546Sopenharmony_ci const char *chip_name; 1216bf215546Sopenharmony_ci 1217bf215546Sopenharmony_ci ws->query_info(ws, &rscreen->info, false, false); 1218bf215546Sopenharmony_ci rscreen->ws = ws; 1219bf215546Sopenharmony_ci 1220bf215546Sopenharmony_ci chip_name = r600_get_family_name(rscreen); 1221bf215546Sopenharmony_ci 1222bf215546Sopenharmony_ci if (uname(&uname_data) == 0) 1223bf215546Sopenharmony_ci snprintf(kernel_version, sizeof(kernel_version), 1224bf215546Sopenharmony_ci " / %s", uname_data.release); 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci snprintf(rscreen->renderer_string, sizeof(rscreen->renderer_string), 1227bf215546Sopenharmony_ci "%s (%sDRM %i.%i.%i%s" 1228bf215546Sopenharmony_ci#ifdef LLVM_AVAILABLE 1229bf215546Sopenharmony_ci ", LLVM " MESA_LLVM_VERSION_STRING 1230bf215546Sopenharmony_ci#endif 1231bf215546Sopenharmony_ci ")", 1232bf215546Sopenharmony_ci chip_name, family_name, rscreen->info.drm_major, 1233bf215546Sopenharmony_ci rscreen->info.drm_minor, rscreen->info.drm_patchlevel, 1234bf215546Sopenharmony_ci kernel_version); 1235bf215546Sopenharmony_ci 1236bf215546Sopenharmony_ci rscreen->b.get_name = r600_get_name; 1237bf215546Sopenharmony_ci rscreen->b.get_vendor = r600_get_vendor; 1238bf215546Sopenharmony_ci rscreen->b.get_device_vendor = r600_get_device_vendor; 1239bf215546Sopenharmony_ci rscreen->b.get_disk_shader_cache = r600_get_disk_shader_cache; 1240bf215546Sopenharmony_ci rscreen->b.get_compute_param = r600_get_compute_param; 1241bf215546Sopenharmony_ci rscreen->b.get_paramf = r600_get_paramf; 1242bf215546Sopenharmony_ci rscreen->b.get_timestamp = r600_get_timestamp; 1243bf215546Sopenharmony_ci rscreen->b.get_compiler_options = r600_get_compiler_options; 1244bf215546Sopenharmony_ci rscreen->b.fence_finish = r600_fence_finish; 1245bf215546Sopenharmony_ci rscreen->b.fence_reference = r600_fence_reference; 1246bf215546Sopenharmony_ci rscreen->b.resource_destroy = r600_resource_destroy; 1247bf215546Sopenharmony_ci rscreen->b.resource_from_user_memory = r600_buffer_from_user_memory; 1248bf215546Sopenharmony_ci rscreen->b.query_memory_info = r600_query_memory_info; 1249bf215546Sopenharmony_ci 1250bf215546Sopenharmony_ci if (rscreen->info.ip[AMD_IP_UVD].num_queues) { 1251bf215546Sopenharmony_ci rscreen->b.get_video_param = rvid_get_video_param; 1252bf215546Sopenharmony_ci rscreen->b.is_video_format_supported = rvid_is_format_supported; 1253bf215546Sopenharmony_ci } else { 1254bf215546Sopenharmony_ci rscreen->b.get_video_param = r600_get_video_param; 1255bf215546Sopenharmony_ci rscreen->b.is_video_format_supported = vl_video_buffer_is_format_supported; 1256bf215546Sopenharmony_ci } 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci r600_init_screen_texture_functions(rscreen); 1259bf215546Sopenharmony_ci r600_init_screen_query_functions(rscreen); 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_ci rscreen->family = rscreen->info.family; 1262bf215546Sopenharmony_ci rscreen->gfx_level = rscreen->info.gfx_level; 1263bf215546Sopenharmony_ci rscreen->debug_flags |= debug_get_flags_option("R600_DEBUG", common_debug_options, 0); 1264bf215546Sopenharmony_ci 1265bf215546Sopenharmony_ci r600_disk_cache_create(rscreen); 1266bf215546Sopenharmony_ci 1267bf215546Sopenharmony_ci slab_create_parent(&rscreen->pool_transfers, sizeof(struct r600_transfer), 64); 1268bf215546Sopenharmony_ci 1269bf215546Sopenharmony_ci rscreen->force_aniso = MIN2(16, debug_get_num_option("R600_TEX_ANISO", -1)); 1270bf215546Sopenharmony_ci if (rscreen->force_aniso >= 0) { 1271bf215546Sopenharmony_ci printf("radeon: Forcing anisotropy filter to %ix\n", 1272bf215546Sopenharmony_ci /* round down to a power of two */ 1273bf215546Sopenharmony_ci 1 << util_logbase2(rscreen->force_aniso)); 1274bf215546Sopenharmony_ci } 1275bf215546Sopenharmony_ci 1276bf215546Sopenharmony_ci (void) mtx_init(&rscreen->aux_context_lock, mtx_plain); 1277bf215546Sopenharmony_ci (void) mtx_init(&rscreen->gpu_load_mutex, mtx_plain); 1278bf215546Sopenharmony_ci 1279bf215546Sopenharmony_ci if (rscreen->debug_flags & DBG_INFO) { 1280bf215546Sopenharmony_ci printf("pci (domain:bus:dev.func): %04x:%02x:%02x.%x\n", 1281bf215546Sopenharmony_ci rscreen->info.pci_domain, rscreen->info.pci_bus, 1282bf215546Sopenharmony_ci rscreen->info.pci_dev, rscreen->info.pci_func); 1283bf215546Sopenharmony_ci printf("pci_id = 0x%x\n", rscreen->info.pci_id); 1284bf215546Sopenharmony_ci printf("family = %i (%s)\n", rscreen->info.family, 1285bf215546Sopenharmony_ci r600_get_family_name(rscreen)); 1286bf215546Sopenharmony_ci printf("gfx_level = %i\n", rscreen->info.gfx_level); 1287bf215546Sopenharmony_ci printf("pte_fragment_size = %u\n", rscreen->info.pte_fragment_size); 1288bf215546Sopenharmony_ci printf("gart_page_size = %u\n", rscreen->info.gart_page_size); 1289bf215546Sopenharmony_ci printf("gart_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.gart_size_kb, 1024)); 1290bf215546Sopenharmony_ci printf("vram_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.vram_size_kb, 1024)); 1291bf215546Sopenharmony_ci printf("vram_vis_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.vram_vis_size_kb, 1024)); 1292bf215546Sopenharmony_ci printf("max_heap_size = %i MB\n", 1293bf215546Sopenharmony_ci (int)DIV_ROUND_UP(rscreen->info.max_heap_size_kb, 1024)); 1294bf215546Sopenharmony_ci printf("min_alloc_size = %u\n", rscreen->info.min_alloc_size); 1295bf215546Sopenharmony_ci printf("has_dedicated_vram = %u\n", rscreen->info.has_dedicated_vram); 1296bf215546Sopenharmony_ci printf("r600_has_virtual_memory = %i\n", rscreen->info.r600_has_virtual_memory); 1297bf215546Sopenharmony_ci printf("gfx_ib_pad_with_type2 = %i\n", rscreen->info.gfx_ib_pad_with_type2); 1298bf215546Sopenharmony_ci printf("ip[AMD_IP_UVD] = %u\n", rscreen->info.ip[AMD_IP_UVD].num_queues); 1299bf215546Sopenharmony_ci printf("ip[AMD_IP_SDMA] = %i\n", rscreen->info.ip[AMD_IP_SDMA].num_queues); 1300bf215546Sopenharmony_ci printf("ip[AMD_IP_COMPUTE] = %u\n", rscreen->info.ip[AMD_IP_COMPUTE].num_queues); 1301bf215546Sopenharmony_ci printf("uvd_fw_version = %u\n", rscreen->info.uvd_fw_version); 1302bf215546Sopenharmony_ci printf("vce_fw_version = %u\n", rscreen->info.vce_fw_version); 1303bf215546Sopenharmony_ci printf("me_fw_version = %i\n", rscreen->info.me_fw_version); 1304bf215546Sopenharmony_ci printf("pfp_fw_version = %i\n", rscreen->info.pfp_fw_version); 1305bf215546Sopenharmony_ci printf("vce_harvest_config = %i\n", rscreen->info.vce_harvest_config); 1306bf215546Sopenharmony_ci printf("clock_crystal_freq = %i\n", rscreen->info.clock_crystal_freq); 1307bf215546Sopenharmony_ci printf("tcc_cache_line_size = %u\n", rscreen->info.tcc_cache_line_size); 1308bf215546Sopenharmony_ci printf("drm = %i.%i.%i\n", rscreen->info.drm_major, 1309bf215546Sopenharmony_ci rscreen->info.drm_minor, rscreen->info.drm_patchlevel); 1310bf215546Sopenharmony_ci printf("has_userptr = %i\n", rscreen->info.has_userptr); 1311bf215546Sopenharmony_ci printf("has_syncobj = %u\n", rscreen->info.has_syncobj); 1312bf215546Sopenharmony_ci 1313bf215546Sopenharmony_ci printf("r600_max_quad_pipes = %i\n", rscreen->info.r600_max_quad_pipes); 1314bf215546Sopenharmony_ci printf("max_gpu_freq_mhz = %i\n", rscreen->info.max_gpu_freq_mhz); 1315bf215546Sopenharmony_ci printf("num_cu = %i\n", rscreen->info.num_cu); 1316bf215546Sopenharmony_ci printf("max_se = %i\n", rscreen->info.max_se); 1317bf215546Sopenharmony_ci printf("max_sh_per_se = %i\n", rscreen->info.max_sa_per_se); 1318bf215546Sopenharmony_ci 1319bf215546Sopenharmony_ci printf("r600_gb_backend_map = %i\n", rscreen->info.r600_gb_backend_map); 1320bf215546Sopenharmony_ci printf("r600_gb_backend_map_valid = %i\n", rscreen->info.r600_gb_backend_map_valid); 1321bf215546Sopenharmony_ci printf("r600_num_banks = %i\n", rscreen->info.r600_num_banks); 1322bf215546Sopenharmony_ci printf("num_render_backends = %i\n", rscreen->info.max_render_backends); 1323bf215546Sopenharmony_ci printf("num_tile_pipes = %i\n", rscreen->info.num_tile_pipes); 1324bf215546Sopenharmony_ci printf("pipe_interleave_bytes = %i\n", rscreen->info.pipe_interleave_bytes); 1325bf215546Sopenharmony_ci printf("enabled_rb_mask = 0x%x\n", rscreen->info.enabled_rb_mask); 1326bf215546Sopenharmony_ci printf("max_alignment = %u\n", (unsigned)rscreen->info.max_alignment); 1327bf215546Sopenharmony_ci } 1328bf215546Sopenharmony_ci 1329bf215546Sopenharmony_ci const struct nir_shader_compiler_options nir_options = { 1330bf215546Sopenharmony_ci .fuse_ffma16 = true, 1331bf215546Sopenharmony_ci .fuse_ffma32 = true, 1332bf215546Sopenharmony_ci .fuse_ffma64 = true, 1333bf215546Sopenharmony_ci .lower_flrp32 = true, 1334bf215546Sopenharmony_ci .lower_flrp64 = true, 1335bf215546Sopenharmony_ci .lower_fdiv = true, 1336bf215546Sopenharmony_ci .lower_isign = true, 1337bf215546Sopenharmony_ci .lower_fsign = true, 1338bf215546Sopenharmony_ci .lower_fmod = true, 1339bf215546Sopenharmony_ci .lower_extract_byte = true, 1340bf215546Sopenharmony_ci .lower_extract_word = true, 1341bf215546Sopenharmony_ci .lower_insert_byte = true, 1342bf215546Sopenharmony_ci .lower_insert_word = true, 1343bf215546Sopenharmony_ci .lower_rotate = true, 1344bf215546Sopenharmony_ci /* due to a bug in the shader compiler, some loops hang 1345bf215546Sopenharmony_ci * if they are not unrolled, see: 1346bf215546Sopenharmony_ci * https://bugs.freedesktop.org/show_bug.cgi?id=86720 1347bf215546Sopenharmony_ci */ 1348bf215546Sopenharmony_ci .max_unroll_iterations = 255, 1349bf215546Sopenharmony_ci .lower_interpolate_at = true, 1350bf215546Sopenharmony_ci .vectorize_io = true, 1351bf215546Sopenharmony_ci .has_umad24 = true, 1352bf215546Sopenharmony_ci .has_umul24 = true, 1353bf215546Sopenharmony_ci .has_fmulz = true, 1354bf215546Sopenharmony_ci .use_interpolated_input_intrinsics = true, 1355bf215546Sopenharmony_ci .has_fsub = true, 1356bf215546Sopenharmony_ci .has_isub = true, 1357bf215546Sopenharmony_ci .lower_iabs = true, 1358bf215546Sopenharmony_ci .lower_uadd_sat = true, 1359bf215546Sopenharmony_ci .lower_usub_sat = true, 1360bf215546Sopenharmony_ci .lower_bitfield_extract = true, 1361bf215546Sopenharmony_ci .lower_bitfield_insert_to_bitfield_select = true, 1362bf215546Sopenharmony_ci .has_fused_comp_and_csel = true, 1363bf215546Sopenharmony_ci .lower_find_msb_to_reverse = true, 1364bf215546Sopenharmony_ci .lower_to_scalar = true, 1365bf215546Sopenharmony_ci .lower_to_scalar_filter = r600_lower_to_scalar_instr_filter, 1366bf215546Sopenharmony_ci .linker_ignore_precision = true, 1367bf215546Sopenharmony_ci .lower_fpow = true, 1368bf215546Sopenharmony_ci .lower_int64_options = ~0 1369bf215546Sopenharmony_ci }; 1370bf215546Sopenharmony_ci 1371bf215546Sopenharmony_ci rscreen->nir_options = nir_options; 1372bf215546Sopenharmony_ci 1373bf215546Sopenharmony_ci if (rscreen->info.family < CHIP_CEDAR) 1374bf215546Sopenharmony_ci rscreen->nir_options.force_indirect_unrolling_sampler = true; 1375bf215546Sopenharmony_ci 1376bf215546Sopenharmony_ci if (rscreen->info.gfx_level < EVERGREEN) { 1377bf215546Sopenharmony_ci /* Pre-EG doesn't have these ALU ops */ 1378bf215546Sopenharmony_ci rscreen->nir_options.lower_bit_count = true; 1379bf215546Sopenharmony_ci rscreen->nir_options.lower_bitfield_reverse = true; 1380bf215546Sopenharmony_ci } 1381bf215546Sopenharmony_ci 1382bf215546Sopenharmony_ci if (rscreen->info.gfx_level < CAYMAN) { 1383bf215546Sopenharmony_ci rscreen->nir_options.lower_doubles_options = nir_lower_fp64_full_software; 1384bf215546Sopenharmony_ci } else { 1385bf215546Sopenharmony_ci rscreen->nir_options.lower_doubles_options = 1386bf215546Sopenharmony_ci nir_lower_ddiv | 1387bf215546Sopenharmony_ci nir_lower_dfloor | 1388bf215546Sopenharmony_ci nir_lower_dceil | 1389bf215546Sopenharmony_ci nir_lower_dmod | 1390bf215546Sopenharmony_ci nir_lower_dsub | 1391bf215546Sopenharmony_ci nir_lower_dtrunc; 1392bf215546Sopenharmony_ci } 1393bf215546Sopenharmony_ci 1394bf215546Sopenharmony_ci if (!(rscreen->debug_flags & DBG_NIR_PREFERRED)) { 1395bf215546Sopenharmony_ci 1396bf215546Sopenharmony_ci rscreen->nir_options.lower_fpow = false; 1397bf215546Sopenharmony_ci /* TGSI is vector, and NIR-to-TGSI doesn't like it when the 1398bf215546Sopenharmony_ci * input vars have been scalarized. 1399bf215546Sopenharmony_ci */ 1400bf215546Sopenharmony_ci rscreen->nir_options.lower_to_scalar = false; 1401bf215546Sopenharmony_ci 1402bf215546Sopenharmony_ci /* NIR-to-TGSI can't do fused integer csel, and it can't just 1403bf215546Sopenharmony_ci * override the flag and get the code lowered back when we ask 1404bf215546Sopenharmony_ci * it to handle it. 1405bf215546Sopenharmony_ci */ 1406bf215546Sopenharmony_ci rscreen->nir_options.has_fused_comp_and_csel = false; 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci /* r600 has a bitfield_select and bitfield_extract opcode 1409bf215546Sopenharmony_ci * (called bfi/bfe), but TGSI's BFI/BFE isn't that. 1410bf215546Sopenharmony_ci */ 1411bf215546Sopenharmony_ci rscreen->nir_options.lower_bitfield_extract = false; 1412bf215546Sopenharmony_ci rscreen->nir_options.lower_bitfield_insert_to_bitfield_select = false; 1413bf215546Sopenharmony_ci 1414bf215546Sopenharmony_ci /* TGSI's ifind is reversed from ours, keep it the TGSI way. */ 1415bf215546Sopenharmony_ci rscreen->nir_options.lower_find_msb_to_reverse = false; 1416bf215546Sopenharmony_ci } else { 1417bf215546Sopenharmony_ci rscreen->nir_options.has_fmulz = true; 1418bf215546Sopenharmony_ci } 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_ci rscreen->nir_options_fs = rscreen->nir_options; 1421bf215546Sopenharmony_ci rscreen->nir_options_fs.lower_all_io_to_temps = true; 1422bf215546Sopenharmony_ci 1423bf215546Sopenharmony_ci return true; 1424bf215546Sopenharmony_ci} 1425bf215546Sopenharmony_ci 1426bf215546Sopenharmony_civoid r600_destroy_common_screen(struct r600_common_screen *rscreen) 1427bf215546Sopenharmony_ci{ 1428bf215546Sopenharmony_ci r600_perfcounters_destroy(rscreen); 1429bf215546Sopenharmony_ci r600_gpu_load_kill_thread(rscreen); 1430bf215546Sopenharmony_ci 1431bf215546Sopenharmony_ci mtx_destroy(&rscreen->gpu_load_mutex); 1432bf215546Sopenharmony_ci mtx_destroy(&rscreen->aux_context_lock); 1433bf215546Sopenharmony_ci rscreen->aux_context->destroy(rscreen->aux_context); 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci slab_destroy_parent(&rscreen->pool_transfers); 1436bf215546Sopenharmony_ci 1437bf215546Sopenharmony_ci disk_cache_destroy(rscreen->disk_shader_cache); 1438bf215546Sopenharmony_ci rscreen->ws->destroy(rscreen->ws); 1439bf215546Sopenharmony_ci FREE(rscreen); 1440bf215546Sopenharmony_ci} 1441bf215546Sopenharmony_ci 1442bf215546Sopenharmony_cibool r600_can_dump_shader(struct r600_common_screen *rscreen, 1443bf215546Sopenharmony_ci unsigned processor) 1444bf215546Sopenharmony_ci{ 1445bf215546Sopenharmony_ci return rscreen->debug_flags & (1 << processor); 1446bf215546Sopenharmony_ci} 1447bf215546Sopenharmony_ci 1448bf215546Sopenharmony_cibool r600_extra_shader_checks(struct r600_common_screen *rscreen, unsigned processor) 1449bf215546Sopenharmony_ci{ 1450bf215546Sopenharmony_ci return (rscreen->debug_flags & DBG_CHECK_IR) || 1451bf215546Sopenharmony_ci r600_can_dump_shader(rscreen, processor); 1452bf215546Sopenharmony_ci} 1453bf215546Sopenharmony_ci 1454bf215546Sopenharmony_civoid r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_resource *dst, 1455bf215546Sopenharmony_ci uint64_t offset, uint64_t size, unsigned value) 1456bf215546Sopenharmony_ci{ 1457bf215546Sopenharmony_ci struct r600_common_context *rctx = (struct r600_common_context*)rscreen->aux_context; 1458bf215546Sopenharmony_ci 1459bf215546Sopenharmony_ci mtx_lock(&rscreen->aux_context_lock); 1460bf215546Sopenharmony_ci rctx->dma_clear_buffer(&rctx->b, dst, offset, size, value); 1461bf215546Sopenharmony_ci rscreen->aux_context->flush(rscreen->aux_context, NULL, 0); 1462bf215546Sopenharmony_ci mtx_unlock(&rscreen->aux_context_lock); 1463bf215546Sopenharmony_ci} 1464