#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_inlines.h"
-#include "util/u_simple_list.h"
-#include "util/u_format.h"
+#include "util/simple_list.h"
+#include "util/format/u_format.h"
#include "lp_scene.h"
#include "lp_fence.h"
#include "lp_debug.h"
scene->data.head =
CALLOC_STRUCT(data_block);
- pipe_mutex_init(scene->mutex);
+ (void) mtx_init(&scene->mutex, mtx_plain);
#ifdef DEBUG
/* Do some scene limit sanity checks here */
lp_scene_destroy(struct lp_scene *scene)
{
lp_fence_reference(&scene->fence, NULL);
- pipe_mutex_destroy(scene->mutex);
+ mtx_destroy(&scene->mutex);
assert(scene->data.head->next == NULL);
FREE(scene->data.head);
FREE(scene);
{
unsigned x, y;
- for (y = 0; y < TILES_Y; y++) {
- for (x = 0; x < TILES_X; x++) {
+ for (y = 0; y < scene->tiles_y; y++) {
+ for (x = 0; x < scene->tiles_x; x++) {
const struct cmd_bin *bin = lp_scene_get_bin(scene, x, y);
if (bin->head) {
return FALSE;
for (i = 0; i < scene->fb.nr_cbufs; i++) {
struct pipe_surface *cbuf = scene->fb.cbufs[i];
+
+ if (!cbuf) {
+ scene->cbufs[i].stride = 0;
+ scene->cbufs[i].layer_stride = 0;
+ scene->cbufs[i].sample_stride = 0;
+ scene->cbufs[i].nr_samples = 0;
+ scene->cbufs[i].map = NULL;
+ continue;
+ }
+
if (llvmpipe_resource_is_texture(cbuf->texture)) {
scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
cbuf->u.tex.level);
+ scene->cbufs[i].layer_stride = llvmpipe_layer_stride(cbuf->texture,
+ cbuf->u.tex.level);
+ scene->cbufs[i].sample_stride = llvmpipe_sample_stride(cbuf->texture);
scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
cbuf->u.tex.level,
cbuf->u.tex.first_layer,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_LINEAR);
+ LP_TEX_USAGE_READ_WRITE);
+ scene->cbufs[i].format_bytes = util_format_get_blocksize(cbuf->format);
+ scene->cbufs[i].nr_samples = util_res_sample_count(cbuf->texture);
}
else {
struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture);
unsigned pixstride = util_format_get_blocksize(cbuf->format);
scene->cbufs[i].stride = cbuf->texture->width0;
+ scene->cbufs[i].layer_stride = 0;
+ scene->cbufs[i].sample_stride = 0;
+ scene->cbufs[i].nr_samples = 1;
scene->cbufs[i].map = lpr->data;
scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride;
+ scene->cbufs[i].format_bytes = util_format_get_blocksize(cbuf->format);
}
}
if (fb->zsbuf) {
struct pipe_surface *zsbuf = scene->fb.zsbuf;
scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level);
- scene->zsbuf.blocksize =
- util_format_get_blocksize(zsbuf->texture->format);
-
+ scene->zsbuf.layer_stride = llvmpipe_layer_stride(zsbuf->texture, zsbuf->u.tex.level);
+ scene->zsbuf.sample_stride = llvmpipe_sample_stride(zsbuf->texture);
+ scene->zsbuf.nr_samples = util_res_sample_count(zsbuf->texture);
scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
zsbuf->u.tex.level,
zsbuf->u.tex.first_layer,
- LP_TEX_USAGE_READ_WRITE,
- LP_TEX_LAYOUT_LINEAR);
+ LP_TEX_USAGE_READ_WRITE);
+ scene->zsbuf.format_bytes = util_format_get_blocksize(zsbuf->format);
}
}
scene->scene_size = 0;
scene->resource_reference_size = 0;
- scene->has_depthstencil_clear = FALSE;
scene->alloc_failed = FALSE;
util_unreference_framebuffer_state( &scene->fb );
}
else {
struct data_block *block = MALLOC_STRUCT(data_block);
- if (block == NULL)
+ if (!block)
return NULL;
scene->scene_size += sizeof *block;
* of work (a bin) to work on.
*/
struct cmd_bin *
-lp_scene_bin_iter_next( struct lp_scene *scene )
+lp_scene_bin_iter_next( struct lp_scene *scene , int *x, int *y)
{
struct cmd_bin *bin = NULL;
- pipe_mutex_lock(scene->mutex);
+ mtx_lock(&scene->mutex);
if (scene->curr_x < 0) {
/* first bin */
}
bin = lp_scene_get_bin(scene, scene->curr_x, scene->curr_y);
+ *x = scene->curr_x;
+ *y = scene->curr_y;
end:
/*printf("return bin %p at %d, %d\n", (void *) bin, *bin_x, *bin_y);*/
- pipe_mutex_unlock(scene->mutex);
+ mtx_unlock(&scene->mutex);
return bin;
}
-void lp_scene_begin_binning( struct lp_scene *scene,
- struct pipe_framebuffer_state *fb, boolean discard )
+void lp_scene_begin_binning(struct lp_scene *scene,
+ struct pipe_framebuffer_state *fb)
{
+ int i;
+ unsigned max_layer = ~0;
+
assert(lp_scene_is_empty(scene));
- scene->discard = discard;
util_copy_framebuffer_state(&scene->fb, fb);
scene->tiles_x = align(fb->width, TILE_SIZE) / TILE_SIZE;
scene->tiles_y = align(fb->height, TILE_SIZE) / TILE_SIZE;
-
assert(scene->tiles_x <= TILES_X);
assert(scene->tiles_y <= TILES_Y);
+
+ /*
+ * Determine how many layers the fb has (used for clamping layer value).
+ * OpenGL (but not d3d10) permits different amount of layers per rt, however
+ * results are undefined if layer exceeds the amount of layers of ANY
+ * attachment hence don't need separate per cbuf and zsbuf max.
+ */
+ for (i = 0; i < scene->fb.nr_cbufs; i++) {
+ struct pipe_surface *cbuf = scene->fb.cbufs[i];
+ if (cbuf) {
+ if (llvmpipe_resource_is_texture(cbuf->texture)) {
+ max_layer = MIN2(max_layer,
+ cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);
+ }
+ else {
+ max_layer = 0;
+ }
+ }
+ }
+ if (fb->zsbuf) {
+ struct pipe_surface *zsbuf = scene->fb.zsbuf;
+ max_layer = MIN2(max_layer, zsbuf->u.tex.last_layer - zsbuf->u.tex.first_layer);
+ }
+ scene->fb_max_layer = max_layer;
+ scene->fb_max_samples = util_framebuffer_get_num_samples(fb);
+ if (scene->fb_max_samples == 4) {
+ for (unsigned i = 0; i < 4; i++) {
+ scene->fixed_sample_pos[i][0] = util_iround(lp_sample_pos_4x[i][0] * FIXED_ONE);
+ scene->fixed_sample_pos[i][1] = util_iround(lp_sample_pos_4x[i][1] * FIXED_ONE);
+ }
+ }
}