struct hud_context {
struct pipe_context *pipe;
struct cso_context *cso;
- struct u_upload_mgr *uploader;
struct hud_batch_query_context *batch_query;
struct list_head pane_list;
struct pipe_vertex_buffer vbuf;
unsigned max_num_vertices;
unsigned num_vertices;
- } text, bg, whitelines;
+ unsigned buffer_size;
+ } text, bg, whitelines, color_prims;
bool has_srgb;
};
int xoffset, int yoffset, float yscale)
{
struct cso_context *cso = hud->cso;
- struct pipe_vertex_buffer vbuffer = {0};
+ unsigned size = num_vertices * hud->color_prims.vbuf.stride;
+
+ assert(size <= hud->color_prims.buffer_size);
+ memcpy(hud->color_prims.vertices, buffer, size);
hud->constants.color[0] = r;
hud->constants.color[1] = g;
hud->constants.scale[1] = yscale;
cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
- vbuffer.user_buffer = buffer;
- vbuffer.stride = 2 * sizeof(float);
-
cso_set_vertex_buffers(cso, cso_get_aux_vertex_buffer_slot(cso),
- 1, &vbuffer);
+ 1, &hud->color_prims.vbuf);
cso_set_fragment_shader_handle(hud->cso, hud->fs_color);
cso_draw_arrays(cso, prim, 0, num_vertices);
+
+ hud->color_prims.vertices += size / sizeof(float);
+ hud->color_prims.vbuf.buffer_offset += size;
+ hud->color_prims.buffer_size -= size;
}
static void
}
static void
-hud_alloc_vertices(struct hud_context *hud, struct vertex_queue *v,
- unsigned num_vertices, unsigned stride)
+hud_prepare_vertices(struct hud_context *hud, struct vertex_queue *v,
+ unsigned num_vertices, unsigned stride)
{
v->num_vertices = 0;
v->max_num_vertices = num_vertices;
v->vbuf.stride = stride;
- u_upload_alloc(hud->uploader, 0, v->vbuf.stride * v->max_num_vertices,
- 16, &v->vbuf.buffer_offset, &v->vbuf.buffer,
- (void**)&v->vertices);
+ v->buffer_size = stride * num_vertices;
}
/**
cso_set_constant_buffer(cso, PIPE_SHADER_VERTEX, 0, &hud->constbuf);
/* prepare vertex buffers */
- hud_alloc_vertices(hud, &hud->bg, 4 * 256, 2 * sizeof(float));
- hud_alloc_vertices(hud, &hud->whitelines, 4 * 256, 2 * sizeof(float));
- hud_alloc_vertices(hud, &hud->text, 16 * 1024, 4 * sizeof(float));
+ hud_prepare_vertices(hud, &hud->bg, 16 * 256, 2 * sizeof(float));
+ hud_prepare_vertices(hud, &hud->whitelines, 4 * 256, 2 * sizeof(float));
+ hud_prepare_vertices(hud, &hud->text, 16 * 1024, 4 * sizeof(float));
+ hud_prepare_vertices(hud, &hud->color_prims, 32 * 1024, 2 * sizeof(float));
+
+ /* Allocate everything once and divide the storage into 3 portions
+ * manually, because u_upload_alloc can unmap memory from previous calls.
+ */
+ u_upload_alloc(hud->pipe->stream_uploader, 0,
+ hud->bg.buffer_size +
+ hud->whitelines.buffer_size +
+ hud->text.buffer_size +
+ hud->color_prims.buffer_size,
+ 16, &hud->bg.vbuf.buffer_offset, &hud->bg.vbuf.buffer,
+ (void**)&hud->bg.vertices);
+ pipe_resource_reference(&hud->whitelines.vbuf.buffer, hud->bg.vbuf.buffer);
+ pipe_resource_reference(&hud->text.vbuf.buffer, hud->bg.vbuf.buffer);
+ pipe_resource_reference(&hud->color_prims.vbuf.buffer, hud->bg.vbuf.buffer);
+
+ hud->whitelines.vbuf.buffer_offset = hud->bg.vbuf.buffer_offset +
+ hud->bg.buffer_size;
+ hud->whitelines.vertices = hud->bg.vertices +
+ hud->bg.buffer_size / sizeof(float);
+
+ hud->text.vbuf.buffer_offset = hud->whitelines.vbuf.buffer_offset +
+ hud->whitelines.buffer_size;
+ hud->text.vertices = hud->whitelines.vertices +
+ hud->whitelines.buffer_size / sizeof(float);
+
+ hud->color_prims.vbuf.buffer_offset = hud->text.vbuf.buffer_offset +
+ hud->text.buffer_size;
+ hud->color_prims.vertices = hud->text.vertices +
+ hud->text.buffer_size / sizeof(float);
/* prepare all graphs */
hud_batch_query_update(hud->batch_query);
}
/* unmap the uploader's vertex buffer before drawing */
- u_upload_unmap(hud->uploader);
+ u_upload_unmap(pipe->stream_uploader);
/* draw accumulated vertices for background quads */
cso_set_blend(cso, &hud->alpha_blend);
cso_restore_constant_buffer_slot0(cso, PIPE_SHADER_VERTEX);
pipe_surface_reference(&surf, NULL);
+
+ /* Start queries. */
+ hud_batch_query_begin(hud->batch_query);
+
+ LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ if (gr->begin_query)
+ gr->begin_query(gr);
+ }
+ }
}
static void
* hard-to-read numbers like 1.753.
*/
- /* Find the left-most digit. */
+ /* Find the left-most digit. Make sure exp10 * 10 and fixup_bytes doesn't
+ * overflow. (11 is safe) */
exp10 = 1;
- for (i = 0; value > 9 * exp10; i++) {
+ for (i = 0; exp10 <= UINT64_MAX / 11 && exp10 * 9 < value; i++) {
exp10 *= 10;
fixup_bytes(pane->type, i + 1, &exp10);
}
FREE(graph);
}
-void
+static void strcat_without_spaces(char *dst, const char *src)
+{
+ dst += strlen(dst);
+ while (*src) {
+ if (*src == ' ')
+ *dst++ = '_';
+ else
+ *dst++ = *src;
+ src++;
+ }
+ *dst = 0;
+}
+
+static void
hud_graph_set_dump_file(struct hud_graph *gr)
{
#ifndef PIPE_OS_WINDOWS
if (dump_file) {
strcpy(dump_file, hud_dump_dir);
strcat(dump_file, "/");
- strcat(dump_file, gr->name);
+ strcat_without_spaces(dump_file, gr->name);
gr->fd = fopen(dump_file, "w+");
free(dump_file);
}
else if (sscanf(name, "cpu%u%s", &i, s) == 1) {
hud_cpu_graph_install(pane, i);
}
+ else if (strcmp(name, "API-thread-busy") == 0) {
+ hud_api_thread_busy_install(pane);
+ }
#if HAVE_GALLIUM_EXTRA_HUD
else if (sscanf(name, "nic-rx-%s", arg_name) == 1) {
hud_nic_graph_install(pane, arg_name, NIC_DIRECTION_RX);
strip_hyphens(s);
if (!LIST_IS_EMPTY(&pane->graph_list)) {
- strcpy(LIST_ENTRY(struct hud_graph,
- pane->graph_list.prev, head)->name, s);
+ struct hud_graph *graph;
+ graph = LIST_ENTRY(struct hud_graph, pane->graph_list.prev, head);
+ strncpy(graph->name, s, sizeof(graph->name)-1);
+ graph->name[sizeof(graph->name)-1] = 0;
}
}
FREE(pane);
}
}
+
+ LIST_FOR_EACH_ENTRY(pane, &hud->pane_list, head) {
+ struct hud_graph *gr;
+
+ LIST_FOR_EACH_ENTRY(gr, &pane->graph_list, head) {
+ hud_graph_set_dump_file(gr);
+ }
+ }
}
static void
hud->pipe = pipe;
hud->cso = cso;
- hud->uploader = u_upload_create(pipe, 256 * 1024,
- PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_STREAM);
/* font */
if (!util_font_create(pipe, UTIL_FONT_FIXED_8X13, &hud->font)) {
- u_upload_destroy(hud->uploader);
FREE(hud);
return NULL;
}
if (!tgsi_text_translate(fragment_shader_text, tokens, ARRAY_SIZE(tokens))) {
assert(0);
pipe_resource_reference(&hud->font.texture, NULL);
- u_upload_destroy(hud->uploader);
FREE(hud);
return NULL;
}
if (!tgsi_text_translate(vertex_shader_text, tokens, ARRAY_SIZE(tokens))) {
assert(0);
pipe_resource_reference(&hud->font.texture, NULL);
- u_upload_destroy(hud->uploader);
FREE(hud);
return NULL;
}
pipe->delete_vs_state(pipe, hud->vs);
pipe_sampler_view_reference(&hud->font_sampler_view, NULL);
pipe_resource_reference(&hud->font.texture, NULL);
- u_upload_destroy(hud->uploader);
FREE(hud);
}