495
539
boolean r300_is_sampler_format_supported(enum pipe_format format)
497
return r300_translate_texformat(format) != ~0;
541
return r300_translate_texformat(format, 0, TRUE) != ~0;
500
static void r300_setup_texture_state(struct r300_screen* screen, struct r300_texture* tex)
544
void r300_texture_setup_format_state(struct r300_screen *screen,
545
struct r300_texture_desc *desc,
547
struct r300_texture_format_state *out)
502
struct r300_texture_format_state* state = &tex->state;
503
struct pipe_texture *pt = &tex->tex;
505
boolean is_r500 = screen->caps->is_r500;
549
struct pipe_resource *pt = &desc->b.b;
550
boolean is_r500 = screen->caps.is_r500;
552
/* Mask out all the fields we change. */
554
out->format1 &= ~R300_TX_FORMAT_TEX_COORD_TYPE_MASK;
555
out->format2 &= R500_TXFORMAT_MSB;
556
out->tile_config = 0;
507
558
/* Set sampler state. */
508
state->format0 = R300_TX_WIDTH((pt->width0 - 1) & 0x7ff) |
509
R300_TX_HEIGHT((pt->height0 - 1) & 0x7ff);
559
out->format0 = R300_TX_WIDTH((u_minify(pt->width0, level) - 1) & 0x7ff) |
560
R300_TX_HEIGHT((u_minify(pt->height0, level) - 1) & 0x7ff);
562
if (desc->uses_stride_addressing) {
512
563
/* rectangles love this */
513
state->format0 |= R300_TX_PITCH_EN;
514
state->format2 = (tex->pitch[0] - 1) & 0x1fff;
564
out->format0 |= R300_TX_PITCH_EN;
565
out->format2 = (desc->stride_in_pixels[level] - 1) & 0x1fff;
516
/* power of two textures (3D, mipmaps, and no pitch) */
517
state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth0) & 0xf);
567
/* Power of two textures (3D, mipmaps, and no pitch),
568
* also NPOT textures with a width being POT. */
570
R300_TX_DEPTH(util_logbase2(u_minify(pt->depth0, level)) & 0xf);
520
state->format1 = r300_translate_texformat(pt->format);
521
573
if (pt->target == PIPE_TEXTURE_CUBE) {
522
state->format1 |= R300_TX_FORMAT_CUBIC_MAP;
574
out->format1 |= R300_TX_FORMAT_CUBIC_MAP;
524
576
if (pt->target == PIPE_TEXTURE_3D) {
525
state->format1 |= R300_TX_FORMAT_3D;
577
out->format1 |= R300_TX_FORMAT_3D;
528
580
/* large textures on r500 */
531
583
if (pt->width0 > 2048) {
532
state->format2 |= R500_TXWIDTH_BIT11;
584
out->format2 |= R500_TXWIDTH_BIT11;
534
586
if (pt->height0 > 2048) {
535
state->format2 |= R500_TXHEIGHT_BIT11;
587
out->format2 |= R500_TXHEIGHT_BIT11;
539
SCREEN_DBG(screen, DBG_TEX, "r300: Set texture state (%dx%d, %d levels)\n",
540
pt->width0, pt->height0, pt->last_level);
591
out->tile_config = R300_TXO_MACRO_TILE(desc->macrotile[level]) |
592
R300_TXO_MICRO_TILE(desc->microtile);
595
static void r300_texture_setup_fb_state(struct r300_screen* screen,
596
struct r300_texture* tex)
542
600
/* Set framebuffer state. */
543
if (util_format_is_depth_or_stencil(tex->tex.format)) {
544
for (i = 0; i <= tex->tex.last_level; i++) {
545
tex->fb_state.depthpitch[i] =
547
R300_DEPTHMACROTILE(tex->mip_macrotile[i]) |
548
R300_DEPTHMICROTILE(tex->microtile);
601
if (util_format_is_depth_or_stencil(tex->desc.b.b.format)) {
602
for (i = 0; i <= tex->desc.b.b.last_level; i++) {
603
tex->fb_state.pitch[i] =
604
tex->desc.stride_in_pixels[i] |
605
R300_DEPTHMACROTILE(tex->desc.macrotile[i]) |
606
R300_DEPTHMICROTILE(tex->desc.microtile);
550
tex->fb_state.zb_format = r300_translate_zsformat(tex->tex.format);
608
tex->fb_state.format = r300_translate_zsformat(tex->desc.b.b.format);
552
for (i = 0; i <= tex->tex.last_level; i++) {
553
tex->fb_state.colorpitch[i] =
555
r300_translate_colorformat(tex->tex.format) |
556
R300_COLOR_TILE(tex->mip_macrotile[i]) |
557
R300_COLOR_MICROTILE(tex->microtile);
610
for (i = 0; i <= tex->desc.b.b.last_level; i++) {
611
tex->fb_state.pitch[i] =
612
tex->desc.stride_in_pixels[i] |
613
r300_translate_colorformat(tex->desc.b.b.format) |
614
R300_COLOR_TILE(tex->desc.macrotile[i]) |
615
R300_COLOR_MICROTILE(tex->desc.microtile);
559
tex->fb_state.us_out_fmt = r300_translate_out_fmt(tex->tex.format);
617
tex->fb_state.format = r300_translate_out_fmt(tex->desc.b.b.format);
563
621
void r300_texture_reinterpret_format(struct pipe_screen *screen,
564
struct pipe_texture *tex,
622
struct pipe_resource *tex,
565
623
enum pipe_format new_format)
567
625
struct r300_screen *r300screen = r300_screen(screen);
569
SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n",
570
util_format_name(tex->format), util_format_name(new_format));
627
SCREEN_DBG(r300screen, DBG_TEX,
628
"r300: texture_reinterpret_format: %s -> %s\n",
629
util_format_short_name(tex->format),
630
util_format_short_name(new_format));
572
632
tex->format = new_format;
574
r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex);
577
unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level,
578
unsigned zslice, unsigned face)
580
unsigned offset = tex->offset[level];
582
switch (tex->tex.target) {
583
case PIPE_TEXTURE_3D:
585
return offset + zslice * tex->layer_size[level];
587
case PIPE_TEXTURE_CUBE:
589
return offset + face * tex->layer_size[level];
592
assert(zslice == 0 && face == 0);
598
* Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile
599
* of the given texture.
601
static unsigned r300_texture_get_tile_size(struct r300_texture* tex,
602
int dim, boolean macrotile)
604
unsigned pixsize, tile_size;
606
pixsize = util_format_get_blocksize(tex->tex.format);
607
tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim];
617
/* Return true if macrotiling should be enabled on the miplevel. */
618
static boolean r300_texture_macro_switch(struct r300_texture *tex,
622
unsigned tile_width, width;
624
tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE);
625
width = u_minify(tex->tex.width0, level);
627
/* See TX_FILTER1_n.MACRO_SWITCH. */
629
return width >= tile_width;
631
return width > tile_width;
636
* Return the stride, in bytes, of the texture images of the given texture
637
* at the given level.
639
unsigned r300_texture_get_stride(struct r300_screen* screen,
640
struct r300_texture* tex, unsigned level)
642
unsigned tile_width, width;
644
if (tex->stride_override)
645
return tex->stride_override;
647
/* Check the level. */
648
if (level > tex->tex.last_level) {
649
SCREEN_DBG(screen, DBG_TEX, "%s: level (%u) > last_level (%u)\n",
650
__FUNCTION__, level, tex->tex.last_level);
654
width = u_minify(tex->tex.width0, level);
656
if (!util_format_is_compressed(tex->tex.format)) {
657
tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH,
658
tex->mip_macrotile[level]);
659
width = align(width, tile_width);
661
return util_format_get_stride(tex->tex.format, width);
663
return align(util_format_get_stride(tex->tex.format, width), 32);
667
static unsigned r300_texture_get_nblocksy(struct r300_texture* tex,
670
unsigned height, tile_height;
672
height = u_minify(tex->tex.height0, level);
674
if (!util_format_is_compressed(tex->tex.format)) {
675
tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT,
676
tex->mip_macrotile[level]);
677
height = align(height, tile_height);
680
return util_format_get_nblocksy(tex->tex.format, height);
683
static void r300_setup_miptree(struct r300_screen* screen,
684
struct r300_texture* tex)
686
struct pipe_texture* base = &tex->tex;
687
unsigned stride, size, layer_size, nblocksy, i;
688
boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350;
690
SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n",
691
util_format_name(base->format));
693
for (i = 0; i <= base->last_level; i++) {
694
/* Let's see if this miplevel can be macrotiled. */
695
tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED &&
696
r300_texture_macro_switch(tex, i, rv350_mode)) ?
697
R300_BUFFER_TILED : R300_BUFFER_LINEAR;
699
stride = r300_texture_get_stride(screen, tex, i);
700
nblocksy = r300_texture_get_nblocksy(tex, i);
701
layer_size = stride * nblocksy;
703
if (base->target == PIPE_TEXTURE_CUBE)
704
size = layer_size * 6;
706
size = layer_size * u_minify(base->depth0, i);
708
tex->offset[i] = tex->size;
709
tex->size = tex->offset[i] + size;
710
tex->layer_size[i] = layer_size;
711
tex->pitch[i] = stride / util_format_get_blocksize(base->format);
713
SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d "
714
"(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n",
715
i, u_minify(base->width0, i), u_minify(base->height0, i),
716
u_minify(base->depth0, i), stride, tex->size,
717
tex->mip_macrotile[i] ? "TRUE" : "FALSE");
721
static void r300_setup_flags(struct r300_texture* tex)
723
tex->is_npot = !util_is_power_of_two(tex->tex.width0) ||
724
!util_is_power_of_two(tex->tex.height0);
634
r300_texture_setup_fb_state(r300_screen(screen), r300_texture(tex));
637
static unsigned r300_texture_is_referenced(struct pipe_context *context,
638
struct pipe_resource *texture,
639
unsigned face, unsigned level)
641
struct r300_context *r300 = r300_context(context);
642
struct r300_texture *rtex = (struct r300_texture *)texture;
644
if (r300->rws->cs_is_buffer_referenced(r300->cs,
645
rtex->buffer, R300_REF_CS))
646
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
648
return PIPE_UNREFERENCED;
651
static void r300_texture_destroy(struct pipe_screen *screen,
652
struct pipe_resource* texture)
654
struct r300_texture* tex = (struct r300_texture*)texture;
655
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)texture->screen->winsys;
658
rws->buffer_reference(rws, &tex->buffer, NULL);
659
for (i = 0; i < R300_MAX_TEXTURE_LEVELS; i++) {
661
u_mmFreeMem(tex->hiz_mem[i]);
662
if (tex->zmask_mem[i])
663
u_mmFreeMem(tex->zmask_mem[i]);
669
static boolean r300_texture_get_handle(struct pipe_screen* screen,
670
struct pipe_resource *texture,
671
struct winsys_handle *whandle)
673
struct r300_winsys_screen *rws = (struct r300_winsys_screen *)screen->winsys;
674
struct r300_texture* tex = (struct r300_texture*)texture;
680
return rws->buffer_get_handle(rws, tex->buffer,
681
tex->desc.stride_in_bytes[0], whandle);
684
struct u_resource_vtbl r300_texture_vtbl =
686
r300_texture_get_handle, /* get_handle */
687
r300_texture_destroy, /* resource_destroy */
688
r300_texture_is_referenced, /* is_resource_referenced */
689
r300_texture_get_transfer, /* get_transfer */
690
r300_texture_transfer_destroy, /* transfer_destroy */
691
r300_texture_transfer_map, /* transfer_map */
692
u_default_transfer_flush_region, /* transfer_flush_region */
693
r300_texture_transfer_unmap, /* transfer_unmap */
694
u_default_transfer_inline_write /* transfer_inline_write */
697
/* The common texture constructor. */
698
static struct r300_texture*
699
r300_texture_create_object(struct r300_screen *rscreen,
700
const struct pipe_resource *base,
701
enum r300_buffer_tiling microtile,
702
enum r300_buffer_tiling macrotile,
703
unsigned stride_in_bytes_override,
704
unsigned max_buffer_size,
705
struct r300_winsys_buffer *buffer)
707
struct r300_winsys_screen *rws = rscreen->rws;
708
struct r300_texture *tex = CALLOC_STRUCT(r300_texture);
711
rws->buffer_reference(rws, &buffer, NULL);
715
/* Initialize the descriptor. */
716
if (!r300_texture_desc_init(rscreen, &tex->desc, base,
717
microtile, macrotile,
718
stride_in_bytes_override,
721
rws->buffer_reference(rws, &buffer, NULL);
725
/* Initialize the hardware state. */
726
r300_texture_setup_format_state(rscreen, &tex->desc, 0, &tex->tx_format);
727
r300_texture_setup_fb_state(rscreen, tex);
729
tex->desc.b.vtbl = &r300_texture_vtbl;
730
pipe_reference_init(&tex->desc.b.b.reference, 1);
731
tex->domain = base->flags & R300_RESOURCE_FLAG_TRANSFER ?
733
R300_DOMAIN_VRAM | R300_DOMAIN_GTT;
734
tex->buffer = buffer;
736
/* Create the backing buffer if needed. */
738
tex->buffer = rws->buffer_create(rws, tex->desc.size_in_bytes, 2048,
739
base->bind, base->usage, tex->domain);
747
rws->buffer_set_tiling(rws, tex->buffer,
748
tex->desc.microtile, tex->desc.macrotile[0],
749
tex->desc.stride_in_bytes[0]);
727
754
/* Create a new texture. */
728
static struct pipe_texture*
729
r300_texture_create(struct pipe_screen* screen,
730
const struct pipe_texture* template)
732
struct r300_texture* tex = CALLOC_STRUCT(r300_texture);
733
struct r300_screen* rscreen = r300_screen(screen);
734
struct radeon_winsys* winsys = (struct radeon_winsys*)screen->winsys;
740
tex->tex = *template;
741
pipe_reference_init(&tex->tex.reference, 1);
742
tex->tex.screen = screen;
744
r300_setup_flags(tex);
745
r300_setup_miptree(rscreen, tex);
746
r300_setup_texture_state(rscreen, tex);
748
tex->buffer = screen->buffer_create(screen, 2048,
749
PIPE_BUFFER_USAGE_PIXEL,
751
winsys->buffer_set_tiling(winsys, tex->buffer,
753
tex->microtile != R300_BUFFER_LINEAR,
754
tex->macrotile != R300_BUFFER_LINEAR);
761
return (struct pipe_texture*)tex;
764
static void r300_texture_destroy(struct pipe_texture* texture)
766
struct r300_texture* tex = (struct r300_texture*)texture;
768
pipe_buffer_reference(&tex->buffer, NULL);
773
static struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
774
struct pipe_texture* texture,
780
struct r300_texture* tex = (struct r300_texture*)texture;
781
struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface);
784
offset = r300_texture_get_offset(tex, level, zslice, face);
787
pipe_reference_init(&surface->reference, 1);
788
pipe_texture_reference(&surface->texture, texture);
789
surface->format = texture->format;
790
surface->width = u_minify(texture->width0, level);
791
surface->height = u_minify(texture->height0, level);
792
surface->offset = offset;
793
surface->usage = flags;
794
surface->zslice = zslice;
795
surface->texture = texture;
796
surface->face = face;
797
surface->level = level;
803
static void r300_tex_surface_destroy(struct pipe_surface* s)
805
pipe_texture_reference(&s->texture, NULL);
809
static struct pipe_texture*
810
r300_texture_blanket(struct pipe_screen* screen,
811
const struct pipe_texture* base,
812
const unsigned* stride,
813
struct pipe_buffer* buffer)
815
struct r300_texture* tex;
816
struct r300_screen* rscreen = r300_screen(screen);
755
struct pipe_resource *r300_texture_create(struct pipe_screen *screen,
756
const struct pipe_resource *base)
758
struct r300_screen *rscreen = r300_screen(screen);
759
enum r300_buffer_tiling microtile, macrotile;
761
if ((base->flags & R300_RESOURCE_FLAG_TRANSFER) ||
762
(base->bind & PIPE_BIND_SCANOUT)) {
763
microtile = R300_BUFFER_LINEAR;
764
macrotile = R300_BUFFER_LINEAR;
766
microtile = R300_BUFFER_SELECT_LAYOUT;
767
macrotile = R300_BUFFER_SELECT_LAYOUT;
770
return (struct pipe_resource*)
771
r300_texture_create_object(rscreen, base, microtile, macrotile,
775
struct pipe_resource *r300_texture_from_handle(struct pipe_screen *screen,
776
const struct pipe_resource *base,
777
struct winsys_handle *whandle)
779
struct r300_winsys_screen *rws = (struct r300_winsys_screen*)screen->winsys;
780
struct r300_screen *rscreen = r300_screen(screen);
781
struct r300_winsys_buffer *buffer;
782
enum r300_buffer_tiling microtile, macrotile;
783
unsigned stride, size;
818
785
/* Support only 2D textures without mipmaps */
819
if (base->target != PIPE_TEXTURE_2D ||
786
if ((base->target != PIPE_TEXTURE_2D &&
787
base->target != PIPE_TEXTURE_RECT) ||
820
788
base->depth0 != 1 ||
821
789
base->last_level != 0) {
825
tex = CALLOC_STRUCT(r300_texture);
831
pipe_reference_init(&tex->tex.reference, 1);
832
tex->tex.screen = screen;
834
tex->stride_override = *stride;
835
tex->pitch[0] = *stride / util_format_get_blocksize(base->format);
837
r300_setup_flags(tex);
838
r300_setup_texture_state(rscreen, tex);
840
pipe_buffer_reference(&tex->buffer, buffer);
842
return (struct pipe_texture*)tex;
845
static struct pipe_video_surface *
846
r300_video_surface_create(struct pipe_screen *screen,
847
enum pipe_video_chroma_format chroma_format,
848
unsigned width, unsigned height)
850
struct r300_video_surface *r300_vsfc;
851
struct pipe_texture template;
854
assert(width && height);
856
r300_vsfc = CALLOC_STRUCT(r300_video_surface);
860
pipe_reference_init(&r300_vsfc->base.reference, 1);
861
r300_vsfc->base.screen = screen;
862
r300_vsfc->base.chroma_format = chroma_format;
863
r300_vsfc->base.width = width;
864
r300_vsfc->base.height = height;
866
memset(&template, 0, sizeof(struct pipe_texture));
867
template.target = PIPE_TEXTURE_2D;
868
template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
869
template.last_level = 0;
870
template.width0 = util_next_power_of_two(width);
871
template.height0 = util_next_power_of_two(height);
873
template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER |
874
PIPE_TEXTURE_USAGE_RENDER_TARGET;
876
r300_vsfc->tex = screen->texture_create(screen, &template);
883
return &r300_vsfc->base;
886
static void r300_video_surface_destroy(struct pipe_video_surface *vsfc)
888
struct r300_video_surface *r300_vsfc = r300_video_surface(vsfc);
889
pipe_texture_reference(&r300_vsfc->tex, NULL);
893
void r300_init_screen_texture_functions(struct pipe_screen* screen)
895
screen->texture_create = r300_texture_create;
896
screen->texture_destroy = r300_texture_destroy;
897
screen->get_tex_surface = r300_get_tex_surface;
898
screen->tex_surface_destroy = r300_tex_surface_destroy;
899
screen->texture_blanket = r300_texture_blanket;
901
screen->video_surface_create = r300_video_surface_create;
902
screen->video_surface_destroy= r300_video_surface_destroy;
905
boolean r300_get_texture_buffer(struct pipe_screen* screen,
906
struct pipe_texture* texture,
907
struct pipe_buffer** buffer,
910
struct r300_texture* tex = (struct r300_texture*)texture;
915
pipe_buffer_reference(buffer, tex->buffer);
918
*stride = r300_texture_get_stride(r300_screen(screen), tex, 0);
793
buffer = rws->buffer_from_handle(rws, whandle, &stride, &size);
797
rws->buffer_get_tiling(rws, buffer, µtile, ¯otile);
799
/* Enforce a microtiled zbuffer. */
800
if (util_format_is_depth_or_stencil(base->format) &&
801
microtile == R300_BUFFER_LINEAR) {
802
switch (util_format_get_blocksize(base->format)) {
804
microtile = R300_BUFFER_TILED;
808
if (rws->get_value(rws, R300_VID_SQUARE_TILING_SUPPORT))
809
microtile = R300_BUFFER_SQUARETILED;
814
return (struct pipe_resource*)
815
r300_texture_create_object(rscreen, base, microtile, macrotile,
816
stride, size, buffer);
819
/* Not required to implement u_resource_vtbl, consider moving to another file:
821
struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen,
822
struct pipe_resource* texture,
828
struct r300_texture* tex = r300_texture(texture);
829
struct r300_surface* surface = CALLOC_STRUCT(r300_surface);
832
uint32_t offset, tile_height;
834
pipe_reference_init(&surface->base.reference, 1);
835
pipe_resource_reference(&surface->base.texture, texture);
836
surface->base.format = texture->format;
837
surface->base.width = u_minify(texture->width0, level);
838
surface->base.height = u_minify(texture->height0, level);
839
surface->base.usage = flags;
840
surface->base.zslice = zslice;
841
surface->base.face = face;
842
surface->base.level = level;
844
surface->buffer = tex->buffer;
846
/* Prefer VRAM if there are multiple domains to choose from. */
847
surface->domain = tex->domain;
848
if (surface->domain & R300_DOMAIN_VRAM)
849
surface->domain &= ~R300_DOMAIN_GTT;
851
surface->offset = r300_texture_get_offset(&tex->desc,
852
level, zslice, face);
853
surface->pitch = tex->fb_state.pitch[level];
854
surface->format = tex->fb_state.format;
856
/* Parameters for the CBZB clear. */
857
surface->cbzb_allowed = tex->desc.cbzb_allowed[level];
858
surface->cbzb_width = align(surface->base.width, 64);
860
/* Height must be aligned to the size of a tile. */
861
tile_height = r300_get_pixel_alignment(tex->desc.b.b.format,
862
tex->desc.b.b.nr_samples,
864
tex->desc.macrotile[level],
867
surface->cbzb_height = align((surface->base.height + 1) / 2,
870
/* Offset must be aligned to 2K and must point at the beginning
872
offset = surface->offset +
873
tex->desc.stride_in_bytes[level] * surface->cbzb_height;
874
surface->cbzb_midpoint_offset = offset & ~2047;
876
surface->cbzb_pitch = surface->pitch & 0x1ffffc;
878
if (util_format_get_blocksizebits(surface->base.format) == 32)
879
surface->cbzb_format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
881
surface->cbzb_format = R300_DEPTHFORMAT_16BIT_INT_Z;
883
SCREEN_DBG(r300_screen(screen), DBG_CBZB,
884
"CBZB Dim: %ix%i, Misalignment: %i, Macro: %s\n",
885
surface->cbzb_width, surface->cbzb_height,
887
tex->desc.macrotile[level] ? "YES" : " NO");
890
return &surface->base;
893
/* Not required to implement u_resource_vtbl, consider moving to another file:
895
void r300_tex_surface_destroy(struct pipe_surface* s)
897
pipe_resource_reference(&s->texture, NULL);