Mostly just make sure the layer parameter gets passed through to the right
places (and get clamped, can do this at setup time), fix up clears to
clear all layers and disable opaque optimization. Luckily don't need to
touch the jitted code.
(Clears invoked via pipe's clear_render_target method will not work however
since the pipe_util_clear function used for it doesn't handle clearing
multiple layers yet.)
v2: per Brian's suggestion, prettify var initialization and add some comments,
add assertion for impossible layer specification for surface.
Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
15 files changed:
/** Which vertex shader output slot contains viewport index */
int viewport_index_slot;
/** Which vertex shader output slot contains viewport index */
int viewport_index_slot;
+ /** Which geometry shader output slot contains layer */
+ int layer_slot;
+
/**< minimum resolvable depth value, for polygon offset */
double mrd;
/**< minimum resolvable depth value, for polygon offset */
double mrd;
const void *dadx,
const void *dady,
uint8_t **color,
const void *dadx,
const void *dady,
uint8_t **color,
uint32_t mask,
struct lp_jit_thread_data *thread_data,
unsigned *stride,
uint32_t mask,
struct lp_jit_thread_data *thread_data,
unsigned *stride,
/**
* Clear the rasterizer's current color tile.
* This is a bin command called during bin processing.
/**
* Clear the rasterizer's current color tile.
* This is a bin command called during bin processing.
+ * Clear commands always clear all bound layers.
*/
static void
lp_rast_clear_color(struct lp_rasterizer_task *task,
*/
static void
lp_rast_clear_color(struct lp_rasterizer_task *task,
for (i = 0; i < scene->fb.nr_cbufs; i++) {
enum pipe_format format = scene->fb.cbufs[i]->format;
for (i = 0; i < scene->fb.nr_cbufs; i++) {
enum pipe_format format = scene->fb.cbufs[i]->format;
+ unsigned layer;
+ uint8_t *map_layer = scene->cbufs[i].map;
if (util_format_is_pure_sint(format)) {
util_format_write_4i(format, arg.clear_color.i, 0, &uc, 0, 0, 0, 1, 1);
if (util_format_is_pure_sint(format)) {
util_format_write_4i(format, arg.clear_color.i, 0, &uc, 0, 0, 0, 1, 1);
util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, 0, 0, 0, 1, 1);
}
util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, 0, 0, 0, 1, 1);
}
- util_fill_rect(scene->cbufs[i].map,
- scene->fb.cbufs[i]->format,
- scene->cbufs[i].stride,
- task->x,
- task->y,
- task->width,
- task->height,
- &uc);
+ for (layer = 0; layer <= scene->fb_max_layer; layer++) {
+ util_fill_rect(map_layer,
+ scene->fb.cbufs[i]->format,
+ scene->cbufs[i].stride,
+ task->x,
+ task->y,
+ task->width,
+ task->height,
+ &uc);
+ map_layer += scene->cbufs[i].layer_stride;
+ }
clear_color[3]);
for (i = 0; i < scene->fb.nr_cbufs; i++) {
clear_color[3]);
for (i = 0; i < scene->fb.nr_cbufs; i++) {
-
- util_pack_color(arg.clear_color.f,
- scene->fb.cbufs[i]->format, &uc);
-
- util_fill_rect(scene->cbufs[i].map,
- scene->fb.cbufs[i]->format,
- scene->cbufs[i].stride,
- task->x,
- task->y,
- task->width,
- task->height,
- &uc);
+ unsigned layer;
+ uint8_t *map_layer = scene->cbufs[i].map;
+
+ for (layer = 0; layer <= scene->fb_max_layer; layer++) {
+ util_pack_color(arg.clear_color.f,
+ scene->fb.cbufs[i]->format, &uc);
+ util_fill_rect(map_layer,
+ scene->fb.cbufs[i]->format,
+ scene->cbufs[i].stride,
+ task->x,
+ task->y,
+ task->width,
+ task->height,
+ &uc);
+ map_layer += scene->cbufs[i].layer_stride;
+ }
/**
* Clear the rasterizer's current z/stencil tile.
* This is a bin command called during bin processing.
/**
* Clear the rasterizer's current z/stencil tile.
* This is a bin command called during bin processing.
+ * Clear commands always clear all bound layers.
*/
static void
lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
*/
static void
lp_rast_clear_zstencil(struct lp_rasterizer_task *task,
uint32_t clear_mask = (uint32_t) clear_mask64;
const unsigned height = task->height;
const unsigned width = task->width;
uint32_t clear_mask = (uint32_t) clear_mask64;
const unsigned height = task->height;
const unsigned width = task->width;
- const unsigned block_size = scene->zsbuf.blocksize;
const unsigned dst_stride = scene->zsbuf.stride;
uint8_t *dst;
unsigned i, j;
const unsigned dst_stride = scene->zsbuf.stride;
uint8_t *dst;
unsigned i, j;
LP_DBG(DEBUG_RAST, "%s: value=0x%08x, mask=0x%08x\n",
__FUNCTION__, clear_value, clear_mask);
LP_DBG(DEBUG_RAST, "%s: value=0x%08x, mask=0x%08x\n",
__FUNCTION__, clear_value, clear_mask);
*/
if (scene->fb.zsbuf) {
*/
if (scene->fb.zsbuf) {
-
- dst = lp_rast_get_unswizzled_depth_tile_pointer(task, LP_TEX_USAGE_READ_WRITE);
+ unsigned layer;
+ uint8_t *dst_layer = lp_rast_get_unswizzled_depth_tile_pointer(task, LP_TEX_USAGE_READ_WRITE);
+ block_size = util_format_get_blocksize(scene->fb.zsbuf->format);
clear_value &= clear_mask;
clear_value &= clear_mask;
- switch (block_size) {
- case 1:
- assert(clear_mask == 0xff);
- memset(dst, (uint8_t) clear_value, height * width);
- break;
- case 2:
- if (clear_mask == 0xffff) {
- for (i = 0; i < height; i++) {
- uint16_t *row = (uint16_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = (uint16_t) clear_value;
- dst += dst_stride;
+ for (layer = 0; layer <= scene->fb_max_layer; layer++) {
+ dst = dst_layer;
+
+ switch (block_size) {
+ case 1:
+ assert(clear_mask == 0xff);
+ memset(dst, (uint8_t) clear_value, height * width);
+ break;
+ case 2:
+ if (clear_mask == 0xffff) {
+ for (i = 0; i < height; i++) {
+ uint16_t *row = (uint16_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = (uint16_t) clear_value;
+ dst += dst_stride;
+ }
- }
- else {
- for (i = 0; i < height; i++) {
- uint16_t *row = (uint16_t *)dst;
- for (j = 0; j < width; j++) {
- uint16_t tmp = ~clear_mask & *row;
- *row++ = clear_value | tmp;
+ else {
+ for (i = 0; i < height; i++) {
+ uint16_t *row = (uint16_t *)dst;
+ for (j = 0; j < width; j++) {
+ uint16_t tmp = ~clear_mask & *row;
+ *row++ = clear_value | tmp;
+ }
+ dst += dst_stride;
- }
- break;
- case 4:
- if (clear_mask == 0xffffffff) {
- for (i = 0; i < height; i++) {
- uint32_t *row = (uint32_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = clear_value;
- dst += dst_stride;
+ break;
+ case 4:
+ if (clear_mask == 0xffffffff) {
+ for (i = 0; i < height; i++) {
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = clear_value;
+ dst += dst_stride;
+ }
- }
- else {
- for (i = 0; i < height; i++) {
- uint32_t *row = (uint32_t *)dst;
- for (j = 0; j < width; j++) {
- uint32_t tmp = ~clear_mask & *row;
- *row++ = clear_value | tmp;
+ else {
+ for (i = 0; i < height; i++) {
+ uint32_t *row = (uint32_t *)dst;
+ for (j = 0; j < width; j++) {
+ uint32_t tmp = ~clear_mask & *row;
+ *row++ = clear_value | tmp;
+ }
+ dst += dst_stride;
- }
- break;
- case 8:
- clear_value64 &= clear_mask64;
- if (clear_mask64 == 0xffffffffffULL) {
- for (i = 0; i < height; i++) {
- uint64_t *row = (uint64_t *)dst;
- for (j = 0; j < width; j++)
- *row++ = clear_value64;
- dst += dst_stride;
+ break;
+ case 8:
+ clear_value64 &= clear_mask64;
+ if (clear_mask64 == 0xffffffffffULL) {
+ for (i = 0; i < height; i++) {
+ uint64_t *row = (uint64_t *)dst;
+ for (j = 0; j < width; j++)
+ *row++ = clear_value64;
+ dst += dst_stride;
+ }
- }
- else {
- for (i = 0; i < height; i++) {
- uint64_t *row = (uint64_t *)dst;
- for (j = 0; j < width; j++) {
- uint64_t tmp = ~clear_mask64 & *row;
- *row++ = clear_value64 | tmp;
+ else {
+ for (i = 0; i < height; i++) {
+ uint64_t *row = (uint64_t *)dst;
+ for (j = 0; j < width; j++) {
+ uint64_t tmp = ~clear_mask64 & *row;
+ *row++ = clear_value64 | tmp;
+ }
+ dst += dst_stride;
- default:
- assert(0);
- break;
+ default:
+ assert(0);
+ break;
+ }
+ dst_layer += scene->zsbuf.layer_stride;
/* color buffer */
for (i = 0; i < scene->fb.nr_cbufs; i++){
stride[i] = scene->cbufs[i].stride;
/* color buffer */
for (i = 0; i < scene->fb.nr_cbufs; i++){
stride[i] = scene->cbufs[i].stride;
-
- color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, tile_x + x, tile_y + y);
+ color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, tile_x + x,
+ tile_y + y, inputs->layer);
}
/* depth buffer */
if (scene->zsbuf.map) {
}
/* depth buffer */
if (scene->zsbuf.map) {
- depth = lp_rast_get_unswizzled_depth_block_pointer(task, tile_x + x, tile_y + y);
+ depth = lp_rast_get_unswizzled_depth_block_pointer(task, tile_x + x,
+ tile_y + y, inputs->layer);
depth_stride = scene->zsbuf.stride;
}
depth_stride = scene->zsbuf.stride;
}
/* run shader on 4x4 block */
BEGIN_JIT_CALL(state, task);
variant->jit_function[RAST_WHOLE]( &state->jit_context,
/* run shader on 4x4 block */
BEGIN_JIT_CALL(state, task);
variant->jit_function[RAST_WHOLE]( &state->jit_context,
const struct lp_scene *scene = task->scene;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
unsigned stride[PIPE_MAX_COLOR_BUFS];
const struct lp_scene *scene = task->scene;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
unsigned stride[PIPE_MAX_COLOR_BUFS];
unsigned depth_stride = 0;
unsigned i;
unsigned depth_stride = 0;
unsigned i;
/* color buffer */
for (i = 0; i < scene->fb.nr_cbufs; i++) {
stride[i] = scene->cbufs[i].stride;
/* color buffer */
for (i = 0; i < scene->fb.nr_cbufs; i++) {
stride[i] = scene->cbufs[i].stride;
-
- color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y);
+ color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer);
}
/* depth buffer */
if (scene->zsbuf.map) {
depth_stride = scene->zsbuf.stride;
}
/* depth buffer */
if (scene->zsbuf.map) {
depth_stride = scene->zsbuf.stride;
- depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y);
+ depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y, inputs->layer);
}
assert(lp_check_alignment(state->jit_context.u8_blend_color, 16));
}
assert(lp_check_alignment(state->jit_context.u8_blend_color, 16));
unsigned opaque:1; /** Is opaque */
unsigned pad0:29; /* wasted space */
unsigned stride; /* how much to advance data between a0, dadx, dady */
unsigned opaque:1; /** Is opaque */
unsigned pad0:29; /* wasted space */
unsigned stride; /* how much to advance data between a0, dadx, dady */
+ unsigned layer; /* the layer to render to (from gs, already clamped) */
unsigned pad2; /* wasted space */
unsigned pad2; /* wasted space */
- unsigned pad3; /* wasted space */
/* followed by a0, dadx, dady and planes[] */
};
/* followed by a0, dadx, dady and planes[] */
};
*/
static INLINE uint8_t *
lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task,
*/
static INLINE uint8_t *
lp_rast_get_unswizzled_color_block_pointer(struct lp_rasterizer_task *task,
- unsigned buf, unsigned x, unsigned y)
+ unsigned buf, unsigned x, unsigned y,
+ unsigned layer)
{
unsigned px, py, pixel_offset, format_bytes;
uint8_t *color;
{
unsigned px, py, pixel_offset, format_bytes;
uint8_t *color;
color = color + pixel_offset;
color = color + pixel_offset;
+ if (layer) {
+ color += layer * task->scene->cbufs[buf].layer_stride;
+ }
+
assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format)));
return color;
}
assert(lp_check_alignment(color, llvmpipe_get_format_alignment(task->scene->fb.cbufs[buf]->format)));
return color;
}
*/
static INLINE uint8_t *
lp_rast_get_unswizzled_depth_block_pointer(struct lp_rasterizer_task *task,
*/
static INLINE uint8_t *
lp_rast_get_unswizzled_depth_block_pointer(struct lp_rasterizer_task *task,
- unsigned x, unsigned y)
+ unsigned x, unsigned y, unsigned layer)
{
unsigned px, py, pixel_offset, format_bytes;
uint8_t *depth;
{
unsigned px, py, pixel_offset, format_bytes;
uint8_t *depth;
depth = depth + pixel_offset;
depth = depth + pixel_offset;
+ if (layer) {
+ depth += layer * task->scene->zsbuf.layer_stride;
+ }
+
assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format)));
return depth;
}
assert(lp_check_alignment(depth, llvmpipe_get_format_alignment(task->scene->fb.zsbuf->format)));
return depth;
}
struct lp_fragment_shader_variant *variant = state->variant;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
unsigned stride[PIPE_MAX_COLOR_BUFS];
struct lp_fragment_shader_variant *variant = state->variant;
uint8_t *color[PIPE_MAX_COLOR_BUFS];
unsigned stride[PIPE_MAX_COLOR_BUFS];
unsigned depth_stride = 0;
unsigned i;
/* color buffer */
for (i = 0; i < scene->fb.nr_cbufs; i++) {
stride[i] = scene->cbufs[i].stride;
unsigned depth_stride = 0;
unsigned i;
/* color buffer */
for (i = 0; i < scene->fb.nr_cbufs; i++) {
stride[i] = scene->cbufs[i].stride;
-
- color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y);
+ color[i] = lp_rast_get_unswizzled_color_block_pointer(task, i, x, y, inputs->layer);
}
if (scene->zsbuf.map) {
}
if (scene->zsbuf.map) {
- depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y);
+ depth = lp_rast_get_unswizzled_depth_block_pointer(task, x, y, inputs->layer);
depth_stride = scene->zsbuf.stride;
}
depth_stride = scene->zsbuf.stride;
}
{
const struct pipe_framebuffer_state *fb = &scene->fb;
int i;
{
const struct pipe_framebuffer_state *fb = &scene->fb;
int i;
+ unsigned max_layer = ~0;
//LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
//LP_DBG(DEBUG_RAST, "%s\n", __FUNCTION__);
if (llvmpipe_resource_is_texture(cbuf->texture)) {
scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture,
cbuf->u.tex.level);
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);
+ max_layer = MIN2(max_layer, cbuf->u.tex.last_layer - cbuf->u.tex.first_layer);
scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
cbuf->u.tex.level,
scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture,
cbuf->u.tex.level,
struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture);
unsigned pixstride = util_format_get_blocksize(cbuf->format);
scene->cbufs[i].stride = cbuf->texture->width0;
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].map = lpr->data;
scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride;
}
scene->cbufs[i].map = lpr->data;
scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride;
}
if (fb->zsbuf) {
struct pipe_surface *zsbuf = scene->fb.zsbuf;
scene->zsbuf.stride = llvmpipe_resource_stride(zsbuf->texture, zsbuf->u.tex.level);
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);
+ max_layer = MIN2(max_layer, zsbuf->u.tex.last_layer - zsbuf->u.tex.first_layer);
scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
zsbuf->u.tex.level,
zsbuf->u.tex.first_layer,
LP_TEX_USAGE_READ_WRITE);
}
scene->zsbuf.map = llvmpipe_resource_map(zsbuf->texture,
zsbuf->u.tex.level,
zsbuf->u.tex.first_layer,
LP_TEX_USAGE_READ_WRITE);
}
+
+ scene->fb_max_layer = max_layer;
struct {
uint8_t *map;
unsigned stride;
struct {
uint8_t *map;
unsigned stride;
} zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
} zsbuf, cbufs[PIPE_MAX_COLOR_BUFS];
+
+ /* OpenGL permits different amount of layers per rt, but rendering limited to minimum */
+ unsigned fb_max_layer;
+
/** the framebuffer to render the scene into */
struct pipe_framebuffer_state fb;
/** the framebuffer to render the scene into */
struct pipe_framebuffer_state fb;
*/
setup->psize = lp->psize_slot;
setup->viewport_index_slot = lp->viewport_index_slot;
*/
setup->psize = lp->psize_slot;
setup->viewport_index_slot = lp->viewport_index_slot;
+ setup->layer_slot = lp->layer_slot;
float point_size;
float psize;
unsigned viewport_index_slot;
float point_size;
float psize;
unsigned viewport_index_slot;
struct pipe_framebuffer_state fb;
struct u_rect framebuffer;
struct pipe_framebuffer_state fb;
struct u_rect framebuffer;
int i;
int nr_planes = 4;
unsigned scissor_index = 0;
int i;
int nr_planes = 4;
unsigned scissor_index = 0;
/* linewidth should be interpreted as integer */
int fixed_width = util_iround(width) * FIXED_ONE;
/* linewidth should be interpreted as integer */
int fixed_width = util_iround(width) * FIXED_ONE;
+ if (setup->layer_slot > 0) {
+ layer = *(unsigned*)v1[setup->layer_slot];
+ layer = MIN2(layer, scene->fb_max_layer);
+ }
dx = v1[0][0] - v2[0][0];
dy = v1[0][1] - v2[0][1];
dx = v1[0][0] - v2[0][0];
dy = v1[0][1] - v2[0][1];
line->inputs.frontfacing = TRUE;
line->inputs.disable = FALSE;
line->inputs.opaque = FALSE;
line->inputs.frontfacing = TRUE;
line->inputs.disable = FALSE;
line->inputs.opaque = FALSE;
+ line->inputs.layer = layer;
for (i = 0; i < 4; i++) {
for (i = 0; i < 4; i++) {
unsigned nr_planes = 4;
struct point_info info;
unsigned scissor_index = 0;
unsigned nr_planes = 4;
struct point_info info;
unsigned scissor_index = 0;
if (setup->viewport_index_slot > 0) {
unsigned *udata = (unsigned*)v0[setup->viewport_index_slot];
scissor_index = lp_clamp_scissor_idx(*udata);
}
if (setup->viewport_index_slot > 0) {
unsigned *udata = (unsigned*)v0[setup->viewport_index_slot];
scissor_index = lp_clamp_scissor_idx(*udata);
}
+ if (setup->layer_slot > 0) {
+ layer = *(unsigned*)v0[setup->layer_slot];
+ layer = MIN2(layer, scene->fb_max_layer);
+ }
+
/* Bounding rectangle (in pixels) */
{
/* Yes this is necessary to accurately calculate bounding boxes
/* Bounding rectangle (in pixels) */
{
/* Yes this is necessary to accurately calculate bounding boxes
point->inputs.frontfacing = TRUE;
point->inputs.disable = FALSE;
point->inputs.opaque = FALSE;
point->inputs.frontfacing = TRUE;
point->inputs.disable = FALSE;
point->inputs.opaque = FALSE;
+ point->inputs.layer = layer;
{
struct lp_rast_plane *plane = GET_PLANES(point);
{
struct lp_rast_plane *plane = GET_PLANES(point);
LP_COUNT(nr_fully_covered_64);
/* if variant is opaque and scissor doesn't effect the tile */
LP_COUNT(nr_fully_covered_64);
/* if variant is opaque and scissor doesn't effect the tile */
+ /*
+ * Need to disable this optimization for layered rendering and cannot use
+ * setup->layer_slot here to determine it, because it could incorrectly
+ * reset the tile if a previous shader used layer_slot but not this one
+ * (or maybe even "undo" clears). So determine this from presence of layers
+ * instead (in which case layer_slot will have no effect).
+ */
+ if (inputs->opaque && scene->fb_max_layer == 0) {
if (!scene->fb.zsbuf) {
/*
* All previous rendering will be overwritten so reset the bin.
if (!scene->fb.zsbuf) {
/*
* All previous rendering will be overwritten so reset the bin.
unsigned tri_bytes;
int nr_planes = 3;
unsigned scissor_index = 0;
unsigned tri_bytes;
int nr_planes = 3;
unsigned scissor_index = 0;
/* Area should always be positive here */
assert(position->area > 0);
/* Area should always be positive here */
assert(position->area > 0);
+ if (setup->layer_slot > 0) {
+ layer = *(unsigned*)v1[setup->layer_slot];
+ layer = MIN2(layer, scene->fb_max_layer);
+ }
/* Bounding rectangle (in pixels) */
{
/* Bounding rectangle (in pixels) */
{
tri->inputs.frontfacing = frontfacing;
tri->inputs.disable = FALSE;
tri->inputs.opaque = setup->fs.current.variant->opaque;
tri->inputs.frontfacing = frontfacing;
tri->inputs.disable = FALSE;
tri->inputs.opaque = setup->fs.current.variant->opaque;
+ tri->inputs.layer = layer;
if (0)
lp_dump_setup_coef(&setup->setup.variant->key,
if (0)
lp_dump_setup_coef(&setup->setup.variant->key,
- return lp_setup_bin_triangle( setup, tri, &bbox, nr_planes, scissor_index );
+ return lp_setup_bin_triangle(setup, tri, &bbox, nr_planes, scissor_index);
} else {
llvmpipe->viewport_index_slot = 0;
}
} else {
llvmpipe->viewport_index_slot = 0;
}
+
+ /* Figure out if we need layer */
+ vs_index = draw_find_shader_output(llvmpipe->draw,
+ TGSI_SEMANTIC_LAYER,
+ 0);
+ if (vs_index >= 0) {
+ llvmpipe->layer_slot = vinfo->num_attribs;
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT, vs_index);
+ } else {
+ llvmpipe->layer_slot = 0;
+ }
+
draw_compute_vertex_size(vinfo);
lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
draw_compute_vertex_size(vinfo);
lp_setup_set_vertex_info(llvmpipe->setup, vinfo);
ps->format = surf_tmpl->format;
if (llvmpipe_resource_is_texture(pt)) {
assert(surf_tmpl->u.tex.level <= pt->last_level);
ps->format = surf_tmpl->format;
if (llvmpipe_resource_is_texture(pt)) {
assert(surf_tmpl->u.tex.level <= pt->last_level);
+ assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer);
ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
ps->u.tex.level = surf_tmpl->u.tex.level;
ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level);
ps->u.tex.level = surf_tmpl->u.tex.level;
ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
- if (ps->u.tex.first_layer != ps->u.tex.last_layer) {
- debug_printf("creating surface with multiple layers, rendering to first layer only\n");
- }
}
else {
/* setting width as number of elements should get us correct renderbuffer width */
}
else {
/* setting width as number of elements should get us correct renderbuffer width */
llvmpipe_surface_destroy(struct pipe_context *pipe,
struct pipe_surface *surf)
{
llvmpipe_surface_destroy(struct pipe_context *pipe,
struct pipe_surface *surf)
{
+llvmpipe_layer_stride(struct pipe_resource *resource,
+ unsigned level)
+{
+ struct llvmpipe_resource *lpr = llvmpipe_resource(resource);
+ assert(level < LP_MAX_TEXTURE_2D_LEVELS);
+ return lpr->img_stride[level];
+}
+
+
+static INLINE unsigned
llvmpipe_resource_stride(struct pipe_resource *resource,
unsigned level)
{
llvmpipe_resource_stride(struct pipe_resource *resource,
unsigned level)
{