Jump to content

  • Log In with Google      Sign In   
  • Create Account


Making SlimDX tutorial code compatible with old graphics hardware...


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
No replies to this topic

#1 CdrTomalak   Members   -  Reputation: 271

Like
1Likes
Like

Posted 05 June 2012 - 10:26 AM

You might have seen me post about this problem before, but basically I have just merged the SlimDX tutorial code with Ron Pentons game framework as per his C# Game Programming book.

The problem is, this won't run on my Dell Latitude D600 (DXGI ERROR UNSUPPORTED), whilst is fine on my slightly old gaming rig with an Nvidia 9800GT. All it's doing is displaying a triangle.

The quesiton is, how can I alter the code to make it compatible with the ATI Radeon Mobility 9000 graphics hardware on the D600? The specificaiton for this GPU says it doesn't even officically support DirectX9!

Here's the code anyways (excuse the lack of comments - I've stripped most of them out shorten this post).

using System;
using System.ComponentModel;
using SlimDX;
using SlimDX.Windows;
using System.Windows.Forms;
namespace BasicWindow_1
{
public class Game : Form
{
	 // --------------------------------------------------------------------
		// static variables
		// --------------------------------------------------------------------
		static string gametitle  = "Test";
		static int screenwidth   = 640;
		static int screenheight  = 480;
  static bool windowed	 = true;
		static bool graphicslost = false;
  static bool paused	   = false;
  // --------------------------------------------------------------------

  // --------------------------------------------------------------------
  // Direct3D9 object
  // --------------------------------------------------------------------
  SlimDX.Direct3D9.Direct3D myD3D;
  // --------------------------------------------------------------------

  // --------------------------------------------------------------------
		// Devices
  // --------------------------------------------------------------------

  SlimDX.Direct3D11.Device graphics		= null;
  SlimDX.DXGI.SwapChain swapChain = null;

  SlimDX.D3DCompiler.ShaderSignature inputSignature = null;
		SlimDX.Direct3D11.VertexShader vertexShader = null;
		SlimDX.Direct3D11.PixelShader pixelShader = null;

  SlimDX.Direct3D11.RenderTargetView renderTarget = null;

  SlimDX.Direct3D11.DeviceContext context = null;

  // KEYBOARD ...
  SlimDX.DirectInput.DirectInput directInput = null;
  SlimDX.DirectInput.Keyboard keyboard = null;

  // MOUSE ...
  SlimDX.DirectInput.Mouse mouse		= null;

  // SOUND ...
		SlimDX.DirectSound.DirectSound sound		= null;
	  
	  
  // --------------------------------------------------------------------

  // --------------------------------------------------------------------
  // Vertex Object
  // --------------------------------------------------------------------
  SlimDX.DataStream vertices = new DataStream(12 * 3, true, true);
  SlimDX.Direct3D11.Buffer vertexBuffer = null; // This is set in init geom.
  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


