Hi, About this patch: 1. It is not tested. I'll test it after 12th. 2. It implements atomic buffers as a surface which can be reused for ARB_shader_image_load_store 3. You can ignore the first patch.
My questions: 1. What does R_028AC0_ALU_ATOM_CACHE_GS_0 represent? 2. What determines the values 160, 336 and 0 in r600_emit_vs,gs,ps_atomic,constant_buffers();? 3. What does these macros represent? What are they used for? #define R600_UCP_CONST_BUFFER R600_MAX_USER_CONST_BUFFERS #define R600_TXQ_CONST_BUFFER R600_MAX_USER_CONST_BUFFERS + 1 #define R600_BUFFER_INFO_CONST_BUFFER R600_MAX_USER_CONST_BUFFERS + 2 #define R600_GS_RING_CONST_BUFFER R600_MAX_USER_CONST_BUFFERS + 3 #define R600_MAX_CONST_BUFFER_SIZE (4096 * sizeof(float[4])) // It is self-explanatory here. 4. What is the function of R600_CONTEXT_INV_ATOM_CACHE? 5. Does my implementation make sense? Thank you!! On Sun, Jan 4, 2015 at 3:44 PM, adityaatluri <adityaavina...@gmail.com> wrote: > --- > 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 > > -- Regards, *Aditya Atluri,* *USA.*
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev