16173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
26173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
36173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark/*
46173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Copyright (C) 2012 Rob Clark <robclark@freedesktop.org>
56173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
66173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Permission is hereby granted, free of charge, to any person obtaining a
76173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * copy of this software and associated documentation files (the "Software"),
86173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * to deal in the Software without restriction, including without limitation
96173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * the rights to use, copy, modify, merge, publish, distribute, sublicense,
106173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * and/or sell copies of the Software, and to permit persons to whom the
116173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Software is furnished to do so, subject to the following conditions:
126173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
136173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * The above copyright notice and this permission notice (including the next
146173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * paragraph) shall be included in all copies or substantial portions of the
156173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Software.
166173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
176173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
186173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
196173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
206173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
216173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
226173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
236173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * SOFTWARE.
246173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *
256173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark * Authors:
266173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark *    Rob Clark <robclark@freedesktop.org>
276173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark */
286173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
296173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "pipe/p_state.h"
306173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "util/u_string.h"
316173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "util/u_memory.h"
326173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "util/u_inlines.h"
336173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "freedreno_texture.h"
3518c317b21ddc2ec4538544f9dd69dc568dcf821fRob Clark#include "freedreno_context.h"
366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark#include "freedreno_util.h"
376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkstatic void
396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkfd_sampler_state_delete(struct pipe_context *pctx, void *hwcso)
406173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
416173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	FREE(hwcso);
426173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
436173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
446173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkstatic void
456173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkfd_sampler_view_destroy(struct pipe_context *pctx,
466173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		struct pipe_sampler_view *view)
476173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
486173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	pipe_resource_reference(&view->texture, NULL);
496173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	FREE(view);
506173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
516173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
52a6746d11247cdd6f795c7e857019c3a4bd71e26aRob Clarkstatic void bind_sampler_states(struct fd_texture_stateobj *tex,
53243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		unsigned start, unsigned nr, void **hwcso)
546173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
556173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	unsigned i;
566173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
576173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	for (i = 0; i < nr; i++) {
58243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		unsigned p = i + start;
59243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		tex->samplers[p] = hwcso[i];
60243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		if (tex->samplers[p])
61243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark			tex->valid_samplers |= (1 << p);
62243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		else
63243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark			tex->valid_samplers &= ~(1 << p);
646173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
656173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
66243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark	tex->num_samplers = util_last_bit(tex->valid_samplers);
676173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
686173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
69a6746d11247cdd6f795c7e857019c3a4bd71e26aRob Clarkstatic void set_sampler_views(struct fd_texture_stateobj *tex,
70243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		unsigned start, unsigned nr, struct pipe_sampler_view **views)
716173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
726173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	unsigned i;
736173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
746173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	for (i = 0; i < nr; i++) {
75243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		struct pipe_sampler_view *view = views ? views[i] : NULL;
76243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		unsigned p = i + start;
77243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		pipe_sampler_view_reference(&tex->textures[p], view);
78243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		if (tex->textures[p])
79243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark			tex->valid_textures |= (1 << p);
80243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		else
81243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark			tex->valid_textures &= ~(1 << p);
826173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	}
836173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
84243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark	tex->num_textures = util_last_bit(tex->valid_textures);
856173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
866173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
87a6746d11247cdd6f795c7e857019c3a4bd71e26aRob Clarkvoid
887d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paulfd_sampler_states_bind(struct pipe_context *pctx,
897413625ad357c87f409cd1673b40f8dffbc43259Kai Wasserbäch		enum pipe_shader_type shader, unsigned start,
906173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		unsigned nr, void **hwcso)
916173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
926173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	struct fd_context *ctx = fd_context(pctx);
93f706d4d340f0778de23062ef13c54b07bfac7967Rob Clark
947d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paul	if (shader == PIPE_SHADER_FRAGMENT) {
95243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		bind_sampler_states(&ctx->fragtex, start, nr, hwcso);
967d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paul		ctx->dirty |= FD_DIRTY_FRAGTEX;
977d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paul	}
987d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paul	else if (shader == PIPE_SHADER_VERTEX) {
99243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		bind_sampler_states(&ctx->verttex, start, nr, hwcso);
1007d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paul		ctx->dirty |= FD_DIRTY_VERTTEX;
1017d7a9714d2f6cdceb9e9e6f6b43004008b56c8d2Brian Paul	}
1026173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
1036173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
104d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clarkvoid
105532db3b7881f3dfcd299320cbf44443d06b88373Kai Wasserbächfd_set_sampler_views(struct pipe_context *pctx, enum pipe_shader_type shader,
106d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		unsigned start, unsigned nr,
1076173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark		struct pipe_sampler_view **views)
1086173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
1096173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	struct fd_context *ctx = fd_context(pctx);
110f706d4d340f0778de23062ef13c54b07bfac7967Rob Clark
111d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark	switch (shader) {
112d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark	case PIPE_SHADER_FRAGMENT:
113d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		/* on a2xx, since there is a flat address space for textures/samplers,
114d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		 * a change in # of fragment textures/samplers will trigger patching
115d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		 * and re-emitting the vertex shader:
116d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		 *
117d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		 * (note: later gen's ignore FD_DIRTY_TEXSTATE so fine to set it)
118d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		 */
119d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		if (nr != ctx->fragtex.num_textures)
120d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark			ctx->dirty |= FD_DIRTY_TEXSTATE;
121d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark
122243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		set_sampler_views(&ctx->fragtex, start, nr, views);
123d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		ctx->dirty |= FD_DIRTY_FRAGTEX;
124d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		break;
125d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark	case PIPE_SHADER_VERTEX:
126243417810bce6b4e0c466a8b1dbe3873b4f5562bRob Clark		set_sampler_views(&ctx->verttex, start, nr, views);
127d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		ctx->dirty |= FD_DIRTY_VERTTEX;
128d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		break;
129d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark	default:
130d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark		break;
131d4ff42bd0a80acfac080507e4e14f33f0b3bffbbRob Clark	}
132a3ed98f7aa85636579a5696bf036ec13e5c9104aBrian Paul}
133a3ed98f7aa85636579a5696bf036ec13e5c9104aBrian Paul
1346173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkvoid
1356173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clarkfd_texture_init(struct pipe_context *pctx)
1366173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark{
1376173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	pctx->delete_sampler_state = fd_sampler_state_delete;
1386173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark
1396173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark	pctx->sampler_view_destroy = fd_sampler_view_destroy;
1406173cc19c45d92ef0b7bc6aa008aa89bb29abbdaRob Clark}
1419124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark
1429124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark/* helper for setting up border-color buffer for a3xx/a4xx: */
1439124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clarkvoid
1449124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clarkfd_setup_border_colors(struct fd_texture_stateobj *tex, void *ptr,
1459124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		unsigned offset)
1469124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark{
1479124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark	unsigned i, j;
1489124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark
1499124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark	for (i = 0; i < tex->num_samplers; i++) {
1509124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		struct pipe_sampler_state *sampler = tex->samplers[i];
1519124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		uint16_t *bcolor = (uint16_t *)((uint8_t *)ptr +
1529124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark				(BORDERCOLOR_SIZE * offset) +
1539124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark				(BORDERCOLOR_SIZE * i));
1549124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		uint32_t *bcolor32 = (uint32_t *)&bcolor[16];
1559124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark
1569124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		if (!sampler)
1579124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark			continue;
1589124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark
1599124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		/*
1609124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 * XXX HACK ALERT XXX
1619124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 *
1629124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 * The border colors need to be swizzled in a particular
1639124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 * format-dependent order. Even though samplers don't know about
1649124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 * formats, we can assume that with a GL state tracker, there's a
1659124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 * 1:1 correspondence between sampler and texture. Take advantage
1669124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 * of that knowledge.
1679124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		 */
1689124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		if (i < tex->num_textures && tex->textures[i]) {
1699124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark			const struct util_format_description *desc =
1709124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark					util_format_description(tex->textures[i]->format);
1719124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark			for (j = 0; j < 4; j++) {
1729124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark				if (desc->swizzle[j] >= 4)
1739124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark					continue;
1749124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark
1759124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark				const struct util_format_channel_description *chan =
176c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin					&desc->channel[desc->swizzle[j]];
177c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin				if (chan->pure_integer) {
178c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin					bcolor32[desc->swizzle[j] + 4] = sampler->border_color.i[j];
179c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin					bcolor[desc->swizzle[j] + 8] = sampler->border_color.i[j];
180c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin				} else {
181c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin					bcolor32[desc->swizzle[j]] = fui(sampler->border_color.f[j]);
1829124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark					bcolor[desc->swizzle[j]] =
183c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin						util_float_to_half(sampler->border_color.f[j]);
184c1babbd85c4069d9d9b319d5ca95a614039ba609Ilia Mirkin				}
1859124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark			}
1869124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark		}
1879124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark	}
1889124a49d54af5d7bd8230af4ba3eebfb167a7655Rob Clark}
189