nv50: always keep TSC slot 0 bound
authorIlia Mirkin <imirkin@alum.mit.edu>
Sun, 2 Dec 2018 02:28:04 +0000 (21:28 -0500)
committerIlia Mirkin <imirkin@alum.mit.edu>
Tue, 4 Dec 2018 04:11:29 +0000 (23:11 -0500)
All TXF operations implicitly use sampler 0, and fail if it's not bound
to anything. This does not happen in LINKED_TSC mode, but we don't
currently use this.

We ensure that TSC entry at id 0 has the SRGB conversion bit enabled
(and all samplers we normally generate will too). Then when the TSC at
*slot* 0 (not to be confused with entry 0 in the global TSC table) is
unbound, we bind it to entry 0. This way, TXF operations are not
dependent on there being a regular sampler bound there.

Fixes arb_texture_buffer_object-subdata-sync among others. (TBO's are
particularly susceptible to this as they don't bind a sampler.)

Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/nv50/nv50_context.c
src/gallium/drivers/nouveau/nv50/nv50_context.h
src/gallium/drivers/nouveau/nv50/nv50_tex.c

index 61243438fcb2752a5b4c0383ebe4612ba8758f8b..f08e8c4b6b39635fd940f306c04b406fd9d6a19e 100644 (file)
@@ -379,6 +379,15 @@ nv50_create(struct pipe_screen *pscreen, void *priv, unsigned ctxflags)
 
    util_dynarray_init(&nv50->global_residents, NULL);
 
+   // Make sure that the first TSC entry has SRGB conversion bit set, since we
+   // use it as a fallback.
+   if (!screen->tsc.entries[0])
+      nv50_upload_tsc0(nv50);
+
+   // And mark samplers as dirty so that the first slot would get bound to the
+   // zero entry if it's not otherwise set.
+   nv50->dirty_3d |= NV50_NEW_3D_SAMPLERS;
+
    return pipe;
 
 out_err:
index 224535a9381f224fdd661ec05c05809328c8e4f2..88720b1b1d5ecc5d8701c8232aba50e3f7a4f4bb 100644 (file)
@@ -256,6 +256,7 @@ extern void nv50_init_surface_functions(struct nv50_context *);
 void nv50_validate_textures(struct nv50_context *);
 void nv50_validate_samplers(struct nv50_context *);
 void nv50_upload_ms_info(struct nouveau_pushbuf *);
+void nv50_upload_tsc0(struct nv50_context *);
 
 struct pipe_sampler_view *
 nv50_create_texture_view(struct pipe_context *,
index ad230186427f61b26950a61b79814275f7e78474..741e350c2733f1cc5d17354615949e7eac097ef9 100644 (file)
@@ -380,6 +380,16 @@ nv50_validate_tsc(struct nv50_context *nv50, int s)
    }
    nv50->state.num_samplers[s] = nv50->num_samplers[s];
 
+   // TXF, in unlinked tsc mode, will always use sampler 0. So we have to
+   // ensure that it remains bound. Its contents don't matter, all samplers we
+   // ever create have the SRGB_CONVERSION bit set, so as long as the first
+   // entry is initialized, we're good to go. This is the only bit that has
+   // any effect on what TXF does.
+   if (!nv50->samplers[s][0]) {
+      BEGIN_NV04(push, NV50_3D(BIND_TSC(s)), 1);
+      PUSH_DATA (push, 1);
+   }
+
    return need_flush;
 }
 
@@ -451,3 +461,14 @@ void nv50_upload_ms_info(struct nouveau_pushbuf *push)
    BEGIN_NI04(push, NV50_3D(CB_DATA(0)), ARRAY_SIZE(msaa_sample_xy_offsets));
    PUSH_DATAp(push, msaa_sample_xy_offsets, ARRAY_SIZE(msaa_sample_xy_offsets));
 }
+
+void nv50_upload_tsc0(struct nv50_context *nv50)
+{
+   struct nouveau_pushbuf *push = nv50->base.pushbuf;
+   u32 data[8] = { G80_TSC_0_SRGB_CONVERSION };
+   nv50_sifc_linear_u8(&nv50->base, nv50->screen->txc,
+                       65536 /* + tsc->id * 32 */,
+                       NOUVEAU_BO_VRAM, 32, data);
+   BEGIN_NV04(push, NV50_3D(TSC_FLUSH), 1);
+   PUSH_DATA (push, 0);
+}