llvmpipe/draw: handle constant buffer limits and robustness (v1.1)
[mesa.git] / src / gallium / drivers / llvmpipe / lp_state_cs.c
index 7bd52bb78b02ec0c71c80135c1339b11790a5d3b..be6d648cd537a830259a5aadc54343812d5af96c 100644 (file)
@@ -43,6 +43,7 @@
 #include "lp_perf.h"
 #include "lp_screen.h"
 #include "lp_memory.h"
+#include "lp_query.h"
 #include "lp_cs_tpool.h"
 #include "frontend/sw_winsys.h"
 #include "nir/nir_to_tgsi_info.h"
@@ -1160,7 +1161,7 @@ update_csctx_consts(struct llvmpipe_context *llvmpipe)
    for (i = 0; i < ARRAY_SIZE(csctx->constants); ++i) {
       struct pipe_resource *buffer = csctx->constants[i].current.buffer;
       const ubyte *current_data = NULL;
-
+      unsigned current_size = csctx->constants[i].current.buffer_size;
       if (buffer) {
          /* resource buffer */
          current_data = (ubyte *) llvmpipe_resource_data(buffer);
@@ -1170,13 +1171,15 @@ update_csctx_consts(struct llvmpipe_context *llvmpipe)
          current_data = (ubyte *) csctx->constants[i].current.user_buffer;
       }
 
-      if (current_data) {
+      if (current_data && current_size >= sizeof(float)) {
          current_data += csctx->constants[i].current.buffer_offset;
-
          csctx->cs.current.jit_context.constants[i] = (const float *)current_data;
-         csctx->cs.current.jit_context.num_constants[i] = csctx->constants[i].current.buffer_size;
+         csctx->cs.current.jit_context.num_constants[i] =
+            DIV_ROUND_UP(csctx->constants[i].current.buffer_size,
+                         lp_get_constant_buffer_stride(llvmpipe->pipe.screen));
       } else {
-         csctx->cs.current.jit_context.constants[i] = NULL;
+         static const float fake_const_buf[4];
+         csctx->cs.current.jit_context.constants[i] = fake_const_buf;
          csctx->cs.current.jit_context.num_constants[i] = 0;
       }
    }
@@ -1210,9 +1213,6 @@ update_csctx_ssbo(struct llvmpipe_context *llvmpipe)
 static void
 llvmpipe_cs_update_derived(struct llvmpipe_context *llvmpipe, void *input)
 {
-   if (llvmpipe->cs_dirty & (LP_CSNEW_CS))
-      llvmpipe_update_cs(llvmpipe);
-
    if (llvmpipe->cs_dirty & LP_CSNEW_CONSTANTS) {
       lp_csctx_set_cs_constants(llvmpipe->csctx,
                                 ARRAY_SIZE(llvmpipe->constants[PIPE_SHADER_COMPUTE]),
@@ -1248,6 +1248,13 @@ llvmpipe_cs_update_derived(struct llvmpipe_context *llvmpipe, void *input)
       csctx->cs.current.jit_context.kernel_args = input;
    }
 
+   if (llvmpipe->cs_dirty & (LP_CSNEW_CS |
+                             LP_CSNEW_IMAGES |
+                             LP_CSNEW_SAMPLER_VIEW |
+                             LP_CSNEW_SAMPLER))
+      llvmpipe_update_cs(llvmpipe);
+
+
    llvmpipe->cs_dirty = 0;
 }
 
@@ -1312,6 +1319,9 @@ static void llvmpipe_launch_grid(struct pipe_context *pipe,
    struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
    struct lp_cs_job_info job_info;
 
+   if (!llvmpipe_check_render_cond(llvmpipe))
+      return;
+
    memset(&job_info, 0, sizeof(job_info));
 
    llvmpipe_cs_update_derived(llvmpipe, info->input);