X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fr300%2Fr300_state.c;h=058e6f881f0fafbb0e832d756e76b07e568b549f;hb=507337864fa80caf9f26602324d2c28dd0a75d61;hp=ecb4fc691cc8ff0355f20d2c54c87e0d283e8c42;hpb=79ddcb93fbd9d9786e4c7a6da4c71005b587a1bb;p=mesa.git diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index ecb4fc691cc..058e6f881f0 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -45,7 +45,6 @@ #include "r300_fs.h" #include "r300_texture.h" #include "r300_vs.h" -#include "r300_winsys.h" /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ @@ -398,10 +397,6 @@ static void r300_bind_blend_state(struct pipe_context* pipe, struct r300_context* r300 = r300_context(pipe); UPDATE_STATE(state, r300->blend_state); - - if (r300->fs.state && r300_pick_fragment_shader(r300)) { - r300_mark_fs_code_dirty(r300); - } } /* Free blend state. */ @@ -498,21 +493,13 @@ static void r300_set_clip_state(struct pipe_context* pipe, (struct r300_clip_state*)r300->clip_state.state; CB_LOCALS; - clip->clip = *state; - if (r300->screen->caps.has_tcl) { - r300->clip_state.size = 2 + !!state->nr * 3 + state->nr * 4; - BEGIN_CB(clip->cb, r300->clip_state.size); - if (state->nr) { - OUT_CB_REG(R300_VAP_PVS_VECTOR_INDX_REG, + OUT_CB_REG(R300_VAP_PVS_VECTOR_INDX_REG, (r300->screen->caps.is_r500 ? R500_PVS_UCP_START : R300_PVS_UCP_START)); - OUT_CB_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, state->nr * 4); - OUT_CB_TABLE(state->ucp, state->nr * 4); - } - OUT_CB_REG(R300_VAP_CLIP_CNTL, ((1 << state->nr) - 1) | - R300_PS_UCP_MODE_CLIP_AS_TRIFAN); + OUT_CB_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, 6 * 4); + OUT_CB_TABLE(state->ucp, 6 * 4); END_CB; r300_mark_atom_dirty(r300, &r300->clip_state); @@ -554,6 +541,10 @@ static void* dsa->z_stencil_control |= (r300_translate_depth_stencil_function(state->depth.func) << R300_Z_FUNC_SHIFT); + } else { + /* We must enable depth test, otherwise occlusion queries won't work. */ + dsa->z_buffer_control |= R300_Z_ENABLE; + dsa->z_stencil_control |= R300_ZS_ALWAYS; } /* Stencil buffer setup. */ @@ -637,11 +628,13 @@ static void* OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); END_CB; + /* We must enable depth test, otherwise occlusion queries won't work. + * We setup a dummy zbuffer to silent the CS checker, see emit_fb_state. */ BEGIN_CB(dsa->cb_zb_no_readwrite, 10); OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function); OUT_CB_REG_SEQ(R300_ZB_CNTL, 3); - OUT_CB(0); - OUT_CB(0); + OUT_CB(R300_Z_ENABLE); + OUT_CB(R300_ZS_ALWAYS); OUT_CB(0); OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0); OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); @@ -650,8 +643,8 @@ static void* BEGIN_CB(dsa->cb_fp16_zb_no_readwrite, 10); OUT_CB_REG(R300_FG_ALPHA_FUNC, dsa->alpha_function_fp16); OUT_CB_REG_SEQ(R300_ZB_CNTL, 3); - OUT_CB(0); - OUT_CB(0); + OUT_CB(R300_Z_ENABLE); + OUT_CB(R300_ZS_ALWAYS); OUT_CB(0); OUT_CB_REG(R500_ZB_STENCILREFMASK_BF, 0); OUT_CB_REG(R500_FG_ALPHA_VALUE, dsa->alpha_value); @@ -755,7 +748,7 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index, "r300: %s[%i] Dim: %ix%i, Firstlayer: %i, " "Lastlayer: %i, Level: %i, Format: %s\n" - "r300: TEX: Macro: %s, Micro: %s, Pitch: %i, " + "r300: TEX: Macro: %s, Micro: %s, " "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n", binding, index, surf->width, surf->height, @@ -764,16 +757,14 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index, rtex->tex.macrotile[0] ? "YES" : " NO", rtex->tex.microtile ? "YES" : " NO", - rtex->tex.stride_in_pixels[0], tex->width0, tex->height0, tex->depth0, - tex->last_level, util_format_short_name(tex->format)); + tex->last_level, util_format_short_name(surf->format)); } void r300_mark_fb_state_dirty(struct r300_context *r300, enum r300_fb_state_change change) { struct pipe_framebuffer_state *state = r300->fb_state.state; - boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ); r300_mark_atom_dirty(r300, &r300->gpu_flush); r300_mark_atom_dirty(r300, &r300->fb_state); @@ -798,12 +789,14 @@ void r300_mark_fb_state_dirty(struct r300_context *r300, /* Now compute the fb_state atom size. */ r300->fb_state.size = 2 + (8 * state->nr_cbufs); - if (r300->cbzb_clear) + if (r300->cbzb_clear) { r300->fb_state.size += 10; - else if (state->zsbuf) { + } else if (state->zsbuf) { r300->fb_state.size += 10; - if (can_hyperz) + if (r300->hyperz_enabled) r300->fb_state.size += 8; + } else if (state->nr_cbufs) { + r300->fb_state.size += 10; } /* The size of the rest of atoms stays the same. */ @@ -818,6 +811,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe, struct pipe_framebuffer_state *old_state = r300->fb_state.state; unsigned max_width, max_height, i; uint32_t zbuffer_bpp = 0; + boolean unlock_zbuffer = FALSE; if (r300->screen->caps.is_r500) { max_width = max_height = 4096; @@ -833,7 +827,7 @@ r300_set_framebuffer_state(struct pipe_context* pipe, return; } - if (old_state->zsbuf && r300->zmask_in_use && !r300->hyperz_locked) { + if (old_state->zsbuf && r300->zmask_in_use && !r300->locked_zbuffer) { /* There is a zmask in use, what are we gonna do? */ if (state->zsbuf) { if (!pipe_surface_equal(old_state->zsbuf, state->zsbuf)) { @@ -843,10 +837,9 @@ r300_set_framebuffer_state(struct pipe_context* pipe, } } else { /* We don't bind another zbuffer, so lock the current one. */ - r300->hyperz_locked = TRUE; pipe_surface_reference(&r300->locked_zbuffer, old_state->zsbuf); } - } else if (r300->hyperz_locked && r300->locked_zbuffer) { + } else if (r300->locked_zbuffer) { /* We have a locked zbuffer now, what are we gonna do? */ if (state->zsbuf) { if (!pipe_surface_equal(r300->locked_zbuffer, state->zsbuf)) { @@ -856,10 +849,11 @@ r300_set_framebuffer_state(struct pipe_context* pipe, r300->hiz_in_use = FALSE; } else { /* We are binding the locked zbuffer again, so unlock it. */ - r300->hyperz_locked = FALSE; + unlock_zbuffer = TRUE; } } } + assert(state->zsbuf || (r300->locked_zbuffer && !unlock_zbuffer) || !r300->zmask_in_use); /* Need to reset clamping or colormask. */ r300_mark_atom_dirty(r300, &r300->blend_state); @@ -869,19 +863,23 @@ r300_set_framebuffer_state(struct pipe_context* pipe, r300_mark_atom_dirty(r300, &r300->dsa_state); } - /* The tiling flags are dependent on the surface miplevel, unfortunately. */ - r300_fb_set_tiling_flags(r300, state); + if (r300->screen->info.drm_minor < 12) { + /* The tiling flags are dependent on the surface miplevel, unfortunately. + * This workarounds a bad design decision in old kernels which were + * rewriting tile fields in registers. */ + r300_fb_set_tiling_flags(r300, state); + } util_copy_framebuffer_state(r300->fb_state.state, state); - if (!r300->hyperz_locked) { + if (unlock_zbuffer) { pipe_surface_reference(&r300->locked_zbuffer, NULL); } r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE); if (state->zsbuf) { - switch (util_format_get_blocksize(state->zsbuf->texture->format)) { + switch (util_format_get_blocksize(state->zsbuf->format)) { case 2: zbuffer_bpp = 16; break; @@ -973,24 +971,14 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader) { struct r300_context* r300 = r300_context(pipe); struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader; - struct pipe_framebuffer_state *fb = r300->fb_state.state; - boolean last_multi_write; if (fs == NULL) { r300->fs.state = NULL; return; } - last_multi_write = r300_fragment_shader_writes_all(r300_fs(r300)); - r300->fs.state = fs; - r300_pick_fragment_shader(r300); - r300_mark_fs_code_dirty(r300); - - if (fb->nr_cbufs > 1 && - last_multi_write != r300_fragment_shader_writes_all(fs)) { - r300_mark_fb_state_dirty(r300, R300_CHANGED_MULTIWRITE); - } + r300->fs_status = FRAGMENT_SHADER_DIRTY; r300_mark_atom_dirty(r300, &r300->rs_block_state); /* Will be updated before the emission. */ } @@ -1029,8 +1017,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe, const struct pipe_rasterizer_state* state) { struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); - float psiz; uint32_t vap_control_status; /* R300_VAP_CNTL_STATUS: 0x2140 */ + uint32_t vap_clip_cntl; /* R300_VAP_CLIP_CNTL: 0x221C */ uint32_t point_size; /* R300_GA_POINT_SIZE: 0x421c */ uint32_t point_minmax; /* R300_GA_POINT_MINMAX: 0x4230 */ uint32_t line_control; /* R300_GA_LINE_CNTL: 0x4234 */ @@ -1047,7 +1035,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe, float point_texcoord_bottom = 0;/* R300_GA_POINT_T0: 0x4204 */ float point_texcoord_right = 1; /* R300_GA_POINT_S1: 0x4208 */ float point_texcoord_top = 0; /* R300_GA_POINT_T1: 0x420c */ - boolean vclamp = TRUE; + boolean vclamp = state->clamp_vertex_color || + !r300_context(pipe)->screen->caps.is_r500; CB_LOCALS; /* Copy rasterizer state. */ @@ -1059,6 +1048,10 @@ static void* r300_create_rs_state(struct pipe_context* pipe, /* Override some states for Draw. */ rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */ + rs->rs_draw.offset_point = 0; + rs->rs_draw.offset_line = 0; + rs->rs_draw.offset_tri = 0; + rs->rs_draw.offset_clamp = 0; #ifdef PIPE_ARCH_LITTLE_ENDIAN vap_control_status = R300_VC_NO_SWAP; @@ -1080,14 +1073,16 @@ static void* r300_create_rs_state(struct pipe_context* pipe, if (state->point_size_per_vertex) { /* Per-vertex point size. * Clamp to [0, max FB size] */ - psiz = pipe->screen->get_paramf(pipe->screen, - PIPE_CAP_MAX_POINT_WIDTH); + float min_psiz = util_get_min_point_size(state); + float max_psiz = pipe->screen->get_paramf(pipe->screen, + PIPE_CAPF_MAX_POINT_WIDTH); point_minmax = - pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT; + (pack_float_16_6x(min_psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) | + (pack_float_16_6x(max_psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT); } else { /* We cannot disable the point-size vertex output, * so clamp it. */ - psiz = state->point_size; + float psiz = state->point_size; point_minmax = (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MIN_SHIFT) | (pack_float_16_6x(psiz) << R300_GA_POINT_MINMAX_MAX_SHIFT); @@ -1170,6 +1165,13 @@ static void* r300_create_rs_state(struct pipe_context* pipe, } } + if (r300_screen(pipe->screen)->caps.has_tcl) { + vap_clip_cntl = (state->clip_plane_enable & 63) | + R300_PS_UCP_MODE_CLIP_AS_TRIFAN; + } else { + vap_clip_cntl = R300_CLIP_DISABLE; + } + /* Vertex color clamping. FP20 means no clamping. */ round_mode = R300_GA_ROUND_MODE_GEOMETRY_ROUND_NEAREST | @@ -1179,13 +1181,14 @@ static void* r300_create_rs_state(struct pipe_context* pipe, /* Build the main command buffer. */ BEGIN_CB(rs->cb_main, RS_STATE_MAIN_SIZE); OUT_CB_REG(R300_VAP_CNTL_STATUS, vap_control_status); + OUT_CB_REG(R300_VAP_CLIP_CNTL, vap_clip_cntl); OUT_CB_REG(R300_GA_POINT_SIZE, point_size); OUT_CB_REG_SEQ(R300_GA_POINT_MINMAX, 2); OUT_CB(point_minmax); OUT_CB(line_control); OUT_CB_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2); OUT_CB(polygon_offset_enable); - rs->cull_mode_index = 9; + rs->cull_mode_index = 11; OUT_CB(cull_mode); OUT_CB_REG(R300_GA_LINE_STIPPLE_CONFIG, line_stipple_config); OUT_CB_REG(R300_GA_LINE_STIPPLE_VALUE, line_stipple_value); @@ -1306,7 +1309,7 @@ static void* sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter, state->mag_img_filter, state->min_mip_filter, - state->max_anisotropy > 0); + state->max_anisotropy > 1); sampler->filter0 |= r300_anisotropy(state->max_anisotropy); @@ -1453,10 +1456,12 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe, } } -static struct pipe_sampler_view * -r300_create_sampler_view(struct pipe_context *pipe, +struct pipe_sampler_view * +r300_create_sampler_view_custom(struct pipe_context *pipe, struct pipe_resource *texture, - const struct pipe_sampler_view *templ) + const struct pipe_sampler_view *templ, + unsigned width0_override, + unsigned height0_override) { struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view); struct r300_resource *tex = r300_resource(texture); @@ -1464,22 +1469,37 @@ r300_create_sampler_view(struct pipe_context *pipe, boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle; if (view) { + unsigned hwformat; + view->base = *templ; view->base.reference.count = 1; view->base.context = pipe; view->base.texture = NULL; pipe_resource_reference(&view->base.texture, texture); + view->width0_override = width0_override; + view->height0_override = height0_override; view->swizzle[0] = templ->swizzle_r; view->swizzle[1] = templ->swizzle_g; view->swizzle[2] = templ->swizzle_b; view->swizzle[3] = templ->swizzle_a; - view->format = tex->tx_format; - view->format.format1 |= r300_translate_texformat(templ->format, - view->swizzle, - is_r500, - dxtc_swizzle); + hwformat = r300_translate_texformat(templ->format, + view->swizzle, + is_r500, + dxtc_swizzle); + + if (hwformat == ~0) { + fprintf(stderr, "r300: Ooops. Got unsupported format %s in %s.\n", + util_format_short_name(templ->format), __func__); + } + assert(hwformat != ~0); + + r300_texture_setup_format_state(r300_screen(pipe->screen), tex, + templ->format, 0, + width0_override, height0_override, + &view->format); + view->format.format1 |= hwformat; if (is_r500) { view->format.format2 |= r500_tx_format_msb_bit(templ->format); } @@ -1488,6 +1508,17 @@ r300_create_sampler_view(struct pipe_context *pipe, return (struct pipe_sampler_view*)view; } +static struct pipe_sampler_view * +r300_create_sampler_view(struct pipe_context *pipe, + struct pipe_resource *texture, + const struct pipe_sampler_view *templ) +{ + return r300_create_sampler_view_custom(pipe, texture, templ, + r300_resource(texture)->tex.width0, + r300_resource(texture)->tex.height0); +} + + static void r300_sampler_view_destroy(struct pipe_context *pipe, struct pipe_sampler_view *view) @@ -1551,7 +1582,8 @@ static void r300_set_viewport_state(struct pipe_context* pipe, } r300_mark_atom_dirty(r300, &r300->viewport_state); - if (r300->fs.state && r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) { + if (r300->fs.state && r300_fs(r300)->shader && + r300_fs(r300)->shader->inputs.wpos != ATTR_UNUSED) { r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state); } } @@ -1561,28 +1593,20 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe, const struct pipe_vertex_buffer* buffers) { struct r300_context* r300 = r300_context(pipe); - unsigned i; - struct pipe_vertex_buffer dummy_vb = {0}; /* There must be at least one vertex buffer set, otherwise it locks up. */ if (!count) { - dummy_vb.buffer = r300->dummy_vb; - buffers = &dummy_vb; + buffers = &r300->dummy_vb; count = 1; } - u_vbuf_mgr_set_vertex_buffers(r300->vbuf_mgr, count, buffers); + util_copy_vertex_buffers(r300->vertex_buffer, + &r300->nr_vertex_buffers, + buffers, count); if (r300->screen->caps.has_tcl) { - /* HW TCL. */ - for (i = 0; i < count; i++) { - if (buffers[i].buffer && - !r300_resource(buffers[i].buffer)->b.user_ptr) { - } - } r300->vertex_arrays_dirty = TRUE; } else { - /* SW TCL. */ draw_set_vertex_buffers(r300->draw, count, buffers); } } @@ -1592,16 +1616,11 @@ static void r300_set_index_buffer(struct pipe_context* pipe, { struct r300_context* r300 = r300_context(pipe); - if (ib && ib->buffer) { - assert(ib->offset % ib->index_size == 0); - + if (ib) { pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer); - memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer)); - r300->index_buffer.offset /= r300->index_buffer.index_size; - } - else { + memcpy(&r300->index_buffer, ib, sizeof(*ib)); + } else { pipe_resource_reference(&r300->index_buffer.buffer, NULL); - memset(&r300->index_buffer, 0, sizeof(r300->index_buffer)); } if (!r300->screen->caps.has_tcl) { @@ -1657,7 +1676,6 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, unsigned count, const struct pipe_vertex_element* attribs) { - struct r300_context *r300 = r300_context(pipe); struct r300_vertex_element_state *velems; unsigned i; struct pipe_vertex_element dummy_attrib = {0}; @@ -1678,9 +1696,7 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe, return NULL; velems->count = count; - velems->vmgr_elements = - u_vbuf_mgr_create_vertex_elements(r300->vbuf_mgr, count, attribs, - velems->velem); + memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count); if (r300_screen(pipe->screen)->caps.has_tcl) { /* Setup PSC. @@ -1709,8 +1725,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, r300->velems = velems; - u_vbuf_mgr_bind_vertex_elements(r300->vbuf_mgr, state, velems->vmgr_elements); - if (r300->draw) { draw_set_vertex_elements(r300->draw, velems->count, velems->velem); return; @@ -1723,10 +1737,6 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe, static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state) { - struct r300_context *r300 = r300_context(pipe); - struct r300_vertex_element_state *velems = state; - - u_vbuf_mgr_destroy_vertex_elements(r300->vbuf_mgr, velems->vmgr_elements); FREE(state); } @@ -1741,10 +1751,10 @@ static void* r300_create_vs_state(struct pipe_context* pipe, vs->state.tokens = tgsi_dup_tokens(shader->tokens); if (r300->screen->caps.has_tcl) { - r300_init_vs_outputs(vs); + r300_init_vs_outputs(r300, vs); r300_translate_vertex_shader(r300, vs); } else { - r300_draw_init_vertex_shader(r300->draw, vs); + r300_draw_init_vertex_shader(r300, vs); } return vs; @@ -1770,9 +1780,8 @@ static void r300_bind_vs_state(struct pipe_context* pipe, void* shader) if (r300->screen->caps.has_tcl) { unsigned fc_op_dwords = r300->screen->caps.is_r500 ? 3 : 2; r300_mark_atom_dirty(r300, &r300->vs_state); - r300->vs_state.size = - vs->code.length + 9 + - (vs->code.num_fc_ops ? vs->code.num_fc_ops * fc_op_dwords + 4 : 0); + r300->vs_state.size = vs->code.length + 9 + + (R300_VS_MAX_FC_OPS * fc_op_dwords + 4); r300_mark_atom_dirty(r300, &r300->vs_constants); r300->vs_constants.size = @@ -1810,9 +1819,10 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader) static void r300_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, - struct pipe_resource *buf) + struct pipe_constant_buffer *cb) { struct r300_context* r300 = r300_context(pipe); + struct pipe_resource *buf = cb ? cb->buffer : NULL; struct r300_constant_buffer *cbuf; struct r300_resource *rbuf = r300_resource(buf); uint32_t *mapped; @@ -1831,8 +1841,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, if (buf == NULL || buf->width0 == 0) return; - if (rbuf->b.user_ptr) - mapped = (uint32_t*)rbuf->b.user_ptr; + if (rbuf->b.b.user_ptr) + mapped = (uint32_t*)rbuf->b.b.user_ptr; else if (rbuf->constant_buffer) mapped = (uint32_t*)rbuf->constant_buffer; else