#include "util/u_blitter.h"
#include "util/u_format_s3tc.h"
#include "util/u_simple_shaders.h"
+#include "util/u_upload_mgr.h"
#include "vl/vl_decoder.h"
#include "vl/vl_video_buffer.h"
#include "os/os_time.h"
R600_ERR("r600: failed to create bo for fence objects\n");
goto out;
}
- rscreen->fences.data = rctx->ws->buffer_map(rscreen->fences.bo->buf,
+ rscreen->fences.data = rctx->ws->buffer_map(rscreen->fences.bo->cs_buf,
rctx->cs,
PIPE_TRANSFER_READ_WRITE);
}
r600_flush((struct pipe_context*)ctx, NULL, flags);
}
-static void r600_update_num_contexts(struct r600_screen *rscreen, int diff)
-{
- pipe_mutex_lock(rscreen->mutex_num_contexts);
- if (diff > 0) {
- rscreen->num_contexts++;
-
- if (rscreen->num_contexts > 1)
- util_slab_set_thread_safety(&rscreen->pool_buffers,
- UTIL_SLAB_MULTITHREADED);
- } else {
- rscreen->num_contexts--;
-
- if (rscreen->num_contexts <= 1)
- util_slab_set_thread_safety(&rscreen->pool_buffers,
- UTIL_SLAB_SINGLETHREADED);
- }
- pipe_mutex_unlock(rscreen->mutex_num_contexts);
-}
-
static void r600_destroy_context(struct pipe_context *context)
{
struct r600_context *rctx = (struct r600_context *)context;
+ pipe_resource_reference((struct pipe_resource**)&rctx->dummy_cmask, NULL);
+ pipe_resource_reference((struct pipe_resource**)&rctx->dummy_fmask, NULL);
+
+ if (rctx->no_blend) {
+ rctx->context.delete_blend_state(&rctx->context, rctx->no_blend);
+ }
if (rctx->dummy_pixel_shader) {
rctx->context.delete_fs_state(&rctx->context, rctx->dummy_pixel_shader);
}
if (rctx->custom_dsa_flush) {
rctx->context.delete_depth_stencil_alpha_state(&rctx->context, rctx->custom_dsa_flush);
}
+ if (rctx->custom_blend_resolve) {
+ rctx->context.delete_blend_state(&rctx->context, rctx->custom_blend_resolve);
+ }
+ if (rctx->custom_blend_decompress) {
+ rctx->context.delete_blend_state(&rctx->context, rctx->custom_blend_decompress);
+ }
util_unreference_framebuffer_state(&rctx->framebuffer);
r600_context_fini(rctx);
free(rctx->states[i]);
}
- if (rctx->vbuf_mgr) {
- u_vbuf_destroy(rctx->vbuf_mgr);
+ if (rctx->uploader) {
+ u_upload_destroy(rctx->uploader);
}
util_slab_destroy(&rctx->pool_transfers);
- r600_update_num_contexts(rctx->screen, -1);
-
r600_release_command_buffer(&rctx->start_cs_cmd);
if (rctx->cs) {
{
struct r600_context *rctx = CALLOC_STRUCT(r600_context);
struct r600_screen* rscreen = (struct r600_screen *)screen;
+ struct pipe_blend_state no_blend = {};
if (rctx == NULL)
return NULL;
util_slab_create(&rctx->pool_transfers,
- sizeof(struct pipe_transfer), 64,
+ sizeof(struct r600_transfer), 64,
UTIL_SLAB_SINGLETHREADED);
- r600_update_num_contexts(rscreen, 1);
-
rctx->context.screen = screen;
rctx->context.priv = priv;
rctx->context.destroy = r600_destroy_context;
rctx->family = rscreen->family;
rctx->chip_class = rscreen->chip_class;
- LIST_INITHEAD(&rctx->dirty_states);
LIST_INITHEAD(&rctx->active_timer_queries);
LIST_INITHEAD(&rctx->active_nontimer_queries);
LIST_INITHEAD(&rctx->dirty);
- LIST_INITHEAD(&rctx->resource_dirty);
LIST_INITHEAD(&rctx->enable_list);
rctx->range = CALLOC(NUM_RANGES, sizeof(struct r600_range));
r600_init_query_functions(rctx);
r600_init_context_resource_functions(rctx);
r600_init_surface_functions(rctx);
- rctx->context.draw_vbo = r600_draw_vbo;
+
rctx->context.create_video_decoder = vl_create_decoder;
rctx->context.create_video_buffer = vl_video_buffer_create;
- r600_init_common_atoms(rctx);
+ r600_init_common_state_functions(rctx);
switch (rctx->chip_class) {
case R600:
if (r600_context_init(rctx))
goto fail;
rctx->custom_dsa_flush = r600_create_db_flush_dsa(rctx);
+ rctx->custom_blend_resolve = rctx->chip_class == R700 ? r700_create_resolve_blend(rctx)
+ : r600_create_resolve_blend(rctx);
+ rctx->custom_blend_decompress = r600_create_decompress_blend(rctx);
rctx->has_vertex_cache = !(rctx->family == CHIP_RV610 ||
rctx->family == CHIP_RV620 ||
rctx->family == CHIP_RS780 ||
case CAYMAN:
evergreen_init_state_functions(rctx);
evergreen_init_atom_start_cs(rctx);
+ evergreen_init_atom_start_compute_cs(rctx);
if (evergreen_context_init(rctx))
goto fail;
rctx->custom_dsa_flush = evergreen_create_db_flush_dsa(rctx);
+ rctx->custom_blend_resolve = evergreen_create_resolve_blend(rctx);
+ rctx->custom_blend_decompress = evergreen_create_decompress_blend(rctx);
rctx->has_vertex_cache = !(rctx->family == CHIP_CEDAR ||
rctx->family == CHIP_PALM ||
rctx->family == CHIP_SUMO ||
rctx->cs = rctx->ws->cs_create(rctx->ws);
rctx->ws->cs_set_flush_callback(rctx->cs, r600_flush_from_winsys, rctx);
- r600_emit_atom(rctx, &rctx->start_cs_cmd.atom);
-
- rctx->vbuf_mgr = u_vbuf_create(&rctx->context, 1024 * 1024, 256,
- PIPE_BIND_VERTEX_BUFFER |
- PIPE_BIND_INDEX_BUFFER |
- PIPE_BIND_CONSTANT_BUFFER,
- U_VERTEX_FETCH_DWORD_ALIGNED);
- if (!rctx->vbuf_mgr)
- goto fail;
- rctx->vbuf_mgr->caps.format_fixed32 = 0;
+
+ rctx->uploader = u_upload_create(&rctx->context, 1024 * 1024, 256,
+ PIPE_BIND_INDEX_BUFFER |
+ PIPE_BIND_CONSTANT_BUFFER);
+ if (!rctx->uploader)
+ goto fail;
rctx->blitter = util_blitter_create(&rctx->context);
if (rctx->blitter == NULL)
goto fail;
+ rctx->blitter->draw_rectangle = r600_draw_rectangle;
+ r600_begin_new_cs(rctx);
r600_get_backend_mask(rctx); /* this emits commands and must be last */
if (rctx->chip_class == R600)
TGSI_INTERPOLATE_CONSTANT);
rctx->context.bind_fs_state(&rctx->context, rctx->dummy_pixel_shader);
+ no_blend.rt[0].colormask = 0xF;
+ rctx->no_blend = rctx->context.create_blend_state(&rctx->context, &no_blend);
+
return &rctx->context;
fail:
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
case PIPE_CAP_TGSI_INSTANCEID:
+ case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
+ case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
+ case PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY:
+ case PIPE_CAP_USER_INDEX_BUFFERS:
+ case PIPE_CAP_USER_CONSTANT_BUFFERS:
+ case PIPE_CAP_COMPUTE:
+ case PIPE_CAP_START_INSTANCE:
+ case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
return 1;
+ case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
+ return 256;
+
case PIPE_CAP_GLSL_FEATURE_LEVEL:
- return rscreen->glsl_feature_level;
+ return 130;
/* Supported except the original R600. */
case PIPE_CAP_INDEP_BLEND_ENABLE:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
case PIPE_CAP_FRAGMENT_COLOR_CLAMPED:
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
+ case PIPE_CAP_USER_VERTEX_BUFFERS:
return 0;
/* Stream output. */
case PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS:
- return rscreen->info.r600_has_streamout ? 4 : 0;
+ return rscreen->has_streamout ? 4 : 0;
case PIPE_CAP_STREAM_OUTPUT_PAUSE_RESUME:
- return rscreen->info.r600_has_streamout ? 1 : 0;
+ return rscreen->has_streamout ? 1 : 0;
case PIPE_CAP_MAX_STREAM_OUTPUT_SEPARATE_COMPONENTS:
case PIPE_CAP_MAX_STREAM_OUTPUT_INTERLEAVED_COMPONENTS:
return 16*4;
/* Timer queries, present when the clock frequency is non zero. */
case PIPE_CAP_TIMER_QUERY:
return rscreen->info.r600_clock_crystal_freq != 0;
+ case PIPE_CAP_QUERY_TIMESTAMP:
+ return rscreen->info.drm_minor >= 20 &&
+ rscreen->info.r600_clock_crystal_freq != 0;
case PIPE_CAP_MIN_TEXEL_OFFSET:
return -8;
case PIPE_CAP_MAX_TEXEL_OFFSET:
return 7;
-
- case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS:
- return 0;
}
return 0;
}
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:
case PIPE_SHADER_VERTEX:
+ case PIPE_SHADER_COMPUTE:
break;
case PIPE_SHADER_GEOMETRY:
/* XXX: support and enable geometry programs */
case PIPE_SHADER_CAP_SUBROUTINES:
return 0;
case PIPE_SHADER_CAP_INTEGERS:
- return rscreen->glsl_feature_level >= 130;
+ return 1;
case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
return 16;
+ case PIPE_SHADER_CAP_PREFERRED_IR:
+ if (shader == PIPE_SHADER_COMPUTE) {
+ return PIPE_SHADER_IR_LLVM;
+ } else {
+ return PIPE_SHADER_IR_TGSI;
+ }
}
return 0;
}
}
}
+static int r600_get_compute_param(struct pipe_screen *screen,
+ enum pipe_compute_cap param,
+ void *ret)
+{
+ //TODO: select these params by asic
+ switch (param) {
+ case PIPE_COMPUTE_CAP_IR_TARGET:
+ if (ret) {
+ strcpy(ret, "r600--");
+ }
+ return 7 * sizeof(char);
+
+ case PIPE_COMPUTE_CAP_GRID_DIMENSION:
+ if (ret) {
+ uint64_t * grid_dimension = ret;
+ grid_dimension[0] = 3;
+ }
+ return 1 * sizeof(uint64_t);
+
+ case PIPE_COMPUTE_CAP_MAX_GRID_SIZE:
+ if (ret) {
+ uint64_t * grid_size = ret;
+ grid_size[0] = 65535;
+ grid_size[1] = 65535;
+ grid_size[2] = 1;
+ }
+ return 3 * sizeof(uint64_t) ;
+
+ case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE:
+ if (ret) {
+ uint64_t * block_size = ret;
+ block_size[0] = 256;
+ block_size[1] = 256;
+ block_size[2] = 256;
+ }
+ return 3 * sizeof(uint64_t);
+
+ case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK:
+ if (ret) {
+ uint64_t * max_threads_per_block = ret;
+ *max_threads_per_block = 256;
+ }
+ return sizeof(uint64_t);
+
+ case PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE:
+ if (ret) {
+ uint64_t * max_global_size = ret;
+ /* XXX: This is 64kb for now until we get the
+ * compute memory pool working correctly.
+ */
+ *max_global_size = 1024 * 16 * 4;
+ }
+ return sizeof(uint64_t);
+
+ case PIPE_COMPUTE_CAP_MAX_INPUT_SIZE:
+ if (ret) {
+ uint64_t * max_input_size = ret;
+ *max_input_size = 1024;
+ }
+ return sizeof(uint64_t);
+
+ case PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE:
+ if (ret) {
+ uint64_t * max_local_size = ret;
+ /* XXX: This is what the proprietary driver reports, we
+ * may want to use a different value. */
+ *max_local_size = 32768;
+ }
+ return sizeof(uint64_t);
+
+ default:
+ fprintf(stderr, "unknown PIPE_COMPUTE_CAP %d\n", param);
+ return 0;
+ }
+}
+
static void r600_destroy_screen(struct pipe_screen* pscreen)
{
struct r600_screen *rscreen = (struct r600_screen *)pscreen;
if (rscreen == NULL)
return;
+ if (rscreen->global_pool) {
+ compute_memory_pool_delete(rscreen->global_pool);
+ }
+
if (rscreen->fences.bo) {
struct r600_fence_block *entry, *tmp;
FREE(entry);
}
- rscreen->ws->buffer_unmap(rscreen->fences.bo->buf);
+ rscreen->ws->buffer_unmap(rscreen->fences.bo->cs_buf);
pipe_resource_reference((struct pipe_resource**)&rscreen->fences.bo, NULL);
}
pipe_mutex_destroy(rscreen->fences.mutex);
rscreen->ws->destroy(rscreen->ws);
-
- util_slab_destroy(&rscreen->pool_buffers);
- pipe_mutex_destroy(rscreen->mutex_num_contexts);
FREE(rscreen);
}
}
}
+static uint64_t r600_get_timestamp(struct pipe_screen *screen)
+{
+ struct r600_screen *rscreen = (struct r600_screen*)screen;
+
+ return 1000000 * rscreen->ws->query_timestamp(rscreen->ws) /
+ rscreen->info.r600_clock_crystal_freq;
+}
+
struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
{
struct r600_screen *rscreen = CALLOC_STRUCT(r600_screen);
- boolean glsl130_default;
+
if (rscreen == NULL) {
return NULL;
}
rscreen->chip_class = R600;
}
- /* XXX streamout is said to be broken on r700 and cayman */
- if ((rscreen->chip_class == R700 ||
- rscreen->chip_class == CAYMAN) &&
- !debug_get_bool_option("R600_STREAMOUT", FALSE)) {
- rscreen->info.r600_has_streamout = false;
+ /* Figure out streamout kernel support. */
+ switch (rscreen->chip_class) {
+ case R600:
+ case EVERGREEN:
+ case CAYMAN:
+ rscreen->has_streamout = rscreen->info.drm_minor >= 14;
+ break;
+ case R700:
+ rscreen->has_streamout = rscreen->info.drm_minor >= 17;
+ break;
}
if (r600_init_tiling(rscreen)) {
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;
+ rscreen->screen.get_compute_param = r600_get_compute_param;
+ rscreen->screen.get_timestamp = r600_get_timestamp;
+
if (rscreen->chip_class >= EVERGREEN) {
rscreen->screen.is_format_supported = evergreen_is_format_supported;
} else {
util_format_s3tc_init();
- util_slab_create(&rscreen->pool_buffers,
- sizeof(struct r600_resource), 64,
- UTIL_SLAB_SINGLETHREADED);
-
- pipe_mutex_init(rscreen->mutex_num_contexts);
-
rscreen->fences.bo = NULL;
rscreen->fences.data = NULL;
rscreen->fences.next_index = 0;
LIST_INITHEAD(&rscreen->fences.blocks);
pipe_mutex_init(rscreen->fences.mutex);
- rscreen->use_surface_alloc = debug_get_bool_option("R600_SURF", TRUE);
- glsl130_default = (rscreen->chip_class >= R600 && rscreen->chip_class <= EVERGREEN) ? TRUE : FALSE;
- rscreen->glsl_feature_level = debug_get_bool_option("R600_GLSL130", glsl130_default) ? 130 : 120;
+ rscreen->global_pool = compute_memory_pool_new(rscreen);
return &rscreen->screen;
}