X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgallium%2Fdrivers%2Fr600%2Fr600_pipe.c;h=97c6808260d75f44092a97eda3dea9e0ebefbb67;hb=14bd9d764802b5fedb652c791faafe4d13b65262;hp=8a18207d1ea66a61f31de1db2a0416ff830abf55;hpb=2ce783d8ddec1b1fcadc0798af0ebb045bba1cc4;p=mesa.git diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c index 8a18207d1ea..97c6808260d 100644 --- a/src/gallium/drivers/r600/r600_pipe.c +++ b/src/gallium/drivers/r600/r600_pipe.c @@ -22,32 +22,31 @@ */ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "pipe/p_defines.h" +#include "pipe/p_state.h" +#include "pipe/p_context.h" +#include "tgsi/tgsi_scan.h" +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_util.h" +#include "util/u_blitter.h" +#include "util/u_double_list.h" #include "util/u_format.h" -#include -#include -#include -#include -#include -#include +#include "util/u_format_s3tc.h" +#include "util/u_transfer.h" +#include "util/u_surface.h" +#include "util/u_pack_color.h" +#include "util/u_memory.h" +#include "util/u_inlines.h" #include "util/u_upload_mgr.h" -#include -#include +#include "vl/vl_decoder.h" +#include "vl/vl_video_buffer.h" #include "os/os_time.h" -#include +#include "pipebuffer/pb_buffer.h" #include "r600.h" #include "r600d.h" #include "r600_resource.h" #include "r600_shader.h" #include "r600_pipe.h" -#include "../../winsys/r600/drm/r600_drm_public.h" /* * pipe_context @@ -58,12 +57,15 @@ static struct r600_fence *r600_create_fence(struct r600_pipe_context *ctx) 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, PIPE_TRANSFER_UNSYNCHRONIZED, NULL); + ctx->fences.data = ctx->ws->buffer_map(ctx->fences.bo->buf, ctx->ctx.cs, + PIPE_TRANSFER_WRITE); } if (!LIST_IS_EMPTY(&ctx->fences.pool)) { @@ -114,16 +116,42 @@ static struct r600_fence *r600_create_fence(struct r600_pipe_context *ctx) return fence; } -static void r600_flush(struct pipe_context *ctx, - struct pipe_fence_handle **fence) + +void r600_flush(struct pipe_context *ctx, struct pipe_fence_handle **fence, + unsigned flags) { 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); - r600_context_flush(&rctx->ctx); + /* 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, + struct pipe_fence_handle **fence) +{ + r600_flush(ctx, fence, 0); +} + +static void r600_flush_from_winsys(void *ctx, unsigned flags) +{ + r600_flush((struct pipe_context*)ctx, NULL, flags); } static void r600_update_num_contexts(struct r600_screen *rscreen, int diff) @@ -160,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) { @@ -171,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->radeon, &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); @@ -194,13 +222,13 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void rctx->context.screen = screen; rctx->context.priv = priv; rctx->context.destroy = r600_destroy_context; - rctx->context.flush = r600_flush; + rctx->context.flush = r600_flush_from_st; /* 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; @@ -221,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; } @@ -231,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; } @@ -244,11 +272,15 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void return NULL; } + 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, @@ -257,6 +289,7 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void r600_destroy_context(&rctx->context); return NULL; } + rctx->vbuf_mgr->caps.format_fixed32 = 0; rctx->blitter = util_blitter_create(&rctx->context); if (rctx->blitter == NULL) { @@ -264,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; } @@ -309,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: @@ -343,6 +375,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) case PIPE_CAP_SM3: 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. */ @@ -356,17 +391,17 @@ 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_PRIMITIVE_RESTART: + 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; - case PIPE_CAP_ARRAY_TEXTURES: - /* fix once the CS checker upstream is fixed */ - return debug_get_bool_option("R600_ARRAY_TEXTURE", FALSE); - /* Texturing. */ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: @@ -375,9 +410,9 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) return 15; else return 14; - case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS: - case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 16; + case PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS: + return rscreen->info.drm_minor >= 9 ? + (family >= CHIP_CEDAR ? 16384 : 8192) : 0; case PIPE_CAP_MAX_COMBINED_SAMPLERS: return 32; @@ -388,40 +423,48 @@ static int r600_get_param(struct pipe_screen* pscreen, enum pipe_cap param) /* Timer queries, present when the clock frequency is non zero. */ case PIPE_CAP_TIMER_QUERY: - return r600_get_clock_crystal_freq(rscreen->radeon) != 0; + return rscreen->info.r600_clock_crystal_freq != 0; - default: - R600_ERR("r600: unknown param %d\n", param); - return 0; + case PIPE_CAP_MIN_TEXEL_OFFSET: + return -8; + + case PIPE_CAP_MAX_TEXEL_OFFSET: + return 7; } + 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: @@ -470,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, @@ -488,6 +536,8 @@ static int r600_get_video_param(struct pipe_screen *screen, case PIPE_VIDEO_CAP_MAX_WIDTH: case PIPE_VIDEO_CAP_MAX_HEIGHT: return vl_video_buffer_max_size(screen); + case PIPE_VIDEO_CAP_NUM_BUFFERS_DESIRED: + return vl_num_buffers_desired(screen, profile); default: return 0; } @@ -500,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); @@ -565,18 +614,160 @@ static boolean r600_fence_finish(struct pipe_screen *pscreen, return TRUE; } -struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) +static int r600_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config) +{ + switch ((tiling_config & 0xe) >> 1) { + case 0: + rscreen->tiling_info.num_channels = 1; + break; + case 1: + rscreen->tiling_info.num_channels = 2; + break; + case 2: + rscreen->tiling_info.num_channels = 4; + break; + case 3: + rscreen->tiling_info.num_channels = 8; + break; + default: + return -EINVAL; + } + + switch ((tiling_config & 0x30) >> 4) { + case 0: + rscreen->tiling_info.num_banks = 4; + break; + case 1: + rscreen->tiling_info.num_banks = 8; + break; + default: + return -EINVAL; + + } + switch ((tiling_config & 0xc0) >> 6) { + case 0: + rscreen->tiling_info.group_bytes = 256; + break; + case 1: + rscreen->tiling_info.group_bytes = 512; + break; + default: + return -EINVAL; + } + return 0; +} + +static int evergreen_interpret_tiling(struct r600_screen *rscreen, uint32_t tiling_config) { - struct r600_screen *rscreen; - struct radeon *radeon = radeon_create(ws); + switch (tiling_config & 0xf) { + case 0: + rscreen->tiling_info.num_channels = 1; + break; + case 1: + rscreen->tiling_info.num_channels = 2; + break; + case 2: + rscreen->tiling_info.num_channels = 4; + break; + case 3: + rscreen->tiling_info.num_channels = 8; + break; + default: + return -EINVAL; + } + + switch ((tiling_config & 0xf0) >> 4) { + case 0: + rscreen->tiling_info.num_banks = 4; + break; + case 1: + rscreen->tiling_info.num_banks = 8; + break; + case 2: + rscreen->tiling_info.num_banks = 16; + break; + default: + return -EINVAL; + } + + switch ((tiling_config & 0xf00) >> 8) { + case 0: + rscreen->tiling_info.group_bytes = 256; + break; + case 1: + rscreen->tiling_info.group_bytes = 512; + break; + default: + return -EINVAL; + } + return 0; +} + +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 (rscreen->chip_class <= R700) { + rscreen->tiling_info.group_bytes = 256; + } else { + rscreen->tiling_info.group_bytes = 512; + } - rscreen = CALLOC_STRUCT(r600_screen); + if (!tiling_config) + return 0; + + if (rscreen->chip_class <= R700) { + return r600_interpret_tiling(rscreen, tiling_config); + } else { + return evergreen_interpret_tiling(rscreen, tiling_config); + } +} + +static unsigned radeon_family_from_device(unsigned device) +{ + 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; + } +} + +struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) +{ + struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen); if (rscreen == NULL) { 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)) { + FREE(rscreen); + return NULL; + } + rscreen->screen.winsys = (struct pipe_winsys*)ws; rscreen->screen.destroy = r600_destroy_screen; rscreen->screen.get_name = r600_get_name; @@ -585,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; @@ -597,11 +788,10 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws) rscreen->screen.fence_finish = r600_fence_finish; r600_init_screen_resource_functions(&rscreen->screen); - rscreen->tiling_info = r600_get_tiling_info(radeon); util_format_s3tc_init(); util_slab_create(&rscreen->pool_buffers, - sizeof(struct r600_resource_buffer), 64, + sizeof(struct r600_resource), 64, UTIL_SLAB_SINGLETHREADED); pipe_mutex_init(rscreen->mutex_num_contexts);