summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/r300/r300_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_state.c')
-rw-r--r--src/gallium/drivers/r300/r300_state.c306
1 files changed, 95 insertions, 211 deletions
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 3a97b76a4c8..09f18b3e624 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -28,6 +28,7 @@
#include "util/u_mm.h"
#include "util/u_memory.h"
#include "util/u_pack_color.h"
+#include "util/u_transfer.h"
#include "tgsi/tgsi_parse.h"
@@ -442,8 +443,7 @@ static void r300_set_clip_state(struct pipe_context* pipe,
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 |
- (state->depth_clamp ? R300_CLIP_DISABLE : 0));
+ R300_PS_UCP_MODE_CLIP_AS_TRIFAN);
END_CB;
r300_mark_atom_dirty(r300, &r300->clip_state);
@@ -617,21 +617,16 @@ static void r300_set_stencil_ref(struct pipe_context* pipe,
}
static void r300_tex_set_tiling_flags(struct r300_context *r300,
- struct r300_texture *tex, unsigned level)
+ struct r300_resource *tex,
+ unsigned level)
{
/* Check if the macrotile flag needs to be changed.
* Skip changing the flags otherwise. */
- if (tex->desc.macrotile[tex->surface_level] !=
- tex->desc.macrotile[level]) {
- /* Tiling determines how DRM treats the buffer data.
- * We must flush CS when changing it if the buffer is referenced. */
- if (r300->rws->cs_is_buffer_referenced(r300->cs,
- tex->cs_buffer, R300_REF_CS))
- r300->context.flush(&r300->context, 0, NULL);
-
- r300->rws->buffer_set_tiling(r300->rws, tex->buffer,
- tex->desc.microtile, tex->desc.macrotile[level],
- tex->desc.stride_in_bytes[0]);
+ if (tex->tex.macrotile[tex->surface_level] !=
+ tex->tex.macrotile[level]) {
+ r300->rws->buffer_set_tiling(tex->buf, r300->cs,
+ tex->tex.microtile, tex->tex.macrotile[level],
+ tex->tex.stride_in_bytes[0]);
tex->surface_level = level;
}
@@ -646,12 +641,12 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300,
/* Set tiling flags for new surfaces. */
for (i = 0; i < state->nr_cbufs; i++) {
r300_tex_set_tiling_flags(r300,
- r300_texture(state->cbufs[i]->texture),
+ r300_resource(state->cbufs[i]->texture),
state->cbufs[i]->u.tex.level);
}
if (state->zsbuf) {
r300_tex_set_tiling_flags(r300,
- r300_texture(state->zsbuf->texture),
+ r300_resource(state->zsbuf->texture),
state->zsbuf->u.tex.level);
}
}
@@ -660,7 +655,7 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
const char *binding)
{
struct pipe_resource *tex = surf->texture;
- struct r300_texture *rtex = r300_texture(tex);
+ struct r300_resource *rtex = r300_resource(tex);
fprintf(stderr,
"r300: %s[%i] Dim: %ix%i, Firstlayer: %i, "
@@ -673,9 +668,9 @@ static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
surf->u.tex.first_layer, surf->u.tex.last_layer, surf->u.tex.level,
util_format_short_name(surf->format),
- rtex->desc.macrotile[0] ? "YES" : " NO",
- rtex->desc.microtile ? "YES" : " NO",
- rtex->desc.stride_in_pixels[0],
+ 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));
}
@@ -695,8 +690,7 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
}
if (change == R300_CHANGED_FB_STATE ||
- change == R300_CHANGED_CBZB_FLAG ||
- change == R300_CHANGED_ZCLEAR_FLAG) {
+ change == R300_CHANGED_HYPERZ_FLAG) {
r300_mark_atom_dirty(r300, &r300->hyperz_state);
}
@@ -720,8 +714,8 @@ void r300_mark_fb_state_dirty(struct r300_context *r300,
}
static void
- r300_set_framebuffer_state(struct pipe_context* pipe,
- const struct pipe_framebuffer_state* state)
+r300_set_framebuffer_state(struct pipe_context* pipe,
+ const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
struct r300_aa_state *aa = (struct r300_aa_state*)r300->aa_state.state;
@@ -729,7 +723,6 @@ static void
boolean can_hyperz = r300->rws->get_value(r300->rws, R300_CAN_HYPERZ);
unsigned max_width, max_height, i;
uint32_t zbuffer_bpp = 0;
- int blocksize;
if (r300->screen->caps.is_r500) {
max_width = max_height = 4096;
@@ -745,6 +738,32 @@ static void
return;
}
+ if (old_state->zsbuf && r300->zmask_in_use && !r300->zmask_locked) {
+ /* There is a zmask in use, what are we gonna do? */
+ if (state->zsbuf) {
+ if (!pipe_surface_equal(old_state->zsbuf, state->zsbuf)) {
+ /* Decompress the currently bound zbuffer before we bind another one. */
+ r300_decompress_zmask(r300);
+ }
+ } else {
+ /* We don't bind another zbuffer, so lock the current one. */
+ r300->zmask_locked = TRUE;
+ pipe_surface_reference(&r300->locked_zbuffer, old_state->zsbuf);
+ }
+ } else if (r300->zmask_locked && 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)) {
+ /* We are binding some other zbuffer, so decompress the locked one,
+ * it gets unlocked automatically. */
+ r300_decompress_zmask_locked_unsafe(r300);
+ } else {
+ /* We are binding the locked zbuffer again, so unlock it. */
+ r300->zmask_locked = FALSE;
+ }
+ }
+ }
+
/* If nr_cbufs is changed from zero to non-zero or vice versa... */
if (!!old_state->nr_cbufs != !!state->nr_cbufs) {
r300_mark_atom_dirty(r300, &r300->blend_state);
@@ -759,14 +778,14 @@ static void
util_copy_framebuffer_state(r300->fb_state.state, state);
+ if (!r300->zmask_locked) {
+ pipe_surface_reference(&r300->locked_zbuffer, NULL);
+ }
+
r300_mark_fb_state_dirty(r300, R300_CHANGED_FB_STATE);
- r300->validate_buffers = TRUE;
- r300->z_compression = false;
-
if (state->zsbuf) {
- blocksize = util_format_get_blocksize(state->zsbuf->texture->format);
- switch (blocksize) {
+ switch (util_format_get_blocksize(state->zsbuf->texture->format)) {
case 2:
zbuffer_bpp = 16;
break;
@@ -774,30 +793,19 @@ static void
zbuffer_bpp = 24;
break;
}
+
+ /* Setup Hyper-Z. */
if (can_hyperz) {
struct r300_surface *zs_surf = r300_surface(state->zsbuf);
- struct r300_texture *tex;
- int compress = r300->screen->caps.is_rv350 ? RV350_Z_COMPRESS_88 : R300_Z_COMPRESS_44;
+ struct r300_resource *tex = r300_resource(zs_surf->base.texture);
int level = zs_surf->base.u.tex.level;
- tex = r300_texture(zs_surf->base.texture);
-
/* work out whether we can support hiz on this buffer */
r300_hiz_alloc_block(r300, zs_surf);
-
- /* work out whether we can support zmask features on this buffer */
- r300_zmask_alloc_block(r300, zs_surf, compress);
-
- if (tex->zmask_mem[level]) {
- /* compression causes hangs on 16-bit */
- if (zbuffer_bpp == 24)
- r300->z_compression = compress;
- }
+
DBG(r300, DBG_HYPERZ,
- "hyper-z features: hiz: %d @ %08x z-compression: %d z-fastfill: %d @ %08x\n", tex->hiz_mem[level] ? 1 : 0,
- tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef,
- r300->z_compression, tex->zmask_mem[level] ? 1 : 0,
- tex->zmask_mem[level] ? tex->zmask_mem[level]->ofs : 0xdeadbeef);
+ "hyper-z features: hiz: %d @ %08x\n", tex->hiz_mem[level] ? 1 : 0,
+ tex->hiz_mem[level] ? tex->hiz_mem[level]->ofs : 0xdeadbeef);
}
/* Polygon offset depends on the zbuffer bit depth. */
@@ -1300,7 +1308,7 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct r300_textures_state* state =
(struct r300_textures_state*)r300->textures_state.state;
- struct r300_texture *texture;
+ struct r300_resource *texture;
unsigned i, real_num_views = 0, view_index = 0;
unsigned tex_units = r300->screen->caps.num_tex_units;
boolean dirty_tex = FALSE;
@@ -1329,8 +1337,8 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
/* Set the texrect factor in the fragment shader.
* Needed for RECT and NPOT fallback. */
- texture = r300_texture(views[i]->texture);
- if (texture->desc.is_npot) {
+ texture = r300_resource(views[i]->texture);
+ if (texture->tex.is_npot) {
r300_mark_atom_dirty(r300, &r300->fs_rc_constant_state);
}
@@ -1350,7 +1358,6 @@ static void r300_set_fragment_sampler_views(struct pipe_context* pipe,
state->sampler_view_count = count;
r300_mark_atom_dirty(r300, &r300->textures_state);
- r300->validate_buffers = TRUE;
if (dirty_tex) {
r300_mark_atom_dirty(r300, &r300->texture_cache_inval);
@@ -1363,7 +1370,7 @@ r300_create_sampler_view(struct pipe_context *pipe,
const struct pipe_sampler_view *templ)
{
struct r300_sampler_view *view = CALLOC_STRUCT(r300_sampler_view);
- struct r300_texture *tex = r300_texture(texture);
+ struct r300_resource *tex = r300_resource(texture);
boolean is_r500 = r300_screen(pipe->screen)->caps.is_r500;
boolean dxtc_swizzle = r300_screen(pipe->screen)->caps.dxtc_swizzle;
@@ -1465,10 +1472,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
const struct pipe_vertex_buffer* buffers)
{
struct r300_context* r300 = r300_context(pipe);
- const struct pipe_vertex_buffer *vbo;
- unsigned i, max_index = (1 << 24) - 1;
- boolean any_user_buffer = FALSE;
- boolean any_nonuser_buffer = FALSE;
+ unsigned i;
struct pipe_vertex_buffer dummy_vb = {0};
/* There must be at least one vertex buffer set, otherwise it locks up. */
@@ -1478,90 +1482,20 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
count = 1;
}
- if (count == r300->vertex_buffer_count &&
- memcmp(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count) == 0) {
- return;
- }
+ u_vbuf_mgr_set_vertex_buffers(r300->vbuf_mgr, count, buffers);
if (r300->screen->caps.has_tcl) {
/* HW TCL. */
- r300->incompatible_vb_layout = FALSE;
-
- /* Check if the strides and offsets are aligned to the size of DWORD. */
- for (i = 0; i < count; i++) {
- if (buffers[i].buffer) {
- if (buffers[i].stride % 4 != 0 ||
- buffers[i].buffer_offset % 4 != 0) {
- r300->incompatible_vb_layout = TRUE;
- break;
- }
- }
- }
-
for (i = 0; i < count; i++) {
- vbo = &buffers[i];
-
- /* Skip NULL buffers */
- if (!vbo->buffer) {
- continue;
- }
-
- /* User buffers have no info about maximum index,
- * we will have to compute it in draw_vbo. */
- if (r300_is_user_buffer(vbo->buffer)) {
- any_user_buffer = TRUE;
- continue;
- }
- any_nonuser_buffer = TRUE;
-
- /* The stride of zero means we will be fetching only the first
- * vertex, so don't care about max_index. */
- if (!vbo->stride)
- continue;
-
- /* Update the maximum index. */
- {
- unsigned vbo_max_index =
- (vbo->buffer->width0 - vbo->buffer_offset) / vbo->stride;
- max_index = MIN2(max_index, vbo_max_index);
+ if (buffers[i].buffer &&
+ !r300_resource(buffers[i].buffer)->b.user_ptr) {
}
}
-
- r300->any_user_vbs = any_user_buffer;
- r300->vertex_buffer_max_index = max_index;
r300->vertex_arrays_dirty = TRUE;
- if (any_nonuser_buffer)
- r300->validate_buffers = TRUE;
- if (!any_user_buffer)
- r300->upload_vb_validated = FALSE;
} else {
/* SW TCL. */
draw_set_vertex_buffers(r300->draw, count, buffers);
}
-
- /* Common code. */
- for (i = 0; i < count; i++) {
- vbo = &buffers[i];
-
- /* Reference our buffer. */
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, vbo->buffer);
- if (vbo->buffer && r300_is_user_buffer(vbo->buffer)) {
- pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL);
- } else {
- pipe_resource_reference(&r300->valid_vertex_buffer[i], vbo->buffer);
- }
- }
- for (; i < r300->vertex_buffer_count; i++) {
- /* Dereference any old buffers. */
- pipe_resource_reference(&r300->vertex_buffer[i].buffer, NULL);
- pipe_resource_reference(&r300->valid_vertex_buffer[i], NULL);
- }
-
- memcpy(r300->vertex_buffer, buffers,
- sizeof(struct pipe_vertex_buffer) * count);
-
- r300->vertex_buffer_count = count;
}
static void r300_set_index_buffer(struct pipe_context* pipe,
@@ -1570,14 +1504,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);
+
pipe_resource_reference(&r300->index_buffer.buffer, ib->buffer);
memcpy(&r300->index_buffer, ib, sizeof(r300->index_buffer));
-
- if (r300->screen->caps.has_tcl &&
- !r300_is_user_buffer(ib->buffer)) {
- r300->validate_buffers = TRUE;
- r300->upload_ib_validated = FALSE;
- }
+ r300->index_buffer.offset /= r300->index_buffer.index_size;
}
else {
pipe_resource_reference(&r300->index_buffer.buffer, NULL);
@@ -1607,7 +1538,7 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
* so PSC should just route stuff based on the vertex elements,
* and not on attrib information. */
for (i = 0; i < velems->count; i++) {
- format = velems->hw_format[i];
+ format = velems->velem[i].src_format;
type = r300_translate_vertex_data_type(format);
if (type == R300_INVALID_FORMAT) {
@@ -1639,16 +1570,13 @@ static void r300_vertex_psc(struct r300_vertex_element_state *velems)
vstream->count = (i >> 1) + 1;
}
-#define FORMAT_REPLACE(what, withwhat) \
- case PIPE_FORMAT_##what: *format = PIPE_FORMAT_##withwhat; break
-
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;
- enum pipe_format *format;
struct pipe_vertex_element dummy_attrib = {0};
/* R300 Programmable Stream Control (PSC) doesn't support 0 vertex elements. */
@@ -1660,77 +1588,26 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
assert(count <= PIPE_MAX_ATTRIBS);
velems = CALLOC_STRUCT(r300_vertex_element_state);
- if (velems != NULL) {
- velems->count = count;
- memcpy(velems->velem, attribs, sizeof(struct pipe_vertex_element) * count);
-
- if (r300_screen(pipe->screen)->caps.has_tcl) {
- /* Set the best hw format in case the original format is not
- * supported by hw. */
- for (i = 0; i < count; i++) {
- velems->hw_format[i] = velems->velem[i].src_format;
- format = &velems->hw_format[i];
-
- /* This is basically the list of unsupported formats.
- * For now we don't care about the alignment, that's going to
- * be sorted out after the PSC setup. */
- switch (*format) {
- FORMAT_REPLACE(R64_FLOAT, R32_FLOAT);
- FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT);
- FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT);
- FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_UNORM, R32_FLOAT);
- FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_USCALED, R32_FLOAT);
- FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_SNORM, R32_FLOAT);
- FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_SSCALED, R32_FLOAT);
- FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
-
- FORMAT_REPLACE(R32_FIXED, R32_FLOAT);
- FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT);
- FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT);
- FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT);
-
- default:;
- }
+ if (!velems)
+ return NULL;
- velems->incompatible_layout =
- velems->incompatible_layout ||
- velems->velem[i].src_format != velems->hw_format[i] ||
- velems->velem[i].src_offset % 4 != 0;
- }
+ velems->count = count;
+ velems->vmgr_elements =
+ u_vbuf_mgr_create_vertex_elements(r300->vbuf_mgr, count, attribs,
+ velems->velem);
- /* Now setup PSC.
- * The unused components will be replaced by (..., 0, 1). */
- r300_vertex_psc(velems);
-
- /* Align the formats to the size of DWORD.
- * We only care about the blocksizes of the formats since
- * swizzles are already set up.
- * Also compute the vertex size. */
- for (i = 0; i < count; i++) {
- /* This is OK because we check for aligned strides too
- * elsewhere. */
- velems->hw_format_size[i] =
- align(util_format_get_blocksize(velems->hw_format[i]), 4);
- velems->vertex_size_dwords += velems->hw_format_size[i] / 4;
- }
+ if (r300_screen(pipe->screen)->caps.has_tcl) {
+ /* Setup PSC.
+ * The unused components will be replaced by (..., 0, 1). */
+ r300_vertex_psc(velems);
+
+ for (i = 0; i < count; i++) {
+ velems->format_size[i] =
+ align(util_format_get_blocksize(velems->velem[i].src_format), 4);
+ velems->vertex_size_dwords += velems->format_size[i] / 4;
}
}
+
return velems;
}
@@ -1746,6 +1623,8 @@ 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;
@@ -1758,7 +1637,11 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
static void r300_delete_vertex_elements_state(struct pipe_context *pipe, void *state)
{
- FREE(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);
}
static void* r300_create_vs_state(struct pipe_context* pipe,
@@ -1845,7 +1728,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
{
struct r300_context* r300 = r300_context(pipe);
struct r300_constant_buffer *cbuf;
- struct r300_buffer *rbuf = r300_buffer(buf);
+ struct r300_resource *rbuf = r300_resource(buf);
uint32_t *mapped;
switch (shader) {
@@ -1862,8 +1745,8 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
if (buf == NULL || buf->width0 == 0)
return;
- if (rbuf->user_buffer)
- mapped = (uint32_t*)rbuf->user_buffer;
+ if (rbuf->b.user_ptr)
+ mapped = (uint32_t*)rbuf->b.user_ptr;
else if (rbuf->constant_buffer)
mapped = (uint32_t*)rbuf->constant_buffer;
else
@@ -1947,6 +1830,7 @@ void r300_init_state_functions(struct r300_context* r300)
r300->context.set_vertex_buffers = r300_set_vertex_buffers;
r300->context.set_index_buffer = r300_set_index_buffer;
+ r300->context.redefine_user_buffer = u_default_redefine_user_buffer;
r300->context.create_vertex_elements_state = r300_create_vertex_elements_state;
r300->context.bind_vertex_elements_state = r300_bind_vertex_elements_state;