void r300_texture_reinterpret_format(struct pipe_screen *screen, struct pipe_texture *tex, enum pipe_format new_format) { struct r300_screen *r300screen = r300_screen(screen); SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n", util_format_name(tex->format), util_format_name(new_format)); tex->format = new_format; r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex); }
static void* r300_create_sampler_state(struct pipe_context* pipe, const struct pipe_sampler_state* state) { struct r300_context* r300 = r300_context(pipe); struct r300_sampler_state* sampler = CALLOC_STRUCT(r300_sampler_state); int lod_bias; sampler->filter0 |= (r300_translate_wrap(state->wrap_s) << R300_TX_WRAP_S_SHIFT) | (r300_translate_wrap(state->wrap_t) << R300_TX_WRAP_T_SHIFT) | (r300_translate_wrap(state->wrap_r) << R300_TX_WRAP_R_SHIFT); sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter, state->mag_img_filter, state->min_mip_filter); lod_bias = CLAMP((int)(state->lod_bias * 32), -(1 << 9), (1 << 9) - 1); sampler->filter1 |= lod_bias << R300_LOD_BIAS_SHIFT; sampler->filter1 |= r300_anisotropy(state->max_anisotropy); util_pack_color(state->border_color, PIPE_FORMAT_A8R8G8B8_UNORM, &sampler->border_color); /* R500-specific fixups and optimizations */ if (r300_screen(r300->context.screen)->caps->is_r500) { sampler->filter1 |= R500_BORDER_FIX; } return (void*)sampler; }
static void * r300_buffer_transfer_map( struct pipe_context *pipe, struct pipe_transfer *transfer ) { struct r300_context *r300 = r300_context(pipe); struct r300_screen *r300screen = r300_screen(pipe->screen); struct radeon_winsys *rws = r300screen->rws; struct r300_resource *rbuf = r300_resource(transfer->resource); uint8_t *map; enum pipe_transfer_usage usage; if (rbuf->b.b.user_ptr) return rbuf->b.b.user_ptr + transfer->box.x; if (rbuf->constant_buffer) return (uint8_t *) rbuf->constant_buffer + transfer->box.x; /* Buffers are never used for write, therefore mapping for read can be * unsynchronized. */ usage = transfer->usage; if (!(usage & PIPE_TRANSFER_WRITE)) { usage |= PIPE_TRANSFER_UNSYNCHRONIZED; } map = rws->buffer_map(rbuf->cs_buf, r300->cs, usage); if (map == NULL) return NULL; return map + transfer->box.x; }
static boolean r300_fence_signalled(struct pipe_screen *screen, struct pipe_fence_handle *fence) { struct radeon_winsys *rws = r300_screen(screen)->rws; return rws->fence_wait(rws, fence, 0); }
static float r300_get_paramf(struct pipe_screen* pscreen, int param) { struct r300_screen* r300screen = r300_screen(pscreen); 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: /* The maximum dimensions of the colorbuffer are our practical * rendering limits. 2048 pixels should be enough for anybody. */ if (r300screen->caps->is_r500) { return 4096.0f; } else if (r300screen->caps->is_r400) { return 4021.0f; } else { return 2560.0f; } case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: return 16.0f; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0f; default: debug_printf("r300: Implementation error: Bad paramf %d\n", param); return 0.0f; } }
static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); FREE(r300screen->caps); FREE(r300screen); }
struct pipe_resource *r300_user_buffer_create(struct pipe_screen *screen, void *ptr, unsigned size, unsigned bind) { struct r300_screen *r300screen = r300_screen(screen); struct r300_resource *rbuf; rbuf = util_slab_alloc(&r300screen->pool_buffers); pipe_reference_init(&rbuf->b.b.reference, 1); rbuf->b.b.screen = screen; rbuf->b.b.target = PIPE_BUFFER; rbuf->b.b.format = PIPE_FORMAT_R8_UNORM; rbuf->b.b.usage = PIPE_USAGE_IMMUTABLE; rbuf->b.b.bind = bind; rbuf->b.b.width0 = ~0; rbuf->b.b.height0 = 1; rbuf->b.b.depth0 = 1; rbuf->b.b.array_size = 1; rbuf->b.b.flags = 0; rbuf->b.b.user_ptr = ptr; rbuf->b.vtbl = &r300_buffer_vtbl; rbuf->domain = RADEON_DOMAIN_GTT; rbuf->buf = NULL; rbuf->constant_buffer = NULL; return &rbuf->b.b; }
static boolean r300_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, uint64_t timeout) { struct radeon_winsys *rws = r300_screen(screen)->rws; struct pb_buffer *rfence = (struct pb_buffer*)fence; if (timeout != PIPE_TIMEOUT_INFINITE) { int64_t start_time = os_time_get(); /* Convert to microseconds. */ timeout /= 1000; /* Wait in a loop. */ while (rws->buffer_is_busy(rfence, RADEON_USAGE_READWRITE)) { if (os_time_get() - start_time >= timeout) { return FALSE; } os_time_sleep(10); } return TRUE; } rws->buffer_wait(rfence, RADEON_USAGE_READWRITE); return TRUE; }
static float r300_get_paramf(struct pipe_screen* pscreen, enum pipe_capf param) { struct r300_screen* r300screen = r300_screen(pscreen); switch (param) { 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: /* The maximum dimensions of the colorbuffer are our practical * rendering limits. 2048 pixels should be enough for anybody. */ if (r300screen->caps.is_r500) { return 4096.0f; } else if (r300screen->caps.is_r400) { return 4021.0f; } else { return 2560.0f; } case PIPE_CAPF_MAX_TEXTURE_ANISOTROPY: return 16.0f; case PIPE_CAPF_MAX_TEXTURE_LOD_BIAS: return 16.0f; 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; default: debug_printf("r300: Warning: Unknown CAP %d in get_paramf.\n", param); return 0.0f; } }
static struct pipe_transfer* r300_get_tex_transfer(struct pipe_screen *screen, struct pipe_texture *texture, unsigned face, unsigned level, unsigned zslice, enum pipe_transfer_usage usage, unsigned x, unsigned y, unsigned w, unsigned h) { struct r300_texture *tex = (struct r300_texture *)texture; struct r300_transfer *trans; struct r300_screen *rscreen = r300_screen(screen); unsigned offset; offset = r300_texture_get_offset(tex, level, zslice, face); /* in bytes */ trans = CALLOC_STRUCT(r300_transfer); if (trans) { pipe_texture_reference(&trans->transfer.texture, texture); trans->transfer.x = x; trans->transfer.y = y; trans->transfer.width = w; trans->transfer.height = h; trans->transfer.stride = r300_texture_get_stride(rscreen, tex, level); trans->transfer.usage = usage; trans->transfer.zslice = zslice; trans->transfer.face = face; trans->offset = offset; } return &trans->transfer; }
static boolean r300_fence_finish(struct pipe_screen *screen, struct pipe_fence_handle *fence, uint64_t timeout) { struct radeon_winsys *rws = r300_screen(screen)->rws; return rws->fence_wait(rws, fence, timeout); }
static void r300_fence_reference(struct pipe_screen *screen, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence) { struct radeon_winsys *rws = r300_screen(screen)->rws; rws->fence_reference(ptr, fence); }
static boolean r300_fence_signalled(struct pipe_screen *screen, struct pipe_fence_handle *fence) { struct radeon_winsys *rws = r300_screen(screen)->rws; struct pb_buffer *rfence = (struct pb_buffer*)fence; return !rws->buffer_is_busy(rfence, RADEON_USAGE_READWRITE); }
static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); struct radeon_winsys *rws = radeon_winsys(pscreen); if (rws) rws->destroy(rws); FREE(r300screen); }
static void r300_set_clip_state(struct pipe_context* pipe, const struct pipe_clip_state* state) { struct r300_context* r300 = r300_context(pipe); if (r300_screen(pipe->screen)->caps->has_tcl) { r300->clip_state = *state; r300->dirty_state |= R300_NEW_CLIP; } else { draw_flush(r300->draw); draw_set_clip_state(r300->draw, state); } }
static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); struct radeon_winsys *rws = radeon_winsys(pscreen); util_slab_destroy(&r300screen->pool_buffers); pipe_mutex_destroy(r300screen->num_contexts_mutex); if (rws) rws->destroy(rws); FREE(r300screen); }
static void r300_buffer_destroy(struct pipe_screen *screen, struct pipe_resource *buf) { struct r300_screen *r300screen = r300_screen(screen); struct r300_resource *rbuf = r300_resource(buf); if (rbuf->constant_buffer) FREE(rbuf->constant_buffer); if (rbuf->buf) pb_reference(&rbuf->buf, NULL); util_slab_free(&r300screen->pool_buffers, rbuf); }
static void r300_destroy_screen(struct pipe_screen* pscreen) { struct r300_screen* r300screen = r300_screen(pscreen); struct radeon_winsys *rws = radeon_winsys(pscreen); if (rws && !rws->unref(rws)) return; pipe_mutex_destroy(r300screen->cmask_mutex); if (rws) rws->destroy(rws); FREE(r300screen); }
static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); if (r300_screen(pipe->screen)->caps->has_tcl) { struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; rc_constants_destroy(&vs->code.constants); draw_delete_vertex_shader(r300->draw, vs->draw); FREE((void*)vs->state.tokens); FREE(shader); } else { draw_delete_vertex_shader(r300->draw, (struct draw_vertex_shader*)shader); } }
void r300_translate_fragment_shader(struct r300_context* r300, struct r300_fragment_shader* fs) { struct r300_fragment_program_compiler compiler; struct tgsi_to_rc ttr; memset(&compiler, 0, sizeof(compiler)); rc_init(&compiler.Base); compiler.Base.Debug = DBG_ON(r300, DBG_FP); compiler.code = &fs->code; compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500; compiler.AllocateHwInputs = &allocate_hardware_inputs; compiler.UserData = fs; /* TODO: Program compilation depends on texture compare modes, * which are sampler state. Therefore, programs need to be recompiled * depending on this state as in the classic Mesa driver. * * This is not yet handled correctly. */ find_output_registers(&compiler, fs); if (compiler.Base.Debug) { debug_printf("r300: Initial fragment program\n"); tgsi_dump(fs->state.tokens, 0); } /* Translate TGSI to our internal representation */ ttr.compiler = &compiler.Base; ttr.info = &fs->info; r300_tgsi_to_rc(&ttr, fs->state.tokens); /* Invoke the compiler */ r3xx_compile_fragment_program(&compiler); if (compiler.Base.Error) { /* XXX failover maybe? */ DBG(r300, DBG_FP, "r300: Error compiling fragment program: %s\n", compiler.Base.ErrorMsg); } /* And, finally... */ rc_destroy(&compiler.Base); fs->translated = TRUE; }
static boolean r300_is_format_supported(struct pipe_screen* screen, enum pipe_format format, enum pipe_texture_target target, unsigned usage, unsigned geom_flags) { uint32_t retval = 0; boolean is_r500 = r300_screen(screen)->caps->is_r500; boolean is_z24 = format == PIPE_FORMAT_X8Z24_UNORM || format == PIPE_FORMAT_S8Z24_UNORM; boolean is_color2101010 = format == PIPE_FORMAT_R10G10B10A2_UNORM; if (target >= PIPE_MAX_TEXTURE_TYPES) { debug_printf("r300: Implementation error: Received bogus texture " "target %d in %s\n", target, __FUNCTION__); return FALSE; } /* Check sampler format support. */ if ((usage & PIPE_TEXTURE_USAGE_SAMPLER) && /* Z24 cannot be sampled from on non-r5xx. */ (is_r500 || !is_z24) && r300_is_sampler_format_supported(format)) { retval |= PIPE_TEXTURE_USAGE_SAMPLER; } /* Check colorbuffer format support. */ if ((usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | PIPE_TEXTURE_USAGE_PRIMARY)) && /* 2101010 cannot be rendered to on non-r5xx. */ (is_r500 || !is_color2101010) && r300_is_colorbuffer_format_supported(format)) { retval |= usage & (PIPE_TEXTURE_USAGE_RENDER_TARGET | PIPE_TEXTURE_USAGE_DISPLAY_TARGET | PIPE_TEXTURE_USAGE_PRIMARY); } /* Check depth-stencil format support. */ if (usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL && r300_is_zs_format_supported(format)) { retval |= PIPE_TEXTURE_USAGE_DEPTH_STENCIL; } return retval == usage; }
struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen, const struct pipe_resource *base, struct winsys_handle *whandle) { struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys; struct r300_screen *rscreen = r300_screen(screen); struct r300_winsys_buffer *buffer; enum r300_buffer_tiling microtile, macrotile; unsigned stride, size; /* Support only 2D textures without mipmaps */ if ((base->target != PIPE_TEXTURE_2D && base->target != PIPE_TEXTURE_RECT) || base->depth0 != 1 || base->last_level != 0) { return NULL; } buffer = rws->buffer_from_handle(rws, whandle, &stride, &size); if (!buffer) return NULL; rws->buffer_get_tiling(rws, buffer, µtile, ¯otile); /* Enforce a microtiled zbuffer. */ if (util_format_is_depth_or_stencil(base->format) && microtile == R300_BUFFER_LINEAR) { switch (util_format_get_blocksize(base->format)) { case 4: microtile = R300_BUFFER_TILED; break; case 2: if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT)) microtile = R300_BUFFER_SQUARETILED; break; } } return (struct pipe_resource*) r300_texture_create_object(rscreen, base, microtile, macrotile, stride, size, buffer); }
/* Create a new texture. */ struct pipe_resource *r300_texture_create(struct pipe_screen *screen, const struct pipe_resource *base) { struct r300_screen *rscreen = r300_screen(screen); enum r300_buffer_tiling microtile, macrotile; if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) || (base->bind & PIPE_BIND_SCANOUT)) { microtile = R300_BUFFER_LINEAR; macrotile = R300_BUFFER_LINEAR; } else { microtile = R300_BUFFER_SELECT_LAYOUT; macrotile = R300_BUFFER_SELECT_LAYOUT; } return (struct pipe_resource*) r300_texture_create_object(rscreen, base, microtile, macrotile, 0, 0, NULL); }
static void* r300_create_vs_state(struct pipe_context* pipe, const struct pipe_shader_state* shader) { struct r300_context* r300 = r300_context(pipe); if (r300_screen(pipe->screen)->caps->has_tcl) { struct r300_vertex_shader* vs = CALLOC_STRUCT(r300_vertex_shader); /* Copy state directly into shader. */ vs->state = *shader; vs->state.tokens = tgsi_dup_tokens(shader->tokens); tgsi_scan_shader(shader->tokens, &vs->info); /* Appease Draw. */ vs->draw = draw_create_vertex_shader(r300->draw, shader); return (void*)vs; } else { return draw_create_vertex_shader(r300->draw, shader); } }
struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) { struct r300_screen *r300screen = r300_screen(screen); struct r300_resource *rbuf; rbuf = MALLOC_STRUCT(r300_resource); rbuf->b.b = *templ; rbuf->b.vtbl = &r300_buffer_vtbl; pipe_reference_init(&rbuf->b.b.reference, 1); rbuf->b.b.screen = screen; rbuf->domain = RADEON_DOMAIN_GTT; rbuf->buf = NULL; rbuf->malloced_buffer = NULL; /* Allocate constant buffers and SWTCL vertex and index buffers in RAM. * Note that uploaded index buffers use the flag PIPE_BIND_CUSTOM, so that * we can distinguish them from user-created buffers. */ if (templ->bind & PIPE_BIND_CONSTANT_BUFFER || (!r300screen->caps.has_tcl && !(templ->bind & PIPE_BIND_CUSTOM))) { rbuf->malloced_buffer = align_malloc(templ->width0, 64); return &rbuf->b.b; } rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, rbuf->b.b.width0, R300_BUFFER_ALIGNMENT, TRUE, rbuf->domain, 0); if (!rbuf->buf) { FREE(rbuf); return NULL; } rbuf->cs_buf = r300screen->rws->buffer_get_cs_handle(rbuf->buf); return &rbuf->b.b; }
struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) { struct r300_screen *r300screen = r300_screen(screen); struct r300_resource *rbuf; unsigned alignment = 16; rbuf = MALLOC_STRUCT(r300_resource); rbuf->b.b = *templ; rbuf->b.vtbl = &r300_buffer_vtbl; pipe_reference_init(&rbuf->b.b.reference, 1); rbuf->b.b.screen = screen; rbuf->domain = RADEON_DOMAIN_GTT; rbuf->buf = NULL; rbuf->malloced_buffer = NULL; /* Alloc constant buffers and SWTCL buffers in RAM. */ if (templ->bind & PIPE_BIND_CONSTANT_BUFFER || (!r300screen->caps.has_tcl && (templ->bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)))) { rbuf->malloced_buffer = MALLOC(templ->width0); return &rbuf->b.b; } rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, rbuf->b.b.width0, alignment, rbuf->b.b.bind, rbuf->domain); if (!rbuf->buf) { FREE(rbuf); return NULL; } rbuf->cs_buf = r300screen->rws->buffer_get_cs_handle(rbuf->buf); return &rbuf->b.b; }
struct pipe_resource *r300_buffer_create(struct pipe_screen *screen, const struct pipe_resource *templ) { struct r300_screen *r300screen = r300_screen(screen); struct r300_resource *rbuf; unsigned alignment = 16; rbuf = util_slab_alloc(&r300screen->pool_buffers); rbuf->b.b = *templ; rbuf->b.vtbl = &r300_buffer_vtbl; pipe_reference_init(&rbuf->b.b.reference, 1); rbuf->b.b.screen = screen; rbuf->b.b.user_ptr = NULL; rbuf->domain = RADEON_DOMAIN_GTT; rbuf->buf = NULL; rbuf->constant_buffer = NULL; /* Alloc constant buffers in RAM. */ if (templ->bind & PIPE_BIND_CONSTANT_BUFFER) { rbuf->constant_buffer = MALLOC(templ->width0); return &rbuf->b.b; } rbuf->buf = r300screen->rws->buffer_create(r300screen->rws, rbuf->b.b.width0, alignment, rbuf->b.b.bind, rbuf->domain); if (!rbuf->buf) { util_slab_free(&r300screen->pool_buffers, rbuf); return NULL; } rbuf->cs_buf = r300screen->rws->buffer_get_cs_handle(rbuf->buf); return &rbuf->b.b; }
static void r300_set_scissor_state(struct pipe_context* pipe, const struct pipe_scissor_state* state) { struct r300_context* r300 = r300_context(pipe); if (r300_screen(r300->context.screen)->caps->is_r500) { r300->scissor_state->scissor_top_left = (state->minx << R300_SCISSORS_X_SHIFT) | (state->miny << R300_SCISSORS_Y_SHIFT); r300->scissor_state->scissor_bottom_right = ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) | ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT); } else { /* Offset of 1440 in non-R500 chipsets. */ r300->scissor_state->scissor_top_left = ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) | ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT); r300->scissor_state->scissor_bottom_right = (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) | (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT); } r300->dirty_state |= R300_NEW_SCISSOR; }
static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); draw_flush(r300->draw); if (r300_screen(pipe->screen)->caps->has_tcl) { struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader; if (vs == NULL) { r300->vs = NULL; return; } else if (!vs->translated) { r300_translate_vertex_shader(r300, vs); } draw_bind_vertex_shader(r300->draw, vs->draw); r300->vs = vs; r300->dirty_state |= R300_NEW_VERTEX_SHADER | R300_NEW_VERTEX_SHADER_CONSTANTS; } else { draw_bind_vertex_shader(r300->draw, (struct draw_vertex_shader*)shader); } }
struct pipe_context* r300_create_context(struct pipe_screen* screen, void *priv) { struct r300_context* r300 = CALLOC_STRUCT(r300_context); struct r300_screen* r300screen = r300_screen(screen); struct radeon_winsys *rws = r300screen->rws; if (!r300) return NULL; r300->rws = rws; r300->screen = r300screen; r300->context.screen = screen; r300->context.priv = priv; r300->context.destroy = r300_destroy_context; util_slab_create(&r300->pool_transfers, sizeof(struct pipe_transfer), 64, UTIL_SLAB_SINGLETHREADED); r300->cs = rws->cs_create(rws, RING_GFX, r300_flush_callback, r300, NULL); if (r300->cs == NULL) goto fail; if (!r300screen->caps.has_tcl) { /* Create a Draw. This is used for SW TCL. */ r300->draw = draw_create(&r300->context); if (r300->draw == NULL) goto fail; /* Enable our renderer. */ draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300)); /* Disable converting points/lines to triangles. */ draw_wide_line_threshold(r300->draw, 10000000.f); draw_wide_point_threshold(r300->draw, 10000000.f); draw_wide_point_sprites(r300->draw, FALSE); draw_enable_line_stipple(r300->draw, TRUE); draw_enable_point_sprites(r300->draw, FALSE); } if (!r300_setup_atoms(r300)) goto fail; r300_init_blit_functions(r300); r300_init_flush_functions(r300); r300_init_query_functions(r300); r300_init_state_functions(r300); r300_init_resource_functions(r300); r300_init_render_functions(r300); r300_init_states(&r300->context); r300->context.create_video_codec = vl_create_decoder; r300->context.create_video_buffer = vl_video_buffer_create; r300->uploader = u_upload_create(&r300->context, 256 * 1024, 4, PIPE_BIND_CUSTOM); r300->blitter = util_blitter_create(&r300->context); if (r300->blitter == NULL) goto fail; r300->blitter->draw_rectangle = r300_blitter_draw_rectangle; /* The KIL opcode needs the first texture unit to be enabled * on r3xx-r4xx. In order to calm down the CS checker, we bind this * dummy texture there. */ if (!r300->screen->caps.is_r500) { struct pipe_resource *tex; struct pipe_resource rtempl = {{0}}; struct pipe_sampler_view vtempl = {{0}}; rtempl.target = PIPE_TEXTURE_2D; rtempl.format = PIPE_FORMAT_I8_UNORM; rtempl.usage = PIPE_USAGE_IMMUTABLE; rtempl.width0 = 1; rtempl.height0 = 1; rtempl.depth0 = 1; tex = screen->resource_create(screen, &rtempl); u_sampler_view_default_template(&vtempl, tex, tex->format); r300->texkill_sampler = (struct r300_sampler_view*) r300->context.create_sampler_view(&r300->context, tex, &vtempl); pipe_resource_reference(&tex, NULL); } if (r300screen->caps.has_tcl) { struct pipe_resource vb; memset(&vb, 0, sizeof(vb)); vb.target = PIPE_BUFFER; vb.format = PIPE_FORMAT_R8_UNORM; vb.usage = PIPE_USAGE_DEFAULT; vb.width0 = sizeof(float) * 16; vb.height0 = 1; vb.depth0 = 1; r300->dummy_vb.buffer = screen->resource_create(screen, &vb); r300->context.set_vertex_buffers(&r300->context, 0, 1, &r300->dummy_vb); } { struct pipe_depth_stencil_alpha_state dsa; memset(&dsa, 0, sizeof(dsa)); dsa.depth.writemask = 1; r300->dsa_decompress_zmask = r300->context.create_depth_stencil_alpha_state(&r300->context, &dsa); } r300->hyperz_time_of_last_flush = os_time_get(); /* Register allocator state */ rc_init_regalloc_state(&r300->fs_regalloc_state); /* Print driver info. */ #ifdef DEBUG { #else if (DBG_ON(r300, DBG_INFO)) { #endif fprintf(stderr, "r300: DRM version: %d.%d.%d, Name: %s, ID: 0x%04x, GB: %d, Z: %d\n" "r300: GART size: %"PRIu64" MB, VRAM size: %"PRIu64" MB\n" "r300: AA compression RAM: %s, Z compression RAM: %s, HiZ RAM: %s\n", r300->screen->info.drm_major, r300->screen->info.drm_minor, r300->screen->info.drm_patchlevel, screen->get_name(screen), r300->screen->info.pci_id, r300->screen->info.r300_num_gb_pipes, r300->screen->info.r300_num_z_pipes, r300->screen->info.gart_size >> 20, r300->screen->info.vram_size >> 20, "YES", /* XXX really? */ r300->screen->caps.zmask_ram ? "YES" : "NO", r300->screen->caps.hiz_ram ? "YES" : "NO"); } return &r300->context; fail: r300_destroy_context(&r300->context); return NULL; }