Path: blob/21.2-virgl/src/gallium/drivers/softpipe/sp_state_sampler.c
4570 views
/**************************************************************************1*2* Copyright 2007 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/* Authors:28* Brian Paul29*/3031#include "util/u_memory.h"32#include "util/u_inlines.h"33#include "util/format/u_format.h"3435#include "draw/draw_context.h"3637#include "sp_context.h"38#include "sp_state.h"39#include "sp_texture.h"40#include "sp_tex_sample.h"41#include "sp_tex_tile_cache.h"42#include "sp_screen.h"43#include "frontend/sw_winsys.h"444546/**47* Bind a range [start, start+num-1] of samplers for a shader stage.48*/49static void50softpipe_bind_sampler_states(struct pipe_context *pipe,51enum pipe_shader_type shader,52unsigned start,53unsigned num,54void **samplers)55{56struct softpipe_context *softpipe = softpipe_context(pipe);57unsigned i;5859assert(shader < PIPE_SHADER_TYPES);60assert(start + num <= ARRAY_SIZE(softpipe->samplers[shader]));6162draw_flush(softpipe->draw);6364/* set the new samplers */65for (i = 0; i < num; i++) {66softpipe->samplers[shader][start + i] = samplers[i];67}6869/* find highest non-null samplers[] entry */70{71unsigned j = MAX2(softpipe->num_samplers[shader], start + num);72while (j > 0 && softpipe->samplers[shader][j - 1] == NULL)73j--;74softpipe->num_samplers[shader] = j;75}7677if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {78draw_set_samplers(softpipe->draw,79shader,80softpipe->samplers[shader],81softpipe->num_samplers[shader]);82}8384softpipe->dirty |= SP_NEW_SAMPLER;85}868788static void89softpipe_sampler_view_destroy(struct pipe_context *pipe,90struct pipe_sampler_view *view)91{92pipe_resource_reference(&view->texture, NULL);93FREE(view);94}959697void98softpipe_set_sampler_views(struct pipe_context *pipe,99enum pipe_shader_type shader,100unsigned start,101unsigned num,102unsigned unbind_num_trailing_slots,103struct pipe_sampler_view **views)104{105struct softpipe_context *softpipe = softpipe_context(pipe);106uint i;107108assert(shader < PIPE_SHADER_TYPES);109assert(start + num <= ARRAY_SIZE(softpipe->sampler_views[shader]));110111draw_flush(softpipe->draw);112113/* set the new sampler views */114for (i = 0; i < num; i++) {115struct sp_sampler_view *sp_sviewsrc;116struct sp_sampler_view *sp_sviewdst =117&softpipe->tgsi.sampler[shader]->sp_sview[start + i];118struct pipe_sampler_view **pview = &softpipe->sampler_views[shader][start + i];119pipe_sampler_view_reference(pview, views[i]);120sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[shader][start + i],121views[i]);122/*123* We don't really have variants, however some bits are different per shader,124* so just copy?125*/126sp_sviewsrc = (struct sp_sampler_view *)*pview;127if (sp_sviewsrc) {128memcpy(sp_sviewdst, sp_sviewsrc, sizeof(*sp_sviewsrc));129sp_sviewdst->compute_lambda = softpipe_get_lambda_func(&sp_sviewdst->base, shader);130sp_sviewdst->compute_lambda_from_grad = softpipe_get_lambda_from_grad_func(&sp_sviewdst->base, shader);131sp_sviewdst->cache = softpipe->tex_cache[shader][start + i];132}133else {134memset(sp_sviewdst, 0, sizeof(*sp_sviewsrc));135}136}137for (; i < num + unbind_num_trailing_slots; i++) {138struct pipe_sampler_view **pview = &softpipe->sampler_views[shader][start + i];139pipe_sampler_view_reference(pview, NULL);140sp_tex_tile_cache_set_sampler_view(softpipe->tex_cache[shader][start + i],141NULL);142}143144145/* find highest non-null sampler_views[] entry */146{147unsigned j = MAX2(softpipe->num_sampler_views[shader], start + num);148while (j > 0 && softpipe->sampler_views[shader][j - 1] == NULL)149j--;150softpipe->num_sampler_views[shader] = j;151}152153if (shader == PIPE_SHADER_VERTEX || shader == PIPE_SHADER_GEOMETRY) {154draw_set_sampler_views(softpipe->draw,155shader,156softpipe->sampler_views[shader],157softpipe->num_sampler_views[shader]);158}159160softpipe->dirty |= SP_NEW_TEXTURE;161}162163164static void165softpipe_delete_sampler_state(struct pipe_context *pipe,166void *sampler)167{168FREE( sampler );169}170171172static void173prepare_shader_sampling(174struct softpipe_context *sp,175unsigned num,176struct pipe_sampler_view **views,177enum pipe_shader_type shader_type,178struct pipe_resource *mapped_tex[PIPE_MAX_SHADER_SAMPLER_VIEWS])179{180181unsigned i;182uint32_t row_stride[PIPE_MAX_TEXTURE_LEVELS];183uint32_t img_stride[PIPE_MAX_TEXTURE_LEVELS];184uint32_t mip_offsets[PIPE_MAX_TEXTURE_LEVELS];185const void *addr;186187assert(num <= PIPE_MAX_SHADER_SAMPLER_VIEWS);188if (!num)189return;190191for (i = 0; i < num; i++) {192struct pipe_sampler_view *view = views[i];193194if (view) {195struct pipe_resource *tex = view->texture;196struct softpipe_resource *sp_tex = softpipe_resource(tex);197unsigned width0 = tex->width0;198unsigned num_layers = tex->depth0;199unsigned first_level = 0;200unsigned last_level = 0;201202/* We're referencing the texture's internal data, so save a203* reference to it.204*/205pipe_resource_reference(&mapped_tex[i], tex);206207if (!sp_tex->dt) {208/* regular texture - setup array of mipmap level offsets */209ASSERTED struct pipe_resource *res = view->texture;210int j;211212if (view->target != PIPE_BUFFER) {213first_level = view->u.tex.first_level;214last_level = view->u.tex.last_level;215assert(first_level <= last_level);216assert(last_level <= res->last_level);217addr = sp_tex->data;218219for (j = first_level; j <= last_level; j++) {220mip_offsets[j] = sp_tex->level_offset[j];221row_stride[j] = sp_tex->stride[j];222img_stride[j] = sp_tex->img_stride[j];223}224if (tex->target == PIPE_TEXTURE_1D_ARRAY ||225tex->target == PIPE_TEXTURE_2D_ARRAY ||226tex->target == PIPE_TEXTURE_CUBE ||227tex->target == PIPE_TEXTURE_CUBE_ARRAY) {228num_layers = view->u.tex.last_layer - view->u.tex.first_layer + 1;229for (j = first_level; j <= last_level; j++) {230mip_offsets[j] += view->u.tex.first_layer *231sp_tex->img_stride[j];232}233if (view->target == PIPE_TEXTURE_CUBE ||234view->target == PIPE_TEXTURE_CUBE_ARRAY) {235assert(num_layers % 6 == 0);236}237assert(view->u.tex.first_layer <= view->u.tex.last_layer);238assert(view->u.tex.last_layer < res->array_size);239}240}241else {242unsigned view_blocksize = util_format_get_blocksize(view->format);243addr = sp_tex->data;244/* probably don't really need to fill that out */245mip_offsets[0] = 0;246row_stride[0] = 0;247img_stride[0] = 0;248249/* everything specified in number of elements here. */250width0 = view->u.buf.size / view_blocksize;251addr = (uint8_t *)addr + view->u.buf.offset;252assert(view->u.buf.offset + view->u.buf.size <= res->width0);253}254}255else {256/* display target texture/surface */257struct softpipe_screen *screen = softpipe_screen(tex->screen);258struct sw_winsys *winsys = screen->winsys;259addr = winsys->displaytarget_map(winsys, sp_tex->dt,260PIPE_MAP_READ);261row_stride[0] = sp_tex->stride[0];262img_stride[0] = sp_tex->img_stride[0];263mip_offsets[0] = 0;264assert(addr);265}266draw_set_mapped_texture(sp->draw,267shader_type,268i,269width0, tex->height0, num_layers,270first_level, last_level, 0, 0,271addr,272row_stride, img_stride, mip_offsets);273}274}275}276277static void278sp_sampler_view_display_target_unmap(struct softpipe_context *sp,279struct pipe_sampler_view *view)280{281if (view) {282struct pipe_resource *tex = view->texture;283struct softpipe_resource *sp_tex = softpipe_resource(tex);284if (sp_tex->dt) {285struct softpipe_screen *screen = softpipe_screen(tex->screen);286struct sw_winsys *winsys = screen->winsys;287winsys->displaytarget_unmap(winsys, sp_tex->dt);288}289}290}291292/**293* Called during state validation when SP_NEW_TEXTURE is set.294*/295void296softpipe_prepare_vertex_sampling(struct softpipe_context *sp,297unsigned num,298struct pipe_sampler_view **views)299{300prepare_shader_sampling(sp, num, views, PIPE_SHADER_VERTEX,301sp->mapped_vs_tex);302}303304void305softpipe_cleanup_vertex_sampling(struct softpipe_context *ctx)306{307unsigned i;308for (i = 0; i < ARRAY_SIZE(ctx->mapped_vs_tex); i++) {309sp_sampler_view_display_target_unmap(310ctx, ctx->sampler_views[PIPE_SHADER_VERTEX][i]);311pipe_resource_reference(&ctx->mapped_vs_tex[i], NULL);312}313}314315316/**317* Called during state validation when SP_NEW_TEXTURE is set.318*/319void320softpipe_prepare_geometry_sampling(struct softpipe_context *sp,321unsigned num,322struct pipe_sampler_view **views)323{324prepare_shader_sampling(sp, num, views, PIPE_SHADER_GEOMETRY,325sp->mapped_gs_tex);326}327328void329softpipe_cleanup_geometry_sampling(struct softpipe_context *ctx)330{331unsigned i;332for (i = 0; i < ARRAY_SIZE(ctx->mapped_gs_tex); i++) {333sp_sampler_view_display_target_unmap(334ctx, ctx->sampler_views[PIPE_SHADER_GEOMETRY][i]);335pipe_resource_reference(&ctx->mapped_gs_tex[i], NULL);336}337}338339340void341softpipe_init_sampler_funcs(struct pipe_context *pipe)342{343pipe->create_sampler_state = softpipe_create_sampler_state;344pipe->bind_sampler_states = softpipe_bind_sampler_states;345pipe->delete_sampler_state = softpipe_delete_sampler_state;346347pipe->create_sampler_view = softpipe_create_sampler_view;348pipe->set_sampler_views = softpipe_set_sampler_views;349pipe->sampler_view_destroy = softpipe_sampler_view_destroy;350}351352353354