boolean draw_gs_init( struct draw_context *draw ) { draw->gs.tgsi.machine = tgsi_exec_machine_create(); if (!draw->gs.tgsi.machine) return FALSE; draw->gs.tgsi.machine->Primitives = align_malloc( MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector), 16); if (!draw->gs.tgsi.machine->Primitives) return FALSE; memset(draw->gs.tgsi.machine->Primitives, 0, MAX_PRIMITIVES * sizeof(struct tgsi_exec_vector)); return TRUE; }
struct pipe_context * softpipe_create_context( struct pipe_screen *screen, void *priv ) { struct softpipe_screen *sp_screen = softpipe_screen(screen); struct softpipe_context *softpipe = CALLOC_STRUCT(softpipe_context); uint i, sh; util_init_math(); softpipe->dump_fs = debug_get_bool_option( "SOFTPIPE_DUMP_FS", FALSE ); softpipe->dump_gs = debug_get_bool_option( "SOFTPIPE_DUMP_GS", FALSE ); softpipe->pipe.screen = screen; softpipe->pipe.destroy = softpipe_destroy; softpipe->pipe.priv = priv; /* state setters */ softpipe_init_blend_funcs(&softpipe->pipe); softpipe_init_clip_funcs(&softpipe->pipe); softpipe_init_query_funcs( softpipe ); softpipe_init_rasterizer_funcs(&softpipe->pipe); softpipe_init_sampler_funcs(&softpipe->pipe); softpipe_init_shader_funcs(&softpipe->pipe); softpipe_init_streamout_funcs(&softpipe->pipe); softpipe_init_texture_funcs( &softpipe->pipe ); softpipe_init_vertex_funcs(&softpipe->pipe); softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; softpipe->pipe.draw_vbo = softpipe_draw_vbo; softpipe->pipe.clear = softpipe_clear; softpipe->pipe.flush = softpipe_flush_wrapped; softpipe->pipe.render_condition = softpipe_render_condition; softpipe->pipe.create_video_decoder = vl_create_decoder; softpipe->pipe.create_video_buffer = vl_video_buffer_create; /* * Alloc caches for accessing drawing surfaces and textures. * Must be before quad stage setup! */ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) softpipe->cbuf_cache[i] = sp_create_tile_cache( &softpipe->pipe ); softpipe->zsbuf_cache = sp_create_tile_cache( &softpipe->pipe ); /* Allocate texture caches */ for (sh = 0; sh < Elements(softpipe->tex_cache); sh++) { for (i = 0; i < Elements(softpipe->tex_cache[0]); i++) { softpipe->tex_cache[sh][i] = sp_create_tex_tile_cache(&softpipe->pipe); if (!softpipe->tex_cache[sh][i]) goto fail; } } softpipe->fs_machine = tgsi_exec_machine_create(); /* setup quad rendering stages */ softpipe->quad.shade = sp_quad_shade_stage(softpipe); softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe); softpipe->quad.blend = sp_quad_blend_stage(softpipe); softpipe->quad.pstipple = sp_quad_polygon_stipple_stage(softpipe); /* * Create drawing context and plug our rendering stage into it. */ if (sp_screen->use_llvm) softpipe->draw = draw_create(&softpipe->pipe); else softpipe->draw = draw_create_no_llvm(&softpipe->pipe); if (!softpipe->draw) goto fail; draw_texture_samplers(softpipe->draw, PIPE_SHADER_VERTEX, PIPE_MAX_SAMPLERS, (struct tgsi_sampler **) softpipe->tgsi.samplers_list[PIPE_SHADER_VERTEX]); draw_texture_samplers(softpipe->draw, PIPE_SHADER_GEOMETRY, PIPE_MAX_SAMPLERS, (struct tgsi_sampler **) softpipe->tgsi.samplers_list[PIPE_SHADER_GEOMETRY]); if (debug_get_bool_option( "SOFTPIPE_NO_RAST", FALSE )) softpipe->no_rast = TRUE; softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe); if (!softpipe->vbuf_backend) goto fail; softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend); if (!softpipe->vbuf) goto fail; draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf); draw_set_render(softpipe->draw, softpipe->vbuf_backend); /* plug in AA line/point stages */ draw_install_aaline_stage(softpipe->draw, &softpipe->pipe); draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe); /* Do polygon stipple w/ texture map + frag prog? */ #if DO_PSTIPPLE_IN_DRAW_MODULE draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe); #endif draw_wide_point_sprites(softpipe->draw, TRUE); sp_init_surface_functions(softpipe); #if DO_PSTIPPLE_IN_HELPER_MODULE /* create the polgon stipple sampler */ softpipe->pstipple.sampler = util_pstipple_create_sampler(&softpipe->pipe); #endif return &softpipe->pipe; fail: softpipe_destroy(&softpipe->pipe); return NULL; }
void softpipe_launch_grid(struct pipe_context *context, const struct pipe_grid_info *info) { struct softpipe_context *softpipe = softpipe_context(context); struct sp_compute_shader *cs = softpipe->cs; int num_threads_in_group; struct tgsi_exec_machine **machines; int bwidth, bheight, bdepth; int w, h, d, i; int g_w, g_h, g_d; uint32_t grid_size[3]; void *local_mem = NULL; softpipe_update_compute_samplers(softpipe); bwidth = cs->info.properties[TGSI_PROPERTY_CS_FIXED_BLOCK_WIDTH]; bheight = cs->info.properties[TGSI_PROPERTY_CS_FIXED_BLOCK_HEIGHT]; bdepth = cs->info.properties[TGSI_PROPERTY_CS_FIXED_BLOCK_DEPTH]; num_threads_in_group = bwidth * bheight * bdepth; fill_grid_size(context, info, grid_size); if (cs->shader.req_local_mem) { local_mem = CALLOC(1, cs->shader.req_local_mem); } machines = CALLOC(sizeof(struct tgsi_exec_machine *), num_threads_in_group); if (!machines) { FREE(local_mem); return; } /* initialise machines + GRID_SIZE + THREAD_ID + BLOCK_SIZE */ for (d = 0; d < bdepth; d++) { for (h = 0; h < bheight; h++) { for (w = 0; w < bwidth; w++) { int idx = w + (h * bwidth) + (d * bheight * bwidth); machines[idx] = tgsi_exec_machine_create(PIPE_SHADER_COMPUTE); machines[idx]->LocalMem = local_mem; machines[idx]->LocalMemSize = cs->shader.req_local_mem; cs_prepare(cs, machines[idx], w, h, d, grid_size[0], grid_size[1], grid_size[2], bwidth, bheight, bdepth, (struct tgsi_sampler *)softpipe->tgsi.sampler[PIPE_SHADER_COMPUTE], (struct tgsi_image *)softpipe->tgsi.image[PIPE_SHADER_COMPUTE], (struct tgsi_buffer *)softpipe->tgsi.buffer[PIPE_SHADER_COMPUTE]); tgsi_exec_set_constant_buffers(machines[idx], PIPE_MAX_CONSTANT_BUFFERS, softpipe->mapped_constants[PIPE_SHADER_COMPUTE], softpipe->const_buffer_size[PIPE_SHADER_COMPUTE]); } } } for (g_d = 0; g_d < grid_size[2]; g_d++) { for (g_h = 0; g_h < grid_size[1]; g_h++) { for (g_w = 0; g_w < grid_size[0]; g_w++) { run_workgroup(cs, g_w, g_h, g_d, num_threads_in_group, machines); } } } for (i = 0; i < num_threads_in_group; i++) { cs_delete(cs, machines[i]); tgsi_exec_machine_destroy(machines[i]); } FREE(local_mem); FREE(machines); }