nvc0: implement new stream output interface
[mesa.git] / src / gallium / drivers / r600 / r600_pipe.c
index 48b0fe97a6a3ba9f52b9e1221f6439a6e49b919a..97c6808260d75f44092a97eda3dea9e0ebefbb67 100644 (file)
  */
 static struct r600_fence *r600_create_fence(struct r600_pipe_context *ctx)
 {
-       struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_fence *fence = NULL;
 
        if (!ctx->fences.bo) {
                /* Create the shared buffer object */
-               ctx->fences.bo = r600_bo(ctx->radeon, 4096, 0, 0, 0);
+               ctx->fences.bo = (struct r600_resource*)
+                       pipe_buffer_create(&ctx->screen->screen, PIPE_BIND_CUSTOM,
+                                          PIPE_USAGE_STAGING, 4096);
                if (!ctx->fences.bo) {
                        R600_ERR("r600: failed to create bo for fence objects\n");
                        return NULL;
                }
-               ctx->fences.data = r600_bo_map(ctx->radeon, ctx->fences.bo, rctx->ctx.cs,
-                                              PIPE_TRANSFER_UNSYNCHRONIZED | PIPE_TRANSFER_WRITE);
+               ctx->fences.data = ctx->ws->buffer_map(ctx->fences.bo->buf, ctx->ctx.cs,
+                                                      PIPE_TRANSFER_WRITE);
        }
 
        if (!LIST_IS_EMPTY(&ctx->fences.pool)) {
@@ -121,11 +122,25 @@ void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence,
 {
        struct r600_pipe_context *rctx = (struct r600_pipe_context *)ctx;
        struct r600_fence **rfence = (struct r600_fence**)fence;
+       struct pipe_query *render_cond = NULL;
+       unsigned render_cond_mode = 0;
 
        if (rfence)
                *rfence = r600_create_fence(rctx);
 
+       /* Disable render condition. */
+       if (rctx->current_render_cond) {
+               render_cond = rctx->current_render_cond;
+               render_cond_mode = rctx->current_render_cond_mode;
+               ctx->render_condition(ctx, NULL, 0);
+       }
+
        r600_context_flush(&rctx->ctx, flags);
+
+       /* Re-enable render condition. */
+       if (render_cond) {
+               ctx->render_condition(ctx, render_cond, render_cond_mode);
+       }
 }
 
 static void r600_flush_from_st(struct pipe_context *ctx,
@@ -173,7 +188,7 @@ static void r600_destroy_context(struct pipe_context *context)
                free(rctx->states[i]);
        }
 
-       u_vbuf_mgr_destroy(rctx->vbuf_mgr);
+       u_vbuf_destroy(rctx->vbuf_mgr);
        util_slab_destroy(&rctx->pool_transfers);
 
        if (rctx->fences.bo) {
@@ -184,8 +199,8 @@ static void r600_destroy_context(struct pipe_context *context)
                        FREE(entry);
                }
 
-               r600_bo_unmap(rctx->radeon, rctx->fences.bo);
-               r600_bo_reference(&rctx->fences.bo, NULL);
+               rctx->ws->buffer_unmap(rctx->fences.bo->buf);
+               pipe_resource_reference((struct pipe_resource**)&rctx->fences.bo, NULL);
        }
 
        r600_update_num_contexts(rctx->screen, -1);
@@ -211,9 +226,9 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 
        /* Easy accessing of screen/winsys. */
        rctx->screen = rscreen;
-       rctx->radeon = rscreen->radeon;
-       rctx->family = r600_get_family(rctx->radeon);
-       rctx->chip_class = r600_get_family_class(rctx->radeon);
+       rctx->ws = rscreen->ws;
+       rctx->family = rscreen->family;
+       rctx->chip_class = rscreen->chip_class;
 
        rctx->fences.bo = NULL;
        rctx->fences.data = NULL;
@@ -234,7 +249,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
        case R600:
        case R700:
                r600_init_state_functions(rctx);
-               if (r600_context_init(&rctx->ctx, rctx->radeon)) {
+               if (r600_context_init(&rctx->ctx, rctx->screen)) {
                        r600_destroy_context(&rctx->context);
                        return NULL;
                }
@@ -244,7 +259,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
        case EVERGREEN:
        case CAYMAN:
                evergreen_init_state_functions(rctx);
-               if (evergreen_context_init(&rctx->ctx, rctx->radeon)) {
+               if (evergreen_context_init(&rctx->ctx, rctx->screen)) {
                        r600_destroy_context(&rctx->context);
                        return NULL;
                }
@@ -257,13 +272,15 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
                return NULL;
        }
 
-       rctx->screen->ws->cs_set_flush_callback(rctx->ctx.cs, r600_flush_from_winsys, rctx);
+       rctx->ctx.pipe = &rctx->context;
+       rctx->ctx.flush = r600_flush_from_winsys;
+       rctx->ws->cs_set_flush_callback(rctx->ctx.cs, r600_flush_from_winsys, rctx);
 
        util_slab_create(&rctx->pool_transfers,
                         sizeof(struct pipe_transfer), 64,
                         UTIL_SLAB_SINGLETHREADED);
 
-       rctx->vbuf_mgr = u_vbuf_mgr_create(&rctx->context, 1024 * 1024, 256,
+       rctx->vbuf_mgr = u_vbuf_create(&rctx->context, 1024 * 1024, 256,
                                           PIPE_BIND_VERTEX_BUFFER |
                                           PIPE_BIND_INDEX_BUFFER |
                                           PIPE_BIND_CONSTANT_BUFFER,
@@ -280,6 +297,8 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
                return NULL;
        }
 
+       r600_get_backend_mask(&rctx->ctx); /* this emits commands and must be last */
+
        return &rctx->context;
 }
 
@@ -325,28 +344,25 @@ static const char *r600_get_family_name(enum radeon_family family)
 static const char* r600_get_name(struct pipe_screen* pscreen)
 {
        struct r600_screen *rscreen = (struct r600_screen *)pscreen;
-       enum radeon_family family = r600_get_family(rscreen->radeon);
 
-       return r600_get_family_name(family);
+       return r600_get_family_name(rscreen->family);
 }
 
 static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 {
        struct r600_screen *rscreen = (struct r600_screen *)pscreen;
-       enum radeon_family family = r600_get_family(rscreen->radeon);
+       enum radeon_family family = rscreen->family;
 
        switch (param) {
        /* Supported features (boolean caps). */
        case PIPE_CAP_NPOT_TEXTURES:
        case PIPE_CAP_TWO_SIDED_STENCIL:
-       case PIPE_CAP_GLSL:
        case PIPE_CAP_DUAL_SOURCE_BLEND:
        case PIPE_CAP_ANISOTROPIC_FILTER:
        case PIPE_CAP_POINT_SPRITE:
        case PIPE_CAP_OCCLUSION_QUERY:
        case PIPE_CAP_TEXTURE_SHADOW_MAP:
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
-       case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
        case PIPE_CAP_BLEND_EQUATION_SEPARATE:
        case PIPE_CAP_TEXTURE_SWIZZLE:
        case PIPE_CAP_DEPTHSTENCIL_CLEAR_SEPARATE:
@@ -360,6 +376,8 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_SEAMLESS_CUBE_MAP:
        case PIPE_CAP_FRAGMENT_COLOR_CLAMP_CONTROL:
        case PIPE_CAP_PRIMITIVE_RESTART:
+       case PIPE_CAP_CONDITIONAL_RENDER:
+       case PIPE_CAP_TEXTURE_BARRIER:
                return 1;
 
        /* Supported except the original R600. */
@@ -373,10 +391,15 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
                return family >= CHIP_CEDAR ? 1 : 0;
 
        /* Unsupported features. */
-       case PIPE_CAP_STREAM_OUTPUT:
+       case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
+       case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_ATTRIBS:
+       case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
+       case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
+       case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
        case PIPE_CAP_TGSI_INSTANCEID:
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
+       case PIPE_CAP_SCALED_RESOLVE:
                return 0;
 
        /* Texturing. */
@@ -390,9 +413,6 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
        case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS:
                return rscreen->info.drm_minor >= 9 ?
                        (family >= CHIP_CEDAR ? 16384 : 8192) : 0;
-       case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
-       case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
-               return 16;
        case PIPE_CAP_MAX_COMBINED_SAMPLERS:
                return 32;
 
@@ -410,39 +430,41 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
 
        case PIPE_CAP_MAX_TEXEL_OFFSET:
                return 7;
-
-       default:
-               R600_ERR("r600: unknown param %d\n", param);
-               return 0;
        }
+       return 0;
 }
 
-static float r600_get_paramf(struct pipe_screen* pscreen, enum pipe_cap param)
+static float r600_get_paramf(struct pipe_screen* pscreen,
+                            enum pipe_capf param)
 {
        struct r600_screen *rscreen = (struct r600_screen *)pscreen;
-       enum radeon_family family = r600_get_family(rscreen->radeon);
+       enum radeon_family family = rscreen->family;
 
        switch (param) {
-       case PIPE_CAP_MAX_LINE_WIDTH:
-       case PIPE_CAP_MAX_LINE_WIDTH_AA:
-       case PIPE_CAP_MAX_POINT_WIDTH:
-       case PIPE_CAP_MAX_POINT_WIDTH_AA:
+       case PIPE_CAPF_MAX_LINE_WIDTH:
+       case PIPE_CAPF_MAX_LINE_WIDTH_AA:
+       case PIPE_CAPF_MAX_POINT_WIDTH:
+       case PIPE_CAPF_MAX_POINT_WIDTH_AA:
                if (family >= CHIP_CEDAR)
                        return 16384.0f;
                else
                        return 8192.0f;
-       case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+       case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY:
                return 16.0f;
-       case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+       case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS:
                return 16.0f;
-       default:
-               R600_ERR("r600: unsupported paramf %d\n", param);
+       case PIPE_CAPF_GUARD_BAND_LEFT:
+       case PIPE_CAPF_GUARD_BAND_TOP:
+       case PIPE_CAPF_GUARD_BAND_RIGHT:
+       case PIPE_CAPF_GUARD_BAND_BOTTOM:
                return 0.0f;
        }
+       return 0.0f;
 }
 
 static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, enum pipe_shader_cap param)
 {
+       struct r600_screen *rscreen = (struct r600_screen *)pscreen;
        switch(shader)
        {
        case PIPE_SHADER_FRAGMENT:
@@ -491,10 +513,15 @@ static int r600_get_shader_param(struct pipe_screen* pscreen, unsigned shader, e
        case PIPE_SHADER_CAP_SUBROUTINES:
                return 0;
        case PIPE_SHADER_CAP_INTEGERS:
+               if (rscreen->chip_class == EVERGREEN)
+                       return 1;
                return 0;
-       default:
-               return 0;
+       case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
+               return 16;
+       case PIPE_SHADER_CAP_OUTPUT_READ:
+               return 1;
        }
+       return 0;
 }
 
 static int r600_get_video_param(struct pipe_screen *screen,
@@ -523,7 +550,6 @@ static void r600_destroy_screen(struct pipe_screen* pscreen)
        if (rscreen == NULL)
                return;
 
-       radeon_destroy(rscreen->radeon);
        rscreen->ws->destroy(rscreen->ws);
 
        util_slab_destroy(&rscreen->pool_buffers);
@@ -682,7 +708,7 @@ static int r600_init_tiling(struct r600_screen *rscreen)
        uint32_t tiling_config = rscreen->info.r600_tiling_config;
 
        /* set default group bytes, overridden by tiling info ioctl */
-       if (r600_get_family_class(rscreen->radeon) <= R700) {
+       if (rscreen->chip_class <= R700) {
                rscreen->tiling_info.group_bytes = 256;
        } else {
                rscreen->tiling_info.group_bytes = 512;
@@ -691,33 +717,53 @@ static int r600_init_tiling(struct r600_screen *rscreen)
        if (!tiling_config)
                return 0;
 
-       if (r600_get_family_class(rscreen->radeon) <= R700) {
+       if (rscreen->chip_class <= R700) {
                return r600_interpret_tiling(rscreen, tiling_config);
        } else {
                return evergreen_interpret_tiling(rscreen, tiling_config);
        }
 }
 
-struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
+static unsigned radeon_family_from_device(unsigned device)
 {
-       struct r600_screen *rscreen;
-       struct radeon *radeon = radeon_create(ws);
-       if (!radeon) {
-               return NULL;
+       switch (device) {
+#define CHIPSET(pciid, name, family) case pciid: return CHIP_##family;
+#include "pci_ids/r600_pci_ids.h"
+#undef CHIPSET
+       default:
+               return CHIP_UNKNOWN;
        }
+}
 
-       rscreen = CALLOC_STRUCT(r600_screen);
+struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
+{
+       struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
        if (rscreen == NULL) {
-               radeon_destroy(radeon);
                return NULL;
        }
 
        rscreen->ws = ws;
-       rscreen->radeon = radeon;
        ws->query_info(ws, &rscreen->info);
 
+       rscreen->family = radeon_family_from_device(rscreen->info.pci_id);
+       if (rscreen->family == CHIP_UNKNOWN) {
+               fprintf(stderr, "r600: Unknown chipset 0x%04X\n", rscreen->info.pci_id);
+               FREE(rscreen);
+               return NULL;
+       }
+
+       /* setup class */
+       if (rscreen->family == CHIP_CAYMAN) {
+               rscreen->chip_class = CAYMAN;
+       } else if (rscreen->family >= CHIP_CEDAR) {
+               rscreen->chip_class = EVERGREEN;
+       } else if (rscreen->family >= CHIP_RV770) {
+               rscreen->chip_class = R700;
+       } else {
+               rscreen->chip_class = R600;
+       }
+
        if (r600_init_tiling(rscreen)) {
-               radeon_destroy(radeon);
                FREE(rscreen);
                return NULL;
        }
@@ -730,7 +776,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
        rscreen->screen.get_shader_param = r600_get_shader_param;
        rscreen->screen.get_paramf = r600_get_paramf;
        rscreen->screen.get_video_param = r600_get_video_param;
-       if (r600_get_family_class(radeon) >= EVERGREEN) {
+       if (rscreen->chip_class >= EVERGREEN) {
                rscreen->screen.is_format_supported = evergreen_is_format_supported;
        } else {
                rscreen->screen.is_format_supported = r600_is_format_supported;