--- a/src/video/win32/SDL_d3drender.c Thu Jul 13 08:15:35 2006 +0000
+++ b/src/video/win32/SDL_d3drender.c Fri Jul 14 06:40:53 2006 +0000
@@ -24,7 +24,6 @@
#if SDL_VIDEO_RENDER_D3D
#include "SDL_win32video.h"
-#include "../SDL_yuv_sw_c.h"
/* Direct3D renderer implementation */
@@ -32,9 +31,6 @@
Uint32 flags);
static int SDL_D3D_CreateTexture(SDL_Renderer * renderer,
SDL_Texture * texture);
-static int SDL_D3D_QueryTexturePixels(SDL_Renderer * renderer,
- SDL_Texture * texture, void **pixels,
- int *pitch);
static int SDL_D3D_SetTexturePalette(SDL_Renderer * renderer,
SDL_Texture * texture,
const SDL_Color * colors, int firstcolor,
@@ -85,19 +81,20 @@
(SDL_TextureBlendMode_None |
SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
- 11,
+ 12,
{
SDL_PixelFormat_Index8,
+ SDL_PixelFormat_RGB332,
+ SDL_PixelFormat_RGB444,
SDL_PixelFormat_RGB555,
+ SDL_PixelFormat_ARGB4444,
+ SDL_PixelFormat_ARGB1555,
SDL_PixelFormat_RGB565,
SDL_PixelFormat_RGB888,
- SDL_PixelFormat_BGR888,
SDL_PixelFormat_ARGB8888,
- SDL_PixelFormat_RGBA8888,
- SDL_PixelFormat_ABGR8888,
- SDL_PixelFormat_BGRA8888,
- SDL_PixelFormat_YUY2,
- SDL_PixelFormat_UYVY},
+ SDL_PixelFormat_ARGB2101010,
+ SDL_PixelFormat_UYVY,
+ SDL_PixelFormat_YUY2},
0,
0}
};
@@ -110,9 +107,15 @@
typedef struct
{
- SDL_SW_YUVTexture *yuv;
+ IDirect3DTexture9 *texture;
} SDL_D3D_TextureData;
+typedef struct
+{
+ float x, y, z;
+ float tu, tv;
+} Vertex;
+
static void
D3D_SetError(const char *prefix, HRESULT result)
{
@@ -192,18 +195,37 @@
SDL_SetError("%s: %s", prefix, error);
}
-static void
-UpdateYUVTextureData(SDL_Texture * texture)
+static D3DFORMAT
+PixelFormatToD3DFMT(Uint32 format)
{
- SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
- SDL_Rect rect;
-
- rect.x = 0;
- rect.y = 0;
- rect.w = texture->w;
- rect.h = texture->h;
- //SDL_SW_CopyYUVToRGB(data->yuv, &rect, data->format, texture->w,
- // texture->h, data->pixels, data->pitch);
+ switch (format) {
+ case SDL_PixelFormat_Index8:
+ return D3DFMT_P8;
+ case SDL_PixelFormat_RGB332:
+ return D3DFMT_R3G3B2;
+ case SDL_PixelFormat_RGB444:
+ return D3DFMT_X4R4G4B4;
+ case SDL_PixelFormat_RGB555:
+ return D3DFMT_X1R5G5B5;
+ case SDL_PixelFormat_ARGB4444:
+ return D3DFMT_A4R4G4B4;
+ case SDL_PixelFormat_ARGB1555:
+ return D3DFMT_A1R5G5B5;
+ case SDL_PixelFormat_RGB565:
+ return D3DFMT_R5G6B5;
+ case SDL_PixelFormat_RGB888:
+ return D3DFMT_X8R8G8B8;
+ case SDL_PixelFormat_ARGB8888:
+ return D3DFMT_A8R8G8B8;
+ case SDL_PixelFormat_ARGB2101010:
+ return D3DFMT_A2R10G10B10;
+ case SDL_PixelFormat_UYVY:
+ return D3DFMT_UYVY;
+ case SDL_PixelFormat_YUY2:
+ return D3DFMT_YUY2;
+ default:
+ return D3DFMT_UNKNOWN;
+ }
}
void
@@ -243,7 +265,6 @@
SDL_zerop(data);
renderer->CreateTexture = SDL_D3D_CreateTexture;
- renderer->QueryTexturePixels = SDL_D3D_QueryTexturePixels;
renderer->SetTexturePalette = SDL_D3D_SetTexturePalette;
renderer->GetTexturePalette = SDL_D3D_GetTexturePalette;
renderer->UpdateTexture = SDL_D3D_UpdateTexture;
@@ -267,7 +288,12 @@
SDL_zero(pparams);
pparams.BackBufferWidth = window->w;
pparams.BackBufferHeight = window->h;
- pparams.BackBufferFormat = D3DFMT_UNKNOWN; /* FIXME */
+ if (window->flags & SDL_WINDOW_FULLSCREEN) {
+ pparams.BackBufferFormat =
+ PixelFormatToD3DFMT(display->fullscreen_mode->format);
+ } else {
+ pparams.BackBufferFormat = D3DFMT_UNKNOWN;
+ }
if (flags & SDL_Renderer_PresentFlip2) {
pparams.BackBufferCount = 2;
pparams.SwapEffect = D3DSWAPEFFECT_FLIP;
@@ -283,10 +309,12 @@
}
if (window->flags & SDL_WINDOW_FULLSCREEN) {
pparams.Windowed = FALSE;
+ pparams.FullScreen_RefreshRateInHz =
+ display->fullscreen_mode->refresh_rate;
} else {
pparams.Windowed = TRUE;
+ pparams.FullScreen_RefreshRateInHz = 0;
}
- pparams.FullScreen_RefreshRateInHz = 0; /* FIXME */
pparams.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
result = IDirect3D9_CreateDevice(videodata->d3d, D3DADAPTER_DEFAULT, /* FIXME */
@@ -301,6 +329,11 @@
}
data->beginScene = SDL_TRUE;
+ /* Set up parameters for rendering */
+ IDirect3DDevice9_SetRenderState(data->device, D3DRS_CULLMODE,
+ D3DCULL_NONE);
+ IDirect3DDevice9_SetFVF(data->device, D3DFVF_XYZ | D3DFVF_TEX1);
+
return renderer;
}
@@ -312,6 +345,8 @@
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
SDL_D3D_TextureData *data;
+ D3DPOOL pool;
+ HRESULT result;
data = (SDL_D3D_TextureData *) SDL_malloc(sizeof(*data));
if (!data) {
@@ -322,20 +357,23 @@
texture->driverdata = data;
- return 0;
-}
+ if (texture->access == SDL_TextureAccess_Local) {
+ pool = D3DPOOL_MANAGED;
+ } else {
+ pool = D3DPOOL_DEFAULT;
+ }
+ result =
+ IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
+ texture->h, 1, 0,
+ PixelFormatToD3DFMT(texture->format),
+ pool, &data->texture, NULL);
+ if (FAILED(result)) {
+ SDL_free(data);
+ D3D_SetError("CreateTexture()", result);
+ return -1;
+ }
-static int
-SDL_D3D_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
- void **pixels, int *pitch)
-{
- SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
-
- if (data->yuv) {
- return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
- } else {
- return 0;
- }
+ return 0;
}
static int
@@ -347,12 +385,7 @@
(SDL_D3D_RenderData *) renderer->driverdata;
SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
- if (data->yuv) {
- SDL_SetError("YUV textures don't have a palette");
- return -1;
- } else {
- return 0;
- }
+ return 0;
}
static int
@@ -361,12 +394,7 @@
{
SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
- if (data->yuv) {
- SDL_SetError("YUV textures don't have a palette");
- return -1;
- } else {
- return 0;
- }
+ return 0;
}
static int
@@ -374,19 +402,59 @@
const SDL_Rect * rect, const void *pixels, int pitch)
{
SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
+ SDL_D3D_RenderData *renderdata =
+ (SDL_D3D_RenderData *) renderer->driverdata;
+ IDirect3DTexture9 *temp;
+ RECT d3drect;
+ D3DLOCKED_RECT locked;
+ const Uint8 *src;
+ Uint8 *dst;
+ int row, length;
+ HRESULT result;
- if (data->yuv) {
- if (SDL_SW_UpdateYUVTexture(data->yuv, rect, pixels, pitch) < 0) {
- return -1;
- }
- UpdateYUVTextureData(texture);
- return 0;
- } else {
- SDL_D3D_RenderData *renderdata =
- (SDL_D3D_RenderData *) renderer->driverdata;
+ result =
+ IDirect3DDevice9_CreateTexture(renderdata->device, texture->w,
+ texture->h, 1, 0,
+ PixelFormatToD3DFMT(texture->format),
+ D3DPOOL_SYSTEMMEM, &temp, NULL);
+ if (FAILED(result)) {
+ D3D_SetError("CreateTexture()", result);
+ return -1;
+ }
+
+ d3drect.left = rect->x;
+ d3drect.right = rect->x + rect->w;
+ d3drect.top = rect->y;
+ d3drect.bottom = rect->y + rect->h;
+
+ result = IDirect3DTexture9_LockRect(temp, 0, &locked, &d3drect, 0);
+ if (FAILED(result)) {
+ IDirect3DTexture9_Release(temp);
+ D3D_SetError("LockRect()", result);
+ return -1;
+ }
- return 0;
+ src = pixels;
+ dst = locked.pBits;
+ length = rect->w * SDL_BYTESPERPIXEL(texture->format);
+ for (row = 0; row < rect->h; ++row) {
+ SDL_memcpy(dst, src, length);
+ src += pitch;
+ dst += locked.Pitch;
}
+ IDirect3DTexture9_UnlockRect(temp, 0);
+
+ result =
+ IDirect3DDevice9_UpdateTexture(renderdata->device,
+ (IDirect3DBaseTexture9 *) temp,
+ (IDirect3DBaseTexture9 *) data->
+ texture);
+ IDirect3DTexture9_Release(temp);
+ if (FAILED(result)) {
+ D3D_SetError("UpdateTexture()", result);
+ return -1;
+ }
+ return 0;
}
static int
@@ -395,13 +463,30 @@
int *pitch)
{
SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
+ RECT d3drect;
+ D3DLOCKED_RECT locked;
+ HRESULT result;
- if (data->yuv) {
- return SDL_SW_LockYUVTexture(data->yuv, rect, markDirty, pixels,
- pitch);
- } else {
+ if (texture->access != SDL_TextureAccess_Local) {
+ SDL_SetError("Can't lock remote video memory");
return -1;
}
+
+ d3drect.left = rect->x;
+ d3drect.right = rect->x + rect->w;
+ d3drect.top = rect->y;
+ d3drect.bottom = rect->y + rect->h;
+
+ result =
+ IDirect3DTexture9_LockRect(data->texture, 0, &locked, &d3drect,
+ markDirty ? 0 : D3DLOCK_NO_DIRTY_UPDATE);
+ if (FAILED(result)) {
+ D3D_SetError("LockRect()", result);
+ return -1;
+ }
+ *pixels = locked.pBits;
+ *pitch = locked.Pitch;
+ return 0;
}
static void
@@ -409,16 +494,27 @@
{
SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
- if (data->yuv) {
- SDL_SW_UnlockYUVTexture(data->yuv);
- UpdateYUVTextureData(texture);
- }
+ IDirect3DTexture9_UnlockRect(data->texture, 0);
}
static void
SDL_D3D_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
int numrects, const SDL_Rect * rects)
{
+ SDL_D3D_TextureData *data = (SDL_D3D_TextureData *) texture->driverdata;
+ RECT d3drect;
+ int i;
+
+ for (i = 0; i < numrects; ++i) {
+ const SDL_Rect *rect = &rects[i];
+
+ d3drect.left = rect->x;
+ d3drect.right = rect->x + rect->w;
+ d3drect.top = rect->y;
+ d3drect.bottom = rect->y + rect->h;
+
+ IDirect3DTexture9_AddDirtyRect(data->texture, &d3drect);
+ }
}
static void
@@ -441,11 +537,13 @@
}
d3drect.x1 = rect->x;
- d3drect.x2 = rect->x+rect->w;
+ d3drect.x2 = rect->x + rect->w;
d3drect.y1 = rect->y;
- d3drect.y2 = rect->y+rect->h;
+ d3drect.y2 = rect->y + rect->h;
- result = IDirect3DDevice9_Clear(data->device, 1, &d3drect, D3DCLEAR_TARGET, (D3DCOLOR) color, 1.0f, 0);
+ result =
+ IDirect3DDevice9_Clear(data->device, 1, &d3drect, D3DCLEAR_TARGET,
+ (D3DCOLOR) color, 1.0f, 0);
if (FAILED(result)) {
D3D_SetError("Clear()", result);
return -1;
@@ -461,11 +559,62 @@
SDL_D3D_RenderData *data = (SDL_D3D_RenderData *) renderer->driverdata;
SDL_D3D_TextureData *texturedata =
(SDL_D3D_TextureData *) texture->driverdata;
+ float minx, miny, maxx, maxy;
+ float mintu, maxtu, mintv, maxtv;
+ Vertex vertices[4];
+ HRESULT result;
if (data->beginScene) {
IDirect3DDevice9_BeginScene(data->device);
data->beginScene = SDL_FALSE;
}
+
+ minx = (float) dstrect->x;
+ miny = (float) dstrect->y;
+ maxx = (float) dstrect->x + dstrect->w;
+ maxy = (float) dstrect->y + dstrect->h;
+
+ mintu = (float) srcrect->x / texture->w;
+ maxtu = (float) (srcrect->x + srcrect->w) / texture->w;
+ mintv = (float) srcrect->y / texture->h;
+ maxtv = (float) (srcrect->y + srcrect->h) / texture->h;
+
+ vertices[0].x = minx;
+ vertices[0].y = miny;
+ vertices[0].z = 0.0f;
+ vertices[0].tu = mintu;
+ vertices[0].tv = mintv;
+ vertices[1].x = maxx;
+ vertices[1].y = miny;
+ vertices[1].z = 0.0f;
+ vertices[1].tu = maxtu;
+ vertices[1].tv = mintv;
+ vertices[2].x = maxx;
+ vertices[2].y = maxy;
+ vertices[2].z = 0.0f;
+ vertices[2].tu = maxtu;
+ vertices[2].tv = maxtv;
+ vertices[3].x = minx;
+ vertices[3].y = maxy;
+ vertices[3].z = 0.0f;
+ vertices[3].tu = mintu;
+ vertices[3].tv = maxtv;
+
+ result =
+ IDirect3DDevice9_SetTexture(data->device, 0,
+ (IDirect3DBaseTexture9 *) texturedata->
+ texture);
+ if (FAILED(result)) {
+ D3D_SetError("SetTexture()", result);
+ return -1;
+ }
+ result =
+ IDirect3DDevice9_DrawPrimitiveUP(data->device, D3DPT_TRIANGLEFAN, 2,
+ vertices, sizeof(*vertices));
+ if (FAILED(result)) {
+ D3D_SetError("DrawPrimitiveUP()", result);
+ return -1;
+ }
return 0;
}
@@ -512,6 +661,9 @@
if (!data) {
return;
}
+ if (data->texture) {
+ IDirect3DTexture9_Release(data->texture);
+ }
SDL_free(data);
texture->driverdata = NULL;
}