Direct3D 12 API Preview Max McMullen Direct3D Development Lead

Slides:



Advertisements
Similar presentations
Introduction to Direct3D 10 Course Porting Game Engines to Direct3D 10: Crysis / CryEngine2 Carsten Wenzel.
Advertisements

Advanced Virtual Texture Topics
Advanced Visual Effects with Direct3D
OIT and Indirect Illumination using DX11 Linked Lists
DirectX11 Performance Reloaded
Firaxis LORE And other uses of D3D11.
Multi-monitor Game Development Thomas Fortier AMD Graphics Developer Relations
Introduction to the Direct3D 11 Graphics Pipeline
Maximizing Multi-GPU Performance
Vertex Shader Tricks New Ways to Use the Vertex Shader to Improve Performance Bill Bilodeau Developer Technology Engineer, AMD.
Processes Management.
Agenda Windows Display Driver Model (WDDM) What is GPUView?
DirectX Graphics: Direct3D 10 and Beyond
Introduction to Direct3D 12
Direct3D12 and the future of graphics APIs
Improving Performance in Your Game
D3D11 Tessellation Sarah Tariq NVIDIA
COMPUTER GRAPHICS CS 482 – FALL 2014 NOVEMBER 10, 2014 GRAPHICS HARDWARE GRAPHICS PROCESSING UNITS PARALLELISM.
Understanding the graphics pipeline Lecture 2 Original Slides by: Suresh Venkatasubramanian Updates by Joseph Kider.
Status – Week 257 Victor Moya. Summary GPU interface. GPU interface. GPU state. GPU state. API/Driver State. API/Driver State. Driver/CPU Proxy. Driver/CPU.
Graphics Hardware CMSC 435/634. Transform Shade Clip Project Rasterize Texture Z-buffer Interpolate Vertex Fragment Triangle A Graphics Pipeline.
Advanced Graphics and Performance
Getting The Best Out Of D3D12 Evan Hart, Principal Engineer, NVIDIA Dave Oldcorn, D3D12 Technical Lead, AMD.
GRAPHICS AND COMPUTING GPUS Jehan-François Pâris
Optimizing and Debugging Graphics Applications with AMD's GPU PerfStudio 2.2 GPG Developer Tools Raul Aguaviva Gordon Selley Seth Sowerby.
Damon Rocco.  Tessellation: The filling of a plane with polygons such that there is no overlap or gap.  In computer graphics objects are rendered as.
Tools for Investigating Graphics System Performance
© David Kirk/NVIDIA and Wen-mei W. Hwu, ECE408, University of Illinois, Urbana-Champaign 1 Programming Massively Parallel Processors Chapter.
GRAMPS: A Programming Model For Graphics Pipelines Jeremy Sugerman, Kayvon Fatahalian, Solomon Boulos, Kurt Akeley, Pat Hanrahan.
Many-Core Programming with GRAMPS Jeremy Sugerman Kayvon Fatahalian Solomon Boulos Kurt Akeley Pat Hanrahan.
Pixel Shader Vertex Shader The Real-time Graphics Pipeline Input Assembler Rasterizer Output Merger.
The Graphics Pipeline CS2150 Anthony Jones. Introduction What is this lecture about? – The graphics pipeline as a whole – With examples from the video.
Hybrid PC architecture Jeremy Sugerman Kayvon Fatahalian.
The programmable pipeline Lecture 10 Slide Courtesy to Dr. Suresh Venkatasubramanian.
Mapping Computational Concepts to GPU’s Jesper Mosegaard Based primarily on SIGGRAPH 2004 GPGPU COURSE and Visualization 2004 Course.
GPU Graphics Processing Unit. Graphics Pipeline Scene Transformations Lighting & Shading ViewingTransformations Rasterization GPUs evolved as hardware.
High Performance in Broad Reach Games Chas. Boyd
Chas. Boyd Principal PM Microsoft OSG Graphics
Kenneth Hurley Sr. Software Engineer
4/23/2017 4:23 AM © 2009 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered.
Cg Programming Mapping Computational Concepts to GPUs.
The Graphics Rendering Pipeline 3D SCENE Collection of 3D primitives IMAGE Array of pixels Primitives: Basic geometric structures (points, lines, triangles,
Next-Generation Graphics APIs: Similarities and Differences Tim Foley NVIDIA Corporation
OpenGL Performance John Spitzer. 2 OpenGL Performance John Spitzer Manager, OpenGL Applications Engineering
The programmable pipeline Lecture 3.
Stream Processing Main References: “Comparing Reyes and OpenGL on a Stream Architecture”, 2002 “Polygon Rendering on a Stream Architecture”, 2000 Department.
Computer Graphics The Rendering Pipeline - Review CO2409 Computer Graphics Week 15.
Ritual ™ Entertainment: Next-Gen Effects on Direct3D ® 10 Sam Z. Glassenberg Program Manager Microsoft ® – Direct3D ® Doug Service Director of Technology.
Xbox MB system memory IBM 3-way symmetric core processor ATI GPU with embedded EDRAM 12x DVD Optional Hard disk.
A SEMINAR ON 1 CONTENT 2  The Stream Programming Model  The Stream Programming Model-II  Advantage of Stream Processor  Imagine’s.
Computer Graphics 3 Lecture 6: Other Hardware-Based Extensions Benjamin Mora 1 University of Wales Swansea Dr. Benjamin Mora.
Maths & Technologies for Games Graphics Optimisation - Batching CO3303 Week 5.
© David Kirk/NVIDIA and Wen-mei W. Hwu, ECE408, University of Illinois, Urbana-Champaign 1 Programming Massively Parallel Processors Lecture.
Emerging Technologies for Games Capability Testing and DirectX10 Features CO3301 Week 6.
What are shaders? In the field of computer graphics, a shader is a computer program that runs on the graphics processing unit(GPU) and is used to do shading.
UW EXTENSION CERTIFICATE PROGRAM IN GAME DEVELOPMENT 2 ND QUARTER: ADVANCED GRAPHICS The GPU.
GPU Computing for GIS James Mower Department of Geography and Planning University at Albany.
COMPUTER GRAPHICS CHAPTER 38 CS 482 – Fall 2017 GRAPHICS HARDWARE
Graphics on GPU © David Kirk/NVIDIA and Wen-mei W. Hwu,
Graphics Processing Unit
Chapter 6 GPU, Shaders, and Shading Languages
UMBC Graphics for Games
Graphics Processing Unit
Introduction to geometry instancing
UE4 Vulkan Updates & Tips
Computer Graphics Introduction to Shaders
CIS 441/541: Introduction to Computer Graphics Lecture 15: shaders
OpenGL-Rendering Pipeline
CIS 6930: Chip Multiprocessor: GPU Architecture and Programming
Presentation transcript:

Direct3D 12 API Preview 3-564 Max McMullen Direct3D Development Lead Build 2014 4/7/2017 3-564 Direct3D 12 API Preview Max McMullen Direct3D Development Lead 3-564: Direct3D 12 API Preview © 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

Goals & Assumptions Preview of Direct3D 12 More API details in future talks Assuming familiarity with Direct3D 11

Direct3D 12 API Reduce CPU overhead Increase scalability across multiple CPU cores Greater developer control Console API efficiency and performance Superset of D3D 11 rendering functionality

Render Context: Direct3D 11 ID3D11DeviceContext GPU Memory Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Other State

CPU Overhead: Changing Pipeline State Direct3D 10 reduced number of state objects Still mismatched from hardware state Drivers resolve state at Draw

Direct3D 11 – Pipeline State Overhead Small state objects  Hardware mismatch overhead D3D Vertex Shader HW State 1 D3D Rasterizer HW State 2 D3D Pixel Shader HW State 3 D3D Blend State

Direct3D 12 – Pipeline State Optimization Group pipeline into single object Copy from PSO to Hardware State Pipeline State Object HW State 1 HW State 2 HW State 3

Render Context: Direct3D 11 ID3D11DeviceContext GPU Memory Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

Render Context: Pipeline State Object (PSO) GPU Memory Pipeline State Object Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

CPU Overhead: Resource Binding System needs to do lots of binding inspection Resource hazards Resource lifetime Resource residency management Mirrored copies of state used to implement Get* Ease of use for middleware

Resource Hazard Resolution Hazard tracking and resolution Runtime Driver Resource hazards Render Target/Depth <> Texture Tile Resource Aliasing etc…

Direct3D 12 – Explicit Hazard Resolution ResourceBarrier: generalization of Direct3D 11’s TiledResourceBarrier D3D12_RESOURCE_BARRIER_DESC Desc; Desc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; Desc.Transition.pResource = pRTTexture; Desc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; Desc.Transition.StateBefore = D3D12_RESOURCE_USAGE_RENDER_TARGET; Desc.Transition.StateAfter = D3D12_RESOURCE_USAGE_PIXEL_SHADER_RESOURCE; pContext->ResourceBarrier( 1, &Desc );

Resource Lifetime and Residency Explicit application control over resource lifetime Resource destruction is immediate Application must ensure no queued GPU work Use Fence API to track GPU progress One fence per-frame is well amortized Explicit application control over resource residency Application declares resources currently in use on GPU

Remove State Mirroring Application responsibility to communicate current state to middleware

Render Context: Pipeline State Object (PSO) GPU Memory Pipeline State Object Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

Render Context: Remove State Reflection GPU Memory Pipeline State Object Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

CPU Overhead: Redundant Resource Binding Streaming identical resource bindings frame over frame Partial changes require copying all bindings

Direct3D 12: Descriptor Heaps & Tables Scales across extremes of HW capability Unified approach serves breadth of app binding flows Streaming changes to bindings Reuse of static bindings And everything between Dynamic indexing of shader resources

Descriptor Texture Small chunk of data defining resource parameters Just opaque data – no OS lifetime management Hardware representation of Direct3D “View” Texture Descriptor { Type Format Mip Count pData }

Descriptor Heaps Storage for descriptors App owns the layout GPU Memory Storage for descriptors App owns the layout Low overhead to manipulate Multiple heaps allowed Descriptor Heap

Descriptor Tables Context points to active heap A table is an index and a size in the heap Not an API object Single view type per table Multiple tables per type Pipeline State Object … Vertex Shader … Pixel Shader … Start Index Size

Render Context: Remove State Reflection GPU Memory Pipeline State Object Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

Render Context: Descriptor Tables & Heaps GPU Memory Pipeline State Object Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

Render Context: Direct3D 12 GPU Memory Pipeline State Object Input Assembler Vertex Shader Hull Shader Tessellator Domain Shader Geometry Shader Rasterizer Pixel Shader Output Merger Non-PSO State

CPU Overhead: Redundant Render Commands Typical applications send identical sequences of commands frame- over-frame Measured 90-95% coherence on typical modern games

Bundles Small command list Free threaded creation Recorded once Reused multiple times Free threaded creation Inherits from execute site Non-PSO State Descriptor Table Bindings Restrictions to ensure efficient driver implementation

Bundles SetPSO Draw SetTable Dispatch SetPSO SetTable Draw Context Clear Draw SetTable Execute Bundle SetPSO … SetPSO SetTable Draw

Example code without Bundles // Setup pContext->SetPipelineState(pPSO); pContext->SetRenderTargetViewTable(0, 1, FALSE, 0); pContext->SetVertexBufferTable(0, 1); pContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Draw 1 pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1); pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1); pContext->DrawInstanced(6, 1, 0, 0); pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1); pContext->DrawInstanced(6, 1, 6, 0); // Draw 2 pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1); Setup pipeline state and common descriptor tables Set object #1 specific tables and draw Set object #2 specific tables and draw

Bundles – Creating a Bundle // Create bundle pDevice->CreateCommandList(D3D12_COMMAND_LIST_TYPE_BUNDLE, pBundleAllocator, pPSO, pDescriptorHeap, &pBundle); // Record commands pBundle->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); pBundle->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1); pBundle->DrawInstanced(6, 1, 0, 0); pBundle->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1); pBundle->DrawInstanced(6, 1, 6, 0); pBundle->Close();

No Bundles Bundles // Setup pContext->SetPipelineState(pPSO); pContext->SetRenderTargetViewTable(0, 1, FALSE, 0); pContext->SetVertexBufferTable(0, 1); pContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // Draw 1 pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1); pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1); pContext->DrawInstanced(6, 1, 0, 0); pContext->SetShaderResourceViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1); pContext->DrawInstanced(6, 1, 6, 0); // Draw 2 pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1); // Setup pContext->SetRenderTargetViewTable(0, 1, FALSE, 0); pContext->SetVertexBufferTable(0, 1); // Draw 1 and 2 pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 0, 1); pContext->ExecuteBundle(pBundle); pContext->SetConstantBufferViewTable(D3D12_SHADER_STAGE_PIXEL, 1, 1);

Bundle Demo CPU usage comparison

Direct3D 12 – Command Creation Parallelism About that context… No Immediate Context All rendering via Command Lists Command Lists are submitted on a Command Queue

Command Lists and Command Queue Application responsible for Hazard tracking Declaring maximum number of recording command lists Resource renaming with GPU signaled fence Resources lifetime referenced by command lists Fence operations on the Command Queue Not on Command List or Bundle Signals occur on Command List completion Command List submission cost reduced by WDDM 2.0

Command Queue SetPSO Draw SetTable Dispatch SetPSO SetTable Draw Command List 1 Clear SetTable Execute Bundle A Draw SetPSO SetPSO Draw SetTable Dispatch Command Queue Execute Command List 1 Execute Command List 2 Signal Fence Command List 2 SetPSO SetTable Draw Clear Dispatch SetTable Execute Bundle A Execute Bundle B

Command Queue SetPSO Draw SetTable Dispatch SetPSO SetTable Draw Command List 1 Clear SetTable Execute Bundle A Draw SetPSO SetPSO Draw SetTable Dispatch Command Queue Execute Command List 1 Execute Command List 2 Signal Fence Command List 2 SetPSO SetTable Draw Clear Dispatch SetTable Execute Bundle A Execute Bundle B

Dynamic Heaps Resource Renaming Overhead Significant CPU overhead on ExecuteCommandList Significant driver complexity Solution: Efficient Application Suballocation Application creates large buffer resource and suballocates Data type determined by application Standardized alignment requirements Persistently mapped memory

Allocation vs. Suballocation CB IB VB GPU Memory Resource 1 Resource 2 CB IB VB … GPU Memory Resource 2 Resource 1 Heap

Direct3D 12 – CPU Parallelism Direct3D 12 has several parallel tasks Command List Generation Bundle Generation PSO Creation Resource Creation Dynamic Data Generation Runtime and driver designed for parallelism Developer chooses what to make parallel

3DMark Demo D3D11 vs D3D12 CPU usage comparison

D3D11 Profiling App Logic D3D11 UMD KMD DXGK App Logic App Logic Thread 0 Present App Logic D3D11 UMD KMD DXGK App Logic D3D11 Thread 1 App Logic D3D 11 Thread 2 Thread 3 App Logic D3D 11 0 ms 2.50 ms 5.00 ms 7.50 ms App Logic D3D Runtime User-mode Driver DXGKernel Kernel-mode Driver Present

D3D12 Profiling App Logic UMD App Logic UMD App Logic UMD App Logic Thread 0 App Logic D3D12 UMD DXGK/KMD Present App Logic UMD D3D12 Thread 1 App Logic UMD D3D12 Thread 2 App Logic UMD D3D12 Thread 3 0 ms 2.50 ms 5.00 ms 7.50 ms App Logic D3D Runtime User-mode Driver DXGKernel Kernel-mode Driver Present

D3D11 v D3D12 numbers App+GFX (ms) GFX-only (ms) D3D11 D3D12 Thread 0 App Logic UMD D3D12 Present DXGK/KMD Thread 0 Thread 1 Thread 2 Thread 3 0 ms 2.50 ms 5.00 ms 7.50 ms D3D11 KMD DXGK D3D 11 App+GFX (ms) GFX-only (ms) D3D11 D3D12 Thread 0 7.88 3.80 5.73 1.17 Thread 1 3.08 2.50 0.35 0.81 Thread 2 2.84 2.46 0.34 0.69 Thread 3 2.63 2.45 0.23 0.65 Total 16.42 11.21 6.65 3.32

Summary Greater CPU Efficiency Greater CPU Scalability Greater Developer Control CPU Parallelism Resource Lifetime Memory Usage

Thanks Game Developers Futuremark Hardware Vendors Microsoft AMD Intel nVidia Qualcomm Microsoft Direct3D Team Windows Graphics and Partner Teams

The End

Backup

Direct3D 12 – Pipeline State Object Inside PSO Outside PSO Shaders: VS/HS/TS/DS/GS/PS Blend State Rasterizer State Depth/Stencil State Input Layout IA Primitive Topology Type Triangle/Line/Point/Patch RT/DS Properties Format Sample Counts Resource Bindings Viewports Scissor Rects Blend Factor Depth Test Stencil Ref IA PrimitiveTopology Bucket List/Strip/ListAdj/StripAdj

Direct3D 12 – Bundle Disabled APIs ClearState Clear*/Copy*/Discard* ExecuteBundle ResourceBarrier SetPredication BeginQuery/EndQuery GenerateMips/ResolveSubresource SetDescriptorHeap CopyDescriptors {Create/Copy}StreamOutputViewsInHeap {Create/Copy}RenderTargetViewsInHeap {Create/Copy}DepthStencilViewsToHeap SetStreamOutputViewTable SetRenderTargetViewTable SetStreamOutputBufferOffset

Resource Hazard Example Scenario A simple read after write hazard in Direct3D 11 pContext->OMSetRenderTargets( 0, 1, &pRTTexture_RTV ); pContext->Draw( ... ); // write to pRTTexture pContext->OMSetRenderTargets( ... ); // Bind texture after rendering to it, // resulting in a read after write hazard for the GPU. pContext->PSSetShaderResources( 0, 1, &pRTTexture_SRV ); pContext->Draw( ... ); // read from pRTTexture

Direct3D 11 – Implicit Hazard Resolution Implicit hazard resolution by Direct3D runtime and driver. // Inside: pContext->PSSetShaderResources( 0, 1, &pRTTexture_SRV ); for (UINT Slot = 0; Slot < Slots; ++Slot) { // Enforce resource is not simultaneously bound as a GPU output, by using reference counts // If bound elsewhere, prevent state change by binding NULL instead. // Detect read after write hazard if (pSRV[ Slot ]->m_Fence != pSRV[ Slot ]->Resource().m_LastOutputFence) pSRV[ Slot ]->m_Fence = pSRV[ Slot ]->Resource().m_LastOutputFence; // Use the GPU operations to ensure the GPU completes all writes to this resource, // before any further render operations are issued. ResolveHazardInDriver(pSRV[ Slot ]) }

ResourceBarrier Types typedef enum D3D12_RESOURCE_BARRIER_TYPE { D3D12_RESOURCE_BARRIER_TYPE_TRANSITION, D3D12_RESOURCE_BARRIER_TYPE_ALIASING, D3D12_RESOURCE_BARRIER_TYPE_UAV, } D3D12_RESOURCE_BARRIER_TYPE;

Descriptor Tables - HLSL // Two fixed 8-element array at SRV table 2, offset 3, and SRV table 4, offset 2 Texture2D texA[8] : register(t3, 2); Texture2D texB[8] : register(t2, 4); // Fixed 2-element array at Sampler table 1 offset 0 SamplerState sam[2] : register(s0, 1); // Fixed 4-element array at CB table 2 offset 0 struct MyCBufferType { float foo; float bar; }; cbuffer MyCBufferType buf[4] : register(c0, 2);

Descriptor Tables - HLSL float4 main( uint i1 : INDEX1, uint i2 : INDEX2, float2 coord : TEXCOORD) : SV_TARGET { MyCBufferType b = buf[i1]; // CBuffer table 2 element #(i1) SamplerState s = sam[i1]; // Sampler table 1 element #(i1) Texture2D tA = texA[i1]; // SRV table 2 element #(i1+3) Texture2D tB = texB[i2]; // SRV table 4 element #(i2+2) float4 colorA = tA.Sample(s, coord); float4 colorB = tB.Sample(s, coord); return colorA * b.foo + colorB * b.bar; }

Bundles vs Multidraw Bundles Multidraw Fixed number of draws State change allowed between draws All 12 hardware Multidraw Flexible number of draws Single state Subset of 12 hardware Concepts are compatible and can be combined

More API Changes coming Draw Constants Heaps Swizzled Texture CPU Access Rendering Features Conservative Rasterization Pixel Shader UAV Ordering

Your Feedback is Important Build 2014 4/7/2017 Your Feedback is Important Fill out an evaluation of this session and help shape future events. Scan the QR code to evaluate this session on your mobile device. You’ll also be entered into a daily prize drawing! © 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.

© 2014 Microsoft Corporation. All rights reserved © 2014 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.