i915g: Fix point sprites.
This commit is contained in:
@@ -106,7 +106,7 @@ static void i915_destroy(struct pipe_context *pipe)
|
||||
|
||||
if (i915->blitter)
|
||||
util_blitter_destroy(i915->blitter);
|
||||
|
||||
|
||||
if(i915->batch)
|
||||
i915->iws->batchbuffer_destroy(i915->batch);
|
||||
|
||||
@@ -150,6 +150,8 @@ i915_create_context(struct pipe_screen *screen, void *priv)
|
||||
/* init this before draw */
|
||||
util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
|
||||
16, UTIL_SLAB_SINGLETHREADED);
|
||||
util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer),
|
||||
16, UTIL_SLAB_SINGLETHREADED);
|
||||
|
||||
/* Batch stream debugging is a bit hacked up at the moment:
|
||||
*/
|
||||
|
@@ -102,6 +102,8 @@ struct i915_fragment_shader
|
||||
|
||||
struct tgsi_shader_info info;
|
||||
|
||||
struct draw_fragment_shader *draw_data;
|
||||
|
||||
uint *program;
|
||||
uint program_len;
|
||||
|
||||
@@ -260,6 +262,7 @@ struct i915_context {
|
||||
int num_validation_buffers;
|
||||
|
||||
struct util_slab_mempool transfer_pool;
|
||||
struct util_slab_mempool texture_transfer_pool;
|
||||
|
||||
/** blitter/hw-clear */
|
||||
struct blitter_context* blitter;
|
||||
|
@@ -7,12 +7,12 @@
|
||||
|
||||
static struct pipe_resource *
|
||||
i915_resource_create(struct pipe_screen *screen,
|
||||
const struct pipe_resource *template)
|
||||
const struct pipe_resource *template)
|
||||
{
|
||||
if (template->target == PIPE_BUFFER)
|
||||
return i915_buffer_create(screen, template);
|
||||
else
|
||||
return i915_texture_create(screen, template);
|
||||
return i915_texture_create(screen, template, FALSE);
|
||||
|
||||
}
|
||||
|
||||
|
@@ -45,6 +45,15 @@ struct i915_buffer {
|
||||
boolean free_on_destroy;
|
||||
};
|
||||
|
||||
|
||||
/* Texture transfer. */
|
||||
struct i915_transfer {
|
||||
/* Base class. */
|
||||
struct pipe_transfer b;
|
||||
struct pipe_resource *staging_texture;
|
||||
};
|
||||
|
||||
|
||||
#define I915_MAX_TEXTURE_2D_LEVELS 12 /* max 2048x2048 */
|
||||
#define I915_MAX_TEXTURE_3D_LEVELS 9 /* max 256x256x256 */
|
||||
|
||||
@@ -101,7 +110,8 @@ static INLINE struct i915_buffer *i915_buffer(struct pipe_resource *resource)
|
||||
|
||||
struct pipe_resource *
|
||||
i915_texture_create(struct pipe_screen *screen,
|
||||
const struct pipe_resource *template);
|
||||
const struct pipe_resource *template,
|
||||
boolean force_untiled);
|
||||
|
||||
struct pipe_resource *
|
||||
i915_texture_from_handle(struct pipe_screen * screen,
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "util/u_format.h"
|
||||
#include "util/u_math.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_rect.h"
|
||||
|
||||
#include "i915_context.h"
|
||||
#include "i915_resource.h"
|
||||
@@ -710,7 +711,7 @@ i915_texture_destroy(struct pipe_screen *screen,
|
||||
FREE(tex);
|
||||
}
|
||||
|
||||
static struct pipe_transfer *
|
||||
static struct pipe_transfer *
|
||||
i915_texture_get_transfer(struct pipe_context *pipe,
|
||||
struct pipe_resource *resource,
|
||||
unsigned level,
|
||||
@@ -719,19 +720,44 @@ i915_texture_get_transfer(struct pipe_context *pipe,
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
struct i915_texture *tex = i915_texture(resource);
|
||||
struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool);
|
||||
struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool);
|
||||
boolean use_staging_texture = FALSE;
|
||||
|
||||
if (transfer == NULL)
|
||||
return NULL;
|
||||
|
||||
transfer->resource = resource;
|
||||
transfer->level = level;
|
||||
transfer->usage = usage;
|
||||
transfer->box = *box;
|
||||
transfer->stride = tex->stride;
|
||||
/* FIXME: layer_stride */
|
||||
transfer->b.resource = resource;
|
||||
transfer->b.level = level;
|
||||
transfer->b.usage = usage;
|
||||
transfer->b.box = *box;
|
||||
transfer->b.stride = tex->stride;
|
||||
transfer->staging_texture = NULL;
|
||||
/* XXX: handle depth textures everyhwere*/
|
||||
transfer->b.layer_stride = 0;
|
||||
transfer->b.data = NULL;
|
||||
|
||||
return transfer;
|
||||
/* only support textures we can render to, because we need that for u_blitter */
|
||||
if (i915->blitter &&
|
||||
i915_is_format_supported(NULL, /* screen */
|
||||
transfer->b.resource->format,
|
||||
0, /* target */
|
||||
1, /* sample count */
|
||||
PIPE_BIND_RENDER_TARGET) &&
|
||||
(usage & PIPE_TRANSFER_WRITE) &&
|
||||
!(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED)))
|
||||
use_staging_texture = TRUE;
|
||||
|
||||
use_staging_texture = FALSE;
|
||||
|
||||
if (use_staging_texture) {
|
||||
/*
|
||||
* Allocate the untiled staging texture.
|
||||
* If the alloc fails, transfer->staging_texture is NULL and we fallback to a map()
|
||||
*/
|
||||
transfer->staging_texture = i915_texture_create(pipe->screen, resource, TRUE);
|
||||
}
|
||||
|
||||
return (struct pipe_transfer*)transfer;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -739,17 +765,33 @@ i915_transfer_destroy(struct pipe_context *pipe,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct i915_context *i915 = i915_context(pipe);
|
||||
util_slab_free(&i915->transfer_pool, transfer);
|
||||
struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
|
||||
|
||||
if ((itransfer->staging_texture) &&
|
||||
(transfer->usage & PIPE_TRANSFER_WRITE)) {
|
||||
struct pipe_box sbox;
|
||||
|
||||
u_box_origin_2d(itransfer->b.box.width, itransfer->b.box.height, &sbox);
|
||||
pipe->resource_copy_region(pipe, itransfer->b.resource, itransfer->b.level,
|
||||
itransfer->b.box.x, itransfer->b.box.y, itransfer->b.box.z,
|
||||
itransfer->staging_texture,
|
||||
0, &sbox);
|
||||
pipe->flush(pipe, NULL);
|
||||
pipe_resource_reference(&itransfer->staging_texture, NULL);
|
||||
}
|
||||
|
||||
util_slab_free(&i915->texture_transfer_pool, itransfer);
|
||||
}
|
||||
|
||||
static void *
|
||||
i915_texture_transfer_map(struct pipe_context *pipe,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct pipe_resource *resource = transfer->resource;
|
||||
struct i915_texture *tex = i915_texture(resource);
|
||||
struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
|
||||
struct pipe_resource *resource = itransfer->b.resource;
|
||||
struct i915_texture *tex = NULL;
|
||||
struct i915_winsys *iws = i915_screen(pipe->screen)->iws;
|
||||
struct pipe_box *box = &transfer->box;
|
||||
struct pipe_box *box = &itransfer->b.box;
|
||||
enum pipe_format format = resource->format;
|
||||
unsigned offset;
|
||||
char *map;
|
||||
@@ -757,18 +799,25 @@ i915_texture_transfer_map(struct pipe_context *pipe,
|
||||
if (resource->target != PIPE_TEXTURE_3D &&
|
||||
resource->target != PIPE_TEXTURE_CUBE)
|
||||
assert(box->z == 0);
|
||||
offset = i915_texture_offset(tex, transfer->level, box->z);
|
||||
|
||||
/* TODO this is a sledgehammer */
|
||||
pipe->flush(pipe, NULL);
|
||||
if (itransfer->staging_texture) {
|
||||
tex = i915_texture(itransfer->staging_texture);
|
||||
} else {
|
||||
/* TODO this is a sledgehammer */
|
||||
tex = i915_texture(resource);
|
||||
pipe->flush(pipe, NULL);
|
||||
}
|
||||
|
||||
offset = i915_texture_offset(tex, itransfer->b.level, box->z);
|
||||
|
||||
map = iws->buffer_map(iws, tex->buffer,
|
||||
(transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
|
||||
if (map == NULL)
|
||||
(itransfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
|
||||
if (map == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return map + offset +
|
||||
box->y / util_format_get_blockheight(format) * transfer->stride +
|
||||
box->y / util_format_get_blockheight(format) * itransfer->b.stride +
|
||||
box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
|
||||
}
|
||||
|
||||
@@ -776,14 +825,106 @@ static void
|
||||
i915_texture_transfer_unmap(struct pipe_context *pipe,
|
||||
struct pipe_transfer *transfer)
|
||||
{
|
||||
struct i915_texture *tex = i915_texture(transfer->resource);
|
||||
struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
|
||||
struct i915_texture *tex = i915_texture(itransfer->b.resource);
|
||||
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
|
||||
|
||||
if (itransfer->staging_texture)
|
||||
tex = i915_texture(itransfer->staging_texture);
|
||||
|
||||
iws->buffer_unmap(iws, tex->buffer);
|
||||
}
|
||||
|
||||
static void i915_transfer_inline_write( struct pipe_context *pipe,
|
||||
struct pipe_resource *resource,
|
||||
unsigned level,
|
||||
unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
const void *data,
|
||||
unsigned stride,
|
||||
unsigned layer_stride)
|
||||
{
|
||||
struct pipe_transfer *transfer = NULL;
|
||||
struct i915_transfer *itransfer = NULL;
|
||||
const uint8_t *src_data = data;
|
||||
unsigned i;
|
||||
|
||||
transfer = pipe->get_transfer(pipe,
|
||||
resource,
|
||||
level,
|
||||
usage,
|
||||
box );
|
||||
if (transfer == NULL)
|
||||
goto out;
|
||||
|
||||
itransfer = (struct i915_transfer*)transfer;
|
||||
|
||||
if (itransfer->staging_texture) {
|
||||
struct i915_texture *tex = i915_texture(itransfer->staging_texture);
|
||||
enum pipe_format format = tex->b.b.format;
|
||||
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
|
||||
size_t offset;
|
||||
size_t size;
|
||||
|
||||
offset = i915_texture_offset(tex, transfer->level, transfer->box.z);
|
||||
|
||||
for (i = 0; i < box->depth; i++) {
|
||||
if (!tex->b.b.last_level &&
|
||||
tex->b.b.width0 == transfer->box.width) {
|
||||
unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
|
||||
assert(!offset);
|
||||
assert(!transfer->box.x);
|
||||
assert(tex->stride == transfer->stride);
|
||||
|
||||
offset += tex->stride * nby;
|
||||
size = util_format_get_2d_size(format, transfer->stride,
|
||||
transfer->box.height);
|
||||
iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
|
||||
|
||||
} else {
|
||||
unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
|
||||
int i;
|
||||
offset += util_format_get_stride(format, transfer->box.x);
|
||||
size = transfer->stride;
|
||||
|
||||
for (i = 0; i < nby; i++) {
|
||||
iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
|
||||
offset += tex->stride;
|
||||
}
|
||||
}
|
||||
offset += layer_stride;
|
||||
}
|
||||
} else {
|
||||
uint8_t *map = pipe_transfer_map(pipe, &itransfer->b);
|
||||
if (map == NULL)
|
||||
goto nomap;
|
||||
|
||||
for (i = 0; i < box->depth; i++) {
|
||||
util_copy_rect(map,
|
||||
resource->format,
|
||||
itransfer->b.stride, /* bytes */
|
||||
0, 0,
|
||||
box->width,
|
||||
box->height,
|
||||
src_data,
|
||||
stride, /* bytes */
|
||||
0, 0);
|
||||
map += itransfer->b.layer_stride;
|
||||
src_data += layer_stride;
|
||||
}
|
||||
nomap:
|
||||
if (map)
|
||||
pipe_transfer_unmap(pipe, &itransfer->b);
|
||||
}
|
||||
|
||||
out:
|
||||
if (itransfer)
|
||||
pipe_transfer_destroy(pipe, &itransfer->b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct u_resource_vtbl i915_texture_vtbl =
|
||||
struct u_resource_vtbl i915_texture_vtbl =
|
||||
{
|
||||
i915_texture_get_handle, /* get_handle */
|
||||
i915_texture_destroy, /* resource_destroy */
|
||||
@@ -792,7 +933,7 @@ struct u_resource_vtbl i915_texture_vtbl =
|
||||
i915_texture_transfer_map, /* transfer_map */
|
||||
u_default_transfer_flush_region, /* transfer_flush_region */
|
||||
i915_texture_transfer_unmap, /* transfer_unmap */
|
||||
u_default_transfer_inline_write /* transfer_inline_write */
|
||||
i915_transfer_inline_write /* transfer_inline_write */
|
||||
};
|
||||
|
||||
|
||||
@@ -800,7 +941,8 @@ struct u_resource_vtbl i915_texture_vtbl =
|
||||
|
||||
struct pipe_resource *
|
||||
i915_texture_create(struct pipe_screen *screen,
|
||||
const struct pipe_resource *template)
|
||||
const struct pipe_resource *template,
|
||||
boolean force_untiled)
|
||||
{
|
||||
struct i915_screen *is = i915_screen(screen);
|
||||
struct i915_winsys *iws = is->iws;
|
||||
@@ -815,7 +957,10 @@ i915_texture_create(struct pipe_screen *screen,
|
||||
pipe_reference_init(&tex->b.b.reference, 1);
|
||||
tex->b.b.screen = screen;
|
||||
|
||||
tex->tiling = i915_texture_tiling(is, tex);
|
||||
if (force_untiled)
|
||||
tex->tiling = I915_TILE_NONE;
|
||||
else
|
||||
tex->tiling = i915_texture_tiling(is, tex);
|
||||
|
||||
if (is->is_i945) {
|
||||
if (!i945_texture_layout(tex))
|
||||
@@ -835,8 +980,12 @@ i915_texture_create(struct pipe_screen *screen,
|
||||
else
|
||||
buf_usage = I915_NEW_TEXTURE;
|
||||
|
||||
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
|
||||
&tex->tiling, buf_usage);
|
||||
if (tex->tiling == I915_TILE_NONE)
|
||||
tex->buffer = iws->buffer_create(iws, tex->total_nblocksy * tex->stride,
|
||||
buf_usage);
|
||||
else
|
||||
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
|
||||
&tex->tiling, buf_usage);
|
||||
if (!tex->buffer)
|
||||
goto fail;
|
||||
|
||||
|
@@ -253,7 +253,7 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap)
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
boolean
|
||||
i915_is_format_supported(struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
|
@@ -65,5 +65,11 @@ i915_screen(struct pipe_screen *pscreen)
|
||||
return (struct i915_screen *) pscreen;
|
||||
}
|
||||
|
||||
boolean
|
||||
i915_is_format_supported(struct pipe_screen *screen,
|
||||
enum pipe_format format,
|
||||
enum pipe_texture_target target,
|
||||
unsigned sample_count,
|
||||
unsigned tex_usage);
|
||||
|
||||
#endif /* I915_SCREEN_H */
|
||||
|
@@ -466,6 +466,7 @@ i915_create_fs_state(struct pipe_context *pipe,
|
||||
if (!ifs)
|
||||
return NULL;
|
||||
|
||||
ifs->draw_data = draw_create_fragment_shader(i915->draw, templ);
|
||||
ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
|
||||
|
||||
tgsi_scan_shader(templ->tokens, &ifs->info);
|
||||
@@ -495,6 +496,8 @@ i915_bind_fs_state(struct pipe_context *pipe, void *shader)
|
||||
|
||||
i915->fs = (struct i915_fragment_shader*) shader;
|
||||
|
||||
draw_bind_fragment_shader(i915->draw, (i915->fs ? i915->fs->draw_data : NULL));
|
||||
|
||||
i915->dirty |= I915_NEW_FS;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user