Skip to content

Commit 1a69b50

Browse files
committed
i915g: Fix point sprites.
1 parent 6b28b44 commit 1a69b50

File tree

8 files changed

+204
-31
lines changed

8 files changed

+204
-31
lines changed

src/gallium/drivers/i915/i915_context.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static void i915_destroy(struct pipe_context *pipe)
106106

107107
if (i915->blitter)
108108
util_blitter_destroy(i915->blitter);
109-
109+
110110
if(i915->batch)
111111
i915->iws->batchbuffer_destroy(i915->batch);
112112

@@ -150,6 +150,8 @@ i915_create_context(struct pipe_screen *screen, void *priv)
150150
/* init this before draw */
151151
util_slab_create(&i915->transfer_pool, sizeof(struct pipe_transfer),
152152
16, UTIL_SLAB_SINGLETHREADED);
153+
util_slab_create(&i915->texture_transfer_pool, sizeof(struct i915_transfer),
154+
16, UTIL_SLAB_SINGLETHREADED);
153155

154156
/* Batch stream debugging is a bit hacked up at the moment:
155157
*/

src/gallium/drivers/i915/i915_context.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ struct i915_fragment_shader
102102

103103
struct tgsi_shader_info info;
104104

105+
struct draw_fragment_shader *draw_data;
106+
105107
uint *program;
106108
uint program_len;
107109

@@ -260,6 +262,7 @@ struct i915_context {
260262
int num_validation_buffers;
261263

262264
struct util_slab_mempool transfer_pool;
265+
struct util_slab_mempool texture_transfer_pool;
263266

264267
/** blitter/hw-clear */
265268
struct blitter_context* blitter;

src/gallium/drivers/i915/i915_resource.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
static struct pipe_resource *
99
i915_resource_create(struct pipe_screen *screen,
10-
const struct pipe_resource *template)
10+
const struct pipe_resource *template)
1111
{
1212
if (template->target == PIPE_BUFFER)
1313
return i915_buffer_create(screen, template);
1414
else
15-
return i915_texture_create(screen, template);
15+
return i915_texture_create(screen, template, FALSE);
1616

1717
}
1818

src/gallium/drivers/i915/i915_resource.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ struct i915_buffer {
4545
boolean free_on_destroy;
4646
};
4747

48+
49+
/* Texture transfer. */
50+
struct i915_transfer {
51+
/* Base class. */
52+
struct pipe_transfer b;
53+
struct pipe_resource *staging_texture;
54+
};
55+
56+
4857
#define I915_MAX_TEXTURE_2D_LEVELS 12 /* max 2048x2048 */
4958
#define I915_MAX_TEXTURE_3D_LEVELS 9 /* max 256x256x256 */
5059

@@ -101,7 +110,8 @@ static INLINE struct i915_buffer *i915_buffer(struct pipe_resource *resource)
101110

102111
struct pipe_resource *
103112
i915_texture_create(struct pipe_screen *screen,
104-
const struct pipe_resource *template);
113+
const struct pipe_resource *template,
114+
boolean force_untiled);
105115

