early-access version 2835
This commit is contained in:
6
externals/SDL/src/render/SDL_d3dmath.c
vendored
6
externals/SDL/src/render/SDL_d3dmath.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED
|
||||
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED
|
||||
#include "SDL_stdinc.h"
|
||||
|
||||
#include "SDL_d3dmath.h"
|
||||
@@ -131,6 +131,6 @@ Float4X4 MatrixRotationZ(float r)
|
||||
|
||||
}
|
||||
|
||||
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED */
|
||||
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
6
externals/SDL/src/render/SDL_d3dmath.h
vendored
6
externals/SDL/src/render/SDL_d3dmath.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -20,7 +20,7 @@
|
||||
*/
|
||||
#include "../SDL_internal.h"
|
||||
|
||||
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED
|
||||
#if (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED
|
||||
|
||||
/* Direct3D matrix math functions */
|
||||
|
||||
@@ -67,6 +67,6 @@ Float4X4 MatrixRotationX(float r);
|
||||
Float4X4 MatrixRotationY(float r);
|
||||
Float4X4 MatrixRotationZ(float r);
|
||||
|
||||
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11) && !SDL_RENDER_DISABLED */
|
||||
#endif /* (SDL_VIDEO_RENDER_D3D || SDL_VIDEO_RENDER_D3D11 || SDL_VIDEO_RENDER_D3D12) && !SDL_RENDER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
706
externals/SDL/src/render/SDL_render.c
vendored
706
externals/SDL/src/render/SDL_render.c
vendored
File diff suppressed because it is too large
Load Diff
50
externals/SDL/src/render/SDL_sysrender.h
vendored
50
externals/SDL/src/render/SDL_sysrender.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -28,6 +28,19 @@
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_yuv_sw_c.h"
|
||||
|
||||
|
||||
/**
|
||||
* A rectangle, with the origin at the upper left (double precision).
|
||||
*/
|
||||
typedef struct SDL_DRect
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
double w;
|
||||
double h;
|
||||
} SDL_DRect;
|
||||
|
||||
|
||||
/* The SDL 2D rendering system */
|
||||
|
||||
typedef struct SDL_RenderDriver SDL_RenderDriver;
|
||||
@@ -107,6 +120,21 @@ typedef struct SDL_RenderCommand
|
||||
} SDL_RenderCommand;
|
||||
|
||||
|
||||
typedef struct SDL_VertexSolid
|
||||
{
|
||||
SDL_FPoint position;
|
||||
SDL_Color color;
|
||||
} SDL_VertexSolid;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SDL_RENDERLINEMETHOD_POINTS,
|
||||
SDL_RENDERLINEMETHOD_LINES,
|
||||
SDL_RENDERLINEMETHOD_GEOMETRY,
|
||||
} SDL_RenderLineMethod;
|
||||
|
||||
|
||||
/* Define the SDL renderer structure */
|
||||
struct SDL_Renderer
|
||||
{
|
||||
@@ -128,9 +156,9 @@ struct SDL_Renderer
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect);
|
||||
int (*QueueCopyEx) (SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcquad, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y);
|
||||
int (*QueueGeometry) (SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y);
|
||||
|
||||
@@ -186,12 +214,12 @@ struct SDL_Renderer
|
||||
SDL_bool integer_scale;
|
||||
|
||||
/* The drawable area within the window */
|
||||
SDL_FRect viewport;
|
||||
SDL_FRect viewport_backup;
|
||||
SDL_DRect viewport;
|
||||
SDL_DRect viewport_backup;
|
||||
|
||||
/* The clip rectangle within the window */
|
||||
SDL_FRect clip_rect;
|
||||
SDL_FRect clip_rect_backup;
|
||||
SDL_DRect clip_rect;
|
||||
SDL_DRect clip_rect_backup;
|
||||
|
||||
/* Wether or not the clipping rectangle is used. */
|
||||
SDL_bool clipping_enabled;
|
||||
@@ -207,6 +235,9 @@ struct SDL_Renderer
|
||||
/* Whether or not to scale relative mouse motion */
|
||||
SDL_bool relative_scaling;
|
||||
|
||||
/* The method of drawing lines */
|
||||
SDL_RenderLineMethod line_method;
|
||||
|
||||
/* Remainder from scaled relative motion */
|
||||
float xrel;
|
||||
float yrel;
|
||||
@@ -226,8 +257,8 @@ struct SDL_Renderer
|
||||
SDL_RenderCommand *render_commands_pool;
|
||||
Uint32 render_command_generation;
|
||||
Uint32 last_queued_color;
|
||||
SDL_FRect last_queued_viewport;
|
||||
SDL_FRect last_queued_cliprect;
|
||||
SDL_DRect last_queued_viewport;
|
||||
SDL_DRect last_queued_cliprect;
|
||||
SDL_bool last_queued_cliprect_enabled;
|
||||
SDL_bool color_queued;
|
||||
SDL_bool viewport_queued;
|
||||
@@ -252,6 +283,7 @@ struct SDL_RenderDriver
|
||||
/* Not all of these are available in a given build. Use #ifdefs, etc. */
|
||||
extern SDL_RenderDriver D3D_RenderDriver;
|
||||
extern SDL_RenderDriver D3D11_RenderDriver;
|
||||
extern SDL_RenderDriver D3D12_RenderDriver;
|
||||
extern SDL_RenderDriver GL_RenderDriver;
|
||||
extern SDL_RenderDriver GLES2_RenderDriver;
|
||||
extern SDL_RenderDriver GLES_RenderDriver;
|
||||
|
2
externals/SDL/src/render/SDL_yuv_sw.c
vendored
2
externals/SDL/src/render/SDL_yuv_sw.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
2
externals/SDL/src/render/SDL_yuv_sw_c.h
vendored
2
externals/SDL/src/render/SDL_yuv_sw_c.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
227
externals/SDL/src/render/direct3d/SDL_render_d3d.c
vendored
227
externals/SDL/src/render/direct3d/SDL_render_d3d.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -41,6 +41,13 @@
|
||||
|
||||
#include "SDL_shaders_d3d.h"
|
||||
|
||||
#ifdef __WATCOMC__
|
||||
/* FIXME: Remove this once https://github.com/open-watcom/open-watcom-v2/pull/868 is merged */
|
||||
#define D3DBLENDOP_REVSUBTRACT 3
|
||||
/* FIXME: Remove this once https://github.com/open-watcom/open-watcom-v2/pull/869 is merged */
|
||||
#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT( 2073 )
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_Rect viewport;
|
||||
@@ -71,7 +78,9 @@ typedef struct
|
||||
IDirect3DSurface9 *defaultRenderTarget;
|
||||
IDirect3DSurface9 *currentRenderTarget;
|
||||
void* d3dxDLL;
|
||||
#if SDL_HAVE_YUV
|
||||
LPDIRECT3DPIXELSHADER9 shaders[NUM_SHADERS];
|
||||
#endif
|
||||
LPDIRECT3DVERTEXBUFFER9 vertexBuffers[8];
|
||||
size_t vertexBufferSize[8];
|
||||
int currentVertexBuffer;
|
||||
@@ -95,6 +104,7 @@ typedef struct
|
||||
D3D_TextureRep texture;
|
||||
D3DTEXTUREFILTERTYPE scaleMode;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
/* YV12 texture support */
|
||||
SDL_bool yuv;
|
||||
D3D_TextureRep utexture;
|
||||
@@ -102,6 +112,7 @@ typedef struct
|
||||
Uint8 *pixels;
|
||||
int pitch;
|
||||
SDL_Rect locked_rect;
|
||||
#endif
|
||||
} D3D_TextureData;
|
||||
|
||||
typedef struct
|
||||
@@ -297,7 +308,7 @@ D3D_ActivateRenderer(SDL_Renderer * renderer)
|
||||
int w, h;
|
||||
Uint32 window_flags = SDL_GetWindowFlags(window);
|
||||
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
WIN_GetDrawableSize(window, &w, &h);
|
||||
data->pparams.BackBufferWidth = w;
|
||||
data->pparams.BackBufferHeight = h;
|
||||
if (window_flags & SDL_WINDOW_FULLSCREEN && (window_flags & SDL_WINDOW_FULLSCREEN_DESKTOP) != SDL_WINDOW_FULLSCREEN_DESKTOP) {
|
||||
@@ -343,7 +354,15 @@ D3D_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
|
||||
static int
|
||||
D3D_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
{
|
||||
WIN_GetDrawableSize(renderer->window, w, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static D3DBLEND
|
||||
GetBlendFunc(SDL_BlendFactor factor)
|
||||
{
|
||||
switch (factor) {
|
||||
case SDL_BLENDFACTOR_ZERO:
|
||||
@@ -366,9 +385,28 @@ static D3DBLEND GetBlendFunc(SDL_BlendFactor factor)
|
||||
return D3DBLEND_DESTALPHA;
|
||||
case SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA:
|
||||
return D3DBLEND_INVDESTALPHA;
|
||||
default:
|
||||
return (D3DBLEND)0;
|
||||
default: break;
|
||||
}
|
||||
return (D3DBLEND) 0;
|
||||
}
|
||||
|
||||
static D3DBLENDOP
|
||||
GetBlendEquation(SDL_BlendOperation operation)
|
||||
{
|
||||
switch (operation) {
|
||||
case SDL_BLENDOPERATION_ADD:
|
||||
return D3DBLENDOP_ADD;
|
||||
case SDL_BLENDOPERATION_SUBTRACT:
|
||||
return D3DBLENDOP_SUBTRACT;
|
||||
case SDL_BLENDOPERATION_REV_SUBTRACT:
|
||||
return D3DBLENDOP_REVSUBTRACT;
|
||||
case SDL_BLENDOPERATION_MINIMUM:
|
||||
return D3DBLENDOP_MIN;
|
||||
case SDL_BLENDOPERATION_MAXIMUM:
|
||||
return D3DBLENDOP_MAX;
|
||||
default: break;
|
||||
}
|
||||
return (D3DBLENDOP) 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
@@ -383,14 +421,16 @@ D3D_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
|
||||
SDL_BlendOperation alphaOperation = SDL_GetBlendModeAlphaOperation(blendMode);
|
||||
|
||||
if (!GetBlendFunc(srcColorFactor) || !GetBlendFunc(srcAlphaFactor) ||
|
||||
!GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor)) {
|
||||
!GetBlendEquation(colorOperation) ||
|
||||
!GetBlendFunc(dstColorFactor) || !GetBlendFunc(dstAlphaFactor) ||
|
||||
!GetBlendEquation(alphaOperation)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->enableSeparateAlphaBlend) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
if (colorOperation != SDL_BLENDOPERATION_ADD || alphaOperation != SDL_BLENDOPERATION_ADD) {
|
||||
return SDL_FALSE;
|
||||
|
||||
if (!data->enableSeparateAlphaBlend) {
|
||||
if ((srcColorFactor != srcAlphaFactor) || (dstColorFactor != dstAlphaFactor) || (colorOperation != alphaOperation)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
}
|
||||
return SDL_TRUE;
|
||||
}
|
||||
@@ -534,7 +574,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
if (D3D_CreateTextureRep(data->device, &texturedata->texture, usage, texture->format, PixelFormatToD3DFMT(texture->format), texture->w, texture->h) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
texturedata->yuv = SDL_TRUE;
|
||||
@@ -547,6 +587,7 @@ D3D_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -563,7 +604,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
if (D3D_RecreateTextureRep(data->device, &texturedata->texture) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
if (D3D_RecreateTextureRep(data->device, &texturedata->utexture) < 0) {
|
||||
return -1;
|
||||
@@ -573,6 +614,7 @@ D3D_RecreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -584,14 +626,13 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
|
||||
|
||||
if (!texturedata) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, pixels, pitch) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
/* Skip to the correct offset into the next texture */
|
||||
pixels = (const void*)((const Uint8*)pixels + rect->h * pitch);
|
||||
@@ -606,6 +647,7 @@ D3D_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -621,8 +663,7 @@ D3D_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
|
||||
|
||||
if (!texturedata) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
if (D3D_UpdateTextureRep(data->device, &texturedata->texture, rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
|
||||
@@ -647,10 +688,9 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
IDirect3DDevice9 *device = data->device;
|
||||
|
||||
if (!texturedata) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
texturedata->locked_rect = *rect;
|
||||
|
||||
if (texturedata->yuv) {
|
||||
@@ -666,7 +706,9 @@ D3D_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
(void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
|
||||
rect->x * SDL_BYTESPERPIXEL(texture->format));
|
||||
*pitch = texturedata->pitch;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
RECT d3drect;
|
||||
D3DLOCKED_RECT locked;
|
||||
HRESULT result;
|
||||
@@ -699,14 +741,17 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
if (!texturedata) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
const SDL_Rect *rect = &texturedata->locked_rect;
|
||||
void *pixels =
|
||||
(void *) ((Uint8 *) texturedata->pixels + rect->y * texturedata->pitch +
|
||||
rect->x * SDL_BYTESPERPIXEL(texture->format));
|
||||
D3D_UpdateTexture(renderer, texture, rect, pixels, texturedata->pitch);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
IDirect3DTexture9_UnlockRect(texturedata->texture.staging, 0);
|
||||
texturedata->texture.dirty = SDL_TRUE;
|
||||
if (data->drawstate.texture == texture) {
|
||||
@@ -714,10 +759,6 @@ D3D_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
data->drawstate.shader = NULL;
|
||||
IDirect3DDevice9_SetPixelShader(data->device, NULL);
|
||||
IDirect3DDevice9_SetTexture(data->device, 0, NULL);
|
||||
if (texturedata->yuv) {
|
||||
IDirect3DDevice9_SetTexture(data->device, 1, NULL);
|
||||
IDirect3DDevice9_SetTexture(data->device, 2, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -756,8 +797,7 @@ D3D_SetRenderTargetInternal(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
|
||||
texturedata = (D3D_TextureData *)texture->driverdata;
|
||||
if (!texturedata) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
/* Make sure the render target is updated if it was locked and written to */
|
||||
@@ -833,7 +873,7 @@ D3D_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
|
||||
|
||||
static int
|
||||
D3D_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
@@ -942,8 +982,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
|
||||
SDL_assert(*shader == NULL);
|
||||
|
||||
if (!texturedata) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
UpdateTextureScaleMode(data, texturedata, 0);
|
||||
@@ -951,7 +990,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
|
||||
if (BindTextureRep(data->device, &texturedata->texture, 0) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
@@ -977,6 +1016,7 @@ SetupTextureState(D3D_RenderData *data, SDL_Texture * texture, LPDIRECT3DPIXELSH
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -987,18 +1027,22 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
#if SDL_HAVE_YUV
|
||||
D3D_TextureData *oldtexturedata = data->drawstate.texture ? (D3D_TextureData *) data->drawstate.texture->driverdata : NULL;
|
||||
D3D_TextureData *newtexturedata = texture ? (D3D_TextureData *) texture->driverdata : NULL;
|
||||
#endif
|
||||
LPDIRECT3DPIXELSHADER9 shader = NULL;
|
||||
|
||||
/* disable any enabled textures we aren't going to use, let SetupTextureState() do the rest. */
|
||||
if (texture == NULL) {
|
||||
IDirect3DDevice9_SetTexture(data->device, 0, NULL);
|
||||
}
|
||||
#if SDL_HAVE_YUV
|
||||
if ((!newtexturedata || !newtexturedata->yuv) && (oldtexturedata && oldtexturedata->yuv)) {
|
||||
IDirect3DDevice9_SetTexture(data->device, 1, NULL);
|
||||
IDirect3DDevice9_SetTexture(data->device, 2, NULL);
|
||||
}
|
||||
#endif
|
||||
if (texture && SetupTextureState(data, texture, &shader) < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1015,10 +1059,12 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
} else if (texture) {
|
||||
D3D_TextureData *texturedata = (D3D_TextureData *) texture->driverdata;
|
||||
UpdateDirtyTexture(data->device, &texturedata->texture);
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata->yuv) {
|
||||
UpdateDirtyTexture(data->device, &texturedata->utexture);
|
||||
UpdateDirtyTexture(data->device, &texturedata->vtexture);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (blend != data->drawstate.blend) {
|
||||
@@ -1030,11 +1076,15 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLEND,
|
||||
GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOP,
|
||||
GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
|
||||
if (data->enableSeparateAlphaBlend) {
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_SRCBLENDALPHA,
|
||||
GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_DESTBLENDALPHA,
|
||||
GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
|
||||
IDirect3DDevice9_SetRenderState(data->device, D3DRS_BLENDOPALPHA,
|
||||
GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1043,7 +1093,13 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
|
||||
if (data->drawstate.viewport_dirty) {
|
||||
const SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
const D3DVIEWPORT9 d3dviewport = { viewport->x, viewport->y, viewport->w, viewport->h, 0.0f, 1.0f };
|
||||
D3DVIEWPORT9 d3dviewport;
|
||||
d3dviewport.X = viewport->x;
|
||||
d3dviewport.Y = viewport->y;
|
||||
d3dviewport.Width = viewport->w;
|
||||
d3dviewport.Height = viewport->h;
|
||||
d3dviewport.MinZ = 0.0f;
|
||||
d3dviewport.MaxZ = 1.0f;
|
||||
IDirect3DDevice9_SetViewport(data->device, &d3dviewport);
|
||||
|
||||
/* Set an orthographic projection matrix */
|
||||
@@ -1070,7 +1126,11 @@ SetDrawState(D3D_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
if (data->drawstate.cliprect_dirty) {
|
||||
const SDL_Rect *viewport = &data->drawstate.viewport;
|
||||
const SDL_Rect *rect = &data->drawstate.cliprect;
|
||||
const RECT d3drect = { viewport->x + rect->x, viewport->y + rect->y, viewport->x + rect->x + rect->w, viewport->y + rect->y + rect->h };
|
||||
RECT d3drect;
|
||||
d3drect.left = viewport->x + rect->x;
|
||||
d3drect.top = viewport->y + rect->y;
|
||||
d3drect.right = viewport->x + rect->x + rect->w;
|
||||
d3drect.bottom = viewport->y + rect->y + rect->h;
|
||||
IDirect3DDevice9_SetScissorRect(data->device, &d3drect);
|
||||
data->drawstate.cliprect_dirty = SDL_FALSE;
|
||||
}
|
||||
@@ -1090,46 +1150,48 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* upload the new VBO data for this set of commands. */
|
||||
vbo = data->vertexBuffers[vboidx];
|
||||
if (data->vertexBufferSize[vboidx] < vertsize) {
|
||||
const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
|
||||
const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
|
||||
if (vertices) {
|
||||
/* upload the new VBO data for this set of commands. */
|
||||
vbo = data->vertexBuffers[vboidx];
|
||||
if (data->vertexBufferSize[vboidx] < vertsize) {
|
||||
const DWORD usage = D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY;
|
||||
const DWORD fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1;
|
||||
if (vbo) {
|
||||
IDirect3DVertexBuffer9_Release(vbo);
|
||||
}
|
||||
|
||||
if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT) vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) {
|
||||
vbo = NULL;
|
||||
}
|
||||
data->vertexBuffers[vboidx] = vbo;
|
||||
data->vertexBufferSize[vboidx] = vbo ? vertsize : 0;
|
||||
}
|
||||
|
||||
if (vbo) {
|
||||
IDirect3DVertexBuffer9_Release(vbo);
|
||||
}
|
||||
|
||||
if (FAILED(IDirect3DDevice9_CreateVertexBuffer(data->device, (UINT) vertsize, usage, fvf, D3DPOOL_DEFAULT, &vbo, NULL))) {
|
||||
vbo = NULL;
|
||||
}
|
||||
data->vertexBuffers[vboidx] = vbo;
|
||||
data->vertexBufferSize[vboidx] = vbo ? vertsize : 0;
|
||||
}
|
||||
|
||||
if (vbo) {
|
||||
void *ptr;
|
||||
if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &ptr, D3DLOCK_DISCARD))) {
|
||||
vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */
|
||||
} else {
|
||||
SDL_memcpy(ptr, vertices, vertsize);
|
||||
if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) {
|
||||
void *ptr;
|
||||
if (FAILED(IDirect3DVertexBuffer9_Lock(vbo, 0, (UINT) vertsize, &ptr, D3DLOCK_DISCARD))) {
|
||||
vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */
|
||||
} else {
|
||||
SDL_memcpy(ptr, vertices, vertsize);
|
||||
if (FAILED(IDirect3DVertexBuffer9_Unlock(vbo))) {
|
||||
vbo = NULL; /* oh well, we'll do immediate mode drawing. :( */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cycle through a few VBOs so D3D has some time with the data before we replace it. */
|
||||
if (vbo) {
|
||||
data->currentVertexBuffer++;
|
||||
if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) {
|
||||
data->currentVertexBuffer = 0;
|
||||
/* cycle through a few VBOs so D3D has some time with the data before we replace it. */
|
||||
if (vbo) {
|
||||
data->currentVertexBuffer++;
|
||||
if (data->currentVertexBuffer >= SDL_arraysize(data->vertexBuffers)) {
|
||||
data->currentVertexBuffer = 0;
|
||||
}
|
||||
} else if (!data->reportedVboProblem) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method.");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why.");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer.");
|
||||
data->reportedVboProblem = SDL_TRUE;
|
||||
}
|
||||
} else if (!data->reportedVboProblem) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "SDL failed to get a vertex buffer for this Direct3D 9 rendering batch!");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Dropping back to a slower method.");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This might be a brief hiccup, but if performance is bad, this is probably why.");
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "This error will not be logged again for this renderer.");
|
||||
data->reportedVboProblem = SDL_TRUE;
|
||||
}
|
||||
|
||||
IDirect3DDevice9_SetStreamSource(data->device, 0, vbo, 0, sizeof (Vertex));
|
||||
@@ -1183,7 +1245,9 @@ D3D_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *verti
|
||||
IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
|
||||
} else {
|
||||
/* Clear is defined to clear the entire render target */
|
||||
const D3DVIEWPORT9 wholeviewport = { 0, 0, backw, backh, 0.0f, 1.0f };
|
||||
D3DVIEWPORT9 wholeviewport = { 0, 0, 0, 0, 0.0f, 1.0f };
|
||||
wholeviewport.Width = backw;
|
||||
wholeviewport.Height = backh;
|
||||
IDirect3DDevice9_SetViewport(data->device, &wholeviewport);
|
||||
data->drawstate.viewport_dirty = SDL_TRUE; /* we still need to (re)set orthographic projection, so always mark it dirty. */
|
||||
IDirect3DDevice9_Clear(data->device, 0, NULL, D3DCLEAR_TARGET, color, 0.0f, 0);
|
||||
@@ -1274,6 +1338,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
RECT d3drect;
|
||||
D3DLOCKED_RECT locked;
|
||||
HRESULT result;
|
||||
int status;
|
||||
|
||||
if (data->currentRenderTarget) {
|
||||
backBuffer = data->currentRenderTarget;
|
||||
@@ -1308,7 +1373,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
return D3D_SetError("LockRect()", result);
|
||||
}
|
||||
|
||||
SDL_ConvertPixels(rect->w, rect->h,
|
||||
status = SDL_ConvertPixels(rect->w, rect->h,
|
||||
D3DFMTToPixelFormat(desc.Format), locked.pBits, locked.Pitch,
|
||||
format, pixels, pitch);
|
||||
|
||||
@@ -1316,7 +1381,7 @@ D3D_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
|
||||
IDirect3DSurface9_Release(surface);
|
||||
|
||||
return 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1355,10 +1420,12 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
renderdata->drawstate.shader = NULL;
|
||||
IDirect3DDevice9_SetPixelShader(renderdata->device, NULL);
|
||||
IDirect3DDevice9_SetTexture(renderdata->device, 0, NULL);
|
||||
#if SDL_HAVE_YUV
|
||||
if (data->yuv) {
|
||||
IDirect3DDevice9_SetTexture(renderdata->device, 1, NULL);
|
||||
IDirect3DDevice9_SetTexture(renderdata->device, 2, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
@@ -1366,9 +1433,11 @@ D3D_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
}
|
||||
|
||||
D3D_DestroyTextureRep(&data->texture);
|
||||
#if SDL_HAVE_YUV
|
||||
D3D_DestroyTextureRep(&data->utexture);
|
||||
D3D_DestroyTextureRep(&data->vtexture);
|
||||
SDL_free(data->pixels);
|
||||
#endif
|
||||
SDL_free(data);
|
||||
texture->driverdata = NULL;
|
||||
}
|
||||
@@ -1390,12 +1459,14 @@ D3D_DestroyRenderer(SDL_Renderer * renderer)
|
||||
IDirect3DSurface9_Release(data->currentRenderTarget);
|
||||
data->currentRenderTarget = NULL;
|
||||
}
|
||||
#if SDL_HAVE_YUV
|
||||
for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
|
||||
if (data->shaders[i]) {
|
||||
IDirect3DPixelShader9_Release(data->shaders[i]);
|
||||
data->shaders[i] = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* Release all vertex buffers */
|
||||
for (i = 0; i < SDL_arraysize(data->vertexBuffers); ++i) {
|
||||
if (data->vertexBuffers[i]) {
|
||||
@@ -1552,6 +1623,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
}
|
||||
|
||||
renderer->WindowEvent = D3D_WindowEvent;
|
||||
renderer->GetOutputSize = D3D_GetOutputSize;
|
||||
renderer->SupportsBlendMode = D3D_SupportsBlendMode;
|
||||
renderer->CreateTexture = D3D_CreateTexture;
|
||||
renderer->UpdateTexture = D3D_UpdateTexture;
|
||||
@@ -1581,7 +1653,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
SDL_GetWindowWMInfo(window, &windowinfo);
|
||||
|
||||
window_flags = SDL_GetWindowFlags(window);
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
WIN_GetDrawableSize(window, &w, &h);
|
||||
SDL_GetWindowDisplayMode(window, &fullscreen_mode);
|
||||
|
||||
SDL_zero(pparams);
|
||||
@@ -1668,7 +1740,7 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
|
||||
/* Set up parameters for rendering */
|
||||
D3D_InitRenderState(data);
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (caps.MaxSimultaneousTextures >= 3) {
|
||||
int i;
|
||||
for (i = 0; i < SDL_arraysize(data->shaders); ++i) {
|
||||
@@ -1682,7 +1754,10 @@ D3D_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
|
||||
data->drawstate.blend = SDL_BLENDMODE_INVALID;
|
||||
|
||||
return renderer;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
#define COBJMACROS
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#if !defined(__WINRT__)
|
||||
#include "../../video/windows/SDL_windowswindow.h"
|
||||
#endif
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_loadso.h"
|
||||
#include "SDL_syswm.h"
|
||||
@@ -63,8 +66,8 @@ extern ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNat
|
||||
#define SAFE_RELEASE(X) if ((X)) { IUnknown_Release(SDL_static_cast(IUnknown*, X)); X = NULL; }
|
||||
|
||||
|
||||
/* !!! FIXME: vertex buffer bandwidth could be significantly lower; move color to a uniform, only use UV coords
|
||||
!!! FIXME: when textures are needed, and don't ever pass Z, since it's always zero. */
|
||||
/* !!! FIXME: vertex buffer bandwidth could be lower; only use UV coords when
|
||||
!!! FIXME: textures are needed. */
|
||||
|
||||
/* Vertex shader, common values */
|
||||
typedef struct
|
||||
@@ -76,9 +79,9 @@ typedef struct
|
||||
/* Per-vertex data */
|
||||
typedef struct
|
||||
{
|
||||
Float3 pos;
|
||||
Float2 pos;
|
||||
Float2 tex;
|
||||
Float4 color;
|
||||
SDL_Color color;
|
||||
} VertexPositionColor;
|
||||
|
||||
/* Per-texture data */
|
||||
@@ -91,7 +94,7 @@ typedef struct
|
||||
int lockedTexturePositionX;
|
||||
int lockedTexturePositionY;
|
||||
D3D11_FILTER scaleMode;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
/* YV12 texture support */
|
||||
SDL_bool yuv;
|
||||
ID3D11Texture2D *mainTextureU;
|
||||
@@ -107,6 +110,7 @@ typedef struct
|
||||
Uint8 *pixels;
|
||||
int pitch;
|
||||
SDL_Rect locked_rect;
|
||||
#endif
|
||||
} D3D11_TextureData;
|
||||
|
||||
/* Blend mode data */
|
||||
@@ -487,6 +491,11 @@ D3D11_CreateDeviceResources(SDL_Renderer * renderer)
|
||||
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
|
||||
/* Create a single-threaded device unless the app requests otherwise. */
|
||||
if (!SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D_THREADSAFE, SDL_FALSE)) {
|
||||
creationFlags |= D3D11_CREATE_DEVICE_SINGLETHREADED;
|
||||
}
|
||||
|
||||
/* Create the Direct3D 11 API device object and a corresponding context. */
|
||||
result = D3D11CreateDeviceFunc(
|
||||
data->dxgiAdapter,
|
||||
@@ -904,7 +913,11 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
||||
/* The width and height of the swap chain must be based on the display's
|
||||
* non-rotated size.
|
||||
*/
|
||||
#if defined(__WINRT__)
|
||||
SDL_GetWindowSize(renderer->window, &w, &h);
|
||||
#else
|
||||
WIN_GetDrawableSize(renderer->window, &w, &h);
|
||||
#endif
|
||||
data->rotation = D3D11_GetCurrentRotation();
|
||||
/* SDL_Log("%s: windowSize={%d,%d}, orientation=%d\n", __FUNCTION__, w, h, (int)data->rotation); */
|
||||
if (D3D11_IsDisplayRotated90Degrees(data->rotation)) {
|
||||
@@ -992,6 +1005,16 @@ D3D11_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Set the swap chain target immediately, so that a target is always set
|
||||
* even before we get to SetDrawState. Without this it's possible to hit
|
||||
* null references in places like ReadPixels!
|
||||
*/
|
||||
ID3D11DeviceContext_OMSetRenderTargets(data->d3dContext,
|
||||
1,
|
||||
&data->mainRenderTargetView,
|
||||
NULL
|
||||
);
|
||||
|
||||
data->viewportDirty = SDL_TRUE;
|
||||
|
||||
done:
|
||||
@@ -1035,6 +1058,15 @@ D3D11_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__WINRT__)
|
||||
static int
|
||||
D3D11_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
{
|
||||
WIN_GetDrawableSize(renderer->window, w, h);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SDL_bool
|
||||
D3D11_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
|
||||
{
|
||||
@@ -1109,10 +1141,9 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12 ||
|
||||
texture->format == SDL_PIXELFORMAT_IYUV) {
|
||||
textureData->yuv = SDL_TRUE;
|
||||
@@ -1127,8 +1158,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
}
|
||||
|
||||
result = ID3D11Device_CreateTexture2D(rendererData->d3dDevice,
|
||||
@@ -1138,8 +1168,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1160,11 +1189,11 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D"), result);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
SDL_zero(resourceViewDesc);
|
||||
resourceViewDesc.Format = textureDesc.Format;
|
||||
resourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
resourceViewDesc.Texture2D.MostDetailedMip = 0;
|
||||
@@ -1176,10 +1205,9 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (textureData->yuv) {
|
||||
result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
|
||||
(ID3D11Resource *)textureData->mainTextureU,
|
||||
@@ -1188,8 +1216,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
}
|
||||
result = ID3D11Device_CreateShaderResourceView(rendererData->d3dDevice,
|
||||
(ID3D11Resource *)textureData->mainTextureV,
|
||||
@@ -1198,8 +1225,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1215,13 +1241,14 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateShaderResourceView"), result);
|
||||
}
|
||||
}
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
|
||||
if (texture->access & SDL_TEXTUREACCESS_TARGET) {
|
||||
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
|
||||
SDL_zero(renderTargetViewDesc);
|
||||
renderTargetViewDesc.Format = textureDesc.Format;
|
||||
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
||||
renderTargetViewDesc.Texture2D.MipSlice = 0;
|
||||
@@ -1232,8 +1259,7 @@ D3D11_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
&textureData->mainTextureRenderTargetView);
|
||||
if (FAILED(result)) {
|
||||
D3D11_DestroyTexture(renderer, texture);
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateRenderTargetView"), result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1254,6 +1280,7 @@ D3D11_DestroyTexture(SDL_Renderer * renderer,
|
||||
SAFE_RELEASE(data->mainTextureResourceView);
|
||||
SAFE_RELEASE(data->mainTextureRenderTargetView);
|
||||
SAFE_RELEASE(data->stagingTexture);
|
||||
#if SDL_HAVE_YUV
|
||||
SAFE_RELEASE(data->mainTextureU);
|
||||
SAFE_RELEASE(data->mainTextureResourceViewU);
|
||||
SAFE_RELEASE(data->mainTextureV);
|
||||
@@ -1261,6 +1288,7 @@ D3D11_DestroyTexture(SDL_Renderer * renderer,
|
||||
SAFE_RELEASE(data->mainTextureNV);
|
||||
SAFE_RELEASE(data->mainTextureResourceViewNV);
|
||||
SDL_free(data->pixels);
|
||||
#endif
|
||||
SDL_free(data);
|
||||
texture->driverdata = NULL;
|
||||
}
|
||||
@@ -1290,8 +1318,7 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex
|
||||
NULL,
|
||||
&stagingTexture);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
|
||||
}
|
||||
|
||||
/* Get a write-only pointer to data in the staging texture: */
|
||||
@@ -1303,9 +1330,8 @@ D3D11_UpdateTextureInternal(D3D11_RenderData *rendererData, ID3D11Texture2D *tex
|
||||
&textureMemory
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
|
||||
SAFE_RELEASE(stagingTexture);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
|
||||
}
|
||||
|
||||
src = (const Uint8 *)pixels;
|
||||
@@ -1357,14 +1383,13 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
|
||||
|
||||
if (!textureData) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, srcPixels, srcPitch) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (textureData->yuv) {
|
||||
/* Skip to the correct offset into the next texture */
|
||||
srcPixels = (const void*)((const Uint8*)srcPixels + rect->h * srcPitch);
|
||||
@@ -1388,6 +1413,7 @@ D3D11_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1403,8 +1429,7 @@ D3D11_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
|
||||
|
||||
if (!textureData) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
|
||||
@@ -1429,8 +1454,7 @@ D3D11_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
D3D11_TextureData *textureData = (D3D11_TextureData *)texture->driverdata;
|
||||
|
||||
if (!textureData) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
if (D3D11_UpdateTextureInternal(rendererData, textureData->mainTexture, SDL_BYTESPERPIXEL(texture->format), rect->x, rect->y, rect->w, rect->h, Yplane, Ypitch) < 0) {
|
||||
@@ -1455,10 +1479,9 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
D3D11_MAPPED_SUBRESOURCE textureMemory;
|
||||
|
||||
if (!textureData) {
|
||||
SDL_SetError("Texture is not currently available");
|
||||
return -1;
|
||||
return SDL_SetError("Texture is not currently available");
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (textureData->yuv || textureData->nv12) {
|
||||
/* It's more efficient to upload directly... */
|
||||
if (!textureData->pixels) {
|
||||
@@ -1475,7 +1498,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
*pitch = textureData->pitch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (textureData->stagingTexture) {
|
||||
return SDL_SetError("texture is already locked");
|
||||
}
|
||||
@@ -1500,8 +1523,7 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
NULL,
|
||||
&textureData->stagingTexture);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateTexture2D [create staging texture]"), result);
|
||||
}
|
||||
|
||||
/* Get a write-only pointer to data in the staging texture: */
|
||||
@@ -1513,9 +1535,8 @@ D3D11_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
&textureMemory
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
|
||||
SAFE_RELEASE(textureData->stagingTexture);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [map staging texture]"), result);
|
||||
}
|
||||
|
||||
/* Make note of where the staging texture will be written to
|
||||
@@ -1541,7 +1562,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
if (!textureData) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (textureData->yuv || textureData->nv12) {
|
||||
const SDL_Rect *rect = &textureData->locked_rect;
|
||||
void *pixels =
|
||||
@@ -1550,7 +1571,7 @@ D3D11_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
D3D11_UpdateTexture(renderer, texture, rect, pixels, textureData->pitch);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Commit the pixel buffer's changes back to the staging texture: */
|
||||
ID3D11DeviceContext_Unmap(rendererData->d3dContext,
|
||||
(ID3D11Resource *)textureData->stagingTexture,
|
||||
@@ -1614,11 +1635,12 @@ static int
|
||||
D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
VertexPositionColor *verts = (VertexPositionColor *) SDL_AllocateRenderVertices(renderer, count * sizeof (VertexPositionColor), 0, &cmd->data.draw.first);
|
||||
const float r = (float)(cmd->data.draw.r / 255.0f);
|
||||
const float g = (float)(cmd->data.draw.g / 255.0f);
|
||||
const float b = (float)(cmd->data.draw.b / 255.0f);
|
||||
const float a = (float)(cmd->data.draw.a / 255.0f);
|
||||
int i;
|
||||
SDL_Color color;
|
||||
color.r = cmd->data.draw.r;
|
||||
color.g = cmd->data.draw.g;
|
||||
color.b = cmd->data.draw.b;
|
||||
color.a = cmd->data.draw.a;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
@@ -1629,13 +1651,9 @@ D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
|
||||
for (i = 0; i < count; i++) {
|
||||
verts->pos.x = points[i].x + 0.5f;
|
||||
verts->pos.y = points[i].y + 0.5f;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->tex.x = 0.0f;
|
||||
verts->tex.y = 0.0f;
|
||||
verts->color.x = r;
|
||||
verts->color.y = g;
|
||||
verts->color.z = b;
|
||||
verts->color.w = a;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
}
|
||||
|
||||
@@ -1644,7 +1662,7 @@ D3D11_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
|
||||
|
||||
static int
|
||||
D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
@@ -1662,7 +1680,6 @@ D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
SDL_Color col_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
@@ -1674,15 +1691,10 @@ D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
||||
}
|
||||
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
verts->pos.x = xy_[0] * scale_x;
|
||||
verts->pos.y = xy_[1] * scale_y;
|
||||
verts->pos.z = 0.0f;
|
||||
verts->color.x = col_.r / 255.0f;
|
||||
verts->color.y = col_.g / 255.0f;
|
||||
verts->color.z = col_.b / 255.0f;
|
||||
verts->color.w = col_.a / 255.0f;
|
||||
verts->color = *(SDL_Color*)((char*)color + j * color_stride);
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
@@ -1722,8 +1734,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
|
||||
&mappedResource
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11DeviceContext1::Map [vertex buffer]"), result);
|
||||
}
|
||||
SDL_memcpy(mappedResource.pData, vertexData, dataSizeInBytes);
|
||||
ID3D11DeviceContext_Unmap(rendererData->d3dContext, (ID3D11Resource *)rendererData->vertexBuffers[vbidx], 0);
|
||||
@@ -1750,8 +1761,7 @@ D3D11_UpdateVertexBuffer(SDL_Renderer *renderer,
|
||||
&rendererData->vertexBuffers[vbidx]
|
||||
);
|
||||
if (FAILED(result)) {
|
||||
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
|
||||
return -1;
|
||||
return WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D11Device1::CreateBuffer [vertex buffer]"), result);
|
||||
}
|
||||
|
||||
rendererData->vertexBufferSizes[vbidx] = dataSizeInBytes;
|
||||
@@ -2004,7 +2014,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const
|
||||
default:
|
||||
return SDL_SetError("Unknown scale mode: %d\n", textureData->scaleMode);
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (textureData->yuv) {
|
||||
ID3D11ShaderResourceView *shaderResources[] = {
|
||||
textureData->mainTextureResourceView,
|
||||
@@ -2055,7 +2065,7 @@ D3D11_SetCopyState(SDL_Renderer * renderer, const SDL_RenderCommand *cmd, const
|
||||
SDL_arraysize(shaderResources), shaderResources, textureSampler, matrix);
|
||||
|
||||
}
|
||||
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
return D3D11_SetDrawState(renderer, cmd, rendererData->pixelShaders[SHADER_RGB],
|
||||
1, &textureData->mainTextureResourceView, textureSampler, matrix);
|
||||
}
|
||||
@@ -2258,30 +2268,20 @@ D3D11_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||
/* Copy the data into the desired buffer, converting pixels to the
|
||||
* desired format at the same time:
|
||||
*/
|
||||
if (SDL_ConvertPixels(
|
||||
status = SDL_ConvertPixels(
|
||||
rect->w, rect->h,
|
||||
D3D11_DXGIFormatToSDLPixelFormat(stagingTextureDesc.Format),
|
||||
textureMemory.pData,
|
||||
textureMemory.RowPitch,
|
||||
format,
|
||||
pixels,
|
||||
pitch) != 0) {
|
||||
/* When SDL_ConvertPixels fails, it'll have already set the format.
|
||||
* Get the error message, and attach some extra data to it.
|
||||
*/
|
||||
char errorMessage[1024];
|
||||
SDL_snprintf(errorMessage, sizeof(errorMessage), "%s, Convert Pixels failed: %s", __FUNCTION__, SDL_GetError());
|
||||
SDL_SetError("%s", errorMessage);
|
||||
goto done;
|
||||
}
|
||||
pitch);
|
||||
|
||||
/* Unmap the texture: */
|
||||
ID3D11DeviceContext_Unmap(data->d3dContext,
|
||||
(ID3D11Resource *)stagingTexture,
|
||||
0);
|
||||
|
||||
status = 0;
|
||||
|
||||
done:
|
||||
SAFE_RELEASE(backBuffer);
|
||||
SAFE_RELEASE(stagingTexture);
|
||||
@@ -2374,6 +2374,7 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
|
||||
data = (D3D11_RenderData *) SDL_calloc(1, sizeof(*data));
|
||||
if (!data) {
|
||||
SDL_free(renderer);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
@@ -2381,6 +2382,9 @@ D3D11_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
data->identity = MatrixIdentity();
|
||||
|
||||
renderer->WindowEvent = D3D11_WindowEvent;
|
||||
#if !defined(__WINRT__)
|
||||
renderer->GetOutputSize = D3D11_GetOutputSize;
|
||||
#endif
|
||||
renderer->SupportsBlendMode = D3D11_SupportsBlendMode;
|
||||
renderer->CreateTexture = D3D11_CreateTexture;
|
||||
renderer->UpdateTexture = D3D11_UpdateTexture;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -1886,9 +1886,10 @@ static struct
|
||||
{
|
||||
const void *shader_data;
|
||||
SIZE_T shader_size;
|
||||
} D3D11_shaders[] = {
|
||||
} D3D11_shaders[NUM_SHADERS] = {
|
||||
{ D3D11_PixelShader_Colors, sizeof(D3D11_PixelShader_Colors) },
|
||||
{ D3D11_PixelShader_Textures, sizeof(D3D11_PixelShader_Textures) },
|
||||
#if SDL_HAVE_YUV
|
||||
{ D3D11_PixelShader_YUV_JPEG, sizeof(D3D11_PixelShader_YUV_JPEG) },
|
||||
{ D3D11_PixelShader_YUV_BT601, sizeof(D3D11_PixelShader_YUV_BT601) },
|
||||
{ D3D11_PixelShader_YUV_BT709, sizeof(D3D11_PixelShader_YUV_BT709) },
|
||||
@@ -1898,6 +1899,7 @@ static struct
|
||||
{ D3D11_PixelShader_NV21_JPEG, sizeof(D3D11_PixelShader_NV21_JPEG) },
|
||||
{ D3D11_PixelShader_NV21_BT601, sizeof(D3D11_PixelShader_NV21_BT601) },
|
||||
{ D3D11_PixelShader_NV21_BT709, sizeof(D3D11_PixelShader_NV21_BT709) },
|
||||
#endif
|
||||
};
|
||||
|
||||
int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vertexShader, ID3D11InputLayout **inputLayout)
|
||||
@@ -1905,9 +1907,9 @@ int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vert
|
||||
/* Declare how the input layout for SDL's vertex shader will be setup: */
|
||||
const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
HRESULT result;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,6 +25,7 @@
|
||||
typedef enum {
|
||||
SHADER_SOLID,
|
||||
SHADER_RGB,
|
||||
#if SDL_HAVE_YUV
|
||||
SHADER_YUV_JPEG,
|
||||
SHADER_YUV_BT601,
|
||||
SHADER_YUV_BT709,
|
||||
@@ -34,6 +35,7 @@ typedef enum {
|
||||
SHADER_NV21_JPEG,
|
||||
SHADER_NV21_BT601,
|
||||
SHADER_NV21_BT709,
|
||||
#endif
|
||||
NUM_SHADERS
|
||||
} D3D11_Shader;
|
||||
|
||||
|
3053
externals/SDL/src/render/direct3d12/SDL_render_d3d12.c
vendored
Executable file
3053
externals/SDL/src/render/direct3d12/SDL_render_d3d12.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
6967
externals/SDL/src/render/direct3d12/SDL_shaders_d3d12.c
vendored
Executable file
6967
externals/SDL/src/render/direct3d12/SDL_shaders_d3d12.c
vendored
Executable file
File diff suppressed because it is too large
Load Diff
57
externals/SDL/src/render/direct3d12/SDL_shaders_d3d12.h
vendored
Executable file
57
externals/SDL/src/render/direct3d12/SDL_shaders_d3d12.h
vendored
Executable file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "../../SDL_internal.h"
|
||||
|
||||
/* D3D12 shader implementation */
|
||||
|
||||
typedef enum {
|
||||
SHADER_SOLID,
|
||||
SHADER_RGB,
|
||||
#if SDL_HAVE_YUV
|
||||
SHADER_YUV_JPEG,
|
||||
SHADER_YUV_BT601,
|
||||
SHADER_YUV_BT709,
|
||||
SHADER_NV12_JPEG,
|
||||
SHADER_NV12_BT601,
|
||||
SHADER_NV12_BT709,
|
||||
SHADER_NV21_JPEG,
|
||||
SHADER_NV21_BT601,
|
||||
SHADER_NV21_BT709,
|
||||
#endif
|
||||
NUM_SHADERS
|
||||
} D3D12_Shader;
|
||||
|
||||
typedef enum {
|
||||
ROOTSIG_COLOR,
|
||||
ROOTSIG_TEXTURE,
|
||||
#if SDL_HAVE_YUV
|
||||
ROOTSIG_YUV,
|
||||
ROOTSIG_NV,
|
||||
#endif
|
||||
NUM_ROOTSIGS
|
||||
} D3D12_RootSignature;
|
||||
|
||||
extern void D3D12_GetVertexShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode);
|
||||
extern void D3D12_GetPixelShader(D3D12_Shader shader, D3D12_SHADER_BYTECODE *outBytecode);
|
||||
extern D3D12_RootSignature D3D12_GetRootSignatureType(D3D12_Shader shader);
|
||||
extern void D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECODE* outBytecode);
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
230
externals/SDL/src/render/metal/SDL_render_metal.m
vendored
230
externals/SDL/src/render/metal/SDL_render_metal.m
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -32,6 +32,7 @@
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#ifdef __MACOSX__
|
||||
#import <AppKit/NSWindow.h>
|
||||
#import <AppKit/NSView.h>
|
||||
#endif
|
||||
|
||||
@@ -141,24 +142,6 @@ typedef struct METAL_ShaderPipelines
|
||||
@end
|
||||
|
||||
@implementation METAL_RenderData
|
||||
#if !__has_feature(objc_arc)
|
||||
- (void)dealloc
|
||||
{
|
||||
[_mtldevice release];
|
||||
[_mtlcmdqueue release];
|
||||
[_mtlcmdbuffer release];
|
||||
[_mtlcmdencoder release];
|
||||
[_mtllibrary release];
|
||||
[_mtlbackbuffer release];
|
||||
[_mtlsamplernearest release];
|
||||
[_mtlsamplerlinear release];
|
||||
[_mtlbufconstants release];
|
||||
[_mtlbufquadindices release];
|
||||
[_mtllayer release];
|
||||
[_mtlpassdesc release];
|
||||
[super dealloc];
|
||||
}
|
||||
#endif
|
||||
@end
|
||||
|
||||
@interface METAL_TextureData : NSObject
|
||||
@@ -166,26 +149,17 @@ typedef struct METAL_ShaderPipelines
|
||||
@property (nonatomic, retain) id<MTLTexture> mtltexture_uv;
|
||||
@property (nonatomic, retain) id<MTLSamplerState> mtlsampler;
|
||||
@property (nonatomic, assign) SDL_MetalFragmentFunction fragmentFunction;
|
||||
#if SDL_HAVE_YUV
|
||||
@property (nonatomic, assign) BOOL yuv;
|
||||
@property (nonatomic, assign) BOOL nv12;
|
||||
@property (nonatomic, assign) size_t conversionBufferOffset;
|
||||
#endif
|
||||
@property (nonatomic, assign) BOOL hasdata;
|
||||
|
||||
@property (nonatomic, retain) id<MTLBuffer> lockedbuffer;
|
||||
@property (nonatomic, assign) SDL_Rect lockedrect;
|
||||
@end
|
||||
|
||||
@implementation METAL_TextureData
|
||||
#if !__has_feature(objc_arc)
|
||||
- (void)dealloc
|
||||
{
|
||||
[_mtltexture release];
|
||||
[_mtltexture_uv release];
|
||||
[_mtlsampler release];
|
||||
[_lockedbuffer release];
|
||||
[super dealloc];
|
||||
}
|
||||
#endif
|
||||
@end
|
||||
|
||||
static int
|
||||
@@ -340,13 +314,6 @@ MakePipelineState(METAL_RenderData *data, METAL_PipelineCache *cache,
|
||||
|
||||
METAL_PipelineState *states = SDL_realloc(cache->states, (cache->count + 1) * sizeof(pipeline));
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtlpipedesc release]; // !!! FIXME: can these be reused for each creation, or does the pipeline obtain it?
|
||||
[mtlvertfn release];
|
||||
[mtlfragfn release];
|
||||
[state release];
|
||||
#endif
|
||||
|
||||
if (states) {
|
||||
states[cache->count++] = pipeline;
|
||||
cache->states = states;
|
||||
@@ -604,14 +571,14 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
mtltexdesc.usage = MTLTextureUsageShaderRead;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
id<MTLTexture> mtltexture = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
||||
if (mtltexture == nil) {
|
||||
return SDL_SetError("Texture allocation failed");
|
||||
}
|
||||
|
||||
id<MTLTexture> mtltexture_uv = nil;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
BOOL yuv = (texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12);
|
||||
BOOL nv12 = (texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21);
|
||||
|
||||
@@ -630,13 +597,10 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
if (yuv || nv12) {
|
||||
mtltexture_uv = [data.mtldevice newTextureWithDescriptor:mtltexdesc];
|
||||
if (mtltexture_uv == nil) {
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtltexture release];
|
||||
#endif
|
||||
return SDL_SetError("Texture allocation failed");
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
METAL_TextureData *texturedata = [[METAL_TextureData alloc] init];
|
||||
if (texture->scaleMode == SDL_ScaleModeNearest) {
|
||||
texturedata.mtlsampler = data.mtlsamplernearest;
|
||||
@@ -645,7 +609,7 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
}
|
||||
texturedata.mtltexture = mtltexture;
|
||||
texturedata.mtltexture_uv = mtltexture_uv;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
texturedata.yuv = yuv;
|
||||
texturedata.nv12 = nv12;
|
||||
|
||||
@@ -655,10 +619,12 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV12;
|
||||
} else if (texture->format == SDL_PIXELFORMAT_NV21) {
|
||||
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_NV21;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
texturedata.fragmentFunction = SDL_METAL_FRAGMENT_COPY;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (yuv || nv12) {
|
||||
size_t offset = 0;
|
||||
SDL_YUV_CONVERSION_MODE mode = SDL_GetYUVConversionModeForResolution(texture->w, texture->h);
|
||||
@@ -670,14 +636,8 @@ METAL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
}
|
||||
texturedata.conversionBufferOffset = offset;
|
||||
}
|
||||
|
||||
texture->driverdata = (void*)CFBridgingRetain(texturedata);
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[texturedata release];
|
||||
[mtltexture release];
|
||||
[mtltexture_uv release];
|
||||
#endif
|
||||
texture->driverdata = (void*)CFBridgingRetain(texturedata);
|
||||
|
||||
return 0;
|
||||
}}
|
||||
@@ -738,10 +698,6 @@ METAL_UpdateTextureInternal(SDL_Renderer * renderer, METAL_TextureData *textured
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[stagingtex autorelease];
|
||||
#endif
|
||||
|
||||
METAL_UploadTextureData(stagingtex, stagingrect, 0, pixels, pitch);
|
||||
|
||||
if (data.mtlcmdencoder != nil) {
|
||||
@@ -784,7 +740,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
if (METAL_UpdateTextureInternal(renderer, texturedata, texturedata.mtltexture, *rect, 0, pixels, pitch) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata.yuv) {
|
||||
int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
|
||||
int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
|
||||
@@ -814,7 +770,7 @@ METAL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
texturedata.hasdata = YES;
|
||||
|
||||
return 0;
|
||||
@@ -895,10 +851,12 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
}
|
||||
|
||||
*pitch = SDL_BYTESPERPIXEL(texture->format) * rect->w;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata.yuv || texturedata.nv12) {
|
||||
buffersize = ((*pitch) * rect->h) + (2 * (*pitch + 1) / 2) * ((rect->h + 1) / 2);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
buffersize = (*pitch) * rect->h;
|
||||
}
|
||||
|
||||
@@ -911,11 +869,6 @@ METAL_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
texturedata.lockedbuffer = lockedbuffer;
|
||||
*pixels = [lockedbuffer contents];
|
||||
|
||||
/* METAL_TextureData.lockedbuffer retains. */
|
||||
#if !__has_feature(objc_arc)
|
||||
[lockedbuffer release];
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}}
|
||||
|
||||
@@ -952,7 +905,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
destinationSlice:0
|
||||
destinationLevel:0
|
||||
destinationOrigin:MTLOriginMake(rect.x, rect.y, 0)];
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata.yuv) {
|
||||
int Uslice = texture->format == SDL_PIXELFORMAT_YV12 ? 1 : 0;
|
||||
int Vslice = texture->format == SDL_PIXELFORMAT_YV12 ? 0 : 1;
|
||||
@@ -992,7 +945,7 @@ METAL_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||
destinationLevel:0
|
||||
destinationOrigin:MTLOriginMake(UVrect.x, UVrect.y, 0)];
|
||||
}
|
||||
|
||||
#endif
|
||||
[blitcmd endEncoding];
|
||||
|
||||
[data.mtlcmdbuffer commit];
|
||||
@@ -1084,8 +1037,14 @@ METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
|
||||
static int
|
||||
METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
const int color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
|
||||
const SDL_Color color = {
|
||||
cmd->data.draw.r,
|
||||
cmd->data.draw.g,
|
||||
cmd->data.draw.b,
|
||||
cmd->data.draw.a
|
||||
};
|
||||
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (SDL_Color)) * count;
|
||||
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
@@ -1095,7 +1054,7 @@ METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
*(verts++) = points->x;
|
||||
*(verts++) = points->y;
|
||||
*((int *)verts++) = color;
|
||||
*((SDL_Color *)verts++) = color;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1103,12 +1062,16 @@ METAL_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL
|
||||
static int
|
||||
METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
|
||||
const int color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
const SDL_Color color = {
|
||||
cmd->data.draw.r,
|
||||
cmd->data.draw.g,
|
||||
cmd->data.draw.b,
|
||||
cmd->data.draw.a
|
||||
};
|
||||
|
||||
SDL_assert(count >= 2); /* should have been checked at the higher level. */
|
||||
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (SDL_Color)) * count;
|
||||
float *verts = (float *) SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
@@ -1118,7 +1081,7 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
for (int i = 0; i < count; i++, points++) {
|
||||
*(verts++) = points->x;
|
||||
*(verts++) = points->y;
|
||||
*((int *)verts++) = color;
|
||||
*((SDL_Color *)verts++) = color;
|
||||
}
|
||||
|
||||
/* If the line segment is completely horizontal or vertical,
|
||||
@@ -1148,7 +1111,7 @@ METAL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
|
||||
static int
|
||||
METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
@@ -1175,12 +1138,11 @@ METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
||||
}
|
||||
|
||||
float *xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
int col_ = *(int *)((char*)color + j * color_stride);
|
||||
|
||||
*(verts++) = xy_[0] * scale_x;
|
||||
*(verts++) = xy_[1] * scale_y;
|
||||
|
||||
*((int *)verts++) = col_;
|
||||
*((SDL_Color *)verts++) = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
@@ -1194,13 +1156,8 @@ METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if __has_feature(objc_arc)
|
||||
__unsafe_unretained id<MTLRenderPipelineState> pipeline;
|
||||
__unsafe_unretained id<MTLBuffer> vertex_buffer;
|
||||
#else
|
||||
id<MTLRenderPipelineState> pipeline;
|
||||
id<MTLBuffer> vertex_buffer;
|
||||
#endif
|
||||
size_t constants_offset;
|
||||
SDL_Texture *texture;
|
||||
SDL_bool cliprect_dirty;
|
||||
@@ -1240,22 +1197,29 @@ SetDrawState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const SDL_Met
|
||||
}
|
||||
|
||||
if (statecache->cliprect_dirty) {
|
||||
MTLScissorRect mtlrect;
|
||||
SDL_Rect output;
|
||||
SDL_Rect clip;
|
||||
if (statecache->cliprect_enabled) {
|
||||
const SDL_Rect *rect = &statecache->cliprect;
|
||||
mtlrect.x = statecache->viewport.x + rect->x;
|
||||
mtlrect.y = statecache->viewport.y + rect->y;
|
||||
mtlrect.width = rect->w;
|
||||
mtlrect.height = rect->h;
|
||||
clip = statecache->cliprect;
|
||||
clip.x += statecache->viewport.x;
|
||||
clip.y += statecache->viewport.y;
|
||||
} else {
|
||||
mtlrect.x = statecache->viewport.x;
|
||||
mtlrect.y = statecache->viewport.y;
|
||||
mtlrect.width = statecache->viewport.w;
|
||||
mtlrect.height = statecache->viewport.h;
|
||||
clip = statecache->viewport;
|
||||
}
|
||||
if (mtlrect.width > 0 && mtlrect.height > 0) {
|
||||
|
||||
/* Set Scissor Rect Validation: w/h must be <= render pass */
|
||||
SDL_zero(output);
|
||||
METAL_GetOutputSize(renderer, &output.w, &output.h);
|
||||
|
||||
if (SDL_IntersectRect(&output, &clip, &clip)) {
|
||||
MTLScissorRect mtlrect;
|
||||
mtlrect.x = clip.x;
|
||||
mtlrect.y = clip.y;
|
||||
mtlrect.width = clip.w;
|
||||
mtlrect.height = clip.h;
|
||||
[data.mtlcmdencoder setScissorRect:mtlrect];
|
||||
}
|
||||
|
||||
statecache->cliprect_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
@@ -1303,10 +1267,12 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, const size_t
|
||||
}
|
||||
|
||||
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture atIndex:0];
|
||||
#if SDL_HAVE_YUV
|
||||
if (texturedata.yuv || texturedata.nv12) {
|
||||
[data.mtlcmdencoder setFragmentTexture:texturedata.mtltexture_uv atIndex:1];
|
||||
[data.mtlcmdencoder setFragmentBuffer:data.mtlbufconstants offset:texturedata.conversionBufferOffset atIndex:1];
|
||||
}
|
||||
#endif
|
||||
statecache->texture = texture;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
@@ -1341,9 +1307,6 @@ METAL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
* TODO: this buffer is also used for constants. Is performance still
|
||||
* good for those, or should we have a managed buffer for them? */
|
||||
mtlbufvertex = [data.mtldevice newBufferWithLength:vertsize options:MTLResourceStorageModeShared];
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtlbufvertex autorelease];
|
||||
#endif
|
||||
mtlbufvertex.label = @"SDL vertex data";
|
||||
SDL_memcpy([mtlbufvertex contents], vertices, vertsize);
|
||||
|
||||
@@ -1556,7 +1519,11 @@ METAL_DestroyRenderer(SDL_Renderer * renderer)
|
||||
|
||||
DestroyAllPipelines(data.allpipelines, data.pipelinescount);
|
||||
|
||||
SDL_Metal_DestroyView(data.mtlview);
|
||||
/* Release the metal view instead of destroying it,
|
||||
in case we want to use it later (recreating the renderer)
|
||||
*/
|
||||
/* SDL_Metal_DestroyView(data.mtlview); */
|
||||
CFBridgingRelease(data.mtlview);
|
||||
}
|
||||
|
||||
SDL_free(renderer);
|
||||
@@ -1599,6 +1566,33 @@ METAL_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
return SDL_SetError("This Apple OS does not support displaySyncEnabled!");
|
||||
}
|
||||
|
||||
static SDL_MetalView GetWindowView(SDL_Window *window)
|
||||
{
|
||||
SDL_SysWMinfo info;
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWindowWMInfo(window, &info)) {
|
||||
#ifdef __MACOSX__
|
||||
if (info.subsystem == SDL_SYSWM_COCOA) {
|
||||
NSView *view = info.info.cocoa.window.contentView;
|
||||
if (view.subviews.count > 0) {
|
||||
view = view.subviews[0];
|
||||
if (view.tag == SDL_METALVIEW_TAG) {
|
||||
return (SDL_MetalView)CFBridgingRetain(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (info.subsystem == SDL_SYSWM_UIKIT) {
|
||||
UIView *view = info.info.uikit.window.rootViewController.view;
|
||||
if (view.tag == SDL_METALVIEW_TAG) {
|
||||
return (SDL_MetalView)CFBridgingRetain(view);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
static SDL_Renderer *
|
||||
METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
@@ -1650,12 +1644,12 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
view = SDL_Metal_CreateView(window);
|
||||
view = GetWindowView(window);
|
||||
if (view == nil) {
|
||||
view = SDL_Metal_CreateView(window);
|
||||
}
|
||||
|
||||
if (view == NULL) {
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtldevice release];
|
||||
#endif
|
||||
SDL_free(renderer);
|
||||
if (changed_window) {
|
||||
SDL_RecreateWindow(window, window_flags);
|
||||
@@ -1667,10 +1661,11 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
data = [[METAL_RenderData alloc] init];
|
||||
|
||||
if (data == nil) {
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtldevice release];
|
||||
#endif
|
||||
SDL_Metal_DestroyView(view);
|
||||
/* Release the metal view instead of destroying it,
|
||||
in case we want to use it later (recreating the renderer)
|
||||
*/
|
||||
/* SDL_Metal_DestroyView(view); */
|
||||
CFBridgingRelease(view);
|
||||
SDL_free(renderer);
|
||||
if (changed_window) {
|
||||
SDL_RecreateWindow(window, window_flags);
|
||||
@@ -1684,7 +1679,7 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
data.mtlview = view;
|
||||
|
||||
#ifdef __MACOSX__
|
||||
layer = (CAMetalLayer *)[(NSView *)view layer];
|
||||
layer = (CAMetalLayer *)[(__bridge NSView *)view layer];
|
||||
#else
|
||||
layer = (CAMetalLayer *)[(__bridge UIView *)view layer];
|
||||
#endif
|
||||
@@ -1709,9 +1704,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
id<MTLLibrary> mtllibrary = [data.mtldevice newLibraryWithData:mtllibdata error:&err];
|
||||
data.mtllibrary = mtllibrary;
|
||||
SDL_assert(err == nil);
|
||||
#if !__has_feature(objc_arc)
|
||||
dispatch_release(mtllibdata);
|
||||
#endif
|
||||
data.mtllibrary.label = @"SDL Metal renderer shader library";
|
||||
|
||||
/* Do some shader pipeline state loading up-front rather than on demand. */
|
||||
@@ -1769,9 +1761,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
};
|
||||
|
||||
id<MTLBuffer> mtlbufconstantstaging = [data.mtldevice newBufferWithLength:CONSTANTS_LENGTH options:MTLResourceStorageModeShared];
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtlbufconstantstaging autorelease];
|
||||
#endif
|
||||
|
||||
char *constantdata = [mtlbufconstantstaging contents];
|
||||
SDL_memcpy(constantdata + CONSTANTS_OFFSET_IDENTITY, identitytransform, sizeof(identitytransform));
|
||||
@@ -1783,9 +1772,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
int quadcount = UINT16_MAX / 4;
|
||||
size_t indicessize = sizeof(UInt16) * quadcount * 6;
|
||||
id<MTLBuffer> mtlbufquadindicesstaging = [data.mtldevice newBufferWithLength:indicessize options:MTLResourceStorageModeShared];
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtlbufquadindicesstaging autorelease];
|
||||
#endif
|
||||
|
||||
/* Quads in the following vertex order (matches the FillRects vertices):
|
||||
* 1---3
|
||||
@@ -1903,18 +1889,6 @@ METAL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->info.max_texture_width = maxtexsize;
|
||||
renderer->info.max_texture_height = maxtexsize;
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
[mtlcmdqueue release];
|
||||
[mtllibrary release];
|
||||
[samplerdesc release];
|
||||
[mtlsamplernearest release];
|
||||
[mtlsamplerlinear release];
|
||||
[mtlbufconstants release];
|
||||
[mtlbufquadindices release];
|
||||
[data release];
|
||||
[mtldevice release];
|
||||
#endif
|
||||
|
||||
return renderer;
|
||||
}}
|
||||
|
||||
|
16
externals/SDL/src/render/opengl/SDL_glfuncs.h
vendored
16
externals/SDL/src/render/opengl/SDL_glfuncs.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -73,7 +73,7 @@ SDL_PROC_UNUSED(void, glColor4i, (GLint, GLint, GLint, GLint))
|
||||
SDL_PROC_UNUSED(void, glColor4iv, (const GLint *))
|
||||
SDL_PROC_UNUSED(void, glColor4s, (GLshort, GLshort, GLshort, GLshort))
|
||||
SDL_PROC_UNUSED(void, glColor4sv, (const GLshort *))
|
||||
SDL_PROC_UNUSED(void, glColor4ub,
|
||||
SDL_PROC(void, glColor4ub,
|
||||
(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha))
|
||||
SDL_PROC_UNUSED(void, glColor4ubv, (const GLubyte * v))
|
||||
SDL_PROC_UNUSED(void, glColor4ui,
|
||||
@@ -86,7 +86,7 @@ SDL_PROC_UNUSED(void, glColorMask,
|
||||
(GLboolean red, GLboolean green, GLboolean blue,
|
||||
GLboolean alpha))
|
||||
SDL_PROC_UNUSED(void, glColorMaterial, (GLenum face, GLenum mode))
|
||||
SDL_PROC_UNUSED(void, glColorPointer,
|
||||
SDL_PROC(void, glColorPointer,
|
||||
(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid * pointer))
|
||||
SDL_PROC_UNUSED(void, glCopyPixels,
|
||||
@@ -111,8 +111,8 @@ SDL_PROC(void, glDepthFunc, (GLenum func))
|
||||
SDL_PROC_UNUSED(void, glDepthMask, (GLboolean flag))
|
||||
SDL_PROC_UNUSED(void, glDepthRange, (GLclampd zNear, GLclampd zFar))
|
||||
SDL_PROC(void, glDisable, (GLenum cap))
|
||||
SDL_PROC_UNUSED(void, glDisableClientState, (GLenum array))
|
||||
SDL_PROC_UNUSED(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
|
||||
SDL_PROC(void, glDisableClientState, (GLenum array))
|
||||
SDL_PROC(void, glDrawArrays, (GLenum mode, GLint first, GLsizei count))
|
||||
SDL_PROC_UNUSED(void, glDrawBuffer, (GLenum mode))
|
||||
SDL_PROC_UNUSED(void, glDrawElements,
|
||||
(GLenum mode, GLsizei count, GLenum type,
|
||||
@@ -125,7 +125,7 @@ SDL_PROC_UNUSED(void, glEdgeFlagPointer,
|
||||
(GLsizei stride, const GLvoid * pointer))
|
||||
SDL_PROC_UNUSED(void, glEdgeFlagv, (const GLboolean * flag))
|
||||
SDL_PROC(void, glEnable, (GLenum cap))
|
||||
SDL_PROC_UNUSED(void, glEnableClientState, (GLenum array))
|
||||
SDL_PROC(void, glEnableClientState, (GLenum array))
|
||||
SDL_PROC(void, glEnd, (void))
|
||||
SDL_PROC_UNUSED(void, glEndList, (void))
|
||||
SDL_PROC_UNUSED(void, glEvalCoord1d, (GLdouble u))
|
||||
@@ -401,7 +401,7 @@ SDL_PROC_UNUSED(void, glTexCoord4iv, (const GLint * v))
|
||||
SDL_PROC_UNUSED(void, glTexCoord4s,
|
||||
(GLshort s, GLshort t, GLshort r, GLshort q))
|
||||
SDL_PROC_UNUSED(void, glTexCoord4sv, (const GLshort * v))
|
||||
SDL_PROC_UNUSED(void, glTexCoordPointer,
|
||||
SDL_PROC(void, glTexCoordPointer,
|
||||
(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid * pointer))
|
||||
SDL_PROC(void, glTexEnvf, (GLenum target, GLenum pname, GLfloat param))
|
||||
@@ -470,7 +470,7 @@ SDL_PROC_UNUSED(void, glVertex4iv, (const GLint * v))
|
||||
SDL_PROC_UNUSED(void, glVertex4s,
|
||||
(GLshort x, GLshort y, GLshort z, GLshort w))
|
||||
SDL_PROC_UNUSED(void, glVertex4sv, (const GLshort * v))
|
||||
SDL_PROC_UNUSED(void, glVertexPointer,
|
||||
SDL_PROC(void, glVertexPointer,
|
||||
(GLint size, GLenum type, GLsizei stride,
|
||||
const GLvoid * pointer))
|
||||
SDL_PROC(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height))
|
||||
|
343
externals/SDL/src/render/opengl/SDL_render_gl.c
vendored
343
externals/SDL/src/render/opengl/SDL_render_gl.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -30,6 +30,11 @@
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_VITA_PVR_OGL
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
|
||||
/* To prevent unnecessary window recreation,
|
||||
* these should match the defaults selected in SDL_GL_ResetAttributes
|
||||
*/
|
||||
@@ -72,6 +77,9 @@ typedef struct
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_Rect cliprect;
|
||||
SDL_bool texturing;
|
||||
SDL_bool vertex_array;
|
||||
SDL_bool color_array;
|
||||
SDL_bool texture_array;
|
||||
Uint32 color;
|
||||
Uint32 clear_color;
|
||||
} GL_DrawStateCache;
|
||||
@@ -316,6 +324,20 @@ GL_GetFBO(GL_RenderData *data, Uint32 w, Uint32 h)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
GL_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
|
||||
{
|
||||
/* If the window x/y/w/h changed at all, assume the viewport has been
|
||||
* changed behind our backs. x/y changes might seem weird but viewport
|
||||
* resets have been observed on macOS at minimum!
|
||||
*/
|
||||
if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
|
||||
event->event == SDL_WINDOWEVENT_MOVED) {
|
||||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
GL_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
{
|
||||
@@ -981,7 +1003,7 @@ GL_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPo
|
||||
|
||||
static int
|
||||
GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
@@ -989,9 +1011,9 @@ GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te
|
||||
int i;
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
GLfloat *verts;
|
||||
int sz = 2 + 4 + (texture ? 2 : 0);
|
||||
size_t sz = 2 * sizeof(GLfloat) + 4 * sizeof(Uint8) + (texture ? 2 : 0) * sizeof(GLfloat);
|
||||
|
||||
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (GLfloat), 0, &cmd->data.draw.first);
|
||||
verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1006,7 +1028,6 @@ GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
SDL_Color col_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
@@ -1018,15 +1039,14 @@ GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te
|
||||
}
|
||||
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
*(verts++) = xy_[0] * scale_x;
|
||||
*(verts++) = xy_[1] * scale_y;
|
||||
|
||||
*(verts++) = col_.r * inv255f;
|
||||
*(verts++) = col_.g * inv255f;
|
||||
*(verts++) = col_.b * inv255f;
|
||||
*(verts++) = col_.a * inv255f;
|
||||
/* Not really a float, but it is still 4 bytes and will be cast to the
|
||||
right type in the graphics driver. */
|
||||
SDL_memcpy(verts, ((char*)color + j * color_stride), sizeof(*color));
|
||||
++verts;
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
@@ -1037,10 +1057,13 @@ GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *te
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader shader)
|
||||
{
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
SDL_bool vertex_array;
|
||||
SDL_bool color_array;
|
||||
SDL_bool texture_array;
|
||||
|
||||
if (data->drawstate.viewport_dirty) {
|
||||
const SDL_bool istarget = data->drawstate.target != NULL;
|
||||
@@ -1106,9 +1129,46 @@ SetDrawState(GL_RenderData *data, const SDL_RenderCommand *cmd, const GL_Shader
|
||||
data->drawstate.texturing = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
vertex_array = cmd->command == SDL_RENDERCMD_DRAW_POINTS
|
||||
|| cmd->command == SDL_RENDERCMD_DRAW_LINES
|
||||
|| cmd->command == SDL_RENDERCMD_GEOMETRY;
|
||||
color_array = cmd->command == SDL_RENDERCMD_GEOMETRY;
|
||||
texture_array = cmd->data.draw.texture != NULL;
|
||||
|
||||
if (vertex_array != data->drawstate.vertex_array) {
|
||||
if (vertex_array) {
|
||||
data->glEnableClientState(GL_VERTEX_ARRAY);
|
||||
} else {
|
||||
data->glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
data->drawstate.vertex_array = vertex_array;
|
||||
}
|
||||
|
||||
if (color_array != data->drawstate.color_array) {
|
||||
if (color_array) {
|
||||
data->glEnableClientState(GL_COLOR_ARRAY);
|
||||
} else {
|
||||
data->glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
data->drawstate.color_array = color_array;
|
||||
}
|
||||
|
||||
/* This is a little awkward but should avoid texcoord arrays getting into
|
||||
a bad state if SDL_GL_BindTexture/UnbindTexture are called. */
|
||||
if (texture_array != data->drawstate.texture_array) {
|
||||
if (texture_array) {
|
||||
data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
} else {
|
||||
data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
data->drawstate.texture_array = texture_array;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
@@ -1144,6 +1204,8 @@ SetCopyState(GL_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
|
||||
data->drawstate.texture = texture;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1151,7 +1213,6 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
{
|
||||
/* !!! FIXME: it'd be nice to use a vertex buffer instead of immediate mode... */
|
||||
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
|
||||
size_t i;
|
||||
|
||||
if (GL_ActivateRenderer(renderer) < 0) {
|
||||
return -1;
|
||||
@@ -1170,9 +1231,9 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
}
|
||||
|
||||
#ifdef __MACOSX__
|
||||
// On macOS, moving the window seems to invalidate the OpenGL viewport state,
|
||||
// so don't bother trying to persist it across frames; always reset it.
|
||||
// Workaround for: https://github.com/libsdl-org/SDL/issues/1504
|
||||
// On macOS on older systems, the OpenGL view change and resize events aren't
|
||||
// necessarily synchronized, so just always reset it.
|
||||
// Workaround for: https://discourse.libsdl.org/t/sdl-2-0-22-prerelease/35306/6
|
||||
data->drawstate.viewport_dirty = SDL_TRUE;
|
||||
#endif
|
||||
|
||||
@@ -1185,10 +1246,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
|
||||
if (color != data->drawstate.color) {
|
||||
data->glColor4f((GLfloat) r * inv255f,
|
||||
(GLfloat) g * inv255f,
|
||||
(GLfloat) b * inv255f,
|
||||
(GLfloat) a * inv255f);
|
||||
data->glColor4ub((GLubyte) r, (GLubyte) g, (GLubyte) b, (GLubyte) a);
|
||||
data->drawstate.color = color;
|
||||
}
|
||||
break;
|
||||
@@ -1209,6 +1267,7 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
|
||||
data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
|
||||
SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
|
||||
data->drawstate.cliprect_dirty = SDL_TRUE;
|
||||
@@ -1237,32 +1296,6 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
}
|
||||
|
||||
data->glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_POINTS: {
|
||||
const size_t count = cmd->data.draw.count;
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
SetDrawState(data, cmd, SHADER_SOLID);
|
||||
data->glBegin(GL_POINTS);
|
||||
for (i = 0; i < count; i++, verts += 2) {
|
||||
data->glVertex2f(verts[0], verts[1]);
|
||||
}
|
||||
data->glEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
const size_t count = cmd->data.draw.count;
|
||||
SDL_assert(count >= 2);
|
||||
SetDrawState(data, cmd, SHADER_SOLID);
|
||||
data->glBegin(GL_LINE_STRIP);
|
||||
for (i = 0; i < count; ++i, verts += 2) {
|
||||
data->glVertex2f(verts[0], verts[1]);
|
||||
}
|
||||
data->glEnd();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1275,47 +1308,113 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
case SDL_RENDERCMD_COPY_EX: /* unused */
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const size_t count = cmd->data.draw.count;
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
if (SetDrawState(data, cmd, SHADER_SOLID) == 0) {
|
||||
size_t count = cmd->data.draw.count;
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
|
||||
if (texture) {
|
||||
SetCopyState(data, cmd);
|
||||
} else {
|
||||
SetDrawState(data, cmd, SHADER_SOLID);
|
||||
}
|
||||
/* SetDrawState handles glEnableClientState. */
|
||||
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts);
|
||||
|
||||
{
|
||||
size_t j;
|
||||
float currentColor[4];
|
||||
data->glGetFloatv(GL_CURRENT_COLOR, currentColor);
|
||||
data->glBegin(GL_TRIANGLES);
|
||||
for (j = 0; j < count; ++j)
|
||||
{
|
||||
const GLfloat x = *(verts++);
|
||||
const GLfloat y = *(verts++);
|
||||
if (count > 2) {
|
||||
/* joined lines cannot be grouped */
|
||||
data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)count);
|
||||
} else {
|
||||
/* let's group non joined lines */
|
||||
SDL_RenderCommand *finalcmd = cmd;
|
||||
SDL_RenderCommand *nextcmd = cmd->next;
|
||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||
|
||||
const GLfloat r = *(verts++);
|
||||
const GLfloat g = *(verts++);
|
||||
const GLfloat b = *(verts++);
|
||||
const GLfloat a = *(verts++);
|
||||
|
||||
data->glColor4f(r, g, b, a);
|
||||
|
||||
if (texture) {
|
||||
GLfloat u = *(verts++);
|
||||
GLfloat v = *(verts++);
|
||||
data->glTexCoord2f(u,v);
|
||||
while (nextcmd != NULL) {
|
||||
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
|
||||
if (nextcmdtype != SDL_RENDERCMD_DRAW_LINES) {
|
||||
break; /* can't go any further on this draw call, different render command up next. */
|
||||
} else if (nextcmd->data.draw.count != 2) {
|
||||
break; /* can't go any further on this draw call, those are joined lines */
|
||||
} else if (nextcmd->data.draw.blend != thisblend) {
|
||||
break; /* can't go any further on this draw call, different blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += nextcmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
data->glVertex2f(x, y);
|
||||
|
||||
data->glDrawArrays(GL_LINES, 0, (GLsizei)count);
|
||||
cmd = finalcmd; /* skip any copy commands we just combined in here. */
|
||||
}
|
||||
data->glEnd();
|
||||
data->glColor4f(currentColor[0], currentColor[1], currentColor[2], currentColor[3]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_DRAW_POINTS:
|
||||
case SDL_RENDERCMD_GEOMETRY: {
|
||||
/* as long as we have the same copy command in a row, with the
|
||||
same texture, we can combine them all into a single draw call. */
|
||||
SDL_Texture *thistexture = cmd->data.draw.texture;
|
||||
SDL_BlendMode thisblend = cmd->data.draw.blend;
|
||||
const SDL_RenderCommandType thiscmdtype = cmd->command;
|
||||
SDL_RenderCommand *finalcmd = cmd;
|
||||
SDL_RenderCommand *nextcmd = cmd->next;
|
||||
size_t count = cmd->data.draw.count;
|
||||
int ret;
|
||||
while (nextcmd != NULL) {
|
||||
const SDL_RenderCommandType nextcmdtype = nextcmd->command;
|
||||
if (nextcmdtype != thiscmdtype) {
|
||||
break; /* can't go any further on this draw call, different render command up next. */
|
||||
} else if (nextcmd->data.draw.texture != thistexture || nextcmd->data.draw.blend != thisblend) {
|
||||
break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += nextcmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(data, cmd);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd, SHADER_SOLID);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */
|
||||
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
|
||||
op = GL_POINTS;
|
||||
}
|
||||
|
||||
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
|
||||
/* SetDrawState handles glEnableClientState. */
|
||||
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 2, verts);
|
||||
} else {
|
||||
/* SetDrawState handles glEnableClientState. */
|
||||
if (thistexture) {
|
||||
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 0);
|
||||
data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 5, verts + 2);
|
||||
data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 3);
|
||||
} else {
|
||||
data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 3, verts + 0);
|
||||
data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 3, verts + 2);
|
||||
}
|
||||
}
|
||||
|
||||
data->glDrawArrays(op, 0, (GLsizei) count);
|
||||
|
||||
/* Restore previously set color when we're done. */
|
||||
if (thiscmdtype != SDL_RENDERCMD_DRAW_POINTS) {
|
||||
Uint32 color = data->drawstate.color;
|
||||
GLubyte a = (GLubyte)((color >> 24) & 0xFF);
|
||||
GLubyte r = (GLubyte)((color >> 16) & 0xFF);
|
||||
GLubyte g = (GLubyte)((color >> 8) & 0xFF);
|
||||
GLubyte b = (GLubyte)((color >> 0) & 0xFF);
|
||||
data->glColor4ub(r, g, b, a);
|
||||
}
|
||||
}
|
||||
|
||||
cmd = finalcmd; /* skip any copy commands we just combined in here. */
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_RENDERCMD_NO_OP:
|
||||
break;
|
||||
@@ -1324,6 +1423,21 @@ GL_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
cmd = cmd->next;
|
||||
}
|
||||
|
||||
/* Turn off vertex array state when we're done, in case external code
|
||||
relies on it being off. */
|
||||
if (data->drawstate.vertex_array) {
|
||||
data->glDisableClientState(GL_VERTEX_ARRAY);
|
||||
data->drawstate.vertex_array = SDL_FALSE;
|
||||
}
|
||||
if (data->drawstate.color_array) {
|
||||
data->glDisableClientState(GL_COLOR_ARRAY);
|
||||
data->drawstate.color_array = SDL_FALSE;
|
||||
}
|
||||
if (data->drawstate.texture_array) {
|
||||
data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
data->drawstate.texture_array = SDL_FALSE;
|
||||
}
|
||||
|
||||
return GL_CheckError("", renderer);
|
||||
}
|
||||
|
||||
@@ -1595,6 +1709,32 @@ GL_SetVSync(SDL_Renderer * renderer, const int vsync)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
GL_IsProbablyAccelerated(const GL_RenderData *data)
|
||||
{
|
||||
/*const char *vendor = (const char *) data->glGetString(GL_VENDOR);*/
|
||||
const char *renderer = (const char *) data->glGetString(GL_RENDERER);
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
if (SDL_strcmp(renderer, "GDI Generic") == 0) {
|
||||
return SDL_FALSE; /* Microsoft's fallback software renderer. Fix your system! */
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (SDL_strcmp(renderer, "Apple Software Renderer") == 0) {
|
||||
return SDL_FALSE; /* (a probably very old) Apple software-based OpenGL. */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SDL_strcmp(renderer, "Software Rasterizer") == 0) {
|
||||
return SDL_FALSE; /* (a probably very old) Software Mesa, or some other generic thing. */
|
||||
}
|
||||
|
||||
/* !!! FIXME: swrast? llvmpipe? softpipe? */
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
static SDL_Renderer *
|
||||
GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
@@ -1605,11 +1745,14 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
Uint32 window_flags;
|
||||
int profile_mask = 0, major = 0, minor = 0;
|
||||
SDL_bool changed_window = SDL_FALSE;
|
||||
const char *hint;
|
||||
SDL_bool non_power_of_two_supported = SDL_FALSE;
|
||||
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile_mask);
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
|
||||
SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
|
||||
|
||||
#ifndef SDL_VIDEO_VITA_PVR_OGL
|
||||
window_flags = SDL_GetWindowFlags(window);
|
||||
if (!(window_flags & SDL_WINDOW_OPENGL) ||
|
||||
profile_mask == SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
|
||||
@@ -1623,6 +1766,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
|
||||
if (!renderer) {
|
||||
@@ -1637,6 +1781,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
goto error;
|
||||
}
|
||||
|
||||
renderer->WindowEvent = GL_WindowEvent;
|
||||
renderer->GetOutputSize = GL_GetOutputSize;
|
||||
renderer->SupportsBlendMode = GL_SupportsBlendMode;
|
||||
renderer->CreateTexture = GL_CreateTexture;
|
||||
@@ -1663,7 +1808,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->GL_BindTexture = GL_BindTexture;
|
||||
renderer->GL_UnbindTexture = GL_UnbindTexture;
|
||||
renderer->info = GL_RenderDriver.info;
|
||||
renderer->info.flags = SDL_RENDERER_ACCELERATED;
|
||||
renderer->info.flags = 0; /* will set some flags below. */
|
||||
renderer->driverdata = data;
|
||||
renderer->window = window;
|
||||
|
||||
@@ -1687,6 +1832,10 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (GL_IsProbablyAccelerated(data)) {
|
||||
renderer->info.flags |= SDL_RENDERER_ACCELERATED;
|
||||
}
|
||||
|
||||
#ifdef __MACOSX__
|
||||
/* Enable multi-threaded rendering */
|
||||
/* Disabled until Ryan finishes his VBO/PBO code...
|
||||
@@ -1720,15 +1869,37 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
data->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
|
||||
}
|
||||
|
||||
hint = SDL_getenv("GL_ARB_texture_non_power_of_two");
|
||||
if (!hint || *hint != '0') {
|
||||
SDL_bool isGL2 = SDL_FALSE;
|
||||
const char *verstr = (const char *)data->glGetString(GL_VERSION);
|
||||
if (verstr) {
|
||||
char verbuf[16];
|
||||
char *ptr;
|
||||
SDL_strlcpy(verbuf, verstr, sizeof (verbuf));
|
||||
ptr = SDL_strchr(verbuf, '.');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
if (SDL_atoi(verbuf) >= 2) {
|
||||
isGL2 = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isGL2 || SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
|
||||
non_power_of_two_supported = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
data->textype = GL_TEXTURE_2D;
|
||||
if (SDL_GL_ExtensionSupported("GL_ARB_texture_non_power_of_two")) {
|
||||
if (non_power_of_two_supported) {
|
||||
data->GL_ARB_texture_non_power_of_two_supported = SDL_TRUE;
|
||||
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
||||
renderer->info.max_texture_width = value;
|
||||
renderer->info.max_texture_height = value;
|
||||
} else if (SDL_GL_ExtensionSupported("GL_ARB_texture_rectangle") ||
|
||||
SDL_GL_ExtensionSupported("GL_EXT_texture_rectangle")) {
|
||||
data->GL_ARB_texture_rectangle_supported = SDL_TRUE;
|
||||
data->textype = GL_TEXTURE_RECTANGLE_ARB;
|
||||
}
|
||||
if (data->GL_ARB_texture_rectangle_supported) {
|
||||
data->glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB, &value);
|
||||
renderer->info.max_texture_width = value;
|
||||
renderer->info.max_texture_height = value;
|
||||
@@ -1753,7 +1924,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
}
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_RENDER, "OpenGL shaders: %s",
|
||||
data->shaders ? "ENABLED" : "DISABLED");
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
/* We support YV12 textures using 3 textures and a shader */
|
||||
if (data->shaders && data->num_texture_units >= 3) {
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
|
||||
@@ -1761,7 +1932,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef __MACOSX__
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_UYVY;
|
||||
#endif
|
||||
@@ -1790,7 +1961,7 @@ GL_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||
data->glDisable(GL_SCISSOR_TEST);
|
||||
data->glDisable(data->textype);
|
||||
data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
data->glColor4ub(255, 255, 255, 255);
|
||||
/* This ended up causing video discrepancies between OpenGL and Direct3D */
|
||||
/* data->glEnable(GL_LINE_SMOOTH); */
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -284,7 +284,7 @@ static const char *shader_source[NUM_SHADERS][2] =
|
||||
" gl_FragColor = texture2D(tex0, v_texCoord) * v_color;\n"
|
||||
"}"
|
||||
},
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
/* SHADER_YUV_JPEG */
|
||||
{
|
||||
/* vertex shader */
|
||||
@@ -384,6 +384,7 @@ static const char *shader_source[NUM_SHADERS][2] =
|
||||
BT709_SHADER_CONSTANTS
|
||||
NV21_SHADER_BODY
|
||||
},
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
};
|
||||
|
||||
static SDL_bool
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -32,6 +32,7 @@ typedef enum {
|
||||
SHADER_SOLID,
|
||||
SHADER_RGB,
|
||||
SHADER_RGBA,
|
||||
#if SDL_HAVE_YUV
|
||||
SHADER_YUV_JPEG,
|
||||
SHADER_YUV_BT601,
|
||||
SHADER_YUV_BT709,
|
||||
@@ -43,6 +44,7 @@ typedef enum {
|
||||
SHADER_NV21_JPEG,
|
||||
SHADER_NV21_BT601,
|
||||
SHADER_NV21_BT709,
|
||||
#endif
|
||||
NUM_SHADERS
|
||||
} GL_Shader;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -603,7 +603,7 @@ GLES_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_F
|
||||
|
||||
static int
|
||||
GLES_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -28,6 +28,17 @@
|
||||
#include "../../video/SDL_blit.h"
|
||||
#include "SDL_shaders_gles2.h"
|
||||
|
||||
/* WebGL doesn't offer client-side arrays, so use Vertex Buffer Objects
|
||||
on Emscripten, which converts GLES2 into WebGL calls.
|
||||
In all other cases, attempt to use client-side arrays, as they tend to
|
||||
be dramatically faster when not batching, and about the same when
|
||||
we are. */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#define USE_VERTEX_BUFFER_OBJECTS 1
|
||||
#else
|
||||
#define USE_VERTEX_BUFFER_OBJECTS 0
|
||||
#endif
|
||||
|
||||
/* To prevent unnecessary window recreation,
|
||||
* these should match the defaults selected in SDL_GL_ResetAttributes
|
||||
*/
|
||||
@@ -151,9 +162,12 @@ typedef struct GLES2_RenderData
|
||||
GLES2_ProgramCache program_cache;
|
||||
Uint8 clear_r, clear_g, clear_b, clear_a;
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
GLuint vertex_buffers[8];
|
||||
size_t vertex_buffer_size[8];
|
||||
int current_vertex_buffer;
|
||||
#endif
|
||||
|
||||
GLES2_DrawStateCache drawstate;
|
||||
} GLES2_RenderData;
|
||||
|
||||
@@ -480,7 +494,7 @@ GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_t
|
||||
{
|
||||
GLuint id;
|
||||
GLint compileSuccessful = GL_FALSE;
|
||||
const Uint8 *shader_src = GLES2_GetShader(type);
|
||||
const char *shader_src = (char *)GLES2_GetShader(type);
|
||||
|
||||
if (!shader_src) {
|
||||
SDL_SetError("No shader src");
|
||||
@@ -489,7 +503,7 @@ GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_t
|
||||
|
||||
/* Compile */
|
||||
id = data->glCreateShader(shader_type);
|
||||
data->glShaderSource(id, 1, (const char**)&shader_src, NULL);
|
||||
data->glShaderSource(id, 1, &shader_src, NULL);
|
||||
data->glCompileShader(id);
|
||||
data->glGetShaderiv(id, GL_COMPILE_STATUS, &compileSuccessful);
|
||||
|
||||
@@ -547,6 +561,7 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
|
||||
case GLES2_IMAGESOURCE_TEXTURE_BGR:
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR;
|
||||
break;
|
||||
#if SDL_HAVE_YUV
|
||||
case GLES2_IMAGESOURCE_TEXTURE_YUV:
|
||||
switch (SDL_GetYUVConversionModeForResolution(w, h)) {
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
@@ -603,6 +618,7 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
|
||||
goto fault;
|
||||
}
|
||||
break;
|
||||
#endif /* SDL_HAVE_YUV */
|
||||
case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
|
||||
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES;
|
||||
break;
|
||||
@@ -663,26 +679,30 @@ static int
|
||||
GLES2_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
int color;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int)) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
|
||||
int i;
|
||||
SDL_Color color;
|
||||
color.r = cmd->data.draw.r;
|
||||
color.g = cmd->data.draw.g;
|
||||
color.b = cmd->data.draw.b;
|
||||
color.a = cmd->data.draw.a;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (colorswap == 0) {
|
||||
color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
} else {
|
||||
color = (cmd->data.draw.r << 16) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 0) | ((Uint32)cmd->data.draw.a << 24);
|
||||
if (colorswap) {
|
||||
Uint8 r = color.r;
|
||||
color.r = color.b;
|
||||
color.b = r;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
for (i = 0; i < count; i++) {
|
||||
*(verts++) = 0.5f + points[i].x;
|
||||
*(verts++) = 0.5f + points[i].y;
|
||||
*((int *)verts++) = color;
|
||||
verts->position.x = 0.5f + points[i].x;
|
||||
verts->position.y = 0.5f + points[i].y;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -692,19 +712,23 @@ static int
|
||||
GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
int color;
|
||||
int i;
|
||||
GLfloat prevx, prevy;
|
||||
const size_t vertlen = ((2 * sizeof (float)) + sizeof (int)) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
|
||||
SDL_Color color;
|
||||
color.r = cmd->data.draw.r;
|
||||
color.g = cmd->data.draw.g;
|
||||
color.b = cmd->data.draw.b;
|
||||
color.a = cmd->data.draw.a;
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (colorswap == 0) {
|
||||
color = (cmd->data.draw.r << 0) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 16) | ((Uint32)cmd->data.draw.a << 24);
|
||||
} else {
|
||||
color = (cmd->data.draw.r << 16) | (cmd->data.draw.g << 8) | (cmd->data.draw.b << 0) | ((Uint32)cmd->data.draw.a << 24);
|
||||
if (colorswap) {
|
||||
Uint8 r = color.r;
|
||||
color.r = color.b;
|
||||
color.b = r;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
@@ -712,9 +736,10 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
/* 0.5f offset to hit the center of the pixel. */
|
||||
prevx = 0.5f + points->x;
|
||||
prevy = 0.5f + points->y;
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
*((int *)verts++) = color;
|
||||
verts->position.x = prevx;
|
||||
verts->position.y = prevy;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
|
||||
/* bump the end of each line segment out a quarter of a pixel, to provoke
|
||||
the diamond-exit rule. Without this, you won't just drop the last
|
||||
@@ -731,9 +756,10 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
const GLfloat angle = SDL_atan2f(deltay, deltax);
|
||||
prevx = xend + (SDL_cosf(angle) * 0.25f);
|
||||
prevy = yend + (SDL_sinf(angle) * 0.25f);
|
||||
*(verts++) = prevx;
|
||||
*(verts++) = prevy;
|
||||
*((int *)verts++) = color;
|
||||
verts->position.x = prevx;
|
||||
verts->position.y = prevy;
|
||||
verts->color = color;
|
||||
verts++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -741,59 +767,92 @@ GLES2_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_
|
||||
|
||||
static int
|
||||
GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
int i;
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
int count = indices ? num_indices : num_vertices;
|
||||
const size_t vertlen = (2 * sizeof (float) + sizeof (int) + (texture ? 2 : 0) * sizeof (float)) * count;
|
||||
GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, vertlen, 0, &cmd->data.draw.first);
|
||||
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd->data.draw.count = count;
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
int col_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
j = ((const Uint16 *)indices)[i];
|
||||
} else if (size_indices == 1) {
|
||||
j = ((const Uint8 *)indices)[i];
|
||||
} else {
|
||||
j = i;
|
||||
if (texture) {
|
||||
SDL_Vertex *verts = (SDL_Vertex *) SDL_AllocateRenderVertices(renderer, count * sizeof (*verts), 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(int *)((char*)color + j * color_stride);
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
SDL_Color col_;
|
||||
float *uv_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
j = ((const Uint16 *)indices)[i];
|
||||
} else if (size_indices == 1) {
|
||||
j = ((const Uint8 *)indices)[i];
|
||||
} else {
|
||||
j = i;
|
||||
}
|
||||
|
||||
*(verts++) = xy_[0] * scale_x;
|
||||
*(verts++) = xy_[1] * scale_y;
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
|
||||
if (colorswap == 0) {
|
||||
*((int *)verts++) = col_;
|
||||
} else {
|
||||
Uint8 r, g, b, a;
|
||||
r = (col_ >> 0) & 0xff;
|
||||
g = (col_ >> 8) & 0xff;
|
||||
b = (col_ >> 16) & 0xff;
|
||||
a = (col_ >> 24) & 0xff;
|
||||
col_ = (r << 16) | (g << 8) | (b << 0) | ((Uint32)a << 24);
|
||||
*((int *)verts++) = col_;
|
||||
verts->position.x = xy_[0] * scale_x;
|
||||
verts->position.y = xy_[1] * scale_y;
|
||||
|
||||
if (colorswap) {
|
||||
Uint8 r = col_.r;
|
||||
col_.r = col_.b;
|
||||
col_.b = r;
|
||||
}
|
||||
|
||||
verts->color = col_;
|
||||
verts->tex_coord.x = uv_[0];
|
||||
verts->tex_coord.y = uv_[1];
|
||||
verts++;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
float *uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
*(verts++) = uv_[0];
|
||||
*(verts++) = uv_[1];
|
||||
} else {
|
||||
SDL_VertexSolid *verts = (SDL_VertexSolid *) SDL_AllocateRenderVertices(renderer, count * sizeof (*verts), 0, &cmd->data.draw.first);
|
||||
if (!verts) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
SDL_Color col_;
|
||||
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
j = ((const Uint16 *)indices)[i];
|
||||
} else if (size_indices == 1) {
|
||||
j = ((const Uint8 *)indices)[i];
|
||||
} else {
|
||||
j = i;
|
||||
}
|
||||
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
verts->position.x = xy_[0] * scale_x;
|
||||
verts->position.y = xy_[1] * scale_y;
|
||||
|
||||
if (colorswap) {
|
||||
Uint8 r = col_.r;
|
||||
col_.r = col_.b;
|
||||
col_.b = r;
|
||||
}
|
||||
|
||||
verts->color = col_;
|
||||
verts++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,12 +860,12 @@ GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture
|
||||
}
|
||||
|
||||
static int
|
||||
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc)
|
||||
SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_ImageSource imgsrc, void *vertices)
|
||||
{
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
const SDL_BlendMode blend = cmd->data.draw.blend;
|
||||
GLES2_ProgramCacheEntry *program;
|
||||
int stride = sizeof (GLfloat) * 2 /* position */ + sizeof (int) /* color */;
|
||||
int stride;
|
||||
|
||||
SDL_assert((texture != NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID));
|
||||
|
||||
@@ -841,47 +900,25 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
||||
data->drawstate.cliprect_dirty = SDL_FALSE;
|
||||
}
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
if ((texture != NULL) != data->drawstate.texturing) {
|
||||
if (texture == NULL) {
|
||||
data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
|
||||
data->drawstate.texturing = SDL_FALSE;
|
||||
} else {
|
||||
data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
|
||||
data->drawstate.texturing = SDL_TRUE;
|
||||
}
|
||||
if ((texture != NULL) != data->drawstate.texturing) {
|
||||
if (texture == NULL) {
|
||||
data->glDisableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
|
||||
data->drawstate.texturing = SDL_FALSE;
|
||||
} else {
|
||||
data->glEnableVertexAttribArray((GLenum) GLES2_ATTRIBUTE_TEXCOORD);
|
||||
data->drawstate.texturing = SDL_TRUE;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata;
|
||||
#if SDL_HAVE_YUV
|
||||
if (tdata->yuv) {
|
||||
data->glActiveTexture(GL_TEXTURE2);
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture_v);
|
||||
|
||||
data->glActiveTexture(GL_TEXTURE1);
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
||||
|
||||
data->glActiveTexture(GL_TEXTURE0);
|
||||
} else if (tdata->nv12) {
|
||||
data->glActiveTexture(GL_TEXTURE1);
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
||||
|
||||
data->glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
#endif
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture);
|
||||
}
|
||||
|
||||
data->drawstate.texture = texture;
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
stride += sizeof (GLfloat) * 2; /* tex coord */
|
||||
stride = sizeof(SDL_Vertex);
|
||||
} else {
|
||||
stride = sizeof(SDL_VertexSolid);
|
||||
}
|
||||
|
||||
if (texture) {
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + sizeof (GLfloat) * (2 + 1)));
|
||||
SDL_Vertex *verts = (SDL_Vertex *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->tex_coord);
|
||||
}
|
||||
|
||||
if (GLES2_SelectProgram(data, imgsrc, texture ? texture->w : 0, texture ? texture->h : 0) < 0) {
|
||||
@@ -913,18 +950,22 @@ SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, const GLES2_I
|
||||
}
|
||||
|
||||
/* all drawing commands use this */
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) (uintptr_t) cmd->data.draw.first);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) (uintptr_t) (cmd->data.draw.first + sizeof (GLfloat) * 2));
|
||||
{
|
||||
SDL_VertexSolid *verts = (SDL_VertexSolid *) (((Uint8 *) vertices) + cmd->data.draw.first);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) &verts->position);
|
||||
data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *) &verts->color);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd, void *vertices)
|
||||
{
|
||||
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
|
||||
GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
|
||||
SDL_Texture *texture = cmd->data.draw.texture;
|
||||
int ret;
|
||||
|
||||
/* Pick an appropriate shader */
|
||||
if (renderer->target) {
|
||||
@@ -979,6 +1020,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#if SDL_HAVE_YUV
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
|
||||
@@ -989,6 +1031,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
|
||||
break;
|
||||
#endif
|
||||
case SDL_PIXELFORMAT_EXTERNAL_OES:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
|
||||
break;
|
||||
@@ -1012,6 +1055,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
case SDL_PIXELFORMAT_BGR888:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
|
||||
break;
|
||||
#if SDL_HAVE_YUV
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
|
||||
@@ -1022,6 +1066,7 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
|
||||
break;
|
||||
#endif
|
||||
case SDL_PIXELFORMAT_EXTERNAL_OES:
|
||||
sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
|
||||
break;
|
||||
@@ -1030,7 +1075,31 @@ SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
return SetDrawState(data, cmd, sourceType);
|
||||
ret = SetDrawState(data, cmd, sourceType, vertices);
|
||||
|
||||
if (texture != data->drawstate.texture) {
|
||||
GLES2_TextureData *tdata = (GLES2_TextureData *) texture->driverdata;
|
||||
#if SDL_HAVE_YUV
|
||||
if (tdata->yuv) {
|
||||
data->glActiveTexture(GL_TEXTURE2);
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture_v);
|
||||
|
||||
data->glActiveTexture(GL_TEXTURE1);
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
||||
|
||||
data->glActiveTexture(GL_TEXTURE0);
|
||||
} else if (tdata->nv12) {
|
||||
data->glActiveTexture(GL_TEXTURE1);
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture_u);
|
||||
|
||||
data->glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
#endif
|
||||
data->glBindTexture(tdata->texture_type, tdata->texture);
|
||||
data->drawstate.texture = texture;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1038,8 +1107,11 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
{
|
||||
GLES2_RenderData *data = (GLES2_RenderData *) renderer->driverdata;
|
||||
const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 || renderer->target->format == SDL_PIXELFORMAT_RGB888));
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
const int vboidx = data->current_vertex_buffer;
|
||||
const GLuint vbo = data->vertex_buffers[vboidx];
|
||||
#endif
|
||||
|
||||
if (GLES2_ActivateRenderer(renderer) < 0) {
|
||||
return -1;
|
||||
@@ -1057,6 +1129,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
}
|
||||
}
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
/* upload the new VBO data for this set of commands. */
|
||||
data->glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||
if (data->vertex_buffer_size[vboidx] < vertsize) {
|
||||
@@ -1071,6 +1144,8 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
if (data->current_vertex_buffer >= SDL_arraysize(data->vertex_buffers)) {
|
||||
data->current_vertex_buffer = 0;
|
||||
}
|
||||
vertices = NULL; /* attrib pointers will be offsets into the VBO. */
|
||||
#endif
|
||||
|
||||
while (cmd) {
|
||||
switch (cmd->command) {
|
||||
@@ -1135,7 +1210,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
break;
|
||||
|
||||
case SDL_RENDERCMD_DRAW_LINES: {
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
|
||||
if (SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices) == 0) {
|
||||
size_t count = cmd->data.draw.count;
|
||||
if (count > 2) {
|
||||
/* joined lines cannot be grouped */
|
||||
@@ -1156,7 +1231,7 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
break; /* can't go any further on this draw call, different blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += cmd->data.draw.count;
|
||||
count += nextcmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
@@ -1187,21 +1262,21 @@ GLES2_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *ver
|
||||
break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += cmd->data.draw.count;
|
||||
count += nextcmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(renderer, cmd);
|
||||
ret = SetCopyState(renderer, cmd, vertices);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID);
|
||||
ret = SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID, vertices);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
int op = GL_TRIANGLES; /* SDL_RENDERCMD_GEOMETRY */
|
||||
if (thiscmdtype == SDL_RENDERCMD_DRAW_POINTS) {
|
||||
op = GL_POINTS;
|
||||
op = GL_POINTS;
|
||||
}
|
||||
data->glDrawArrays(op, 0, (GLsizei) count);
|
||||
}
|
||||
@@ -1259,8 +1334,10 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
|
||||
data->framebuffers = nextnode;
|
||||
}
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
data->glDeleteBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
||||
GL_CheckError("", renderer);
|
||||
#endif
|
||||
|
||||
SDL_GL_DeleteContext(data->context);
|
||||
}
|
||||
@@ -1293,6 +1370,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
format = GL_RGBA;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
#if SDL_HAVE_YUV
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
@@ -1300,6 +1378,7 @@ GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
format = GL_LUMINANCE;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GL_TEXTURE_EXTERNAL_OES
|
||||
case SDL_PIXELFORMAT_EXTERNAL_OES:
|
||||
format = GL_NONE;
|
||||
@@ -1437,6 +1516,9 @@ static int
|
||||
GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels, GLint pitch, GLint bpp)
|
||||
{
|
||||
Uint8 *blob = NULL;
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
Uint32 *blob2 = NULL;
|
||||
#endif
|
||||
Uint8 *src;
|
||||
int src_pitch;
|
||||
int y;
|
||||
@@ -1463,10 +1545,33 @@ GLES2_TexSubImage2D(GLES2_RenderData *data, GLenum target, GLint xoffset, GLint
|
||||
src = blob;
|
||||
}
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
if (format == GL_RGBA) {
|
||||
int i;
|
||||
Uint32 *src32 = (Uint32 *)src;
|
||||
blob2 = (Uint32 *)SDL_malloc(src_pitch * height);
|
||||
if (!blob2) {
|
||||
if (blob) {
|
||||
SDL_free(blob);
|
||||
}
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
for (i = 0; i < (src_pitch * height) / 4; i++) {
|
||||
blob2[i] = SDL_Swap32(src32[i]);
|
||||
}
|
||||
src = (Uint8 *) blob2;
|
||||
}
|
||||
#endif
|
||||
|
||||
data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src);
|
||||
if (blob) {
|
||||
SDL_free(blob);
|
||||
}
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
if (blob2) {
|
||||
SDL_free(blob2);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1996,8 +2101,10 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
|
||||
renderer->info.max_texture_height = value;
|
||||
|
||||
#if USE_VERTEX_BUFFER_OBJECTS
|
||||
/* we keep a few of these and cycle through them, so data can live for a few frames. */
|
||||
data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
|
||||
#endif
|
||||
|
||||
data->framebuffers = NULL;
|
||||
data->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
|
||||
@@ -2030,11 +2137,12 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
renderer->SetVSync = GLES2_SetVSync;
|
||||
renderer->GL_BindTexture = GLES2_BindTexture;
|
||||
renderer->GL_UnbindTexture = GLES2_UnbindTexture;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_YV12;
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_IYUV;
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV12;
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_NV21;
|
||||
#endif
|
||||
#ifdef GL_TEXTURE_EXTERNAL_OES
|
||||
renderer->info.texture_formats[renderer->info.num_texture_formats++] = SDL_PIXELFORMAT_EXTERNAL_OES;
|
||||
#endif
|
||||
@@ -2090,3 +2198,4 @@ SDL_RenderDriver GLES2_RenderDriver = {
|
||||
#endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -121,6 +121,8 @@ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
|
||||
} \
|
||||
";
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
|
||||
#define JPEG_SHADER_CONSTANTS \
|
||||
"// YUV offset \n" \
|
||||
"const vec3 offset = vec3(0, -0.501960814, -0.501960814);\n" \
|
||||
@@ -299,6 +301,7 @@ static const Uint8 GLES2_Fragment_TextureNV21BT709[] = \
|
||||
BT709_SHADER_CONSTANTS \
|
||||
NV21_SHADER_BODY \
|
||||
;
|
||||
#endif
|
||||
|
||||
/* Custom Android video format texture */
|
||||
static const Uint8 GLES2_Fragment_TextureExternalOES[] = " \
|
||||
@@ -335,6 +338,7 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
|
||||
return GLES2_Fragment_TextureRGB;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
|
||||
return GLES2_Fragment_TextureBGR;
|
||||
#if SDL_HAVE_YUV
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG:
|
||||
return GLES2_Fragment_TextureYUVJPEG;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601:
|
||||
@@ -357,6 +361,7 @@ const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
|
||||
return GLES2_Fragment_TextureNV21BT601;
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709:
|
||||
return GLES2_Fragment_TextureNV21BT709;
|
||||
#endif
|
||||
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
|
||||
return GLES2_Fragment_TextureExternalOES;
|
||||
default:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -34,6 +34,7 @@ typedef enum
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_ARGB,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_BGR,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_RGB,
|
||||
#if SDL_HAVE_YUV
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
|
||||
@@ -45,6 +46,7 @@ typedef enum
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,
|
||||
#endif
|
||||
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES,
|
||||
GLES2_SHADER_COUNT
|
||||
} GLES2_ShaderType;
|
||||
|
674
externals/SDL/src/render/psp/SDL_render_psp.c
vendored
674
externals/SDL/src/render/psp/SDL_render_psp.c
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -220,7 +220,7 @@ SDL_BlendFillRect(SDL_Surface * dst, const SDL_Rect * rect,
|
||||
SDL_Rect clipped;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_BlendFillRect(): dst");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
@@ -291,7 +291,7 @@ SDL_BlendFillRects(SDL_Surface * dst, const SDL_Rect * rects, int count,
|
||||
int status = 0;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_BlendFillRects(): dst");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -809,7 +809,7 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
|
||||
BlendLineFunc func;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("SDL_BlendLine(): Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_BlendLine(): dst");
|
||||
}
|
||||
|
||||
func = SDL_CalculateBlendLineFunc(dst->format);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -218,7 +218,7 @@ SDL_BlendPoint(SDL_Surface * dst, int x, int y, SDL_BlendMode blendMode, Uint8 r
|
||||
Uint8 g, Uint8 b, Uint8 a)
|
||||
{
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_BlendPoint(): dst");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
@@ -287,7 +287,7 @@ SDL_BlendPoints(SDL_Surface * dst, const SDL_Point * points, int count,
|
||||
int status = 0;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_BlendPoints(): dst");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
2
externals/SDL/src/render/software/SDL_draw.h
vendored
2
externals/SDL/src/render/software/SDL_draw.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -144,7 +144,7 @@ SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
|
||||
DrawLineFunc func;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("SDL_DrawLine(): Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_DrawLine(): dst");
|
||||
}
|
||||
|
||||
func = SDL_CalculateDrawLineFunc(dst->format);
|
||||
@@ -173,7 +173,7 @@ SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
|
||||
DrawLineFunc func;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("SDL_DrawLines(): Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_DrawLines(): dst");
|
||||
}
|
||||
|
||||
func = SDL_CalculateDrawLineFunc(dst->format);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -30,7 +30,7 @@ int
|
||||
SDL_DrawPoint(SDL_Surface * dst, int x, int y, Uint32 color)
|
||||
{
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_DrawPoint(): dst");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
@@ -71,7 +71,7 @@ SDL_DrawPoints(SDL_Surface * dst, const SDL_Point * points, int count,
|
||||
int x, y;
|
||||
|
||||
if (!dst) {
|
||||
return SDL_SetError("Passed NULL destination surface");
|
||||
return SDL_InvalidParamError("SDL_DrawPoints(): dst");
|
||||
}
|
||||
|
||||
/* This function doesn't work on surfaces < 8 bpp */
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
142
externals/SDL/src/render/software/SDL_render_sw.c
vendored
142
externals/SDL/src/render/software/SDL_render_sw.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -99,8 +99,7 @@ SW_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_SetError("Software renderer doesn't have an output surface");
|
||||
return -1;
|
||||
return SDL_SetError("Software renderer doesn't have an output surface");
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -274,12 +273,14 @@ typedef struct CopyExData
|
||||
double angle;
|
||||
SDL_FPoint center;
|
||||
SDL_RendererFlip flip;
|
||||
float scale_x;
|
||||
float scale_y;
|
||||
} CopyExData;
|
||||
|
||||
static int
|
||||
SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_FRect * dstrect,
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
|
||||
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, float scale_x, float scale_y)
|
||||
{
|
||||
CopyExData *verts = (CopyExData *) SDL_AllocateRenderVertices(renderer, sizeof (CopyExData), 0, &cmd->data.draw.first);
|
||||
|
||||
@@ -298,21 +299,41 @@ SW_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * te
|
||||
verts->angle = angle;
|
||||
SDL_memcpy(&verts->center, center, sizeof (SDL_FPoint));
|
||||
verts->flip = flip;
|
||||
verts->scale_x = scale_x;
|
||||
verts->scale_y = scale_y;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
Blit_to_Screen(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *surface, SDL_Rect *dstrect,
|
||||
float scale_x, float scale_y, SDL_ScaleMode scaleMode)
|
||||
{
|
||||
int retval;
|
||||
/* Renderer scaling, if needed */
|
||||
if (scale_x != 1.0f || scale_y != 1.0f) {
|
||||
SDL_Rect r;
|
||||
r.x = (int)((float) dstrect->x * scale_x);
|
||||
r.y = (int)((float) dstrect->y * scale_y);
|
||||
r.w = (int)((float) dstrect->w * scale_x);
|
||||
r.h = (int)((float) dstrect->h * scale_y);
|
||||
retval = SDL_PrivateUpperBlitScaled(src, srcrect, surface, &r, scaleMode);
|
||||
} else {
|
||||
retval = SDL_BlitSurface(src, srcrect, surface, dstrect);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * texture,
|
||||
const SDL_Rect * srcrect, const SDL_Rect * final_rect,
|
||||
const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip)
|
||||
const double angle, const SDL_FPoint * center, const SDL_RendererFlip flip, float scale_x, float scale_y)
|
||||
{
|
||||
SDL_Surface *src = (SDL_Surface *) texture->driverdata;
|
||||
SDL_Rect tmp_rect;
|
||||
SDL_Surface *src_clone, *src_rotated, *src_scaled;
|
||||
SDL_Surface *mask = NULL, *mask_rotated = NULL;
|
||||
int retval = 0, dstwidth, dstheight, abscenterx, abscentery;
|
||||
double cangle, sangle, px, py, p1x, p1y, p2x, p2y, p3x, p3y, p4x, p4y;
|
||||
int retval = 0;
|
||||
SDL_BlendMode blendmode;
|
||||
Uint8 alphaMod, rMod, gMod, bMod;
|
||||
int applyModulation = SDL_FALSE;
|
||||
@@ -414,53 +435,32 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
||||
SDL_SetSurfaceBlendMode(src_clone, blendmode);
|
||||
|
||||
if (!retval) {
|
||||
SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, &dstwidth, &dstheight, &cangle, &sangle);
|
||||
src_rotated = SDLgfx_rotateSurface(src_clone, angle, dstwidth/2, dstheight/2, (texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL, dstwidth, dstheight, cangle, sangle);
|
||||
SDL_Rect rect_dest;
|
||||
double cangle, sangle;
|
||||
|
||||
SDLgfx_rotozoomSurfaceSizeTrig(tmp_rect.w, tmp_rect.h, angle, center,
|
||||
&rect_dest, &cangle, &sangle);
|
||||
src_rotated = SDLgfx_rotateSurface(src_clone, angle,
|
||||
(texture->scaleMode == SDL_ScaleModeNearest) ? 0 : 1, flip & SDL_FLIP_HORIZONTAL, flip & SDL_FLIP_VERTICAL,
|
||||
&rect_dest, cangle, sangle, center);
|
||||
if (src_rotated == NULL) {
|
||||
retval = -1;
|
||||
}
|
||||
if (!retval && mask != NULL) {
|
||||
/* The mask needed for the NONE blend mode gets rotated with the same parameters. */
|
||||
mask_rotated = SDLgfx_rotateSurface(mask, angle, dstwidth/2, dstheight/2, SDL_FALSE, 0, 0, dstwidth, dstheight, cangle, sangle);
|
||||
mask_rotated = SDLgfx_rotateSurface(mask, angle,
|
||||
SDL_FALSE, 0, 0,
|
||||
&rect_dest, cangle, sangle, center);
|
||||
if (mask_rotated == NULL) {
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
if (!retval) {
|
||||
/* Find out where the new origin is by rotating the four final_rect points around the center and then taking the extremes */
|
||||
abscenterx = final_rect->x + (int)center->x;
|
||||
abscentery = final_rect->y + (int)center->y;
|
||||
/* Compensate the angle inversion to match the behaviour of the other backends */
|
||||
sangle = -sangle;
|
||||
|
||||
/* Top Left */
|
||||
px = final_rect->x - abscenterx;
|
||||
py = final_rect->y - abscentery;
|
||||
p1x = px * cangle - py * sangle + abscenterx;
|
||||
p1y = px * sangle + py * cangle + abscentery;
|
||||
|
||||
/* Top Right */
|
||||
px = final_rect->x + final_rect->w - abscenterx;
|
||||
py = final_rect->y - abscentery;
|
||||
p2x = px * cangle - py * sangle + abscenterx;
|
||||
p2y = px * sangle + py * cangle + abscentery;
|
||||
|
||||
/* Bottom Left */
|
||||
px = final_rect->x - abscenterx;
|
||||
py = final_rect->y + final_rect->h - abscentery;
|
||||
p3x = px * cangle - py * sangle + abscenterx;
|
||||
p3y = px * sangle + py * cangle + abscentery;
|
||||
|
||||
/* Bottom Right */
|
||||
px = final_rect->x + final_rect->w - abscenterx;
|
||||
py = final_rect->y + final_rect->h - abscentery;
|
||||
p4x = px * cangle - py * sangle + abscenterx;
|
||||
p4y = px * sangle + py * cangle + abscentery;
|
||||
|
||||
tmp_rect.x = (int)MIN(MIN(p1x, p2x), MIN(p3x, p4x));
|
||||
tmp_rect.y = (int)MIN(MIN(p1y, p2y), MIN(p3y, p4y));
|
||||
tmp_rect.w = dstwidth;
|
||||
tmp_rect.h = dstheight;
|
||||
tmp_rect.x = final_rect->x + rect_dest.x;
|
||||
tmp_rect.y = final_rect->y + rect_dest.y;
|
||||
tmp_rect.w = rect_dest.w;
|
||||
tmp_rect.h = rect_dest.h;
|
||||
|
||||
/* The NONE blend mode needs some special care with non-opaque surfaces.
|
||||
* Other blend modes or opaque surfaces can be blitted directly.
|
||||
@@ -471,7 +471,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
||||
SDL_SetSurfaceAlphaMod(src_rotated, alphaMod);
|
||||
SDL_SetSurfaceColorMod(src_rotated, rMod, gMod, bMod);
|
||||
}
|
||||
retval = SDL_BlitSurface(src_rotated, NULL, surface, &tmp_rect);
|
||||
/* Renderer scaling, if needed */
|
||||
retval = Blit_to_Screen(src_rotated, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode);
|
||||
} else {
|
||||
/* The NONE blend mode requires three steps to get the pixels onto the destination surface.
|
||||
* First, the area where the rotated pixels will be blitted to get set to zero.
|
||||
@@ -480,7 +481,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
||||
*/
|
||||
SDL_Rect mask_rect = tmp_rect;
|
||||
SDL_SetSurfaceBlendMode(mask_rotated, SDL_BLENDMODE_NONE);
|
||||
retval = SDL_BlitSurface(mask_rotated, NULL, surface, &mask_rect);
|
||||
/* Renderer scaling, if needed */
|
||||
retval = Blit_to_Screen(mask_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode);
|
||||
if (!retval) {
|
||||
/* The next step copies the alpha value. This is done with the BLEND blend mode and
|
||||
* by modulating the source colors with 0. Since the destination is all zeros, this
|
||||
@@ -488,7 +490,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
||||
*/
|
||||
SDL_SetSurfaceColorMod(src_rotated, 0, 0, 0);
|
||||
mask_rect = tmp_rect;
|
||||
retval = SDL_BlitSurface(src_rotated, NULL, surface, &mask_rect);
|
||||
/* Renderer scaling, if needed */
|
||||
retval = Blit_to_Screen(src_rotated, NULL, surface, &mask_rect, scale_x, scale_y, texture->scaleMode);
|
||||
if (!retval) {
|
||||
/* The last step gets the color values in place. The ADD blend mode simply adds them to
|
||||
* the destination (where the color values are all zero). However, because the ADD blend
|
||||
@@ -504,7 +507,8 @@ SW_RenderCopyEx(SDL_Renderer * renderer, SDL_Surface *surface, SDL_Texture * tex
|
||||
retval = -1;
|
||||
} else {
|
||||
SDL_SetSurfaceBlendMode(src_rotated_rgb, SDL_BLENDMODE_ADD);
|
||||
retval = SDL_BlitSurface(src_rotated_rgb, NULL, surface, &tmp_rect);
|
||||
/* Renderer scaling, if needed */
|
||||
retval = Blit_to_Screen(src_rotated_rgb, NULL, surface, &tmp_rect, scale_x, scale_y, texture->scaleMode);
|
||||
SDL_FreeSurface(src_rotated_rgb);
|
||||
}
|
||||
}
|
||||
@@ -545,7 +549,7 @@ typedef struct GeometryCopyData
|
||||
|
||||
static int
|
||||
SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
@@ -823,7 +827,42 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
* to avoid potentially frequent RLE encoding/decoding.
|
||||
*/
|
||||
SDL_SetSurfaceRLE(surface, 0);
|
||||
SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode);
|
||||
|
||||
/* Prevent to do scaling + clipping on viewport boundaries as it may lose proportion */
|
||||
if (dstrect->x < 0 || dstrect->y < 0 || dstrect->x + dstrect->w > surface->w || dstrect->y + dstrect->h > surface->h) {
|
||||
SDL_Surface *tmp = SDL_CreateRGBSurfaceWithFormat(0, dstrect->w, dstrect->h, 0, src->format->format);
|
||||
/* Scale to an intermediate surface, then blit */
|
||||
if (tmp) {
|
||||
SDL_Rect r;
|
||||
SDL_BlendMode blendmode;
|
||||
Uint8 alphaMod, rMod, gMod, bMod;
|
||||
|
||||
SDL_GetSurfaceBlendMode(src, &blendmode);
|
||||
SDL_GetSurfaceAlphaMod(src, &alphaMod);
|
||||
SDL_GetSurfaceColorMod(src, &rMod, &gMod, &bMod);
|
||||
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.w = dstrect->w;
|
||||
r.h = dstrect->h;
|
||||
|
||||
SDL_SetSurfaceBlendMode(src, SDL_BLENDMODE_NONE);
|
||||
SDL_SetSurfaceColorMod(src, 255, 255, 255);
|
||||
SDL_SetSurfaceAlphaMod(src, 255);
|
||||
|
||||
SDL_PrivateUpperBlitScaled(src, srcrect, tmp, &r, texture->scaleMode);
|
||||
|
||||
SDL_SetSurfaceColorMod(tmp, rMod, gMod, bMod);
|
||||
SDL_SetSurfaceAlphaMod(tmp, alphaMod);
|
||||
SDL_SetSurfaceBlendMode(tmp, blendmode);
|
||||
|
||||
SDL_BlitSurface(tmp, NULL, surface, dstrect);
|
||||
SDL_FreeSurface(tmp);
|
||||
/* No need to set back r/g/b/a/blendmode to 'src' since it's done in PrepTextureForCopy() */
|
||||
}
|
||||
} else{
|
||||
SDL_PrivateUpperBlitScaled(src, srcrect, surface, dstrect, texture->scaleMode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -840,7 +879,8 @@ SW_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertic
|
||||
}
|
||||
|
||||
SW_RenderCopyEx(renderer, surface, cmd->data.draw.texture, ©data->srcrect,
|
||||
©data->dstrect, copydata->angle, ©data->center, copydata->flip);
|
||||
©data->dstrect, copydata->angle, ©data->center, copydata->flip,
|
||||
copydata->scale_x, copydata->scale_y);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -977,7 +1017,7 @@ SW_CreateRendererForSurface(SDL_Surface * surface)
|
||||
SW_RenderData *data;
|
||||
|
||||
if (!surface) {
|
||||
SDL_SetError("Can't create renderer for NULL surface");
|
||||
SDL_InvalidParamError("surface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
235
externals/SDL/src/render/software/SDL_rotate.c
vendored
235
externals/SDL/src/render/software/SDL_rotate.c
vendored
@@ -61,11 +61,6 @@ typedef struct tColorY {
|
||||
Uint8 y;
|
||||
} tColorY;
|
||||
|
||||
/* !
|
||||
\brief Returns maximum of two numbers a and b.
|
||||
*/
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/* !
|
||||
\brief Number of guard rows added to destination surfaces.
|
||||
|
||||
@@ -82,7 +77,7 @@ to a situation where the program can segfault.
|
||||
\brief Returns colorkey info for a surface
|
||||
*/
|
||||
static Uint32
|
||||
_colorkey(SDL_Surface *src)
|
||||
get_colorkey(SDL_Surface *src)
|
||||
{
|
||||
Uint32 key = 0;
|
||||
if (SDL_HasColorKey(src)) {
|
||||
@@ -91,6 +86,18 @@ _colorkey(SDL_Surface *src)
|
||||
return key;
|
||||
}
|
||||
|
||||
/* rotate (sx, sy) by (angle, center) into (dx, dy) */
|
||||
static void
|
||||
rotate(double sx, double sy, double sinangle, double cosangle, const SDL_FPoint *center, double *dx, double *dy) {
|
||||
sx -= center->x;
|
||||
sy -= center->y;
|
||||
|
||||
*dx = cosangle * sx - sinangle * sy;
|
||||
*dy = sinangle * sx + cosangle * sy;
|
||||
|
||||
*dx += center->x;
|
||||
*dy += center->y;
|
||||
}
|
||||
|
||||
/* !
|
||||
\brief Internal target surface sizing function for rotations with trig result return.
|
||||
@@ -105,49 +112,61 @@ _colorkey(SDL_Surface *src)
|
||||
|
||||
*/
|
||||
void
|
||||
SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle,
|
||||
int *dstwidth, int *dstheight,
|
||||
double *cangle, double *sangle)
|
||||
SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center,
|
||||
SDL_Rect *rect_dest, double *cangle, double *sangle)
|
||||
{
|
||||
/* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
|
||||
int angle90 = (int)(angle/90);
|
||||
if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
|
||||
angle90 %= 4;
|
||||
if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
|
||||
if(angle90 & 1) {
|
||||
*dstwidth = height;
|
||||
*dstheight = width;
|
||||
*cangle = 0;
|
||||
*sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
|
||||
} else {
|
||||
*dstwidth = width;
|
||||
*dstheight = height;
|
||||
*cangle = angle90 == 0 ? 1 : -1;
|
||||
*sangle = 0;
|
||||
}
|
||||
} else {
|
||||
double x, y, cx, cy, sx, sy;
|
||||
double radangle;
|
||||
int dstwidthhalf, dstheighthalf;
|
||||
/*
|
||||
* Determine destination width and height by rotating a centered source box
|
||||
*/
|
||||
radangle = angle * (M_PI / -180.0); /* reverse the angle because our rotations are clockwise */
|
||||
*sangle = SDL_sin(radangle);
|
||||
*cangle = SDL_cos(radangle);
|
||||
x = (double)(width / 2);
|
||||
y = (double)(height / 2);
|
||||
cx = *cangle * x;
|
||||
cy = *cangle * y;
|
||||
sx = *sangle * x;
|
||||
sy = *sangle * y;
|
||||
int minx, maxx, miny, maxy;
|
||||
double radangle;
|
||||
double x0, x1, x2, x3;
|
||||
double y0, y1, y2, y3;
|
||||
double sinangle;
|
||||
double cosangle;
|
||||
|
||||
dstwidthhalf = MAX((int)
|
||||
SDL_ceil(MAX(MAX(MAX(SDL_fabs(cx + sy), SDL_fabs(cx - sy)), SDL_fabs(-cx + sy)), SDL_fabs(-cx - sy))), 1);
|
||||
dstheighthalf = MAX((int)
|
||||
SDL_ceil(MAX(MAX(MAX(SDL_fabs(sx + cy), SDL_fabs(sx - cy)), SDL_fabs(-sx + cy)), SDL_fabs(-sx - cy))), 1);
|
||||
*dstwidth = 2 * dstwidthhalf;
|
||||
*dstheight = 2 * dstheighthalf;
|
||||
radangle = angle * (M_PI / 180.0);
|
||||
sinangle = SDL_sin(radangle);
|
||||
cosangle = SDL_cos(radangle);
|
||||
|
||||
/*
|
||||
* Determine destination width and height by rotating a source box, at pixel center
|
||||
*/
|
||||
rotate(0.5, 0.5, sinangle, cosangle, center, &x0, &y0);
|
||||
rotate(width - 0.5, 0.5, sinangle, cosangle, center, &x1, &y1);
|
||||
rotate(0.5, height - 0.5, sinangle, cosangle, center, &x2, &y2);
|
||||
rotate(width - 0.5, height - 0.5, sinangle, cosangle, center, &x3, &y3);
|
||||
|
||||
minx = (int)SDL_floor( SDL_min( SDL_min(x0, x1), SDL_min(x2, x3) ) );
|
||||
maxx = (int)SDL_ceil( SDL_max( SDL_max(x0, x1), SDL_max(x2, x3) ) );
|
||||
|
||||
miny = (int)SDL_floor( SDL_min( SDL_min(y0, y1), SDL_min(y2, y3) ) );
|
||||
maxy = (int)SDL_ceil( SDL_max( SDL_max(y0, y1), SDL_max(y2, y3) ) );
|
||||
|
||||
rect_dest->w = maxx - minx;
|
||||
rect_dest->h = maxy - miny;
|
||||
rect_dest->x = minx;
|
||||
rect_dest->y = miny;
|
||||
|
||||
/* reverse the angle because our rotations are clockwise */
|
||||
*sangle = -sinangle;
|
||||
*cangle = cosangle;
|
||||
|
||||
{
|
||||
/* The trig code below gets the wrong size (due to FP inaccuracy?) when angle is a multiple of 90 degrees */
|
||||
int angle90 = (int)(angle/90);
|
||||
if(angle90 == angle/90) { /* if the angle is a multiple of 90 degrees */
|
||||
angle90 %= 4;
|
||||
if(angle90 < 0) angle90 += 4; /* 0:0 deg, 1:90 deg, 2:180 deg, 3:270 deg */
|
||||
if(angle90 & 1) {
|
||||
rect_dest->w = height;
|
||||
rect_dest->h = width;
|
||||
*cangle = 0;
|
||||
*sangle = angle90 == 1 ? -1 : 1; /* reversed because our rotations are clockwise */
|
||||
} else {
|
||||
rect_dest->w = width;
|
||||
rect_dest->h = height;
|
||||
*cangle = angle90 == 0 ? 1 : -1;
|
||||
*sangle = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,48 +239,56 @@ Assumes dst surface was allocated with the correct dimensions.
|
||||
|
||||
\param src Source surface.
|
||||
\param dst Destination surface.
|
||||
\param cx Horizontal center coordinate.
|
||||
\param cy Vertical center coordinate.
|
||||
\param isin Integer version of sine of angle.
|
||||
\param icos Integer version of cosine of angle.
|
||||
\param flipx Flag indicating horizontal mirroring should be applied.
|
||||
\param flipy Flag indicating vertical mirroring should be applied.
|
||||
\param smooth Flag indicating anti-aliasing should be used.
|
||||
\param dst_rect destination coordinates
|
||||
\param center true center.
|
||||
*/
|
||||
static void
|
||||
_transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy, int smooth)
|
||||
transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int isin, int icos,
|
||||
int flipx, int flipy, int smooth,
|
||||
const SDL_Rect *rect_dest,
|
||||
const SDL_FPoint *center)
|
||||
{
|
||||
int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh;
|
||||
int sw, sh;
|
||||
int cx, cy;
|
||||
tColorRGBA c00, c01, c10, c11, cswap;
|
||||
tColorRGBA *pc, *sp;
|
||||
int gap;
|
||||
const int fp_half = (1<<15);
|
||||
|
||||
/*
|
||||
* Variable setup
|
||||
*/
|
||||
xd = ((src->w - dst->w) << 15);
|
||||
yd = ((src->h - dst->h) << 15);
|
||||
ax = (cx << 16) - (icos * cx);
|
||||
ay = (cy << 16) - (isin * cx);
|
||||
sw = src->w - 1;
|
||||
sh = src->h - 1;
|
||||
pc = (tColorRGBA*) dst->pixels;
|
||||
gap = dst->pitch - dst->w * 4;
|
||||
cx = (int)(center->x * 65536.0);
|
||||
cy = (int)(center->y * 65536.0);
|
||||
|
||||
/*
|
||||
* Switch between interpolating and non-interpolating code
|
||||
*/
|
||||
if (smooth) {
|
||||
int y;
|
||||
for (y = 0; y < dst->h; y++) {
|
||||
dy = cy - y;
|
||||
sdx = (ax + (isin * dy)) + xd;
|
||||
sdy = (ay - (icos * dy)) + yd;
|
||||
int x;
|
||||
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
|
||||
double src_y = (rect_dest->y + y + 0.5 - center->y);
|
||||
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
|
||||
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
|
||||
for (x = 0; x < dst->w; x++) {
|
||||
dx = (sdx >> 16);
|
||||
dy = (sdy >> 16);
|
||||
int dx = (sdx >> 16);
|
||||
int dy = (sdy >> 16);
|
||||
if (flipx) dx = sw - dx;
|
||||
if (flipy) dy = sh - dy;
|
||||
if ((dx > -1) && (dy > -1) && (dx < (src->w-1)) && (dy < (src->h-1))) {
|
||||
int ex, ey;
|
||||
int t1, t2;
|
||||
sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy) + dx;
|
||||
c00 = *sp;
|
||||
sp += 1;
|
||||
@@ -303,13 +330,16 @@ _transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int
|
||||
pc = (tColorRGBA *) ((Uint8 *) pc + gap);
|
||||
}
|
||||
} else {
|
||||
int y;
|
||||
for (y = 0; y < dst->h; y++) {
|
||||
dy = cy - y;
|
||||
sdx = (ax + (isin * dy)) + xd;
|
||||
sdy = (ay - (icos * dy)) + yd;
|
||||
int x;
|
||||
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
|
||||
double src_y = (rect_dest->y + y + 0.5 - center->y);
|
||||
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
|
||||
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
|
||||
for (x = 0; x < dst->w; x++) {
|
||||
dx = (sdx >> 16);
|
||||
dy = (sdy >> 16);
|
||||
int dx = (sdx >> 16);
|
||||
int dy = (sdy >> 16);
|
||||
if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
|
||||
if(flipx) dx = sw - dx;
|
||||
if(flipy) dy = sh - dy;
|
||||
@@ -335,46 +365,54 @@ Assumes dst surface was allocated with the correct dimensions.
|
||||
|
||||
\param src Source surface.
|
||||
\param dst Destination surface.
|
||||
\param cx Horizontal center coordinate.
|
||||
\param cy Vertical center coordinate.
|
||||
\param isin Integer version of sine of angle.
|
||||
\param icos Integer version of cosine of angle.
|
||||
\param flipx Flag indicating horizontal mirroring should be applied.
|
||||
\param flipy Flag indicating vertical mirroring should be applied.
|
||||
\param dst_rect destination coordinates
|
||||
\param center true center.
|
||||
*/
|
||||
static void
|
||||
transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int flipx, int flipy)
|
||||
transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int isin, int icos, int flipx, int flipy,
|
||||
const SDL_Rect *rect_dest,
|
||||
const SDL_FPoint *center)
|
||||
{
|
||||
int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay;
|
||||
int sw, sh;
|
||||
int cx, cy;
|
||||
tColorY *pc;
|
||||
int gap;
|
||||
const int fp_half = (1<<15);
|
||||
int y;
|
||||
|
||||
/*
|
||||
* Variable setup
|
||||
*/
|
||||
xd = ((src->w - dst->w) << 15);
|
||||
yd = ((src->h - dst->h) << 15);
|
||||
ax = (cx << 16) - (icos * cx);
|
||||
ay = (cy << 16) - (isin * cx);
|
||||
sw = src->w - 1;
|
||||
sh = src->h - 1;
|
||||
pc = (tColorY*) dst->pixels;
|
||||
gap = dst->pitch - dst->w;
|
||||
cx = (int)(center->x * 65536.0);
|
||||
cy = (int)(center->y * 65536.0);
|
||||
|
||||
/*
|
||||
* Clear surface to colorkey
|
||||
*/
|
||||
SDL_memset(pc, (int)(_colorkey(src) & 0xff), dst->pitch * dst->h);
|
||||
SDL_memset(pc, (int)(get_colorkey(src) & 0xff), dst->pitch * dst->h);
|
||||
/*
|
||||
* Iterate through destination surface
|
||||
*/
|
||||
for (y = 0; y < dst->h; y++) {
|
||||
dy = cy - y;
|
||||
sdx = (ax + (isin * dy)) + xd;
|
||||
sdy = (ay - (icos * dy)) + yd;
|
||||
int x;
|
||||
double src_x = (rect_dest->x + 0 + 0.5 - center->x);
|
||||
double src_y = (rect_dest->y + y + 0.5 - center->y);
|
||||
int sdx = (int)((icos * src_x - isin * src_y) + cx - fp_half);
|
||||
int sdy = (int)((isin * src_x + icos * src_y) + cy - fp_half);
|
||||
for (x = 0; x < dst->w; x++) {
|
||||
dx = (sdx >> 16);
|
||||
dy = (sdy >> 16);
|
||||
int dx = (sdx >> 16);
|
||||
int dy = (sdy >> 16);
|
||||
if ((unsigned)dx < (unsigned)src->w && (unsigned)dy < (unsigned)src->h) {
|
||||
if (flipx) dx = (src->w-1)-dx;
|
||||
if (flipy) dy = (src->h-1)-dy;
|
||||
if (flipx) dx = sw - dx;
|
||||
if (flipy) dy = sh- dy;
|
||||
*pc = *((tColorY *)src->pixels + src->pitch * dy + dx);
|
||||
}
|
||||
sdx += icos;
|
||||
@@ -390,7 +428,7 @@ transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin
|
||||
\brief Rotates and zooms a surface with different horizontal and vertival scaling factors and optional anti-aliasing.
|
||||
|
||||
Rotates a 32-bit or 8-bit 'src' surface to newly created 'dst' surface.
|
||||
'angle' is the rotation in degrees, 'centerx' and 'centery' the rotation center. If 'smooth' is set
|
||||
'angle' is the rotation in degrees, 'center' the rotation center. If 'smooth' is set
|
||||
then the destination 32-bit surface is anti-aliased. 8-bit surfaces must have a colorkey. 32-bit
|
||||
surfaces must have a 8888 layout with red, green, blue and alpha masks (any ordering goes).
|
||||
The blend mode of the 'src' surface has some effects on generation of the 'dst' surface: The NONE
|
||||
@@ -400,21 +438,21 @@ When using the NONE and MOD modes, color and alpha modulation must be applied be
|
||||
|
||||
\param src The surface to rotozoom.
|
||||
\param angle The angle to rotate in degrees.
|
||||
\param centerx The horizontal coordinate of the center of rotation
|
||||
\param zoomy The vertical coordinate of the center of rotation
|
||||
\param smooth Antialiasing flag; set to SMOOTHING_ON to enable.
|
||||
\param flipx Set to 1 to flip the image horizontally
|
||||
\param flipy Set to 1 to flip the image vertically
|
||||
\param dstwidth The destination surface width
|
||||
\param dstheight The destination surface height
|
||||
\param rect_dest The destination rect bounding box
|
||||
\param cangle The angle cosine
|
||||
\param sangle The angle sine
|
||||
\param center The true coordinate of the center of rotation
|
||||
\return The new rotated surface.
|
||||
|
||||
*/
|
||||
|
||||
SDL_Surface *
|
||||
SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle)
|
||||
SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy,
|
||||
const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center)
|
||||
{
|
||||
SDL_Surface *rz_dst;
|
||||
int is8bit, angle90;
|
||||
@@ -433,7 +471,6 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
colorKeyAvailable = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function requires a 32-bit surface or 8-bit surface with a colorkey */
|
||||
is8bit = src->format->BitsPerPixel == 8 && colorKeyAvailable;
|
||||
if (!(is8bit || (src->format->BitsPerPixel == 32 && src->format->Amask)))
|
||||
@@ -447,16 +484,18 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
rz_dst = NULL;
|
||||
if (is8bit) {
|
||||
/* Target surface is 8 bit */
|
||||
rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 8, 0, 0, 0, 0);
|
||||
rz_dst = SDL_CreateRGBSurfaceWithFormat(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 8, src->format->format);
|
||||
if (rz_dst != NULL) {
|
||||
for (i = 0; i < src->format->palette->ncolors; i++) {
|
||||
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
|
||||
if (src->format->palette) {
|
||||
for (i = 0; i < src->format->palette->ncolors; i++) {
|
||||
rz_dst->format->palette->colors[i] = src->format->palette->colors[i];
|
||||
}
|
||||
rz_dst->format->palette->ncolors = src->format->palette->ncolors;
|
||||
}
|
||||
rz_dst->format->palette->ncolors = src->format->palette->ncolors;
|
||||
}
|
||||
} else {
|
||||
/* Target surface is 32 bit with source RGBA ordering */
|
||||
rz_dst = SDL_CreateRGBSurface(0, dstwidth, dstheight + GUARD_ROWS, 32,
|
||||
rz_dst = SDL_CreateRGBSurface(0, rect_dest->w, rect_dest->h + GUARD_ROWS, 32,
|
||||
src->format->Rmask, src->format->Gmask,
|
||||
src->format->Bmask, src->format->Amask);
|
||||
}
|
||||
@@ -466,7 +505,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
return NULL;
|
||||
|
||||
/* Adjust for guard rows */
|
||||
rz_dst->h = dstheight;
|
||||
rz_dst->h = rect_dest->h;
|
||||
|
||||
SDL_GetSurfaceBlendMode(src, &blendmode);
|
||||
|
||||
@@ -497,7 +536,7 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
}
|
||||
|
||||
/* check if the rotation is a multiple of 90 degrees so we can take a fast path and also somewhat reduce
|
||||
* the off-by-one problem in _transformSurfaceRGBA that expresses itself when the rotation is near
|
||||
* the off-by-one problem in transformSurfaceRGBA that expresses itself when the rotation is near
|
||||
* multiples of 90 degrees.
|
||||
*/
|
||||
angle90 = (int)(angle/90);
|
||||
@@ -513,16 +552,16 @@ SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery,
|
||||
if(angle90 >= 0) {
|
||||
transformSurfaceY90(src, rz_dst, angle90, flipx, flipy);
|
||||
} else {
|
||||
transformSurfaceY(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
|
||||
flipx, flipy);
|
||||
transformSurfaceY(src, rz_dst, (int)sangleinv, (int)cangleinv,
|
||||
flipx, flipy, rect_dest, center);
|
||||
}
|
||||
} else {
|
||||
/* Call the 32-bit transformation routine to do the rotation */
|
||||
if (angle90 >= 0) {
|
||||
transformSurfaceRGBA90(src, rz_dst, angle90, flipx, flipy);
|
||||
} else {
|
||||
_transformSurfaceRGBA(src, rz_dst, centerx, centery, (int)sangleinv, (int)cangleinv,
|
||||
flipx, flipy, smooth);
|
||||
transformSurfaceRGBA(src, rz_dst, (int)sangleinv, (int)cangleinv,
|
||||
flipx, flipy, smooth, rect_dest, center);
|
||||
}
|
||||
}
|
||||
|
||||
|
12
externals/SDL/src/render/software/SDL_rotate.h
vendored
12
externals/SDL/src/render/software/SDL_rotate.h
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -22,11 +22,9 @@
|
||||
#ifndef SDL_rotate_h_
|
||||
#define SDL_rotate_h_
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int centerx, int centery, int smooth, int flipx, int flipy, int dstwidth, int dstheight, double cangle, double sangle);
|
||||
extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, int *dstwidth, int *dstheight, double *cangle, double *sangle);
|
||||
extern SDL_Surface *SDLgfx_rotateSurface(SDL_Surface * src, double angle, int smooth, int flipx, int flipy,
|
||||
const SDL_Rect *rect_dest, double cangle, double sangle, const SDL_FPoint *center);
|
||||
extern void SDLgfx_rotozoomSurfaceSizeTrig(int width, int height, double angle, const SDL_FPoint *center,
|
||||
SDL_Rect *rect_dest, double *cangle, double *sangle);
|
||||
|
||||
#endif /* SDL_rotate_h_ */
|
||||
|
102
externals/SDL/src/render/software/SDL_triangle.c
vendored
102
externals/SDL/src/render/software/SDL_triangle.c
vendored
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -119,8 +119,8 @@ void trianglepoint_2_fixedpoint(SDL_Point *a) {
|
||||
a->y <<= FP_BITS;
|
||||
}
|
||||
|
||||
/* bounding rect of three points */
|
||||
static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r)
|
||||
/* bounding rect of three points (in fixed point) */
|
||||
static void bounding_rect_fixedpoint(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r)
|
||||
{
|
||||
int min_x = SDL_min(a->x, SDL_min(b->x, c->x));
|
||||
int max_x = SDL_max(a->x, SDL_max(b->x, c->x));
|
||||
@@ -133,6 +133,20 @@ static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Poin
|
||||
r->h = (max_y - min_y) >> FP_BITS;
|
||||
}
|
||||
|
||||
/* bounding rect of three points */
|
||||
static void bounding_rect(const SDL_Point *a, const SDL_Point *b, const SDL_Point *c, SDL_Rect *r)
|
||||
{
|
||||
int min_x = SDL_min(a->x, SDL_min(b->x, c->x));
|
||||
int max_x = SDL_max(a->x, SDL_max(b->x, c->x));
|
||||
int min_y = SDL_min(a->y, SDL_min(b->y, c->y));
|
||||
int max_y = SDL_max(a->y, SDL_max(b->y, c->y));
|
||||
r->x = min_x;
|
||||
r->y = min_y;
|
||||
r->w = (max_x - min_x);
|
||||
r->h = (max_y - min_y);
|
||||
}
|
||||
|
||||
|
||||
/* Triangle rendering, using Barycentric coordinates (w0, w1, w2)
|
||||
*
|
||||
* The cross product isn't computed from scratch at each iteration,
|
||||
@@ -232,7 +246,7 @@ int SDL_SW_FillTriangle(SDL_Surface *dst, SDL_Point *d0, SDL_Point *d1, SDL_Poin
|
||||
}
|
||||
}
|
||||
|
||||
bounding_rect(d0, d1, d2, &dstrect);
|
||||
bounding_rect_fixedpoint(d0, d1, d2, &dstrect);
|
||||
|
||||
{
|
||||
/* Clip triangle rect with surface rect */
|
||||
@@ -438,7 +452,6 @@ int SDL_SW_BlitTriangle(
|
||||
|
||||
SDL_BlendMode blend;
|
||||
|
||||
SDL_Rect srcrect;
|
||||
SDL_Rect dstrect;
|
||||
|
||||
SDL_Point s2_x_area;
|
||||
@@ -495,11 +508,29 @@ int SDL_SW_BlitTriangle(
|
||||
|
||||
is_uniform = COLOR_EQ(c0, c1) && COLOR_EQ(c1, c2);
|
||||
|
||||
bounding_rect(s0, s1, s2, &srcrect);
|
||||
bounding_rect(d0, d1, d2, &dstrect);
|
||||
bounding_rect_fixedpoint(d0, d1, d2, &dstrect);
|
||||
|
||||
SDL_GetSurfaceBlendMode(src, &blend);
|
||||
|
||||
/* TRIANGLE_GET_TEXTCOORD interpolates up to the max values included, so reduce by 1 */
|
||||
{
|
||||
SDL_Rect srcrect;
|
||||
int maxx, maxy;
|
||||
bounding_rect(s0, s1, s2, &srcrect);
|
||||
maxx = srcrect.x + srcrect.w;
|
||||
maxy = srcrect.y + srcrect.h;
|
||||
if (srcrect.w > 0) {
|
||||
if (s0->x == maxx) s0->x--;
|
||||
if (s1->x == maxx) s1->x--;
|
||||
if (s2->x == maxx) s2->x--;
|
||||
}
|
||||
if (srcrect.h > 0) {
|
||||
if (s0->y == maxy) s0->y--;
|
||||
if (s1->y == maxy) s1->y--;
|
||||
if (s2->y == maxy) s2->y--;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_uniform) {
|
||||
// SDL_GetSurfaceColorMod(src, &r, &g, &b);
|
||||
has_modulation = c0.r != 255 || c0.g != 255 || c0.b != 255 || c0.a != 255;;
|
||||
@@ -687,6 +718,21 @@ end:
|
||||
}
|
||||
|
||||
|
||||
#define FORMAT_ALPHA 0
|
||||
#define FORMAT_NO_ALPHA -1
|
||||
#define FORMAT_2101010 1
|
||||
#define FORMAT_HAS_ALPHA(format) format == 0
|
||||
#define FORMAT_HAS_NO_ALPHA(format) format < 0
|
||||
static int SDL_INLINE detect_format(SDL_PixelFormat *pf) {
|
||||
if (pf->format == SDL_PIXELFORMAT_ARGB2101010) {
|
||||
return FORMAT_2101010;
|
||||
} else if (pf->Amask) {
|
||||
return FORMAT_ALPHA;
|
||||
} else {
|
||||
return FORMAT_NO_ALPHA;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
||||
SDL_Point s2_x_area, SDL_Rect dstrect, int area, int bias_w0, int bias_w1, int bias_w2,
|
||||
@@ -707,25 +753,32 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
||||
SDL_PixelFormat *dst_fmt = info->dst_fmt;
|
||||
int srcbpp = src_fmt->BytesPerPixel;
|
||||
int dstbpp = dst_fmt->BytesPerPixel;
|
||||
int srcfmt_val;
|
||||
int dstfmt_val;
|
||||
Uint32 rgbmask = ~src_fmt->Amask;
|
||||
Uint32 ckey = info->colorkey & rgbmask;
|
||||
|
||||
Uint8 *dst_ptr = info->dst;
|
||||
int dst_pitch = info->dst_pitch;;
|
||||
|
||||
srcfmt_val = detect_format(src_fmt);
|
||||
dstfmt_val = detect_format(dst_fmt);
|
||||
|
||||
TRIANGLE_BEGIN_LOOP
|
||||
{
|
||||
Uint8 *src;
|
||||
Uint8 *dst = dptr;
|
||||
TRIANGLE_GET_TEXTCOORD
|
||||
src = (info->src + (srcy * info->src_pitch) + (srcx * srcbpp));
|
||||
if (src_fmt->Amask) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB, srcA);
|
||||
} else {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG,
|
||||
srcB);
|
||||
if (FORMAT_HAS_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGBA(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB, srcA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(srcfmt_val)) {
|
||||
DISEMBLE_RGB(src, srcbpp, src_fmt, srcpixel, srcR, srcG, srcB);
|
||||
srcA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
srcpixel = *((Uint32 *)(src));
|
||||
RGBA_FROM_ARGB2101010(srcpixel, srcR, srcG, srcB, srcA);
|
||||
}
|
||||
if (flags & SDL_COPY_COLORKEY) {
|
||||
/* srcpixel isn't set for 24 bpp */
|
||||
@@ -737,13 +790,15 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB, dstA);
|
||||
} else {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG,
|
||||
dstB);
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGBA(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB, dstA);
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
DISEMBLE_RGB(dst, dstbpp, dst_fmt, dstpixel, dstR, dstG, dstB);
|
||||
dstA = 0xFF;
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
dstpixel = *((Uint32 *)(dst));
|
||||
RGBA_FROM_ARGB2101010(dstpixel, dstR, dstG, dstB, dstA);
|
||||
}
|
||||
|
||||
if (! is_uniform) {
|
||||
@@ -814,10 +869,15 @@ SDL_BlitTriangle_Slow(SDL_BlitInfo *info,
|
||||
dstA = 255;
|
||||
break;
|
||||
}
|
||||
if (dst_fmt->Amask) {
|
||||
if (FORMAT_HAS_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGBA(dst, dstbpp, dst_fmt, dstR, dstG, dstB, dstA);
|
||||
} else {
|
||||
} else if (FORMAT_HAS_NO_ALPHA(dstfmt_val)) {
|
||||
ASSEMBLE_RGB(dst, dstbpp, dst_fmt, dstR, dstG, dstB);
|
||||
} else {
|
||||
/* SDL_PIXELFORMAT_ARGB2101010 */
|
||||
Uint32 pixel;
|
||||
ARGB2101010_FROM_RGBA(pixel, dstR, dstG, dstB, dstA);
|
||||
*(Uint32 *)dst = pixel;
|
||||
}
|
||||
}
|
||||
TRIANGLE_END_LOOP
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -61,6 +61,11 @@ static int VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * text
|
||||
const Uint8 *Uplane, int Upitch,
|
||||
const Uint8 *Vplane, int Vpitch);
|
||||
|
||||
static int VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect,
|
||||
const Uint8 *Yplane, int Ypitch,
|
||||
const Uint8 *UVplane, int UVpitch);
|
||||
|
||||
static int VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, void **pixels, int *pitch);
|
||||
|
||||
@@ -83,7 +88,7 @@ static int VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *c
|
||||
|
||||
static int
|
||||
VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y);
|
||||
|
||||
@@ -105,12 +110,16 @@ SDL_RenderDriver VITA_GXM_RenderDriver = {
|
||||
.info = {
|
||||
.name = "VITA gxm",
|
||||
.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE,
|
||||
.num_texture_formats = 4,
|
||||
.num_texture_formats = 8,
|
||||
.texture_formats = {
|
||||
[0] = SDL_PIXELFORMAT_ABGR8888,
|
||||
[1] = SDL_PIXELFORMAT_ARGB8888,
|
||||
[2] = SDL_PIXELFORMAT_RGB565,
|
||||
[3] = SDL_PIXELFORMAT_BGR565
|
||||
[3] = SDL_PIXELFORMAT_BGR565,
|
||||
[4] = SDL_PIXELFORMAT_YV12,
|
||||
[5] = SDL_PIXELFORMAT_IYUV,
|
||||
[6] = SDL_PIXELFORMAT_NV12,
|
||||
[7] = SDL_PIXELFORMAT_NV21,
|
||||
},
|
||||
.max_texture_width = 4096,
|
||||
.max_texture_height = 4096,
|
||||
@@ -133,6 +142,15 @@ PixelFormatToVITAFMT(Uint32 format)
|
||||
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_RGB;
|
||||
case SDL_PIXELFORMAT_BGR565:
|
||||
return SCE_GXM_TEXTURE_FORMAT_U5U6U5_BGR;
|
||||
case SDL_PIXELFORMAT_YV12:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YVU420P3_CSC0;
|
||||
case SDL_PIXELFORMAT_IYUV:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YUV420P3_CSC0;
|
||||
// should be the other way around. looks like SCE bug.
|
||||
case SDL_PIXELFORMAT_NV12:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YVU420P2_CSC0;
|
||||
case SDL_PIXELFORMAT_NV21:
|
||||
return SCE_GXM_TEXTURE_FORMAT_YUV420P2_CSC0;
|
||||
default:
|
||||
return SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ABGR;
|
||||
}
|
||||
@@ -217,7 +235,7 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
|
||||
data = (VITA_GXM_RenderData *) SDL_calloc(1, sizeof(VITA_GXM_RenderData));
|
||||
if (!data) {
|
||||
VITA_GXM_DestroyRenderer(renderer);
|
||||
SDL_free(renderer);
|
||||
SDL_OutOfMemory();
|
||||
return NULL;
|
||||
}
|
||||
@@ -226,7 +244,10 @@ VITA_GXM_CreateRenderer(SDL_Window *window, Uint32 flags)
|
||||
renderer->SupportsBlendMode = VITA_GXM_SupportsBlendMode;
|
||||
renderer->CreateTexture = VITA_GXM_CreateTexture;
|
||||
renderer->UpdateTexture = VITA_GXM_UpdateTexture;
|
||||
#if SDL_HAVE_YUV
|
||||
renderer->UpdateTextureYUV = VITA_GXM_UpdateTextureYUV;
|
||||
renderer->UpdateTextureNV = VITA_GXM_UpdateTextureNV;
|
||||
#endif
|
||||
renderer->LockTexture = VITA_GXM_LockTexture;
|
||||
renderer->UnlockTexture = VITA_GXM_UnlockTexture;
|
||||
renderer->SetTextureScaleMode = VITA_GXM_SetTextureScaleMode;
|
||||
@@ -293,7 +314,17 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
|
||||
vita_texture->tex = create_gxm_texture(data, texture->w, texture->h, PixelFormatToVITAFMT(texture->format), (texture->access == SDL_TEXTUREACCESS_TARGET));
|
||||
vita_texture->tex = create_gxm_texture(
|
||||
data,
|
||||
texture->w,
|
||||
texture->h,
|
||||
PixelFormatToVITAFMT(texture->format),
|
||||
(texture->access == SDL_TEXTUREACCESS_TARGET),
|
||||
&(vita_texture->w),
|
||||
&(vita_texture->h),
|
||||
&(vita_texture->pitch),
|
||||
&(vita_texture->wscale)
|
||||
);
|
||||
|
||||
if (!vita_texture->tex) {
|
||||
SDL_free(vita_texture);
|
||||
@@ -304,38 +335,129 @@ VITA_GXM_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
|
||||
VITA_GXM_SetTextureScaleMode(renderer, texture, texture->scaleMode);
|
||||
|
||||
vita_texture->w = gxm_texture_get_width(vita_texture->tex);
|
||||
vita_texture->h = gxm_texture_get_height(vita_texture->tex);
|
||||
vita_texture->pitch = gxm_texture_get_stride(vita_texture->tex);
|
||||
#if SDL_HAVE_YUV
|
||||
vita_texture->yuv = ((texture->format == SDL_PIXELFORMAT_IYUV) || (texture->format == SDL_PIXELFORMAT_YV12));
|
||||
vita_texture->nv12 = ((texture->format == SDL_PIXELFORMAT_NV12) || (texture->format == SDL_PIXELFORMAT_NV21));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void VITA_GXM_SetYUVProfile(SDL_Renderer * renderer, SDL_Texture *texture)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
int ret = 0;
|
||||
switch (SDL_GetYUVConversionModeForResolution(texture->w, texture->h)) {
|
||||
case SDL_YUV_CONVERSION_BT601:
|
||||
ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT601_STANDARD);
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_BT709:
|
||||
ret = sceGxmSetYuvProfile(data->gxm_context, 0, SCE_GXM_YUV_PROFILE_BT709_STANDARD);
|
||||
break;
|
||||
case SDL_YUV_CONVERSION_JPEG:
|
||||
default:
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Unsupported YUV profile: %d\n", SDL_GetYUVConversionModeForResolution(texture->w, texture->h));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Setting YUV profile failed: %x\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, const void *pixels, int pitch)
|
||||
{
|
||||
const Uint8 *src;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
Uint8 *dst;
|
||||
int row, length,dpitch;
|
||||
src = pixels;
|
||||
int row, length, dpitch;
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (vita_texture->yuv || vita_texture->nv12) {
|
||||
VITA_GXM_SetYUVProfile(renderer, texture);
|
||||
}
|
||||
#endif
|
||||
|
||||
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
if (length == pitch && length == dpitch) {
|
||||
SDL_memcpy(dst, src, length*rect->h);
|
||||
SDL_memcpy(dst, pixels, length*rect->h);
|
||||
} else {
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, src, length);
|
||||
src += pitch;
|
||||
SDL_memcpy(dst, pixels, length);
|
||||
pixels += pitch;
|
||||
dst += dpitch;
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
if (vita_texture->yuv) {
|
||||
void *Udst;
|
||||
void *Vdst;
|
||||
int uv_pitch = (dpitch+1) / 2;
|
||||
int uv_src_pitch = (pitch+1) / 2;
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
|
||||
|
||||
// skip Y plane
|
||||
Uint8 *Dpixels = gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h);
|
||||
|
||||
Udst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
Vdst = Dpixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
|
||||
length = UVrect.w;
|
||||
|
||||
// U plane
|
||||
if (length == uv_src_pitch && length == uv_pitch) {
|
||||
SDL_memcpy(Udst, pixels, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Udst, pixels, length);
|
||||
pixels += uv_src_pitch;
|
||||
Udst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// V plane
|
||||
if (length == uv_src_pitch && length == uv_pitch) {
|
||||
SDL_memcpy(Vdst, pixels, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Vdst, pixels, length);
|
||||
pixels += uv_src_pitch;
|
||||
Vdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (vita_texture->nv12) {
|
||||
void *UVdst;
|
||||
int uv_pitch = 2 * ((dpitch+1) / 2);
|
||||
int uv_src_pitch = 2 * ((pitch+1) / 2);
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2 , (rect->h + 1) / 2};
|
||||
|
||||
// skip Y plane
|
||||
void *Dpixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
|
||||
UVdst = Dpixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
|
||||
length = UVrect.w*2;
|
||||
|
||||
// UV plane
|
||||
if (length == uv_src_pitch && length == uv_pitch) {
|
||||
SDL_memcpy(UVdst, pixels, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(UVdst, pixels, length);
|
||||
pixels += uv_src_pitch;
|
||||
UVdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if SDL_HAVE_YUV
|
||||
static int
|
||||
VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect,
|
||||
@@ -343,9 +465,133 @@ VITA_GXM_UpdateTextureYUV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const Uint8 *Uplane, int Upitch,
|
||||
const Uint8 *Vplane, int Vpitch)
|
||||
{
|
||||
Uint8 *dst;
|
||||
int row, length, dpitch;
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
|
||||
|
||||
VITA_GXM_SetYUVProfile(renderer, texture);
|
||||
|
||||
// copy Y plane
|
||||
// obtain pixels via locking so that texture is flushed
|
||||
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||
|
||||
length = rect->w;
|
||||
|
||||
if (length == Ypitch && length == dpitch) {
|
||||
SDL_memcpy(dst, Yplane, length*rect->h);
|
||||
} else {
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, Yplane, length);
|
||||
Yplane += Ypitch;
|
||||
dst += dpitch;
|
||||
}
|
||||
}
|
||||
|
||||
// U/V planes
|
||||
{
|
||||
void *Udst;
|
||||
void *Vdst;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
int uv_pitch = (dpitch+1) / 2;
|
||||
|
||||
// skip Y plane
|
||||
void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
|
||||
|
||||
if (texture->format == SDL_PIXELFORMAT_YV12) { // YVU
|
||||
Vdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
Udst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
} else { // YUV
|
||||
Udst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
Vdst = pixels + (uv_pitch * ((vita_texture->h + 1) / 2)) + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
}
|
||||
|
||||
length = UVrect.w;
|
||||
|
||||
// U plane
|
||||
if (length == Upitch && length == uv_pitch) {
|
||||
SDL_memcpy(Udst, Uplane, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Udst, Uplane, length);
|
||||
Uplane += Upitch;
|
||||
Udst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
// V plane
|
||||
if (length == Vpitch && length == uv_pitch) {
|
||||
SDL_memcpy(Vdst, Vplane, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(Vdst, Vplane, length);
|
||||
Vplane += Vpitch;
|
||||
Vdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_UpdateTextureNV(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||
const SDL_Rect * rect,
|
||||
const Uint8 *Yplane, int Ypitch,
|
||||
const Uint8 *UVplane, int UVpitch)
|
||||
{
|
||||
|
||||
Uint8 *dst;
|
||||
int row, length, dpitch;
|
||||
SDL_Rect UVrect = {rect->x / 2, rect->y / 2, (rect->w + 1) / 2, (rect->h + 1) / 2};
|
||||
|
||||
VITA_GXM_SetYUVProfile(renderer, texture);
|
||||
|
||||
// copy Y plane
|
||||
VITA_GXM_LockTexture(renderer, texture, rect, (void **)&dst, &dpitch);
|
||||
|
||||
length = rect->w * SDL_BYTESPERPIXEL(texture->format);
|
||||
|
||||
if (length == Ypitch && length == dpitch) {
|
||||
SDL_memcpy(dst, Yplane, length*rect->h);
|
||||
} else {
|
||||
for (row = 0; row < rect->h; ++row) {
|
||||
SDL_memcpy(dst, Yplane, length);
|
||||
Yplane += Ypitch;
|
||||
dst += dpitch;
|
||||
}
|
||||
}
|
||||
|
||||
// UV plane
|
||||
{
|
||||
void *UVdst;
|
||||
VITA_GXM_TextureData *vita_texture = (VITA_GXM_TextureData *) texture->driverdata;
|
||||
int uv_pitch = 2 * ((dpitch+1) / 2);
|
||||
|
||||
// skip Y plane
|
||||
void *pixels = (void *) ((Uint8 *) gxm_texture_get_datap(vita_texture->tex) + (vita_texture->pitch * vita_texture->h));
|
||||
|
||||
UVdst = pixels + (UVrect.y * uv_pitch) + UVrect.x;
|
||||
|
||||
length = UVrect.w * 2;
|
||||
|
||||
// UV plane
|
||||
if (length == UVpitch && length == uv_pitch) {
|
||||
SDL_memcpy(UVdst, UVplane, length*UVrect.h);
|
||||
} else {
|
||||
for (row = 0; row < UVrect.h; ++row) {
|
||||
SDL_memcpy(UVdst, UVplane, length);
|
||||
UVplane += UVpitch;
|
||||
UVdst += uv_pitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
VITA_GXM_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture,
|
||||
const SDL_Rect *rect, void **pixels, int *pitch)
|
||||
@@ -442,11 +688,10 @@ VITA_GXM_QueueSetDrawColor(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
const Uint8 r = cmd->data.color.r;
|
||||
const Uint8 g = cmd->data.color.g;
|
||||
const Uint8 b = cmd->data.color.b;
|
||||
const Uint8 a = cmd->data.color.a;
|
||||
data->drawstate.color = (((Uint32)a << 24) | (b << 16) | (g << 8) | r);
|
||||
data->drawstate.color.r = cmd->data.color.r;
|
||||
data->drawstate.color.g = cmd->data.color.g;
|
||||
data->drawstate.color.b = cmd->data.color.b;
|
||||
data->drawstate.color.a = cmd->data.color.a;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -456,7 +701,7 @@ VITA_GXM_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
int color = data->drawstate.color;
|
||||
SDL_Color color = data->drawstate.color;
|
||||
|
||||
color_vertex *vertex = (color_vertex *)pool_malloc(
|
||||
data,
|
||||
@@ -480,7 +725,7 @@ static int
|
||||
VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
int color = data->drawstate.color;
|
||||
SDL_Color color = data->drawstate.color;
|
||||
|
||||
color_vertex *vertex = (color_vertex *)pool_malloc(
|
||||
data,
|
||||
@@ -506,7 +751,7 @@ VITA_GXM_QueueDrawLines(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const S
|
||||
|
||||
static int
|
||||
VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
|
||||
const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
|
||||
const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
|
||||
int num_vertices, const void *indices, int num_indices, int size_indices,
|
||||
float scale_x, float scale_y)
|
||||
{
|
||||
@@ -518,6 +763,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
||||
size_indices = indices ? size_indices : 0;
|
||||
|
||||
if (texture) {
|
||||
VITA_GXM_TextureData* vita_texture = (VITA_GXM_TextureData*) texture->driverdata;
|
||||
texture_vertex *vertices;
|
||||
|
||||
vertices = (texture_vertex *)pool_malloc(
|
||||
@@ -533,7 +779,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
||||
int j;
|
||||
float *xy_;
|
||||
float *uv_;
|
||||
int col_;
|
||||
SDL_Color col_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
@@ -545,12 +791,12 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
||||
}
|
||||
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(int *)((char*)color + j * color_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
uv_ = (float *)((char*)uv + j * uv_stride);
|
||||
|
||||
vertices[i].x = xy_[0] * scale_x;
|
||||
vertices[i].y = xy_[1] * scale_y;
|
||||
vertices[i].u = uv_[0];
|
||||
vertices[i].u = uv_[0] * vita_texture->wscale;
|
||||
vertices[i].v = uv_[1];
|
||||
vertices[i].color = col_;
|
||||
}
|
||||
@@ -572,7 +818,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
||||
for (i = 0; i < count; i++) {
|
||||
int j;
|
||||
float *xy_;
|
||||
int col_;
|
||||
SDL_Color col_;
|
||||
if (size_indices == 4) {
|
||||
j = ((const Uint32 *)indices)[i];
|
||||
} else if (size_indices == 2) {
|
||||
@@ -584,7 +830,7 @@ VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Textu
|
||||
}
|
||||
|
||||
xy_ = (float *)((char*)xy + j * xy_stride);
|
||||
col_ = *(int *)((char*)color + j * color_stride);
|
||||
col_ = *(SDL_Color *)((char*)color + j * color_stride);
|
||||
|
||||
vertices[i].x = xy_[0] * scale_x;
|
||||
vertices[i].y = xy_[1] * scale_y;
|
||||
@@ -729,14 +975,6 @@ SetDrawState(VITA_GXM_RenderData *data, const SDL_RenderCommand *cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SetCopyState(SDL_Renderer *renderer, const SDL_RenderCommand *cmd)
|
||||
{
|
||||
VITA_GXM_RenderData *data = (VITA_GXM_RenderData *) renderer->driverdata;
|
||||
|
||||
return SetDrawState(data, cmd);
|
||||
}
|
||||
|
||||
static int
|
||||
VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
|
||||
{
|
||||
@@ -818,16 +1056,12 @@ VITA_GXM_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *
|
||||
break; /* can't go any further on this draw call, different texture/blendmode copy up next. */
|
||||
} else {
|
||||
finalcmd = nextcmd; /* we can combine copy operations here. Mark this one as the furthest okay command. */
|
||||
count += cmd->data.draw.count;
|
||||
count += nextcmd->data.draw.count;
|
||||
}
|
||||
nextcmd = nextcmd->next;
|
||||
}
|
||||
|
||||
if (thistexture) {
|
||||
ret = SetCopyState(renderer, cmd);
|
||||
} else {
|
||||
ret = SetDrawState(data, cmd);
|
||||
}
|
||||
ret = SetDrawState(data, cmd);
|
||||
|
||||
if (ret == 0) {
|
||||
int op = SCE_GXM_PRIMITIVE_TRIANGLES;
|
||||
@@ -1012,7 +1246,7 @@ VITA_GXM_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
|
||||
sceGxmFinish(data->gxm_context);
|
||||
|
||||
free_gxm_texture(vita_texture->tex);
|
||||
free_gxm_texture(data, vita_texture->tex);
|
||||
|
||||
SDL_free(vita_texture);
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -26,7 +26,7 @@
|
||||
#include "SDL_render_vita_gxm_memory.h"
|
||||
|
||||
void *
|
||||
mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
|
||||
vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid)
|
||||
{
|
||||
void *mem;
|
||||
|
||||
@@ -51,7 +51,7 @@ mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignm
|
||||
}
|
||||
|
||||
void
|
||||
mem_gpu_free(SceUID uid)
|
||||
vita_mem_free(SceUID uid)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
|
||||
@@ -61,7 +61,71 @@ mem_gpu_free(SceUID uid)
|
||||
}
|
||||
|
||||
void *
|
||||
mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size)
|
||||
{
|
||||
void *mem;
|
||||
|
||||
if (data->texturePool == NULL) {
|
||||
int poolsize;
|
||||
int ret;
|
||||
SceKernelFreeMemorySizeInfo info;
|
||||
info.size = sizeof(SceKernelFreeMemorySizeInfo);
|
||||
sceKernelGetFreeMemorySize(&info);
|
||||
|
||||
poolsize = ALIGN(info.size_cdram, 256*1024);
|
||||
if (poolsize > info.size_cdram) {
|
||||
poolsize = ALIGN(info.size_cdram - 256*1024, 256*1024);
|
||||
}
|
||||
data->texturePoolUID = sceKernelAllocMemBlock("gpu_texture_pool", SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW, poolsize, NULL);
|
||||
if (data->texturePoolUID < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = sceKernelGetMemBlockBase(data->texturePoolUID, &mem);
|
||||
if ( ret < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
data->texturePool = sceClibMspaceCreate(mem, poolsize);
|
||||
|
||||
if (data->texturePool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ret = sceGxmMapMemory(mem, poolsize, SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE);
|
||||
if (ret < 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return sceClibMspaceMemalign(data->texturePool, SCE_GXM_TEXTURE_ALIGNMENT, size);
|
||||
}
|
||||
|
||||
void
|
||||
vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr)
|
||||
{
|
||||
if (data->texturePool != NULL)
|
||||
{
|
||||
sceClibMspaceFree(data->texturePool, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vita_gpu_mem_destroy(VITA_GXM_RenderData *data)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (data->texturePool != NULL)
|
||||
{
|
||||
sceClibMspaceDestroy(data->texturePool);
|
||||
data->texturePool = NULL;
|
||||
if (sceKernelGetMemBlockBase(data->texturePoolUID, &mem) < 0)
|
||||
return;
|
||||
sceGxmUnmapMemory(mem);
|
||||
sceKernelFreeMemBlock(data->texturePoolUID);
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
{
|
||||
void *mem = NULL;
|
||||
|
||||
@@ -77,7 +141,7 @@ mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
}
|
||||
|
||||
void
|
||||
mem_vertex_usse_free(SceUID uid)
|
||||
vita_mem_vertex_usse_free(SceUID uid)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
|
||||
@@ -87,7 +151,7 @@ mem_vertex_usse_free(SceUID uid)
|
||||
}
|
||||
|
||||
void *
|
||||
mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset)
|
||||
{
|
||||
void *mem = NULL;
|
||||
|
||||
@@ -103,7 +167,7 @@ mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offse
|
||||
}
|
||||
|
||||
void
|
||||
mem_fragment_usse_free(SceUID uid)
|
||||
vita_mem_fragment_usse_free(SceUID uid)
|
||||
{
|
||||
void *mem = NULL;
|
||||
if (sceKernelGetMemBlockBase(uid, &mem) < 0)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -25,15 +25,19 @@
|
||||
#include <psp2/gxm.h>
|
||||
#include <psp2/types.h>
|
||||
#include <psp2/kernel/sysmem.h>
|
||||
#include "SDL_render_vita_gxm_types.h"
|
||||
|
||||
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
|
||||
void *mem_gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
|
||||
void mem_gpu_free(SceUID uid);
|
||||
void *mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void mem_vertex_usse_free(SceUID uid);
|
||||
void *mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void mem_fragment_usse_free(SceUID uid);
|
||||
void *vita_mem_alloc(unsigned int type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
|
||||
void vita_mem_free(SceUID uid);
|
||||
void *vita_gpu_mem_alloc(VITA_GXM_RenderData *data, unsigned int size);
|
||||
void vita_gpu_mem_free(VITA_GXM_RenderData *data, void* ptr);
|
||||
void vita_gpu_mem_destroy(VITA_GXM_RenderData *data);
|
||||
void *vita_mem_vertex_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void vita_mem_vertex_usse_free(SceUID uid);
|
||||
void *vita_mem_fragment_usse_alloc(unsigned int size, SceUID *uid, unsigned int *usse_offset);
|
||||
void vita_mem_fragment_usse_free(SceUID uid);
|
||||
|
||||
#endif /* SDL_RENDER_VITA_GXM_MEMORY_H */
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -117,6 +117,8 @@ tex_format_to_bytespp(SceGxmTextureFormat format)
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U8:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_S8:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_P8:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2: // YUV actually uses 12 bits per pixel. UV planes bits/mem are handled elsewhere
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3:
|
||||
return 1;
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U4U4U4U4:
|
||||
case SCE_GXM_TEXTURE_BASE_FORMAT_U8U3U3U2:
|
||||
@@ -216,19 +218,31 @@ set_stencil_mask(VITA_GXM_RenderData *data, float x, float y, float w, float h)
|
||||
|
||||
vertices[0].x = x;
|
||||
vertices[0].y = y;
|
||||
vertices[0].color = 0;
|
||||
vertices[0].color.r = 0;
|
||||
vertices[0].color.g = 0;
|
||||
vertices[0].color.b = 0;
|
||||
vertices[0].color.a = 0;
|
||||
|
||||
vertices[1].x = x + w;
|
||||
vertices[1].y = y;
|
||||
vertices[1].color = 0;
|
||||
vertices[1].color.r = 0;
|
||||
vertices[1].color.g = 0;
|
||||
vertices[1].color.b = 0;
|
||||
vertices[1].color.a = 0;
|
||||
|
||||
vertices[2].x = x;
|
||||
vertices[2].y = y + h;
|
||||
vertices[2].color = 0;
|
||||
vertices[2].color.r = 0;
|
||||
vertices[2].color.g = 0;
|
||||
vertices[2].color.b = 0;
|
||||
vertices[2].color.a = 0;
|
||||
|
||||
vertices[3].x = x + w;
|
||||
vertices[3].y = y + h;
|
||||
vertices[3].color = 0;
|
||||
vertices[3].color.r = 0;
|
||||
vertices[3].color.g = 0;
|
||||
vertices[3].color.b = 0;
|
||||
vertices[3].color.a = 0;
|
||||
|
||||
data->drawstate.fragment_program = data->colorFragmentProgram;
|
||||
data->drawstate.vertex_program = data->colorVertexProgram;
|
||||
@@ -402,28 +416,28 @@ gxm_init(SDL_Renderer *renderer)
|
||||
}
|
||||
|
||||
// allocate ring buffer memory using default sizes
|
||||
vdmRingBuffer = mem_gpu_alloc(
|
||||
vdmRingBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
SCE_GXM_DEFAULT_VDM_RING_BUFFER_SIZE,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||
&data->vdmRingBufferUid);
|
||||
|
||||
vertexRingBuffer = mem_gpu_alloc(
|
||||
vertexRingBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
SCE_GXM_DEFAULT_VERTEX_RING_BUFFER_SIZE,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||
&data->vertexRingBufferUid);
|
||||
|
||||
fragmentRingBuffer = mem_gpu_alloc(
|
||||
fragmentRingBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
SCE_GXM_DEFAULT_FRAGMENT_RING_BUFFER_SIZE,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ,
|
||||
&data->fragmentRingBufferUid);
|
||||
|
||||
fragmentUsseRingBuffer = mem_fragment_usse_alloc(
|
||||
fragmentUsseRingBuffer = vita_mem_fragment_usse_alloc(
|
||||
SCE_GXM_DEFAULT_FRAGMENT_USSE_RING_BUFFER_SIZE,
|
||||
&data->fragmentUsseRingBufferUid,
|
||||
&fragmentUsseRingBufferOffset);
|
||||
@@ -468,7 +482,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
for (i = 0; i < VITA_GXM_BUFFERS; i++) {
|
||||
|
||||
// allocate memory for display
|
||||
data->displayBufferData[i] = mem_gpu_alloc(
|
||||
data->displayBufferData[i] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
||||
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
||||
@@ -513,7 +527,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
|
||||
|
||||
// allocate the depth buffer
|
||||
data->depthBufferData = mem_gpu_alloc(
|
||||
data->depthBufferData = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
4 * sampleCount,
|
||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||
@@ -521,7 +535,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
&data->depthBufferUid);
|
||||
|
||||
// allocate the stencil buffer
|
||||
data->stencilBufferData = mem_gpu_alloc(
|
||||
data->stencilBufferData = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
4 * sampleCount,
|
||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||
@@ -553,19 +567,19 @@ gxm_init(SDL_Renderer *renderer)
|
||||
|
||||
|
||||
// allocate memory for buffers and USSE code
|
||||
patcherBuffer = mem_gpu_alloc(
|
||||
patcherBuffer = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
patcherBufferSize,
|
||||
4,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&data->patcherBufferUid);
|
||||
|
||||
patcherVertexUsse = mem_vertex_usse_alloc(
|
||||
patcherVertexUsse = vita_mem_vertex_usse_alloc(
|
||||
patcherVertexUsseSize,
|
||||
&data->patcherVertexUsseUid,
|
||||
&patcherVertexUsseOffset);
|
||||
|
||||
patcherFragmentUsse = mem_fragment_usse_alloc(
|
||||
patcherFragmentUsse = vita_mem_fragment_usse_alloc(
|
||||
patcherFragmentUsseSize,
|
||||
&data->patcherFragmentUsseUid,
|
||||
&patcherFragmentUsseOffset);
|
||||
@@ -716,7 +730,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
}
|
||||
|
||||
// create the clear triangle vertex/index data
|
||||
data->clearVertices = (clear_vertex *)mem_gpu_alloc(
|
||||
data->clearVertices = (clear_vertex *)vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
3*sizeof(clear_vertex),
|
||||
4,
|
||||
@@ -728,7 +742,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
// Allocate a 64k * 2 bytes = 128 KiB buffer and store all possible
|
||||
// 16-bit indices in linear ascending order, so we can use this for
|
||||
// all drawing operations where we don't want to use indexing.
|
||||
data->linearIndices = (uint16_t *)mem_gpu_alloc(
|
||||
data->linearIndices = (uint16_t *)vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
UINT16_MAX*sizeof(uint16_t),
|
||||
sizeof(uint16_t),
|
||||
@@ -859,7 +873,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
data->textureWvpParam = (SceGxmProgramParameter *)sceGxmProgramFindParameterByName(textureVertexProgramGxp, "wvp");
|
||||
|
||||
// Allocate memory for the memory pool
|
||||
data->pool_addr[0] = mem_gpu_alloc(
|
||||
data->pool_addr[0] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
|
||||
VITA_GXM_POOL_SIZE,
|
||||
sizeof(void *),
|
||||
@@ -867,7 +881,7 @@ gxm_init(SDL_Renderer *renderer)
|
||||
&data->poolUid[0]
|
||||
);
|
||||
|
||||
data->pool_addr[1] = mem_gpu_alloc(
|
||||
data->pool_addr[1] = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
|
||||
VITA_GXM_POOL_SIZE,
|
||||
sizeof(void *),
|
||||
@@ -906,28 +920,28 @@ void gxm_finish(SDL_Renderer *renderer)
|
||||
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mod);
|
||||
free_fragment_programs(data, &data->blendFragmentPrograms.blend_mode_mul);
|
||||
|
||||
mem_gpu_free(data->linearIndicesUid);
|
||||
mem_gpu_free(data->clearVerticesUid);
|
||||
vita_mem_free(data->linearIndicesUid);
|
||||
vita_mem_free(data->clearVerticesUid);
|
||||
|
||||
// wait until display queue is finished before deallocating display buffers
|
||||
sceGxmDisplayQueueFinish();
|
||||
|
||||
// clean up display queue
|
||||
mem_gpu_free(data->depthBufferUid);
|
||||
vita_mem_free(data->depthBufferUid);
|
||||
|
||||
for (size_t i = 0; i < VITA_GXM_BUFFERS; i++)
|
||||
{
|
||||
// clear the buffer then deallocate
|
||||
SDL_memset(data->displayBufferData[i], 0, VITA_GXM_SCREEN_HEIGHT * VITA_GXM_SCREEN_STRIDE * 4);
|
||||
mem_gpu_free(data->displayBufferUid[i]);
|
||||
vita_mem_free(data->displayBufferUid[i]);
|
||||
|
||||
// destroy the sync object
|
||||
sceGxmSyncObjectDestroy(data->displayBufferSync[i]);
|
||||
}
|
||||
|
||||
// Free the depth and stencil buffer
|
||||
mem_gpu_free(data->depthBufferUid);
|
||||
mem_gpu_free(data->stencilBufferUid);
|
||||
vita_mem_free(data->depthBufferUid);
|
||||
vita_mem_free(data->stencilBufferUid);
|
||||
|
||||
// unregister programs and destroy shader patcher
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->clearFragmentProgramId);
|
||||
@@ -938,23 +952,24 @@ void gxm_finish(SDL_Renderer *renderer)
|
||||
sceGxmShaderPatcherUnregisterProgram(data->shaderPatcher, data->textureVertexProgramId);
|
||||
|
||||
sceGxmShaderPatcherDestroy(data->shaderPatcher);
|
||||
mem_fragment_usse_free(data->patcherFragmentUsseUid);
|
||||
mem_vertex_usse_free(data->patcherVertexUsseUid);
|
||||
mem_gpu_free(data->patcherBufferUid);
|
||||
vita_mem_fragment_usse_free(data->patcherFragmentUsseUid);
|
||||
vita_mem_vertex_usse_free(data->patcherVertexUsseUid);
|
||||
vita_mem_free(data->patcherBufferUid);
|
||||
|
||||
// destroy the render target
|
||||
sceGxmDestroyRenderTarget(data->renderTarget);
|
||||
|
||||
// destroy the gxm context
|
||||
sceGxmDestroyContext(data->gxm_context);
|
||||
mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
|
||||
mem_gpu_free(data->fragmentRingBufferUid);
|
||||
mem_gpu_free(data->vertexRingBufferUid);
|
||||
mem_gpu_free(data->vdmRingBufferUid);
|
||||
vita_mem_fragment_usse_free(data->fragmentUsseRingBufferUid);
|
||||
vita_mem_free(data->fragmentRingBufferUid);
|
||||
vita_mem_free(data->vertexRingBufferUid);
|
||||
vita_mem_free(data->vdmRingBufferUid);
|
||||
SDL_free(data->contextParams.hostMem);
|
||||
|
||||
mem_gpu_free(data->poolUid[0]);
|
||||
mem_gpu_free(data->poolUid[1]);
|
||||
vita_mem_free(data->poolUid[0]);
|
||||
vita_mem_free(data->poolUid[1]);
|
||||
vita_gpu_mem_destroy(data);
|
||||
|
||||
// terminate libgxm
|
||||
sceGxmTerminate();
|
||||
@@ -963,16 +978,20 @@ void gxm_finish(SDL_Renderer *renderer)
|
||||
// textures
|
||||
|
||||
void
|
||||
free_gxm_texture(gxm_texture *texture)
|
||||
free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture)
|
||||
{
|
||||
if (texture) {
|
||||
if (texture->gxm_rendertarget) {
|
||||
sceGxmDestroyRenderTarget(texture->gxm_rendertarget);
|
||||
}
|
||||
if (texture->depth_UID) {
|
||||
mem_gpu_free(texture->depth_UID);
|
||||
vita_mem_free(texture->depth_UID);
|
||||
}
|
||||
if (texture->cdram) {
|
||||
vita_gpu_mem_free(data, sceGxmTextureGetData(&texture->gxm_tex));
|
||||
} else {
|
||||
vita_mem_free(texture->data_UID);
|
||||
}
|
||||
mem_gpu_free(texture->data_UID);
|
||||
SDL_free(texture);
|
||||
}
|
||||
}
|
||||
@@ -983,25 +1002,6 @@ gxm_texture_get_format(const gxm_texture *texture)
|
||||
return sceGxmTextureGetFormat(&texture->gxm_tex);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gxm_texture_get_width(const gxm_texture *texture)
|
||||
{
|
||||
return sceGxmTextureGetWidth(&texture->gxm_tex);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gxm_texture_get_height(const gxm_texture *texture)
|
||||
{
|
||||
return sceGxmTextureGetHeight(&texture->gxm_tex);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
gxm_texture_get_stride(const gxm_texture *texture)
|
||||
{
|
||||
return ((gxm_texture_get_width(texture) + 7) & ~7)
|
||||
* tex_format_to_bytespp(gxm_texture_get_format(texture));
|
||||
}
|
||||
|
||||
void *
|
||||
gxm_texture_get_datap(const gxm_texture *texture)
|
||||
{
|
||||
@@ -1009,34 +1009,53 @@ gxm_texture_get_datap(const gxm_texture *texture)
|
||||
}
|
||||
|
||||
gxm_texture *
|
||||
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget)
|
||||
create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale)
|
||||
{
|
||||
gxm_texture *texture = SDL_calloc(1, sizeof(gxm_texture));
|
||||
const int tex_size = ((w + 7) & ~ 7) * h * tex_format_to_bytespp(format);
|
||||
int aligned_w = ALIGN(w, 8);
|
||||
int texture_w = w;
|
||||
int tex_size = aligned_w * h * tex_format_to_bytespp(format);
|
||||
void *texture_data;
|
||||
int ret;
|
||||
|
||||
*return_wscale = 1.0f;
|
||||
|
||||
// SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3/P2 based formats require width aligned to 16
|
||||
if ( (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P3 || (format & 0x9f000000U) == SCE_GXM_TEXTURE_BASE_FORMAT_YUV420P2) {
|
||||
aligned_w = ALIGN(w, 16);
|
||||
texture_w = aligned_w;
|
||||
tex_size = aligned_w * h * tex_format_to_bytespp(format);
|
||||
*return_wscale = (float) (w) / texture_w;
|
||||
// add storage for UV planes
|
||||
tex_size += (((aligned_w + 1) / 2) * ((h + 1) / 2)) * 2;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
return NULL;
|
||||
|
||||
*return_w = w;
|
||||
*return_h = h;
|
||||
*return_pitch = aligned_w * tex_format_to_bytespp(format);
|
||||
|
||||
/* Allocate a GPU buffer for the texture */
|
||||
texture_data = mem_gpu_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
tex_size,
|
||||
SCE_GXM_TEXTURE_ALIGNMENT,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&texture->data_UID
|
||||
texture_data = vita_gpu_mem_alloc(
|
||||
data,
|
||||
tex_size
|
||||
);
|
||||
|
||||
/* Try SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE in case we're out of VRAM */
|
||||
if (!texture_data) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "CDRAM texture allocation failed\n");
|
||||
texture_data = mem_gpu_alloc(
|
||||
texture_data = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
tex_size,
|
||||
SCE_GXM_TEXTURE_ALIGNMENT,
|
||||
SCE_GXM_MEMORY_ATTRIB_READ | SCE_GXM_MEMORY_ATTRIB_WRITE,
|
||||
&texture->data_UID
|
||||
);
|
||||
texture->cdram = 0;
|
||||
} else {
|
||||
texture->cdram = 1;
|
||||
}
|
||||
|
||||
if (!texture_data) {
|
||||
@@ -1048,7 +1067,12 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
SDL_memset(texture_data, 0, tex_size);
|
||||
|
||||
/* Create the gxm texture */
|
||||
sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, w, h, 0);
|
||||
ret = sceGxmTextureInitLinear( &texture->gxm_tex, texture_data, format, texture_w, h, 0);
|
||||
if (ret < 0) {
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "texture init failed: %x\n", ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (isRenderTarget) {
|
||||
void *depthBufferData;
|
||||
@@ -1071,13 +1095,13 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
);
|
||||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %d\n", err);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "color surface init failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// allocate it
|
||||
depthBufferData = mem_gpu_alloc(
|
||||
depthBufferData = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE,
|
||||
4*sampleCount,
|
||||
SCE_GXM_DEPTHSTENCIL_SURFACE_ALIGNMENT,
|
||||
@@ -1094,8 +1118,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
NULL);
|
||||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %d\n", err);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "depth stencil init failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1119,8 +1143,8 @@ create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, Sc
|
||||
texture->gxm_rendertarget = tgt;
|
||||
|
||||
if (err < 0) {
|
||||
free_gxm_texture(texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %d\n", err);
|
||||
free_gxm_texture(data, texture);
|
||||
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "create render target failed: %x\n", err);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1169,7 +1193,7 @@ void gxm_init_for_common_dialog(void)
|
||||
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
|
||||
{
|
||||
buffer_for_common_dialog[i].displayData.wait_vblank = SDL_TRUE;
|
||||
buffer_for_common_dialog[i].displayData.address = mem_gpu_alloc(
|
||||
buffer_for_common_dialog[i].displayData.address = vita_mem_alloc(
|
||||
SCE_KERNEL_MEMBLOCK_TYPE_USER_CDRAM_RW,
|
||||
4 * VITA_GXM_SCREEN_STRIDE * VITA_GXM_SCREEN_HEIGHT,
|
||||
SCE_GXM_COLOR_SURFACE_ALIGNMENT,
|
||||
@@ -1217,7 +1241,7 @@ void gxm_term_for_common_dialog(void)
|
||||
sceGxmDisplayQueueFinish();
|
||||
for (int i = 0; i < VITA_GXM_BUFFERS; i += 1)
|
||||
{
|
||||
mem_gpu_free(buffer_for_common_dialog[i].uid);
|
||||
vita_mem_free(buffer_for_common_dialog[i].uid);
|
||||
sceGxmSyncObjectDestroy(buffer_for_common_dialog[i].sync);
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -48,15 +48,12 @@ void unset_clip_rectangle(VITA_GXM_RenderData *data);
|
||||
int gxm_init(SDL_Renderer *renderer);
|
||||
void gxm_finish(SDL_Renderer *renderer);
|
||||
|
||||
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget);
|
||||
void free_gxm_texture(gxm_texture *texture);
|
||||
gxm_texture *create_gxm_texture(VITA_GXM_RenderData *data, unsigned int w, unsigned int h, SceGxmTextureFormat format, unsigned int isRenderTarget, unsigned int *return_w, unsigned int *return_h, unsigned int *return_pitch, float *return_wscale);
|
||||
void free_gxm_texture(VITA_GXM_RenderData *data, gxm_texture *texture);
|
||||
|
||||
void gxm_texture_set_filters(gxm_texture *texture, SceGxmTextureFilter min_filter, SceGxmTextureFilter mag_filter);
|
||||
SceGxmTextureFormat gxm_texture_get_format(const gxm_texture *texture);
|
||||
|
||||
unsigned int gxm_texture_get_width(const gxm_texture *texture);
|
||||
unsigned int gxm_texture_get_height(const gxm_texture *texture);
|
||||
unsigned int gxm_texture_get_stride(const gxm_texture *texture);
|
||||
void *gxm_texture_get_datap(const gxm_texture *texture);
|
||||
|
||||
void gxm_minimal_init_for_common_dialog(void);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
|
||||
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <psp2/gxm.h>
|
||||
#include <psp2/types.h>
|
||||
#include <psp2/kernel/sysmem.h>
|
||||
#include <psp2/kernel/clib.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -61,7 +62,7 @@ typedef struct clear_vertex {
|
||||
typedef struct color_vertex {
|
||||
float x;
|
||||
float y;
|
||||
unsigned int color;
|
||||
SDL_Color color;
|
||||
} color_vertex;
|
||||
|
||||
typedef struct texture_vertex {
|
||||
@@ -69,7 +70,7 @@ typedef struct texture_vertex {
|
||||
float y;
|
||||
float u;
|
||||
float v;
|
||||
unsigned int color;
|
||||
SDL_Color color;
|
||||
} texture_vertex;
|
||||
|
||||
typedef struct gxm_texture {
|
||||
@@ -79,6 +80,7 @@ typedef struct gxm_texture {
|
||||
SceGxmColorSurface gxm_colorsurface;
|
||||
SceGxmDepthStencilSurface gxm_depthstencil;
|
||||
SceUID depth_UID;
|
||||
SDL_bool cdram;
|
||||
} gxm_texture;
|
||||
|
||||
typedef struct fragment_programs {
|
||||
@@ -100,7 +102,7 @@ typedef struct
|
||||
SDL_bool viewport_dirty;
|
||||
SDL_Texture *texture;
|
||||
SDL_Texture *target;
|
||||
Uint32 color;
|
||||
SDL_Color color;
|
||||
SceGxmFragmentProgram *fragment_program;
|
||||
SceGxmVertexProgram *vertex_program;
|
||||
int last_command;
|
||||
@@ -110,7 +112,7 @@ typedef struct
|
||||
SDL_bool cliprect_dirty;
|
||||
SDL_Rect cliprect;
|
||||
SDL_bool texturing;
|
||||
Uint32 clear_color;
|
||||
SDL_Color clear_color;
|
||||
int drawablew;
|
||||
int drawableh;
|
||||
} gxm_drawstate_cache;
|
||||
@@ -186,14 +188,19 @@ typedef struct
|
||||
blend_fragment_programs blendFragmentPrograms;
|
||||
|
||||
gxm_drawstate_cache drawstate;
|
||||
SceClibMspace texturePool;
|
||||
SceUID texturePoolUID;
|
||||
} VITA_GXM_RenderData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gxm_texture *tex;
|
||||
unsigned int pitch;
|
||||
unsigned int w;
|
||||
unsigned int h;
|
||||
unsigned int pitch;
|
||||
unsigned int w;
|
||||
unsigned int h;
|
||||
float wscale;
|
||||
SDL_bool yuv;
|
||||
SDL_bool nv12;
|
||||
} VITA_GXM_TextureData;
|
||||
|
||||
#endif /* SDL_RENDER_VITA_GXM_TYPES_H */
|
||||
|
Reference in New Issue
Block a user