static void tgsi_gs_prepare(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS]) { struct tgsi_exec_machine *machine = shader->machine; tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, constants_size); }
static void tgsi_gs_prepare(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS]) { struct tgsi_exec_machine *machine = shader->machine; int j; tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, constants_size); if (shader->info.uses_invocationid) { unsigned i = machine->SysSemanticToIndex[TGSI_SEMANTIC_INVOCATIONID]; for (j = 0; j < TGSI_QUAD_SIZE; j++) machine->SystemValue[i].i[j] = shader->invocation_id; } }
/** * Shade/write an array of quads * Called via quad_stage::run() */ static void shade_quads(struct quad_stage *qs, struct quad_header *quads[], unsigned nr) { struct softpipe_context *softpipe = qs->softpipe; struct tgsi_exec_machine *machine = softpipe->fs_machine; unsigned i, nr_quads = 0; tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, softpipe->mapped_constants[PIPE_SHADER_FRAGMENT], softpipe->const_buffer_size[PIPE_SHADER_FRAGMENT]); machine->InterpCoefs = quads[0]->coef; for (i = 0; i < nr; i++) { /* Only omit this quad from the output list if all the fragments * are killed _AND_ it's not the first quad in the list. * The first quad is special in the (optimized) depth-testing code: * the quads' Z coordinates are step-wise interpolated with respect * to the first quad in the list. * For multi-pass algorithms we need to produce exactly the same * Z values in each pass. If interpolation starts with different quads * we can get different Z values for the same (x,y). */ if (!shade_quad(qs, quads[i]) && i > 0) continue; /* quad totally culled/killed */ if (/*do_coverage*/ 0) coverage_quad( qs, quads[i] ); quads[nr_quads++] = quads[i]; } if (nr_quads) qs->next->run(qs->next, quads, nr_quads); }
/** * Execute geometry shader using TGSI interpreter. */ int draw_geometry_shader_run(struct draw_geometry_shader *shader, const void *constants[PIPE_MAX_CONSTANT_BUFFERS], const unsigned constants_size[PIPE_MAX_CONSTANT_BUFFERS], const struct draw_vertex_info *input_verts, const struct draw_prim_info *input_prim, struct draw_vertex_info *output_verts, struct draw_prim_info *output_prims ) { const float (*input)[4] = (const float (*)[4])input_verts->verts->data; unsigned input_stride = input_verts->vertex_size; unsigned vertex_size = input_verts->vertex_size; struct tgsi_exec_machine *machine = shader->machine; unsigned num_input_verts = input_prim->linear ? input_verts->count : input_prim->count; unsigned num_in_primitives = MAX2(u_gs_prims_for_vertices(input_prim->prim, num_input_verts), u_gs_prims_for_vertices(shader->input_primitive, num_input_verts)); unsigned max_out_prims = u_gs_prims_for_vertices(shader->output_primitive, shader->max_output_vertices) * num_in_primitives; output_verts->vertex_size = input_verts->vertex_size; output_verts->stride = input_verts->vertex_size; output_verts->verts = (struct vertex_header *)MALLOC(input_verts->vertex_size * num_in_primitives * shader->max_output_vertices); #if 0 debug_printf("%s count = %d (in prims # = %d)\n", __FUNCTION__, num_input_verts, num_in_primitives); debug_printf("\tlinear = %d, prim_info->count = %d\n", input_prim->linear, input_prim->count); debug_printf("\tprimt pipe = %d, shader in = %d, shader out = %d, max out = %d\n", input_prim->prim, shader->input_primitive, shader->output_primitive, shader->max_output_vertices); #endif shader->emitted_vertices = 0; shader->emitted_primitives = 0; shader->vertex_size = vertex_size; shader->tmp_output = (float (*)[4])output_verts->verts->data; shader->in_prim_idx = 0; shader->input_vertex_stride = input_stride; shader->input = input; if (shader->primitive_lengths) { FREE(shader->primitive_lengths); } shader->primitive_lengths = MALLOC(max_out_prims * sizeof(unsigned)); tgsi_exec_set_constant_buffers(machine, PIPE_MAX_CONSTANT_BUFFERS, constants, constants_size); if (input_prim->linear) gs_run(shader, input_prim, input_verts, output_prims, output_verts); else gs_run_elts(shader, input_prim, input_verts, output_prims, output_verts); /* Update prim_info: */ output_prims->linear = TRUE; output_prims->elts = NULL; output_prims->start = 0; output_prims->count = shader->emitted_vertices; output_prims->prim = shader->output_primitive; output_prims->flags = 0x0; output_prims->primitive_lengths = shader->primitive_lengths; output_prims->primitive_count = shader->emitted_primitives; output_verts->count = shader->emitted_vertices; #if 0 debug_printf("GS finished, prims = %d, verts = %d\n", output_prims->primitive_count, output_verts->count); #endif return shader->emitted_vertices; }
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); }