  // ********************************************************************
  // Game Constructor!
  public Game()
  {
	  ClientSize = new System.Drawing.Size( screenwidth, screenheight );
  
			Text = gametitle;

  }
  // ********************************************************************


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // START: Method InitialiseGraphics
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  public void InitialiseGraphics()
  {
  
   var description = new SlimDX.DXGI.SwapChainDescription()
			{
				BufferCount = 2,
				Usage = SlimDX.DXGI.Usage.RenderTargetOutput,
				OutputHandle = this.Handle,
				IsWindowed = true,
				ModeDescription = new SlimDX.DXGI.ModeDescription(0, 0, new SlimDX.Rational(60, 1), SlimDX.DXGI.Format.R8G8B8A8_UNorm),
				SampleDescription = new SlimDX.DXGI.SampleDescription(1, 0),
				Flags = SlimDX.DXGI.SwapChainFlags.AllowModeSwitch,
				SwapEffect = SlimDX.DXGI.SwapEffect.Discard
			};
  
   SlimDX.Direct3D11.Device.CreateWithSwapChain(
	SlimDX.Direct3D11.DriverType.Hardware,
	SlimDX.Direct3D11.DeviceCreationFlags.Debug,
	description,
	out graphics,
	out swapChain
   );
  
   // create a view of our render target, which is the backbuffer of the swap chain we just created
   using (var resource = SlimDX.Direct3D11.Resource.FromSwapChain<SlimDX.Direct3D11.Texture2D>(swapChain, 0))
				renderTarget = new SlimDX.Direct3D11.RenderTargetView(graphics, resource);
   // setting a viewport is required if you want to actually see anything
			context = graphics.ImmediateContext;
			var viewport = new SlimDX.Direct3D11.Viewport(0.0f, 0.0f, this.ClientSize.Width, this.ClientSize.Height);
			context.OutputMerger.SetTargets(renderTarget);
			context.Rasterizer.SetViewports(viewport);
   // load and compile the vertex shader  
			using (var bytecode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile("E:\\MY_AREA\\SharpDevelop_Projects\\SlimDX_StartOver\\BasicWindow_1\\BasicWindow_1\	riangle.fx", "VShader", "vs_4_0", SlimDX.D3DCompiler.ShaderFlags.None, SlimDX.D3DCompiler.EffectFlags.None))
			{
				inputSignature = SlimDX.D3DCompiler.ShaderSignature.GetInputSignature(bytecode);
				vertexShader = new SlimDX.Direct3D11.VertexShader(graphics, bytecode);
			}
  
   // load and compile the pixel shader
			using (var bytecode = SlimDX.D3DCompiler.ShaderBytecode.CompileFromFile("E:\\MY_AREA\\SharpDevelop_Projects\\SlimDX_StartOver\\BasicWindow_1\\BasicWindow_1\	riangle.fx", "PShader", "ps_4_0", SlimDX.D3DCompiler.ShaderFlags.None, SlimDX.D3DCompiler.EffectFlags.None))
				pixelShader = new SlimDX.Direct3D11.PixelShader(graphics, bytecode);
  
  
   // -----------------------------------------------------------------------
  }
  // END: Method InitialiseGraphics


		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // ***************** InitializeSound START ****************************
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// Initialize the DirectSound subsystem
		public void InitialiseSound()
		{
			// set up a device
			sound = new SlimDX.DirectSound.DirectSound();

   sound.SetCooperativeLevel( this.Handle, SlimDX.DirectSound.CooperativeLevel.Normal );
		}
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // ********************************************************************
  // *************** InitializeInput START ******************************
  // ********************************************************************
		// Initialize the DirectInput subsystem
		public void InitialiseInput()
		{
			// set up the keyboard
   directInput = new SlimDX.DirectInput.DirectInput();
			keyboard = new SlimDX.DirectInput.Keyboard(directInput);
  
   keyboard.SetCooperativeLevel(
				this,
				SlimDX.DirectInput.CooperativeLevel.Background |
				SlimDX.DirectInput.CooperativeLevel.Nonexclusive );
			keyboard.Acquire();
			// set up the mouse
			mouse = new SlimDX.DirectInput.Mouse(directInput);
			mouse.SetCooperativeLevel(
				this,
				SlimDX.DirectInput.CooperativeLevel.Background |
				SlimDX.DirectInput.CooperativeLevel.Nonexclusive );
			mouse.Acquire();
		}
  // ********************************************************************

  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // Method InitialiseGeometry
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  public void InitialiseGeometry()
  {
   vertices.Write(new Vector3(0.0f, 0.5f, 0.5f));
   vertices.Write(new Vector3(0.5f, -0.5f, 0.5f));
   vertices.Write(new Vector3(-0.5f, -0.5f, 0.5f));
   vertices.Position = 0;  // Rewind the position after we're done.
			// create the vertex layout and buffer
			var elements = new[] { new SlimDX.Direct3D11.InputElement("POSITION", 0, SlimDX.DXGI.Format.R32G32B32_Float, 0) };
			var layout = new SlimDX.Direct3D11.InputLayout(graphics, inputSignature, elements);
  
   // Once we have our vertex data in memory, we need to load it into
   // a Direct3D vertex buffer, which can then be passed into the graphics pipeline.
   vertexBuffer = new SlimDX.Direct3D11.Buffer(
   graphics,
   vertices,
   12 * 3,
   SlimDX.Direct3D11.ResourceUsage.Default,
   SlimDX.Direct3D11.BindFlags.VertexBuffer,
   SlimDX.Direct3D11.CpuAccessFlags.None,
   SlimDX.Direct3D11.ResourceOptionFlags.None,
   0);
  
			// configure the Input Assembler portion of the pipeline with the vertex data
			context.InputAssembler.InputLayout = layout;
			context.InputAssembler.PrimitiveTopology = SlimDX.Direct3D11.PrimitiveTopology.TriangleList;
			context.InputAssembler.SetVertexBuffers(0, new SlimDX.Direct3D11.VertexBufferBinding(vertexBuffer, 12, 0));
			// set the shaders
			context.VertexShader.Set(vertexShader);
			context.PixelShader.Set(pixelShader);
  }
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // START: Method RenderFrame
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  public void RenderFrame()
  {
   // GT 01/06/12:
   // From what I can tell, the render frame method
  }
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // END: Method RenderFrame
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // ************** ProcessFrame START **********************************
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// Process one iteration of the game loop
		protected virtual void ProcessFrame()
		{
			// process the game only while it's not paused
			if( !paused )
			{

			}
			else
				System.Threading.Thread.Sleep( 1 );
		}
		// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // Render....
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		protected virtual void Render()
		{
			if( graphics != null )
			{
	context.ClearRenderTargetView(renderTarget, new SlimDX.Color4(0.5f, 0.5f, 1.0f));
  
	// draw the triangle
	context.Draw(3, 0);
	swapChain.Present(0, SlimDX.DXGI.PresentFlags.None);
  
			}
		}
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  // ******************** Run START *************************************
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		// Run the game
		public void Run()
		{
			while( this.Created )
			{
				// Process one frame of the game
				ProcessFrame();
				// Render the current scene
	// I.e. display graphics to the user in the game form.
				Render();
				// Handle all events
				Application.DoEvents();
			}
		}
  // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


