(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);
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. */
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);
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);
"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,
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, RADEON_VID_CAN_HYPERZ);
r300_mark_atom_dirty(r300, &r300->gpu_flush);
r300_mark_atom_dirty(r300, &r300->fb_state);
/* 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. */
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;
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)) {
}
} 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)) {
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->hyperz_locked || !r300->zmask_in_use);
+ 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);
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;
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 */
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 = state->clamp_vertex_color;
+ boolean vclamp = state->clamp_vertex_color ||
+ !r300_context(pipe)->screen->caps.is_r500;
CB_LOCALS;
/* Copy rasterizer state. */
/* 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;
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);
}
}
+ 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 |
/* 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);
struct r300_rs_state* rs = (struct r300_rs_state*)state;
int last_sprite_coord_enable = r300->sprite_coord_enable;
boolean last_two_sided_color = r300->two_sided_color;
- boolean last_frag_clamp = r300->frag_clamp;
if (r300->draw && rs) {
draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);
r300->polygon_offset_enabled = rs->polygon_offset_enable;
r300->sprite_coord_enable = rs->rs.sprite_coord_enable;
r300->two_sided_color = rs->rs.light_twoside;
- r300->frag_clamp = rs->rs.clamp_fragment_color;
} else {
r300->polygon_offset_enabled = FALSE;
r300->sprite_coord_enable = 0;
r300->two_sided_color = FALSE;
- r300->frag_clamp = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
last_two_sided_color != r300->two_sided_color) {
r300_mark_atom_dirty(r300, &r300->rs_block_state);
}
-
- if (last_frag_clamp != r300->frag_clamp &&
- r300->fs_status == FRAGMENT_SHADER_VALID) {
- r300->fs_status = FRAGMENT_SHADER_MAYBE_DIRTY;
- }
}
/* Free rasterizer state. */
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);
}
}
-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);
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);
}
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)
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);
}
}
{
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) {
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};
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.
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;
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);
}
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;
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 =
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