1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
32 #include "util/u_memory.h"
33 #include "util/u_inlines.h"
35 #include "draw/draw_context.h"
37 #include "sp_context.h"
39 #include "sp_texture.h"
40 #include "sp_tex_sample.h"
41 #include "sp_tex_tile_cache.h"
45 * Bind a range [start, start+num-1] of samplers for a shader stage.
48 softpipe_bind_sampler_states(struct pipe_context
*pipe
,
54 struct softpipe_context
*softpipe
= softpipe_context(pipe
);
57 assert(shader
< PIPE_SHADER_TYPES
);
58 assert(start
+ num
<= Elements(softpipe
->samplers
[shader
]));
61 if (start
+ num
<= softpipe
->num_samplers
[shader
] &&
62 !memcmp(softpipe
->samplers
[shader
] + start
, samplers
,
63 num
* sizeof(void *))) {
67 draw_flush(softpipe
->draw
);
69 /* set the new samplers */
70 for (i
= 0; i
< num
; i
++) {
71 softpipe
->samplers
[shader
][start
+ i
] = samplers
[i
];
74 /* find highest non-null samplers[] entry */
76 unsigned j
= MAX2(softpipe
->num_samplers
[shader
], start
+ num
);
77 while (j
> 0 && softpipe
->samplers
[shader
][j
- 1] == NULL
)
79 softpipe
->num_samplers
[shader
] = j
;
82 if (shader
== PIPE_SHADER_VERTEX
|| shader
== PIPE_SHADER_GEOMETRY
) {
83 draw_set_samplers(softpipe
->draw
,
85 softpipe
->samplers
[shader
],
86 softpipe
->num_samplers
[shader
]);
89 softpipe
->dirty
|= SP_NEW_SAMPLER
;
94 softpipe_sampler_view_destroy(struct pipe_context
*pipe
,
95 struct pipe_sampler_view
*view
)
97 pipe_resource_reference(&view
->texture
, NULL
);
103 softpipe_set_sampler_views(struct pipe_context
*pipe
,
107 struct pipe_sampler_view
**views
)
109 struct softpipe_context
*softpipe
= softpipe_context(pipe
);
112 assert(shader
< PIPE_SHADER_TYPES
);
113 assert(start
+ num
<= Elements(softpipe
->sampler_views
[shader
]));
115 /* Check for no-op */
116 if (start
+ num
<= softpipe
->num_sampler_views
[shader
] &&
117 !memcmp(softpipe
->sampler_views
[shader
] + start
, views
,
118 num
* sizeof(struct pipe_sampler_view
*))) {
122 draw_flush(softpipe
->draw
);
124 /* set the new sampler views */
125 for (i
= 0; i
< num
; i
++) {
126 struct sp_sampler_view
*sp_sviewsrc
;
127 struct sp_sampler_view
*sp_sviewdst
=
128 &softpipe
->tgsi
.sampler
[shader
]->sp_sview
[start
+ i
];
129 struct pipe_sampler_view
**pview
= &softpipe
->sampler_views
[shader
][start
+ i
];
130 pipe_sampler_view_reference(pview
, views
[i
]);
131 sp_tex_tile_cache_set_sampler_view(softpipe
->tex_cache
[shader
][start
+ i
],
134 * We don't really have variants, however some bits are different per shader,
137 sp_sviewsrc
= (struct sp_sampler_view
*)*pview
;
139 memcpy(sp_sviewdst
, sp_sviewsrc
, sizeof(*sp_sviewsrc
));
140 sp_sviewdst
->compute_lambda
= softpipe_get_lambda_func(&sp_sviewdst
->base
, shader
);
141 sp_sviewdst
->cache
= softpipe
->tex_cache
[shader
][start
+ i
];
144 memset(sp_sviewdst
, 0, sizeof(*sp_sviewsrc
));
149 /* find highest non-null sampler_views[] entry */
151 unsigned j
= MAX2(softpipe
->num_sampler_views
[shader
], start
+ num
);
152 while (j
> 0 && softpipe
->sampler_views
[shader
][j
- 1] == NULL
)
154 softpipe
->num_sampler_views
[shader
] = j
;
157 if (shader
== PIPE_SHADER_VERTEX
|| shader
== PIPE_SHADER_GEOMETRY
) {
158 draw_set_sampler_views(softpipe
->draw
,
160 softpipe
->sampler_views
[shader
],
161 softpipe
->num_sampler_views
[shader
]);
164 softpipe
->dirty
|= SP_NEW_TEXTURE
;
169 softpipe_set_fragment_sampler_views(struct pipe_context
*pipe
,
171 struct pipe_sampler_view
**views
)
173 softpipe_set_sampler_views(pipe
, PIPE_SHADER_FRAGMENT
, 0, num
, views
);
178 softpipe_set_vertex_sampler_views(struct pipe_context
*pipe
,
180 struct pipe_sampler_view
**views
)
182 softpipe_set_sampler_views(pipe
, PIPE_SHADER_VERTEX
, 0, num
, views
);
187 softpipe_set_geometry_sampler_views(struct pipe_context
*pipe
,
189 struct pipe_sampler_view
**views
)
191 softpipe_set_sampler_views(pipe
, PIPE_SHADER_GEOMETRY
, 0, num
, views
);
196 softpipe_delete_sampler_state(struct pipe_context
*pipe
,
204 softpipe_init_sampler_funcs(struct pipe_context
*pipe
)
206 pipe
->create_sampler_state
= softpipe_create_sampler_state
;
207 pipe
->bind_sampler_states
= softpipe_bind_sampler_states
;
208 pipe
->delete_sampler_state
= softpipe_delete_sampler_state
;
210 pipe
->set_fragment_sampler_views
= softpipe_set_fragment_sampler_views
;
211 pipe
->set_vertex_sampler_views
= softpipe_set_vertex_sampler_views
;
212 pipe
->set_geometry_sampler_views
= softpipe_set_geometry_sampler_views
;
214 pipe
->create_sampler_view
= softpipe_create_sampler_view
;
215 pipe
->sampler_view_destroy
= softpipe_sampler_view_destroy
;