void
v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
{
- unsigned unit = instr->texture_index;
+ unsigned texture_idx = instr->texture_index;
+ unsigned sampler_idx = instr->sampler_index;
+
int tmu_writes = 0;
struct V3D41_TMU_CONFIG_PARAMETER_0 p0_unpacked = {
if (instr->op == nir_texop_lod)
p2_packed |= 1UL << 24;
- /* Load unit number into the high bits of the texture address field,
+ /* Load texture_idx number into the high bits of the texture address field,
* which will be be used by the driver to decide which texture to put
* in the actual address field.
*/
- p0_packed |= unit << 24;
+ p0_packed |= texture_idx << 24;
vir_WRTMUC(c, QUNIFORM_TMU_CONFIG_P0, p0_packed);
* itself, we still need to add the sampler configuration
* parameter if the output is 32 bit
*/
- bool output_type_32_bit = (c->key->tex[unit].return_size == 32 &&
+ bool output_type_32_bit = (c->key->sampler[sampler_idx].return_size == 32 &&
!instr->is_shadow);
/*
&p1_unpacked);
if (nir_tex_instr_need_sampler(instr)) {
- /* Load unit number into the high bits of the sampler
- * address field, which will be be used by the driver
- * to decide which sampler to put in the actual
+ /* Load sampler_idx number into the high bits of the
+ * sampler address field, which will be be used by the
+ * driver to decide which sampler to put in the actual
* address field.
*/
- p1_packed |= unit << 24;
+ p1_packed |= sampler_idx << 24;
vir_WRTMUC(c, QUNIFORM_TMU_CONFIG_P1, p1_packed);
} else {
void *shader_state;
struct {
uint8_t swizzle[4];
- uint8_t return_size;
- uint8_t return_channels;
bool clamp_s:1;
bool clamp_t:1;
bool clamp_r:1;
} tex[V3D_MAX_TEXTURE_SAMPLERS];
+ struct {
+ uint8_t return_size;
+ uint8_t return_channels;
+ } sampler[V3D_MAX_TEXTURE_SAMPLERS];
+
uint8_t num_tex_used;
+ uint8_t num_samplers_used;
uint8_t ucp_enables;
bool is_last_geometry_stage;
bool robust_buffer_access;
/* Lower the format swizzle and (for 32-bit returns)
* ARB_texture_swizzle-style swizzle.
*/
- for (int i = 0; i < ARRAY_SIZE(c->key->tex); i++) {
+ assert(c->key->num_tex_used <= ARRAY_SIZE(c->key->tex));
+ for (int i = 0; i < c->key->num_tex_used; i++) {
for (int j = 0; j < 4; j++)
tex_options.swizzles[i][j] = c->key->tex[i].swizzle[j];
tex_options.saturate_t |= 1 << i;
if (c->key->tex[i].clamp_r)
tex_options.saturate_r |= 1 << i;
- if (c->key->tex[i].return_size == 16) {
+ }
+
+ assert(c->key->num_samplers_used <= ARRAY_SIZE(c->key->sampler));
+ for (int i = 0; i < c->key->num_samplers_used; i++) {
+ if (c->key->sampler[i].return_size == 16) {
tex_options.lower_tex_packing[i] =
nir_lower_tex_packing_16;
}
key->tex[tex_idx].swizzle[2] = PIPE_SWIZZLE_Z;
key->tex[tex_idx].swizzle[3] = PIPE_SWIZZLE_W;
- key->tex[tex_idx].return_size = 16;
- key->tex[tex_idx].return_channels = 2;
+ key->sampler[tex_idx].return_size = 16;
+ key->sampler[tex_idx].return_channels = 2;
tex_idx++;
}
const struct v3d_device_info *devinfo = &v3d->screen->devinfo;
key->num_tex_used = texstate->num_textures;
+ key->num_samplers_used = texstate->num_textures;
+ assert(key->num_tex_used == key->num_samplers_used);
for (int i = 0; i < texstate->num_textures; i++) {
struct pipe_sampler_view *sampler = texstate->textures[i];
struct v3d_sampler_view *v3d_sampler = v3d_sampler_view(sampler);
if (!sampler)
continue;
- key->tex[i].return_size =
+ key->sampler[i].return_size =
v3d_get_tex_return_size(devinfo,
sampler->format,
sampler_state->compare_mode);
* channels (meaning no recompiles for most statechanges),
* while for 32 we actually scale the returns with channels.
*/
- if (key->tex[i].return_size == 16) {
- key->tex[i].return_channels = 2;
+ if (key->sampler[i].return_size == 16) {
+ key->sampler[i].return_channels = 2;
} else if (devinfo->ver > 40) {
- key->tex[i].return_channels = 4;
+ key->sampler[i].return_channels = 4;
} else {
- key->tex[i].return_channels =
+ key->sampler[i].return_channels =
v3d_get_tex_return_channels(devinfo,
sampler->format);
}
- if (key->tex[i].return_size == 32 && devinfo->ver < 40) {
+ if (key->sampler[i].return_size == 32 && devinfo->ver < 40) {
memcpy(key->tex[i].swizzle,
v3d_sampler->swizzle,
sizeof(v3d_sampler->swizzle));
{
nir_shader *s = uncompiled->base.ir.nir;
+ /* Note that below we access they key's texture and sampler fields
+ * using the same index. On OpenGL they are the same (they are
+ * combined)
+ */
key->num_tex_used = s->info.num_textures;
+ key->num_samplers_used = s->info.num_textures;
for (int i = 0; i < s->info.num_textures; i++) {
- key->tex[i].return_size = 16;
- key->tex[i].return_channels = 2;
+ key->sampler[i].return_size = 16;
+ key->sampler[i].return_channels = 2;
key->tex[i].swizzle[0] = PIPE_SWIZZLE_X;
key->tex[i].swizzle[1] = PIPE_SWIZZLE_Y;