Path: blob/21.2-virgl/src/gallium/drivers/r600/evergreen_compute.c
4570 views
/*1* Copyright 2011 Adam Rak <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*22* Authors:23* Adam Rak <[email protected]>24*/2526#ifdef HAVE_OPENCL27#include <gelf.h>28#include <libelf.h>29#endif30#include <stdio.h>31#include <errno.h>32#include "pipe/p_defines.h"33#include "pipe/p_state.h"34#include "pipe/p_context.h"35#include "util/u_blitter.h"36#include "util/list.h"37#include "util/u_transfer.h"38#include "util/u_surface.h"39#include "util/u_pack_color.h"40#include "util/u_memory.h"41#include "util/u_inlines.h"42#include "util/u_framebuffer.h"43#include "tgsi/tgsi_parse.h"44#include "pipebuffer/pb_buffer.h"45#include "evergreend.h"46#include "r600_shader.h"47#include "r600_pipe.h"48#include "r600_formats.h"49#include "evergreen_compute.h"50#include "evergreen_compute_internal.h"51#include "compute_memory_pool.h"52#include "sb/sb_public.h"53#include <inttypes.h>5455/**56RAT0 is for global binding write57VTX1 is for global binding read5859for wrting images RAT1...60for reading images TEX2...61TEX2-RAT1 is paired6263TEX2... consumes the same fetch resources, that VTX2... would consume6465CONST0 and VTX0 is for parameters66CONST0 is binding smaller input parameter buffer, and for constant indexing,67also constant cached68VTX0 is for indirect/non-constant indexing, or if the input is bigger than69the constant cache can handle7071RAT-s are limited to 12, so we can only bind at most 11 texture for writing72because we reserve RAT0 for global bindings. With byteaddressing enabled,73we should reserve another one too.=> 10 image binding for writing max.7475from Nvidia OpenCL:76CL_DEVICE_MAX_READ_IMAGE_ARGS: 12877CL_DEVICE_MAX_WRITE_IMAGE_ARGS: 87879so 10 for writing is enough. 176 is the max for reading according to the docs8081writable images should be listed first < 10, so their id corresponds to RAT(id+1)82writable images will consume TEX slots, VTX slots too because of linear indexing8384*/8586#ifdef HAVE_OPENCL87static void radeon_shader_binary_init(struct r600_shader_binary *b)88{89memset(b, 0, sizeof(*b));90}9192static void radeon_shader_binary_clean(struct r600_shader_binary *b)93{94if (!b)95return;96FREE(b->code);97FREE(b->config);98FREE(b->rodata);99FREE(b->global_symbol_offsets);100FREE(b->relocs);101FREE(b->disasm_string);102}103#endif104105struct r600_resource *r600_compute_buffer_alloc_vram(struct r600_screen *screen,106unsigned size)107{108struct pipe_resource *buffer = NULL;109assert(size);110111buffer = pipe_buffer_create((struct pipe_screen*) screen,1120, PIPE_USAGE_IMMUTABLE, size);113114return (struct r600_resource *)buffer;115}116117118static void evergreen_set_rat(struct r600_pipe_compute *pipe,119unsigned id,120struct r600_resource *bo,121int start,122int size)123{124struct pipe_surface rat_templ;125struct r600_surface *surf = NULL;126struct r600_context *rctx = NULL;127128assert(id < 12);129assert((size & 3) == 0);130assert((start & 0xFF) == 0);131132rctx = pipe->ctx;133134COMPUTE_DBG(rctx->screen, "bind rat: %i \n", id);135136/* Create the RAT surface */137memset(&rat_templ, 0, sizeof(rat_templ));138rat_templ.format = PIPE_FORMAT_R32_UINT;139rat_templ.u.tex.level = 0;140rat_templ.u.tex.first_layer = 0;141rat_templ.u.tex.last_layer = 0;142143/* Add the RAT the list of color buffers. Drop the old buffer first. */144pipe_surface_reference(&pipe->ctx->framebuffer.state.cbufs[id], NULL);145pipe->ctx->framebuffer.state.cbufs[id] = pipe->ctx->b.b.create_surface(146(struct pipe_context *)pipe->ctx,147(struct pipe_resource *)bo, &rat_templ);148149/* Update the number of color buffers */150pipe->ctx->framebuffer.state.nr_cbufs =151MAX2(id + 1, pipe->ctx->framebuffer.state.nr_cbufs);152153/* Update the cb_target_mask154* XXX: I think this is a potential spot for bugs once we start doing155* GL interop. cb_target_mask may be modified in the 3D sections156* of this driver. */157pipe->ctx->compute_cb_target_mask |= (0xf << (id * 4));158159surf = (struct r600_surface*)pipe->ctx->framebuffer.state.cbufs[id];160evergreen_init_color_surface_rat(rctx, surf);161}162163static void evergreen_cs_set_vertex_buffer(struct r600_context *rctx,164unsigned vb_index,165unsigned offset,166struct pipe_resource *buffer)167{168struct r600_vertexbuf_state *state = &rctx->cs_vertex_buffer_state;169struct pipe_vertex_buffer *vb = &state->vb[vb_index];170vb->stride = 1;171vb->buffer_offset = offset;172vb->buffer.resource = buffer;173vb->is_user_buffer = false;174175/* The vertex instructions in the compute shaders use the texture cache,176* so we need to invalidate it. */177rctx->b.flags |= R600_CONTEXT_INV_VERTEX_CACHE;178state->enabled_mask |= 1 << vb_index;179state->dirty_mask |= 1 << vb_index;180r600_mark_atom_dirty(rctx, &state->atom);181}182183static void evergreen_cs_set_constant_buffer(struct r600_context *rctx,184unsigned cb_index,185unsigned offset,186unsigned size,187struct pipe_resource *buffer)188{189struct pipe_constant_buffer cb;190cb.buffer_size = size;191cb.buffer_offset = offset;192cb.buffer = buffer;193cb.user_buffer = NULL;194195rctx->b.b.set_constant_buffer(&rctx->b.b, PIPE_SHADER_COMPUTE, cb_index, false, &cb);196}197198/* We need to define these R600 registers here, because we can't include199* evergreend.h and r600d.h.200*/201#define R_028868_SQ_PGM_RESOURCES_VS 0x028868202#define R_028850_SQ_PGM_RESOURCES_PS 0x028850203204#ifdef HAVE_OPENCL205static void parse_symbol_table(Elf_Data *symbol_table_data,206const GElf_Shdr *symbol_table_header,207struct r600_shader_binary *binary)208{209GElf_Sym symbol;210unsigned i = 0;211unsigned symbol_count =212symbol_table_header->sh_size / symbol_table_header->sh_entsize;213214/* We are over allocating this list, because symbol_count gives the215* total number of symbols, and we will only be filling the list216* with offsets of global symbols. The memory savings from217* allocating the correct size of this list will be small, and218* I don't think it is worth the cost of pre-computing the number219* of global symbols.220*/221binary->global_symbol_offsets = CALLOC(symbol_count, sizeof(uint64_t));222223while (gelf_getsym(symbol_table_data, i++, &symbol)) {224unsigned i;225if (GELF_ST_BIND(symbol.st_info) != STB_GLOBAL ||226symbol.st_shndx == 0 /* Undefined symbol */) {227continue;228}229230binary->global_symbol_offsets[binary->global_symbol_count] =231symbol.st_value;232233/* Sort the list using bubble sort. This list will usually234* be small. */235for (i = binary->global_symbol_count; i > 0; --i) {236uint64_t lhs = binary->global_symbol_offsets[i - 1];237uint64_t rhs = binary->global_symbol_offsets[i];238if (lhs < rhs) {239break;240}241binary->global_symbol_offsets[i] = lhs;242binary->global_symbol_offsets[i - 1] = rhs;243}244++binary->global_symbol_count;245}246}247248249static void parse_relocs(Elf *elf, Elf_Data *relocs, Elf_Data *symbols,250unsigned symbol_sh_link,251struct r600_shader_binary *binary)252{253unsigned i;254255if (!relocs || !symbols || !binary->reloc_count) {256return;257}258binary->relocs = CALLOC(binary->reloc_count,259sizeof(struct r600_shader_reloc));260for (i = 0; i < binary->reloc_count; i++) {261GElf_Sym symbol;262GElf_Rel rel;263char *symbol_name;264struct r600_shader_reloc *reloc = &binary->relocs[i];265266gelf_getrel(relocs, i, &rel);267gelf_getsym(symbols, GELF_R_SYM(rel.r_info), &symbol);268symbol_name = elf_strptr(elf, symbol_sh_link, symbol.st_name);269270reloc->offset = rel.r_offset;271strncpy(reloc->name, symbol_name, sizeof(reloc->name)-1);272reloc->name[sizeof(reloc->name)-1] = 0;273}274}275276static void r600_elf_read(const char *elf_data, unsigned elf_size,277struct r600_shader_binary *binary)278{279char *elf_buffer;280Elf *elf;281Elf_Scn *section = NULL;282Elf_Data *symbols = NULL, *relocs = NULL;283size_t section_str_index;284unsigned symbol_sh_link = 0;285286/* One of the libelf implementations287* (http://www.mr511.de/software/english.htm) requires calling288* elf_version() before elf_memory().289*/290elf_version(EV_CURRENT);291elf_buffer = MALLOC(elf_size);292memcpy(elf_buffer, elf_data, elf_size);293294elf = elf_memory(elf_buffer, elf_size);295296elf_getshdrstrndx(elf, §ion_str_index);297298while ((section = elf_nextscn(elf, section))) {299const char *name;300Elf_Data *section_data = NULL;301GElf_Shdr section_header;302if (gelf_getshdr(section, §ion_header) != §ion_header) {303fprintf(stderr, "Failed to read ELF section header\n");304return;305}306name = elf_strptr(elf, section_str_index, section_header.sh_name);307if (!strcmp(name, ".text")) {308section_data = elf_getdata(section, section_data);309binary->code_size = section_data->d_size;310binary->code = MALLOC(binary->code_size * sizeof(unsigned char));311memcpy(binary->code, section_data->d_buf, binary->code_size);312} else if (!strcmp(name, ".AMDGPU.config")) {313section_data = elf_getdata(section, section_data);314binary->config_size = section_data->d_size;315binary->config = MALLOC(binary->config_size * sizeof(unsigned char));316memcpy(binary->config, section_data->d_buf, binary->config_size);317} else if (!strcmp(name, ".AMDGPU.disasm")) {318/* Always read disassembly if it's available. */319section_data = elf_getdata(section, section_data);320binary->disasm_string = strndup(section_data->d_buf,321section_data->d_size);322} else if (!strncmp(name, ".rodata", 7)) {323section_data = elf_getdata(section, section_data);324binary->rodata_size = section_data->d_size;325binary->rodata = MALLOC(binary->rodata_size * sizeof(unsigned char));326memcpy(binary->rodata, section_data->d_buf, binary->rodata_size);327} else if (!strncmp(name, ".symtab", 7)) {328symbols = elf_getdata(section, section_data);329symbol_sh_link = section_header.sh_link;330parse_symbol_table(symbols, §ion_header, binary);331} else if (!strcmp(name, ".rel.text")) {332relocs = elf_getdata(section, section_data);333binary->reloc_count = section_header.sh_size /334section_header.sh_entsize;335}336}337338parse_relocs(elf, relocs, symbols, symbol_sh_link, binary);339340if (elf){341elf_end(elf);342}343FREE(elf_buffer);344345/* Cache the config size per symbol */346if (binary->global_symbol_count) {347binary->config_size_per_symbol =348binary->config_size / binary->global_symbol_count;349} else {350binary->global_symbol_count = 1;351binary->config_size_per_symbol = binary->config_size;352}353}354355static const unsigned char *r600_shader_binary_config_start(356const struct r600_shader_binary *binary,357uint64_t symbol_offset)358{359unsigned i;360for (i = 0; i < binary->global_symbol_count; ++i) {361if (binary->global_symbol_offsets[i] == symbol_offset) {362unsigned offset = i * binary->config_size_per_symbol;363return binary->config + offset;364}365}366return binary->config;367}368369static void r600_shader_binary_read_config(const struct r600_shader_binary *binary,370struct r600_bytecode *bc,371uint64_t symbol_offset,372boolean *use_kill)373{374unsigned i;375const unsigned char *config =376r600_shader_binary_config_start(binary, symbol_offset);377378for (i = 0; i < binary->config_size_per_symbol; i+= 8) {379unsigned reg =380util_le32_to_cpu(*(uint32_t*)(config + i));381unsigned value =382util_le32_to_cpu(*(uint32_t*)(config + i + 4));383switch (reg) {384/* R600 / R700 */385case R_028850_SQ_PGM_RESOURCES_PS:386case R_028868_SQ_PGM_RESOURCES_VS:387/* Evergreen / Northern Islands */388case R_028844_SQ_PGM_RESOURCES_PS:389case R_028860_SQ_PGM_RESOURCES_VS:390case R_0288D4_SQ_PGM_RESOURCES_LS:391bc->ngpr = MAX2(bc->ngpr, G_028844_NUM_GPRS(value));392bc->nstack = MAX2(bc->nstack, G_028844_STACK_SIZE(value));393break;394case R_02880C_DB_SHADER_CONTROL:395*use_kill = G_02880C_KILL_ENABLE(value);396break;397case R_0288E8_SQ_LDS_ALLOC:398bc->nlds_dw = value;399break;400}401}402}403404static unsigned r600_create_shader(struct r600_bytecode *bc,405const struct r600_shader_binary *binary,406boolean *use_kill)407408{409assert(binary->code_size % 4 == 0);410bc->bytecode = CALLOC(1, binary->code_size);411memcpy(bc->bytecode, binary->code, binary->code_size);412bc->ndw = binary->code_size / 4;413414r600_shader_binary_read_config(binary, bc, 0, use_kill);415return 0;416}417418#endif419420static void r600_destroy_shader(struct r600_bytecode *bc)421{422FREE(bc->bytecode);423}424425static void *evergreen_create_compute_state(struct pipe_context *ctx,426const struct pipe_compute_state *cso)427{428struct r600_context *rctx = (struct r600_context *)ctx;429struct r600_pipe_compute *shader = CALLOC_STRUCT(r600_pipe_compute);430#ifdef HAVE_OPENCL431const struct pipe_binary_program_header *header;432void *p;433boolean use_kill;434#endif435436shader->ctx = rctx;437shader->local_size = cso->req_local_mem;438shader->private_size = cso->req_private_mem;439shader->input_size = cso->req_input_mem;440441shader->ir_type = cso->ir_type;442443if (shader->ir_type == PIPE_SHADER_IR_TGSI ||444shader->ir_type == PIPE_SHADER_IR_NIR) {445shader->sel = r600_create_shader_state_tokens(ctx, cso->prog, cso->ir_type, PIPE_SHADER_COMPUTE);446return shader;447}448#ifdef HAVE_OPENCL449COMPUTE_DBG(rctx->screen, "*** evergreen_create_compute_state\n");450header = cso->prog;451radeon_shader_binary_init(&shader->binary);452r600_elf_read(header->blob, header->num_bytes, &shader->binary);453r600_create_shader(&shader->bc, &shader->binary, &use_kill);454455/* Upload code + ROdata */456shader->code_bo = r600_compute_buffer_alloc_vram(rctx->screen,457shader->bc.ndw * 4);458p = r600_buffer_map_sync_with_rings(459&rctx->b, shader->code_bo,460PIPE_MAP_WRITE | RADEON_MAP_TEMPORARY);461//TODO: use util_memcpy_cpu_to_le32 ?462memcpy(p, shader->bc.bytecode, shader->bc.ndw * 4);463rctx->b.ws->buffer_unmap(rctx->b.ws, shader->code_bo->buf);464#endif465466return shader;467}468469static void evergreen_delete_compute_state(struct pipe_context *ctx, void *state)470{471struct r600_context *rctx = (struct r600_context *)ctx;472struct r600_pipe_compute *shader = state;473474COMPUTE_DBG(rctx->screen, "*** evergreen_delete_compute_state\n");475476if (!shader)477return;478479if (shader->ir_type == PIPE_SHADER_IR_TGSI ||480shader->ir_type == PIPE_SHADER_IR_NIR) {481r600_delete_shader_selector(ctx, shader->sel);482} else {483#ifdef HAVE_OPENCL484radeon_shader_binary_clean(&shader->binary);485pipe_resource_reference((struct pipe_resource**)&shader->code_bo, NULL);486pipe_resource_reference((struct pipe_resource**)&shader->kernel_param, NULL);487#endif488r600_destroy_shader(&shader->bc);489}490FREE(shader);491}492493static void evergreen_bind_compute_state(struct pipe_context *ctx, void *state)494{495struct r600_context *rctx = (struct r600_context *)ctx;496struct r600_pipe_compute *cstate = (struct r600_pipe_compute *)state;497COMPUTE_DBG(rctx->screen, "*** evergreen_bind_compute_state\n");498499if (!state) {500rctx->cs_shader_state.shader = (struct r600_pipe_compute *)state;501return;502}503504if (cstate->ir_type == PIPE_SHADER_IR_TGSI ||505cstate->ir_type == PIPE_SHADER_IR_NIR) {506bool compute_dirty;507cstate->sel->ir_type = cstate->ir_type;508if (r600_shader_select(ctx, cstate->sel, &compute_dirty))509R600_ERR("Failed to select compute shader\n");510}511512rctx->cs_shader_state.shader = (struct r600_pipe_compute *)state;513}514515/* The kernel parameters are stored a vtx buffer (ID=0), besides the explicit516* kernel parameters there are implicit parameters that need to be stored517* in the vertex buffer as well. Here is how these parameters are organized in518* the buffer:519*520* DWORDS 0-2: Number of work groups in each dimension (x,y,z)521* DWORDS 3-5: Number of global work items in each dimension (x,y,z)522* DWORDS 6-8: Number of work items within each work group in each dimension523* (x,y,z)524* DWORDS 9+ : Kernel parameters525*/526static void evergreen_compute_upload_input(struct pipe_context *ctx,527const struct pipe_grid_info *info)528{529struct r600_context *rctx = (struct r600_context *)ctx;530struct r600_pipe_compute *shader = rctx->cs_shader_state.shader;531unsigned i;532/* We need to reserve 9 dwords (36 bytes) for implicit kernel533* parameters.534*/535unsigned input_size;536uint32_t *num_work_groups_start;537uint32_t *global_size_start;538uint32_t *local_size_start;539uint32_t *kernel_parameters_start;540struct pipe_box box;541struct pipe_transfer *transfer = NULL;542543if (!shader)544return;545if (shader->input_size == 0) {546return;547}548input_size = shader->input_size + 36;549if (!shader->kernel_param) {550/* Add space for the grid dimensions */551shader->kernel_param = (struct r600_resource *)552pipe_buffer_create(ctx->screen, 0,553PIPE_USAGE_IMMUTABLE, input_size);554}555556u_box_1d(0, input_size, &box);557num_work_groups_start = ctx->buffer_map(ctx,558(struct pipe_resource*)shader->kernel_param,5590, PIPE_MAP_WRITE | PIPE_MAP_DISCARD_RANGE,560&box, &transfer);561global_size_start = num_work_groups_start + (3 * (sizeof(uint) /4));562local_size_start = global_size_start + (3 * (sizeof(uint)) / 4);563kernel_parameters_start = local_size_start + (3 * (sizeof(uint)) / 4);564565/* Copy the work group size */566memcpy(num_work_groups_start, info->grid, 3 * sizeof(uint));567568/* Copy the global size */569for (i = 0; i < 3; i++) {570global_size_start[i] = info->grid[i] * info->block[i];571}572573/* Copy the local dimensions */574memcpy(local_size_start, info->block, 3 * sizeof(uint));575576/* Copy the kernel inputs */577memcpy(kernel_parameters_start, info->input, shader->input_size);578579for (i = 0; i < (input_size / 4); i++) {580COMPUTE_DBG(rctx->screen, "input %i : %u\n", i,581((unsigned*)num_work_groups_start)[i]);582}583584ctx->buffer_unmap(ctx, transfer);585586/* ID=0 and ID=3 are reserved for the parameters.587* LLVM will preferably use ID=0, but it does not work for dynamic588* indices. */589evergreen_cs_set_vertex_buffer(rctx, 3, 0,590(struct pipe_resource*)shader->kernel_param);591evergreen_cs_set_constant_buffer(rctx, 0, 0, input_size,592(struct pipe_resource*)shader->kernel_param);593}594595static void evergreen_emit_dispatch(struct r600_context *rctx,596const struct pipe_grid_info *info,597uint32_t indirect_grid[3])598{599int i;600struct radeon_cmdbuf *cs = &rctx->b.gfx.cs;601struct r600_pipe_compute *shader = rctx->cs_shader_state.shader;602bool render_cond_bit = rctx->b.render_cond && !rctx->b.render_cond_force_off;603unsigned num_waves;604unsigned num_pipes = rctx->screen->b.info.r600_max_quad_pipes;605unsigned wave_divisor = (16 * num_pipes);606int group_size = 1;607int grid_size = 1;608unsigned lds_size = shader->local_size / 4;609610if (shader->ir_type != PIPE_SHADER_IR_TGSI &&611shader->ir_type != PIPE_SHADER_IR_NIR)612lds_size += shader->bc.nlds_dw;613614/* Calculate group_size/grid_size */615for (i = 0; i < 3; i++) {616group_size *= info->block[i];617}618619for (i = 0; i < 3; i++) {620grid_size *= info->grid[i];621}622623/* num_waves = ceil((tg_size.x * tg_size.y, tg_size.z) / (16 * num_pipes)) */624num_waves = (info->block[0] * info->block[1] * info->block[2] +625wave_divisor - 1) / wave_divisor;626627COMPUTE_DBG(rctx->screen, "Using %u pipes, "628"%u wavefronts per thread block, "629"allocating %u dwords lds.\n",630num_pipes, num_waves, lds_size);631632radeon_set_config_reg(cs, R_008970_VGT_NUM_INDICES, group_size);633634radeon_set_config_reg_seq(cs, R_00899C_VGT_COMPUTE_START_X, 3);635radeon_emit(cs, 0); /* R_00899C_VGT_COMPUTE_START_X */636radeon_emit(cs, 0); /* R_0089A0_VGT_COMPUTE_START_Y */637radeon_emit(cs, 0); /* R_0089A4_VGT_COMPUTE_START_Z */638639radeon_set_config_reg(cs, R_0089AC_VGT_COMPUTE_THREAD_GROUP_SIZE,640group_size);641642radeon_compute_set_context_reg_seq(cs, R_0286EC_SPI_COMPUTE_NUM_THREAD_X, 3);643radeon_emit(cs, info->block[0]); /* R_0286EC_SPI_COMPUTE_NUM_THREAD_X */644radeon_emit(cs, info->block[1]); /* R_0286F0_SPI_COMPUTE_NUM_THREAD_Y */645radeon_emit(cs, info->block[2]); /* R_0286F4_SPI_COMPUTE_NUM_THREAD_Z */646647if (rctx->b.chip_class < CAYMAN) {648assert(lds_size <= 8192);649} else {650/* Cayman appears to have a slightly smaller limit, see the651* value of CM_R_0286FC_SPI_LDS_MGMT.NUM_LS_LDS */652assert(lds_size <= 8160);653}654655radeon_compute_set_context_reg(cs, R_0288E8_SQ_LDS_ALLOC,656lds_size | (num_waves << 14));657658if (info->indirect) {659radeon_emit(cs, PKT3C(PKT3_DISPATCH_DIRECT, 3, render_cond_bit));660radeon_emit(cs, indirect_grid[0]);661radeon_emit(cs, indirect_grid[1]);662radeon_emit(cs, indirect_grid[2]);663radeon_emit(cs, 1);664} else {665/* Dispatch packet */666radeon_emit(cs, PKT3C(PKT3_DISPATCH_DIRECT, 3, render_cond_bit));667radeon_emit(cs, info->grid[0]);668radeon_emit(cs, info->grid[1]);669radeon_emit(cs, info->grid[2]);670/* VGT_DISPATCH_INITIATOR = COMPUTE_SHADER_EN */671radeon_emit(cs, 1);672}673674if (rctx->is_debug)675eg_trace_emit(rctx);676}677678static void compute_setup_cbs(struct r600_context *rctx)679{680struct radeon_cmdbuf *cs = &rctx->b.gfx.cs;681unsigned i;682683/* Emit colorbuffers. */684/* XXX support more than 8 colorbuffers (the offsets are not a multiple of 0x3C for CB8-11) */685for (i = 0; i < 8 && i < rctx->framebuffer.state.nr_cbufs; i++) {686struct r600_surface *cb = (struct r600_surface*)rctx->framebuffer.state.cbufs[i];687unsigned reloc = radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx,688(struct r600_resource*)cb->base.texture,689RADEON_USAGE_READWRITE,690RADEON_PRIO_SHADER_RW_BUFFER);691692radeon_compute_set_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 0x3C, 7);693radeon_emit(cs, cb->cb_color_base); /* R_028C60_CB_COLOR0_BASE */694radeon_emit(cs, cb->cb_color_pitch); /* R_028C64_CB_COLOR0_PITCH */695radeon_emit(cs, cb->cb_color_slice); /* R_028C68_CB_COLOR0_SLICE */696radeon_emit(cs, cb->cb_color_view); /* R_028C6C_CB_COLOR0_VIEW */697radeon_emit(cs, cb->cb_color_info); /* R_028C70_CB_COLOR0_INFO */698radeon_emit(cs, cb->cb_color_attrib); /* R_028C74_CB_COLOR0_ATTRIB */699radeon_emit(cs, cb->cb_color_dim); /* R_028C78_CB_COLOR0_DIM */700701radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C60_CB_COLOR0_BASE */702radeon_emit(cs, reloc);703704radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C74_CB_COLOR0_ATTRIB */705radeon_emit(cs, reloc);706}707for (; i < 8 ; i++)708radeon_compute_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C,709S_028C70_FORMAT(V_028C70_COLOR_INVALID));710for (; i < 12; i++)711radeon_compute_set_context_reg(cs, R_028E50_CB_COLOR8_INFO + (i - 8) * 0x1C,712S_028C70_FORMAT(V_028C70_COLOR_INVALID));713714/* Set CB_TARGET_MASK XXX: Use cb_misc_state */715radeon_compute_set_context_reg(cs, R_028238_CB_TARGET_MASK,716rctx->compute_cb_target_mask);717}718719static void compute_emit_cs(struct r600_context *rctx,720const struct pipe_grid_info *info)721{722struct radeon_cmdbuf *cs = &rctx->b.gfx.cs;723bool compute_dirty = false;724struct r600_pipe_shader *current;725struct r600_shader_atomic combined_atomics[8];726uint8_t atomic_used_mask;727uint32_t indirect_grid[3] = { 0, 0, 0 };728729/* make sure that the gfx ring is only one active */730if (radeon_emitted(&rctx->b.dma.cs, 0)) {731rctx->b.dma.flush(rctx, PIPE_FLUSH_ASYNC, NULL);732}733734r600_update_compressed_resource_state(rctx, true);735736if (!rctx->cmd_buf_is_compute) {737rctx->b.gfx.flush(rctx, PIPE_FLUSH_ASYNC, NULL);738rctx->cmd_buf_is_compute = true;739}740741if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI||742rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR) {743if (r600_shader_select(&rctx->b.b, rctx->cs_shader_state.shader->sel, &compute_dirty)) {744R600_ERR("Failed to select compute shader\n");745return;746}747748current = rctx->cs_shader_state.shader->sel->current;749if (compute_dirty) {750rctx->cs_shader_state.atom.num_dw = current->command_buffer.num_dw;751r600_context_add_resource_size(&rctx->b.b, (struct pipe_resource *)current->bo);752r600_set_atom_dirty(rctx, &rctx->cs_shader_state.atom, true);753}754755bool need_buf_const = current->shader.uses_tex_buffers ||756current->shader.has_txq_cube_array_z_comp;757758if (info->indirect) {759struct r600_resource *indirect_resource = (struct r600_resource *)info->indirect;760unsigned *data = r600_buffer_map_sync_with_rings(&rctx->b, indirect_resource, PIPE_MAP_READ);761unsigned offset = info->indirect_offset / 4;762indirect_grid[0] = data[offset];763indirect_grid[1] = data[offset + 1];764indirect_grid[2] = data[offset + 2];765}766for (int i = 0; i < 3; i++) {767rctx->cs_block_grid_sizes[i] = info->block[i];768rctx->cs_block_grid_sizes[i + 4] = info->indirect ? indirect_grid[i] : info->grid[i];769}770rctx->cs_block_grid_sizes[3] = rctx->cs_block_grid_sizes[7] = 0;771rctx->driver_consts[PIPE_SHADER_COMPUTE].cs_block_grid_size_dirty = true;772773evergreen_emit_atomic_buffer_setup_count(rctx, current, combined_atomics, &atomic_used_mask);774r600_need_cs_space(rctx, 0, true, util_bitcount(atomic_used_mask));775776if (need_buf_const) {777eg_setup_buffer_constants(rctx, PIPE_SHADER_COMPUTE);778}779r600_update_driver_const_buffers(rctx, true);780781evergreen_emit_atomic_buffer_setup(rctx, true, combined_atomics, atomic_used_mask);782if (atomic_used_mask) {783radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));784radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_CS_PARTIAL_FLUSH) | EVENT_INDEX(4));785}786} else787r600_need_cs_space(rctx, 0, true, 0);788789/* Initialize all the compute-related registers.790*791* See evergreen_init_atom_start_compute_cs() in this file for the list792* of registers initialized by the start_compute_cs_cmd atom.793*/794r600_emit_command_buffer(cs, &rctx->start_compute_cs_cmd);795796/* emit config state */797if (rctx->b.chip_class == EVERGREEN) {798if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI||799rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR) {800radeon_set_config_reg_seq(cs, R_008C04_SQ_GPR_RESOURCE_MGMT_1, 3);801radeon_emit(cs, S_008C04_NUM_CLAUSE_TEMP_GPRS(rctx->r6xx_num_clause_temp_gprs));802radeon_emit(cs, 0);803radeon_emit(cs, 0);804radeon_set_config_reg(cs, R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, (1 << 8));805} else806r600_emit_atom(rctx, &rctx->config_state.atom);807}808809rctx->b.flags |= R600_CONTEXT_WAIT_3D_IDLE | R600_CONTEXT_FLUSH_AND_INV;810r600_flush_emit(rctx);811812if (rctx->cs_shader_state.shader->ir_type != PIPE_SHADER_IR_TGSI &&813rctx->cs_shader_state.shader->ir_type != PIPE_SHADER_IR_NIR) {814815compute_setup_cbs(rctx);816817/* Emit vertex buffer state */818rctx->cs_vertex_buffer_state.atom.num_dw = 12 * util_bitcount(rctx->cs_vertex_buffer_state.dirty_mask);819r600_emit_atom(rctx, &rctx->cs_vertex_buffer_state.atom);820} else {821uint32_t rat_mask;822823rat_mask = evergreen_construct_rat_mask(rctx, &rctx->cb_misc_state, 0);824radeon_compute_set_context_reg(cs, R_028238_CB_TARGET_MASK,825rat_mask);826}827828r600_emit_atom(rctx, &rctx->b.render_cond_atom);829830/* Emit constant buffer state */831r600_emit_atom(rctx, &rctx->constbuf_state[PIPE_SHADER_COMPUTE].atom);832833/* Emit sampler state */834r600_emit_atom(rctx, &rctx->samplers[PIPE_SHADER_COMPUTE].states.atom);835836/* Emit sampler view (texture resource) state */837r600_emit_atom(rctx, &rctx->samplers[PIPE_SHADER_COMPUTE].views.atom);838839/* Emit images state */840r600_emit_atom(rctx, &rctx->compute_images.atom);841842/* Emit buffers state */843r600_emit_atom(rctx, &rctx->compute_buffers.atom);844845/* Emit shader state */846r600_emit_atom(rctx, &rctx->cs_shader_state.atom);847848/* Emit dispatch state and dispatch packet */849evergreen_emit_dispatch(rctx, info, indirect_grid);850851/* XXX evergreen_flush_emit() hardcodes the CP_COHER_SIZE to 0xffffffff852*/853rctx->b.flags |= R600_CONTEXT_INV_CONST_CACHE |854R600_CONTEXT_INV_VERTEX_CACHE |855R600_CONTEXT_INV_TEX_CACHE;856r600_flush_emit(rctx);857rctx->b.flags = 0;858859if (rctx->b.chip_class >= CAYMAN) {860radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));861radeon_emit(cs, EVENT_TYPE(EVENT_TYPE_CS_PARTIAL_FLUSH) | EVENT_INDEX(4));862/* DEALLOC_STATE prevents the GPU from hanging when a863* SURFACE_SYNC packet is emitted some time after a DISPATCH_DIRECT864* with any of the CB*_DEST_BASE_ENA or DB_DEST_BASE_ENA bits set.865*/866radeon_emit(cs, PKT3C(PKT3_DEALLOC_STATE, 0, 0));867radeon_emit(cs, 0);868}869if (rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_TGSI ||870rctx->cs_shader_state.shader->ir_type == PIPE_SHADER_IR_NIR)871evergreen_emit_atomic_buffer_save(rctx, true, combined_atomics, &atomic_used_mask);872873#if 0874COMPUTE_DBG(rctx->screen, "cdw: %i\n", cs->cdw);875for (i = 0; i < cs->cdw; i++) {876COMPUTE_DBG(rctx->screen, "%4i : 0x%08X\n", i, cs->buf[i]);877}878#endif879880}881882883/**884* Emit function for r600_cs_shader_state atom885*/886void evergreen_emit_cs_shader(struct r600_context *rctx,887struct r600_atom *atom)888{889struct r600_cs_shader_state *state =890(struct r600_cs_shader_state*)atom;891struct r600_pipe_compute *shader = state->shader;892struct radeon_cmdbuf *cs = &rctx->b.gfx.cs;893uint64_t va;894struct r600_resource *code_bo;895unsigned ngpr, nstack;896897if (shader->ir_type == PIPE_SHADER_IR_TGSI ||898shader->ir_type == PIPE_SHADER_IR_NIR) {899code_bo = shader->sel->current->bo;900va = shader->sel->current->bo->gpu_address;901ngpr = shader->sel->current->shader.bc.ngpr;902nstack = shader->sel->current->shader.bc.nstack;903} else {904code_bo = shader->code_bo;905va = shader->code_bo->gpu_address + state->pc;906ngpr = shader->bc.ngpr;907nstack = shader->bc.nstack;908}909910radeon_compute_set_context_reg_seq(cs, R_0288D0_SQ_PGM_START_LS, 3);911radeon_emit(cs, va >> 8); /* R_0288D0_SQ_PGM_START_LS */912radeon_emit(cs, /* R_0288D4_SQ_PGM_RESOURCES_LS */913S_0288D4_NUM_GPRS(ngpr) |914S_0288D4_DX10_CLAMP(1) |915S_0288D4_STACK_SIZE(nstack));916radeon_emit(cs, 0); /* R_0288D8_SQ_PGM_RESOURCES_LS_2 */917918radeon_emit(cs, PKT3C(PKT3_NOP, 0, 0));919radeon_emit(cs, radeon_add_to_buffer_list(&rctx->b, &rctx->b.gfx,920code_bo, RADEON_USAGE_READ,921RADEON_PRIO_SHADER_BINARY));922}923924static void evergreen_launch_grid(struct pipe_context *ctx,925const struct pipe_grid_info *info)926{927struct r600_context *rctx = (struct r600_context *)ctx;928#ifdef HAVE_OPENCL929struct r600_pipe_compute *shader = rctx->cs_shader_state.shader;930boolean use_kill;931932if (shader->ir_type != PIPE_SHADER_IR_TGSI &&933shader->ir_type != PIPE_SHADER_IR_NIR) {934rctx->cs_shader_state.pc = info->pc;935/* Get the config information for this kernel. */936r600_shader_binary_read_config(&shader->binary, &shader->bc,937info->pc, &use_kill);938} else {939use_kill = false;940rctx->cs_shader_state.pc = 0;941}942#endif943944COMPUTE_DBG(rctx->screen, "*** evergreen_launch_grid: pc = %u\n", info->pc);945946947evergreen_compute_upload_input(ctx, info);948compute_emit_cs(rctx, info);949}950951static void evergreen_set_compute_resources(struct pipe_context *ctx,952unsigned start, unsigned count,953struct pipe_surface **surfaces)954{955struct r600_context *rctx = (struct r600_context *)ctx;956struct r600_surface **resources = (struct r600_surface **)surfaces;957958COMPUTE_DBG(rctx->screen, "*** evergreen_set_compute_resources: start = %u count = %u\n",959start, count);960961for (unsigned i = 0; i < count; i++) {962/* The First four vertex buffers are reserved for parameters and963* global buffers. */964unsigned vtx_id = 4 + i;965if (resources[i]) {966struct r600_resource_global *buffer =967(struct r600_resource_global*)968resources[i]->base.texture;969if (resources[i]->base.writable) {970assert(i+1 < 12);971972evergreen_set_rat(rctx->cs_shader_state.shader, i+1,973(struct r600_resource *)resources[i]->base.texture,974buffer->chunk->start_in_dw*4,975resources[i]->base.texture->width0);976}977978evergreen_cs_set_vertex_buffer(rctx, vtx_id,979buffer->chunk->start_in_dw * 4,980resources[i]->base.texture);981}982}983}984985static void evergreen_set_global_binding(struct pipe_context *ctx,986unsigned first, unsigned n,987struct pipe_resource **resources,988uint32_t **handles)989{990struct r600_context *rctx = (struct r600_context *)ctx;991struct compute_memory_pool *pool = rctx->screen->global_pool;992struct r600_resource_global **buffers =993(struct r600_resource_global **)resources;994unsigned i;995996COMPUTE_DBG(rctx->screen, "*** evergreen_set_global_binding first = %u n = %u\n",997first, n);998999if (!resources) {1000/* XXX: Unset */1001return;1002}10031004/* We mark these items for promotion to the pool if they1005* aren't already there */1006for (i = first; i < first + n; i++) {1007struct compute_memory_item *item = buffers[i]->chunk;10081009if (!is_item_in_pool(item))1010buffers[i]->chunk->status |= ITEM_FOR_PROMOTING;1011}10121013if (compute_memory_finalize_pending(pool, ctx) == -1) {1014/* XXX: Unset */1015return;1016}10171018for (i = first; i < first + n; i++)1019{1020uint32_t buffer_offset;1021uint32_t handle;1022assert(resources[i]->target == PIPE_BUFFER);1023assert(resources[i]->bind & PIPE_BIND_GLOBAL);10241025buffer_offset = util_le32_to_cpu(*(handles[i]));1026handle = buffer_offset + buffers[i]->chunk->start_in_dw * 4;10271028*(handles[i]) = util_cpu_to_le32(handle);1029}10301031/* globals for writing */1032evergreen_set_rat(rctx->cs_shader_state.shader, 0, pool->bo, 0, pool->size_in_dw * 4);1033/* globals for reading */1034evergreen_cs_set_vertex_buffer(rctx, 1, 0,1035(struct pipe_resource*)pool->bo);10361037/* constants for reading, LLVM puts them in text segment */1038evergreen_cs_set_vertex_buffer(rctx, 2, 0,1039(struct pipe_resource*)rctx->cs_shader_state.shader->code_bo);1040}10411042/**1043* This function initializes all the compute specific registers that need to1044* be initialized for each compute command stream. Registers that are common1045* to both compute and 3D will be initialized at the beginning of each compute1046* command stream by the start_cs_cmd atom. However, since the SET_CONTEXT_REG1047* packet requires that the shader type bit be set, we must initialize all1048* context registers needed for compute in this function. The registers1049* initialized by the start_cs_cmd atom can be found in evergreen_state.c in the1050* functions evergreen_init_atom_start_cs or cayman_init_atom_start_cs depending1051* on the GPU family.1052*/1053void evergreen_init_atom_start_compute_cs(struct r600_context *rctx)1054{1055struct r600_command_buffer *cb = &rctx->start_compute_cs_cmd;1056int num_threads;1057int num_stack_entries;10581059/* since all required registers are initialized in the1060* start_compute_cs_cmd atom, we can EMIT_EARLY here.1061*/1062r600_init_command_buffer(cb, 256);1063cb->pkt_flags = RADEON_CP_PACKET3_COMPUTE_MODE;10641065/* We're setting config registers here. */1066r600_store_value(cb, PKT3(PKT3_EVENT_WRITE, 0, 0));1067r600_store_value(cb, EVENT_TYPE(EVENT_TYPE_CS_PARTIAL_FLUSH) | EVENT_INDEX(4));10681069switch (rctx->b.family) {1070case CHIP_CEDAR:1071default:1072num_threads = 128;1073num_stack_entries = 256;1074break;1075case CHIP_REDWOOD:1076num_threads = 128;1077num_stack_entries = 256;1078break;1079case CHIP_JUNIPER:1080num_threads = 128;1081num_stack_entries = 512;1082break;1083case CHIP_CYPRESS:1084case CHIP_HEMLOCK:1085num_threads = 128;1086num_stack_entries = 512;1087break;1088case CHIP_PALM:1089num_threads = 128;1090num_stack_entries = 256;1091break;1092case CHIP_SUMO:1093num_threads = 128;1094num_stack_entries = 256;1095break;1096case CHIP_SUMO2:1097num_threads = 128;1098num_stack_entries = 512;1099break;1100case CHIP_BARTS:1101num_threads = 128;1102num_stack_entries = 512;1103break;1104case CHIP_TURKS:1105num_threads = 128;1106num_stack_entries = 256;1107break;1108case CHIP_CAICOS:1109num_threads = 128;1110num_stack_entries = 256;1111break;1112}11131114/* The primitive type always needs to be POINTLIST for compute. */1115r600_store_config_reg(cb, R_008958_VGT_PRIMITIVE_TYPE,1116V_008958_DI_PT_POINTLIST);11171118if (rctx->b.chip_class < CAYMAN) {11191120/* These registers control which simds can be used by each stage.1121* The default for these registers is 0xffffffff, which means1122* all simds are available for each stage. It's possible we may1123* want to play around with these in the future, but for now1124* the default value is fine.1125*1126* R_008E20_SQ_STATIC_THREAD_MGMT11127* R_008E24_SQ_STATIC_THREAD_MGMT21128* R_008E28_SQ_STATIC_THREAD_MGMT31129*/11301131/* XXX: We may need to adjust the thread and stack resource1132* values for 3D/compute interop */11331134r600_store_config_reg_seq(cb, R_008C18_SQ_THREAD_RESOURCE_MGMT_1, 5);11351136/* R_008C18_SQ_THREAD_RESOURCE_MGMT_11137* Set the number of threads used by the PS/VS/GS/ES stage to1138* 0.1139*/1140r600_store_value(cb, 0);11411142/* R_008C1C_SQ_THREAD_RESOURCE_MGMT_21143* Set the number of threads used by the CS (aka LS) stage to1144* the maximum number of threads and set the number of threads1145* for the HS stage to 0. */1146r600_store_value(cb, S_008C1C_NUM_LS_THREADS(num_threads));11471148/* R_008C20_SQ_STACK_RESOURCE_MGMT_11149* Set the Control Flow stack entries to 0 for PS/VS stages */1150r600_store_value(cb, 0);11511152/* R_008C24_SQ_STACK_RESOURCE_MGMT_21153* Set the Control Flow stack entries to 0 for GS/ES stages */1154r600_store_value(cb, 0);11551156/* R_008C28_SQ_STACK_RESOURCE_MGMT_31157* Set the Contol Flow stack entries to 0 for the HS stage, and1158* set it to the maximum value for the CS (aka LS) stage. */1159r600_store_value(cb,1160S_008C28_NUM_LS_STACK_ENTRIES(num_stack_entries));1161}1162/* Give the compute shader all the available LDS space.1163* NOTE: This only sets the maximum number of dwords that a compute1164* shader can allocate. When a shader is executed, we still need to1165* allocate the appropriate amount of LDS dwords using the1166* CM_R_0288E8_SQ_LDS_ALLOC register.1167*/1168if (rctx->b.chip_class < CAYMAN) {1169r600_store_config_reg(cb, R_008E2C_SQ_LDS_RESOURCE_MGMT,1170S_008E2C_NUM_PS_LDS(0x0000) | S_008E2C_NUM_LS_LDS(8192));1171} else {1172r600_store_context_reg(cb, CM_R_0286FC_SPI_LDS_MGMT,1173S_0286FC_NUM_PS_LDS(0) |1174S_0286FC_NUM_LS_LDS(255)); /* 255 * 32 = 8160 dwords */1175}11761177/* Context Registers */11781179if (rctx->b.chip_class < CAYMAN) {1180/* workaround for hw issues with dyn gpr - must set all limits1181* to 240 instead of 0, 0x1e == 240 / 81182*/1183r600_store_context_reg(cb, R_028838_SQ_DYN_GPR_RESOURCE_LIMIT_1,1184S_028838_PS_GPRS(0x1e) |1185S_028838_VS_GPRS(0x1e) |1186S_028838_GS_GPRS(0x1e) |1187S_028838_ES_GPRS(0x1e) |1188S_028838_HS_GPRS(0x1e) |1189S_028838_LS_GPRS(0x1e));1190}11911192/* XXX: Investigate setting bit 15, which is FAST_COMPUTE_MODE */1193r600_store_context_reg(cb, R_028A40_VGT_GS_MODE,1194S_028A40_COMPUTE_MODE(1) | S_028A40_PARTIAL_THD_AT_EOI(1));11951196r600_store_context_reg(cb, R_028B54_VGT_SHADER_STAGES_EN, 2/*CS_ON*/);11971198r600_store_context_reg(cb, R_0286E8_SPI_COMPUTE_INPUT_CNTL,1199S_0286E8_TID_IN_GROUP_ENA(1) |1200S_0286E8_TGID_ENA(1) |1201S_0286E8_DISABLE_INDEX_PACK(1));12021203/* The LOOP_CONST registers are an optimizations for loops that allows1204* you to store the initial counter, increment value, and maximum1205* counter value in a register so that hardware can calculate the1206* correct number of iterations for the loop, so that you don't need1207* to have the loop counter in your shader code. We don't currently use1208* this optimization, so we must keep track of the counter in the1209* shader and use a break instruction to exit loops. However, the1210* hardware will still uses this register to determine when to exit a1211* loop, so we need to initialize the counter to 0, set the increment1212* value to 1 and the maximum counter value to the 4095 (0xfff) which1213* is the maximum value allowed. This gives us a maximum of 40961214* iterations for our loops, but hopefully our break instruction will1215* execute before some time before the 4096th iteration.1216*/1217eg_store_loop_const(cb, R_03A200_SQ_LOOP_CONST_0 + (160 * 4), 0x1000FFF);1218}12191220void evergreen_init_compute_state_functions(struct r600_context *rctx)1221{1222rctx->b.b.create_compute_state = evergreen_create_compute_state;1223rctx->b.b.delete_compute_state = evergreen_delete_compute_state;1224rctx->b.b.bind_compute_state = evergreen_bind_compute_state;1225// rctx->context.create_sampler_view = evergreen_compute_create_sampler_view;1226rctx->b.b.set_compute_resources = evergreen_set_compute_resources;1227rctx->b.b.set_global_binding = evergreen_set_global_binding;1228rctx->b.b.launch_grid = evergreen_launch_grid;12291230}12311232void *r600_compute_global_transfer_map(struct pipe_context *ctx,1233struct pipe_resource *resource,1234unsigned level,1235unsigned usage,1236const struct pipe_box *box,1237struct pipe_transfer **ptransfer)1238{1239struct r600_context *rctx = (struct r600_context*)ctx;1240struct compute_memory_pool *pool = rctx->screen->global_pool;1241struct r600_resource_global* buffer =1242(struct r600_resource_global*)resource;12431244struct compute_memory_item *item = buffer->chunk;1245struct pipe_resource *dst = NULL;1246unsigned offset = box->x;12471248if (is_item_in_pool(item)) {1249compute_memory_demote_item(pool, item, ctx);1250}1251else {1252if (item->real_buffer == NULL) {1253item->real_buffer =1254r600_compute_buffer_alloc_vram(pool->screen, item->size_in_dw * 4);1255}1256}12571258dst = (struct pipe_resource*)item->real_buffer;12591260if (usage & PIPE_MAP_READ)1261buffer->chunk->status |= ITEM_MAPPED_FOR_READING;12621263COMPUTE_DBG(rctx->screen, "* r600_compute_global_transfer_map()\n"1264"level = %u, usage = %u, box(x = %u, y = %u, z = %u "1265"width = %u, height = %u, depth = %u)\n", level, usage,1266box->x, box->y, box->z, box->width, box->height,1267box->depth);1268COMPUTE_DBG(rctx->screen, "Buffer id = %"PRIi64" offset = "1269"%u (box.x)\n", item->id, box->x);127012711272assert(resource->target == PIPE_BUFFER);1273assert(resource->bind & PIPE_BIND_GLOBAL);1274assert(box->x >= 0);1275assert(box->y == 0);1276assert(box->z == 0);12771278///TODO: do it better, mapping is not possible if the pool is too big1279return pipe_buffer_map_range(ctx, dst,1280offset, box->width, usage, ptransfer);1281}12821283void r600_compute_global_transfer_unmap(struct pipe_context *ctx,1284struct pipe_transfer *transfer)1285{1286/* struct r600_resource_global are not real resources, they just map1287* to an offset within the compute memory pool. The function1288* r600_compute_global_transfer_map() maps the memory pool1289* resource rather than the struct r600_resource_global passed to1290* it as an argument and then initializes ptransfer->resource with1291* the memory pool resource (via pipe_buffer_map_range).1292* When transfer_unmap is called it uses the memory pool's1293* vtable which calls r600_buffer_transfer_map() rather than1294* this function.1295*/1296assert (!"This function should not be called");1297}12981299void r600_compute_global_buffer_destroy(struct pipe_screen *screen,1300struct pipe_resource *res)1301{1302struct r600_resource_global* buffer = NULL;1303struct r600_screen* rscreen = NULL;13041305assert(res->target == PIPE_BUFFER);1306assert(res->bind & PIPE_BIND_GLOBAL);13071308buffer = (struct r600_resource_global*)res;1309rscreen = (struct r600_screen*)screen;13101311compute_memory_free(rscreen->global_pool, buffer->chunk->id);13121313buffer->chunk = NULL;1314free(res);1315}13161317struct pipe_resource *r600_compute_global_buffer_create(struct pipe_screen *screen,1318const struct pipe_resource *templ)1319{1320struct r600_resource_global* result = NULL;1321struct r600_screen* rscreen = NULL;1322int size_in_dw = 0;13231324assert(templ->target == PIPE_BUFFER);1325assert(templ->bind & PIPE_BIND_GLOBAL);1326assert(templ->array_size == 1 || templ->array_size == 0);1327assert(templ->depth0 == 1 || templ->depth0 == 0);1328assert(templ->height0 == 1 || templ->height0 == 0);13291330result = (struct r600_resource_global*)1331CALLOC(sizeof(struct r600_resource_global), 1);1332rscreen = (struct r600_screen*)screen;13331334COMPUTE_DBG(rscreen, "*** r600_compute_global_buffer_create\n");1335COMPUTE_DBG(rscreen, "width = %u array_size = %u\n", templ->width0,1336templ->array_size);13371338result->base.b.b = *templ;1339result->base.b.b.screen = screen;1340result->base.compute_global_bo = true;1341pipe_reference_init(&result->base.b.b.reference, 1);13421343size_in_dw = (templ->width0+3) / 4;13441345result->chunk = compute_memory_alloc(rscreen->global_pool, size_in_dw);13461347if (result->chunk == NULL)1348{1349free(result);1350return NULL;1351}13521353return &result->base.b.b;1354}135513561357