diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2018-12-07 13:31:06 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-07 13:31:06 -0800 |
| commit | 135eaff6b892fc91a398714ddcf7ef377cd4cccb (patch) | |
| tree | e69f30a4fadfdb834ea141c1ec9efc862ccc70d3 /tests/hlsl/dxsdk/AdaptiveTessellationCS40 | |
| parent | b0c2423f00b910f2f4d5010e6a04114112e294fd (diff) | |
Change how buffers are emitted (#741)
* Change how buffers are emitted
This is a change with a lot of pieces, which can't always be separated out cleanly. I'm going to walk through them in what I hope is a logical order.
The main goal of this change was to allow arrays of structured buffers to translate to Vulkan. Consider two declarations of structured buffers in HLSL/Slang:
```hlsl
StructuredBuffer<X> single;
StructuredBuffer<Y> multiple[10];
```
The current translation logic was handling `single` by translating it into an *unnamed* GLSL `buffer` block like:
```glsl
layout(std430)
buffer _S1
{
X single[];
};
```
That syntax allows an expression like `single[i]` in Slang to be translated simply as `single[i]` in GLSL.
But that naive translating doesn't work for `multiple`, since we need to declare a array of blocks in GLSL, which requires giving the whole thing a name:
```glsl
layout(std430)
buffer _S2
{
Y _data[];
} multiple[10];
```
Now a reference to `multiple[i][j]` in Slang needs to become `multiple[i]._data[j]` in GLSL.
To avoid having way too many special cases around single structured buffers vs. arrays, it makes sense to allows emit things in the latter form, so that we instead lower `single` as:
```glsl
layout(std430)
buffer _S1
{
X _data[];
} single;
```
So that now a reference to `single[i]` becomes `single._data[i]` in GLSL.
Most of that can be handled in the standard library translation of the structured buffer indexing operations.
The only wrinkle there is that there were some *old* special-case instructions in the IR intended to handle buffer load/store operations (these were added back when I was trying to keep the "VM" path working). These aren't really needed to have structured-buffer operations work; they can be handled as ordinary functions as far as the stdlib is concerned. I removed the old instructions.
Along the way, it became clear that a few other cases follow the same pattern. Byte-addressed buffers are an obvious case. We were lowering HLSL/Slang:
```hlsl
ByteAddressBuffer b;
...
uint x = b.Load(0);
```
to GLSL like:
```glsl
layout(std430)
buffer _S1
{
uint b[];
};
...
uint x = b[0];
```
That logic would fail for arrays the same way that the structured buffer case was failing. The fix is the same: use named `buffer` blocks and then introduce an explicit `_data` field:
```glsl
layout(std430)
buffer _S1
{
uint _data[];
} b;
...
uint x = b._data[0];
```
Just like with structured buffers, all of the VK translation for operations on byte-addressed buffers can be implemented directly in teh stdlib, so once the emit logic was changed it was just a matter of adding `._data` to a bunch of VK tranlsations.
It turns out that arrays of constant buffers have more or less the same problem, and furthermore we have some problems with any code that directly uses the modern HLSL `ConstantBuffer<T>` type.
Note: the emit logic around constant buffers sometimes refers to "parameter groups" because that is being used in the compiler as a catch-all term for constant buffers, texture buffers, and parameter blocks.
The existing code was going out of its way to reproduce the way that constant buffer declarations are implicitly referenced in HLSL:
```hlsl
cbuffer C { float f; }
...
float tmp = f; // No reference to `C` here
```
This can be seen in the emit logic with the `isDerefBaseImplicit` function, which is used to take the internal IR representation for a reference to `f` (which is closer to the expression `(*C).f` or `C->f`) and leave off any reference to `C` so that we emit just `f`.
That kind of logic just flat out doesn't work in some important cases. Arrays of constant buffers are a clear one:
```hlsl
ConstantBuffer<X> cbArray[3];
...
X x = cbArray[0];
```
There is no way to translate that to an ordinary `cbuffer` declaration at all. The same problem can be created without arrays, though:
```hlsl
ConstantBuffer<X> singleCB;
...
X x = singleCB;
```
The current strategy for translating constant buffers was translating `singleCB` into a `cbuffer` declaration that reproduced the fields of `X` as its members, which just wouldn't work:
```hlsl
cbuffer singleCB
{
float f; // field of `X`
}
...
X x = singleCB; // ERROR: there is nothing named `singleCB` in this HLSL
```
The new strategy is more consistent. We still generate a `cbuffer` declaration for a single constant buffer, but we always give it a single field of the chosen element type:
```hlsl
cbuffer singleCB
{
X singleCB;
}
...
X x = singleCB; // this works fine!
```
And in the array case we generate code that uses the explicit `ConstantBuffer<T>` type:
```hlsl
ConstantBuffer<X> cbArray[3];
...
X x = cbArray[0];
```
The GLSL output is more complicated because unlike with HLSL there is no implicit conversion from a uniform block to its element type (there is no notion of an element type). The array case thus needs a `_data` field similar to what we do for structured buffers:
```glsl
layout(std140)
uniform _S3
{
X _data;
} cbArray[3];
...
X x = cbArray[0]._data;
```
And then the non-array case needs to have a similar `_data` field for consistency:
```glsl
layout(std140)
uniform _S1
{
X _data;
} singleCB;
...
X x = singleCB._data;
```
This is handled by inserting the necessary reference to `_data` whenever we dereference a constant buffer, either as part of a load instruction (loading from the whole CB as a pointer), or an `IRFieldAddress` instruction which forms a pointer into the CB (e.g., `&(singleCB->f)` becomes `singleCB._data.f`).
The current emit logic handles `ParameterBlock<X>` differently from `ConstantBuffer<X>`, but really only to allow parameter blocks to be explicitly named in the output, while constant buffers were left implicit by default. Thus the only difference was a legacy one (from back when trying to exactly reproduce the HLSL text we got as input was considered an important goal), and the new approach to emitting constant buffers would get rid of it.
I removed the separate logic for emitting `ParameterBlock<X>` and just let the handling for constant buffers deal with it.
Note that any resource types inside of a `ParameterBlock<X>` would have been moved out as part of legalization, so that a parameter block is 100% equivalent to a constant buffer when it comes time to emit code.
Unsurprisingly, changing the way we generate HLSL and GLSL output for all these buffer types meant that any tests that were directly comparing the output of `slangc` against `fxc`, `dxc`, or `glslang` broke.
The basic approach to fixing the breakage in GLSL tests was to update the GLSL baseline to reflect the new output startegy. In some cases I used macros to name the various `_S<digits>` temporaries so that future renaming will hopefully be easier (it would be great if we auto-generated temporary names with a bit more context). There was one GLSL test (`tests/bugs/vk-structured-buffer-binding`) that was using raw GLSL expected output, and this was changed to use a GLSL baseline to generate SPIR-V for comparison.
For HLSL tests we were sometimes running the same input file through `slangc` and `fxc`/`dxc`, and in these cases I macro-ized the various `cbuffer` declarations to generate different declarations depending on the compiler.
I completely dropped the tests coming from the D3D SDK because they aren't providing much coverage, and updating them would change them so far from the original code that the purported benefit (using a body of existing shaders) would be lost.
I also dropped the explicit matrix layout qualifiers in the `matrix-layout` test because the new output strategy breaks those for GLSL (you can't put matrix layout qualifiers on `struct` fields, and now the body of every constant buffer is inside a `struct`). This isn't as big of a loss as it seems, because our handling of those qualifiers wasn't really right to begin with. Slang users should only be setting the matrix layout mode globally (and we should probably switch to error out on the explicit qualifiers for now).
The other thing that got dropped is tests involving `packoffset` modifiers.
Slang already warns that it doesn't support these, and the way they were used in the test cases is actually misleading. For the binding/layout-related tests, the goal was to show that Slang reproduces the same layout as fxc, in which case explicitly enforcing a layout via `packoffset` seems like cheating (are we sure we enforced the layout fxc would have produced?). The real reason was that Slang used to emit explicit `packoffset` on *every* field of a `cbuffer` it would output, because of an `fxc` bug where you couldn't use `register` on textures/samplers declared inside a `cbuffer` unless *every* field in the `cbuffer` used a `register` or `packoffset` modifier. Slang hasn't required that behavior in a while because it now splits textures and samplers, and the one test case where we needed `packoffset` to work around the `fxc` bug in the baseline HLSL has been macro-ified even more to work around the bug.
The amount of churn in the test cases is unfortunate, but it continues to point at the weakness of any testing strategy that checks for exact equivalent between Slang's output and that of other compilers. We need to keep working to replace these tests with better alternatives.
In `check.cpp` there is logic to perform implicit dereferencing, so that if you write `obj.f` where `obj` is a `ConstantBuffer<X>` (or some other "pointer-like" type) and `f` is a field in `X`, then this effectively translates as `(*obj).f`. That is, we dereference the value of type `ConstantBuffer<X>` to get a value of type `X`, and then refer to the field of the `X` value.
There was a problem where the logic to insert that kind of implicit dereference operation was using a reference (`auto& type = ...`) for the type of the expression being dereferenced, and then clobbering it. This would mean that an expression of type `ConstantBuffer<X>` would have its type overwritten to be just `X` and then codegen would break later on.
I'm not sure how we haven't run into that before.
The `array-of-buffers` test case was added to confirm that we now support arrays of constant, structured, and byte-address buffers for both DXIL and SPIR-V output.
Okay, so that was a lot of stuff, but hopefully it is clear how this all works to make the output of the compiler more consistent and explicit, while also supporting the required new functionality.
* fixup: review feedback
Diffstat (limited to 'tests/hlsl/dxsdk/AdaptiveTessellationCS40')
9 files changed, 0 insertions, 1746 deletions
diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/Render.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/Render.hlsl deleted file mode 100644 index c6b4ac197..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/Render.hlsl +++ /dev/null @@ -1,65 +0,0 @@ -//TEST(smoke):COMPARE_HLSL:-no-mangle -profile sm_4_0 -entry RenderBaseVS -stage vertex -entry RenderPS -stage fragment - -#ifndef __SLANG__ -#define cbPerObject cbPerObject_0 -#define g_mWorldViewProjection g_mWorldViewProjection_0 -#endif - - -//-------------------------------------------------------------------------------------- -// File: Render.hlsl -// -// The shaders for rendering tessellated mesh and base mesh -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- -cbuffer cbPerObject : register( b0 ) -{ - row_major matrix g_mWorldViewProjection ;//SLANG: : packoffset( c0 ); -} - -// The tessellated vertex structure -struct TessedVertex -{ - uint BaseTriID; // Which triangle of the base mesh this tessellated vertex belongs to? - float2 bc; // Barycentric coordinates with regard to the base triangle -}; -Buffer<float4> g_base_vb_buffer : register(t0); // Base mesh vertex buffer -StructuredBuffer<TessedVertex> g_TessedVertices : register(t1); // Tessellated mesh vertex buffer - -float4 bary_centric(float4 v1, float4 v2, float4 v3, float2 bc) -{ - return (1 - bc.x - bc.y) * v1 + bc.x * v2 + bc.y * v3; -} - -float4 RenderVS( uint vertid : SV_VertexID ) : SV_POSITION -{ - TessedVertex input = g_TessedVertices[vertid]; - - // Get the positions of the three vertices of the base triangle - float4 v[3]; - [unroll] - for (int i = 0; i < 3; ++ i) - { - uint vert_id = input.BaseTriID * 3 + i; - v[i] = g_base_vb_buffer[vert_id]; - } - - // Calculate the position of this tessellated vertex from barycentric coordinates and then project it - return mul(bary_centric(v[0], v[1], v[2], input.bc), g_mWorldViewProjection); -} - -struct BaseVertex -{ - float4 pos : POSITION; -}; - -float4 RenderBaseVS( BaseVertex input ) : SV_POSITION -{ - return mul( input.pos, g_mWorldViewProjection ); -} - -float4 RenderPS() : SV_TARGET -{ - return float4( 1.0f, 1.0f, 0.0f, 1.0f ); -}
\ No newline at end of file diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl deleted file mode 100644 index a4472179f..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/ScanCS.hlsl +++ /dev/null @@ -1,109 +0,0 @@ -//TEST_DISABLED:COMPARE_HLSL:-no-mangle -profile cs_4_0 -entry CSScanInBucket -entry CSScanBucketResult -entry CSScanAddBucketResult -//-------------------------------------------------------------------------------------- -// File: ScanCS.hlsl -// -// A simple inclusive prefix sum(scan) implemented in CS4.0, -// using a typical up sweep and down sweep scheme -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- -StructuredBuffer<uint2> Input : register( t0 ); // Change uint2 here if scan other types, and -RWStructuredBuffer<uint2> Result : register( u0 ); // also here - -#define groupthreads 128 -groupshared uint4 bucket[groupthreads]; // Change uint4 to the "type x2" if scan other types, e.g. - // if scan uint2, then put uint4 here, - // if scan float, then put float2 here - -void CSScan( uint3 DTid, uint GI, uint2 x ) // Change the type of x here if scan other types -{ - // since CS40 can only support one shared memory for one shader, we use .xy and .zw as ping-ponging buffers - // if scan a single element type like int, search and replace all .xy to .x and .zw to .y below - bucket[GI].xy = x; - bucket[GI].zw = 0; - - // Up sweep - [unroll] - for ( uint stride = 2; stride <= groupthreads; stride <<= 1 ) - { - GroupMemoryBarrierWithGroupSync(); - - if ( (GI & (stride - 1)) == (stride - 1) ) - { - bucket[GI].xy += bucket[GI - stride/2].xy; - } - } - - if ( GI == (groupthreads - 1) ) - { - bucket[GI].xy = 0; - } - - // Down sweep - bool n = true; - [unroll] - for ( stride = groupthreads / 2; stride >= 1; stride >>= 1 ) - { - GroupMemoryBarrierWithGroupSync(); - - uint a = stride - 1; - uint b = stride | a; - - if ( n ) // ping-pong between passes - { - if ( ( GI & b) == b ) - { - bucket[GI].zw = bucket[GI-stride].xy + bucket[GI].xy; - } else - if ( (GI & a) == a ) - { - bucket[GI].zw = bucket[GI+stride].xy; - } else - { - bucket[GI].zw = bucket[GI].xy; - } - } else - { - if ( ( GI & b) == b ) - { - bucket[GI].xy = bucket[GI-stride].zw + bucket[GI].zw; - } else - if ( (GI & a) == a ) - { - bucket[GI].xy = bucket[GI+stride].zw; - } else - { - bucket[GI].xy = bucket[GI].zw; - } - } - - n = !n; - } - - Result[DTid.x] = bucket[GI].zw + x; -} - -// scan in each bucket -[numthreads( groupthreads, 1, 1 )] -void CSScanInBucket( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI: SV_GroupIndex ) -{ - uint2 x = Input[DTid.x]; // Change the type of x here if scan other types - CSScan( DTid, GI, x ); -} - -// record and scan the sum of each bucket -[numthreads( groupthreads, 1, 1 )] -void CSScanBucketResult( uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI: SV_GroupIndex ) -{ - uint2 x = Input[DTid.x*groupthreads - 1]; // Change the type of x here if scan other types - CSScan( DTid, GI, x ); -} - -StructuredBuffer<uint2> Input1 : register( t1 ); - -// add the bucket scanned result to each bucket to get the final result -[numthreads( groupthreads, 1, 1 )] -void CSScanAddBucketResult( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI: SV_GroupIndex ) -{ - Result[DTid.x] = Input[DTid.x] + Input1[Gid.x]; -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_EdgeFactorCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_EdgeFactorCS.hlsl deleted file mode 100644 index 1bd204efc..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_EdgeFactorCS.hlsl +++ /dev/null @@ -1,217 +0,0 @@ -//TEST_IGNORE_FILE: Currently failing due to Slang compiler issues. -//TEST:COMPARE_HLSL: -profile cs_4_0 -entry CSEdgeFactor -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_EdgeFactorCS.hlsl -// -// The CS to compute edge tessellation factor acoording to current world, view, projection matrix -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- - -// http://jgt.akpeters.com/papers/akeninemoller01/tribox.html -bool planeBoxOverlap(float3 normal, float d, float3 maxbox) -{ - float3 vmin = maxbox, vmax = maxbox; - [unroll] - for (int q = 0;q <= 2; ++ q) - { - if (normal[q] > 0.0f) - { - vmin[q] *= -1; - } - else - { - vmax[q] *= -1; - } - } - if (dot(normal, vmin) + d > 0.0f) - { - return false; - } - if (dot(normal, vmax) + d >= 0.0f) - { - return true; - } - - return false; -} - -/*======================== X-tests ========================*/ -bool AXISTEST_X01(float3 v0, float3 v2, float3 boxhalfsize, float2 ab, float2 fab) -{ - float p0 = ab.x * v0.y - ab.y * v0.z; - float p2 = ab.x * v2.y - ab.y * v2.z; - float min_v = min(p0, p2); - float max_v = max(p0, p2); - float rad = dot(fab, boxhalfsize.yz); - return (min_v < rad) && (max_v > -rad); -} - -bool AXISTEST_X2(float3 v0, float3 v1, float3 boxhalfsize, float2 ab, float2 fab) -{ - float p0 = ab.x * v0.y - ab.y * v0.z; - float p1 = ab.x * v1.y - ab.y * v1.z; - float min_v = min(p0, p1); - float max_v = max(p0, p1); - float rad = dot(fab, boxhalfsize.yz); - return (min_v < rad) && (max_v > -rad); -} - -/*======================== Y-tests ========================*/ -bool AXISTEST_Y02(float3 v0, float3 v2, float3 boxhalfsize, float2 ab, float2 fab) -{ - float p0 = -ab.x * v0.x + ab.y * v0.z; - float p2 = -ab.x * v2.x + ab.y * v2.z; - float min_v = min(p0, p2); - float max_v = max(p0, p2); - float rad = dot(fab, boxhalfsize.xz); - return (min_v < rad) && (max_v > -rad); -} - -bool AXISTEST_Y1(float3 v0, float3 v1, float3 boxhalfsize, float2 ab, float2 fab) -{ - float p0 = -ab.x * v0.x + ab.y * v0.z; - float p1 = -ab.x * v1.x + ab.y * v1.z; - float min_v = min(p0, p1); - float max_v = max(p0, p1); - float rad = dot(fab, boxhalfsize.xz); - return (min_v < rad) && (max_v > -rad); -} - -/*======================== Z-tests ========================*/ -bool AXISTEST_Z12(float3 v1, float3 v2, float3 boxhalfsize, float2 ab, float2 fab) -{ - float p1 = ab.x * v1.x - ab.y * v1.y; - float p2 = ab.x * v2.x - ab.y * v2.y; - float min_v = min(p1, p2); - float max_v = max(p1, p2); - float rad = dot(fab, boxhalfsize.xy); - return (min_v < rad) && (max_v > -rad); -} - -bool AXISTEST_Z0(float3 v0, float3 v1, float3 boxhalfsize, float2 ab, float2 fab) -{ - float p0 = ab.x * v0.x - ab.y * v0.y; - float p1 = ab.x * v1.x - ab.y * v1.y; - float min_v = min(p0, p1); - float max_v = max(p0, p1); - float rad = dot(fab, boxhalfsize.xy); - return (min_v < rad) && (max_v > -rad); -} - -bool triBoxOverlap(float3 boxcenter,float3 boxhalfsize,float3 triverts0, float3 triverts1, float3 triverts2) -{ - /* use separating axis theorem to test overlap between triangle and box */ - /* need to test for overlap in these directions: */ - /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ - /* we do not even need to test these) */ - /* 2) normal of the triangle */ - /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ - /* this gives 3x3=9 more tests */ - - /* This is the fastest branch on Sun */ - /* move everything so that the boxcenter is in (0,0,0) */ - float3 v0 = triverts0 - boxcenter; - float3 v1 = triverts1 - boxcenter; - float3 v2 = triverts2 - boxcenter; - - /* compute triangle edges */ - float3 e0 = v1 - v0; /* tri edge 0 */ - float3 e1 = v2 - v1; /* tri edge 1 */ - float3 e2 = v0 - v2; /* tri edge 2 */ - - /* Bullet 3: */ - /* test the 9 tests first (this was faster) */ - float3 fe = abs(e0); - if (!AXISTEST_X01(v0, v2, boxhalfsize, e0.zy, fe.zy) - || !AXISTEST_Y02(v0, v2, boxhalfsize, e0.zx, fe.zx) - || !AXISTEST_Z12(v1, v2, boxhalfsize, e0.yx, fe.yx)) - { - return false; - } - - fe = abs(e1); - if (!AXISTEST_X01(v0, v2, boxhalfsize, e1.zy, fe.zy) - || !AXISTEST_Y02(v0, v2, boxhalfsize, e1.zx, fe.zx) - || !AXISTEST_Z0(v0, v1, boxhalfsize, e1.yx, fe.yx)) - { - return false; - } - - fe = abs(e2); - if (!AXISTEST_X2(v0, v1, boxhalfsize, e2.zy, fe.zy) - || !AXISTEST_Y1(v0, v1, boxhalfsize, e2.zx, fe.zx) - || !AXISTEST_Z12(v1, v2, boxhalfsize, e2.yx, fe.yx)) - { - return false; - } - - /* Bullet 1: */ - /* first test overlap in the {x,y,z}-directions */ - /* find min, max of the triangle each direction, and test for overlap in */ - /* that direction -- this is equivalent to testing a minimal AABB around */ - /* the triangle against the AABB */ - - float3 min_v = min(min(v0, v1), v2); - float3 max_v = max(max(v0, v1), v2); - if ((min_v.x > boxhalfsize.x || max_v.x < -boxhalfsize.x) - || (min_v.y > boxhalfsize.y || max_v.y < -boxhalfsize.y) - || (min_v.z > boxhalfsize.z || max_v.z < -boxhalfsize.z)) - { - return false; - } - - /* Bullet 2: */ - /* test if the box intersects the plane of the triangle */ - /* compute plane equation of triangle: normal*x+d=0 */ - float3 normal = cross(e0, e1); - float d = -dot(normal, v0); /* plane eq: normal.x+d=0 */ - if (!planeBoxOverlap(normal, d, boxhalfsize)) - { - return false; - } - - return true; /* box and triangle overlaps */ -} - - -Buffer<float4> InputVertices : register(t0); -RWStructuredBuffer<float4> EdgeFactorBufOut : register(u0); - -cbuffer cb -{ - row_major matrix g_matWVP; - float2 g_tess_edge_length_scale; - int num_triangles; - float dummy; -} - -[numthreads(128, 1, 1)] -void CSEdgeFactor( uint3 DTid : SV_DispatchThreadID ) -{ - if (DTid.x < num_triangles) - { - float4 p0 = mul(InputVertices[DTid.x*3+0], g_matWVP); - float4 p1 = mul(InputVertices[DTid.x*3+1], g_matWVP); - float4 p2 = mul(InputVertices[DTid.x*3+2], g_matWVP); - p0 = p0 / p0.w; - p1 = p1 / p1.w; - p2 = p2 / p2.w; - - float4 factor; - // Only triangles which are completely inside or intersect with the view frustum are taken into account - if ( triBoxOverlap( float3(0, 0, 0.5), float3(1.02, 1.02, 0.52), p0.xyz, p1.xyz, p2.xyz ) ) - { - factor.x = length((p0.xy - p2.xy) * g_tess_edge_length_scale); - factor.y = length((p1.xy - p0.xy) * g_tess_edge_length_scale); - factor.z = length((p2.xy - p1.xy) * g_tess_edge_length_scale); - factor.w = min(min(factor.x, factor.y), factor.z); - factor = clamp(factor, 0, 9); - } else - { - factor = 0; - } - - EdgeFactorBufOut[DTid.x] = factor; - } -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_NumVerticesIndicesCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_NumVerticesIndicesCS.hlsl deleted file mode 100644 index 672996589..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_NumVerticesIndicesCS.hlsl +++ /dev/null @@ -1,56 +0,0 @@ -//TEST_IGNORE_FILE: Currently failing due to Slang compiler issues. -//TEST:COMPARE_HLSL: -profile cs_4_0 -entry CSNumVerticesIndices -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_NumVerticesIndicesCS.hlsl -// -// The CS to compute number of vertices and triangles to be generated from edge tessellation factor -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- - -#include "TessellatorCS40_common.hlsl" - -StructuredBuffer<float4> InputEdgeFactor : register(t0); -RWStructuredBuffer<uint2> NumVerticesIndicesOut : register(u0); - -cbuffer cbCS : register(b1) -{ - uint4 g_param; -} - -[numthreads(128, 1, 1)] -void CSNumVerticesIndices( uint3 DTid : SV_DispatchThreadID ) -{ - if (DTid.x < g_param.x) - { - float4 edge_factor = InputEdgeFactor[DTid.x]; - - PROCESSED_TESS_FACTORS_TRI processedTessFactors; - int num_points = TriProcessTessFactors(edge_factor, processedTessFactors, g_partitioning); - - int num_index; - if (0 == num_points) - { - num_index = 0; - } - else if (3 == num_points) - { - num_index = 4; - } - else - { - int numRings = ((processedTessFactors.numPointsForOutsideInside.w + 1) / 2); // +1 is so even tess includes the center point, which we want to now - - int4 outsideInsideHalfTessFactor = int4(ceil(processedTessFactors.outsideInsideHalfTessFactor)); - uint3 n = NumStitchTransition(outsideInsideHalfTessFactor, processedTessFactors.outsideInsideTessFactorParity); - num_index = n.x + n.y + n.z; - num_index += TotalNumStitchRegular(true, DIAGONALS_MIRRORED, processedTessFactors.numPointsForOutsideInside.w, numRings - 1) * 3; - if( processedTessFactors.outsideInsideTessFactorParity.w == TESSELLATOR_PARITY_ODD ) - { - num_index += 4; - } - } - - NumVerticesIndicesOut[DTid.x] = uint2(num_points, num_index); - } -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_ScatterIDCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_ScatterIDCS.hlsl deleted file mode 100644 index f6f9081da..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_ScatterIDCS.hlsl +++ /dev/null @@ -1,45 +0,0 @@ -//TEST_DISABLED:COMPARE_HLSL:-no-mangle -profile cs_4_0 -entry CSScatterVertexTriIDIndexID -entry CSScatterIndexTriIDIndexID -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_ScatterIDCS.hlsl -// -// The CS to scatter vertex ID and triangle ID -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- -StructuredBuffer<uint2> InputScanned : register(t0); -RWStructuredBuffer<uint2> TriIDIndexIDOut : register(u0); - -cbuffer cbCS : register(b1) -{ - uint4 g_param; -} - -[numthreads(128, 1, 1)] -void CSScatterVertexTriIDIndexID( uint3 DTid : SV_DispatchThreadID ) -{ - if (DTid.x < g_param.x) - { - uint start = InputScanned[DTid.x-1].x; - uint end = InputScanned[DTid.x].x; - - for ( uint i = start; i < end; ++i ) - { - TriIDIndexIDOut[i] = uint2(DTid.x, i - start); - } - } -} - -[numthreads(128, 1, 1)] -void CSScatterIndexTriIDIndexID( uint3 DTid : SV_DispatchThreadID ) -{ - if (DTid.x < g_param.x) - { - uint start = InputScanned[DTid.x-1].y; - uint end = InputScanned[DTid.x].y; - - for ( uint i = start; i < end; ++i ) - { - TriIDIndexIDOut[i] = uint2(DTid.x, i - start); - } - } -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_TessellateIndicesCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_TessellateIndicesCS.hlsl deleted file mode 100644 index 8c0a5b63b..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_TessellateIndicesCS.hlsl +++ /dev/null @@ -1,628 +0,0 @@ -//TEST_IGNORE_FILE: Currently failing due to Slang compiler issues. -//TEST:COMPARE_HLSL: -profile cs_4_0 -entry CSTessellationIndices -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_TessellateIndicesCS.hlsl -// -// The CS to tessellate indices -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- - -#include "TessellatorCS40_common.hlsl" - -StructuredBuffer<uint2> InputTriIDIndexID : register(t0); -StructuredBuffer<float4> InputEdgeFactor : register(t1); -StructuredBuffer<uint2> InputScanned : register(t2); - -RWByteAddressBuffer TessedIndicesOut : register(u0); - -cbuffer cbCS : register(b1) -{ - uint4 g_param; -} - - -int TransformIndex1(int index, int vertices_base) -{ - return vertices_base + index; -} - -int TransformIndex2(int index, int vertices_base, INDEX_PATCH_CONTEXT IndexPatchContext) -{ - if( index >= IndexPatchContext.outsidePointIndexPatchBase ) // assumed remapped outide indices are > remapped inside vertices - { - if( index == IndexPatchContext.outsidePointIndexBadValue ) - { - index = IndexPatchContext.outsidePointIndexReplacementValue; - } - else - { - index += IndexPatchContext.outsidePointIndexDeltaToRealValue; - } - } - else - { - if( index == IndexPatchContext.insidePointIndexBadValue ) - { - index = IndexPatchContext.insidePointIndexReplacementValue; - } - else - { - index += IndexPatchContext.insidePointIndexDeltaToRealValue; - } - } - - return vertices_base + index; -} - - -int AStitchRegular(bool bTrapezoid, int diagonals, - uint numInsideEdgePoints, - int2 outsideInsideEdgePointBaseOffset, - int i) -{ - if (bTrapezoid) - { - ++ outsideInsideEdgePointBaseOffset.x; - } - - int pt; - - if ((i < 4) && bTrapezoid) - { - if (i < 2) - { - pt = outsideInsideEdgePointBaseOffset.x - 1 + i; - } - else if (i == 2) - { - pt = outsideInsideEdgePointBaseOffset.y; - } - else - { - pt = -1; - } - } - - int index = i; - if (bTrapezoid) - { - index -= 4; - } - - if (index >= 0) - { - uint uindex = (uint)index; - - switch( diagonals ) - { - case DIAGONALS_INSIDE_TO_OUTSIDE: - if (uindex < 5 * numInsideEdgePoints - 5) - { - uint p = uindex / 5; - uint r = uindex - p * 5; - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + p + r; - } - else if (r < 4) - { - pt = outsideInsideEdgePointBaseOffset.y + p + r; - } - else - { - pt = -1; - } - } - else - { - int r = i - (4 + 5 * numInsideEdgePoints - 5); - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + numInsideEdgePoints - 1 + r; - } - else if (r == 2) - { - pt = outsideInsideEdgePointBaseOffset.y + numInsideEdgePoints - 1; - } - else - { - pt = -1; - } - } - break; - - case DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE: // Assumes ODD tessellation - if (uindex < (numInsideEdgePoints / 2 - 1) * 5) - { - // First half - uint p = uindex / 5; - uint r = uindex - p * 5; - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + p + r; - } - else if (r < 4) - { - pt = outsideInsideEdgePointBaseOffset.y + p; - } - else - { - pt = -1; - } - } - else if (uindex < (numInsideEdgePoints / 2 - 1) * 5 + 8) - { - // Middle - uint r = uindex - (numInsideEdgePoints / 2 - 1) * 5; - if (0 == r) - { - pt = outsideInsideEdgePointBaseOffset.x + numInsideEdgePoints / 2 - 1; - } - else if (r < 3) - { - pt = outsideInsideEdgePointBaseOffset.y + numInsideEdgePoints / 2 - 1 + (2 - r); - } - else if (r == 3) - { - pt = -1; - } - else if (r < 6) - { - pt = outsideInsideEdgePointBaseOffset.x + numInsideEdgePoints / 2 - 1 + (r - 4); - } - else if (r == 6) - { - pt = outsideInsideEdgePointBaseOffset.y + numInsideEdgePoints / 2 - 1 + 1; - } - else if (r == 7) - { - pt = -1; - } - } - //else if (uindex < (numInsideEdgePoints/2-1) * 5 + 8 + (numInsideEdgePoints - numInsideEdgePoints/2 - 1) * 5) - else if (uindex < numInsideEdgePoints * 5 - 2) - { - // Second half - uint p = (uindex - (numInsideEdgePoints / 2 - 1) * 5 + 8) / 5 + numInsideEdgePoints / 2 + 1; - uint r = uindex - (numInsideEdgePoints / 2 - 1) * 5 + 8 - (p - (numInsideEdgePoints / 2 + 1)) * 5; - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + p - 1 + r; - } - else if (r < 4) - { - pt = outsideInsideEdgePointBaseOffset.y + p - 1 + r; - } - else - { - pt = -1; - } - } - else - { - //int r = i - (4 + (numInsideEdgePoints/2-1) * 5 + 8 + (numInsideEdgePoints - numInsideEdgePoints/2 - 1) * 5); - int r = i - (numInsideEdgePoints * 5 + 2); - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + numInsideEdgePoints - 1 + r; - } - else if (r == 2) - { - pt = outsideInsideEdgePointBaseOffset.y + numInsideEdgePoints - 1; - } - else - { - pt = -1; - } - } - break; - - case DIAGONALS_MIRRORED: - if (uindex < (numInsideEdgePoints / 2 + 1) * 2) - { - uint p = uindex / 2; - uint r = uindex - p * 2; - if (0 == r) - { - pt = outsideInsideEdgePointBaseOffset.y + p; - } - else - { - pt = outsideInsideEdgePointBaseOffset.x + p; - } - } - else if (uindex == (numInsideEdgePoints / 2 + 1) * 2) - { - pt = -1; - } - else if (uindex == (numInsideEdgePoints / 2 + 1) * 2 + 1) - { - pt = outsideInsideEdgePointBaseOffset.x + numInsideEdgePoints / 2; - } - //else if (uindex < (numInsideEdgePoints / 2 + 1) * 2 + 2 + (numInsideEdgePoints - numInsideEdgePoints / 2) * 2) - else if (uindex < numInsideEdgePoints * 2 + 4) - { - uint p = (uindex - ((numInsideEdgePoints / 2 + 1) * 2 + 2)) / 2 + numInsideEdgePoints / 2; - uint r = uindex - ((numInsideEdgePoints / 2 + 1) * 2 + 2) - (p - numInsideEdgePoints / 2) * 2; - if (0 == r) - { - pt = outsideInsideEdgePointBaseOffset.x + p; - } - else - { - pt = outsideInsideEdgePointBaseOffset.y + p; - } - } - //else if (uindex == (numInsideEdgePoints / 2 + 1) * 2 + 2 + (numInsideEdgePoints - numInsideEdgePoints / 2) * 2) - else if (uindex == numInsideEdgePoints * 2 + 4) - { - pt = -1; - } - else - { - //int r = i - (4 + (numInsideEdgePoints / 2 + 1) * 2 + 2 + (numInsideEdgePoints - numInsideEdgePoints / 2) * 2 + 1); - uint r = i - (numInsideEdgePoints * 2 + 9); - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + numInsideEdgePoints - 1 + r; - } - else if (r == 2) - { - pt = outsideInsideEdgePointBaseOffset.y + numInsideEdgePoints - 1; - } - else - { - pt = -1; - } - } - break; - } - } - - return pt; -} - -int AStitchTransition(int2 outsideInsideEdgePointBaseOffset, int2 outsideInsideNumHalfTessFactorPoints, - int2 outsideInsideEdgeTessFactorParity, - uint i) -{ - outsideInsideNumHalfTessFactorPoints -= (TESSELLATOR_PARITY_ODD == outsideInsideEdgeTessFactorParity); - - uint2 out_in_first_half = uint2(outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][MAX_FACTOR / 2 + 1].y, insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][MAX_FACTOR / 2 + 1].y) * 4; - - uint3 out_in_middle = 0; - if ((outsideInsideEdgeTessFactorParity.y != outsideInsideEdgeTessFactorParity.x) || (outsideInsideEdgeTessFactorParity.y == TESSELLATOR_PARITY_ODD)) - { - if (outsideInsideEdgeTessFactorParity.y == outsideInsideEdgeTessFactorParity.x) - { - // Quad in the middle - out_in_middle.z = 5; - out_in_middle.xy = 1; - } - else if (TESSELLATOR_PARITY_EVEN == outsideInsideEdgeTessFactorParity.y) - { - // Triangle pointing inside - out_in_middle.z = 4; - out_in_middle.x = 1; - } - else - { - // Triangle pointing outside - out_in_middle.z = 4; - out_in_middle.y = 1; - } - } - - - int pt = -1; - - if (i < out_in_first_half.y) - { - // Advance inside - - uint p = i / 4; - uint r = i - p * 4; - p = insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p].z; - if ((0 == r) || (2 == r)) - { - pt = outsideInsideEdgePointBaseOffset.y + insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p].y + r / 2; - } - else if (1 == r) - { - pt = outsideInsideEdgePointBaseOffset.x + outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p].y; - } - } - else - { - i -= out_in_first_half.y; - - if (i < out_in_first_half.x) - { - // Advance outside - - uint p = i / 4; - uint r = i - p * 4; - p = outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p].z; - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p].y + r; - } - else if (r == 2) - { - pt = outsideInsideEdgePointBaseOffset.y + insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p].y; - if (insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p].x) - { - ++ pt; - } - } - } - else - { - i -= out_in_first_half.x; - - if (i < out_in_middle.z) - { - uint r = i; - if (outsideInsideEdgeTessFactorParity.y == outsideInsideEdgeTessFactorParity.x) - { - // Quad in the middle - if ((0 == r) || (2 == r)) - { - pt = outsideInsideEdgePointBaseOffset.y + out_in_first_half.y / 4 + (2 == r);//r / 2; - } - else if ((1 == r) || (3 == r)) - { - pt = outsideInsideEdgePointBaseOffset.x + out_in_first_half.x / 4 + (3 == r);//(r - 1) / 2; - } - } - else if (TESSELLATOR_PARITY_EVEN == outsideInsideEdgeTessFactorParity.y) - { - // Triangle pointing inside - if (r == 0) - { - pt = outsideInsideEdgePointBaseOffset.y + out_in_first_half.y / 4; - } - else if (r < 3) - { - pt = outsideInsideEdgePointBaseOffset.x + out_in_first_half.x / 4 + r - 1; - } - } - else - { - // Triangle pointing outside - if ((0 == r) || (2 == r)) - { - pt = outsideInsideEdgePointBaseOffset.y + out_in_first_half.y / 4 + (2 == r);//r / 2; - } - else if (1 == r) - { - pt = outsideInsideEdgePointBaseOffset.x + out_in_first_half.x / 4; - } - } - } - else - { - i -= out_in_middle.z; - - if (i < out_in_first_half.x) - { - // Advance outside - - uint p = i / 4; - uint r = i - p * 4; - p = outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p].z; - if (r < 2) - { - pt = outsideInsideEdgePointBaseOffset.x + out_in_first_half.x / 4 + out_in_middle.x + (outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][MAX_FACTOR / 2 + 1].y - outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p + 1].y) + r; - } - else if (r == 2) - { - pt = outsideInsideEdgePointBaseOffset.y + out_in_first_half.y / 4 + out_in_middle.y + (insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][MAX_FACTOR / 2 + 1].y - insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p + 1].y); - } - } - else - { - // Advance inside - - i -= out_in_first_half.x; - - uint p = i / 4; - uint r = i - p * 4; - p = insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p].w; - if ((0 == r) || (2 == r)) - { - pt = outsideInsideEdgePointBaseOffset.y + out_in_first_half.y / 4 + out_in_middle.y - + (insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][MAX_FACTOR / 2 + 1].y - insidePointIndex[outsideInsideNumHalfTessFactorPoints.y][p + 1].y) + (2 == r);//r / 2; - } - else if (1 == r) - { - pt = outsideInsideEdgePointBaseOffset.x + out_in_first_half.x / 4 + out_in_middle.x - + (outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][MAX_FACTOR / 2 + 1].y - outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p + 1].y); - if (outsidePointIndex[outsideInsideNumHalfTessFactorPoints.x][p].x) - { - ++ pt; - } - } - } - } - } - } - - return pt; -} - -[numthreads(128, 1, 1)] -void CSTessellationIndices( uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex ) -{ - uint id = DTid.x; - //uint id = Gid.x * 128 + GI; // Workaround for some CS4x preview drivers - - if ( id < g_param.x ) - { - uint tri_id = InputTriIDIndexID[id].x; - uint index_id = InputTriIDIndexID[id].y; - uint base_vertex = InputScanned[tri_id-1].x; - - float4 outside_inside_factor = InputEdgeFactor[tri_id]; - - PROCESSED_TESS_FACTORS_TRI processedTessFactors; - int num_points = TriProcessTessFactors(outside_inside_factor, processedTessFactors, g_partitioning); - - uint tessed_indices; - if (3 == num_points) - { - if (index_id < 3) - { - tessed_indices = TransformIndex1(index_id, base_vertex); - } - else - { - tessed_indices = -1; - } - } - else - { - // Generate primitives for all the concentric rings, one side at a time for each ring - static const int startRing = 1; - int numRings = ((processedTessFactors.numPointsForOutsideInside.w + 1) / 2); // +1 is so even tess includes the center point, which we want to now - - int4 outsideInsideHalfTessFactor = int4(ceil(processedTessFactors.outsideInsideHalfTessFactor)); - uint3 num = NumStitchTransition(outsideInsideHalfTessFactor, processedTessFactors.outsideInsideTessFactorParity); - num.y += num.x; - num.z += num.y; - uint num_index = num.z; - num_index += TotalNumStitchRegular(true, DIAGONALS_MIRRORED, processedTessFactors.numPointsForOutsideInside.w, numRings - 1) * 3; - if( processedTessFactors.outsideInsideTessFactorParity.w == TESSELLATOR_PARITY_ODD ) - { - num_index += 4; - } - - int pt; - - if (index_id < num.x) - { - int numPointsForInsideEdge = processedTessFactors.numPointsForOutsideInside.w - 2 * startRing; - - pt = AStitchTransition(int2(0, processedTessFactors.insideEdgePointBaseOffset), - outsideInsideHalfTessFactor.xw, - processedTessFactors.outsideInsideTessFactorParity.xw, - index_id); - if (pt != -1) - { - pt = TransformIndex1(pt, base_vertex); - } - } - else if (index_id < num.y) - { - int numPointsForInsideEdge = processedTessFactors.numPointsForOutsideInside.w - 2 * startRing; - - pt = AStitchTransition( - int2(processedTessFactors.numPointsForOutsideInside.x - 1, processedTessFactors.insideEdgePointBaseOffset + numPointsForInsideEdge - 1), - outsideInsideHalfTessFactor.yw, - processedTessFactors.outsideInsideTessFactorParity.yw, - index_id - num.x); - if (pt != -1) - { - pt = TransformIndex1(pt, base_vertex); - } - } - else if (index_id < num.z) - { - int numPointsForInsideEdge = processedTessFactors.numPointsForOutsideInside.w - 2 * startRing; - - INDEX_PATCH_CONTEXT IndexPatchContext; - IndexPatchContext.insidePointIndexDeltaToRealValue = processedTessFactors.insideEdgePointBaseOffset + 2 * (numPointsForInsideEdge - 1); - IndexPatchContext.insidePointIndexBadValue = numPointsForInsideEdge - 1; - IndexPatchContext.insidePointIndexReplacementValue = processedTessFactors.insideEdgePointBaseOffset; - IndexPatchContext.outsidePointIndexPatchBase = IndexPatchContext.insidePointIndexBadValue+1; // past inside patched index range - IndexPatchContext.outsidePointIndexDeltaToRealValue = processedTessFactors.numPointsForOutsideInside.x + processedTessFactors.numPointsForOutsideInside.y - 2 - - IndexPatchContext.outsidePointIndexPatchBase; - IndexPatchContext.outsidePointIndexBadValue = IndexPatchContext.outsidePointIndexPatchBase - + processedTessFactors.numPointsForOutsideInside.z - 1; - IndexPatchContext.outsidePointIndexReplacementValue = 0; - - pt = AStitchTransition(int2(numPointsForInsideEdge, 0), - outsideInsideHalfTessFactor.zw, - processedTessFactors.outsideInsideTessFactorParity.zw, - index_id - num.y); - if (pt != -1) - { - pt = TransformIndex2(pt, base_vertex, IndexPatchContext); - } - } - else - { - if ((processedTessFactors.outsideInsideTessFactorParity.w == TESSELLATOR_PARITY_ODD) && (index_id >= num_index - 4)) - { - int outsideEdgePointBaseOffset = processedTessFactors.insideEdgePointBaseOffset - + ((processedTessFactors.numPointsForOutsideInside.w + 1) - (numRings + startRing)) * (numRings - startRing - 1) * 3; - - if (index_id - (num_index - 4) != 3) - { - pt = TransformIndex1(outsideEdgePointBaseOffset + index_id - (num_index - 4), base_vertex); - } - else - { - pt = -1; - } - } - else - { - int ring = GetRingFromIndexStitchRegular(true, DIAGONALS_MIRRORED, processedTessFactors.numPointsForOutsideInside.w, index_id - num.z); - - int tn = TotalNumStitchRegular(true, DIAGONALS_MIRRORED, processedTessFactors.numPointsForOutsideInside.w, ring - 1) * 3; - int n = NumStitchRegular(true, DIAGONALS_MIRRORED, processedTessFactors.numPointsForOutsideInside.w - 2 * ring); - - int edge = (index_id - num.z - tn) / n; - int index = (index_id - num.z - tn) - edge * n; - - int2 outsideInsideEdgePointBaseOffset = processedTessFactors.insideEdgePointBaseOffset - + int2(0, 3 * (processedTessFactors.numPointsForOutsideInside.w - 3)) - + ((processedTessFactors.numPointsForOutsideInside.w - (ring + startRing)) + int2(1, -1)) * (ring - startRing - 1) * 3; - - int numPointsForInsideEdge = processedTessFactors.numPointsForOutsideInside.w - 2 * ring; - int numLastPointsForInsideEdge = numPointsForInsideEdge + 2; - - if (edge < 2) - { - pt = AStitchRegular(true, DIAGONALS_MIRRORED, - numPointsForInsideEdge, - outsideInsideEdgePointBaseOffset + (int2(numLastPointsForInsideEdge, numPointsForInsideEdge) - 1) * edge, - index); - if (pt != -1) - { - pt = TransformIndex1(pt, base_vertex); - } - } - else - { - INDEX_PATCH_CONTEXT IndexPatchContext; - IndexPatchContext.insidePointIndexDeltaToRealValue = outsideInsideEdgePointBaseOffset.y + (numPointsForInsideEdge - 1) * 2; - IndexPatchContext.insidePointIndexBadValue = numPointsForInsideEdge - 1; - IndexPatchContext.insidePointIndexReplacementValue = outsideInsideEdgePointBaseOffset.y; - IndexPatchContext.outsidePointIndexPatchBase = IndexPatchContext.insidePointIndexBadValue+1; // past inside patched index range - IndexPatchContext.outsidePointIndexDeltaToRealValue = outsideInsideEdgePointBaseOffset.x + (numLastPointsForInsideEdge - 1) * 2 - - IndexPatchContext.outsidePointIndexPatchBase; - IndexPatchContext.outsidePointIndexBadValue = IndexPatchContext.outsidePointIndexPatchBase - + numLastPointsForInsideEdge - 1; - IndexPatchContext.outsidePointIndexReplacementValue = outsideInsideEdgePointBaseOffset.x; - - pt = AStitchRegular(true, DIAGONALS_MIRRORED, - numPointsForInsideEdge, - int2(numPointsForInsideEdge, 0), - index); - if (pt != -1) - { - pt = TransformIndex2(pt, base_vertex, IndexPatchContext); - } - } - } - } - - tessed_indices = pt; - } - - TessedIndicesOut.Store(id*4, tessed_indices); - } -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_TessellateVerticesCS.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_TessellateVerticesCS.hlsl deleted file mode 100644 index e1f6b9ec3..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_TessellateVerticesCS.hlsl +++ /dev/null @@ -1,206 +0,0 @@ -//TEST_IGNORE_FILE: Currently failing due to Slang compiler issues. -//TEST:COMPARE_HLSL: -profile cs_4_0 -entry CSTessellationVertices -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_TessellateVerticesCS.hlsl -// -// The CS to tessellate vertices -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- - -#include "TessellatorCS40_common.hlsl" - -StructuredBuffer<uint2> InputTriIDIndexID : register(t0); -StructuredBuffer<float4> InputEdgeFactor : register(t1); - -struct TessedVertex -{ - uint BaseTriID; - float2 bc; -}; -RWStructuredBuffer<TessedVertex> TessedVerticesOut : register(u0); - -cbuffer cbCS : register(b1) -{ - uint4 g_param; -} - -void PlacePointIn1D(PROCESSED_TESS_FACTORS_TRI processedTessFactors, int ctx_index, int pt, out float location, int parity) -{ - int numHalfTessFactorPoints = int(ceil(processedTessFactors.outsideInsideHalfTessFactor[ctx_index])); - - bool bFlip; - if( pt >= numHalfTessFactorPoints ) - { - pt = (numHalfTessFactorPoints << 1) - pt; - if( TESSELLATOR_PARITY_ODD == parity ) - { - pt -= 1; - } - bFlip = true; - } - else - { - bFlip = false; - } - - if( pt == numHalfTessFactorPoints ) - { - location = 0.5f; - } - else - { - unsigned int indexOnCeilHalfTessFactor = pt; - unsigned int indexOnFloorHalfTessFactor = indexOnCeilHalfTessFactor; - if( pt > processedTessFactors.outsideInsideSplitPointOnFloorHalfTessFactor[ctx_index] ) - { - indexOnFloorHalfTessFactor -= 1; - } - float locationOnFloorHalfTessFactor = indexOnFloorHalfTessFactor * processedTessFactors.outsideInsideInvNumSegmentsOnFloorTessFactor[ctx_index]; - float locationOnCeilHalfTessFactor = indexOnCeilHalfTessFactor * processedTessFactors.outsideInsideInvNumSegmentsOnCeilTessFactor[ctx_index]; - - location = lerp(locationOnFloorHalfTessFactor, locationOnCeilHalfTessFactor, frac(processedTessFactors.outsideInsideHalfTessFactor[ctx_index])); - - if( bFlip ) - { - location = 1.0f - location; - } - } -} - -[numthreads(128, 1, 1)] -void CSTessellationVertices( uint3 DTid : SV_DispatchThreadID, uint3 Gid : SV_GroupID, uint GI : SV_GroupIndex ) -{ - uint id = DTid.x; - //uint id = Gid.x * 128 + GI; // Workaround for some CS4x preview drivers - - if ( id < g_param.x ) - { - uint tri_id = InputTriIDIndexID[id].x; - uint vert_id = InputTriIDIndexID[id].y; - - float4 outside_inside_factor = InputEdgeFactor[tri_id]; - - PROCESSED_TESS_FACTORS_TRI processedTessFactors; - int num_points = TriProcessTessFactors(outside_inside_factor, processedTessFactors, g_partitioning); - - float2 uv; - if (3 == num_points) - { - if (0 == vert_id) - { - uv = float2(0, 1); - } - else if (1 == vert_id) - { - uv = float2(0, 0); - } - else - { - uv = float2(1, 0); - } - } - else - { - if (vert_id < processedTessFactors.insideEdgePointBaseOffset) - { - // Generate exterior ring edge points, clockwise starting from point V (VW, the U==0 edge) - - int edge; - if (vert_id < processedTessFactors.numPointsForOutsideInside.x - 1) - { - edge = 0; - } - else - { - vert_id -= processedTessFactors.numPointsForOutsideInside.x - 1; - if (vert_id < processedTessFactors.numPointsForOutsideInside.y - 1) - { - edge = 1; - } - else - { - vert_id -= processedTessFactors.numPointsForOutsideInside.y - 1; - edge = 2; - } - } - - int p = vert_id; - int endPoint = processedTessFactors.numPointsForOutsideInside[edge] - 1; - float param; - int q = (edge & 0x1) ? p : endPoint - p; // whether to reverse point order given we are defining V or U (W implicit): - // edge0, VW, has V decreasing, so reverse 1D points below - // edge1, WU, has U increasing, so don't reverse 1D points below - // edge2, UV, has U decreasing, so reverse 1D points below - PlacePointIn1D(processedTessFactors, edge,q,param, processedTessFactors.outsideInsideTessFactorParity[edge]); - if (0 == edge) - { - uv = float2(0, param); - } - else if (1 == edge) - { - uv = float2(param, 0); - } - else - { - uv = float2(param, 1 - param); - } - } - else - { - // Generate interior ring points, clockwise spiralling in - - uint index = vert_id - processedTessFactors.insideEdgePointBaseOffset; - uint ring = 1 + (((3 * processedTessFactors.numPointsForOutsideInside.w - 6) - sqrt(sqr(3 * processedTessFactors.numPointsForOutsideInside.w - 6) - 4 * 3 * index)) + 0.001f) / 6; - index -= 3 * (processedTessFactors.numPointsForOutsideInside.w - ring - 1) * (ring - 1); - - uint startPoint = ring; - uint endPoint = processedTessFactors.numPointsForOutsideInside.w - 1 - startPoint; - if (index < 3 * (endPoint - startPoint)) - { - uint edge = index / (endPoint - startPoint); - uint p = index - edge * (endPoint - startPoint) + startPoint; - - int perpendicularAxisPoint = startPoint; - float perpParam; - PlacePointIn1D(processedTessFactors, 3, perpendicularAxisPoint, perpParam, processedTessFactors.outsideInsideTessFactorParity.w); - perpParam = perpParam * 2 / 3; - - float param; - int q = (edge & 0x1) ? p : endPoint - (p - startPoint); // whether to reverse point given we are defining V or U (W implicit): - // edge0, VW, has V decreasing, so reverse 1D points below - // edge1, WU, has U increasing, so don't reverse 1D points below - // edge2, UV, has U decreasing, so reverse 1D points below - PlacePointIn1D(processedTessFactors, 3, q,param, processedTessFactors.outsideInsideTessFactorParity.w); - // edge0 VW, has perpendicular parameter U constant - // edge1 WU, has perpendicular parameter V constant - // edge2 UV, has perpendicular parameter W constant - const unsigned int deriv = 2; // reciprocal is the rate of change of edge-parallel parameters as they are pushed into the triangle - if (0 == edge) - { - uv = float2(perpParam, param - perpParam / deriv); - } - else if (1 == edge) - { - uv = float2(param - perpParam / deriv, perpParam); - } - else - { - uv = float2(param - perpParam / deriv, 1 - (param - perpParam / deriv + perpParam)); - } - } - else - { - if( processedTessFactors.outsideInsideTessFactorParity.w != TESSELLATOR_PARITY_ODD ) - { - // Last point is the point at the center. - uv = 1 / 3.0f; - } - } - } - } - - TessedVerticesOut[id].BaseTriID = tri_id; - TessedVerticesOut[id].bc = uv; - } -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_common.hlsl b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_common.hlsl deleted file mode 100644 index 309044cdb..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_common.hlsl +++ /dev/null @@ -1,411 +0,0 @@ -//TEST_IGNORE_FILE: -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_common.hlsl -// -// The common utils included by other shaders in the sample -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- - -#include "TessellatorCS40_defines.h" - -cbuffer cbNeverChanges : register(b0) -{ - uint4 insidePointIndex[MAX_FACTOR / 2 + 1][MAX_FACTOR / 2 + 2]; - uint4 outsidePointIndex[MAX_FACTOR / 2 + 1][MAX_FACTOR / 2 + 2]; -} - -#define D3D11_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR ( 64 ) -#define D3D11_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR ( 63 ) -#define D3D11_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR ( 2 ) -#define D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR ( 1 ) - -#define D3D11_TESSELLATOR_PARTITIONING_INTEGER ( 0 ) -#define D3D11_TESSELLATOR_PARTITIONING_POW2 ( 1 ) -#define D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD ( 2 ) -#define D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN ( 3 ) - -#define TESSELLATOR_PARITY_EVEN ( 0 ) -#define TESSELLATOR_PARITY_ODD ( 1 ) - -#define EPSILON 1e-6f -#define MIN_ODD_TESSFACTOR_PLUS_HALF_EPSILON (D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR + EPSILON/2) - -#define DIAGONALS_INSIDE_TO_OUTSIDE ( 0 ) -#define DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE ( 1 ) -#define DIAGONALS_MIRRORED ( 2 ) - - -// This is moved to macro defines at shader compile time, so that the partitioning mode can be changed during runtime -//#define g_partitioning (D3D11_TESSELLATOR_PARTITIONING_POW2) - - -struct PROCESSED_TESS_FACTORS_TRI -{ - float4 outsideInsideTessFactor; - int4 outsideInsideTessFactorParity; - - float4 outsideInsideInvNumSegmentsOnFloorTessFactor; - float4 outsideInsideInvNumSegmentsOnCeilTessFactor; - float4 outsideInsideHalfTessFactor; - int4 outsideInsideSplitPointOnFloorHalfTessFactor; - - // Stuff below is specific to the traversal order - uint4 numPointsForOutsideInside; - uint insideEdgePointBaseOffset; -}; - -struct INDEX_PATCH_CONTEXT -{ - int insidePointIndexDeltaToRealValue; - int insidePointIndexBadValue; - int insidePointIndexReplacementValue; - int outsidePointIndexPatchBase; - int outsidePointIndexDeltaToRealValue; - int outsidePointIndexBadValue; - int outsidePointIndexReplacementValue; -}; - -bool4 isEven(float4 input) -{ - return (((uint4)input) & 1) ? false : true; -} - -uint RemoveMSB(uint val) -{ - int check; - if( val <= 0x0000ffff ) - { - check = ( val <= 0x000000ff ) ? 0x00000080 : 0x00008000; - } - else - { - check = ( val <= 0x00ffffff ) ? 0x00800000 : 0x80000000; - } - for (int i = 0; i < 8; i++, check >>= 1) - { - if( val & check ) - { - return (val & ~check); - } - } - return 0; -} - -uint4 NumPointsForTessFactor(float4 tessFactor, int4 parity) -{ - return TESSELLATOR_PARITY_ODD == parity ? uint4(ceil(0.5f + tessFactor / 2)) * 2 : uint4(ceil(tessFactor / 2)) * 2 + 1; -} - -void ComputeTessFactorContext(float4 tessFactor, int4 parity, - out float4 invNumSegmentsOnFloorTessFactor, - out float4 invNumSegmentsOnCeilTessFactor, - out float4 halfTessFactor, - out int4 splitPointOnFloorHalfTessFactor) -{ - halfTessFactor = tessFactor / 2; - - halfTessFactor += 0.5 * ((TESSELLATOR_PARITY_ODD == parity) | (0.5f == halfTessFactor)); - - float4 floorHalfTessFactor = floor(halfTessFactor); - float4 ceilHalfTessFactor = ceil(halfTessFactor); - int4 numHalfTessFactorPoints = int4(ceilHalfTessFactor); - - for (int index = 0; index < 4; ++ index) - { - if( ceilHalfTessFactor[index] == floorHalfTessFactor[index] ) - { - splitPointOnFloorHalfTessFactor[index] = /*pick value to cause this to be ignored*/ numHalfTessFactorPoints[index]+1; - } - else if( TESSELLATOR_PARITY_ODD == parity[index] ) - { - if( floorHalfTessFactor[index] == 1 ) - { - splitPointOnFloorHalfTessFactor[index] = 0; - } - else - { - splitPointOnFloorHalfTessFactor[index] = (RemoveMSB(int(floorHalfTessFactor[index]) - 1) << 1) + 1; - } - } - else - { - splitPointOnFloorHalfTessFactor[index] = (RemoveMSB(int(floorHalfTessFactor[index])) << 1) + 1; - } - } - - int4 numFloorSegments = int4(floorHalfTessFactor * 2); - int4 numCeilSegments = int4(ceilHalfTessFactor * 2); - int4 s = (TESSELLATOR_PARITY_ODD == parity); - numFloorSegments -= s; - numCeilSegments -= s; - invNumSegmentsOnFloorTessFactor = 1.0f / numFloorSegments; - invNumSegmentsOnCeilTessFactor = 1.0f / numCeilSegments; -} - -int TriProcessTessFactors( inout float4 tessFactor, - out PROCESSED_TESS_FACTORS_TRI processedTessFactors, - int partitioning ) -{ - processedTessFactors = (PROCESSED_TESS_FACTORS_TRI)0; - - int parity = TESSELLATOR_PARITY_EVEN; - switch( partitioning ) - { - case D3D11_TESSELLATOR_PARTITIONING_INTEGER: - default: - break; - case D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD: - parity = TESSELLATOR_PARITY_ODD; - break; - case D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN: - parity = TESSELLATOR_PARITY_EVEN; - break; - } - - // Is the patch culled? - if( !(tessFactor.x > 0) || // NaN will pass - !(tessFactor.y > 0) || - !(tessFactor.z > 0) ) - { - return 0; - } - - // Clamp edge TessFactors - float lowerBound, upperBound; - switch(partitioning) - { - case D3D11_TESSELLATOR_PARTITIONING_INTEGER: - case D3D11_TESSELLATOR_PARTITIONING_POW2: // don't care about pow2 distinction for validation, just treat as integer - default: - lowerBound = D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR; - upperBound = D3D11_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR; - break; - - case D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN: - lowerBound = D3D11_TESSELLATOR_MIN_EVEN_TESSELLATION_FACTOR; - upperBound = D3D11_TESSELLATOR_MAX_EVEN_TESSELLATION_FACTOR; - break; - - case D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD: - lowerBound = D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR; - upperBound = D3D11_TESSELLATOR_MAX_ODD_TESSELLATION_FACTOR; - break; - } - - tessFactor.xyz = min( upperBound, max( lowerBound, tessFactor.xyz ) ); - - // Clamp inside TessFactors - if(D3D11_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD == partitioning) - { - if( (tessFactor.x > MIN_ODD_TESSFACTOR_PLUS_HALF_EPSILON) || - (tessFactor.y > MIN_ODD_TESSFACTOR_PLUS_HALF_EPSILON) || - (tessFactor.z > MIN_ODD_TESSFACTOR_PLUS_HALF_EPSILON)) - // Don't need the same check for insideTessFactor for tri patches, - // since there is only one insideTessFactor, as opposed to quad - // patches which have 2 insideTessFactors. - { - // Force picture frame - lowerBound = D3D11_TESSELLATOR_MIN_ODD_TESSELLATION_FACTOR + EPSILON; - } - } - - tessFactor.w = min( upperBound, max( lowerBound, tessFactor.w ) ); - // Note the above clamps map NaN to lowerBound - - if (partitioning == D3D11_TESSELLATOR_PARTITIONING_INTEGER) - { - tessFactor = ceil(tessFactor); - } - else if (partitioning == D3D11_TESSELLATOR_PARTITIONING_POW2) - { - static const int exponentMask = 0x7f800000; - static const int mantissaMask = 0x007fffff; - static const int exponentLSB = 0x00800000; - - int4 bits = asint(tessFactor); - tessFactor = bits & mantissaMask ? asfloat((bits & exponentMask) + exponentLSB) : tessFactor; - } - - // Process tessFactors - if ((partitioning == D3D11_TESSELLATOR_PARTITIONING_INTEGER)|| (partitioning == D3D11_TESSELLATOR_PARTITIONING_POW2)) - { - bool4 e = isEven(tessFactor); - processedTessFactors.outsideInsideTessFactorParity.xyz = e.xyz ? TESSELLATOR_PARITY_EVEN : TESSELLATOR_PARITY_ODD; - processedTessFactors.outsideInsideTessFactorParity.w = (e.w || (1 == tessFactor.w)) ? TESSELLATOR_PARITY_EVEN : TESSELLATOR_PARITY_ODD; - } - else - { - processedTessFactors.outsideInsideTessFactorParity = parity; - } - - processedTessFactors.outsideInsideTessFactor = tessFactor; - - if (((partitioning == D3D11_TESSELLATOR_PARTITIONING_INTEGER)|| (partitioning == D3D11_TESSELLATOR_PARTITIONING_POW2)) || (parity == TESSELLATOR_PARITY_ODD)) - { - // Special case if all TessFactors are 1 - if( (1 == processedTessFactors.outsideInsideTessFactor.x) && - (1 == processedTessFactors.outsideInsideTessFactor.y) && - (1 == processedTessFactors.outsideInsideTessFactor.z) && - (1 == processedTessFactors.outsideInsideTessFactor.w) ) - { - return 3; - } - } - - // Compute per-TessFactor metadata - ComputeTessFactorContext(processedTessFactors.outsideInsideTessFactor, processedTessFactors.outsideInsideTessFactorParity, - processedTessFactors.outsideInsideInvNumSegmentsOnFloorTessFactor, - processedTessFactors.outsideInsideInvNumSegmentsOnCeilTessFactor, - processedTessFactors.outsideInsideHalfTessFactor, - processedTessFactors.outsideInsideSplitPointOnFloorHalfTessFactor); - - // Compute some initial data. - - // outside edge offsets and storage - processedTessFactors.numPointsForOutsideInside = NumPointsForTessFactor(processedTessFactors.outsideInsideTessFactor, processedTessFactors.outsideInsideTessFactorParity); - int NumPoints = processedTessFactors.numPointsForOutsideInside.x + processedTessFactors.numPointsForOutsideInside.y + processedTessFactors.numPointsForOutsideInside.z - 3; - - // inside edge offsets - { - uint pointCountMin = (processedTessFactors.outsideInsideTessFactorParity.w == TESSELLATOR_PARITY_ODD) ? 4 : 3; - // max() allows degenerate transition regions when inside TessFactor == 1 - processedTessFactors.numPointsForOutsideInside.w = max(pointCountMin, processedTessFactors.numPointsForOutsideInside.w); - } - - processedTessFactors.insideEdgePointBaseOffset = NumPoints; - - // inside storage, including interior edges above - { - int numInteriorRings = (processedTessFactors.numPointsForOutsideInside.w >> 1) - 1; - int numInteriorPoints; - if( processedTessFactors.outsideInsideTessFactorParity.w == TESSELLATOR_PARITY_ODD ) - { - numInteriorPoints = 3*(numInteriorRings*(numInteriorRings+1) - numInteriorRings); - } - else - { - numInteriorPoints = 3*(numInteriorRings*(numInteriorRings+1)) + 1; - } - NumPoints += numInteriorPoints; - } - - return NumPoints; -} - -int NumStitchRegular(bool bTrapezoid, int diagonals, int numInsideEdgePoints) -{ - int num_index = 0; - - if( bTrapezoid ) - { - num_index += 8; - } - switch( diagonals ) - { - case DIAGONALS_INSIDE_TO_OUTSIDE: - // Diagonals pointing from inside edge forward towards outside edge - num_index += 5 * numInsideEdgePoints - 5; - break; - - case DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE: // Assumes ODD tessellation - // Diagonals pointing from outside edge forward towards inside edge - num_index += 5 * numInsideEdgePoints - 2; - break; - - case DIAGONALS_MIRRORED: - num_index += 2 * numInsideEdgePoints + 5; - break; - } - - return num_index; -} - -uint TotalNumStitchRegular(bool bTrapezoid, int diagonals, - int numPointsForInsideTessFactor, int ring) -{ - uint num_index = 0; - - if( bTrapezoid ) - { - num_index += 8 * (ring - 1); - } - switch( diagonals ) - { - case DIAGONALS_INSIDE_TO_OUTSIDE: - // Diagonals pointing from inside edge forward towards outside edge - num_index += (5 * numPointsForInsideTessFactor - 35 - 5 * ring) * (ring - 1); - break; - - case DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE: // Assumes ODD tessellation - // Diagonals pointing from outside edge forward towards inside edge - num_index += (5 * numPointsForInsideTessFactor - 12 - 5 * ring) * (ring - 1); - break; - - case DIAGONALS_MIRRORED: - num_index += (2 * numPointsForInsideTessFactor + 1 - 2 * ring) * (ring - 1); - break; - } - - return num_index; -} - -int sqr(int x) -{ - return x * x; -} - -int GetRingFromIndexStitchRegular(bool bTrapezoid, int diagonals, int numPointsForInsideTessFactor, int index) -{ - int t = 0; - if (bTrapezoid) - { - t = 8; - } - - switch( diagonals ) - { - case DIAGONALS_INSIDE_TO_OUTSIDE: - t = (5 * numPointsForInsideTessFactor - (35 - t)) * 3; - return 1 + uint((t + 15) - sqrt(sqr(t + 15) - 4 * 15 * (t + index)) + 0.001f) / 30; - - case DIAGONALS_INSIDE_TO_OUTSIDE_EXCEPT_MIDDLE: - t = (5 * numPointsForInsideTessFactor - (12 - t)) * 3; - return 1 + uint((t + 15) - sqrt(sqr(t + 15) - 4 * 15 * (t + index)) + 0.001f) / 30; - - case DIAGONALS_MIRRORED: - t = ((t + 1) + 2 * numPointsForInsideTessFactor) * 3; - return 1 + uint((t + 6) - sqrt(sqr(t + 6) - 4 * 6 * (t + index)) + 0.001f) / 12; - - default: - return -1; - } -} - -uint3 NumStitchTransition(int4 outsideInsideNumHalfTessFactorPoints, - int4 outsideInsideEdgeTessFactorParity) -{ - outsideInsideNumHalfTessFactorPoints -= (TESSELLATOR_PARITY_ODD == outsideInsideEdgeTessFactorParity); - - uint3 num_index = insidePointIndex[outsideInsideNumHalfTessFactorPoints.w][MAX_FACTOR / 2 + 1].y * 8; - - [unroll] - for (int edge = 0; edge < 3; ++ edge) - { - num_index[edge] += outsidePointIndex[outsideInsideNumHalfTessFactorPoints[edge]][MAX_FACTOR / 2 + 1].y * 8; - - if( (outsideInsideEdgeTessFactorParity.w != outsideInsideEdgeTessFactorParity[edge]) || (outsideInsideEdgeTessFactorParity.w == TESSELLATOR_PARITY_ODD)) - { - if( outsideInsideEdgeTessFactorParity.w == outsideInsideEdgeTessFactorParity[edge] ) - { - num_index[edge] += 5; - } - else - { - num_index[edge] += 4; - } - } - } - - return num_index; -} diff --git a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_defines.h b/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_defines.h deleted file mode 100644 index 6b4382393..000000000 --- a/tests/hlsl/dxsdk/AdaptiveTessellationCS40/TessellatorCS40_defines.h +++ /dev/null @@ -1,9 +0,0 @@ -//-------------------------------------------------------------------------------------- -// File: TessellatorCS40_defines.h -// -// This file defines common constants which are included by both CPU code and shader code -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//-------------------------------------------------------------------------------------- - -#define MAX_FACTOR 16 |
