#include "r600_pipe_common.h"
#include "r600_cs.h"
#include "tgsi/tgsi_parse.h"
+#include "util/list.h"
+#include "util/u_draw_quad.h"
#include "util/u_memory.h"
#include "util/u_format_s3tc.h"
#include "util/u_upload_mgr.h"
+#include "os/os_time.h"
#include "vl/vl_decoder.h"
#include "vl/vl_video_buffer.h"
#include "radeon/radeon_video.h"
#include <inttypes.h>
+#ifndef HAVE_LLVM
+#define HAVE_LLVM 0
+#endif
+
+struct r600_multi_fence {
+ struct pipe_reference reference;
+ struct pipe_fence_handle *gfx;
+ struct pipe_fence_handle *sdma;
+};
+
+/*
+ * shader binary helpers.
+ */
+void radeon_shader_binary_init(struct radeon_shader_binary *b)
+{
+ memset(b, 0, sizeof(*b));
+}
+
+void radeon_shader_binary_clean(struct radeon_shader_binary *b)
+{
+ if (!b)
+ return;
+ FREE(b->code);
+ FREE(b->config);
+ FREE(b->rodata);
+ FREE(b->global_symbol_offsets);
+ FREE(b->relocs);
+ FREE(b->disasm_string);
+}
+
/*
* pipe_context
*/
+void r600_draw_rectangle(struct blitter_context *blitter,
+ int x1, int y1, int x2, int y2, float depth,
+ enum blitter_attrib_type type,
+ const union pipe_color_union *attrib)
+{
+ struct r600_common_context *rctx =
+ (struct r600_common_context*)util_blitter_get_pipe(blitter);
+ struct pipe_viewport_state viewport;
+ struct pipe_resource *buf = NULL;
+ unsigned offset = 0;
+ float *vb;
+
+ if (type == UTIL_BLITTER_ATTRIB_TEXCOORD) {
+ util_blitter_draw_rectangle(blitter, x1, y1, x2, y2, depth, type, attrib);
+ return;
+ }
+
+ /* Some operations (like color resolve on r6xx) don't work
+ * with the conventional primitive types.
+ * One that works is PT_RECTLIST, which we use here. */
+
+ /* setup viewport */
+ viewport.scale[0] = 1.0f;
+ viewport.scale[1] = 1.0f;
+ viewport.scale[2] = 1.0f;
+ viewport.translate[0] = 0.0f;
+ viewport.translate[1] = 0.0f;
+ viewport.translate[2] = 0.0f;
+ rctx->b.set_viewport_states(&rctx->b, 0, 1, &viewport);
+
+ /* Upload vertices. The hw rectangle has only 3 vertices,
+ * I guess the 4th one is derived from the first 3.
+ * The vertex specification should match u_blitter's vertex element state. */
+ u_upload_alloc(rctx->uploader, 0, sizeof(float) * 24, 256, &offset, &buf, (void**)&vb);
+ if (!buf)
+ return;
+
+ vb[0] = x1;
+ vb[1] = y1;
+ vb[2] = depth;
+ vb[3] = 1;
+
+ vb[8] = x1;
+ vb[9] = y2;
+ vb[10] = depth;
+ vb[11] = 1;
+
+ vb[16] = x2;
+ vb[17] = y1;
+ vb[18] = depth;
+ vb[19] = 1;
+
+ if (attrib) {
+ memcpy(vb+4, attrib->f, sizeof(float)*4);
+ memcpy(vb+12, attrib->f, sizeof(float)*4);
+ memcpy(vb+20, attrib->f, sizeof(float)*4);
+ }
+
+ /* draw */
+ util_draw_vertex_buffer(&rctx->b, NULL, buf, blitter->vb_slot, offset,
+ R600_PRIM_RECTANGLE_LIST, 3, 2);
+ pipe_resource_reference(&buf, NULL);
+}
+
void r600_need_dma_space(struct r600_common_context *ctx, unsigned num_dw)
{
- /* The number of dwords we already used in the DMA so far. */
- num_dw += ctx->rings.dma.cs->cdw;
+ /* Flush the GFX IB if it's not empty. */
+ if (ctx->gfx.cs->cdw > ctx->initial_gfx_cs_size)
+ ctx->gfx.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
+
/* Flush if there's not enough space. */
- if (num_dw > RADEON_MAX_CMDBUF_DWORDS) {
- ctx->rings.dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
+ if ((num_dw + ctx->dma.cs->cdw) > ctx->dma.cs->max_dw) {
+ ctx->dma.flush(ctx, RADEON_FLUSH_ASYNC, NULL);
+ assert((num_dw + ctx->dma.cs->cdw) <= ctx->dma.cs->max_dw);
}
}
void r600_preflush_suspend_features(struct r600_common_context *ctx)
{
- /* Disable render condition. */
- ctx->saved_render_cond = NULL;
- ctx->saved_render_cond_cond = FALSE;
- ctx->saved_render_cond_mode = 0;
- if (ctx->current_render_cond) {
- ctx->saved_render_cond = ctx->current_render_cond;
- ctx->saved_render_cond_cond = ctx->current_render_cond_cond;
- ctx->saved_render_cond_mode = ctx->current_render_cond_mode;
- ctx->b.render_condition(&ctx->b, NULL, FALSE, 0);
- }
-
/* suspend queries */
- ctx->nontimer_queries_suspended = false;
if (ctx->num_cs_dw_nontimer_queries_suspend) {
+ /* Since non-timer queries are suspended during blits,
+ * we have to guard against double-suspends. */
r600_suspend_nontimer_queries(ctx);
- ctx->nontimer_queries_suspended = true;
+ ctx->nontimer_queries_suspended_by_flush = true;
}
+ if (!LIST_IS_EMPTY(&ctx->active_timer_queries))
+ r600_suspend_timer_queries(ctx);
ctx->streamout.suspended = false;
if (ctx->streamout.begin_emitted) {
}
/* resume queries */
- if (ctx->nontimer_queries_suspended) {
+ if (!LIST_IS_EMPTY(&ctx->active_timer_queries))
+ r600_resume_timer_queries(ctx);
+ if (ctx->nontimer_queries_suspended_by_flush) {
+ ctx->nontimer_queries_suspended_by_flush = false;
r600_resume_nontimer_queries(ctx);
}
-
- /* Re-enable render condition. */
- if (ctx->saved_render_cond) {
- ctx->b.render_condition(&ctx->b, ctx->saved_render_cond,
- ctx->saved_render_cond_cond,
- ctx->saved_render_cond_mode);
- }
}
static void r600_flush_from_st(struct pipe_context *ctx,
struct pipe_fence_handle **fence,
unsigned flags)
{
+ struct pipe_screen *screen = ctx->screen;
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
unsigned rflags = 0;
+ struct pipe_fence_handle *gfx_fence = NULL;
+ struct pipe_fence_handle *sdma_fence = NULL;
if (flags & PIPE_FLUSH_END_OF_FRAME)
rflags |= RADEON_FLUSH_END_OF_FRAME;
- if (rctx->rings.dma.cs) {
- rctx->rings.dma.flush(rctx, rflags, NULL);
+ if (rctx->dma.cs) {
+ rctx->dma.flush(rctx, rflags, fence ? &sdma_fence : NULL);
+ }
+ rctx->gfx.flush(rctx, rflags, fence ? &gfx_fence : NULL);
+
+ /* Both engines can signal out of order, so we need to keep both fences. */
+ if (gfx_fence || sdma_fence) {
+ struct r600_multi_fence *multi_fence =
+ CALLOC_STRUCT(r600_multi_fence);
+ if (!multi_fence)
+ return;
+
+ multi_fence->reference.count = 1;
+ multi_fence->gfx = gfx_fence;
+ multi_fence->sdma = sdma_fence;
+
+ screen->fence_reference(screen, fence, NULL);
+ *fence = (struct pipe_fence_handle*)multi_fence;
}
- rctx->rings.gfx.flush(rctx, rflags, fence);
}
static void r600_flush_dma_ring(void *ctx, unsigned flags,
struct pipe_fence_handle **fence)
{
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
- struct radeon_winsys_cs *cs = rctx->rings.dma.cs;
+ struct radeon_winsys_cs *cs = rctx->dma.cs;
- if (!cs->cdw) {
- return;
- }
+ if (cs->cdw)
+ rctx->ws->cs_flush(cs, flags, &rctx->last_sdma_fence, 0);
+ if (fence)
+ rctx->ws->fence_reference(fence, rctx->last_sdma_fence);
+}
+
+static enum pipe_reset_status r600_get_reset_status(struct pipe_context *ctx)
+{
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+ unsigned latest = rctx->ws->query_value(rctx->ws,
+ RADEON_GPU_RESET_COUNTER);
+
+ if (rctx->gpu_reset_counter == latest)
+ return PIPE_NO_RESET;
- rctx->rings.dma.flushing = true;
- rctx->ws->cs_flush(cs, flags, fence, 0);
- rctx->rings.dma.flushing = false;
+ rctx->gpu_reset_counter = latest;
+ return PIPE_UNKNOWN_CONTEXT_RESET;
+}
+
+static void r600_set_debug_callback(struct pipe_context *ctx,
+ const struct pipe_debug_callback *cb)
+{
+ struct r600_common_context *rctx = (struct r600_common_context *)ctx;
+
+ if (cb)
+ rctx->debug = *cb;
+ else
+ memset(&rctx->debug, 0, sizeof(rctx->debug));
}
bool r600_common_context_init(struct r600_common_context *rctx,
rctx->family = rscreen->family;
rctx->chip_class = rscreen->chip_class;
- if (rscreen->family == CHIP_HAWAII)
- rctx->max_db = 16;
+ if (rscreen->chip_class >= CIK)
+ rctx->max_db = MAX2(8, rscreen->info.num_render_backends);
else if (rscreen->chip_class >= EVERGREEN)
rctx->max_db = 8;
else
rctx->max_db = 4;
+ rctx->b.invalidate_resource = r600_invalidate_resource;
rctx->b.transfer_map = u_transfer_map_vtbl;
- rctx->b.transfer_flush_region = u_default_transfer_flush_region;
+ rctx->b.transfer_flush_region = u_transfer_flush_region_vtbl;
rctx->b.transfer_unmap = u_transfer_unmap_vtbl;
rctx->b.transfer_inline_write = u_default_transfer_inline_write;
rctx->b.memory_barrier = r600_memory_barrier;
rctx->b.flush = r600_flush_from_st;
+ rctx->b.set_debug_callback = r600_set_debug_callback;
+
+ if (rscreen->info.drm_major == 2 && rscreen->info.drm_minor >= 43) {
+ rctx->b.get_device_reset_status = r600_get_reset_status;
+ rctx->gpu_reset_counter =
+ rctx->ws->query_value(rctx->ws,
+ RADEON_GPU_RESET_COUNTER);
+ }
LIST_INITHEAD(&rctx->texture_buffers);
if (!rctx->allocator_so_filled_size)
return false;
- rctx->uploader = u_upload_create(&rctx->b, 1024 * 1024, 256,
+ rctx->uploader = u_upload_create(&rctx->b, 1024 * 1024,
PIPE_BIND_INDEX_BUFFER |
- PIPE_BIND_CONSTANT_BUFFER);
+ PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM);
if (!rctx->uploader)
return false;
- if (rscreen->info.r600_has_dma && !(rscreen->debug_flags & DBG_NO_ASYNC_DMA)) {
- rctx->rings.dma.cs = rctx->ws->cs_create(rctx->ws, RING_DMA,
- r600_flush_dma_ring,
- rctx, NULL);
- rctx->rings.dma.flush = r600_flush_dma_ring;
+ rctx->ctx = rctx->ws->ctx_create(rctx->ws);
+ if (!rctx->ctx)
+ return false;
+
+ if (rscreen->info.has_sdma && !(rscreen->debug_flags & DBG_NO_ASYNC_DMA)) {
+ rctx->dma.cs = rctx->ws->cs_create(rctx->ctx, RING_DMA,
+ r600_flush_dma_ring,
+ rctx, NULL);
+ rctx->dma.flush = r600_flush_dma_ring;
}
return true;
void r600_common_context_cleanup(struct r600_common_context *rctx)
{
- if (rctx->rings.gfx.cs) {
- rctx->ws->cs_destroy(rctx->rings.gfx.cs);
- }
- if (rctx->rings.dma.cs) {
- rctx->ws->cs_destroy(rctx->rings.dma.cs);
- }
+ if (rctx->gfx.cs)
+ rctx->ws->cs_destroy(rctx->gfx.cs);
+ if (rctx->dma.cs)
+ rctx->ws->cs_destroy(rctx->dma.cs);
+ if (rctx->ctx)
+ rctx->ws->ctx_destroy(rctx->ctx);
if (rctx->uploader) {
u_upload_destroy(rctx->uploader);
if (rctx->allocator_so_filled_size) {
u_suballocator_destroy(rctx->allocator_so_filled_size);
}
+ rctx->ws->fence_reference(&rctx->last_sdma_fence, NULL);
}
void r600_context_add_resource_size(struct pipe_context *ctx, struct pipe_resource *r)
struct r600_common_context *rctx = (struct r600_common_context *)ctx;
struct r600_resource *rr = (struct r600_resource *)r;
- if (r == NULL) {
+ if (!r) {
return;
}
static const struct debug_named_value common_debug_options[] = {
/* logging */
{ "tex", DBG_TEX, "Print texture info" },
- { "texmip", DBG_TEXMIP, "Print texture info (mipmapped only)" },
{ "compute", DBG_COMPUTE, "Print compute info" },
{ "vm", DBG_VM, "Print virtual addresses when creating resources" },
{ "trace_cs", DBG_TRACE_CS, "Trace cs and write rlockup_<csid>.c file with faulty cs" },
+ { "info", DBG_INFO, "Print driver information" },
/* shaders */
{ "fs", DBG_FS, "Print fetch shaders" },
{ "gs", DBG_GS, "Print geometry shaders" },
{ "ps", DBG_PS, "Print pixel shaders" },
{ "cs", DBG_CS, "Print compute shaders" },
+ { "tcs", DBG_TCS, "Print tessellation control shaders" },
+ { "tes", DBG_TES, "Print tessellation evaluation shaders" },
+ { "noir", DBG_NO_IR, "Don't print the LLVM IR"},
+ { "notgsi", DBG_NO_TGSI, "Don't print the TGSI"},
+ { "noasm", DBG_NO_ASM, "Don't print disassembled shaders"},
+ { "preoptir", DBG_PREOPT_IR, "Print the LLVM IR before initial optimizations" },
/* features */
{ "nodma", DBG_NO_ASYNC_DMA, "Disable asynchronous DMA" },
- { "hyperz", DBG_HYPERZ, "Enable Hyper-Z" },
+ { "nohyperz", DBG_NO_HYPERZ, "Disable Hyper-Z" },
/* GL uses the word INVALIDATE, gallium uses the word DISCARD */
{ "noinvalrange", DBG_NO_DISCARD_RANGE, "Disable handling of INVALIDATE_RANGE map flags" },
{ "no2d", DBG_NO_2D_TILING, "Disable 2D tiling" },
{ "notiling", DBG_NO_TILING, "Disable tiling" },
{ "switch_on_eop", DBG_SWITCH_ON_EOP, "Program WD/IA to switch on end-of-packet." },
+ { "forcedma", DBG_FORCE_DMA, "Use asynchronous DMA for all operations when possible." },
+ { "precompile", DBG_PRECOMPILE, "Compile one shader variant at shader creation." },
+ { "nowc", DBG_NO_WC, "Disable GTT write combining" },
+ { "check_vm", DBG_CHECK_VM, "Check VM faults and dump debug info." },
+ { "nodcc", DBG_NO_DCC, "Disable DCC." },
+ { "nodccclear", DBG_NO_DCC_CLEAR, "Disable DCC fast clear." },
+ { "norbplus", DBG_NO_RB_PLUS, "Disable RB+ on Stoney." },
+ { "sisched", DBG_SI_SCHED, "Enable LLVM SI Machine Instruction Scheduler." },
DEBUG_NAMED_VALUE_END /* must be last */
};
return "X.Org";
}
-static const char* r600_get_name(struct pipe_screen* pscreen)
+static const char* r600_get_device_vendor(struct pipe_screen* pscreen)
{
- struct r600_common_screen *rscreen = (struct r600_common_screen*)pscreen;
+ return "AMD";
+}
- switch (rscreen->family) {
+static const char* r600_get_chip_name(struct r600_common_screen *rscreen)
+{
+ switch (rscreen->info.family) {
case CHIP_R600: return "AMD R600";
case CHIP_RV610: return "AMD RV610";
case CHIP_RV630: return "AMD RV630";
case CHIP_KABINI: return "AMD KABINI";
case CHIP_HAWAII: return "AMD HAWAII";
case CHIP_MULLINS: return "AMD MULLINS";
+ case CHIP_TONGA: return "AMD TONGA";
+ case CHIP_ICELAND: return "AMD ICELAND";
+ case CHIP_CARRIZO: return "AMD CARRIZO";
+ case CHIP_FIJI: return "AMD FIJI";
+ case CHIP_STONEY: return "AMD STONEY";
default: return "AMD unknown";
}
}
+static const char* r600_get_name(struct pipe_screen* pscreen)
+{
+ struct r600_common_screen *rscreen = (struct r600_common_screen*)pscreen;
+
+ return rscreen->renderer_string;
+}
+
static float r600_get_paramf(struct pipe_screen* pscreen,
enum pipe_capf param)
{
case CHIP_KAVERI: return "kaveri";
case CHIP_HAWAII: return "hawaii";
case CHIP_MULLINS:
-#if HAVE_LLVM >= 0x0305
return "mullins";
+ case CHIP_TONGA: return "tonga";
+ case CHIP_ICELAND: return "iceland";
+ case CHIP_CARRIZO: return "carrizo";
+#if HAVE_LLVM <= 0x0307
+ case CHIP_FIJI: return "tonga";
+ case CHIP_STONEY: return "carrizo";
#else
- return "kabini";
+ case CHIP_FIJI: return "fiji";
+ case CHIP_STONEY: return "stoney";
#endif
default: return "";
}
//TODO: select these params by asic
switch (param) {
case PIPE_COMPUTE_CAP_IR_TARGET: {
- const char *gpu = r600_get_llvm_processor_name(rscreen->family);
+ const char *gpu;
+ const char *triple;
+ if (rscreen->family <= CHIP_ARUBA || HAVE_LLVM < 0x0306) {
+ triple = "r600--";
+ } else {
+ triple = "amdgcn--";
+ }
+ switch(rscreen->family) {
+ /* Clang < 3.6 is missing Hainan in its list of
+ * GPUs, so we need to use the name of a similar GPU.
+ */
+#if HAVE_LLVM < 0x0306
+ case CHIP_HAINAN:
+ gpu = "oland";
+ break;
+#endif
+ default:
+ gpu = r600_get_llvm_processor_name(rscreen->family);
+ break;
+ }
if (ret) {
- sprintf(ret, "%s-r600--", gpu);
+ sprintf(ret, "%s-%s", gpu, triple);
}
- return (8 + strlen(gpu)) * sizeof(char);
+ /* +2 for dash and terminating NIL byte */
+ return (strlen(triple) + strlen(gpu) + 2) * sizeof(char);
}
case PIPE_COMPUTE_CAP_GRID_DIMENSION:
if (ret) {
case PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE:
if (ret) {
- uint64_t max_global_size;
uint64_t *max_mem_alloc_size = ret;
/* XXX: The limit in older kernels is 256 MB. We
case PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY:
if (ret) {
uint32_t *max_clock_frequency = ret;
- *max_clock_frequency = rscreen->info.max_sclk;
+ *max_clock_frequency = rscreen->info.max_shader_clock;
}
return sizeof(uint32_t);
case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS:
if (ret) {
uint32_t *max_compute_units = ret;
- *max_compute_units = MAX2(rscreen->info.max_compute_units, 1);
+ *max_compute_units = rscreen->info.num_good_compute_units;
}
return sizeof(uint32_t);
*images_supported = 0;
}
return sizeof(uint32_t);
+ case PIPE_COMPUTE_CAP_MAX_PRIVATE_SIZE:
+ break; /* unused */
+ case PIPE_COMPUTE_CAP_SUBGROUP_SIZE:
+ if (ret) {
+ uint32_t *subgroup_size = ret;
+ *subgroup_size = r600_wavefront_size(rscreen->family);
+ }
+ return sizeof(uint32_t);
}
fprintf(stderr, "unknown PIPE_COMPUTE_CAP %d\n", param);
struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
return 1000000 * rscreen->ws->query_value(rscreen->ws, RADEON_TIMESTAMP) /
- rscreen->info.r600_clock_crystal_freq;
-}
-
-static int r600_get_driver_query_info(struct pipe_screen *screen,
- unsigned index,
- struct pipe_driver_query_info *info)
-{
- struct r600_common_screen *rscreen = (struct r600_common_screen*)screen;
- struct pipe_driver_query_info list[] = {
- {"draw-calls", R600_QUERY_DRAW_CALLS, 0},
- {"requested-VRAM", R600_QUERY_REQUESTED_VRAM, rscreen->info.vram_size, TRUE},
- {"requested-GTT", R600_QUERY_REQUESTED_GTT, rscreen->info.gart_size, TRUE},
- {"buffer-wait-time", R600_QUERY_BUFFER_WAIT_TIME, 0, FALSE},
- {"num-cs-flushes", R600_QUERY_NUM_CS_FLUSHES, 0, FALSE},
- {"num-bytes-moved", R600_QUERY_NUM_BYTES_MOVED, 0, TRUE},
- {"VRAM-usage", R600_QUERY_VRAM_USAGE, rscreen->info.vram_size, TRUE},
- {"GTT-usage", R600_QUERY_GTT_USAGE, rscreen->info.gart_size, TRUE},
- };
-
- if (!info)
- return Elements(list);
-
- if (index >= Elements(list))
- return 0;
-
- *info = list[index];
- return 1;
+ rscreen->info.clock_crystal_freq;
}
static void r600_fence_reference(struct pipe_screen *screen,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- struct radeon_winsys *rws = ((struct r600_common_screen*)screen)->ws;
-
- rws->fence_reference(ptr, fence);
-}
-
-static boolean r600_fence_signalled(struct pipe_screen *screen,
- struct pipe_fence_handle *fence)
+ struct pipe_fence_handle **dst,
+ struct pipe_fence_handle *src)
{
- struct radeon_winsys *rws = ((struct r600_common_screen*)screen)->ws;
-
- return rws->fence_wait(rws, fence, 0);
+ struct radeon_winsys *ws = ((struct r600_common_screen*)screen)->ws;
+ struct r600_multi_fence **rdst = (struct r600_multi_fence **)dst;
+ struct r600_multi_fence *rsrc = (struct r600_multi_fence *)src;
+
+ if (pipe_reference(&(*rdst)->reference, &rsrc->reference)) {
+ ws->fence_reference(&(*rdst)->gfx, NULL);
+ ws->fence_reference(&(*rdst)->sdma, NULL);
+ FREE(*rdst);
+ }
+ *rdst = rsrc;
}
static boolean r600_fence_finish(struct pipe_screen *screen,
uint64_t timeout)
{
struct radeon_winsys *rws = ((struct r600_common_screen*)screen)->ws;
+ struct r600_multi_fence *rfence = (struct r600_multi_fence *)fence;
+ int64_t abs_timeout = os_time_get_absolute_timeout(timeout);
+
+ if (rfence->sdma) {
+ if (!rws->fence_wait(rws, rfence->sdma, timeout))
+ return false;
- return rws->fence_wait(rws, fence, timeout);
+ /* Recompute the timeout after waiting. */
+ if (timeout && timeout != PIPE_TIMEOUT_INFINITE) {
+ int64_t time = os_time_get_nano();
+ timeout = abs_timeout > time ? abs_timeout - time : 0;
+ }
+ }
+
+ if (!rfence->gfx)
+ return true;
+
+ return rws->fence_wait(rws, rfence->gfx, timeout);
}
static bool r600_interpret_tiling(struct r600_common_screen *rscreen,
uint32_t tiling_config)
{
- switch ((tiling_config & 0xe) >> 1) {
- case 0:
- rscreen->tiling_info.num_channels = 1;
- break;
- case 1:
- rscreen->tiling_info.num_channels = 2;
- break;
- case 2:
- rscreen->tiling_info.num_channels = 4;
- break;
- case 3:
- rscreen->tiling_info.num_channels = 8;
- break;
- default:
- return false;
- }
-
switch ((tiling_config & 0x30) >> 4) {
case 0:
rscreen->tiling_info.num_banks = 4;
static bool evergreen_interpret_tiling(struct r600_common_screen *rscreen,
uint32_t tiling_config)
{
- switch (tiling_config & 0xf) {
- case 0:
- rscreen->tiling_info.num_channels = 1;
- break;
- case 1:
- rscreen->tiling_info.num_channels = 2;
- break;
- case 2:
- rscreen->tiling_info.num_channels = 4;
- break;
- case 3:
- rscreen->tiling_info.num_channels = 8;
- break;
- default:
- return false;
- }
-
switch ((tiling_config & 0xf0) >> 4) {
case 0:
rscreen->tiling_info.num_banks = 4;
bool r600_common_screen_init(struct r600_common_screen *rscreen,
struct radeon_winsys *ws)
{
+ char llvm_string[32] = {};
+
ws->query_info(ws, &rscreen->info);
+#if HAVE_LLVM
+ snprintf(llvm_string, sizeof(llvm_string),
+ ", LLVM %i.%i.%i", (HAVE_LLVM >> 8) & 0xff,
+ HAVE_LLVM & 0xff, MESA_LLVM_VERSION_PATCH);
+#endif
+
+ snprintf(rscreen->renderer_string, sizeof(rscreen->renderer_string),
+ "%s (DRM %i.%i.%i%s)",
+ r600_get_chip_name(rscreen), rscreen->info.drm_major,
+ rscreen->info.drm_minor, rscreen->info.drm_patchlevel,
+ llvm_string);
+
rscreen->b.get_name = r600_get_name;
rscreen->b.get_vendor = r600_get_vendor;
+ rscreen->b.get_device_vendor = r600_get_device_vendor;
rscreen->b.get_compute_param = r600_get_compute_param;
rscreen->b.get_paramf = r600_get_paramf;
- rscreen->b.get_driver_query_info = r600_get_driver_query_info;
rscreen->b.get_timestamp = r600_get_timestamp;
rscreen->b.fence_finish = r600_fence_finish;
rscreen->b.fence_reference = r600_fence_reference;
- rscreen->b.fence_signalled = r600_fence_signalled;
rscreen->b.resource_destroy = u_resource_destroy_vtbl;
+ rscreen->b.resource_from_user_memory = r600_buffer_from_user_memory;
if (rscreen->info.has_uvd) {
rscreen->b.get_video_param = rvid_get_video_param;
}
r600_init_screen_texture_functions(rscreen);
+ r600_init_screen_query_functions(rscreen);
rscreen->ws = ws;
rscreen->family = rscreen->info.family;
}
util_format_s3tc_init();
pipe_mutex_init(rscreen->aux_context_lock);
+ pipe_mutex_init(rscreen->gpu_load_mutex);
- if (rscreen->info.drm_minor >= 28 && (rscreen->debug_flags & DBG_TRACE_CS)) {
+ if (((rscreen->info.drm_major == 2 && rscreen->info.drm_minor >= 28) ||
+ rscreen->info.drm_major == 3) &&
+ (rscreen->debug_flags & DBG_TRACE_CS)) {
rscreen->trace_bo = (struct r600_resource*)pipe_buffer_create(&rscreen->b,
PIPE_BIND_CUSTOM,
PIPE_USAGE_STAGING,
4096);
if (rscreen->trace_bo) {
- rscreen->trace_ptr = rscreen->ws->buffer_map(rscreen->trace_bo->cs_buf, NULL,
+ rscreen->trace_ptr = rscreen->ws->buffer_map(rscreen->trace_bo->buf, NULL,
PIPE_TRANSFER_UNSYNCHRONIZED);
}
}
+ if (rscreen->debug_flags & DBG_INFO) {
+ printf("pci_id = 0x%x\n", rscreen->info.pci_id);
+ printf("family = %i (%s)\n", rscreen->info.family,
+ r600_get_chip_name(rscreen));
+ printf("chip_class = %i\n", rscreen->info.chip_class);
+ printf("gart_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.gart_size, 1024*1024));
+ printf("vram_size = %i MB\n", (int)DIV_ROUND_UP(rscreen->info.vram_size, 1024*1024));
+ printf("has_virtual_memory = %i\n", rscreen->info.has_virtual_memory);
+ printf("gfx_ib_pad_with_type2 = %i\n", rscreen->info.gfx_ib_pad_with_type2);
+ printf("has_sdma = %i\n", rscreen->info.has_sdma);
+ printf("has_uvd = %i\n", rscreen->info.has_uvd);
+ printf("vce_fw_version = %i\n", rscreen->info.vce_fw_version);
+ printf("vce_harvest_config = %i\n", rscreen->info.vce_harvest_config);
+ printf("clock_crystal_freq = %i\n", rscreen->info.clock_crystal_freq);
+ printf("drm = %i.%i.%i\n", rscreen->info.drm_major,
+ rscreen->info.drm_minor, rscreen->info.drm_patchlevel);
+ printf("has_userptr = %i\n", rscreen->info.has_userptr);
+
+ printf("r600_max_quad_pipes = %i\n", rscreen->info.r600_max_quad_pipes);
+ printf("max_shader_clock = %i\n", rscreen->info.max_shader_clock);
+ printf("num_good_compute_units = %i\n", rscreen->info.num_good_compute_units);
+ printf("max_se = %i\n", rscreen->info.max_se);
+ printf("max_sh_per_se = %i\n", rscreen->info.max_sh_per_se);
+
+ printf("r600_gb_backend_map = %i\n", rscreen->info.r600_gb_backend_map);
+ printf("r600_gb_backend_map_valid = %i\n", rscreen->info.r600_gb_backend_map_valid);
+ printf("r600_tiling_config = 0x%x\n", rscreen->info.r600_tiling_config);
+ printf("num_render_backends = %i\n", rscreen->info.num_render_backends);
+ printf("num_tile_pipes = %i\n", rscreen->info.num_tile_pipes);
+ printf("si_tile_mode_array_valid = %i\n", rscreen->info.si_tile_mode_array_valid);
+ printf("cik_macrotile_mode_array_valid = %i\n", rscreen->info.cik_macrotile_mode_array_valid);
+ }
return true;
}
void r600_destroy_common_screen(struct r600_common_screen *rscreen)
{
+ r600_perfcounters_destroy(rscreen);
+ r600_gpu_load_kill_thread(rscreen);
+
+ pipe_mutex_destroy(rscreen->gpu_load_mutex);
pipe_mutex_destroy(rscreen->aux_context_lock);
rscreen->aux_context->destroy(rscreen->aux_context);
- if (rscreen->trace_bo) {
- rscreen->ws->buffer_unmap(rscreen->trace_bo->cs_buf);
+ if (rscreen->trace_bo)
pipe_resource_reference((struct pipe_resource**)&rscreen->trace_bo, NULL);
- }
rscreen->ws->destroy(rscreen->ws);
FREE(rscreen);
}
-static unsigned tgsi_get_processor_type(const struct tgsi_token *tokens)
-{
- struct tgsi_parse_context parse;
-
- if (tgsi_parse_init( &parse, tokens ) != TGSI_PARSE_OK) {
- debug_printf("tgsi_parse_init() failed in %s:%i!\n", __func__, __LINE__);
- return ~0;
- }
- return parse.FullHeader.Processor.Processor;
-}
-
bool r600_can_dump_shader(struct r600_common_screen *rscreen,
- const struct tgsi_token *tokens)
+ unsigned processor)
{
- /* Compute shader don't have tgsi_tokens */
- if (!tokens)
- return (rscreen->debug_flags & DBG_CS) != 0;
-
- switch (tgsi_get_processor_type(tokens)) {
+ switch (processor) {
case TGSI_PROCESSOR_VERTEX:
return (rscreen->debug_flags & DBG_VS) != 0;
+ case TGSI_PROCESSOR_TESS_CTRL:
+ return (rscreen->debug_flags & DBG_TCS) != 0;
+ case TGSI_PROCESSOR_TESS_EVAL:
+ return (rscreen->debug_flags & DBG_TES) != 0;
case TGSI_PROCESSOR_GEOMETRY:
return (rscreen->debug_flags & DBG_GS) != 0;
case TGSI_PROCESSOR_FRAGMENT:
}
void r600_screen_clear_buffer(struct r600_common_screen *rscreen, struct pipe_resource *dst,
- unsigned offset, unsigned size, unsigned value)
+ unsigned offset, unsigned size, unsigned value,
+ bool is_framebuffer)
{
struct r600_common_context *rctx = (struct r600_common_context*)rscreen->aux_context;
pipe_mutex_lock(rscreen->aux_context_lock);
- rctx->clear_buffer(&rctx->b, dst, offset, size, value);
+ rctx->clear_buffer(&rctx->b, dst, offset, size, value, is_framebuffer);
rscreen->aux_context->flush(rscreen->aux_context, NULL, 0);
pipe_mutex_unlock(rscreen->aux_context_lock);
}