cell: Don't segfault when unbinding alpha / stencil / depth test state
authorIan Romanick <idr@us.ibm.com>
Mon, 17 Mar 2008 23:09:28 +0000 (16:09 -0700)
committerIan Romanick <idr@us.ibm.com>
Mon, 17 Mar 2008 23:09:28 +0000 (16:09 -0700)
src/gallium/drivers/cell/ppu/cell_pipe_state.c
src/gallium/drivers/cell/ppu/cell_state_emit.c
src/gallium/drivers/cell/spu/spu_main.c

index 66ede99d13bb51dde67a4ec491e1fd66a849f279..c880760e4bd43f493c588000f2956cfc15acd240 100644 (file)
@@ -116,7 +116,7 @@ cell_bind_depth_stencil_alpha_state(struct pipe_context *pipe,
 
    draw_flush(cell->draw);
 
-   if (cdsa->code.store == NULL) {
+   if ((cdsa != NULL) && (cdsa->code.store == NULL)) {
       cell_generate_depth_stencil_test(cdsa);
    }
 
index c8d5fdf709bfae00daf641db0f54031f40fe7b92..e2cc9de48ad4d69af24daf709313dc8460fdc53b 100644 (file)
@@ -74,11 +74,18 @@ cell_emit_state(struct cell_context *cell)
       struct cell_command_depth_stencil_alpha_test dsat;
       
 
-      dsat.base = (intptr_t) cell->depth_stencil->code.store;
-      dsat.size = (char *) cell->depth_stencil->code.csr
-         - (char *) cell->depth_stencil->code.store;
-      dsat.read_depth = TRUE;
-      dsat.read_stencil = FALSE;
+      if (cell->depth_stencil != NULL) {
+        dsat.base = (intptr_t) cell->depth_stencil->code.store;
+        dsat.size = (char *) cell->depth_stencil->code.csr
+            - (char *) cell->depth_stencil->code.store;
+        dsat.read_depth = TRUE;
+        dsat.read_stencil = FALSE;
+      } else {
+        dsat.base = 0;
+        dsat.size = 0;
+        dsat.read_depth = FALSE;
+        dsat.read_stencil = FALSE;
+      }
 
       {
         uint32_t *p = cell->depth_stencil->code.store;
index 8e46f6e4719e90cde5211e2d8d29574e491cc316..b8bb8e9449b2d4b367d8f8871816272641391d2f 100644 (file)
@@ -260,13 +260,22 @@ cmd_state_depth_stencil(const struct cell_command_depth_stencil_alpha_test *stat
 
    ASSERT_ALIGN16(state->base);
 
-   mfc_get(depth_stencil_code_buffer,
-          (unsigned int) state->base,  /* src */
-          ROUNDUP16(state->size),
-          TAG_BATCH_BUFFER,
-          0, /* tid */
-          0  /* rid */);
-   wait_on_mask(1 << TAG_BATCH_BUFFER);
+   if (state->size != 0) {
+      mfc_get(depth_stencil_code_buffer,
+             (unsigned int) state->base,  /* src */
+             ROUNDUP16(state->size),
+             TAG_BATCH_BUFFER,
+             0, /* tid */
+             0  /* rid */);
+      wait_on_mask(1 << TAG_BATCH_BUFFER);
+   } else {
+      /* If there is no code, emit a return instruction.
+       */
+      depth_stencil_code_buffer[0] = 0x35;
+      depth_stencil_code_buffer[1] = 0x00;
+      depth_stencil_code_buffer[2] = 0x00;
+      depth_stencil_code_buffer[3] = 0x00;
+   }
 
    spu.frag_test = (frag_test_func) depth_stencil_code_buffer;
    spu.read_depth = state->read_depth;