*/
-struct r600_resource* r600_compute_buffer_alloc_vram(
- struct r600_screen *screen,
- unsigned size)
+struct r600_resource *r600_compute_buffer_alloc_vram(struct r600_screen *screen,
+ unsigned size)
{
- struct pipe_resource * buffer = NULL;
+ struct pipe_resource *buffer = NULL;
assert(size);
- buffer = pipe_buffer_create(
- (struct pipe_screen*) screen,
- PIPE_BIND_CUSTOM,
- PIPE_USAGE_IMMUTABLE,
- size);
+ buffer = pipe_buffer_create((struct pipe_screen*) screen,
+ PIPE_BIND_CUSTOM,
+ PIPE_USAGE_IMMUTABLE,
+ size);
return (struct r600_resource *)buffer;
}
-static void evergreen_set_rat(
- struct r600_pipe_compute *pipe,
- unsigned id,
- struct r600_resource* bo,
- int start,
- int size)
+static void evergreen_set_rat(struct r600_pipe_compute *pipe,
+ unsigned id,
+ struct r600_resource *bo,
+ int start,
+ int size)
{
struct pipe_surface rat_templ;
struct r600_surface *surf = NULL;
evergreen_init_color_surface_rat(rctx, surf);
}
-static void evergreen_cs_set_vertex_buffer(
- struct r600_context * rctx,
- unsigned vb_index,
- unsigned offset,
- struct pipe_resource * buffer)
+static void evergreen_cs_set_vertex_buffer(struct r600_context *rctx,
+ unsigned vb_index,
+ unsigned offset,
+ struct pipe_resource *buffer)
{
struct r600_vertexbuf_state *state = &rctx->cs_vertex_buffer_state;
struct pipe_vertex_buffer *vb = &state->vb[vb_index];
r600_mark_atom_dirty(rctx, &state->atom);
}
-static void evergreen_cs_set_constant_buffer(
- struct r600_context * rctx,
- unsigned cb_index,
- unsigned offset,
- unsigned size,
- struct pipe_resource * buffer)
+static void evergreen_cs_set_constant_buffer(struct r600_context *rctx,
+ unsigned cb_index,
+ unsigned offset,
+ unsigned size,
+ struct pipe_resource *buffer)
{
struct pipe_constant_buffer cb;
cb.buffer_size = size;
r600_compute_global_transfer_inline_write /* transfer_inline_write */
};
+/* We need to define these R600 registers here, because we can't include
+ * evergreend.h and r600d.h.
+ */
+#define R_028868_SQ_PGM_RESOURCES_VS 0x028868
+#define R_028850_SQ_PGM_RESOURCES_PS 0x028850
+
+#ifdef HAVE_OPENCL
-void *evergreen_create_compute_state(
- struct pipe_context *ctx_,
- const const struct pipe_compute_state *cso)
+static void r600_shader_binary_read_config(const struct radeon_shader_binary *binary,
+ struct r600_bytecode *bc,
+ uint64_t symbol_offset,
+ boolean *use_kill)
+{
+ unsigned i;
+ const unsigned char *config =
+ radeon_shader_binary_config_start(binary, symbol_offset);
+
+ for (i = 0; i < binary->config_size_per_symbol; i+= 8) {
+ unsigned reg =
+ util_le32_to_cpu(*(uint32_t*)(config + i));
+ unsigned value =
+ util_le32_to_cpu(*(uint32_t*)(config + i + 4));
+ switch (reg) {
+ /* R600 / R700 */
+ case R_028850_SQ_PGM_RESOURCES_PS:
+ case R_028868_SQ_PGM_RESOURCES_VS:
+ /* Evergreen / Northern Islands */
+ case R_028844_SQ_PGM_RESOURCES_PS:
+ case R_028860_SQ_PGM_RESOURCES_VS:
+ case R_0288D4_SQ_PGM_RESOURCES_LS:
+ bc->ngpr = MAX2(bc->ngpr, G_028844_NUM_GPRS(value));
+ bc->nstack = MAX2(bc->nstack, G_028844_STACK_SIZE(value));
+ break;
+ case R_02880C_DB_SHADER_CONTROL:
+ *use_kill = G_02880C_KILL_ENABLE(value);
+ break;
+ case R_0288E8_SQ_LDS_ALLOC:
+ bc->nlds_dw = value;
+ break;
+ }
+ }
+}
+
+static unsigned r600_create_shader(struct r600_bytecode *bc,
+ const struct radeon_shader_binary *binary,
+ boolean *use_kill)
+
+{
+ assert(binary->code_size % 4 == 0);
+ bc->bytecode = CALLOC(1, binary->code_size);
+ memcpy(bc->bytecode, binary->code, binary->code_size);
+ bc->ndw = binary->code_size / 4;
+
+ r600_shader_binary_read_config(binary, bc, 0, use_kill);
+ return 0;
+}
+
+#endif
+
+static void r600_destroy_shader(struct r600_bytecode *bc)
+{
+ FREE(bc->bytecode);
+}
+
+void *evergreen_create_compute_state(struct pipe_context *ctx_,
+ const const struct pipe_compute_state *cso)
{
struct r600_context *ctx = (struct r600_context *)ctx_;
struct r600_pipe_compute *shader = CALLOC_STRUCT(r600_pipe_compute);
#ifdef HAVE_OPENCL
- const struct pipe_llvm_program_header * header;
+ const struct pipe_llvm_program_header *header;
const char *code;
void *p;
boolean use_kill;
COMPUTE_DBG(ctx->screen, "*** evergreen_create_compute_state\n");
header = cso->prog;
code = cso->prog + sizeof(struct pipe_llvm_program_header);
-#if HAVE_LLVM < 0x0306
- (void)use_kill;
- (void)p;
- shader->llvm_ctx = LLVMContextCreate();
- shader->num_kernels = radeon_llvm_get_num_kernels(shader->llvm_ctx,
- code, header->num_bytes);
- shader->kernels = CALLOC(sizeof(struct r600_kernel),
- shader->num_kernels);
- {
- unsigned i;
- for (i = 0; i < shader->num_kernels; i++) {
- struct r600_kernel *kernel = &shader->kernels[i];
- kernel->llvm_module = radeon_llvm_get_kernel_module(
- shader->llvm_ctx, i, code, header->num_bytes);
- }
- }
-#else
- memset(&shader->binary, 0, sizeof(shader->binary));
+ radeon_shader_binary_init(&shader->binary);
radeon_elf_read(code, header->num_bytes, &shader->binary);
r600_create_shader(&shader->bc, &shader->binary, &use_kill);
p = r600_buffer_map_sync_with_rings(&ctx->b, shader->code_bo, PIPE_TRANSFER_WRITE);
memcpy(p, shader->bc.bytecode, shader->bc.ndw * 4);
ctx->b.ws->buffer_unmap(shader->code_bo->buf);
-#endif
#endif
shader->ctx = ctx;
return shader;
}
-void evergreen_delete_compute_state(struct pipe_context *ctx, void* state)
+void evergreen_delete_compute_state(struct pipe_context *ctx_, void *state)
{
- struct r600_pipe_compute *shader = (struct r600_pipe_compute *)state;
+ struct r600_context *ctx = (struct r600_context *)ctx_;
+ struct r600_pipe_compute *shader = state;
+
+ COMPUTE_DBG(ctx->screen, "*** evergreen_delete_compute_state\n");
if (!shader)
return;
+ radeon_shader_binary_clean(&shader->binary);
+ r600_destroy_shader(&shader->bc);
+
+ /* TODO destroy shader->code_bo, shader->const_bo
+ * we'll need something like r600_buffer_free */
FREE(shader);
}
* (x,y,z)
* DWORDS 9+ : Kernel parameters
*/
-void evergreen_compute_upload_input(
- struct pipe_context *ctx_,
- const uint *block_layout,
- const uint *grid_layout,
- const void *input)
+void evergreen_compute_upload_input(struct pipe_context *ctx_,
+ const uint *block_layout,
+ const uint *grid_layout,
+ const void *input)
{
struct r600_context *ctx = (struct r600_context *)ctx_;
struct r600_pipe_compute *shader = ctx->cs_shader_state.shader;
* parameters.
*/
unsigned input_size = shader->input_size + 36;
- uint32_t * num_work_groups_start;
- uint32_t * global_size_start;
- uint32_t * local_size_start;
- uint32_t * kernel_parameters_start;
+ uint32_t *num_work_groups_start;
+ uint32_t *global_size_start;
+ uint32_t *local_size_start;
+ uint32_t *kernel_parameters_start;
struct pipe_box box;
struct pipe_transfer *transfer = NULL;
(struct pipe_resource*)shader->kernel_param);
}
-static void evergreen_emit_direct_dispatch(
- struct r600_context *rctx,
- const uint *block_layout, const uint *grid_layout)
+static void evergreen_emit_direct_dispatch(struct r600_context *rctx,
+ const uint *block_layout,
+ const uint *grid_layout)
{
int i;
struct radeon_winsys_cs *cs = rctx->b.gfx.cs;
struct r600_pipe_compute *shader = rctx->cs_shader_state.shader;
unsigned num_waves;
- unsigned num_pipes = rctx->screen->b.info.r600_max_pipes;
+ unsigned num_pipes = rctx->screen->b.info.r600_max_quad_pipes;
unsigned wave_divisor = (16 * num_pipes);
int group_size = 1;
int grid_size = 1;
unsigned lds_size = shader->local_size / 4 +
-#if HAVE_LLVM < 0x0306
- shader->active_kernel->bc.nlds_dw;
-#else
shader->bc.nlds_dw;
-#endif
/* Calculate group_size/grid_size */
radeon_emit(cs, 1);
}
-static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
- const uint *grid_layout)
+static void compute_emit_cs(struct r600_context *ctx,
+ const uint *block_layout,
+ const uint *grid_layout)
{
struct radeon_winsys_cs *cs = ctx->b.gfx.cs;
unsigned i;
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C60_CB_COLOR0_BASE */
radeon_emit(cs, reloc);
- if (!ctx->keep_tiling_flags) {
- radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C70_CB_COLOR0_INFO */
- radeon_emit(cs, reloc);
- }
-
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* R_028C74_CB_COLOR0_ATTRIB */
radeon_emit(cs, reloc);
}
- if (ctx->keep_tiling_flags) {
- for (; i < 8 ; i++) {
- radeon_compute_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C,
- S_028C70_FORMAT(V_028C70_COLOR_INVALID));
- }
- for (; i < 12; i++) {
- radeon_compute_set_context_reg(cs, R_028E50_CB_COLOR8_INFO + (i - 8) * 0x1C,
- S_028C70_FORMAT(V_028C70_COLOR_INVALID));
- }
- }
+ for (; i < 8 ; i++)
+ radeon_compute_set_context_reg(cs, R_028C70_CB_COLOR0_INFO + i * 0x3C,
+ S_028C70_FORMAT(V_028C70_COLOR_INVALID));
+ for (; i < 12; i++)
+ radeon_compute_set_context_reg(cs, R_028E50_CB_COLOR8_INFO + (i - 8) * 0x1C,
+ S_028C70_FORMAT(V_028C70_COLOR_INVALID));
/* Set CB_TARGET_MASK XXX: Use cb_misc_state */
radeon_compute_set_context_reg(cs, R_028238_CB_TARGET_MASK,
/**
* Emit function for r600_cs_shader_state atom
*/
-void evergreen_emit_cs_shader(
- struct r600_context *rctx,
- struct r600_atom *atom)
+void evergreen_emit_cs_shader(struct r600_context *rctx,
+ struct r600_atom *atom)
{
struct r600_cs_shader_state *state =
(struct r600_cs_shader_state*)atom;
struct r600_resource *code_bo;
unsigned ngpr, nstack;
-#if HAVE_LLVM < 0x0306
- struct r600_kernel *kernel = &shader->kernels[state->kernel_index];
- code_bo = kernel->code_bo;
- va = kernel->code_bo->gpu_address;
- ngpr = kernel->bc.ngpr;
- nstack = kernel->bc.nstack;
-#else
code_bo = shader->code_bo;
va = shader->code_bo->gpu_address + state->pc;
ngpr = shader->bc.ngpr;
nstack = shader->bc.nstack;
-#endif
radeon_compute_set_context_reg_seq(cs, R_0288D0_SQ_PGM_START_LS, 3);
radeon_emit(cs, va >> 8); /* R_0288D0_SQ_PGM_START_LS */
RADEON_PRIO_USER_SHADER));
}
-static void evergreen_launch_grid(
- struct pipe_context *ctx_,
- const uint *block_layout, const uint *grid_layout,
- uint32_t pc, const void *input)
+static void evergreen_launch_grid(struct pipe_context *ctx_,
+ const struct pipe_grid_info *info)
{
struct r600_context *ctx = (struct r600_context *)ctx_;
#ifdef HAVE_OPENCL
struct r600_pipe_compute *shader = ctx->cs_shader_state.shader;
boolean use_kill;
-#if HAVE_LLVM < 0x0306
- struct r600_kernel *kernel = &shader->kernels[pc];
- (void)use_kill;
- if (!kernel->code_bo) {
- void *p;
- struct r600_bytecode *bc = &kernel->bc;
- LLVMModuleRef mod = kernel->llvm_module;
- boolean use_kill = false;
- bool dump = (ctx->screen->b.debug_flags & DBG_CS) != 0;
- unsigned use_sb = ctx->screen->b.debug_flags & DBG_SB_CS;
- unsigned sb_disasm = use_sb ||
- (ctx->screen->b.debug_flags & DBG_SB_DISASM);
-
- r600_bytecode_init(bc, ctx->b.chip_class, ctx->b.family,
- ctx->screen->has_compressed_msaa_texturing);
- bc->type = TGSI_PROCESSOR_COMPUTE;
- bc->isa = ctx->isa;
- r600_llvm_compile(mod, ctx->b.family, bc, &use_kill, dump);
-
- if (dump && !sb_disasm) {
- r600_bytecode_disasm(bc);
- } else if ((dump && sb_disasm) || use_sb) {
- if (r600_sb_bytecode_process(ctx, bc, NULL, dump, use_sb))
- R600_ERR("r600_sb_bytecode_process failed!\n");
- }
-
- kernel->code_bo = r600_compute_buffer_alloc_vram(ctx->screen,
- kernel->bc.ndw * 4);
- p = r600_buffer_map_sync_with_rings(&ctx->b, kernel->code_bo, PIPE_TRANSFER_WRITE);
- memcpy(p, kernel->bc.bytecode, kernel->bc.ndw * 4);
- ctx->b.ws->buffer_unmap(kernel->code_bo->buf);
- }
- shader->active_kernel = kernel;
- ctx->cs_shader_state.kernel_index = pc;
-#else
- ctx->cs_shader_state.pc = pc;
+ ctx->cs_shader_state.pc = info->pc;
/* Get the config information for this kernel. */
- r600_shader_binary_read_config(&shader->binary, &shader->bc, pc, &use_kill);
-#endif
+ r600_shader_binary_read_config(&shader->binary, &shader->bc,
+ info->pc, &use_kill);
#endif
- COMPUTE_DBG(ctx->screen, "*** evergreen_launch_grid: pc = %u\n", pc);
+ COMPUTE_DBG(ctx->screen, "*** evergreen_launch_grid: pc = %u\n", info->pc);
- evergreen_compute_upload_input(ctx_, block_layout, grid_layout, input);
- compute_emit_cs(ctx, block_layout, grid_layout);
+ evergreen_compute_upload_input(ctx_, info->block, info->grid, info->input);
+ compute_emit_cs(ctx, info->block, info->grid);
}
-static void evergreen_set_compute_resources(struct pipe_context * ctx_,
- unsigned start, unsigned count,
- struct pipe_surface ** surfaces)
+static void evergreen_set_compute_resources(struct pipe_context *ctx_,
+ unsigned start, unsigned count,
+ struct pipe_surface **surfaces)
{
struct r600_context *ctx = (struct r600_context *)ctx_;
struct r600_surface **resources = (struct r600_surface **)surfaces;
}
}
-static void evergreen_set_global_binding(
- struct pipe_context *ctx_, unsigned first, unsigned n,
- struct pipe_resource **resources,
- uint32_t **handles)
+static void evergreen_set_global_binding(struct pipe_context *ctx_,
+ unsigned first, unsigned n,
+ struct pipe_resource **resources,
+ uint32_t **handles)
{
struct r600_context *ctx = (struct r600_context *)ctx_;
struct compute_memory_pool *pool = ctx->screen->global_pool;
* command stream by the start_cs_cmd atom. However, since the SET_CONTEXT_REG
* packet requires that the shader type bit be set, we must initialize all
* context registers needed for compute in this function. The registers
- * intialized by the start_cs_cmd atom can be found in evereen_state.c in the
+ * initialized by the start_cs_cmd atom can be found in evergreen_state.c in the
* functions evergreen_init_atom_start_cs or cayman_init_atom_start_cs depending
* on the GPU family.
*/
int num_threads;
int num_stack_entries;
- /* since all required registers are initialised in the
+ /* since all required registers are initialized in the
* start_compute_cs_cmd atom, we can EMIT_EARLY here.
*/
r600_init_command_buffer(cb, 256);
* R_008E28_SQ_STATIC_THREAD_MGMT3
*/
- /* XXX: We may need to adjust the thread and stack resouce
+ /* XXX: We may need to adjust the thread and stack resource
* values for 3D/compute interop */
r600_store_config_reg_seq(cb, R_008C18_SQ_THREAD_RESOURCE_MGMT_1, 5);
}
-struct pipe_resource *r600_compute_global_buffer_create(
- struct pipe_screen *screen,
- const struct pipe_resource *templ)
+struct pipe_resource *r600_compute_global_buffer_create(struct pipe_screen *screen,
+ const struct pipe_resource *templ)
{
struct r600_resource_global* result = NULL;
struct r600_screen* rscreen = NULL;
templ->array_size);
result->base.b.vtbl = &r600_global_buffer_vtbl;
- result->base.b.b.screen = screen;
result->base.b.b = *templ;
+ result->base.b.b.screen = screen;
pipe_reference_init(&result->base.b.b.reference, 1);
size_in_dw = (templ->width0+3) / 4;
return &result->base.b.b;
}
-void r600_compute_global_buffer_destroy(
- struct pipe_screen *screen,
- struct pipe_resource *res)
+void r600_compute_global_buffer_destroy(struct pipe_screen *screen,
+ struct pipe_resource *res)
{
struct r600_resource_global* buffer = NULL;
struct r600_screen* rscreen = NULL;
free(res);
}
-void *r600_compute_global_transfer_map(
- struct pipe_context *ctx_,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- struct pipe_transfer **ptransfer)
+void *r600_compute_global_transfer_map(struct pipe_context *ctx_,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ struct pipe_transfer **ptransfer)
{
struct r600_context *rctx = (struct r600_context*)ctx_;
struct compute_memory_pool *pool = rctx->screen->global_pool;
offset, box->width, usage, ptransfer);
}
-void r600_compute_global_transfer_unmap(
- struct pipe_context *ctx_,
- struct pipe_transfer* transfer)
+void r600_compute_global_transfer_unmap(struct pipe_context *ctx_,
+ struct pipe_transfer *transfer)
{
/* struct r600_resource_global are not real resources, they just map
* to an offset within the compute memory pool. The function
assert (!"This function should not be called");
}
-void r600_compute_global_transfer_flush_region(
- struct pipe_context *ctx_,
- struct pipe_transfer *transfer,
- const struct pipe_box *box)
+void r600_compute_global_transfer_flush_region(struct pipe_context *ctx_,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
{
assert(0 && "TODO");
}
-void r600_compute_global_transfer_inline_write(
- struct pipe_context *pipe,
- struct pipe_resource *resource,
- unsigned level,
- unsigned usage,
- const struct pipe_box *box,
- const void *data,
- unsigned stride,
- unsigned layer_stride)
+void r600_compute_global_transfer_inline_write(struct pipe_context *pipe,
+ struct pipe_resource *resource,
+ unsigned level,
+ unsigned usage,
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned layer_stride)
{
assert(0 && "TODO");
}