Commit d785d78b authored by Dave Airlie's avatar Dave Airlie

drm/radeon/kms: fix r100->r500 CS checker for compressed textures. (v2)

This adds support for compressed textures to the r100->r500 CS
checker, it lets me run openarena and the demos in mesa fine.

Thanks to Maciej Cencora for initial comments.

Changes since v1:
fix calculations with Maciej formulas
Reviewed-by: default avatarMaciej Cencora <m.cencora@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 6e726772
...@@ -1374,7 +1374,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ...@@ -1374,7 +1374,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
case RADEON_TXFORMAT_ARGB4444: case RADEON_TXFORMAT_ARGB4444:
case RADEON_TXFORMAT_VYUY422: case RADEON_TXFORMAT_VYUY422:
case RADEON_TXFORMAT_YVYU422: case RADEON_TXFORMAT_YVYU422:
case RADEON_TXFORMAT_DXT1:
case RADEON_TXFORMAT_SHADOW16: case RADEON_TXFORMAT_SHADOW16:
case RADEON_TXFORMAT_LDUDV655: case RADEON_TXFORMAT_LDUDV655:
case RADEON_TXFORMAT_DUDV88: case RADEON_TXFORMAT_DUDV88:
...@@ -1382,12 +1381,19 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ...@@ -1382,12 +1381,19 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
break; break;
case RADEON_TXFORMAT_ARGB8888: case RADEON_TXFORMAT_ARGB8888:
case RADEON_TXFORMAT_RGBA8888: case RADEON_TXFORMAT_RGBA8888:
case RADEON_TXFORMAT_DXT23:
case RADEON_TXFORMAT_DXT45:
case RADEON_TXFORMAT_SHADOW32: case RADEON_TXFORMAT_SHADOW32:
case RADEON_TXFORMAT_LDUDUV8888: case RADEON_TXFORMAT_LDUDUV8888:
track->textures[i].cpp = 4; track->textures[i].cpp = 4;
break; break;
case RADEON_TXFORMAT_DXT1:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break;
case RADEON_TXFORMAT_DXT23:
case RADEON_TXFORMAT_DXT45:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
break;
} }
track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
...@@ -2731,6 +2737,7 @@ static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) ...@@ -2731,6 +2737,7 @@ static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
DRM_ERROR("coordinate type %d\n", t->tex_coord_type); DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
DRM_ERROR("compress format %d\n", t->compress_format);
} }
static int r100_cs_track_cube(struct radeon_device *rdev, static int r100_cs_track_cube(struct radeon_device *rdev,
...@@ -2760,6 +2767,36 @@ static int r100_cs_track_cube(struct radeon_device *rdev, ...@@ -2760,6 +2767,36 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
return 0; return 0;
} }
static int r100_track_compress_size(int compress_format, int w, int h)
{
int block_width, block_height, block_bytes;
int wblocks, hblocks;
int min_wblocks;
int sz;
block_width = 4;
block_height = 4;
switch (compress_format) {
case R100_TRACK_COMP_DXT1:
block_bytes = 8;
min_wblocks = 4;
break;
default:
case R100_TRACK_COMP_DXT35:
block_bytes = 16;
min_wblocks = 2;
break;
}
hblocks = (h + block_height - 1) / block_height;
wblocks = (w + block_width - 1) / block_width;
if (wblocks < min_wblocks)
wblocks = min_wblocks;
sz = wblocks * hblocks * block_bytes;
return sz;
}
static int r100_cs_track_texture_check(struct radeon_device *rdev, static int r100_cs_track_texture_check(struct radeon_device *rdev,
struct r100_cs_track *track) struct r100_cs_track *track)
{ {
...@@ -2797,9 +2834,15 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, ...@@ -2797,9 +2834,15 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
h = h / (1 << i); h = h / (1 << i);
if (track->textures[u].roundup_h) if (track->textures[u].roundup_h)
h = roundup_pow_of_two(h); h = roundup_pow_of_two(h);
if (track->textures[u].compress_format) {
size += r100_track_compress_size(track->textures[u].compress_format, w, h);
/* compressed textures are block based */
} else
size += w * h; size += w * h;
} }
size *= track->textures[u].cpp; size *= track->textures[u].cpp;
switch (track->textures[u].tex_coord_type) { switch (track->textures[u].tex_coord_type) {
case 0: case 0:
break; break;
...@@ -2967,6 +3010,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track ...@@ -2967,6 +3010,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track->arrays[i].esize = 0x7F; track->arrays[i].esize = 0x7F;
} }
for (i = 0; i < track->num_texture; i++) { for (i = 0; i < track->num_texture; i++) {
track->textures[i].compress_format = R100_TRACK_COMP_NONE;
track->textures[i].pitch = 16536; track->textures[i].pitch = 16536;
track->textures[i].width = 16536; track->textures[i].width = 16536;
track->textures[i].height = 16536; track->textures[i].height = 16536;
......
...@@ -28,6 +28,10 @@ struct r100_cs_cube_info { ...@@ -28,6 +28,10 @@ struct r100_cs_cube_info {
unsigned height; unsigned height;
}; };
#define R100_TRACK_COMP_NONE 0
#define R100_TRACK_COMP_DXT1 1
#define R100_TRACK_COMP_DXT35 2
struct r100_cs_track_texture { struct r100_cs_track_texture {
struct radeon_bo *robj; struct radeon_bo *robj;
struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
...@@ -44,6 +48,7 @@ struct r100_cs_track_texture { ...@@ -44,6 +48,7 @@ struct r100_cs_track_texture {
bool enabled; bool enabled;
bool roundup_w; bool roundup_w;
bool roundup_h; bool roundup_h;
unsigned compress_format;
}; };
struct r100_cs_track_limits { struct r100_cs_track_limits {
......
...@@ -401,7 +401,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, ...@@ -401,7 +401,6 @@ int r200_packet0_check(struct radeon_cs_parser *p,
case R200_TXFORMAT_Y8: case R200_TXFORMAT_Y8:
track->textures[i].cpp = 1; track->textures[i].cpp = 1;
break; break;
case R200_TXFORMAT_DXT1:
case R200_TXFORMAT_AI88: case R200_TXFORMAT_AI88:
case R200_TXFORMAT_ARGB1555: case R200_TXFORMAT_ARGB1555:
case R200_TXFORMAT_RGB565: case R200_TXFORMAT_RGB565:
...@@ -418,9 +417,16 @@ int r200_packet0_check(struct radeon_cs_parser *p, ...@@ -418,9 +417,16 @@ int r200_packet0_check(struct radeon_cs_parser *p,
case R200_TXFORMAT_ABGR8888: case R200_TXFORMAT_ABGR8888:
case R200_TXFORMAT_BGR111110: case R200_TXFORMAT_BGR111110:
case R200_TXFORMAT_LDVDU8888: case R200_TXFORMAT_LDVDU8888:
track->textures[i].cpp = 4;
break;
case R200_TXFORMAT_DXT1:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break;
case R200_TXFORMAT_DXT23: case R200_TXFORMAT_DXT23:
case R200_TXFORMAT_DXT45: case R200_TXFORMAT_DXT45:
track->textures[i].cpp = 4; track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break; break;
} }
track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
......
...@@ -860,7 +860,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -860,7 +860,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case R300_TX_FORMAT_Z6Y5X5: case R300_TX_FORMAT_Z6Y5X5:
case R300_TX_FORMAT_W4Z4Y4X4: case R300_TX_FORMAT_W4Z4Y4X4:
case R300_TX_FORMAT_W1Z5Y5X5: case R300_TX_FORMAT_W1Z5Y5X5:
case R300_TX_FORMAT_DXT1:
case R300_TX_FORMAT_D3DMFT_CxV8U8: case R300_TX_FORMAT_D3DMFT_CxV8U8:
case R300_TX_FORMAT_B8G8_B8G8: case R300_TX_FORMAT_B8G8_B8G8:
case R300_TX_FORMAT_G8R8_G8B8: case R300_TX_FORMAT_G8R8_G8B8:
...@@ -874,8 +873,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -874,8 +873,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case 0x17: case 0x17:
case R300_TX_FORMAT_FL_I32: case R300_TX_FORMAT_FL_I32:
case 0x1e: case 0x1e:
case R300_TX_FORMAT_DXT3:
case R300_TX_FORMAT_DXT5:
track->textures[i].cpp = 4; track->textures[i].cpp = 4;
break; break;
case R300_TX_FORMAT_W16Z16Y16X16: case R300_TX_FORMAT_W16Z16Y16X16:
...@@ -886,6 +883,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -886,6 +883,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case R300_TX_FORMAT_FL_R32G32B32A32: case R300_TX_FORMAT_FL_R32G32B32A32:
track->textures[i].cpp = 16; track->textures[i].cpp = 16;
break; break;
case R300_TX_FORMAT_DXT1:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break;
case R300_TX_FORMAT_DXT3:
case R300_TX_FORMAT_DXT5:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
break;
default: default:
DRM_ERROR("Invalid texture format %u\n", DRM_ERROR("Invalid texture format %u\n",
(idx_value & 0x1F)); (idx_value & 0x1F));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment