From 0888dca27d5ec66a3427a1bc33056c0372eb8bd1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 12 Jul 2006 09:25:17 +0000 Subject: [PATCH] First stab at a D3D renderer, only 30FPS so far... ? --- src/video/win32/SDL_d3drender.c | 165 +++++++++++++++++++++++++++++--- src/video/win32/SDL_gdirender.c | 8 +- 2 files changed, 158 insertions(+), 15 deletions(-) diff --git a/src/video/win32/SDL_d3drender.c b/src/video/win32/SDL_d3drender.c index 9d3635da5..9a57101e3 100644 --- a/src/video/win32/SDL_d3drender.c +++ b/src/video/win32/SDL_d3drender.c @@ -78,10 +78,10 @@ SDL_RenderDriver SDL_D3D_RenderDriver = { SDL_D3D_CreateRenderer, { "d3d", - (SDL_Renderer_Minimal | - SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | - SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | - SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), + ( //SDL_Renderer_Minimal | + SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | + SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | + SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), @@ -105,6 +105,7 @@ SDL_RenderDriver SDL_D3D_RenderDriver = { typedef struct { IDirect3DDevice9 *device; + SDL_bool beginScene; } SDL_D3D_RenderData; typedef struct @@ -112,6 +113,85 @@ typedef struct SDL_SW_YUVTexture *yuv; } SDL_D3D_TextureData; +static void +D3D_SetError(const char *prefix, HRESULT result) +{ + const char *error; + + switch (result) { + case D3DERR_WRONGTEXTUREFORMAT: + error = "WRONGTEXTUREFORMAT"; + break; + case D3DERR_UNSUPPORTEDCOLOROPERATION: + error = "UNSUPPORTEDCOLOROPERATION"; + break; + case D3DERR_UNSUPPORTEDCOLORARG: + error = "UNSUPPORTEDCOLORARG"; + break; + case D3DERR_UNSUPPORTEDALPHAOPERATION: + error = "UNSUPPORTEDALPHAOPERATION"; + break; + case D3DERR_UNSUPPORTEDALPHAARG: + error = "UNSUPPORTEDALPHAARG"; + break; + case D3DERR_TOOMANYOPERATIONS: + error = "TOOMANYOPERATIONS"; + break; + case D3DERR_CONFLICTINGTEXTUREFILTER: + error = "CONFLICTINGTEXTUREFILTER"; + break; + case D3DERR_UNSUPPORTEDFACTORVALUE: + error = "UNSUPPORTEDFACTORVALUE"; + break; + case D3DERR_CONFLICTINGRENDERSTATE: + error = "CONFLICTINGRENDERSTATE"; + break; + case D3DERR_UNSUPPORTEDTEXTUREFILTER: + error = "UNSUPPORTEDTEXTUREFILTER"; + break; + case D3DERR_CONFLICTINGTEXTUREPALETTE: + error = "CONFLICTINGTEXTUREPALETTE"; + break; + case D3DERR_DRIVERINTERNALERROR: + error = "DRIVERINTERNALERROR"; + break; + case D3DERR_NOTFOUND: + error = "NOTFOUND"; + break; + case D3DERR_MOREDATA: + error = "MOREDATA"; + break; + case D3DERR_DEVICELOST: + error = "DEVICELOST"; + break; + case D3DERR_DEVICENOTRESET: + error = "DEVICENOTRESET"; + break; + case D3DERR_NOTAVAILABLE: + error = "NOTAVAILABLE"; + break; + case D3DERR_OUTOFVIDEOMEMORY: + error = "OUTOFVIDEOMEMORY"; + break; + case D3DERR_INVALIDDEVICE: + error = "INVALIDDEVICE"; + break; + case D3DERR_INVALIDCALL: + error = "INVALIDCALL"; + break; + case D3DERR_DRIVERINVALIDCALL: + error = "DRIVERINVALIDCALL"; + break; + case D3DERR_WASSTILLDRAWING: + error = "WASSTILLDRAWING"; + break; + default: + error = "UNKNOWN"; + break; + } + SDL_SetError("%s: %s", prefix, error); +} + static void UpdateYUVTextureData(SDL_Texture * texture) { @@ -144,6 +224,8 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; SDL_Renderer *renderer; SDL_D3D_RenderData *data; + HRESULT result; + D3DPRESENT_PARAMETERS pparams; renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer)); if (!renderer) { @@ -160,8 +242,6 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) } SDL_zerop(data); - //data->device = IDirect3D9_CreateDevice(videodata->d3d, - renderer->CreateTexture = SDL_D3D_CreateTexture; renderer->QueryTexturePixels = SDL_D3D_QueryTexturePixels; renderer->SetTexturePalette = SDL_D3D_SetTexturePalette; @@ -184,6 +264,42 @@ SDL_D3D_CreateRenderer(SDL_Window * window, Uint32 flags) renderer->info.flags = SDL_Renderer_RenderTarget; + SDL_zero(pparams); + pparams.BackBufferWidth = window->w; + pparams.BackBufferHeight = window->h; + pparams.BackBufferFormat = D3DFMT_UNKNOWN; /* FIXME */ + if (flags & SDL_Renderer_PresentFlip2) { + pparams.BackBufferCount = 2; + pparams.SwapEffect = D3DSWAPEFFECT_FLIP; + } else if (flags & SDL_Renderer_PresentFlip3) { + pparams.BackBufferCount = 3; + pparams.SwapEffect = D3DSWAPEFFECT_FLIP; + } else if (flags & SDL_Renderer_PresentCopy) { + pparams.BackBufferCount = 1; + pparams.SwapEffect = D3DSWAPEFFECT_COPY; + } else { + pparams.BackBufferCount = 1; + pparams.SwapEffect = D3DSWAPEFFECT_DISCARD; + } + if (window->flags & SDL_WINDOW_FULLSCREEN) { + pparams.Windowed = FALSE; + } else { + pparams.Windowed = TRUE; + } + pparams.FullScreen_RefreshRateInHz = 0; /* FIXME */ + + result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */ + D3DDEVTYPE_HAL, + windowdata->hwnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &pparams, &data->device); + if (FAILED(result)) { + SDL_D3D_DestroyRenderer(renderer); + D3D_SetError("CreateDevice()", result); + return NULL; + } + data->beginScene = SDL_TRUE; + return renderer; } @@ -283,7 +399,7 @@ SDL_D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture, return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels, pitch); } else { - return 0; + return -1; } } @@ -315,12 +431,20 @@ SDL_D3D_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, Uint32 color) { SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; - Uint8 r, g, b; + HRESULT result; - r = (Uint8) ((color >> 16) & 0xFF); - g = (Uint8) ((color >> 8) & 0xFF); - b = (Uint8) (color & 0xFF); + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } + result = + IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, + (D3DCOLOR) color, 1.0f, 0); + if (FAILED(result)) { + D3D_SetError("Clear()", result); + return -1; + } return 0; } @@ -333,6 +457,10 @@ SDL_D3D_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, SDL_D3D_TextureData *texturedata = (SDL_D3D_TextureData *) texture->driverdata; + if (data->beginScene) { + IDirect3DDevice9_BeginScene(data->device); + data->beginScene = SDL_FALSE; + } return 0; } @@ -357,6 +485,18 @@ SDL_D3D_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect, static void SDL_D3D_RenderPresent(SDL_Renderer * renderer) { + SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; + HRESULT result; + + if (!data->beginScene) { + IDirect3DDevice9_EndScene(data->device); + data->beginScene = SDL_TRUE; + } + + result = IDirect3DDevice9_Present(data->device, NULL, NULL, NULL, NULL); + if (FAILED(result)) { + D3D_SetError("Present()", result); + } } static void @@ -377,6 +517,9 @@ SDL_D3D_DestroyRenderer(SDL_Renderer * renderer) SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata; if (data) { + if (data->device) { + IDirect3DDevice9_Release(data->device); + } SDL_free(data); } SDL_free(renderer); diff --git a/src/video/win32/SDL_gdirender.c b/src/video/win32/SDL_gdirender.c index c732e6663..2c0b528b5 100644 --- a/src/video/win32/SDL_gdirender.c +++ b/src/video/win32/SDL_gdirender.c @@ -79,10 +79,10 @@ SDL_RenderDriver SDL_GDI_RenderDriver = { SDL_GDI_CreateRenderer, { "gdi", - (//SDL_Renderer_Minimal | - SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | - SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | - SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), + ( //SDL_Renderer_Minimal | + SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | + SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | + SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),