106116
struct pipe_resource *
107117
i915_texture_from_handle(struct pipe_screen * screen,

src/gallium/drivers/i915/i915_resource_texture.c

Lines changed: 175 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "util/u_format.h"
3838
#include "util/u_math.h"
3939
#include "util/u_memory.h"
40+
#include "util/u_rect.h"
4041

4142
#include "i915_context.h"
4243
#include "i915_resource.h"
@@ -710,7 +711,7 @@ i915_texture_destroy(struct pipe_screen *screen,
710711
FREE(tex);
711712
}
712713

713-
static struct pipe_transfer *
714+
static struct pipe_transfer *
714715
i915_texture_get_transfer(struct pipe_context *pipe,
715716
struct pipe_resource *resource,
716717
unsigned level,
@@ -719,71 +720,211 @@ i915_texture_get_transfer(struct pipe_context *pipe,
719720
{
720721
struct i915_context *i915 = i915_context(pipe);
721722
struct i915_texture *tex = i915_texture(resource);
722-
struct pipe_transfer *transfer = util_slab_alloc(&i915->transfer_pool);
723+
struct i915_transfer *transfer = util_slab_alloc(&i915->texture_transfer_pool);
724+
boolean use_staging_texture = FALSE;
723725

724726
if (transfer == NULL)
725727
return NULL;
726728

727-
transfer->resource = resource;
728-
transfer->level = level;
729-
transfer->usage = usage;
730-
transfer->box = *box;
731-
transfer->stride = tex->stride;
732-
/* FIXME: layer_stride */
729+
transfer->b.resource = resource;
730+
transfer->b.level = level;
731+
transfer->b.usage = usage;
732+
transfer->b.box = *box;
733+
transfer->b.stride = tex->stride;
734+
transfer->staging_texture = NULL;
735+
/* XXX: handle depth textures everyhwere*/
736+
transfer->b.layer_stride = 0;
737+
transfer->b.data = NULL;
738+
739+
/* only support textures we can render to, because we need that for u_blitter */
740+
if (i915->blitter &&
741+
i915_is_format_supported(NULL, /* screen */
742+
transfer->b.resource->format,
743+
0, /* target */
744+
1, /* sample count */
745+
PIPE_BIND_RENDER_TARGET) &&
746+
(usage & PIPE_TRANSFER_WRITE) &&
747+
!(usage & (PIPE_TRANSFER_READ | PIPE_TRANSFER_DONTBLOCK | PIPE_TRANSFER_UNSYNCHRONIZED)))
748+
use_staging_texture = TRUE;
749+
750+
use_staging_texture = FALSE;
751+
752+
if (use_staging_texture) {
753+
/*
754+
* Allocate the untiled staging texture.
755+
* If the alloc fails, transfer->staging_texture is NULL and we fallback to a map()
756+
*/
757+
transfer->staging_texture = i915_texture_create(pipe->screen, resource, TRUE);
758+
}
733759

734-
return transfer;
760+
return (struct pipe_transfer*)transfer;
735761
}
736762

737763
static void
738764
i915_transfer_destroy(struct pipe_context *pipe,
739765
struct pipe_transfer *transfer)
740766
{
741767
struct i915_context *i915 = i915_context(pipe);
742-
util_slab_free(&i915->transfer_pool, transfer);
768+
struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
769+
770+
if ((itransfer->staging_texture) &&
771+
(transfer->usage & PIPE_TRANSFER_WRITE)) {
772+
struct pipe_box sbox;
773+
774+
u_box_origin_2d(itransfer->b.box.width, itransfer->b.box.height, &sbox);
775+
pipe->resource_copy_region(pipe, itransfer->b.resource, itransfer->b.level,
776+
itransfer->b.box.x, itransfer->b.box.y, itransfer->b.box.z,
777+
itransfer->staging_texture,
778+
0, &sbox);
779+
pipe->flush(pipe, NULL);
780+
pipe_resource_reference(&itransfer->staging_texture, NULL);
781+
}
782+
783+
util_slab_free(&i915->texture_transfer_pool, itransfer);
743784
}
744785

745786
static void *
746787
i915_texture_transfer_map(struct pipe_context *pipe,
747788
struct pipe_transfer *transfer)
748789
{
749-
struct pipe_resource *resource = transfer->resource;
750-
struct i915_texture *tex = i915_texture(resource);
790+
struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
791+
struct pipe_resource *resource = itransfer->b.resource;
792+
struct i915_texture *tex = NULL;
751793
struct i915_winsys *iws = i915_screen(pipe->screen)->iws;
752-
struct pipe_box *box = &transfer->box;
794+
struct pipe_box *box = &itransfer->b.box;
753795
enum pipe_format format = resource->format;
754796
unsigned offset;
755797
char *map;
756798

757799
if (resource->target != PIPE_TEXTURE_3D &&
758800
resource->target != PIPE_TEXTURE_CUBE)
759801
assert(box->z == 0);
760-
offset = i915_texture_offset(tex, transfer->level, box->z);
761802

762-
/* TODO this is a sledgehammer */
763-
pipe->flush(pipe, NULL);
803+
if (itransfer->staging_texture) {
804+
tex = i915_texture(itransfer->staging_texture);
805+
} else {
806+
/* TODO this is a sledgehammer */
807+
tex = i915_texture(resource);
808+
pipe->flush(pipe, NULL);
809+
}
810+
811+
offset = i915_texture_offset(tex, itransfer->b.level, box->z);
764812

765813
map = iws->buffer_map(iws, tex->buffer,
766-
(transfer->usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
767-
if (map == NULL)
814+
(itransfer->b.usage & PIPE_TRANSFER_WRITE) ? TRUE : FALSE);
815+
if (map == NULL) {
768816
return NULL;
817+
}
769818

770819
return map + offset +
771-
box->y / util_format_get_blockheight(format) * transfer->stride +
820+
box->y / util_format_get_blockheight(format) * itransfer->b.stride +
772821
box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
773822
}
774823

775824
static void
776825
i915_texture_transfer_unmap(struct pipe_context *pipe,
777826
struct pipe_transfer *transfer)
778827
{
779-
struct i915_texture *tex = i915_texture(transfer->resource);
828+
struct i915_transfer *itransfer = (struct i915_transfer*)transfer;
829+
struct i915_texture *tex = i915_texture(itransfer->b.resource);
780830
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
831+
832+
if (itransfer->staging_texture)
833+
tex = i915_texture(itransfer->staging_texture);
834+
781835
iws->buffer_unmap(iws, tex->buffer);
782836
}
783837

838+
static void i915_transfer_inline_write( struct pipe_context *pipe,
839+
struct pipe_resource *resource,
840+
unsigned level,
841+
unsigned usage,
842+
const struct pipe_box *box,
843+
const void *data,
844+
unsigned stride,
845+
unsigned layer_stride)
846+
{
847+
struct pipe_transfer *transfer = NULL;
848+
struct i915_transfer *itransfer = NULL;
849+
const uint8_t *src_data = data;
850+
unsigned i;
851+
852+
transfer = pipe->get_transfer(pipe,
853+
resource,
854+
level,
855+
usage,
856+
box );
857+
if (transfer == NULL)
858+
goto out;
859+
860+
itransfer = (struct i915_transfer*)transfer;
861+
862+
if (itransfer->staging_texture) {
863+
struct i915_texture *tex = i915_texture(itransfer->staging_texture);
864+
enum pipe_format format = tex->b.b.format;
865+
struct i915_winsys *iws = i915_screen(tex->b.b.screen)->iws;
866+
size_t offset;
867+
size_t size;
868+
869+
offset = i915_texture_offset(tex, transfer->level, transfer->box.z);
870+
871+
for (i = 0; i < box->depth; i++) {
872+
if (!tex->b.b.last_level &&
873+
tex->b.b.width0 == transfer->box.width) {
874+
unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
875+
assert(!offset);
876+
assert(!transfer->box.x);
877+
assert(tex->stride == transfer->stride);
878+
879+
offset += tex->stride * nby;
880+
size = util_format_get_2d_size(format, transfer->stride,
881+
transfer->box.height);
882+
iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
883+
884+
} else {
885+
unsigned nby = util_format_get_nblocksy(format, transfer->box.y);
886+
int i;
887+
offset += util_format_get_stride(format, transfer->box.x);
888+
size = transfer->stride;
889+
890+
for (i = 0; i < nby; i++) {
891+
iws->buffer_write(iws, tex->buffer, offset, size, transfer->data);
892+
offset += tex->stride;
893+
}
894+
}
895+
offset += layer_stride;
896+
}
897+
} else {
898+
uint8_t *map = pipe_transfer_map(pipe, &itransfer->b);
899+
if (map == NULL)
900+
goto nomap;
901+
902+
for (i = 0; i < box->depth; i++) {
903+
util_copy_rect(map,
904+
resource->format,
905+
itransfer->b.stride, /* bytes */
906+
0, 0,
907+
box->width,
908+
box->height,
909+
src_data,
910+
stride, /* bytes */
911+
0, 0);
912+
map += itransfer->b.layer_stride;
913+
src_data += layer_stride;
914+
}
915+
nomap:
916+
if (map)
917+
pipe_transfer_unmap(pipe, &itransfer->b);
918+
}
919+
920+
out:
921+
if (itransfer)
922+
pipe_transfer_destroy(pipe, &itransfer->b);
923+
}
924+
784925

785926

786-
struct u_resource_vtbl i915_texture_vtbl =
927+
struct u_resource_vtbl i915_texture_vtbl =
787928
{
788929
i915_texture_get_handle, /* get_handle */
789930
i915_texture_destroy, /* resource_destroy */
@@ -792,15 +933,16 @@ struct u_resource_vtbl i915_texture_vtbl =
792933
i915_texture_transfer_map, /* transfer_map */
793934
u_default_transfer_flush_region, /* transfer_flush_region */
794935
i915_texture_transfer_unmap, /* transfer_unmap */
795-
u_default_transfer_inline_write /* transfer_inline_write */
936+
i915_transfer_inline_write /* transfer_inline_write */
796937
};
797938

798939

799940

800941

801942
struct pipe_resource *
802943
i915_texture_create(struct pipe_screen *screen,
803-
const struct pipe_resource *template)
944+
const struct pipe_resource *template,
945+
boolean force_untiled)
804946
{
805947
struct i915_screen *is = i915_screen(screen);
806948
struct i915_winsys *iws = is->iws;
@@ -815,7 +957,10 @@ i915_texture_create(struct pipe_screen *screen,
815957
pipe_reference_init(&tex->b.b.reference, 1);
816958
tex->b.b.screen = screen;
817959

818-
tex->tiling = i915_texture_tiling(is, tex);
960+
if (force_untiled)
961+
tex->tiling = I915_TILE_NONE;
962+
else
963+
tex->tiling = i915_texture_tiling(is, tex);
819964

820965
if (is->is_i945) {
821966
if (!i945_texture_layout(tex))
@@ -835,8 +980,12 @@ i915_texture_create(struct pipe_screen *screen,
835980
else
836981
buf_usage = I915_NEW_TEXTURE;
837982

838-
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
839-
&tex->tiling, buf_usage);
983+
if (tex->tiling == I915_TILE_NONE)
984+
tex->buffer = iws->buffer_create(iws, tex->total_nblocksy * tex->stride,
985+
buf_usage);
986+
else
987+
tex->buffer = iws->buffer_create_tiled(iws, &tex->stride, tex->total_nblocksy,
988+
&tex->tiling, buf_usage);
840989
if (!tex->buffer)
841990
goto fail;
842991

src/gallium/drivers/i915/i915_screen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ i915_get_paramf(struct pipe_screen *screen, enum pipe_cap cap)
253253
}
254254
}
255255

256-
static boolean
256+
boolean
257257
i915_is_format_supported(struct pipe_screen *screen,
258258
enum pipe_format format,
259259
enum pipe_texture_target target,

src/gallium/drivers/i915/i915_screen.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,11 @@ i915_screen(struct pipe_screen *pscreen)
6565
return (struct i915_screen *) pscreen;
6666
}
6767

68+
boolean
69+
i915_is_format_supported(struct pipe_screen *screen,
70+
enum pipe_format format,
71+
enum pipe_texture_target target,
72+
unsigned sample_count,
73+
unsigned tex_usage);
6874

6975
#endif /* I915_SCREEN_H */

0 commit comments

Comments
 (0)