freedreno_texture.c revision af69d88d
1/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 2 3/* 4 * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org> 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 * SOFTWARE. 24 * 25 * Authors: 26 * Rob Clark <robclark@freedesktop.org> 27 */ 28 29#include "pipe/p_state.h" 30#include "util/u_string.h" 31#include "util/u_memory.h" 32#include "util/u_inlines.h" 33 34#include "freedreno_texture.h" 35#include "freedreno_context.h" 36#include "freedreno_util.h" 37 38static void 39fd_sampler_state_delete(struct pipe_context *pctx, void *hwcso) 40{ 41 FREE(hwcso); 42} 43 44static void 45fd_sampler_view_destroy(struct pipe_context *pctx, 46 struct pipe_sampler_view *view) 47{ 48 pipe_resource_reference(&view->texture, NULL); 49 FREE(view); 50} 51 52static void bind_sampler_states(struct fd_texture_stateobj *tex, 53 unsigned nr, void **hwcso) 54{ 55 unsigned i; 56 unsigned new_nr = 0; 57 58 for (i = 0; i < nr; i++) { 59 if (hwcso[i]) 60 new_nr = i + 1; 61 tex->samplers[i] = hwcso[i]; 62 tex->dirty_samplers |= (1 << i); 63 } 64 65 for (; i < tex->num_samplers; i++) { 66 tex->samplers[i] = NULL; 67 tex->dirty_samplers |= (1 << i); 68 } 69 70 tex->num_samplers = new_nr; 71} 72 73static void set_sampler_views(struct fd_texture_stateobj *tex, 74 unsigned nr, struct pipe_sampler_view **views) 75{ 76 unsigned i; 77 unsigned new_nr = 0; 78 79 for (i = 0; i < nr; i++) { 80 if (views[i]) 81 new_nr = i + 1; 82 pipe_sampler_view_reference(&tex->textures[i], views[i]); 83 tex->dirty_samplers |= (1 << i); 84 } 85 86 for (; i < tex->num_textures; i++) { 87 pipe_sampler_view_reference(&tex->textures[i], NULL); 88 tex->dirty_samplers |= (1 << i); 89 } 90 91 tex->num_textures = new_nr; 92} 93 94void 95fd_sampler_states_bind(struct pipe_context *pctx, 96 unsigned shader, unsigned start, 97 unsigned nr, void **hwcso) 98{ 99 struct fd_context *ctx = fd_context(pctx); 100 101 assert(start == 0); 102 103 if (shader == PIPE_SHADER_FRAGMENT) { 104 bind_sampler_states(&ctx->fragtex, nr, hwcso); 105 ctx->dirty |= FD_DIRTY_FRAGTEX; 106 } 107 else if (shader == PIPE_SHADER_VERTEX) { 108 bind_sampler_states(&ctx->verttex, nr, hwcso); 109 ctx->dirty |= FD_DIRTY_VERTTEX; 110 } 111} 112 113 114static void 115fd_fragtex_set_sampler_views(struct pipe_context *pctx, unsigned nr, 116 struct pipe_sampler_view **views) 117{ 118 struct fd_context *ctx = fd_context(pctx); 119 120 /* on a2xx, since there is a flat address space for textures/samplers, 121 * a change in # of fragment textures/samplers will trigger patching and 122 * re-emitting the vertex shader: 123 */ 124 if (nr != ctx->fragtex.num_textures) 125 ctx->dirty |= FD_DIRTY_TEXSTATE; 126 127 set_sampler_views(&ctx->fragtex, nr, views); 128 ctx->dirty |= FD_DIRTY_FRAGTEX; 129} 130 131static void 132fd_verttex_set_sampler_views(struct pipe_context *pctx, unsigned nr, 133 struct pipe_sampler_view **views) 134{ 135 struct fd_context *ctx = fd_context(pctx); 136 set_sampler_views(&ctx->verttex, nr, views); 137 ctx->dirty |= FD_DIRTY_VERTTEX; 138} 139 140static void 141fd_set_sampler_views(struct pipe_context *pctx, unsigned shader, 142 unsigned start, unsigned nr, 143 struct pipe_sampler_view **views) 144{ 145 assert(start == 0); 146 switch (shader) { 147 case PIPE_SHADER_FRAGMENT: 148 fd_fragtex_set_sampler_views(pctx, nr, views); 149 break; 150 case PIPE_SHADER_VERTEX: 151 fd_verttex_set_sampler_views(pctx, nr, views); 152 break; 153 default: 154 ; 155 } 156} 157 158void 159fd_texture_init(struct pipe_context *pctx) 160{ 161 pctx->delete_sampler_state = fd_sampler_state_delete; 162 163 pctx->sampler_view_destroy = fd_sampler_view_destroy; 164 165 pctx->set_sampler_views = fd_set_sampler_views; 166} 167