#include "util/u_double_list.h"
#include "util/u_transfer.h"
+#include "radeonsi_resource.h"
+
#define R600_ERR(fmt, args...) \
fprintf(stderr, "EE %s:%d %s - "fmt, __FILE__, __LINE__, __func__, ##args)
unsigned group_bytes;
};
-struct r600_resource {
- struct u_resource b;
-
- /* Winsys objects. */
- struct pb_buffer *buf;
- struct radeon_winsys_cs_handle *cs_buf;
-
- /* Resource state. */
- unsigned domains;
-};
-
/* R600/R700 STATES */
struct r600_query {
union {
/* The buffer where query results are stored. It's used as a ring,
* data blocks for current query are stored sequentially from
* results_start to results_end, with wrapping on the buffer end */
- struct r600_resource *buffer;
+ struct si_resource *buffer;
/* The number of dwords for begin_query or end_query. */
unsigned num_cs_dw;
/* linked list of queries */
struct pipe_stream_output_target b;
/* The buffer where BUFFER_FILLED_SIZE is stored. */
- struct r600_resource *filled_size;
+ struct si_resource *filled_size;
unsigned stride;
unsigned so_index;
};
uint32_t indices_bo_offset;
unsigned db_render_override;
unsigned db_render_control;
- struct r600_resource *indices;
+ struct si_resource *indices;
};
struct r600_context;
void r600_context_queries_resume(struct r600_context *ctx);
void r600_query_predication(struct r600_context *ctx, struct r600_query *query, int operation,
int flag_wait);
-void r600_context_emit_fence(struct r600_context *ctx, struct r600_resource *fence,
+void r600_context_emit_fence(struct r600_context *ctx, struct si_resource *fence,
unsigned offset, unsigned value);
void r600_context_streamout_begin(struct r600_context *ctx);
struct pipe_resource *buf)
{
struct r600_screen *rscreen = (struct r600_screen*)screen;
- struct r600_resource *rbuffer = r600_resource(buf);
+ struct si_resource *rbuffer = si_resource(buf);
pb_reference(&rbuffer->buf, NULL);
FREE(rbuffer);
static void *r600_buffer_transfer_map(struct pipe_context *pipe,
struct pipe_transfer *transfer)
{
- struct r600_resource *rbuffer = r600_resource(transfer->resource);
+ struct si_resource *rbuffer = si_resource(transfer->resource);
struct r600_context *rctx = (struct r600_context*)pipe;
uint8_t *data;
};
bool r600_init_resource(struct r600_screen *rscreen,
- struct r600_resource *res,
+ struct si_resource *res,
unsigned size, unsigned alignment,
unsigned bind, unsigned usage)
{
const struct pipe_resource *templ)
{
struct r600_screen *rscreen = (struct r600_screen*)screen;
- struct r600_resource *rbuffer;
+ struct si_resource *rbuffer;
/* XXX We probably want a different alignment for buffers and textures. */
unsigned alignment = 4096;
- rbuffer = MALLOC_STRUCT(r600_resource);
+ rbuffer = MALLOC_STRUCT(si_resource);
rbuffer->b.b = *templ;
pipe_reference_init(&rbuffer->b.b.reference, 1);
ib->user_buffer, &ib->offset, &ib->buffer);
}
-void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer,
+void r600_upload_const_buffer(struct r600_context *rctx, struct si_resource **rbuffer,
const uint8_t *ptr, unsigned size,
uint32_t *const_offset)
{
void r600_get_backend_mask(struct r600_context *ctx)
{
struct radeon_winsys_cs *cs = ctx->cs;
- struct r600_resource *buffer;
+ struct si_resource *buffer;
uint32_t *results;
unsigned num_backends = ctx->screen->info.r600_num_backends;
unsigned i, mask = 0;
/* otherwise backup path for older kernels */
/* create buffer for event data */
- buffer = (struct r600_resource*)
- pipe_buffer_create(&ctx->screen->screen, PIPE_BIND_CUSTOM,
- PIPE_USAGE_STAGING, ctx->max_db*16);
+ buffer = si_resource_create_custom(&ctx->screen->screen,
+ PIPE_USAGE_STAGING,
+ ctx->max_db*16);
if (!buffer)
goto err;
}
}
- pipe_resource_reference((struct pipe_resource**)&buffer, NULL);
+ si_resource_reference(&buffer, NULL);
if (mask != 0) {
ctx->backend_mask = mask;
si_pm4_reset_emitted(ctx);
}
-void r600_context_emit_fence(struct r600_context *ctx, struct r600_resource *fence_bo, unsigned offset, unsigned value)
+void r600_context_emit_fence(struct r600_context *ctx, struct si_resource *fence_bo, unsigned offset, unsigned value)
{
struct radeon_winsys_cs *cs = ctx->cs;
uint64_t va;
* being written by the gpu, hence staging is probably a good
* usage pattern.
*/
- query->buffer = (struct r600_resource*)
- pipe_buffer_create(&ctx->screen->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STAGING, buffer_size);
+ query->buffer = si_resource_create_custom(&ctx->screen->screen,
+ PIPE_USAGE_STAGING,
+ buffer_size);
if (!query->buffer) {
FREE(query);
return NULL;
void r600_context_query_destroy(struct r600_context *ctx, struct r600_query *query)
{
- pipe_resource_reference((struct pipe_resource**)&query->buffer, NULL);
+ si_resource_reference(&query->buffer, NULL);
free(query);
}
cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
cs->buf[cs->cdw++] =
- r600_context_bo_reloc(ctx, r600_resource(t[i]->b.buffer),
+ r600_context_bo_reloc(ctx, si_resource(t[i]->b.buffer),
RADEON_USAGE_WRITE);
if (ctx->streamout_append_bitmask & (1 << i)) {
cs->buf[cs->cdw++] = t->b.buffer_offset >> 2;
cs->buf[cs->cdw++] = PKT3(PKT3_NOP, 0, 0);
- cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, (struct r600_resource*)t->b.buffer,
+ cs->buf[cs->cdw++] = r600_context_bo_reloc(ctx, (struct si_resource*)t->b.buffer,
RADEON_USAGE_WRITE);
cs->buf[cs->cdw++] = PKT3(PKT3_WAIT_REG_MEM, 5, 0);
void evergreen_set_streamout_enable(struct r600_context *ctx, unsigned buffer_enable_bit);
-static INLINE unsigned r600_context_bo_reloc(struct r600_context *ctx, struct r600_resource *rbo,
+static INLINE unsigned r600_context_bo_reloc(struct r600_context *ctx, struct si_resource *rbo,
enum radeon_bo_usage usage)
{
assert(usage);
};
struct r600_resource_texture {
- struct r600_resource resource;
+ struct si_resource resource;
/* If this resource is a depth-stencil buffer on evergreen, this contains
* the depth part of the format. There is a separate stencil resource
const struct pipe_resource *base,
struct winsys_handle *whandle);
-static INLINE struct r600_resource *r600_resource(struct pipe_resource *r)
-{
- return (struct r600_resource*)r;
-}
-
int r600_texture_depth_flush(struct pipe_context *ctx, struct pipe_resource *texture, boolean just_create);
/* r600_texture.c texture transfer functions. */
struct r600_context;
-void r600_upload_const_buffer(struct r600_context *rctx, struct r600_resource **rbuffer,
+void r600_upload_const_buffer(struct r600_context *rctx, struct si_resource **rbuffer,
const uint8_t *ptr, unsigned size,
uint32_t *const_offset);
struct winsys_handle *whandle)
{
struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
- struct r600_resource *resource = &rtex->resource;
+ struct si_resource *resource = &rtex->resource;
struct radeon_surface *surface = &rtex->surface;
struct r600_screen *rscreen = (struct r600_screen*)screen;
struct pipe_resource *ptex)
{
struct r600_resource_texture *rtex = (struct r600_resource_texture*)ptex;
- struct r600_resource *resource = &rtex->resource;
+ struct si_resource *resource = &rtex->resource;
if (rtex->flushed_depth_texture)
- pipe_resource_reference((struct pipe_resource **)&rtex->flushed_depth_texture, NULL);
+ si_resource_reference(&rtex->flushed_depth_texture, NULL);
if (rtex->stencil)
- pipe_resource_reference((struct pipe_resource **)&rtex->stencil, NULL);
+ si_resource_reference(&rtex->stencil, NULL);
pb_reference(&resource->buf, NULL);
FREE(rtex);
struct radeon_surface *surface)
{
struct r600_resource_texture *rtex;
- struct r600_resource *resource;
+ struct si_resource *resource;
struct r600_screen *rscreen = (struct r600_screen*)screen;
int r;
base_align = rtex->surface.bo_alignment;
if (!r600_init_resource(rscreen, resource, rtex->size, base_align, base->bind, base->usage)) {
- pipe_resource_reference((struct pipe_resource**)&rtex->stencil, NULL);
+ si_resource_reference(&rtex->stencil, NULL);
FREE(rtex);
return NULL;
}
char *map;
if (rtransfer->staging_texture) {
- buf = ((struct r600_resource *)rtransfer->staging_texture)->cs_buf;
+ buf = si_resource(rtransfer->staging_texture)->cs_buf;
} else {
struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
if (rtex->flushed_depth_texture)
- buf = ((struct r600_resource *)rtex->flushed_depth_texture)->cs_buf;
+ buf = si_resource(rtex->flushed_depth_texture)->cs_buf;
else
- buf = ((struct r600_resource *)transfer->resource)->cs_buf;
+ buf = si_resource(transfer->resource)->cs_buf;
offset = rtransfer->offset +
transfer->box.y / util_format_get_blockheight(format) * transfer->stride +
struct radeon_winsys_cs_handle *buf;
if (rtransfer->staging_texture) {
- buf = ((struct r600_resource *)rtransfer->staging_texture)->cs_buf;
+ buf = si_resource(rtransfer->staging_texture)->cs_buf;
} else {
struct r600_resource_texture *rtex = (struct r600_resource_texture*)transfer->resource;
if (rtex->flushed_depth_texture) {
- buf = ((struct r600_resource *)rtex->flushed_depth_texture)->cs_buf;
+ buf = si_resource(rtex->flushed_depth_texture)->cs_buf;
} else {
- buf = ((struct r600_resource *)transfer->resource)->cs_buf;
+ buf = si_resource(transfer->resource)->cs_buf;
}
}
rctx->ws->buffer_unmap(buf);
if (!rscreen->fences.bo) {
/* Create the shared buffer object */
- rscreen->fences.bo = (struct r600_resource*)
- pipe_buffer_create(&rscreen->screen, PIPE_BIND_CUSTOM,
- PIPE_USAGE_STAGING, 4096);
+ rscreen->fences.bo = si_resource_create_custom(&rscreen->screen,
+ PIPE_USAGE_STAGING,
+ 4096);
if (!rscreen->fences.bo) {
R600_ERR("r600: failed to create bo for fence objects\n");
goto out;
r600_context_emit_fence(rctx, rscreen->fences.bo, fence->index, 1);
/* Create a dummy BO so that fence_finish without a timeout can sleep waiting for completion */
- fence->sleep_bo = (struct r600_resource*)
- pipe_buffer_create(&rctx->screen->screen, PIPE_BIND_CUSTOM,
- PIPE_USAGE_STAGING, 1);
+ fence->sleep_bo = si_resource_create_custom(&rctx->screen->screen, PIPE_USAGE_STAGING, 1);
+
/* Add the fence as a dummy relocation. */
r600_context_bo_reloc(rctx, fence->sleep_bo, RADEON_USAGE_READWRITE);
}
rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf);
- pipe_resource_reference((struct pipe_resource**)&rscreen->fences.bo, NULL);
+ si_resource_reference(&rscreen->fences.bo, NULL);
}
pipe_mutex_destroy(rscreen->fences.mutex);
if (pipe_reference(&(*oldf)->reference, &newf->reference)) {
struct r600_screen *rscreen = (struct r600_screen *)pscreen;
pipe_mutex_lock(rscreen->fences.mutex);
- pipe_resource_reference((struct pipe_resource**)&(*oldf)->sleep_bo, NULL);
+ si_resource_reference(&(*oldf)->sleep_bo, NULL);
LIST_ADDTAIL(&(*oldf)->head, &rscreen->fences.pool);
pipe_mutex_unlock(rscreen->fences.mutex);
}
};
struct r600_pipe_fences {
- struct r600_resource *bo;
+ struct si_resource *bo;
unsigned *data;
unsigned next_index;
/* linked list of preallocated blocks */
struct r600_fence {
struct pipe_reference reference;
unsigned index; /* in the shared bo */
- struct r600_resource *sleep_bo;
+ struct si_resource *sleep_bo;
struct list_head head;
};
/* r600_buffer.c */
bool r600_init_resource(struct r600_screen *rscreen,
- struct r600_resource *res,
+ struct si_resource *res,
unsigned size, unsigned alignment,
unsigned bind, unsigned usage);
struct pipe_resource *r600_buffer_create(struct pipe_screen *screen,
static INLINE uint64_t r600_resource_va(struct pipe_screen *screen, struct pipe_resource *resource)
{
struct r600_screen *rscreen = (struct r600_screen*)screen;
- struct r600_resource *rresource = (struct r600_resource*)resource;
+ struct si_resource *rresource = (struct si_resource*)resource;
return rscreen->ws->buffer_get_virtual_address(rresource->cs_buf);
}
}
void si_pm4_add_bo(struct si_pm4_state *state,
- struct r600_resource *bo,
+ struct si_resource *bo,
enum radeon_bo_usage usage)
{
unsigned idx = state->nbo++;
assert(idx < SI_PM4_MAX_BO);
- pipe_resource_reference((struct pipe_resource**)&state->bo[idx],
- (struct pipe_resource*)bo);
+ si_resource_reference(&state->bo[idx], bo);
state->bo_usage[idx] = usage;
}
}
for (int i = 0; i < state->nbo; ++i) {
- pipe_resource_reference((struct pipe_resource**)&state->bo[idx],
- NULL);
+ si_resource_reference(&state->bo[idx], NULL);
}
FREE(state);
}
/* BO's referenced by this state */
unsigned nbo;
- struct r600_resource *bo[SI_PM4_MAX_BO];
+ struct si_resource *bo[SI_PM4_MAX_BO];
enum radeon_bo_usage bo_usage[SI_PM4_MAX_BO];
};
void si_pm4_set_reg(struct si_pm4_state *state, unsigned reg, uint32_t val);
void si_pm4_add_bo(struct si_pm4_state *state,
- struct r600_resource *bo,
+ struct si_resource *bo,
enum radeon_bo_usage usage);
void si_pm4_inval_shader_cache(struct si_pm4_state *state);
--- /dev/null
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Christian König <christian.koenig@amd.com>
+ */
+
+#ifndef RADEONSI_RESOURCE_H
+#define RADEONSI_RESOURCE_H
+
+#include "../../winsys/radeon/drm/radeon_winsys.h"
+#include "util/u_transfer.h"
+#include "util/u_inlines.h"
+
+struct si_resource {
+ struct u_resource b;
+
+ /* Winsys objects. */
+ struct pb_buffer *buf;
+ struct radeon_winsys_cs_handle *cs_buf;
+
+ /* Resource state. */
+ unsigned domains;
+};
+
+static INLINE void
+si_resource_reference(struct si_resource **ptr, struct si_resource *res)
+{
+ pipe_resource_reference((struct pipe_resource **)ptr,
+ (struct pipe_resource *)res);
+}
+
+static INLINE struct si_resource *
+si_resource(struct pipe_resource *r)
+{
+ return (struct si_resource*)r;
+}
+
+static INLINE struct si_resource *
+si_resource_create_custom(struct pipe_screen *screen,
+ unsigned usage, unsigned size)
+{
+ assert(size);
+ return si_resource(pipe_buffer_create(screen,
+ PIPE_BIND_CUSTOM, usage, size));
+}
+
+#endif
if (shader->bo == NULL) {
uint32_t *ptr;
- shader->bo = (struct r600_resource*)
- pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE, inst_byte_count);
+ shader->bo = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE, inst_byte_count);
if (shader->bo == NULL) {
return -ENOMEM;
}
void si_pipe_shader_destroy(struct pipe_context *ctx, struct si_pipe_shader *shader)
{
- pipe_resource_reference((struct pipe_resource**)&shader->bo, NULL);
+ si_resource_reference(&shader->bo, NULL);
memset(&shader->shader,0,sizeof(struct si_shader));
}
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_pipe_sampler_view **resource = (struct si_pipe_sampler_view **)views;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
- struct r600_resource *bo;
+ struct si_resource *bo;
int i;
int has_depth = 0;
uint64_t va;
si_pm4_inval_texture_cache(pm4);
- bo = (struct r600_resource*)
- pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE,
- count * sizeof(resource[0]->state));
+ bo = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE,
+ count * sizeof(resource[0]->state));
ptr = rctx->ws->buffer_map(bo->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE);
for (i = 0; i < count; i++, ptr += sizeof(resource[0]->state)) {
struct r600_context *rctx = (struct r600_context *)ctx;
struct si_pipe_sampler_state **rstates = (struct si_pipe_sampler_state **)states;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
- struct r600_resource *bo;
+ struct si_resource *bo;
uint64_t va;
char *ptr;
int i;
si_pm4_inval_texture_cache(pm4);
- bo = (struct r600_resource*)
- pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_IMMUTABLE,
- count * sizeof(rstates[0]->val));
+ bo = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE,
+ count * sizeof(rstates[0]->val));
ptr = rctx->ws->buffer_map(bo->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE);
for (i = 0; i < count; i++, ptr += sizeof(rstates[0]->val)) {
struct pipe_constant_buffer *cb)
{
struct r600_context *rctx = (struct r600_context *)ctx;
- struct r600_resource *rbuffer = cb ? r600_resource(cb->buffer) : NULL;
+ struct si_resource *rbuffer = cb ? si_resource(cb->buffer) : NULL;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
uint64_t va_offset;
uint32_t offset;
}
if (cb->buffer != &rbuffer->b.b)
- pipe_resource_reference((struct pipe_resource**)&rbuffer, NULL);
+ si_resource_reference(&rbuffer, NULL);
}
/*
t->b.buffer_offset = buffer_offset;
t->b.buffer_size = buffer_size;
- t->filled_size = (struct r600_resource*)
- pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, 4);
+ t->filled_size = si_resource_create_custom(ctx->screen, PIPE_USAGE_STATIC, 4);
ptr = rctx->ws->buffer_map(t->filled_size->cs_buf, rctx->cs, PIPE_TRANSFER_WRITE);
memset(ptr, 0, t->filled_size->buf->size);
rctx->ws->buffer_unmap(t->filled_size->cs_buf);
{
struct r600_so_target *t = (struct r600_so_target*)target;
pipe_resource_reference(&t->b.buffer, NULL);
- pipe_resource_reference((struct pipe_resource**)&t->filled_size, NULL);
+ si_resource_reference(&t->filled_size, NULL);
FREE(t);
}
struct si_pipe_shader {
struct si_shader shader;
struct si_pm4_state *pm4;
- struct r600_resource *bo;
+ struct si_resource *bo;
struct si_vertex_element vertex_elements;
struct tgsi_token *tokens;
unsigned num_sgprs;
static void si_vertex_buffer_update(struct r600_context *rctx)
{
struct pipe_context *ctx = &rctx->context;
- struct r600_resource *rbuffer, *t_list_buffer;
+ struct si_resource *rbuffer, *t_list_buffer;
struct pipe_vertex_buffer *vertex_buffer;
struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
unsigned i, count, offset;
count = rctx->nr_vertex_buffers;
assert(count <= 256 / 4);
- t_list_buffer = (struct r600_resource*)
- pipe_buffer_create(ctx->screen, PIPE_BIND_CUSTOM,
- PIPE_USAGE_IMMUTABLE, 4 * 4 * count);
+ t_list_buffer = si_resource_create_custom(ctx->screen, PIPE_USAGE_IMMUTABLE,
+ 4 * 4 * count);
if (t_list_buffer == NULL) {
FREE(pm4);
return;
/* bind vertex buffer once */
vertex_buffer = &rctx->vertex_buffer[i];
- rbuffer = (struct r600_resource*)vertex_buffer->buffer;
+ rbuffer = (struct si_resource*)vertex_buffer->buffer;
offset = 0;
if (vertex_buffer == NULL || rbuffer == NULL)
continue;
rdraw.vgt_index_type = V_028A7C_VGT_INDEX_16 |
(R600_BIG_ENDIAN ? V_028A7C_VGT_DMA_SWAP_16_BIT : 0);
}
- rdraw.indices = (struct r600_resource*)ib.buffer;
+ rdraw.indices = (struct si_resource*)ib.buffer;
rdraw.indices_bo_offset = ib.offset;
rdraw.vgt_draw_initiator = V_0287F0_DI_SRC_SEL_DMA;
} else {