struct compute_memory_pool* pool = (struct compute_memory_pool*)
CALLOC(sizeof(struct compute_memory_pool), 1);
- COMPUTE_DBG("* compute_memory_pool_new()\n");
+ COMPUTE_DBG(rscreen, "* compute_memory_pool_new()\n");
pool->screen = rscreen;
return pool;
unsigned initial_size_in_dw)
{
- COMPUTE_DBG("* compute_memory_pool_init() initial_size_in_dw = %ld\n",
+ COMPUTE_DBG(pool->screen, "* compute_memory_pool_init() initial_size_in_dw = %ld\n",
initial_size_in_dw);
pool->shadow = (uint32_t*)CALLOC(initial_size_in_dw, 4);
*/
void compute_memory_pool_delete(struct compute_memory_pool* pool)
{
- COMPUTE_DBG("* compute_memory_pool_delete()\n");
+ COMPUTE_DBG(pool->screen, "* compute_memory_pool_delete()\n");
free(pool->shadow);
if (pool->bo) {
pool->screen->screen.resource_destroy((struct pipe_screen *)
assert(size_in_dw <= pool->size_in_dw);
- COMPUTE_DBG("* compute_memory_prealloc_chunk() size_in_dw = %ld\n",
+ COMPUTE_DBG(pool->screen, "* compute_memory_prealloc_chunk() size_in_dw = %ld\n",
size_in_dw);
for (item = pool->item_list; item; item = item->next) {
{
struct compute_memory_item* item;
- COMPUTE_DBG("* compute_memory_postalloc_chunck() start_in_dw = %ld\n",
+ COMPUTE_DBG(pool->screen, "* compute_memory_postalloc_chunck() start_in_dw = %ld\n",
start_in_dw);
/* Check if we can insert it in the front of the list */
void compute_memory_grow_pool(struct compute_memory_pool* pool,
struct pipe_context * pipe, int new_size_in_dw)
{
- COMPUTE_DBG("* compute_memory_grow_pool() new_size_in_dw = %d\n",
+ COMPUTE_DBG(pool->screen, "* compute_memory_grow_pool() new_size_in_dw = %d\n",
new_size_in_dw);
assert(new_size_in_dw >= pool->size_in_dw);
} else {
new_size_in_dw += 1024 - (new_size_in_dw % 1024);
- COMPUTE_DBG(" Aligned size = %d\n", new_size_in_dw);
+ COMPUTE_DBG(pool->screen, " Aligned size = %d\n", new_size_in_dw);
compute_memory_shadow(pool, pipe, 1);
pool->shadow = realloc(pool->shadow, new_size_in_dw*4);
{
struct compute_memory_item chunk;
- COMPUTE_DBG("* compute_memory_shadow() device_to_host = %d\n",
+ COMPUTE_DBG(pool->screen, "* compute_memory_shadow() device_to_host = %d\n",
device_to_host);
chunk.id = 0;
int64_t start_in_dw = 0;
- COMPUTE_DBG("* compute_memory_finalize_pending()\n");
+ COMPUTE_DBG(pool->screen, "* compute_memory_finalize_pending()\n");
for (item = pool->item_list; item; item = item->next) {
- COMPUTE_DBG(" + list: offset = %i id = %i size = %i "
+ COMPUTE_DBG(pool->screen, " + list: offset = %i id = %i size = %i "
"(%i bytes)\n",item->start_in_dw, item->id,
item->size_in_dw, item->size_in_dw * 4);
}
pool->size_in_dw + need);
}
}
- COMPUTE_DBG(" + Found space for Item %p id = %u "
+ COMPUTE_DBG(pool->screen, " + Found space for Item %p id = %u "
"start_in_dw = %u (%u bytes) size_in_dw = %u (%u bytes)\n",
item, item->id, start_in_dw, start_in_dw * 4,
item->size_in_dw, item->size_in_dw * 4);
{
struct compute_memory_item *item, *next;
- COMPUTE_DBG("* compute_memory_free() id + %ld \n", id);
+ COMPUTE_DBG(pool->screen, "* compute_memory_free() id + %ld \n", id);
for (item = pool->item_list; item; item = next) {
next = item->next;
{
struct compute_memory_item *new_item = NULL, *last_item = NULL;
- COMPUTE_DBG("* compute_memory_alloc() size_in_dw = %ld (%ld bytes)\n",
+ COMPUTE_DBG(pool->screen, "* compute_memory_alloc() size_in_dw = %ld (%ld bytes)\n",
size_in_dw, 4 * size_in_dw);
new_item = (struct compute_memory_item *)
pool->item_list = new_item;
}
- COMPUTE_DBG(" + Adding item %p id = %u size = %u (%u bytes)\n",
+ COMPUTE_DBG(pool->screen, " + Adding item %p id = %u size = %u (%u bytes)\n",
new_item, new_item->id, new_item->size_in_dw,
new_item->size_in_dw * 4);
return new_item;
assert(gart);
- COMPUTE_DBG("* compute_memory_transfer() device_to_host = %d, "
+ COMPUTE_DBG(pool->screen, "* compute_memory_transfer() device_to_host = %d, "
"offset_in_chunk = %d, size = %d\n", device_to_host,
offset_in_chunk, size);
const unsigned char * code;
unsigned i;
- COMPUTE_DBG("*** evergreen_create_compute_state\n");
+ COMPUTE_DBG(ctx->screen, "*** evergreen_create_compute_state\n");
header = cso->prog;
code = cso->prog + sizeof(struct pipe_llvm_program_header);
{
struct r600_context *ctx = (struct r600_context *)ctx_;
- COMPUTE_DBG("*** evergreen_bind_compute_state\n");
+ COMPUTE_DBG(ctx->screen, "*** evergreen_bind_compute_state\n");
ctx->cs_shader_state.shader = (struct r600_pipe_compute *)state;
}
for (i = 0; i < (kernel_parameters_offset_bytes / 4) +
(shader->input_size / 4); i++) {
- COMPUTE_DBG("input %i : %i\n", i,
+ COMPUTE_DBG(ctx->screen, "input %i : %i\n", i,
((unsigned*)num_work_groups_start)[i]);
}
num_waves = (block_layout[0] * block_layout[1] * block_layout[2] +
wave_divisor - 1) / wave_divisor;
- COMPUTE_DBG("Using %u pipes, there are %u wavefronts per thread block\n",
+ COMPUTE_DBG(rctx->screen, "Using %u pipes, there are %u wavefronts per thread block\n",
num_pipes, num_waves);
/* XXX: Partition the LDS between PS/CS. By default half (4096 dwords
for (i = 0; i < get_compute_resource_num(); i++) {
if (resources[i].enabled) {
int j;
- COMPUTE_DBG("resnum: %i, cdw: %i\n", i, cs->cdw);
+ COMPUTE_DBG(ctx->screen, "resnum: %i, cdw: %i\n", i, cs->cdw);
for (j = 0; j < resources[i].cs_end; j++) {
if (resources[i].do_reloc[j]) {
r600_flush_emit(ctx);
#if 0
- COMPUTE_DBG("cdw: %i\n", cs->cdw);
+ COMPUTE_DBG(ctx->screen, "cdw: %i\n", cs->cdw);
for (i = 0; i < cs->cdw; i++) {
- COMPUTE_DBG("%4i : 0x%08X\n", i, ctx->cs->buf[i]);
+ COMPUTE_DBG(ctx->screen, "%4i : 0x%08X\n", i, ctx->cs->buf[i]);
}
#endif
ctx->pm4_dirty_cdwords = 0;
ctx->flags = 0;
- COMPUTE_DBG("shader started\n");
+ COMPUTE_DBG(ctx->screen, "shader started\n");
ctx->ws->buffer_wait(onebo->buf, 0);
- COMPUTE_DBG("...\n");
+ COMPUTE_DBG(ctx->screen, "...\n");
}
struct r600_context *ctx = (struct r600_context *)ctx_;
#ifdef HAVE_OPENCL
- COMPUTE_DBG("*** evergreen_launch_grid: pc = %u\n", pc);
+ COMPUTE_DBG(ctx->screen, "*** evergreen_launch_grid: pc = %u\n", pc);
struct r600_pipe_compute *shader = ctx->cs_shader_state.shader;
if (!shader->kernels[pc].code_bo) {
struct r600_context *ctx = (struct r600_context *)ctx_;
struct r600_surface **resources = (struct r600_surface **)surfaces;
- COMPUTE_DBG("*** evergreen_set_compute_resources: start = %u count = %u\n",
+ COMPUTE_DBG(ctx->screen, "*** evergreen_set_compute_resources: start = %u count = %u\n",
start, count);
for (int i = 0; i < count; i++) {
struct r600_resource_global **buffers =
(struct r600_resource_global **)resources;
- COMPUTE_DBG("*** evergreen_set_global_binding first = %u n = %u\n",
+ COMPUTE_DBG(ctx->screen, "*** evergreen_set_global_binding first = %u n = %u\n",
first, n);
if (!resources) {
CALLOC(sizeof(struct r600_resource_global), 1);
rscreen = (struct r600_screen*)screen;
- COMPUTE_DBG("*** r600_compute_global_buffer_create\n");
- COMPUTE_DBG("width = %u array_size = %u\n", templ->width0,
+ COMPUTE_DBG(rscreen, "*** r600_compute_global_buffer_create\n");
+ COMPUTE_DBG(rscreen, "width = %u array_size = %u\n", templ->width0,
templ->array_size);
result->base.b.vtbl = &r600_global_buffer_vtbl;
assert(resource->target == PIPE_BUFFER);
- COMPUTE_DBG("* r600_compute_global_get_transfer()\n"
+ COMPUTE_DBG(rctx->screen, "* r600_compute_global_get_transfer()\n"
"level = %u, usage = %u, box(x = %u, y = %u, z = %u "
"width = %u, height = %u, depth = %u)\n", level, usage,
box->x, box->y, box->z, box->width, box->height,
///TODO: do it better, mapping is not possible if the pool is too big
- COMPUTE_DBG("* r600_compute_global_transfer_map()\n");
+ COMPUTE_DBG(rctx->screen, "* r600_compute_global_transfer_map()\n");
if (!(map = r600_buffer_mmap_sync_with_rings(rctx, buffer->chunk->pool->bo, transfer->usage))) {
util_slab_free(&rctx->pool_transfers, transfer);
*ptransfer = transfer;
- COMPUTE_DBG("Buffer: %p + %u (buffer offset in global memory) "
+ COMPUTE_DBG(rctx->screen, "Buffer: %p + %u (buffer offset in global memory) "
"+ %u (box.x)\n", map, buffer->chunk->start_in_dw, transfer->box.x);
return ((char*)(map + buffer->chunk->start_in_dw)) + transfer->box.x;
}
ctx = (struct r600_context *)ctx_;
buffer = (struct r600_resource_global*)transfer->resource;
- COMPUTE_DBG("* r600_compute_global_transfer_unmap()\n");
+ COMPUTE_DBG(ctx->screen, "* r600_compute_global_transfer_unmap()\n");
ctx->ws->buffer_unmap(buffer->chunk->pool->bo->cs_buf);
util_slab_free(&ctx->pool_transfers, transfer);
unsigned usage, const struct pipe_box *, const void *data, unsigned stride, unsigned layer_stride);
-static inline void COMPUTE_DBG(const char *fmt, ...)
+static inline void COMPUTE_DBG(struct r600_screen *rscreen, const char *fmt, ...)
{
- static bool check_debug = false, debug = false;
+ if (!(rscreen->debug_flags & DBG_COMPUTE)) {
+ return;
+ }
- if (!check_debug) {
- debug = debug_get_bool_option("R600_COMPUTE_DEBUG", FALSE);
- }
-
- if (debug) {
- va_list ap;
- va_start(ap, fmt);
- _debug_vprintf(fmt, ap);
- va_end(ap);
- }
+ va_list ap;
+ va_start(ap, fmt);
+ _debug_vprintf(fmt, ap);
+ va_end(ap);
}
#endif
rctx = pipe->ctx;
- COMPUTE_DBG("bind rat: %i \n", id);
+ COMPUTE_DBG(rctx->screen, "bind rat: %i \n", id);
/* Create the RAT surface */
memset(&rat_templ, 0, sizeof(rat_templ));
const struct pipe_vertex_element *elements)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- static int dump_shaders = -1;
struct r600_bytecode bc;
struct r600_bytecode_vtx vtx;
const struct util_format_description *desc;
return NULL;
}
- if (dump_shaders == -1)
- dump_shaders = debug_get_num_option("R600_DUMP_SHADERS", 0);
-
- if (dump_shaders & 1) {
- fprintf(stderr, "--------------------------------------------------------------\n");
- r600_bytecode_dump(&bc);
- fprintf(stderr, "______________________________________________________________\n");
- }
- if (dump_shaders & 2) {
+ if (rctx->screen->debug_flags & DBG_FS) {
fprintf(stderr, "--------------------------------------------------------------\n");
r600_bytecode_disasm(&bc);
fprintf(stderr, "______________________________________________________________\n");
#if defined R600_USE_LLVM || defined HAVE_OPENCL
unsigned i, use_llvm;
- use_llvm = debug_get_bool_option("R600_LLVM", TRUE);
+ use_llvm = !(ctx->screen->debug_flags & DBG_NO_LLVM);
if (!use_llvm)
return 0;
#include <errno.h>
#include "pipe/p_shader_tokens.h"
#include "util/u_blitter.h"
+#include "util/u_debug.h"
#include "util/u_format_s3tc.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
#include "vl/vl_video_buffer.h"
#include "os/os_time.h"
+static const struct debug_named_value debug_options[] = {
+ /* logging */
+ { "texdepth", DBG_TEX_DEPTH, "Print texture depth info" },
+ { "compute", DBG_COMPUTE, "Print compute info" },
+
+ /* shaders */
+ { "fs", DBG_FS, "Print fetch shaders" },
+ { "vs", DBG_VS, "Print vertex shaders" },
+ { "gs", DBG_GS, "Print geometry shaders" },
+ { "ps", DBG_PS, "Print pixel shaders" },
+ { "cs", DBG_CS, "Print compute shaders" },
+
+ /* features */
+ { "nohyperz", DBG_NO_HYPERZ, "Disable Hyper-Z" },
+#if defined(R600_USE_LLVM)
+ { "nollvm", DBG_NO_LLVM, "Disable the LLVM shader compiler" },
+#endif
+
+ DEBUG_NAMED_VALUE_END /* must be last */
+};
+
/*
* pipe_context
*/
rscreen->ws = ws;
ws->query_info(ws, &rscreen->info);
+ rscreen->debug_flags = debug_get_flags_option("R600_DEBUG", debug_options, 0);
rscreen->family = rscreen->info.family;
rscreen->chip_class = rscreen->info.chip_class;
+
if (rscreen->family == CHIP_UNKNOWN) {
fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id);
FREE(rscreen);
LIST_INITHEAD(&rscreen->fences.blocks);
pipe_mutex_init(rscreen->fences.mutex);
- /* Hyperz is very lockup prone any code that touch related part should be
- * carefully tested especialy on r6xx/r7xx Development show that some piglit
- * case were triggering lockup quickly such as :
- * piglit/bin/depthstencil-render-miplevels 1024 d=s=z24_s8
- */
- rscreen->use_hyperz = debug_get_bool_option("R600_HYPERZ", TRUE);
- rscreen->use_hyperz = rscreen->info.drm_minor >= 26 ? rscreen->use_hyperz : FALSE;
-
rscreen->global_pool = compute_memory_pool_new(rscreen);
#if R600_TRACE_CS
unsigned src_level,
const struct pipe_box *src_box);
+/* logging */
+#define DBG_TEX_DEPTH (1 << 0)
+#define DBG_COMPUTE (1 << 1)
+/* shaders */
+#define DBG_FS (1 << 8)
+#define DBG_VS (1 << 9)
+#define DBG_GS (1 << 10)
+#define DBG_PS (1 << 11)
+#define DBG_CS (1 << 12)
+/* features */
+#define DBG_NO_HYPERZ (1 << 16)
+#define DBG_NO_LLVM (1 << 17)
+
struct r600_screen {
struct pipe_screen screen;
struct radeon_winsys *ws;
+ unsigned debug_flags;
unsigned family;
enum chip_class chip_class;
struct radeon_info info;
bool has_msaa;
bool has_cp_dma;
enum r600_msaa_texture_mode msaa_texture_support;
- bool use_hyperz;
struct r600_tiling_info tiling_info;
struct r600_pipe_fences fences;
struct r600_pipe_shader *pipeshader,
struct r600_shader_key key);
+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;
+}
+
+static bool r600_can_dump_shader(struct r600_screen *rscreen, unsigned processor_type)
+{
+ switch (processor_type) {
+ case TGSI_PROCESSOR_VERTEX:
+ return (rscreen->debug_flags & DBG_VS) != 0;
+ case TGSI_PROCESSOR_GEOMETRY:
+ return (rscreen->debug_flags & DBG_GS) != 0;
+ case TGSI_PROCESSOR_FRAGMENT:
+ return (rscreen->debug_flags & DBG_PS) != 0;
+ case TGSI_PROCESSOR_COMPUTE:
+ return (rscreen->debug_flags & DBG_CS) != 0;
+ default:
+ return false;
+ }
+}
+
static void r600_dump_streamout(struct pipe_stream_output_info *so)
{
unsigned i;
struct r600_pipe_shader *shader,
struct r600_shader_key key)
{
- static int dump_shaders = -1;
struct r600_context *rctx = (struct r600_context *)ctx;
struct r600_pipe_shader_selector *sel = shader->selector;
int r;
+ bool dump = r600_can_dump_shader(rctx->screen, tgsi_get_processor_type(sel->tokens));
shader->shader.bc.isa = rctx->isa;
- /* Would like some magic "get_bool_option_once" routine.
- */
- if (dump_shaders == -1)
- dump_shaders = debug_get_num_option("R600_DUMP_SHADERS", 0);
-
- if (dump_shaders) {
+ if (dump) {
fprintf(stderr, "--------------------------------------------------------------\n");
tgsi_dump(sel->tokens, 0);
R600_ERR("building bytecode failed !\n");
return r;
}
- if (dump_shaders & 1) {
- fprintf(stderr, "--------------------------------------------------------------\n");
- r600_bytecode_dump(&shader->shader.bc);
- fprintf(stderr, "______________________________________________________________\n");
- }
- if (dump_shaders & 2) {
+ if (dump) {
fprintf(stderr, "--------------------------------------------------------------\n");
r600_bytecode_disasm(&shader->shader.bc);
fprintf(stderr, "______________________________________________________________\n");
unsigned char * bytes;
unsigned byte_count;
struct r600_shader_ctx shader_ctx;
- unsigned dump = 0;
-
- if (debug_get_bool_option("R600_DUMP_SHADERS", FALSE)) {
- dump = 1;
- }
+ bool dump = (r600_ctx->screen->debug_flags & DBG_CS) != 0;
r600_llvm_compile(mod, &bytes, &byte_count, r600_ctx->family , dump);
shader_ctx.bc = bytecode;
}
r600_bytecode_build(shader_ctx.bc);
if (dump) {
- r600_bytecode_dump(shader_ctx.bc);
+ r600_bytecode_disasm(shader_ctx.bc);
}
free(bytes);
return 1;
unsigned inst_byte_count = 0;
#ifdef R600_USE_LLVM
- use_llvm = debug_get_bool_option("R600_LLVM", TRUE);
+ use_llvm = !(ctx->screen->debug_flags & DBG_NO_LLVM);
#endif
ctx.bc = &shader->bc;
ctx.shader = shader;
if (use_llvm) {
struct radeon_llvm_context radeon_llvm_ctx;
LLVMModuleRef mod;
- unsigned dump = 0;
+ bool dump = r600_can_dump_shader(rscreen, ctx.type);
+
memset(&radeon_llvm_ctx, 0, sizeof(radeon_llvm_ctx));
radeon_llvm_ctx.type = ctx.type;
radeon_llvm_ctx.two_side = shader->two_side;
radeon_llvm_ctx.clip_vertex = ctx.cv_output;
radeon_llvm_ctx.alpha_to_one = key.alpha_to_one;
mod = r600_tgsi_llvm(&radeon_llvm_ctx, tokens);
- if (debug_get_bool_option("R600_DUMP_SHADERS", FALSE)) {
- dump = 1;
- }
+
if (r600_llvm_compile(mod, &inst_bytes, &inst_byte_count,
- rscreen->family, dump)) {
+ rscreen->family, dump)) {
FREE(inst_bytes);
radeon_llvm_dispose(&radeon_llvm_ctx);
use_llvm = 0;
#endif
}
-DEBUG_GET_ONCE_BOOL_OPTION(print_texdepth, "R600_PRINT_TEXDEPTH", FALSE);
-
static struct r600_texture *
r600_texture_create_object(struct pipe_screen *screen,
const struct pipe_resource *base,
rtex->htile = NULL;
if (!(base->flags & (R600_RESOURCE_FLAG_TRANSFER | R600_RESOURCE_FLAG_FLUSHED_DEPTH)) &&
util_format_is_depth_or_stencil(base->format) &&
- rscreen->use_hyperz &&
+ rscreen->info.drm_minor >= 26 &&
+ !(rscreen->debug_flags & DBG_NO_HYPERZ) &&
base->target == PIPE_TEXTURE_2D &&
rtex->surface.level[0].nblk_x >= 32 &&
rtex->surface.level[0].nblk_y >= 32) {
rscreen->ws->buffer_unmap(resource->cs_buf);
}
- if (debug_get_option_print_texdepth() && rtex->is_depth && rtex->non_disp_tiling) {
+ if (rscreen->debug_flags & DBG_TEX_DEPTH && rtex->is_depth && rtex->non_disp_tiling) {
printf("Texture: npix_x=%u, npix_y=%u, npix_z=%u, blk_w=%u, "
"blk_h=%u, blk_d=%u, array_size=%u, last_level=%u, "
"bpe=%u, nsamples=%u, flags=%u\n",