diff --git a/util/test/demos/d3d11/d3d11_pixel_history_zoo.cpp b/util/test/demos/d3d11/d3d11_pixel_history_zoo.cpp index 4178e3553..3834c6c40 100644 --- a/util/test/demos/d3d11/d3d11_pixel_history_zoo.cpp +++ b/util/test/demos/d3d11/d3d11_pixel_history_zoo.cpp @@ -462,6 +462,25 @@ void main() InterlockedAdd(buf[0], 1); } +)EOSHADER"; + + std::string pixelUAVWrite = R"EOSHADER( + +struct v2f +{ + float4 pos : SV_POSITION; + float4 col : COLOR0; + float2 uv : TEXCOORD0; +}; + +RWTexture2D uavOut; + +float4 main(v2f IN) : SV_Target0 +{ + uavOut[IN.pos.xy*0.5] = float4(IN.uv.x, IN.uv.y, 0.0f, 1.0f); + return float4(0.1234, 1.0f, 0.0f, 0.5f); +} + )EOSHADER"; int main() @@ -478,6 +497,7 @@ void main() ID3D11PixelShaderPtr ps = CreatePS(Compile(pixel, "main", "ps_4_0")); ID3D11PixelShaderPtr psUInt = CreatePS(Compile(pixelUInt, "main", "ps_4_0")); ID3D11PixelShaderPtr psSInt = CreatePS(Compile(pixelSInt, "main", "ps_4_0")); + ID3D11PixelShaderPtr psUAVWrite = CreatePS(Compile(pixelUAVWrite, "main", "ps_5_0")); ID3D11ComputeShaderPtr cs = CreateCS(Compile(compute, "main", "cs_5_0")); @@ -620,6 +640,10 @@ void main() ID3D11RenderTargetViewPtr mrt = MakeRTV(MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM, 16, 16).RTV().Tex2D()); + // texture for UAV write testing + ID3D11UnorderedAccessViewPtr uavView = + MakeUAV(MakeTexture(DXGI_FORMAT_R8G8B8A8_UNORM, 8, 8).UAV().Tex2D()); + while(Running()) { ClearRenderTargetView(bbRTV, {0.2f, 0.2f, 0.2f, 1.0f}); @@ -725,6 +749,18 @@ void main() } } + { + float white[] = {1.0f, 1.0f, 1.0f, 1.0f}; + ctx->ClearUnorderedAccessViewFloat(uavView.GetInterfacePtr(), white); + ctx->PSSetShader(psUAVWrite, NULL, 0); + ctx->OMSetRenderTargetsAndUnorderedAccessViews(1, &rts[0].GetInterfacePtr(), NULL, 1, 1, + &uavView.GetInterfacePtr(), NULL); + + setMarker("UAVWrite"); + ctx->Draw(3, 0); + ctx->PSSetShader(psUAVWrite, NULL, 0); + } + Present(); } diff --git a/util/test/tests/D3D11/D3D11_Pixel_History_Zoo.py b/util/test/tests/D3D11/D3D11_Pixel_History_Zoo.py index 8f2d04430..c714cbce3 100644 --- a/util/test/tests/D3D11/D3D11_Pixel_History_Zoo.py +++ b/util/test/tests/D3D11/D3D11_Pixel_History_Zoo.py @@ -50,29 +50,7 @@ class D3D11_Pixel_History_Zoo(rdtest.TestCase): # Should be at least two modifications in every test - clear and action self.check(len(modifs) >= 2) - # Check that the modifications are self consistent - postmod of each should match premod of the next - for i in range(len(modifs) - 1): - if value_selector(modifs[i].postMod.col) != value_selector(modifs[i + 1].preMod.col): - raise rdtest.TestFailureException( - "postmod at {}: {} doesn't match premod at {}: {}".format(modifs[i].eventId, - value_selector(modifs[i].postMod.col), - modifs[i + 1].eventId, - value_selector(modifs[i].preMod.col))) - - # A fragment event : postMod.stencil should be unknown - if modifs[i].eventId == modifs[i+1].eventId: - if modifs[i].postMod.stencil != -1 and modifs[i].postMod.stencil != -2: - raise rdtest.TestFailureException( - "postmod stencil at {} primitive {}: {} is not unknown".format(modifs[i].eventId, - modifs[i].primitiveID, - modifs[i].postMod.stencil)) - - if self.get_action(modifs[i].eventId).flags & rd.ActionFlags.Drawcall: - if not rdtest.value_compare(value_selector(modifs[i].shaderOut.col), shader_out): - raise rdtest.TestFailureException( - "Shader output {} isn't as expected {}".format(value_selector(modifs[i].shaderOut.col), - shader_out)) - + self.check_modifiations(modifs, value_selector, shader_out) rdtest.log.success("shader output and premod/postmod is consistent") # The current pixel value should match the last postMod @@ -80,3 +58,53 @@ class D3D11_Pixel_History_Zoo(rdtest.TestCase): # Also the red channel should be zero, as it indicates errors self.check(float(value_selector(modifs[-1].postMod.col)[0]) == 0.0) + + self.check_uavwrite() + + def check_uavwrite(self): + uavWrite = self.find_action("UAVWrite") + if uavWrite is None: + rdtest.log.print("UAVWrite Test not found") + return + + self.controller.SetFrameEvent(uavWrite.next.eventId, True) + pipe: rd.PipeState = self.controller.GetPipelineState() + uav = pipe.GetReadWriteResources(rd.ShaderStage.Pixel)[0].descriptor + vp: rd.Viewport = pipe.GetViewport(0) + tex = uav.resource + x, y = 4, 4 + sub = rd.Subresource() + value_selector = lambda x: x.floatValue + shader_out = (0.3451, 0.43922, 0.0, 1.0) + + modifs: List[rd.PixelModification] = self.controller.PixelHistory(tex, x, y, sub, uav.format.compType) + # Should be two modifications - clear and draw + self.check(len(modifs) == 2) + self.check_modifiations(modifs, value_selector, shader_out) + rdtest.log.success("UAVWrite shader output and premod/postmod is consistent") + # The current pixel value should match the last postMod + self.check_pixel_value(tex, x, y, value_selector(modifs[-1].postMod.col), sub=sub, cast=uav.format.compType) + + def check_modifiations(self, modifs: List[rd.PixelModification], value_selector, shader_out): + # Check that the modifications are self consistent - postmod of each should match premod of the next + for i in range(len(modifs) - 1): + if value_selector(modifs[i].postMod.col) != value_selector(modifs[i + 1].preMod.col): + raise rdtest.TestFailureException( + "postmod at {}: {} doesn't match premod at {}: {}".format(modifs[i].eventId, + value_selector(modifs[i].postMod.col), + modifs[i + 1].eventId, + value_selector(modifs[i].preMod.col))) + + # A fragment event : postMod.stencil should be unknown + if modifs[i].eventId == modifs[i+1].eventId: + if modifs[i].postMod.stencil != -1 and modifs[i].postMod.stencil != -2: + raise rdtest.TestFailureException( + "postmod stencil at {} primitive {}: {} is not unknown".format(modifs[i].eventId, + modifs[i].primitiveID, + modifs[i].postMod.stencil)) + + if self.get_action(modifs[i].eventId).flags & rd.ActionFlags.Drawcall: + if not rdtest.value_compare(value_selector(modifs[i].shaderOut.col), shader_out): + raise rdtest.TestFailureException( + "Shader output {} isn't as expected {}".format(value_selector(modifs[i].shaderOut.col), + shader_out)) \ No newline at end of file