r300_texture.c revision 63c9450ae776ff4207422442dd8c3d9d13a05e7a
10648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson/* 20648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com> 30648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * 40648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * Permission is hereby granted, free of charge, to any person obtaining a 50648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * copy of this software and associated documentation files (the "Software"), 60648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * to deal in the Software without restriction, including without limitation 70648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * on the rights to use, copy, modify, merge, publish, distribute, sub 80648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * license, and/or sell copies of the Software, and to permit persons to whom 90648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * the Software is furnished to do so, subject to the following conditions: 100648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * 110648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * The above copyright notice and this permission notice (including the next 120648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * paragraph) shall be included in all copies or substantial portions of the 130648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * Software. 140648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * 150648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 160648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 170648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 180648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 190648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 200648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 210648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 220648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson 236a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "pipe/p_screen.h" 246a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson 256a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "util/u_math.h" 266a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "util/u_memory.h" 276a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson 286a448a525baf81173f92ee8c3074b98baa54397bCorbin Simpson#include "r300_context.h" 290648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson#include "r300_texture.h" 30827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák#include "r300_screen.h" 310648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson 32827002f5ff990f8676385583275d6b8090abfb7aMarek Olšákstatic void r300_setup_texture_state(struct r300_texture* tex, boolean is_r500) 339d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson{ 349d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson struct r300_texture_state* state = &tex->state; 359bf85f6b95cb684d16b6035381b1f8a9c44f473fDave Airlie struct pipe_texture *pt = &tex->tex; 369d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson 379bf85f6b95cb684d16b6035381b1f8a9c44f473fDave Airlie state->format0 = R300_TX_WIDTH((pt->width[0] - 1) & 0x7ff) | 38827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák R300_TX_HEIGHT((pt->height[0] - 1) & 0x7ff); 39827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák 4063c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák if (tex->is_npot) { 41827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák /* rectangles love this */ 42827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák state->format0 |= R300_TX_PITCH_EN; 4363c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák state->format2 = (tex->pitch[0] - 1) & 0x1fff; 4463c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák } else { 45827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák /* power of two textures (3D, mipmaps, and no pitch) */ 46827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák state->format0 |= R300_TX_DEPTH(util_logbase2(pt->depth[0]) & 0xf) | 47827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák R300_TX_NUM_LEVELS(pt->last_level & 0xf); 48827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák } 499d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson 509bf85f6b95cb684d16b6035381b1f8a9c44f473fDave Airlie state->format1 = r300_translate_texformat(pt->format); 51eb5dd947fbed35478784e777fe2e59564fee051bDave Airlie if (pt->target == PIPE_TEXTURE_CUBE) { 52034db65f08b943ee9940947db69e4e190f751061Corbin Simpson state->format1 |= R300_TX_FORMAT_CUBIC_MAP; 53eb5dd947fbed35478784e777fe2e59564fee051bDave Airlie } 54eb5dd947fbed35478784e777fe2e59564fee051bDave Airlie if (pt->target == PIPE_TEXTURE_3D) { 55034db65f08b943ee9940947db69e4e190f751061Corbin Simpson state->format1 |= R300_TX_FORMAT_3D; 56eb5dd947fbed35478784e777fe2e59564fee051bDave Airlie } 579d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson 58827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák /* large textures on r500 */ 59827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák if (is_r500) 60827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák { 61827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák if (pt->width[0] > 2048) { 62827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák state->format2 |= R500_TXWIDTH_BIT11; 63827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák } 64827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák if (pt->height[0] > 2048) { 65827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák state->format2 |= R500_TXHEIGHT_BIT11; 66827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák } 671aa38b2c2d80b67fe2eefe468f90aeb44bc20259Corbin Simpson } 68827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák assert(is_r500 || (pt->width[0] <= 2048 && pt->height[0] <= 2048)); 692cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson 709ca94f91a3b48350b02a8fec5ecf60a819a24de5Nicolai Hähnle debug_printf("r300: Set texture state (%dx%d, %d levels)\n", 719bf85f6b95cb684d16b6035381b1f8a9c44f473fDave Airlie pt->width[0], pt->height[0], pt->last_level); 723cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle} 733cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle 74118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšákunsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, 75118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák unsigned zslice, unsigned face) 76118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák{ 77118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák unsigned offset = tex->offset[level]; 78118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák 79118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák switch (tex->tex.target) { 80118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák case PIPE_TEXTURE_3D: 81118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák assert(face == 0); 82118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák return offset + zslice * tex->layer_size[level]; 83118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák 84118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák case PIPE_TEXTURE_CUBE: 85118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák assert(zslice == 0); 86118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák return offset + face * tex->layer_size[level]; 87118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák 88118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák default: 89118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák assert(zslice == 0 && face == 0); 90118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák return offset; 91118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák } 92118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák} 93118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák 943cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle/** 953cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle * Return the stride, in bytes, of the texture images of the given texture 963cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle * at the given level. 973cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle */ 983cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnleunsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level) 993cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle{ 1003cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle if (tex->stride_override) 1013cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle return tex->stride_override; 1023cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle 1033cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle if (level > tex->tex.last_level) { 104034db65f08b943ee9940947db69e4e190f751061Corbin Simpson debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, 105034db65f08b943ee9940947db69e4e190f751061Corbin Simpson level, tex->tex.last_level); 1063cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle return 0; 1073cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle } 1083cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle 1093cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle return align(pf_get_stride(&tex->tex.block, tex->tex.width[level]), 32); 1109d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson} 1119d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson 1128e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpsonstatic void r300_setup_miptree(struct r300_texture* tex) 1138e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson{ 1148e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson struct pipe_texture* base = &tex->tex; 115118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák int stride, size, layer_size; 1162b5770e652f0e6620b52971755bd7eb31c16ad7dCorbin Simpson int i; 1178e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1182b5770e652f0e6620b52971755bd7eb31c16ad7dCorbin Simpson for (i = 0; i <= base->last_level; i++) { 1198e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson if (i > 0) { 1208e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson base->width[i] = minify(base->width[i-1]); 1218e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson base->height[i] = minify(base->height[i-1]); 1228e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson base->depth[i] = minify(base->depth[i-1]); 1238e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson } 1248e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1258e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]); 1262cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]); 1278e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1283cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle stride = r300_texture_get_stride(tex, i); 129118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák layer_size = stride * base->nblocksy[i]; 130827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák 131827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák if (base->target == PIPE_TEXTURE_CUBE) 132827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák size = layer_size * 6; 133827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák else 134827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák size = layer_size * base->depth[i]; 1358e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1362cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson tex->offset[i] = align(tex->size, 32); 137048f988aeb06fa360c6c41eaa50cb96b4b86e34eMichel Dänzer tex->size = tex->offset[i] + size; 138118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák tex->layer_size[i] = layer_size; 1397c204c975381b0ef4a7693827ffc4ff904de991cCorbin Simpson 14063c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák if (tex->is_npot) { 14163c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák tex->pitch[i] = stride / base->block.size; 14263c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák } else { 14363c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák tex->pitch[i] = base->width[i]; 14463c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák } 14563c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák 1462cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson debug_printf("r300: Texture miptree: Level %d " 1472cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson "(%dx%dx%d px, pitch %d bytes)\n", 1482cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson i, base->width[i], base->height[i], base->depth[i], 1492cbd5ecfb666a757c4abef85dbe40fb53d647ec9Corbin Simpson stride); 1508e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson } 1518e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson} 1528e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 15363c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšákstatic void r300_setup_flags(struct r300_texture* tex) 15463c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák{ 15563c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák tex->is_npot = !util_is_power_of_two(tex->tex.width[0]) || 15663c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák !util_is_power_of_two(tex->tex.height[0]); 15763c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák} 15863c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák 1590648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson/* Create a new texture. */ 1600648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpsonstatic struct pipe_texture* 1610648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson r300_texture_create(struct pipe_screen* screen, 1620648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson const struct pipe_texture* template) 1630648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson{ 1648e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson struct r300_texture* tex = CALLOC_STRUCT(r300_texture); 1658e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1668e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson if (!tex) { 1678e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson return NULL; 1688e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson } 1698e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1708e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson tex->tex = *template; 1715e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_reference_init(&tex->tex.reference, 1); 1728e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson tex->tex.screen = screen; 1738e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 17463c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák r300_setup_flags(tex); 1758e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson r300_setup_miptree(tex); 176827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); 1779d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson 1787a10472f095ef0f9f6109ca17d8be16836e56509Corbin Simpson tex->buffer = screen->buffer_create(screen, 1024, 179ce6710e369d3b5c512ba8b315efc863fd41de734Corbin Simpson PIPE_BUFFER_USAGE_PIXEL, 180ce6710e369d3b5c512ba8b315efc863fd41de734Corbin Simpson tex->size); 1818e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1828e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson if (!tex->buffer) { 1838e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson FREE(tex); 1848e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson return NULL; 1858e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson } 1868e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1878e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson return (struct pipe_texture*)tex; 1888e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson} 1898e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1905e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzerstatic void r300_texture_destroy(struct pipe_texture* texture) 1918e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson{ 1925e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer struct r300_texture* tex = (struct r300_texture*)texture; 1938e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1945e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_buffer_reference(&tex->buffer, NULL); 1958e11e0121466efa34cfc14d299b43455a30b198cCorbin Simpson 1965e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer FREE(tex); 1970648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson} 1980648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson 199471129c7a14fb585ede198970e59270c4afa5310Corbin Simpsonstatic struct pipe_surface* r300_get_tex_surface(struct pipe_screen* screen, 200471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson struct pipe_texture* texture, 201471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson unsigned face, 202471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson unsigned level, 203471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson unsigned zslice, 204471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson unsigned flags) 205471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson{ 206471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson struct r300_texture* tex = (struct r300_texture*)texture; 207471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson struct pipe_surface* surface = CALLOC_STRUCT(pipe_surface); 208471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson unsigned offset; 209471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson 210118dfe16887d1ec4d3b96d49b76fffa0d2924132Marek Olšák offset = r300_texture_get_offset(tex, level, zslice, face); 211471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson 212471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson if (surface) { 2135e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_reference_init(&surface->reference, 1); 214471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson pipe_texture_reference(&surface->texture, texture); 215471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson surface->format = texture->format; 216471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson surface->width = texture->width[level]; 217471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson surface->height = texture->height[level]; 218471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson surface->offset = offset; 219471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson surface->usage = flags; 220c2df759cd73e281c4698c717e0ab89757a7affd5Marek Olšák surface->zslice = zslice; 221c2df759cd73e281c4698c717e0ab89757a7affd5Marek Olšák surface->texture = texture; 222c2df759cd73e281c4698c717e0ab89757a7affd5Marek Olšák surface->face = face; 223c2df759cd73e281c4698c717e0ab89757a7affd5Marek Olšák surface->level = level; 224471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson } 225471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson 226471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson return surface; 227471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson} 228471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson 2295e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzerstatic void r300_tex_surface_destroy(struct pipe_surface* s) 230471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson{ 2315e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_texture_reference(&s->texture, NULL); 2325e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer FREE(s); 233471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson} 234471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson 2351a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpsonstatic struct pipe_texture* 2361a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson r300_texture_blanket(struct pipe_screen* screen, 2371a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson const struct pipe_texture* base, 2381a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson const unsigned* stride, 2391a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson struct pipe_buffer* buffer) 2401a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson{ 2411a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson struct r300_texture* tex; 2421a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson 24363c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák /* Support only 2D textures without mipmaps */ 24463c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák if (base->target != PIPE_TEXTURE_2D || 24563c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák base->depth[0] != 1 || 24663c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák base->last_level != 0) { 24763c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák return NULL; 24863c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák } 24963c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák 2501a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson tex = CALLOC_STRUCT(r300_texture); 2511a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson if (!tex) { 2521a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson return NULL; 2531a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson } 2541a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson 2551a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson tex->tex = *base; 2565e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_reference_init(&tex->tex.reference, 1); 2571a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson tex->tex.screen = screen; 2581a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson 2593cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle tex->stride_override = *stride; 26063c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák tex->pitch[0] = *stride / base->block.size; 2611a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson 26263c9450ae776ff4207422442dd8c3d9d13a05e7aMarek Olšák r300_setup_flags(tex); 263827002f5ff990f8676385583275d6b8090abfb7aMarek Olšák r300_setup_texture_state(tex, r300_screen(screen)->caps->is_r500); 2649d9e0815be41fa72ff5df6752b02551b648b33b6Corbin Simpson 2655e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_buffer_reference(&tex->buffer, buffer); 2665425c4aa28721072085f128e902f5679ba31a963Corbin Simpson 2671a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson return (struct pipe_texture*)tex; 2681a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson} 2691a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson 270a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuanstatic struct pipe_video_surface * 271a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuanr300_video_surface_create(struct pipe_screen *screen, 272a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan enum pipe_video_chroma_format chroma_format, 273a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan unsigned width, unsigned height) 274a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan{ 275a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan struct r300_video_surface *r300_vsfc; 276a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan struct pipe_texture template; 277a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 278a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan assert(screen); 279a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan assert(width && height); 280a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 281a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan r300_vsfc = CALLOC_STRUCT(r300_video_surface); 282a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan if (!r300_vsfc) 283a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan return NULL; 284a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 285a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan pipe_reference_init(&r300_vsfc->base.reference, 1); 286a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan r300_vsfc->base.screen = screen; 287a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan r300_vsfc->base.chroma_format = chroma_format; 288a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan r300_vsfc->base.width = width; 289a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan r300_vsfc->base.height = height; 290a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 291a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan memset(&template, 0, sizeof(struct pipe_texture)); 292a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.target = PIPE_TEXTURE_2D; 293a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.format = PIPE_FORMAT_X8R8G8B8_UNORM; 294a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.last_level = 0; 295a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.width[0] = util_next_power_of_two(width); 296a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.height[0] = util_next_power_of_two(height); 297a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.depth[0] = 1; 298a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan pf_get_block(template.format, &template.block); 299a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER | 300a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan PIPE_TEXTURE_USAGE_RENDER_TARGET; 301a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 302a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan r300_vsfc->tex = screen->texture_create(screen, &template); 303a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan if (!r300_vsfc->tex) 304a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan { 305a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan FREE(r300_vsfc); 306a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan return NULL; 307a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan } 308a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 309a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan return &r300_vsfc->base; 310a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan} 311a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 312a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuanstatic void r300_video_surface_destroy(struct pipe_video_surface *vsfc) 313a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan{ 314a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan struct r300_video_surface *r300_vsfc = r300_video_surface(vsfc); 315a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan pipe_texture_reference(&r300_vsfc->tex, NULL); 316a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan FREE(r300_vsfc); 317a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan} 318a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 3190648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpsonvoid r300_init_screen_texture_functions(struct pipe_screen* screen) 3200648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson{ 3210648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson screen->texture_create = r300_texture_create; 3225e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer screen->texture_destroy = r300_texture_destroy; 323471129c7a14fb585ede198970e59270c4afa5310Corbin Simpson screen->get_tex_surface = r300_get_tex_surface; 3245e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer screen->tex_surface_destroy = r300_tex_surface_destroy; 3251a5eea0c1e9ce6162ed6b07c337bffe62cb3c221Corbin Simpson screen->texture_blanket = r300_texture_blanket; 326a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan 327a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan screen->video_surface_create = r300_video_surface_create; 328a74e53ddba246b1f6604c6120b63a923fd9c60d5Cooper Yuan screen->video_surface_destroy= r300_video_surface_destroy; 3290648bc9f65f1c6700b442e57ac0e82404fb60c2dCorbin Simpson} 33060041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson 33160041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpsonboolean r300_get_texture_buffer(struct pipe_texture* texture, 33260041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson struct pipe_buffer** buffer, 33360041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson unsigned* stride) 33460041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson{ 33560041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson struct r300_texture* tex = (struct r300_texture*)texture; 33660041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson if (!tex) { 33760041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson return FALSE; 33860041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson } 33960041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson 3405e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer pipe_buffer_reference(buffer, tex->buffer); 34160041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson 34260041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson if (stride) { 3433cb30e55e48d86aa5f660e670e055d6b258ea54aNicolai Hähnle *stride = r300_texture_get_stride(tex, 0); 34460041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson } 34560041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson 34660041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson return TRUE; 34760041203d5847de8ab71842a6ce5d33d96cc4930Corbin Simpson} 348