swr: don't claim to allow setting layer/viewport from VS
[mesa.git] / src / gallium / drivers / swr / swr_shader.cpp
index f26467e078e8f9e995679cafaa1b2faa06dd16f9..04637e506f87816e7c9976e214bbb9b59885e297 100644 (file)
  * IN THE SOFTWARE.
  ***************************************************************************/
 
+// llvm redefines DEBUG
+#pragma push_macro("DEBUG")
+#undef DEBUG
 #include "JitManager.h"
+#include "llvm-c/Core.h"
+#include "llvm/Support/CBindingWrapping.h"
+#pragma pop_macro("DEBUG")
+
 #include "state.h"
 #include "state_llvm.h"
 #include "builder.h"
 
-#include "llvm-c/Core.h"
-#include "llvm/Support/CBindingWrapping.h"
-
 #include "tgsi/tgsi_strings.h"
 #include "gallivm/lp_bld_init.h"
 #include "gallivm/lp_bld_flow.h"
 #include "swr_state.h"
 #include "swr_screen.h"
 
+using namespace SwrJit;
+
+static unsigned
+locate_linkage(ubyte name, ubyte index, struct tgsi_shader_info *info);
+
 bool operator==(const swr_jit_fs_key &lhs, const swr_jit_fs_key &rhs)
 {
    return !memcmp(&lhs, &rhs, sizeof(lhs));
@@ -119,6 +128,11 @@ swr_generate_vs_key(struct swr_jit_vs_key &key,
 {
    memset(&key, 0, sizeof(key));
 
+   key.clip_plane_mask =
+      swr_vs->info.base.clipdist_writemask ?
+      swr_vs->info.base.clipdist_writemask & ctx->rasterizer->clip_plane_enable :
+      ctx->rasterizer->clip_plane_enable;
+
    swr_generate_sampler_key(swr_vs->info, ctx, PIPE_SHADER_VERTEX, key);
 }
 
@@ -145,18 +159,6 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key)
 {
    struct swr_vertex_shader *swr_vs = ctx->vs;
 
-   swr_vs->linkageMask = 0;
-
-   for (unsigned i = 0; i < swr_vs->info.base.num_outputs; i++) {
-      switch (swr_vs->info.base.output_semantic_name[i]) {
-      case TGSI_SEMANTIC_POSITION:
-         break;
-      default:
-         swr_vs->linkageMask |= (1 << i);
-         break;
-      }
-   }
-
    LLVMValueRef inputs[PIPE_MAX_SHADER_INPUTS][TGSI_NUM_CHANNELS];
    LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][TGSI_NUM_CHANNELS];
 
@@ -251,6 +253,63 @@ BuilderSWR::CompileVS(struct swr_context *ctx, swr_jit_vs_key &key)
       }
    }
 
+   if (ctx->rasterizer->clip_plane_enable ||
+       swr_vs->info.base.culldist_writemask) {
+      unsigned clip_mask = ctx->rasterizer->clip_plane_enable;
+
+      unsigned cv = 0;
+      if (swr_vs->info.base.writes_clipvertex) {
+         cv = 1 + locate_linkage(TGSI_SEMANTIC_CLIPVERTEX, 0,
+                                 &swr_vs->info.base);
+      } else {
+         for (int i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
+            if (swr_vs->info.base.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
+                swr_vs->info.base.output_semantic_index[i] == 0) {
+               cv = i;
+               break;
+            }
+         }
+      }
+      LLVMValueRef cx = LLVMBuildLoad(gallivm->builder, outputs[cv][0], "");
+      LLVMValueRef cy = LLVMBuildLoad(gallivm->builder, outputs[cv][1], "");
+      LLVMValueRef cz = LLVMBuildLoad(gallivm->builder, outputs[cv][2], "");
+      LLVMValueRef cw = LLVMBuildLoad(gallivm->builder, outputs[cv][3], "");
+
+      for (unsigned val = 0; val < PIPE_MAX_CLIP_PLANES; val++) {
+         // clip distance overrides user clip planes
+         if ((swr_vs->info.base.clipdist_writemask & clip_mask & (1 << val)) ||
+             ((swr_vs->info.base.culldist_writemask << swr_vs->info.base.num_written_clipdistance) & (1 << val))) {
+            unsigned cv = 1 + locate_linkage(TGSI_SEMANTIC_CLIPDIST, val < 4 ? 0 : 1,
+                                             &swr_vs->info.base);
+            if (val < 4) {
+               LLVMValueRef dist = LLVMBuildLoad(gallivm->builder, outputs[cv][val], "");
+               STORE(unwrap(dist), vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_LO_SLOT, val});
+            } else {
+               LLVMValueRef dist = LLVMBuildLoad(gallivm->builder, outputs[cv][val - 4], "");
+               STORE(unwrap(dist), vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_HI_SLOT, val - 4});
+            }
+            continue;
+         }
+
+         if (!(clip_mask & (1 << val)))
+            continue;
+
+         Value *px = LOAD(GEP(hPrivateData, {0, swr_draw_context_userClipPlanes, val, 0}));
+         Value *py = LOAD(GEP(hPrivateData, {0, swr_draw_context_userClipPlanes, val, 1}));
+         Value *pz = LOAD(GEP(hPrivateData, {0, swr_draw_context_userClipPlanes, val, 2}));
+         Value *pw = LOAD(GEP(hPrivateData, {0, swr_draw_context_userClipPlanes, val, 3}));
+         Value *dist = FADD(FMUL(unwrap(cx), VBROADCAST(px)),
+                            FADD(FMUL(unwrap(cy), VBROADCAST(py)),
+                                 FADD(FMUL(unwrap(cz), VBROADCAST(pz)),
+                                      FMUL(unwrap(cw), VBROADCAST(pw)))));
+
+         if (val < 4)
+            STORE(dist, vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_LO_SLOT, val});
+         else
+            STORE(dist, vtxOutput, {0, 0, VERTEX_CLIPCULL_DIST_HI_SLOT, val - 4});
+      }
+   }
+
    RET_VOID();
 
    gallivm_verify_function(gallivm, wrap(pFunction));
@@ -421,8 +480,14 @@ BuilderSWR::CompileFS(struct swr_context *ctx, swr_jit_fs_key &key)
          inputs[attrib][3] = wrap(VIMMED1(1.0f));
          continue;
       } else if (semantic_name == TGSI_SEMANTIC_POSITION) { // gl_FragCoord
-         inputs[attrib][0] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vX, PixelPositions_center}, "vX"));
-         inputs[attrib][1] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vY, PixelPositions_center}, "vY"));
+         if (swr_fs->info.base.properties[TGSI_PROPERTY_FS_COORD_PIXEL_CENTER] ==
+             TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER) {
+            inputs[attrib][0] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vX, PixelPositions_center}, "vX"));
+            inputs[attrib][1] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vY, PixelPositions_center}, "vY"));
+         } else {
+            inputs[attrib][0] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vX, PixelPositions_UL}, "vX"));
+            inputs[attrib][1] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vY, PixelPositions_UL}, "vY"));
+         }
          inputs[attrib][2] = wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vZ}, "vZ"));
          inputs[attrib][3] =
             wrap(LOAD(pPS, {0, SWR_PS_CONTEXT_vOneOverW, PixelPositions_center}, "vOneOverW"));