freedreno_texture.c revision 01e04c3f
1/* 2 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Rob Clark <robclark@freedesktop.org> 25 */ 26 27#include "pipe/p_state.h" 28#include "util/u_string.h" 29#include "util/u_memory.h" 30#include "util/u_inlines.h" 31 32#include "freedreno_texture.h" 33#include "freedreno_context.h" 34#include "freedreno_resource.h" 35#include "freedreno_util.h" 36 37static void 38fd_sampler_state_delete(struct pipe_context *pctx, void *hwcso) 39{ 40 FREE(hwcso); 41} 42 43static void 44fd_sampler_view_destroy(struct pipe_context *pctx, 45 struct pipe_sampler_view *view) 46{ 47 pipe_resource_reference(&view->texture, NULL); 48 FREE(view); 49} 50 51static void bind_sampler_states(struct fd_texture_stateobj *tex, 52 unsigned start, unsigned nr, void **hwcso) 53{ 54 unsigned i; 55 56 for (i = 0; i < nr; i++) { 57 unsigned p = i + start; 58 tex->samplers[p] = hwcso[i]; 59 if (tex->samplers[p]) 60 tex->valid_samplers |= (1 << p); 61 else 62 tex->valid_samplers &= ~(1 << p); 63 } 64 65 tex->num_samplers = util_last_bit(tex->valid_samplers); 66} 67 68static void set_sampler_views(struct fd_texture_stateobj *tex, 69 unsigned start, unsigned nr, struct pipe_sampler_view **views) 70{ 71 unsigned i; 72 unsigned samplers = 0; 73 74 for (i = 0; i < nr; i++) { 75 struct pipe_sampler_view *view = views ? views[i] : NULL; 76 unsigned p = i + start; 77 pipe_sampler_view_reference(&tex->textures[p], view); 78 if (tex->textures[p]) 79 tex->valid_textures |= (1 << p); 80 else 81 tex->valid_textures &= ~(1 << p); 82 } 83 84 tex->num_textures = util_last_bit(tex->valid_textures); 85 86 for (i = 0; i < tex->num_textures; i++) { 87 uint nr_samples = fd_resource_nr_samples(tex->textures[i]->texture); 88 samplers |= (nr_samples >> 1) << (i * 2); 89 } 90 91 tex->samples = samplers; 92} 93 94void 95fd_sampler_states_bind(struct pipe_context *pctx, 96 enum pipe_shader_type shader, unsigned start, 97 unsigned nr, void **hwcso) 98{ 99 struct fd_context *ctx = fd_context(pctx); 100 101 bind_sampler_states(&ctx->tex[shader], start, nr, hwcso); 102 ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX; 103 ctx->dirty |= FD_DIRTY_TEX; 104} 105 106void 107fd_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader, 108 unsigned start, unsigned nr, 109 struct pipe_sampler_view **views) 110{ 111 struct fd_context *ctx = fd_context(pctx); 112 113 set_sampler_views(&ctx->tex[shader], start, nr, views); 114 ctx->dirty_shader[shader] |= FD_DIRTY_SHADER_TEX; 115 ctx->dirty |= FD_DIRTY_TEX; 116} 117 118void 119fd_texture_init(struct pipe_context *pctx) 120{ 121 if (!pctx->delete_sampler_state) 122 pctx->delete_sampler_state = fd_sampler_state_delete; 123 if (!pctx->sampler_view_destroy) 124 pctx->sampler_view_destroy = fd_sampler_view_destroy; 125} 126 127/* helper for setting up border-color buffer for a3xx/a4xx: */ 128void 129fd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr, 130 unsigned offset) 131{ 132 unsigned i, j; 133 134 for (i = 0; i < tex->num_samplers; i++) { 135 struct pipe_sampler_state *sampler = tex->samplers[i]; 136 uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr + 137 (BORDERCOLOR_SIZE * offset) + 138 (BORDERCOLOR_SIZE * i)); 139 uint32_t *bcolor32 = (uint32_t *)&bcolor[16]; 140 141 if (!sampler) 142 continue; 143 144 /* 145 * XXX HACK ALERT XXX 146 * 147 * The border colors need to be swizzled in a particular 148 * format-dependent order. Even though samplers don't know about 149 * formats, we can assume that with a GL state tracker, there's a 150 * 1:1 correspondence between sampler and texture. Take advantage 151 * of that knowledge. 152 */ 153 if (i < tex->num_textures && tex->textures[i]) { 154 const struct util_format_description *desc = 155 util_format_description(tex->textures[i]->format); 156 for (j = 0; j < 4; j++) { 157 if (desc->swizzle[j] >= 4) 158 continue; 159 160 const struct util_format_channel_description *chan = 161 &desc->channel[desc->swizzle[j]]; 162 if (chan->pure_integer) { 163 bcolor32[desc->swizzle[j] + 4] = sampler->border_color.i[j]; 164 bcolor[desc->swizzle[j] + 8] = sampler->border_color.i[j]; 165 } else { 166 bcolor32[desc->swizzle[j]] = fui(sampler->border_color.f[j]); 167 bcolor[desc->swizzle[j]] = 168 util_float_to_half(sampler->border_color.f[j]); 169 } 170 } 171 } 172 } 173} 174