diff options
-rw-r--r-- | src/mesa/state_tracker/st_cb_texture.c | 109 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_pbo.c | 122 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_pbo.h | 4 |
3 files changed, 129 insertions, 106 deletions
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index bf0dd4d113f..d38f24c3084 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1081,19 +1081,7 @@ try_pbo_upload_common(struct gl_context *ctx, struct pipe_context *pipe = st->pipe; bool success = false; - /* Create the shaders */ - if (!st->pbo.vs) { - st->pbo.vs = st_pbo_create_vs(st); - if (!st->pbo.vs) - return false; - } - - if (addr->depth != 1 && st->pbo.use_gs && !st->pbo.gs) { - st->pbo.gs = st_pbo_create_gs(st); - if (!st->pbo.gs) - return false; - } - + /* Create fragment shader */ if (!st->pbo.upload_fs) { st->pbo.upload_fs = st_pbo_create_upload_fs(st); if (!st->pbo.upload_fs) @@ -1143,76 +1131,6 @@ try_pbo_upload_common(struct gl_context *ctx, cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, samplers); } - /* Upload vertices */ - { - struct pipe_vertex_buffer vbo; - struct pipe_vertex_element velem; - - float x0 = (float) addr->xoffset / surface->width * 2.0f - 1.0f; - float y0 = (float) addr->yoffset / surface->height * 2.0f - 1.0f; - float x1 = (float) (addr->xoffset + addr->width) / surface->width * 2.0f - 1.0f; - float y1 = (float) (addr->yoffset + addr->height) / surface->height * 2.0f - 1.0f; - - float *verts = NULL; - - vbo.user_buffer = NULL; - vbo.buffer = NULL; - vbo.stride = 2 * sizeof(float); - - u_upload_alloc(st->uploader, 0, 8 * sizeof(float), 4, - &vbo.buffer_offset, &vbo.buffer, (void **) &verts); - if (!verts) - goto fail; - - verts[0] = x0; - verts[1] = y0; - verts[2] = x0; - verts[3] = y1; - verts[4] = x1; - verts[5] = y0; - verts[6] = x1; - verts[7] = y1; - - u_upload_unmap(st->uploader); - - velem.src_offset = 0; - velem.instance_divisor = 0; - velem.vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso); - velem.src_format = PIPE_FORMAT_R32G32_FLOAT; - - cso_set_vertex_elements(cso, 1, &velem); - - cso_set_vertex_buffers(cso, velem.vertex_buffer_index, 1, &vbo); - - pipe_resource_reference(&vbo.buffer, NULL); - } - - /* Upload constants */ - { - struct pipe_constant_buffer cb; - - if (st->constbuf_uploader) { - cb.buffer = NULL; - cb.user_buffer = NULL; - u_upload_data(st->constbuf_uploader, 0, sizeof(addr->constants), - ctx->Const.UniformBufferOffsetAlignment, - &addr->constants, &cb.buffer_offset, &cb.buffer); - if (!cb.buffer) - goto fail; - - u_upload_unmap(st->constbuf_uploader); - } else { - cb.buffer = NULL; - cb.user_buffer = &addr->constants; - cb.buffer_offset = 0; - } - cb.buffer_size = sizeof(addr->constants); - - cso_set_constant_buffer(cso, PIPE_SHADER_FRAGMENT, 0, &cb); - - pipe_resource_reference(&cb.buffer, NULL); - } - /* Framebuffer_state */ { struct pipe_framebuffer_state fb; @@ -1239,31 +1157,10 @@ try_pbo_upload_common(struct gl_context *ctx, cso_set_depth_stencil_alpha(cso, &dsa); } - /* Rasterizer state */ - cso_set_rasterizer(cso, &st->pbo.raster); - - /* Set up the shaders */ - cso_set_vertex_shader_handle(cso, st->pbo.vs); - - cso_set_geometry_shader_handle(cso, addr->depth != 1 ? st->pbo.gs : NULL); - - cso_set_tessctrl_shader_handle(cso, NULL); - - cso_set_tesseval_shader_handle(cso, NULL); - + /* Set up the fragment shader */ cso_set_fragment_shader_handle(cso, st->pbo.upload_fs); - /* Disable stream output */ - cso_set_stream_outputs(cso, 0, NULL, 0); - - if (addr->depth == 1) { - cso_draw_arrays(cso, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); - } else { - cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_STRIP, - 0, 4, 0, addr->depth); - } - - success = true; + success = st_pbo_draw(st, addr, surface->width, surface->height); fail: cso_restore_state(cso); diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c index 15d82baa503..7cb74530ccd 100644 --- a/src/mesa/state_tracker/st_pbo.c +++ b/src/mesa/state_tracker/st_pbo.c @@ -37,6 +37,8 @@ #include "pipe/p_screen.h" #include "cso_cache/cso_context.h" #include "tgsi/tgsi_ureg.h" +#include "util/u_inlines.h" +#include "util/u_upload_mgr.h" /* Final setup of buffer addressing information. * @@ -150,6 +152,126 @@ st_pbo_addresses_pixelstore(struct st_context *st, return true; } +/* Setup all vertex pipeline state, rasterizer state, and fragment shader + * constants, and issue the draw call for PBO upload/download. + * + * The caller is responsible for saving and restoring state, as well as for + * setting other fragment shader state (fragment shader, samplers), and + * framebuffer/viewport/DSA/blend state. + */ +bool +st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr, + unsigned surface_width, unsigned surface_height) +{ + struct cso_context *cso = st->cso_context; + + /* Setup vertex and geometry shaders */ + if (!st->pbo.vs) { + st->pbo.vs = st_pbo_create_vs(st); + if (!st->pbo.vs) + return false; + } + + if (addr->depth != 1 && st->pbo.use_gs && !st->pbo.gs) { + st->pbo.gs = st_pbo_create_gs(st); + if (!st->pbo.gs) + return false; + } + + cso_set_vertex_shader_handle(cso, st->pbo.vs); + + cso_set_geometry_shader_handle(cso, addr->depth != 1 ? st->pbo.gs : NULL); + + cso_set_tessctrl_shader_handle(cso, NULL); + + cso_set_tesseval_shader_handle(cso, NULL); + + /* Upload vertices */ + { + struct pipe_vertex_buffer vbo; + struct pipe_vertex_element velem; + + float x0 = (float) addr->xoffset / surface_width * 2.0f - 1.0f; + float y0 = (float) addr->yoffset / surface_height * 2.0f - 1.0f; + float x1 = (float) (addr->xoffset + addr->width) / surface_width * 2.0f - 1.0f; + float y1 = (float) (addr->yoffset + addr->height) / surface_height * 2.0f - 1.0f; + + float *verts = NULL; + + vbo.user_buffer = NULL; + vbo.buffer = NULL; + vbo.stride = 2 * sizeof(float); + + u_upload_alloc(st->uploader, 0, 8 * sizeof(float), 4, + &vbo.buffer_offset, &vbo.buffer, (void **) &verts); + if (!verts) + return false; + + verts[0] = x0; + verts[1] = y0; + verts[2] = x0; + verts[3] = y1; + verts[4] = x1; + verts[5] = y0; + verts[6] = x1; + verts[7] = y1; + + u_upload_unmap(st->uploader); + + velem.src_offset = 0; + velem.instance_divisor = 0; + velem.vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso); + velem.src_format = PIPE_FORMAT_R32G32_FLOAT; + + cso_set_vertex_elements(cso, 1, &velem); + + cso_set_vertex_buffers(cso, velem.vertex_buffer_index, 1, &vbo); + + pipe_resource_reference(&vbo.buffer, NULL); + } + + /* Upload constants */ + { + struct pipe_constant_buffer cb; + + if (st->constbuf_uploader) { + cb.buffer = NULL; + cb.user_buffer = NULL; + u_upload_data(st->constbuf_uploader, 0, sizeof(addr->constants), + st->ctx->Const.UniformBufferOffsetAlignment, + &addr->constants, &cb.buffer_offset, &cb.buffer); + if (!cb.buffer) + return false; + + u_upload_unmap(st->constbuf_uploader); + } else { + cb.buffer = NULL; + cb.user_buffer = &addr->constants; + cb.buffer_offset = 0; + } + cb.buffer_size = sizeof(addr->constants); + + cso_set_constant_buffer(cso, PIPE_SHADER_FRAGMENT, 0, &cb); + + pipe_resource_reference(&cb.buffer, NULL); + } + + /* Rasterizer state */ + cso_set_rasterizer(cso, &st->pbo.raster); + + /* Disable stream output */ + cso_set_stream_outputs(cso, 0, NULL, 0); + + if (addr->depth == 1) { + cso_draw_arrays(cso, PIPE_PRIM_TRIANGLE_STRIP, 0, 4); + } else { + cso_draw_arrays_instanced(cso, PIPE_PRIM_TRIANGLE_STRIP, + 0, 4, 0, addr->depth); + } + + return true; +} + void * st_pbo_create_vs(struct st_context *st) { diff --git a/src/mesa/state_tracker/st_pbo.h b/src/mesa/state_tracker/st_pbo.h index 392278e8f9d..fb1b7378545 100644 --- a/src/mesa/state_tracker/st_pbo.h +++ b/src/mesa/state_tracker/st_pbo.h @@ -69,6 +69,10 @@ st_pbo_addresses_pixelstore(struct st_context *st, const void *pixels, struct st_pbo_addresses *addr); +bool +st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr, + unsigned surface_width, unsigned surface_height); + void * st_pbo_create_vs(struct st_context *st); |