nir: Allow for system values with variable numbers of destination components
[mesa.git] / src / gallium / drivers / vc4 / vc4_uniforms.c
index e8cd153ce2078f966412e70578b6025234bc8766..dd07487ab16d7a6a5d4ab1d8900b3fef23442f32 100644 (file)
  */
 
 #include "util/u_pack_color.h"
+#include "util/u_upload_mgr.h"
 #include "util/format_srgb.h"
 
 #include "vc4_context.h"
 #include "vc4_qir.h"
 
 static void
-write_texture_p0(struct vc4_context *vc4,
+write_texture_p0(struct vc4_job *job,
                  struct vc4_cl_out **uniforms,
                  struct vc4_texture_stateobj *texstate,
                  uint32_t unit)
 {
         struct vc4_sampler_view *sview =
                 vc4_sampler_view(texstate->textures[unit]);
-        struct vc4_resource *rsc = vc4_resource(sview->base.texture);
+        struct vc4_resource *rsc = vc4_resource(sview->texture);
 
-        cl_reloc(vc4, &vc4->uniforms, uniforms, rsc->bo, sview->texture_p0);
+        cl_reloc(job, &job->uniforms, uniforms, rsc->bo, sview->texture_p0);
 }
 
 static void
-write_texture_p1(struct vc4_context *vc4,
+write_texture_p1(struct vc4_job *job,
                  struct vc4_cl_out **uniforms,
                  struct vc4_texture_stateobj *texstate,
                  uint32_t unit)
@@ -55,7 +56,7 @@ write_texture_p1(struct vc4_context *vc4,
 }
 
 static void
-write_texture_p2(struct vc4_context *vc4,
+write_texture_p2(struct vc4_job *job,
                  struct vc4_cl_out **uniforms,
                  struct vc4_texture_stateobj *texstate,
                  uint32_t data)
@@ -72,7 +73,7 @@ write_texture_p2(struct vc4_context *vc4,
 }
 
 static void
-write_texture_first_level(struct vc4_context *vc4,
+write_texture_first_level(struct vc4_job *job,
                           struct vc4_cl_out **uniforms,
                           struct vc4_texture_stateobj *texstate,
                           uint32_t data)
@@ -84,7 +85,7 @@ write_texture_first_level(struct vc4_context *vc4,
 }
 
 static void
-write_texture_msaa_addr(struct vc4_context *vc4,
+write_texture_msaa_addr(struct vc4_job *job,
                  struct vc4_cl_out **uniforms,
                         struct vc4_texture_stateobj *texstate,
                         uint32_t unit)
@@ -92,7 +93,7 @@ write_texture_msaa_addr(struct vc4_context *vc4,
         struct pipe_sampler_view *texture = texstate->textures[unit];
         struct vc4_resource *rsc = vc4_resource(texture->texture);
 
-        cl_aligned_reloc(vc4, &vc4->uniforms, uniforms, rsc->bo, 0);
+        cl_aligned_reloc(job, &job->uniforms, uniforms, rsc->bo, 0);
 }
 
 
@@ -104,7 +105,7 @@ write_texture_msaa_addr(struct vc4_context *vc4,
 }
 
 static void
-write_texture_border_color(struct vc4_context *vc4,
+write_texture_border_color(struct vc4_job *job,
                            struct vc4_cl_out **uniforms,
                            struct vc4_texture_stateobj *texstate,
                            uint32_t unit)
@@ -149,6 +150,7 @@ write_texture_border_color(struct vc4_context *vc4,
                                         PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
                         break;
                 case VC4_TEXTURE_TYPE_RGBA4444:
+                case VC4_TEXTURE_TYPE_RGBA5551:
                         util_pack_color(storage_color,
                                         PIPE_FORMAT_A8B8G8R8_UNORM, &uc);
                         break;
@@ -185,51 +187,33 @@ get_texrect_scale(struct vc4_texture_stateobj *texstate,
         return fui(1.0f / dim);
 }
 
-static struct vc4_bo *
-vc4_upload_ubo(struct vc4_context *vc4,
-               struct vc4_compiled_shader *shader,
-               const uint32_t *gallium_uniforms)
-{
-        if (!shader->ubo_size)
-                return NULL;
-
-        struct vc4_bo *ubo = vc4_bo_alloc(vc4->screen, shader->ubo_size, "ubo");
-        void *data = vc4_bo_map(ubo);
-        for (uint32_t i = 0; i < shader->num_ubo_ranges; i++) {
-                memcpy(data + shader->ubo_ranges[i].dst_offset,
-                       ((const void *)gallium_uniforms +
-                        shader->ubo_ranges[i].src_offset),
-                       shader->ubo_ranges[i].size);
-        }
-
-        return ubo;
-}
-
 void
 vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
                    struct vc4_constbuf_stateobj *cb,
                    struct vc4_texture_stateobj *texstate)
 {
         struct vc4_shader_uniform_info *uinfo = &shader->uniforms;
+        struct vc4_job *job = vc4->job;
         const uint32_t *gallium_uniforms = cb->cb[0].user_buffer;
-        struct vc4_bo *ubo = vc4_upload_ubo(vc4, shader, gallium_uniforms);
 
-        cl_ensure_space(&vc4->uniforms, (uinfo->count +
+        cl_ensure_space(&job->uniforms, (uinfo->count +
                                          uinfo->num_texture_samples) * 4);
 
         struct vc4_cl_out *uniforms =
-                cl_start_shader_reloc(&vc4->uniforms,
+                cl_start_shader_reloc(&job->uniforms,
                                       uinfo->num_texture_samples);
 
         for (int i = 0; i < uinfo->count; i++) {
+                enum quniform_contents contents = uinfo->contents[i];
+                uint32_t data = uinfo->data[i];
 
-                switch (uinfo->contents[i]) {
+                switch (contents) {
                 case QUNIFORM_CONSTANT:
-                        cl_aligned_u32(&uniforms, uinfo->data[i]);
+                        cl_aligned_u32(&uniforms, data);
                         break;
                 case QUNIFORM_UNIFORM:
                         cl_aligned_u32(&uniforms,
-                                       gallium_uniforms[uinfo->data[i]]);
+                                       gallium_uniforms[data]);
                         break;
                 case QUNIFORM_VIEWPORT_X_SCALE:
                         cl_aligned_f(&uniforms, vc4->viewport.scale[0] * 16.0f);
@@ -247,41 +231,63 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
 
                 case QUNIFORM_USER_CLIP_PLANE:
                         cl_aligned_f(&uniforms,
-                                     vc4->clip.ucp[uinfo->data[i] / 4][uinfo->data[i] % 4]);
+                                     vc4->clip.ucp[data / 4][data % 4]);
                         break;
 
                 case QUNIFORM_TEXTURE_CONFIG_P0:
-                        write_texture_p0(vc4, &uniforms, texstate,
-                                         uinfo->data[i]);
+                        write_texture_p0(job, &uniforms, texstate, data);
                         break;
 
                 case QUNIFORM_TEXTURE_CONFIG_P1:
-                        write_texture_p1(vc4, &uniforms, texstate,
-                                         uinfo->data[i]);
+                        write_texture_p1(job, &uniforms, texstate, data);
                         break;
 
                 case QUNIFORM_TEXTURE_CONFIG_P2:
-                        write_texture_p2(vc4, &uniforms, texstate,
-                                         uinfo->data[i]);
+                        write_texture_p2(job, &uniforms, texstate, data);
                         break;
 
                 case QUNIFORM_TEXTURE_FIRST_LEVEL:
-                        write_texture_first_level(vc4, &uniforms, texstate,
-                                                  uinfo->data[i]);
+                        write_texture_first_level(job, &uniforms, texstate,
+                                                  data);
+                        break;
+
+                case QUNIFORM_UBO0_ADDR:
+                        /* Constant buffer 0 may be a system memory pointer,
+                         * in which case we want to upload a shadow copy to
+                         * the GPU.
+                        */
+                        if (!cb->cb[0].buffer) {
+                                u_upload_data(vc4->uploader, 0,
+                                              cb->cb[0].buffer_size, 16,
+                                              cb->cb[0].user_buffer,
+                                              &cb->cb[0].buffer_offset,
+                                              &cb->cb[0].buffer);
+                        }
+
+                        cl_aligned_reloc(job, &job->uniforms,
+                                         &uniforms,
+                                         vc4_resource(cb->cb[0].buffer)->bo,
+                                         cb->cb[0].buffer_offset +
+                                         data);
                         break;
 
-                case QUNIFORM_UBO_ADDR:
-                        cl_aligned_reloc(vc4, &vc4->uniforms, &uniforms, ubo, 0);
+                case QUNIFORM_UBO1_ADDR: {
+                        struct vc4_resource *rsc =
+                                vc4_resource(cb->cb[1].buffer);
+
+                        cl_aligned_reloc(job, &job->uniforms,
+                                         &uniforms,
+                                         rsc->bo, cb->cb[1].buffer_offset);
                         break;
+                }
 
                 case QUNIFORM_TEXTURE_MSAA_ADDR:
-                        write_texture_msaa_addr(vc4, &uniforms,
-                                                texstate, uinfo->data[i]);
+                        write_texture_msaa_addr(job, &uniforms, texstate, data);
                         break;
 
                 case QUNIFORM_TEXTURE_BORDER_COLOR:
-                        write_texture_border_color(vc4, &uniforms,
-                                                   texstate, uinfo->data[i]);
+                        write_texture_border_color(job, &uniforms,
+                                                   texstate, data);
                         break;
 
                 case QUNIFORM_TEXRECT_SCALE_X:
@@ -289,7 +295,7 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
                         cl_aligned_u32(&uniforms,
                                        get_texrect_scale(texstate,
                                                          uinfo->contents[i],
-                                                         uinfo->data[i]));
+                                                         data));
                         break;
 
                 case QUNIFORM_BLEND_CONST_COLOR_X:
@@ -328,9 +334,9 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
 
                 case QUNIFORM_STENCIL:
                         cl_aligned_u32(&uniforms,
-                                       vc4->zsa->stencil_uniforms[uinfo->data[i]] |
-                                       (uinfo->data[i] <= 1 ?
-                                        (vc4->stencil_ref.ref_value[uinfo->data[i]] << 8) :
+                                       vc4->zsa->stencil_uniforms[data] |
+                                       (data <= 1 ?
+                                        (vc4->stencil_ref.ref_value[data] << 8) :
                                         0));
                         break;
 
@@ -348,16 +354,21 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
                         cl_aligned_u32(&uniforms, 0xd0d0d0d0);
                         break;
                 }
-#if 0
-                uint32_t written_val = *((uint32_t *)uniforms - 1);
-                fprintf(stderr, "%p: %d / 0x%08x (%f)\n",
-                        shader, i, written_val, uif(written_val));
-#endif
-        }
 
-        cl_end(&vc4->uniforms, uniforms);
+                if (false) {
+                        uint32_t written_val = *((uint32_t *)uniforms - 1);
+                        char *desc = qir_describe_uniform(uinfo->contents[i],
+                                                          uinfo->data[i],
+                                                          gallium_uniforms);
+
+                        fprintf(stderr, "%p/%d: 0x%08x %s\n",
+                                shader, i, written_val, desc);
+
+                        ralloc_free(desc);
+                }
+        }
 
-        vc4_bo_unreference(&ubo);
+        cl_end(&job->uniforms, uniforms);
 }
 
 void
@@ -371,7 +382,8 @@ vc4_set_shader_uniform_dirty_flags(struct vc4_compiled_shader *shader)
                 case QUNIFORM_UNIFORMS_ADDRESS:
                         break;
                 case QUNIFORM_UNIFORM:
-                case QUNIFORM_UBO_ADDR:
+                case QUNIFORM_UBO0_ADDR:
+                case QUNIFORM_UBO1_ADDR:
                         dirty |= VC4_DIRTY_CONSTBUF;
                         break;