summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/swr/rasterizer/jitter
diff options
context:
space:
mode:
authorGeorge Kyriazis <[email protected]>2017-02-02 21:16:47 -0600
committerTim Rowley <[email protected]>2017-02-23 16:36:18 -0600
commitdcac48bfee545660dffbf23bd92a0939b19ffd18 (patch)
treeed9da084c5b41ca162190a3bf511e7c294f8397f /src/gallium/drivers/swr/rasterizer/jitter
parent669d8f626f64cee1bc74ef7869aac8585b6dcfe6 (diff)
swr: fix index buffers with non-zero indices
Fix issue with index buffers that do not contain a 0 index. 0 index can be a non-valid index if the (copied) vertex buffers are a subset of the user's (which happens because we only copy the range between min & max). Core will use an index passed in from the driver to replace invalid indices. Only do this for calls that contain non-zero indices, to minimize performance Reviewed-by: Bruce Cherniak <[email protected]> cost.
Diffstat (limited to 'src/gallium/drivers/swr/rasterizer/jitter')
-rw-r--r--src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp60
-rw-r--r--src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h2
2 files changed, 56 insertions, 6 deletions
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp
index 901bce69468..ffa7605a919 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp
+++ b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.cpp
@@ -309,11 +309,29 @@ void FetchJit::JitLoadVertices(const FETCH_COMPILE_STATE &fetchState, Value* str
Value* startVertexOffset = MUL(Z_EXT(startOffset, mInt64Ty), stride);
+ Value *minVertex = NULL;
+ Value *minVertexOffset = NULL;
+ if (fetchState.bPartialVertexBuffer) {
+ // fetch min index for low bounds checking
+ minVertex = GEP(streams, {C(ied.StreamIndex), C(SWR_VERTEX_BUFFER_STATE_minVertex)});
+ minVertex = LOAD(minVertex);
+ if (!fetchState.bDisableIndexOOBCheck) {
+ minVertexOffset = MUL(Z_EXT(minVertex, mInt64Ty), stride);
+ }
+ }
+
// Load from the stream.
for(uint32_t lane = 0; lane < mVWidth; ++lane)
{
// Get index
Value* index = VEXTRACT(vCurIndices, C(lane));
+
+ if (fetchState.bPartialVertexBuffer) {
+ // clamp below minvertex
+ Value *isBelowMin = ICMP_SLT(index, minVertex);
+ index = SELECT(isBelowMin, minVertex, index);
+ }
+
index = Z_EXT(index, mInt64Ty);
Value* offset = MUL(index, stride);
@@ -321,10 +339,14 @@ void FetchJit::JitLoadVertices(const FETCH_COMPILE_STATE &fetchState, Value* str
offset = ADD(offset, startVertexOffset);
if (!fetchState.bDisableIndexOOBCheck) {
- // check for out of bound access, including partial OOB, and mask them to 0
+ // check for out of bound access, including partial OOB, and replace them with minVertex
Value *endOffset = ADD(offset, C((int64_t)info.Bpp));
Value *oob = ICMP_ULE(endOffset, size);
- offset = SELECT(oob, offset, ConstantInt::get(mInt64Ty, 0));
+ if (fetchState.bPartialVertexBuffer) {
+ offset = SELECT(oob, offset, minVertexOffset);
+ } else {
+ offset = SELECT(oob, offset, ConstantInt::get(mInt64Ty, 0));
+ }
}
Value* pointer = GEP(stream, offset);
@@ -732,6 +754,13 @@ void FetchJit::JitGatherVertices(const FETCH_COMPILE_STATE &fetchState,
Value *maxVertex = GEP(streams, {C(ied.StreamIndex), C(SWR_VERTEX_BUFFER_STATE_maxVertex)});
maxVertex = LOAD(maxVertex);
+ Value *minVertex = NULL;
+ if (fetchState.bPartialVertexBuffer) {
+ // min vertex index for low bounds OOB checking
+ minVertex = GEP(streams, {C(ied.StreamIndex), C(SWR_VERTEX_BUFFER_STATE_minVertex)});
+ minVertex = LOAD(minVertex);
+ }
+
Value *vCurIndices;
Value *startOffset;
if(ied.InstanceEnable)
@@ -769,9 +798,16 @@ void FetchJit::JitGatherVertices(const FETCH_COMPILE_STATE &fetchState,
// if we have a start offset, subtract from max vertex. Used for OOB check
maxVertex = SUB(Z_EXT(maxVertex, mInt64Ty), Z_EXT(startOffset, mInt64Ty));
- Value* neg = ICMP_SLT(maxVertex, C((int64_t)0));
+ Value* maxNeg = ICMP_SLT(maxVertex, C((int64_t)0));
// if we have a negative value, we're already OOB. clamp at 0.
- maxVertex = SELECT(neg, C(0), TRUNC(maxVertex, mInt32Ty));
+ maxVertex = SELECT(maxNeg, C(0), TRUNC(maxVertex, mInt32Ty));
+
+ if (fetchState.bPartialVertexBuffer) {
+ // similary for min vertex
+ minVertex = SUB(Z_EXT(minVertex, mInt64Ty), Z_EXT(startOffset, mInt64Ty));
+ Value *minNeg = ICMP_SLT(minVertex, C((int64_t)0));
+ minVertex = SELECT(minNeg, C(0), TRUNC(minVertex, mInt32Ty));
+ }
// Load the in bounds size of a partially valid vertex
Value *partialInboundsSize = GEP(streams, {C(ied.StreamIndex), C(SWR_VERTEX_BUFFER_STATE_partialInboundsSize)});
@@ -791,8 +827,20 @@ void FetchJit::JitGatherVertices(const FETCH_COMPILE_STATE &fetchState,
Value* vMaxVertex = VBROADCAST(maxVertex);
Value* vPartialOOBMask = ICMP_EQ(vCurIndices, vMaxVertex);
- // are vertices are fully in bounds?
- Value* vGatherMask = ICMP_ULT(vCurIndices, vMaxVertex);
+ // are vertices fully in bounds?
+ Value* vMaxGatherMask = ICMP_ULT(vCurIndices, vMaxVertex);
+
+ Value *vGatherMask;
+ if (fetchState.bPartialVertexBuffer) {
+ // are vertices below minVertex limit?
+ Value *vMinVertex = VBROADCAST(minVertex);
+ Value *vMinGatherMask = ICMP_UGE(vCurIndices, vMinVertex);
+
+ // only fetch lanes that pass both tests
+ vGatherMask = AND(vMaxGatherMask, vMinGatherMask);
+ } else {
+ vGatherMask = vMaxGatherMask;
+ }
// blend in any partially OOB indices that have valid elements
vGatherMask = SELECT(vPartialOOBMask, vElementInBoundsMask, vGatherMask);
diff --git a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h
index 622608a820b..68c6f603985 100644
--- a/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h
+++ b/src/gallium/drivers/swr/rasterizer/jitter/fetch_jit.h
@@ -104,6 +104,7 @@ struct FETCH_COMPILE_STATE
bool bDisableIndexOOBCheck; // If enabled, FetchJit will exclude index OOB check
bool bEnableCutIndex{ false }; // Compares indices with the cut index and returns a cut mask
bool bVertexIDOffsetEnable{ false }; // Offset vertexID by StartVertex for non-indexed draws or BaseVertex for indexed draws
+ bool bPartialVertexBuffer{ false }; // for indexed draws, map illegal indices to a known resident vertex
FETCH_COMPILE_STATE(bool disableVGATHER = false, bool diableIndexOOBCheck = false):
bDisableVGATHER(disableVGATHER), bDisableIndexOOBCheck(diableIndexOOBCheck){ };
@@ -117,6 +118,7 @@ struct FETCH_COMPILE_STATE
if (bEnableCutIndex != other.bEnableCutIndex) return false;
if (cutIndex != other.cutIndex) return false;
if (bVertexIDOffsetEnable != other.bVertexIDOffsetEnable) return false;
+ if (bPartialVertexBuffer != other.bPartialVertexBuffer) return false;
for(uint32_t i = 0; i < numAttribs; ++i)
{