		// ********************************************************************
  // **************** HANDLE WINDOWS EVENTS *****************************
  // ********************************************************************
		// Handle windows events
		protected override void OnLostFocus( EventArgs e )
		{
			base.OnLostFocus( e );
			Paused = true;
		}
		protected override void OnKeyDown( KeyEventArgs e )
		{
			base.OnKeyDown( e );
			if( e.KeyCode == System.Windows.Forms.Keys.Escape )
			{
				this.Close();
			}
			if ( e.KeyCode == System.Windows.Forms.Keys.P )
			{
				Paused = !Paused;
			}
		}
  // ********************************************************************
  // ********************************************************************
		// Property to pause/unpause the game, or get its pause state
		public bool Paused
		{
			get { return paused; }
			set
			{
				// pause the game
				if( value == true && paused == false )
				{
	 // TO DO
	 //
					//gametimer.Pause();
					paused = true;
				}
				// unpause the game
				if( value == false && paused == true )
				{
	 // TO DO
	 //
					//gametimer.Unpause();
					paused = false;
				}
			}
		}
  // ********************************************************************

  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  // START: MAIN
  [STAThread]
  private static void Main(string[] args)
  {
   Game game;
  
   try
   {
	game = new Game();
  
	// Initialise Gfx, Sound, Input, Geometry
				game.InitialiseGraphics();
				game.InitialiseSound();
				game.InitialiseInput();
  
	game.InitialiseGeometry();
	game.Show();
	game.Run();
   }
   catch( Exception e )
			{
				MessageBox.Show( "Error: " + e.Message );
			}
  }
  // END: MAIN
}
}

EDIT: I might have found something in the SlimDX tutorial. One of the parameters to the SlimDX.Direct3D11.Device.CreateWithSwapChain() method is for Feature Levels:

"The third parameter to the device creation function is an array of feature levels. Feature levels provide a unified method by which Direct3D 11 can run on lower end hardware. Each feature level mandates a specific set of functionality that an adapter must expose, enabling application developers to reliably scale their applications depending on the hardware a user might have. The array allows you to specify a set of feature levels that you’d like Direct3D to try to use. It will try them in order and create a device with the first one that works. You can use the Device.GetSupportedFeatureLevel method to get the highest feature level currently supported by the primary adapter. If you don’t care to specify a set and just want to use the highest available, you can skip the parameter and use the less generic overload. Once the device has been created, you can access the Device.FeatureLevel property to see which feature level is currently active. The 10Level9 reference on MSDN gives in-depth details about exactly which portions of the API are available on which feature levels."

I don't actually use this in my program, but perhaps this is the key to making my program compatible with the old D600?

EDIT: I think I've concluded something, although it's not good.

On my 9800GT rig the following works fine:

SlimDX.Direct3D11.FeatureLevel[] featureLevels = new SlimDX.Direct3D11.FeatureLevel[] { SlimDX.Direct3D11.FeatureLevel.Level_10_0 };
   SlimDX.Direct3D11.Device.CreateWithSwapChain(
    SlimDX.Direct3D11.DriverType.Hardware,
    SlimDX.Direct3D11.DeviceCreationFlags.Debug,
    featureLevels,
    description,
    out graphics,
    out swapChain
   );  

But when I use FeatureLevel.Level_10_1 or above, I get DXGI ERROR UNSUPPORTED, because this card doesn't support DX11.

I dropped down to FeatureLevel.Level_9_1 on the D600 laptop, but to no avail. Apparently the GPU supports DX8.1 and Shader 1.4, where as the requirements for Level_9_1 are shader model 2.

Oh dear. Still, it was interesting finding out.

Edited by CdrTomalak, 05 June 2012 - 11:18 AM.


Sponsor:



Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS