---
 src/gallium/include/pipe/p_context.h |  5 +++++
 src/gallium/include/pipe/p_defines.h |  7 ++++++-
 src/gallium/include/pipe/p_state.h   | 10 ++++++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/src/gallium/include/pipe/p_context.h 
b/src/gallium/include/pipe/p_context.h
index af5674f..bf3be31 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -44,6 +44,7 @@ struct pipe_blit_info;
 struct pipe_box;
 struct pipe_clip_state;
 struct pipe_constant_buffer;
+struct pipe_counter_buffer;
 struct pipe_depth_stencil_alpha_state;
 struct pipe_draw_info;
 struct pipe_fence_handle;
@@ -201,6 +202,10 @@ struct pipe_context {
                                 uint shader, uint index,
                                 struct pipe_constant_buffer *buf );
 
+   void (*set_counter_buffer)( struct pipe_context *,
+                               uint shader, uint index,
+                               struct pipe_counter_buffer *buf );
+
    void (*set_framebuffer_state)( struct pipe_context *,
                                   const struct pipe_framebuffer_state * );
 
diff --git a/src/gallium/include/pipe/p_defines.h 
b/src/gallium/include/pipe/p_defines.h
index 8c4e415..717ab6a 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -341,6 +341,7 @@ enum pipe_flush_flags {
 #define PIPE_BIND_VERTEX_BUFFER        (1 << 4) /* set_vertex_buffers */
 #define PIPE_BIND_INDEX_BUFFER         (1 << 5) /* draw_elements */
 #define PIPE_BIND_CONSTANT_BUFFER      (1 << 6) /* set_constant_buffer */
+#define PIPE_BIND_COUNTER_BUFFER       (1 << 7) /* set_counter_buffer */
 #define PIPE_BIND_DISPLAY_TARGET       (1 << 8) /* flush_front_buffer */
 #define PIPE_BIND_TRANSFER_WRITE       (1 << 9) /* transfer_map */
 #define PIPE_BIND_TRANSFER_READ        (1 << 10) /* transfer_map */
@@ -572,6 +573,8 @@ enum pipe_cap {
    PIPE_CAP_MAX_VERTEX_ATTRIB_STRIDE = 109,
    PIPE_CAP_SAMPLER_VIEW_TARGET = 110,
    PIPE_CAP_CLIP_HALFZ = 111,
+   PIPE_CAP_USER_COUNTER_BUFFERS = 112,
+   PIPE_CAP_COUNTER_BUFFER_OFFSET_ALIGNMENT = 113,
 };
 
 #define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
@@ -631,7 +634,9 @@ enum pipe_shader_cap
    PIPE_SHADER_CAP_PREFERRED_IR,
    PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED,
    PIPE_SHADER_CAP_MAX_SAMPLER_VIEWS,
-   PIPE_SHADER_CAP_DOUBLES
+   PIPE_SHADER_CAP_DOUBLES,
+   PIPE_SHADER_CAP_MAX_COUNTER_BUFFER_SIZE,
+   PIPE_SHADER_CAP_MAX_COUNTER_BUFFERS
 };
 
 /**
diff --git a/src/gallium/include/pipe/p_state.h 
b/src/gallium/include/pipe/p_state.h
index 43bc48b..49fae5d 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -57,6 +57,7 @@ extern "C" {
 #define PIPE_MAX_CLIP_PLANES       8
 #define PIPE_MAX_COLOR_BUFS        8
 #define PIPE_MAX_CONSTANT_BUFFERS 32
+#define PIPE_MAX_COUNTER_BUFFERS  32
 #define PIPE_MAX_SAMPLERS         16
 #define PIPE_MAX_SHADER_INPUTS    32
 #define PIPE_MAX_SHADER_OUTPUTS   48 /* 32 GENERICs + POS, PSIZE, FOG, etc. */
@@ -462,6 +463,15 @@ struct pipe_constant_buffer {
    const void *user_buffer;  /**< pointer to a user buffer if buffer == NULL */
 };
 
+/**
+ * A Counter buffer. A new buffer is set everytime a variable with
+ * atomic_uint is defined.
+ */
+struct pipe_counter_buffer{
+   struct pipe_resource *buffer; /**< The actual buffer */
+   unsigned buffer_offset; /**< The offset to start of data in buffer in bytes 
*/
+   const void *user_buffer; /**< The buffer which is created by the compiler */
+};
 
 /**
  * A stream output target. The structure specifies the range vertices can
-- 
1.9.1


From c80ca0e4704b8fc325e109d1770f6c4900d14cec Mon Sep 17 00:00:00 2001
From: adityaatluri <adityaavina...@gmail.com>
Date: Sun, 4 Jan 2015 16:37:43 -0500
Subject: [PATCH 2/2] drivers/r600: added atomic buffer bindings from mesa to
 R600 backend as a surface

---
 src/gallium/drivers/r600/r600_hw_context.c    |  3 ++
 src/gallium/drivers/r600/r600_pipe.h          |  9 ++++
 src/gallium/drivers/r600/r600_state.c         | 66 +++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_state_common.c  | 69 +++++++++++++++++++++++++++
 src/gallium/drivers/r600/r600d.h              | 11 +++++
 src/gallium/drivers/radeon/r600_pipe_common.c |  2 +-
 6 files changed, 159 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/r600/r600_hw_context.c 
b/src/gallium/drivers/r600/r600_hw_context.c
index b6fa3b0..53bc1ab 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -338,14 +338,17 @@ void r600_begin_new_cs(struct r600_context *ctx)
        for (shader = 0; shader < PIPE_SHADER_TYPES; shader++) {
                struct r600_constbuf_state *constbuf = 
&ctx->constbuf_state[shader];
                struct r600_textures_info *samplers = &ctx->samplers[shader];
+               struct r600_atombuf_state *atombuf = 
&ctx->atomic_buffer[shader];
 
                constbuf->dirty_mask = constbuf->enabled_mask;
                samplers->views.dirty_mask = samplers->views.enabled_mask;
                samplers->states.dirty_mask = samplers->states.enabled_mask;
+               atombuf->dirty_mask = atombuf->enabled_mask;
 
                r600_constant_buffers_dirty(ctx, constbuf);
                r600_sampler_views_dirty(ctx, &samplers->views);
                r600_sampler_states_dirty(ctx, &samplers->states);
+               r600_atomic_buffers_dirty(ctx, atombuf);
        }
 
        r600_postflush_resume_features(&ctx->b);
diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index 40b0328..bcdcfac 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -347,6 +347,14 @@ struct r600_constbuf_state
        uint32_t                        dirty_mask;
 };
 
+struct r600_atombuf_state
+{
+       struct r600_atom                atom;
+       struct pipe_surface     ab[PIPE_MAX_ATOMIC_BUFFERS];
+       uint32_t                                enabled_mask;
+       uint32_t                                dirty_mask;
+};
+
 struct r600_vertexbuf_state
 {
        struct r600_atom                atom;
@@ -445,6 +453,7 @@ struct r600_context {
        struct r600_shader_stages_state shader_stages;
        struct r600_gs_rings_state      gs_rings;
        struct r600_constbuf_state      constbuf_state[PIPE_SHADER_TYPES];
+       struct r600_atombuf_state       atomic_buffer[PIPE_SHADER_TYPES];
        struct r600_textures_info       samplers[PIPE_SHADER_TYPES];
        /** Vertex buffers for fetch shaders */
        struct r600_vertexbuf_state     vertex_buffer_state;
diff --git a/src/gallium/drivers/r600/r600_state.c 
b/src/gallium/drivers/r600/r600_state.c
index 61f5c5a..bcea22f 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1782,6 +1782,72 @@ static void r600_emit_ps_constant_buffers(struct 
r600_context *rctx, struct r600
                                   R_028940_ALU_CONST_CACHE_PS_0);
 }
 
+static void r600_emit_atomic_buffers()
+{
+       struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
+       uint32_t dirty_mask = state->dirty_mask;
+
+       while(dirty_mask){
+               struct pipe_surface *surf;
+               struct r600_resource *rbuffer;
+               unsigned offset;
+               unsigned buffer_index = ffs(dirty_mask) - 1;
+               unsigned gs_ring_buffer = (buffer_index == 
R600_GS_RING_ATOM_BUFFER);
+               surf = &state->ab[buffer_index];
+               rbuffer = (struct r600_resource*)surf->texture;
+               assert(rbuffer);
+
+               offset = surf->u.buf.first_element;
+
+               if (!gs_ring_buffer) {
+                       r600_write_context_reg(cs, reg_alu_atombuf_size + 
buffer_index,// * 4,
+                               
ALIGN_BIVUP(surf->height*surf->width*sizeof(unsigned) >> 4, 16));
+                       r600_write_context_reg(cs, reg_alu_atom_cache + 
buffer_index, offset >> 8);
+               }
+
+               radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+               radeon_emit(cs, r600_context_bo_reg(&rctx->b, 
&rctx->b.rings.gfx, rbuffer,
+                               RADEON_USAGE_READ, 
RADEON_PRIO_SHADER_BUFFER_RO));
+               radeon_emit(cs, PKT3(PKT3_SET_RESOURCE, 7, 0));
+               radeon_emit(cs, (buffer_id_base + buffer_index) * 7);
+               radeon_emit(cs, offset);
+               radeon_emit(cs, rbuffer->buf->size - offset - 1);
+               radeon_emit(cs, 
+                               S_038008_ENDIAN_SWAP(gs_ring_buffer ? 
ENDIAN_NONE : r600_endian_swap(32)) | S_038008_STRIDE(gs_ring_buffer ? 4 : 16));
+               radeon_emit(cs, 0);
+               radeon_emit(cs, 0);
+               radeon_emit(cs, 0);
+               radeon_emit(cs, 0x0000000);
+
+               radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
+               radeon_emit(cs, r600_context_bo_reloc(&rctx->b,
+                                                                               
&rctx->b.rings.gfx,
+                                                                               
rbuffer,
+                                                                               
RADEON_USAGE_READ,
+                                                                               
RADEON_PRIO_SHADER_BUFFER_RO));
+               dirty_mask &= ~(1 << buffer_index);
+       }
+       state->dirty_mask = 0;
+}
+
+static void r600_emit_vs_atomic_buffers(struct r600_context *rctx, struct 
r600_atom *atom)
+{
+       r600_emit_atomic_buffers(rctx, &rctx->atomic_state[PIPE_SHADER_VERTEX], 
160,
+                       R_028240_ALU_ATOM_BUFFER_SIZE_VS_0, 
R_028A80_ALU_ATOM_CACHE_VS_0);
+}
+
+static void r600_emit_gs_atomic_buffers(struct r600_context *rctx, struct 
r600_atom *atom)
+{
+       r600_emit_atomic_buffers(rctx, 
&rctx->atomic_state[PIPE_SHADER_GEOMETRY], 336,
+                       R_028280_ALU_ATOM_BUFFER_SIZE_GS_0, 
R_028AC0_ALU_ATOM_CACHE_GS_0);
+}
+
+static void r600_emit_ps_atomic_buffers(struct r600_context *rctx, struct 
r600_atom *atom)
+{
+       r600_emit_atomic_buffers(rctx, 
&rctx->atomic_state[PIPE_SHADER_FRAGMENT], 0,
+                       R_028200_ALU_ATOM_BUFFER_SIZE_PS_0, 
R_028A40_ALU_ATOM_CACHE_PS_0);
+}
+
 static void r600_emit_sampler_views(struct r600_context *rctx,
                                    struct r600_samplerview_state *state,
                                    unsigned resource_id_base)
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index c3f21cb..6d8d728 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -966,6 +966,74 @@ static void r600_set_constant_buffer(struct pipe_context 
*ctx, uint shader, uint
        r600_constant_buffers_dirty(rctx, state);
 }
 
+void r600_atomic_buffers_dirty(struct r600_context *rctx, struct 
r600_atombuf_state *state)
+{
+       if (state->dirty_mask) {
+               rctx->b.flags |= R600_CONTEXT_INV_ATOM_CACHE;
+               state->atom.num_dw = rctx->b.chip_class >= EVERGREEN ? 
util_bitcount(state->dirty_mask)*20 : util_bitcount(state->dirty_mask) * 19;
+               state->atom.dirty = true;
+       }
+}
+
+static void r600_set_atomic_buffer(struct pipe_context *ctx, uint shader, uint 
index,
+                                                                       struct 
pipe_surface *input)
+{
+       struct r600_context *rctx = (struct r600_context *)ctx;
+       struct r600_atombuf_state *state = &rctx->atombuf_state[shader];
+       struct pipe_surface *surf;
+
+       state->surf = r600_create_surface(ctx, input->texture , input);
+
+/*     The code below represent Atomic buffers as a buffer.
+       In our implementation we bind atomic buffers to texture so that
+       it can be reused for image_load_store
+
+       if(unlikely(!input || (!input->texture))){
+               state->enabled_mask &= ~(1 << index);
+               state->dirty_mask &= ~(1 << index);
+               pipe_resource_reference(&state->ab[index].texture, NULL);
+               return;
+       }
+
+       ab = &state->ab[index];
+       ab->width = input->width;
+       ab->height = input->height;
+
+       ptr = input->texture;
+       unsigned size = sizeof(unsigned)*input->height*input->width;
+
+       if (ptr){
+               if(R600_BIG_ENDIAN) {
+                       uint32_t *tmpPtr;
+                       unsigned i;
+
+                       if (!(tmpPtr = malloc(size))) {
+                               R600_ERR("Failed to allocate Atomic buffer\n");
+                               return;
+                       }
+
+                       for(i = 0; i < size / 4; ++i){
+                               tmpPtr[i] = util_cpu_to_le32(((uint32_t 
*)ptr)[i]);
+                       }
+
+                       // This can be changed as no need for data transfer. 
Offset can be changed
+                       u_upload_data(rctx->b.uploader, 0, size, tmpPtr, 
&input->u.buf.first_element, &ab->texture);
+                       free(tmpPtr);
+               } else {
+                       u_upload_data(rctx->b.uploader, 0, size, ptr, 
&input->u.buf.first_element, &ab->texture);
+               }
+               rctx->b.gtt += size;
+       } else {
+               // cb->buffer_offset = input->buffer_offset;
+               pipe_resource_reference(&ab->texture, input->texture);
+               r600_context_add_resource_size(ctx, input->texture);
+       }
+
+       state->enabled_mask |= 1 << index;
+       state->dirty_mask |= 1 << index;*/
+       r600_atomic_buffers_dirty(rctx, state);
+}
+
 static void r600_set_sample_mask(struct pipe_context *pipe, unsigned 
sample_mask)
 {
        struct r600_context *rctx = (struct r600_context*)pipe;
@@ -2452,6 +2520,7 @@ void r600_init_common_state_functions(struct r600_context 
*rctx)
        rctx->b.b.set_blend_color = r600_set_blend_color;
        rctx->b.b.set_clip_state = r600_set_clip_state;
        rctx->b.b.set_constant_buffer = r600_set_constant_buffer;
+       rctx->b.b.set_atomic_buffer = r600_set_atomic_buffer;
        rctx->b.b.set_sample_mask = r600_set_sample_mask;
        rctx->b.b.set_stencil_ref = r600_set_pipe_stencil_ref;
        rctx->b.b.set_viewport_states = r600_set_viewport_states;
diff --git a/src/gallium/drivers/r600/r600d.h b/src/gallium/drivers/r600/r600d.h
index 6a5b964..1a2af8b 100644
--- a/src/gallium/drivers/r600/r600d.h
+++ b/src/gallium/drivers/r600/r600d.h
@@ -3716,6 +3716,17 @@
 #define R_028984_ALU_CONST_CACHE_VS_1                0x00028984
 #define R_0289C0_ALU_CONST_CACHE_GS_0                0x000289C0
 
+#define R_028200_ALU_ATOM_BUFFER_SIZE_PS_0                      0x00028200
+#define R_028204_ALU_ATOM_BUFFER_SIZE_PS_1                      0x00028204
+#define R_028240_ALU_ATOM_BUFFER_SIZE_VS_0                      0x00028240
+#define R_028244_ALU_ATOM_BUFFER_SIZE_VS_1                      0x00028244
+#define R_028280_ALU_ATOM_BUFFER_SIZE_GS_0                      0x00028280
+#define R_028A40_ALU_ATOM_CACHE_PS_0                            0x00028A40
+#define R_028A44_ALU_ATOM_CACHE_PS_1                            0x00028A44
+#define R_028A80_ALU_ATOM_CACHE_VS_0                            0x00028A80
+#define R_028A84_ALU_ATOM_CACHE_VS_1                            0x00028A84
+#define R_028AC0_ALU_ATOM_CACHE_GS_0                            0x00028AC0
+
 #define R_03CFF0_SQ_VTX_BASE_VTX_LOC                 0x03CFF0
 #define R_03CFF4_SQ_VTX_START_INST_LOC               0x03CFF4
 
diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c 
b/src/gallium/drivers/radeon/r600_pipe_common.c
index 8aad178..6c5e1a4 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.c
+++ b/src/gallium/drivers/radeon/r600_pipe_common.c
@@ -233,7 +233,7 @@ bool r600_common_context_init(struct r600_common_context 
*rctx,
 
        rctx->uploader = u_upload_create(&rctx->b, 1024 * 1024, 256,
                                        PIPE_BIND_INDEX_BUFFER |
-                                       PIPE_BIND_CONSTANT_BUFFER);
+                                       PIPE_BIND_CONSTANT_BUFFER | 
PIPE_BIND_ATOMIC_BUFFER);
        if (!rctx->uploader)
                return false;
 
-- 
1.9.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to