* 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));
{
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);
}
{
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];
}
}
+ 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));
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"));