Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include "util/u_memory.h"
  2.  
  3. #include "radeonsi_pipe.h"
  4. #include "radeonsi_shader.h"
  5.  
  6. #include "radeon_llvm_util.h"
  7.  
  8. #define MAX_GLOBAL_BUFFERS 20
  9.  
  10. struct si_pipe_compute {
  11.         struct r600_context *ctx;
  12.  
  13.         unsigned local_size;
  14.         unsigned private_size;
  15.         unsigned input_size;
  16.         unsigned num_kernels;
  17.         struct si_pipe_shader *kernels;
  18.         unsigned num_user_sgprs;
  19.  
  20.         struct pipe_resource *global_buffers[MAX_GLOBAL_BUFFERS];
  21.  
  22. };
  23.  
  24. static void *radeonsi_create_compute_state(
  25.         struct pipe_context *ctx,
  26.         const struct pipe_compute_state *cso)
  27. {
  28.         struct r600_context *rctx = (struct r600_context *)ctx;
  29.         struct si_pipe_compute *program =
  30.                                         CALLOC_STRUCT(si_pipe_compute);
  31.         const struct pipe_llvm_program_header *header;
  32.         const unsigned char *code;
  33.         unsigned i;
  34.  
  35.         header = cso->prog;
  36.         code = cso->prog + sizeof(struct pipe_llvm_program_header);
  37.  
  38.         program->ctx = rctx;
  39.         program->local_size = cso->req_local_mem;
  40.         program->private_size = cso->req_private_mem;
  41.         program->input_size = cso->req_input_mem;
  42.  
  43.         program->num_kernels = radeon_llvm_get_num_kernels(code,
  44.                                                         header->num_bytes);
  45.         program->kernels = CALLOC(sizeof(struct si_pipe_shader),
  46.                                                         program->num_kernels);
  47.         for (i = 0; i < program->num_kernels; i++) {
  48.                 LLVMModuleRef mod = radeon_llvm_get_kernel_module(i, code,
  49.                                                         header->num_bytes);
  50.                 si_compile_llvm(rctx, &program->kernels[i], mod);
  51.         }
  52.  
  53.         return program;
  54. }
  55.  
  56. static void radeonsi_bind_compute_state(struct pipe_context *ctx, void *state)
  57. {
  58.         struct r600_context *rctx = (struct r600_context*)ctx;
  59.         rctx->cs_shader_state.program = (struct si_pipe_compute*)state;
  60. }
  61.  
  62. static void radeonsi_set_global_binding(
  63.         struct pipe_context *ctx, unsigned first, unsigned n,
  64.         struct pipe_resource **resources,
  65.         uint32_t **handles)
  66. {
  67.         unsigned i;
  68.         struct r600_context *rctx = (struct r600_context*)ctx;
  69.         struct si_pipe_compute *program = rctx->cs_shader_state.program;
  70.  
  71.         if (!resources) {
  72.                 for (i = first; i < first + n; i++) {
  73.                         program->global_buffers[i] = NULL;
  74.                 }
  75.                 return;
  76.         }
  77.  
  78.         for (i = first; i < first + n; i++) {
  79.                 uint64_t va;
  80.                 program->global_buffers[i] = resources[i];
  81.                 va = r600_resource_va(ctx->screen, resources[i]);
  82.                 memcpy(handles[i], &va, sizeof(va));
  83.         }
  84. }
  85.  
  86. static void radeonsi_launch_grid(
  87.                 struct pipe_context *ctx,
  88.                 const uint *block_layout, const uint *grid_layout,
  89.                 uint32_t pc, const void *input)
  90. {
  91.         struct r600_context *rctx = (struct r600_context*)ctx;
  92.         struct si_pipe_compute *program = rctx->cs_shader_state.program;
  93.         struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
  94.         struct si_resource *kernel_args_buffer = NULL;
  95.         unsigned kernel_args_size;
  96.         unsigned num_work_size_bytes = 36;
  97.         uint32_t kernel_args_offset = 0;
  98.         uint32_t *kernel_args;
  99.         uint64_t kernel_args_va;
  100.         uint64_t shader_va;
  101.         unsigned arg_user_sgpr_count = 2;
  102.         unsigned i;
  103.         struct si_pipe_shader *shader = &program->kernels[pc];
  104.  
  105.         pm4->compute_pkt = true;
  106.         si_cmd_context_control(pm4);
  107.  
  108.         si_pm4_cmd_begin(pm4, PKT3_EVENT_WRITE);
  109.         si_pm4_cmd_add(pm4, EVENT_TYPE(EVENT_TYPE_CACHE_FLUSH) |
  110.                             EVENT_INDEX(0x7) |
  111.                             EVENT_WRITE_INV_L2);
  112.         si_pm4_cmd_end(pm4, false);
  113.  
  114.         si_pm4_inval_texture_cache(pm4);
  115.         si_pm4_inval_shader_cache(pm4);
  116.         si_cmd_surface_sync(pm4, pm4->cp_coher_cntl);
  117.  
  118.         /* Upload the kernel arguments */
  119.  
  120.         /* The extra num_work_size_bytes are for work group / work item size information */
  121.         kernel_args_size = program->input_size + num_work_size_bytes;
  122.         kernel_args = MALLOC(kernel_args_size);
  123.         for (i = 0; i < 3; i++) {
  124.                 kernel_args[i] = grid_layout[i];
  125.                 kernel_args[i + 3] = grid_layout[i] * block_layout[i];
  126.                 kernel_args[i + 6] = block_layout[i];
  127.         }
  128.  
  129.         memcpy(kernel_args + (num_work_size_bytes / 4), input, program->input_size);
  130.  
  131.         r600_upload_const_buffer(rctx, &kernel_args_buffer, (uint8_t*)kernel_args,
  132.                                         kernel_args_size, &kernel_args_offset);
  133.         kernel_args_va = r600_resource_va(ctx->screen,
  134.                                 (struct pipe_resource*)kernel_args_buffer);
  135.         kernel_args_va += kernel_args_offset;
  136.  
  137.         si_pm4_add_bo(pm4, kernel_args_buffer, RADEON_USAGE_READ);
  138.  
  139.         si_pm4_set_reg(pm4, R_00B900_COMPUTE_USER_DATA_0, kernel_args_va);
  140.         si_pm4_set_reg(pm4, R_00B900_COMPUTE_USER_DATA_0 + 4, S_008F04_BASE_ADDRESS_HI (kernel_args_va >> 32) | S_008F04_STRIDE(0));
  141.  
  142.         si_pm4_set_reg(pm4, R_00B810_COMPUTE_START_X, 0);
  143.         si_pm4_set_reg(pm4, R_00B814_COMPUTE_START_Y, 0);
  144.         si_pm4_set_reg(pm4, R_00B818_COMPUTE_START_Z, 0);
  145.  
  146.         si_pm4_set_reg(pm4, R_00B81C_COMPUTE_NUM_THREAD_X,
  147.                                 S_00B81C_NUM_THREAD_FULL(block_layout[0]));
  148.         si_pm4_set_reg(pm4, R_00B820_COMPUTE_NUM_THREAD_Y,
  149.                                 S_00B820_NUM_THREAD_FULL(block_layout[1]));
  150.         si_pm4_set_reg(pm4, R_00B824_COMPUTE_NUM_THREAD_Z,
  151.                                 S_00B824_NUM_THREAD_FULL(block_layout[2]));
  152.  
  153.         /* Global buffers */
  154.         for (i = 0; i < MAX_GLOBAL_BUFFERS; i++) {
  155.                 struct si_resource *buffer =
  156.                                 (struct si_resource*)program->global_buffers[i];
  157.                 if (!buffer) {
  158.                         continue;
  159.                 }
  160.                 si_pm4_add_bo(pm4, buffer, RADEON_USAGE_READWRITE);
  161.         }
  162.  
  163.         /* XXX: This should be:
  164.          * (number of compute units) * 4 * (waves per simd) - 1 */
  165.         si_pm4_set_reg(pm4, R_00B82C_COMPUTE_MAX_WAVE_ID, 0x190 /* Default value */);
  166.  
  167.         shader_va = r600_resource_va(ctx->screen, (void *)shader->bo);
  168.         si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
  169.         si_pm4_set_reg(pm4, R_00B830_COMPUTE_PGM_LO, (shader_va >> 8) & 0xffffffff);
  170.         si_pm4_set_reg(pm4, R_00B834_COMPUTE_PGM_HI, shader_va >> 40);
  171.  
  172.         si_pm4_set_reg(pm4, R_00B848_COMPUTE_PGM_RSRC1,
  173.                 /* We always use at least 3 VGPRS, these come from
  174.                  * TIDIG_COMP_CNT.
  175.                  * XXX: The compiler should account for this.
  176.                  */
  177.                 S_00B848_VGPRS((MAX2(3, shader->num_vgprs) - 1) / 4)
  178.                 /* We always use at least 4 + arg_user_sgpr_count.  The 4 extra
  179.                  * sgprs are from TGID_X_EN, TGID_Y_EN, TGID_Z_EN, TG_SIZE_EN
  180.                  * XXX: The compiler should account for this.
  181.                  */
  182.                 |  S_00B848_SGPRS(((MAX2(4 + arg_user_sgpr_count,
  183.                                         shader->num_sgprs)) - 1) / 8))
  184.                 ;
  185.  
  186.         si_pm4_set_reg(pm4, R_00B84C_COMPUTE_PGM_RSRC2,
  187.                 S_00B84C_SCRATCH_EN(0)
  188.                 | S_00B84C_USER_SGPR(arg_user_sgpr_count)
  189.                 | S_00B84C_TGID_X_EN(1)
  190.                 | S_00B84C_TGID_Y_EN(1)
  191.                 | S_00B84C_TGID_Z_EN(1)
  192.                 | S_00B84C_TG_SIZE_EN(1)
  193.                 | S_00B84C_TIDIG_COMP_CNT(2)
  194.                 | S_00B84C_LDS_SIZE(shader->lds_size)
  195.                 | S_00B84C_EXCP_EN(0))
  196.                 ;
  197.         si_pm4_set_reg(pm4, R_00B854_COMPUTE_RESOURCE_LIMITS, 0);
  198.  
  199.         si_pm4_set_reg(pm4, R_00B858_COMPUTE_STATIC_THREAD_MGMT_SE0,
  200.                 S_00B858_SH0_CU_EN(0xffff /* Default value */)
  201.                 | S_00B858_SH1_CU_EN(0xffff /* Default value */))
  202.                 ;
  203.  
  204.         si_pm4_set_reg(pm4, R_00B85C_COMPUTE_STATIC_THREAD_MGMT_SE1,
  205.                 S_00B85C_SH0_CU_EN(0xffff /* Default value */)
  206.                 | S_00B85C_SH1_CU_EN(0xffff /* Default value */))
  207.                 ;
  208.  
  209.         si_pm4_cmd_begin(pm4, PKT3_DISPATCH_DIRECT);
  210.         si_pm4_cmd_add(pm4, grid_layout[0]); /* Thread groups DIM_X */
  211.         si_pm4_cmd_add(pm4, grid_layout[1]); /* Thread groups DIM_Y */
  212.         si_pm4_cmd_add(pm4, grid_layout[2]); /* Thread gropus DIM_Z */
  213.         si_pm4_cmd_add(pm4, 1); /* DISPATCH_INITIATOR */
  214.         si_pm4_cmd_end(pm4, false);
  215.  
  216.         si_pm4_cmd_begin(pm4, PKT3_EVENT_WRITE);
  217.         si_pm4_cmd_add(pm4, EVENT_TYPE(V_028A90_CS_PARTIAL_FLUSH | EVENT_INDEX(0x4)));
  218.         si_pm4_cmd_end(pm4, false);
  219.  
  220.         si_pm4_inval_texture_cache(pm4);
  221.         si_pm4_inval_shader_cache(pm4);
  222.         si_cmd_surface_sync(pm4, pm4->cp_coher_cntl);
  223.  
  224.         si_pm4_emit(rctx, pm4);
  225.  
  226. #if 0
  227.         fprintf(stderr, "cdw: %i\n", rctx->cs->cdw);
  228.         for (i = 0; i < rctx->cs->cdw; i++) {
  229.                 fprintf(stderr, "%4i : 0x%08X\n", i, rctx->cs->buf[i]);
  230.         }
  231. #endif
  232.  
  233.         rctx->ws->cs_flush(rctx->cs, RADEON_FLUSH_COMPUTE, 0);
  234.         rctx->ws->buffer_wait(shader->bo->buf, 0);
  235.  
  236.         FREE(pm4);
  237.         FREE(kernel_args);
  238. }
  239.  
  240.  
  241. static void si_delete_compute_state(struct pipe_context *ctx, void* state){}
  242. static void si_set_compute_resources(struct pipe_context * ctx_,
  243.                 unsigned start, unsigned count,
  244.                 struct pipe_surface ** surfaces) { }
  245. static void si_set_cs_sampler_view(struct pipe_context *ctx_,
  246.                 unsigned start_slot, unsigned count,
  247.                 struct pipe_sampler_view **views) { }
  248.  
  249. static void si_bind_compute_sampler_states(
  250.         struct pipe_context *ctx_,
  251.         unsigned start_slot,
  252.         unsigned num_samplers,
  253.         void **samplers_) { }
  254. void si_init_compute_functions(struct r600_context *rctx)
  255. {
  256.         rctx->context.create_compute_state = radeonsi_create_compute_state;
  257.         rctx->context.delete_compute_state = si_delete_compute_state;
  258.         rctx->context.bind_compute_state = radeonsi_bind_compute_state;
  259. /*       ctx->context.create_sampler_view = evergreen_compute_create_sampler_view; */
  260.         rctx->context.set_compute_resources = si_set_compute_resources;
  261.         rctx->context.set_compute_sampler_views = si_set_cs_sampler_view;
  262.         rctx->context.bind_compute_sampler_states = si_bind_compute_sampler_states;
  263.         rctx->context.set_global_binding = radeonsi_set_global_binding;
  264.         rctx->context.launch_grid = radeonsi_launch_grid;
  265. }
  266.