aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-06-26 12:26:02 +0800
committerChia-I Wu <[email protected]>2013-06-26 16:42:45 +0800
commit3eb6754e94c623c4c2393f23aeaafa933bee154e (patch)
tree1df7b9df4f461ffc13cec2d835a3afc1a111e8b2
parent79385950f383771b9021f7b5f016da09a80600d4 (diff)
ilo: support PIPE_CAP_USER_CONSTANT_BUFFERS
We need it for HUD support, and will need it for push constants in the future.
-rw-r--r--src/gallium/drivers/ilo/ilo_context.c23
-rw-r--r--src/gallium/drivers/ilo/ilo_context.h7
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe.h7
-rw-r--r--src/gallium/drivers/ilo/ilo_screen.c2
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c72
5 files changed, 88 insertions, 23 deletions
diff --git a/src/gallium/drivers/ilo/ilo_context.c b/src/gallium/drivers/ilo/ilo_context.c
index d3e900661ee..e355a9c3089 100644
--- a/src/gallium/drivers/ilo/ilo_context.c
+++ b/src/gallium/drivers/ilo/ilo_context.c
@@ -25,6 +25,7 @@
* Chia-I Wu <[email protected]>
*/
+#include "util/u_upload_mgr.h"
#include "intel_chipset.h"
#include "ilo_3d.h"
@@ -96,7 +97,8 @@ ilo_context_destroy(struct pipe_context *pipe)
if (ilo->last_cp_bo)
intel_bo_unreference(ilo->last_cp_bo);
- util_slab_destroy(&ilo->transfer_mempool);
+ if (ilo->uploader)
+ u_upload_destroy(ilo->uploader);
if (ilo->blitter)
ilo_blitter_destroy(ilo->blitter);
@@ -107,6 +109,8 @@ ilo_context_destroy(struct pipe_context *pipe)
if (ilo->cp)
ilo_cp_destroy(ilo->cp);
+ util_slab_destroy(&ilo->transfer_mempool);
+
FREE(ilo);
}
@@ -123,6 +127,13 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
ilo->winsys = is->winsys;
ilo->dev = &is->dev;
+ /*
+ * initialize first, otherwise it may not be safe to call
+ * ilo_context_destroy() on errors
+ */
+ util_slab_create(&ilo->transfer_mempool,
+ sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED);
+
ilo->cp = ilo_cp_create(ilo->winsys, is->dev.has_llc);
ilo->shader_cache = ilo_shader_cache_create();
if (ilo->cp)
@@ -133,12 +144,16 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
return NULL;
}
+ ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024, 16,
+ PIPE_BIND_CONSTANT_BUFFER);
+ if (!ilo->uploader) {
+ ilo_context_destroy(&ilo->base);
+ return NULL;
+ }
+
ilo_cp_set_flush_callback(ilo->cp,
ilo_context_cp_flushed, (void *) ilo);
- util_slab_create(&ilo->transfer_mempool,
- sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED);
-
ilo->base.screen = screen;
ilo->base.priv = priv;
diff --git a/src/gallium/drivers/ilo/ilo_context.h b/src/gallium/drivers/ilo/ilo_context.h
index a37ed001b4c..ed9bba39ab5 100644
--- a/src/gallium/drivers/ilo/ilo_context.h
+++ b/src/gallium/drivers/ilo/ilo_context.h
@@ -34,6 +34,7 @@
#include "ilo_gpe.h"
#include "ilo_common.h"
+struct u_upload_mgr;
struct intel_winsys;
struct intel_bo;
struct ilo_3d;
@@ -48,15 +49,17 @@ struct ilo_context {
struct intel_winsys *winsys;
struct ilo_dev_info *dev;
+ struct util_slab_mempool transfer_mempool;
+
struct ilo_cp *cp;
struct intel_bo *last_cp_bo;
- struct util_slab_mempool transfer_mempool;
-
struct ilo_shader_cache *shader_cache;
struct ilo_3d *hw3d;
struct ilo_blitter *blitter;
+ struct u_upload_mgr *uploader;
+
uint32_t dirty;
struct ilo_vb_state vb;
diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h
index 5e313abd386..7825e58a40f 100644
--- a/src/gallium/drivers/ilo/ilo_gpe.h
+++ b/src/gallium/drivers/ilo/ilo_gpe.h
@@ -207,6 +207,13 @@ struct ilo_view_state {
struct ilo_cbuf_cso {
struct pipe_resource *resource;
struct ilo_view_surface surface;
+
+ /*
+ * this CSO is not so constant because user buffer needs to be uploaded in
+ * finalize_constant_buffers()
+ */
+ const void *user_buffer;
+ unsigned user_buffer_size;
};
struct ilo_cbuf_state {
diff --git a/src/gallium/drivers/ilo/ilo_screen.c b/src/gallium/drivers/ilo/ilo_screen.c
index d2b211366b1..aaceb7a6494 100644
--- a/src/gallium/drivers/ilo/ilo_screen.c
+++ b/src/gallium/drivers/ilo/ilo_screen.c
@@ -393,7 +393,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
case PIPE_CAP_USER_INDEX_BUFFERS:
return false;
case PIPE_CAP_USER_CONSTANT_BUFFERS:
- return false; /* TODO push constants */
+ return true;
case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
/* imposed by OWord (Dual) Block Read */
return 16;
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index 7046a69890c..71783dfaca8 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -27,6 +27,7 @@
#include "util/u_framebuffer.h"
#include "util/u_helpers.h"
+#include "util/u_upload_mgr.h"
#include "ilo_context.h"
#include "ilo_resource.h"
@@ -86,18 +87,40 @@ finalize_shader_states(struct ilo_context *ilo)
static void
finalize_constant_buffers(struct ilo_context *ilo)
{
- int sh;
+ int sh, i;
if (!(ilo->dirty & ILO_DIRTY_CONSTANT_BUFFER))
return;
+ /* TODO push constants? */
for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
- int last_cbuf = Elements(ilo->cbuf[sh].cso) - 1;
+ int last_cbuf = -1;
- /* find the last cbuf */
- while (last_cbuf >= 0 &&
- !ilo->cbuf[sh].cso[last_cbuf].resource)
- last_cbuf--;
+ for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) {
+ struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i];
+
+ /* upload user buffer */
+ if (cbuf->user_buffer) {
+ const enum pipe_format elem_format =
+ PIPE_FORMAT_R32G32B32A32_FLOAT;
+ unsigned offset;
+
+ u_upload_data(ilo->uploader, 0, cbuf->user_buffer_size,
+ cbuf->user_buffer, &offset, &cbuf->resource);
+
+ ilo_gpe_init_view_surface_for_buffer(ilo->dev,
+ ilo_buffer(cbuf->resource),
+ offset, cbuf->user_buffer_size,
+ util_format_get_blocksize(elem_format), elem_format,
+ false, false, &cbuf->surface);
+
+ cbuf->user_buffer = NULL;
+ cbuf->user_buffer_size = 0;
+ }
+
+ if (cbuf->resource)
+ last_cbuf = i;
+ }
ilo->cbuf[sh].count = last_cbuf + 1;
}
@@ -112,6 +135,8 @@ ilo_finalize_states(struct ilo_context *ilo)
{
finalize_shader_states(ilo);
finalize_constant_buffers(ilo);
+
+ u_upload_unmap(ilo->uploader);
}
static void *
@@ -509,7 +534,7 @@ ilo_set_clip_state(struct pipe_context *pipe,
static void
ilo_set_constant_buffer(struct pipe_context *pipe,
uint shader, uint index,
- struct pipe_constant_buffer *buf)
+ struct pipe_constant_buffer *state)
{
struct ilo_context *ilo = ilo_context(pipe);
struct ilo_cbuf_cso *cbuf;
@@ -519,22 +544,37 @@ ilo_set_constant_buffer(struct pipe_context *pipe,
cbuf = &ilo->cbuf[shader].cso[index];
- if (buf) {
- const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ if (state) {
+ pipe_resource_reference(&cbuf->resource, state->buffer);
+
+ if (state->buffer) {
+ const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
- /* no PIPE_CAP_USER_CONSTANT_BUFFERS */
- assert(!buf->user_buffer);
+ ilo_gpe_init_view_surface_for_buffer(ilo->dev,
+ ilo_buffer(cbuf->resource),
+ state->buffer_offset, state->buffer_size,
+ util_format_get_blocksize(elem_format), elem_format,
+ false, false, &cbuf->surface);
- pipe_resource_reference(&cbuf->resource, buf->buffer);
+ cbuf->user_buffer = NULL;
+ cbuf->user_buffer_size = 0;
+ }
+ else {
+ assert(state->user_buffer);
+
+ cbuf->surface.bo = NULL;
- ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(buf->buffer),
- buf->buffer_offset, buf->buffer_size,
- util_format_get_blocksize(elem_format), elem_format,
- false, false, &cbuf->surface);
+ /* state->buffer_offset does not apply for user buffer */
+ cbuf->user_buffer = state->user_buffer;
+ cbuf->user_buffer_size = state->buffer_size;
+ }
}
else {
pipe_resource_reference(&cbuf->resource, NULL);
cbuf->surface.bo = NULL;
+
+ cbuf->user_buffer = NULL;
+ cbuf->user_buffer_size = 0;
}
/* the correct value will be set in ilo_finalize_states() */